Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
6ae1f0e
feat: add pnpm dependency
ukwhatn Oct 31, 2025
1ba2732
feat: add nodejs dependency
ukwhatn Oct 31, 2025
e6a3de1
feat: frontend環境構築(Vite + React + TypeScript)
ukwhatn Oct 31, 2025
7e9d7ed
feat: React Router、TanStack Query、Tailwind CSS導入
ukwhatn Oct 31, 2025
cd22117
deps: remove tailwind
ukwhatn Oct 31, 2025
98644a0
feat: 基本的なページ構造とサンプルページ作成
ukwhatn Oct 31, 2025
e25f8d6
feat: 開発環境のproxy設定追加
ukwhatn Oct 31, 2025
9aee988
feat: Makefileにfrontendコマンド追加(並列実行対応)
ukwhatn Oct 31, 2025
4791d03
feat: FastAPIに静的ファイルサーブ機能とSPA用404フォールバック実装
ukwhatn Oct 31, 2025
34bd4cd
feat: Dockerマルチステージビルドにフロントエンドビルド追加
ukwhatn Oct 31, 2025
5d8524a
docs: フロントエンド統合に関するドキュメント更新
ukwhatn Oct 31, 2025
35f3ee8
fix: SPAStaticFilesのget_responseメソッドの型修正
ukwhatn Oct 31, 2025
08d5dfc
feat: フロントエンドのpre-commitフック追加とtailwindcss依存関係修正
ukwhatn Oct 31, 2025
f44c2cf
fix: 微修正
ukwhatn Oct 31, 2025
642e3e5
deps: update
ukwhatn Oct 31, 2025
bcf8ff4
fix: テスト環境でSPAマウント無効化とPydantic警告抑制
ukwhatn Oct 31, 2025
7d5a610
refactor: ワークフローファイルとComposeファイルをdev→stgにリネーム
ukwhatn Nov 1, 2025
6f68190
chore: .gitignoreに生環境変数ファイルを追加
ukwhatn Nov 1, 2025
3217d70
feat: .env.exampleにAPP_NAME設定を追加
ukwhatn Nov 1, 2025
28aeefa
refactor: .sops.yamlの環境をdev→stgに変更
ukwhatn Nov 1, 2025
9eded39
refactor: config.pyでstaging環境をサポートし関連機能を追加
ukwhatn Nov 1, 2025
ddbeb61
refactor: インフラストラクチャレイヤーをstaging環境に対応
ukwhatn Nov 1, 2025
681e57a
refactor: main.pyでnormalized_env_modeを使用
ukwhatn Nov 1, 2025
a9c15e6
fix: compose.local.ymlのポートマッピングを修正
ukwhatn Nov 1, 2025
1295261
refactor: Makefileをdev→stgに変更し.PHONYを追加
ukwhatn Nov 1, 2025
35f7818
docs: ドキュメントをdev→stgに更新
ukwhatn Nov 1, 2025
e8bb830
refactor: スクリプトとワークフローをdev→stgに変更
ukwhatn Nov 1, 2025
e921c3a
chore: 暗号化された環境変数ファイルを追加
ukwhatn Nov 1, 2025
6730b36
refactor: リネームしたファイルの内容をdev→stgに更新
ukwhatn Nov 1, 2025
ade512a
wip: stgで動かすための試行錯誤
ukwhatn Nov 1, 2025
f85967e
refactor: フロントエンドマウントパスを/adminに変更
ukwhatn Nov 1, 2025
e4d9887
refactor: Viteのbaseパスを/admin/に設定
ukwhatn Nov 1, 2025
71d3fa9
refactor: React Routerのbasenameを/adminに設定
ukwhatn Nov 1, 2025
ae14190
docs: フロントエンドアクセスURLを/adminに更新
ukwhatn Nov 1, 2025
78f874f
feat: healthcheckエンドポイントにDB接続状況とuptimeを追加
ukwhatn Nov 1, 2025
0927147
refactor: バックアップコマンドをdocker compose経由に統一
ukwhatn Nov 1, 2025
d92b9db
fix: 微調整
ukwhatn Nov 1, 2025
8a9a111
refactor: main.pyを分割してアプリケーションファクトリーパターンを導入
ukwhatn Nov 1, 2025
9eb531c
fix: 環境別設定ファイルとマイグレーションログレベルを修正
ukwhatn Nov 1, 2025
47d9352
test: BatchTaskクラスのテストを追加
ukwhatn Nov 1, 2025
3f063ab
test: add comprehensive unit tests for scheduler module
ukwhatn Nov 1, 2025
d2b4afc
test: タスクレジストリの単体テストを追加
ukwhatn Nov 1, 2025
a5a1a83
test: テストケース整理
ukwhatn Nov 1, 2025
b3bed85
fix: mypy
ukwhatn Nov 1, 2025
4fd7788
fix: ci設定修正
ukwhatn Nov 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# ========================================
# 基本設定
# ========================================
APP_NAME="FastAPI Template"
ENV_MODE=test
APP_PORT=59901

# ========================================
# データベース設定
Expand Down
14 changes: 14 additions & 0 deletions .env.prod.enc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"data": "ENC[AES256_GCM,data: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,iv:nQGCHNou2k/yAZmAq50XWLmnNLNZrb+iD5A57N0KAmQ=,tag:c1iLrmV57hK3n9Lo31olMg==,type:str]",
"sops": {
"age": [
{
"recipient": "age1s82807xgq0v92sea205jpmt7q0dat9pe29cdpmm4l2juft9gle6q03h0ut",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5QXVPMnF2a2hIRWRXTTdr\ndXdPSDVaM08rbU1NcGg1R0g5VTZpZno4cG5FCnJGQ2pUb1Y0YTZTRUloODlLcFJs\nVzZLWEY2SU1RWlNiMi9CSDV4Rm5KMVUKLS0tIGZxWS9mNjMvTWxQTVdZY0s5UTRy\nZjg1aDlySjhTRUZvYlJKcjVTZm5hdXMKXoP1fAWMBcR/ecQ3dswyc9hpID0QbN+u\nObCiQlim6whnc+TbeJuN9vnE246SkvA7x78VRB/FeAGo08afVdfL7A==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-11-01T08:23:13Z",
"mac": "ENC[AES256_GCM,data:rw/hWDhtdNgCD34ISqxxUQwAxOvLWVqO5a37GzqZa0MGfDHrYvgaoXGrrXrvixkKkvPibE/EAXZXZnZ6Zn+a5gb84EiaIetmtqZ8a1IHzC7ajYmqM7/Z6ctTvoR9LTgaz8UBohKy+G/ZcFX9d8pDTY34hcFTOtHMe22u9r77O28=,iv:8ihT4tGrAG/DEpNUS6852NJxH2DtoLqmX8vsKWF7GfQ=,tag:1LWbKByJza+SMo8UNP5XjA==,type:str]",
"version": "3.11.0"
}
}
14 changes: 14 additions & 0 deletions .env.stg.enc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"data": "ENC[AES256_GCM,data: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,iv:7Zdi1xI5OiE1hha1if3hMOud11y4gNJQg7TE0h/2RJ0=,tag:7GyrpXhS9A7tLMYA/EGgSg==,type:str]",
"sops": {
"age": [
{
"recipient": "age1pv907v4hzwdf900raqf5w40egm7n73kmhrg6husenmrlsn6f430sa9ncug",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwYUx5V2tXQ0YyR3g3ZkNi\nQ0psWlpFUzdqMnJwNWN0R3ordTlWRTc2SDBrCjM4NDBzeWZkcS9uY0VzRjhjem1G\ncXRkVm44czdKK3pFR0pidkVwQWVFUEUKLS0tIC9HYnJyVmZsMnJ4SlZJSENpRElM\nTlp2S1J2TkVseG0xbDNWNER1ZTBKQlEKkW/uHHKoxIJK7vrewfiDHnBS/kxZXRHY\nxHOM2bpLOmfOTNaCjG27SRSTtb2oBjrDruToMy2bS17IlfubMon0Pw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-11-01T08:23:13Z",
"mac": "ENC[AES256_GCM,data:LRlrXMXtQahMjsNr+krPAokdRpA9RACoVyQ0OePg+gLAmmRu+s4wWmip+rG7U2ixoRC/vGGRhRNiOdPNqB8NOOxkYNRh6svX43qnx47GPUoewvvnl65/zNzYqzeohO4DZkzEghvMgsiBWaObWJ8SH4Ih+4uv3h8+R1d0qN6cLaA=,iv:QQNVDBo5mBhbYHWTsHn4b1DFGoIDwIuEcHS6tl5stWc=,tag:87SdgGkV+T8f2glKYQYaxQ==,type:str]",
"version": "3.11.0"
}
}
12 changes: 6 additions & 6 deletions .github/workflows/cd-dev.yml → .github/workflows/cd-stg.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Deploy to Dev
name: Deploy to Stg

on:
push:
Expand All @@ -15,11 +15,11 @@ jobs:
needs: build-and-push
uses: ./.github/workflows/cd_deliverer.yml
with:
environment: dev
environment: stg
branch: develop
image_tag: develop
secrets:
SSH_HOST: ${{ secrets.DEV_SSH_HOST }}
SSH_USER: ${{ secrets.DEV_SSH_USER }}
SSH_PORT: ${{ secrets.DEV_SSH_PORT }}
SSH_PRIVATE_KEY: ${{ secrets.DEV_SSH_PRIVATE_KEY }}
SSH_HOST: ${{ secrets.STG_SSH_HOST }}
SSH_USER: ${{ secrets.STG_SSH_USER }}
SSH_PORT: ${{ secrets.STG_SSH_PORT }}
SSH_PRIVATE_KEY: ${{ secrets.STG_SSH_PRIVATE_KEY }}
2 changes: 1 addition & 1 deletion .github/workflows/cd_deliverer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
inputs:
environment:
required: true
type: string # dev or prod
type: string # stg or prod
branch:
required: true
type: string # develop or main
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/ci_docker-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:
make env
# ローカルDB使用設定(テスト用)
sed -i 's/POSTGRES_HOST=.*/POSTGRES_HOST=db/' .env
# prod環境用の.env.prodファイルを作成(compose.prod.ymlで必要)
cp .env .env.prod

- name: Start services with local DB
run: make compose:build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
POSTGRES_DB: main
options: >-
--health-cmd pg_isready
--health-interval 10s
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,9 @@ nginx/log/*
!nginx/log/.keep

# Local development files
.local/
.local/

# raw envirionment variables file
.env
.env.stg
.env.prod
26 changes: 22 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,36 @@ repos:
files: ^app/.*\.py$
stages: [pre-commit]

# Type check(pre-pushのみ)
# Frontend lint(pre-commitのみ)
- id: frontend-lint
name: Frontend lint with ESLint
entry: make frontend:lint:fix
language: system
pass_filenames: false
files: ^frontend/.*\.(ts|tsx|js|jsx)$
stages: [pre-commit]

# Backend Type check(pre-pushのみ)
- id: mypy
name: Type check with mypy
name: Backend type check with mypy
entry: make type-check
language: system
pass_filenames: false
always_run: true
stages: [pre-push]

# Tests(pre-pushのみ)
# Frontend Type check(pre-pushのみ)
- id: frontend-type-check
name: Frontend type check with tsc
entry: make frontend:type-check
language: system
pass_filenames: false
files: ^frontend/.*\.(ts|tsx)$
stages: [pre-push]

# Backend Tests(pre-pushのみ)
- id: pytest
name: Run tests
name: Run backend tests
entry: make test
language: system
pass_filenames: false
Expand Down
14 changes: 7 additions & 7 deletions .sops.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@
# 3. Keep private keys secure (never commit to git)
#
# Usage:
# Encrypt: sops -e .env.dev > .env.dev.enc
# Decrypt: sops -d .env.dev.enc > .env
# Edit: sops .env.dev.enc
# Encrypt: sops -e .env.stg > .env.stg.enc
# Decrypt: sops -d .env.stg.enc > .env
# Edit: sops .env.stg.enc

creation_rules:
# Dev environment
- path_regex: \.env\.dev(\.enc)?$
- path_regex: \.env\.stg(\.enc)?$
age: >-
age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
age1pv907v4hzwdf900raqf5w40egm7n73kmhrg6husenmrlsn6f430sa9ncug

# Production environment
- path_regex: \.env\.prod(\.enc)?$
age: >-
age1yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
age1s82807xgq0v92sea205jpmt7q0dat9pe29cdpmm4l2juft9gle6q03h0ut

# Default rule for any other .env files
- path_regex: \.env\..*$
age: >-
age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
age1e37lt3cs8ykf93nl3meav3jx46mnuu63xntxaqruypfv0dchpsfs8den23
158 changes: 148 additions & 10 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

## プロジェクト概要

FastAPIプロダクションテンプレート。Clean Architecture(4層)、RDBベース暗号化セッション、包括的Docker展開を提供。
FastAPIプロダクションテンプレート。Clean Architecture(4層)、RDBベース暗号化セッション、Vite+Reactフロントエンド統合、包括的Docker展開を提供。

**技術スタック**:
- FastAPI 0.120.0+, Python 3.13+
- SQLAlchemy 2.0+, PostgreSQL
- uv, Ruff, mypy strict, pytest
- Docker Compose (multi-profile)
- APScheduler, Sentry, New Relic
- **バックエンド**: FastAPI 0.120.0+, Python 3.13+, SQLAlchemy 2.0+, PostgreSQL
- **フロントエンド**: Vite 6.x, React 19.x, TypeScript 5.x, React Router 7.x, TanStack Query 5.x, Tailwind CSS 4.x
- **ツール**: uv, pnpm, Ruff, mypy strict, pytest
- **インフラ**: Docker Compose (multi-stage build, multi-profile), APScheduler, Sentry, New Relic

**主要機能**:
- Clean Architecture 4層構造
- Vite+Reactフロントエンド統合(SPA fallback対応)
- RDBベースセッション管理(Fernet暗号化、CSRF保護、フィンガープリント検証)
- psycopg2ベースバックアップシステム(S3連携)
- APSchedulerバッチシステム
Expand All @@ -25,11 +25,22 @@ FastAPIプロダクションテンプレート。Clean Architecture(4層)、
**開発**:
```bash
make dev:setup # 依存関係インストール
make frontend:install # フロントエンド依存関係インストール
make local:up # DBサービス起動
make local:serve # アプリ起動(ホットリロード)
make lint # リント
make type-check # 型チェック
make test # テスト
make local:serve # バックエンド + フロントエンド並列起動(ホットリロード)
make local:serve:backend # バックエンドのみ起動
make local:serve:frontend # フロントエンドのみ起動
make lint # バックエンドリント
make type-check # バックエンド型チェック
make test # バックエンドテスト
```

**フロントエンド**:
```bash
make frontend:build # 本番ビルド
make frontend:lint # ESLint実行
make frontend:lint:fix # ESLint修正
make frontend:type-check # TypeScriptチェック
```

**データベース**:
Expand Down Expand Up @@ -299,6 +310,133 @@ TaskRegistry.register(MyCustomTask)

詳細: [docs/features/batch-system.md](docs/features/batch-system.md)

## フロントエンド統合

### アーキテクチャ

**開発環境**:
- Viteがポート5173でフロントエンド開発サーバーを起動
- Vite proxyが`/api/*`リクエストをFastAPI(ポート8000)に転送
- ホットリロード対応

**本番環境**:
- Dockerマルチステージビルドでフロントエンドをビルド(`frontend/dist`)
- FastAPIが静的ファイルとしてフロントエンドを配信
- `SPAStaticFiles`クラスでReact Routerのhistory mode対応(404 → index.html)
- `/api/*`はFastAPIルーター、`/admin/*`はフロントエンドSPA

### ディレクトリ構造

```
frontend/
├── src/
│ ├── pages/ # ページコンポーネント
│ ├── App.tsx # ルーター設定(React Router)
│ └── main.tsx # エントリーポイント
├── dist/ # ビルド成果物(本番)
├── package.json
├── pnpm-lock.yaml
├── vite.config.ts # Vite設定
└── tsconfig.json
```

### Vite設定(proxy)

```typescript
// frontend/vite.config.ts
export default defineConfig({
plugins: [
tailwindcss(), // Tailwind CSS v4
react(),
],
server: {
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
},
},
},
})
```

### SPAStaticFiles実装

```python
# app/main.py
class SPAStaticFiles(StaticFiles):
"""React Routerのhistory mode対応"""
async def get_response(self, path: str, scope: dict[str, Any]) -> Response:
try:
return await super().get_response(path, scope)
except StarletteHTTPException as ex:
if ex.status_code == 404:
return await super().get_response("index.html", scope)
raise ex

# lifespanでマウント(APIルーターより後)
if FRONTEND_DIST_DIR.exists() and FRONTEND_DIST_DIR.is_dir():
app.mount("/admin", SPAStaticFiles(directory=str(FRONTEND_DIST_DIR), html=True), name="frontend")
```

### APIクライアント実装例(フロントエンド)

```typescript
// frontend/src/api/client.ts
import { useQuery } from '@tanstack/react-query'

// 型安全なAPIクライアント
async function fetchApi<T>(path: string): Promise<T> {
const response = await fetch(`/api${path}`)
if (!response.ok) {
throw new Error(`API error: ${response.statusText}`)
}
return response.json()
}

// React Query フック
export function useHealthCheck() {
return useQuery({
queryKey: ['healthcheck'],
queryFn: () => fetchApi<{ status: string }>('/system/healthcheck'),
})
}
```

### 技術スタック

- **Vite 6.x**: 高速ビルドツール
- **React 19.x**: UIライブラリ
- **TypeScript 5.x**: 型安全性
- **React Router 7.x**: クライアントサイドルーティング(BrowserRouter)
- **TanStack Query 5.x**: データフェッチ・キャッシュ
- **Tailwind CSS 4.x**: CSS-first設定(`@import 'tailwindcss'`のみ、postcss不要)
- **pnpm**: パッケージマネージャー

### ベストプラクティス

1. **API呼び出しは常に`/api`プレフィックス付き**
```typescript
// ✅ GOOD
fetch('/api/users')

// ❌ BAD
fetch('http://localhost:8000/users') // 環境依存
```

2. **TanStack Queryを活用**
- データフェッチ、キャッシュ、再検証を自動化
- サーバー状態とクライアント状態を分離

3. **Tailwind CSS v4の使用**
- `frontend/src/index.css`に`@import 'tailwindcss'`のみ
- `vite.config.ts`に`@tailwindcss/vite`プラグイン追加
- postcss/autoprefixerは不要

4. **型安全性の維持**
- OpenAPI Generatorでバックエンドの型を自動生成可能
- Zodでランタイムバリデーション

## 開発ワークフロー

### 新しいAPIエンドポイント追加
Expand Down
Loading