Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
55 changes: 40 additions & 15 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ make mypy # type checking
make up # start docker containers
make down # stop containers
make exec # shell into container
make restart # restart containers
```

**Run pre-commit checks:**
Expand All @@ -35,19 +36,37 @@ make pre-commit-run-all
This is a Python web application template implementing **Onion Architecture** with multiple UI framework options and cloud deployment support.

### Core Architecture
- **Domain Layer:** `app/domain/` - Business entities and repository interfaces
- **Infrastructure Layer:** `app/infrastructure/repository/` - Database implementations (SQLite, Firestore, DynamoDB, CosmosDB)
- **Use Case Layer:** `app/usecase/` - Business logic orchestration
- **Presentation Layer:** `app/presentation/` - Multiple UI frameworks (FastAPI, Flask, Streamlit, Dash, CLI)
- **Domain Layer:** `app/domain/message/` - Business entities (Message, ID) and repository interfaces (IMessageRepository)
- **Infrastructure Layer:** `app/infrastructure/repository/message/` - Database implementations:
- `sqlite_message_repository.py` - SQLite implementation
- `gcp_message_repository.py` - Firestore implementation
- `aws_message_repository.py` - DynamoDB implementation
- `azure_message_repository.py` - CosmosDB implementation
- **Use Case Layer:** `app/usecase/` - Business logic orchestration:
- `register.py` - Message registration use case
- `history.py` - Message history use case
- `error.py` - Error handling use case
- **Presentation Layer:** `app/presentation/` - Multiple UI frameworks:
- `cli/` - Command-line interface using Typer
- `fastapi/` - REST API with frontend
- `flask/` - Server-side rendering
- `streamlit/` - Data visualization framework
- `dash/` - Interactive dashboard framework

### Dependency Injection
The project uses a sophisticated DI system (`app/di.py`) that automatically selects database implementations based on the runtime environment:
- **Local/Test:** SQLite
- **GCP:** Firestore
- **AWS:** DynamoDB
- **Azure:** CosmosDB

Environment detection happens automatically via environment variables in `app/settings.py`.
- **LOCAL/GITHUB_ACTIONS:** SQLite (`LocalModule`) - File-based database
- **TEST:** SQLite in-memory (`TestModule`) - In-memory database for tests
- **GCP:** Firestore (`GCPModule`) - Cloud Firestore NoSQL database
- **AWS:** DynamoDB (`AWSModule`) - AWS NoSQL database service
- **AZURE:** CosmosDB (`AzureModule`) - Azure's multi-model database service

Environment detection happens automatically via `RunEnv.judge_from_env()` in `app/settings.py` by checking specific environment variables:
- `PYTEST_CURRENT_TEST` - Test environment
- `GITHUB_ACTIONS` - GitHub Actions CI/CD
- `K_SERVICE` - Google Cloud Run
- `AWS_EXECUTION_ENV` - AWS App Runner
- `CONTAINER_APP_REPLICA_NAME` - Azure Container Apps

### Multiple UI Frameworks
The same business logic is exposed through different presentation layers:
Expand All @@ -62,15 +81,21 @@ The same business logic is exposed through different presentation layers:
- Secrets management varies by cloud platform (AWS Secrets Manager, GCP Secret Manager, etc.)

### Testing Setup
- Tests automatically use in-memory SQLite via DI container reset in `conftest.py`
- Both unit tests (`tests/unit/`) and e2e tests (`tests/e2e/`) available
- DI container is reset before each test to ensure isolation
- Tests automatically use in-memory SQLite via DI container reset in `tests/conftest.py`
- **Unit tests:** `tests/unit/` - Domain layer tests (e.g., `tests/unit/domain/message/`)
- **E2E tests:** `tests/e2e/` - End-to-end API tests (`test_fastapi.py`, `test_flask.py`)
- DI container is reset before each test via `reset_injector()` to ensure isolation
- Test configuration uses `TestModule` which provides in-memory SQLite database

### Cloud Deployment
Infrastructure as Code using Terraform for GCP, AWS (App Runner & Lambda), and Azure Container Apps. Each platform has specific deployment scripts in the Makefile.

## Project Structure Notes
- `app/` - Main application directory with onion architecture layers
- `tests/` - Unit tests (`unit/`) and end-to-end tests (`e2e/`)
- `credentials/` - Cloud service account files (not in git)
- `infra/` - Terraform modules for each cloud platform
- `scripts/sample/` - Example/demo scripts
- `infra/` - Terraform modules for each cloud platform (`gcp/`, `aws_apprunner/`, `aws_lambda/`)
- `docs/` - Architecture diagrams and requirements documentation
- `db/` - Local SQLite database file
- `.devcontainer/` - VS Code development container configuration
- `compose.yml` - Docker Compose configuration for local development
38 changes: 24 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,29 +85,29 @@ UIフレームワークによって詳細は異なりますが、FastAPIを利
最小限の構成として利用する場合は、以下の手順で不要なファイルを削除してください。

1. `make minimize`を実行
2. docker-compose.ymlからcredentialsのマウントを削除
3. app/presentation/のサブディレクトリのうち、不要なフレームワークのディレクトリを削除
4. .devcontainer/devcontainer.jsonのlaunchの設定のうち、不要なフレームワークの設定を削除
2. `compose.yml`からcredentialsのマウントを削除
3. `app/presentation/`のサブディレクトリのうち、不要なフレームワークのディレクトリを削除
4. `.devcontainer/devcontainer.json`のlaunchの設定のうち、不要なフレームワークの設定を削除
5. README.mdを編集
6. クラウド関係の環境変数を.envとapp/settings.pyから削除
6. クラウド関係の環境変数を`.env`と`app/settings.py`から削除

## Run Application

アプリケーションを実行する際は、以下の手順で行ってください。

1. `make up`でDocker Composeを起動
2. http://localhost:<LOCAL_PORT>/ からアプリにアクセス
3. `make down`でDocker Composeを終了
終了せずにDev Containerを起動すると、docker-compose.override.ymlの内容が上書きされずデバッグが利用できません。
3. `make down`でDocker Composeを終了
終了せずにDev Containerを起動すると、compose.override.ymlの内容が上書きされずデバッグが利用できません。

## Development

アプリケーションの開発を行う際は、以下の手順で行ってください。

1. pre-commitをインストール(ex. `pip install pre-commit`)
2. `pre-commit install`でpre-commitのhookスクリプトを導入
3. VSCodeでDev Container拡張機能をインストール
4. コマンドパレット(`Ctrl+Shift+P`)から`Remote-Containers: Reopen in Container`を実行
3. VS CodeでDev Containers拡張機能をインストール
4. コマンドパレット(`Ctrl+Shift+P`)から`Dev Containers: Reopen in Container`を実行
5. (Docker Compose立ち上げ時のみ)拡張機能の依存関係の解決に失敗することがあるので、ウィンドウの再読み込みする
6. F5でデバッグ実行が可能
7. http://localhost:<LOCAL_PORT>/ からアプリにアクセス
Expand Down Expand Up @@ -216,20 +216,30 @@ make destroy-aws-lambda

Container Appsへのデプロイを実施します

#### 前準備

1. Entra IDのアプリを登録からサービスプリンシパルを登録し、クライアントシークレットを発行する
2. .envのAZURE_CLIENT_ID,AZURE_CLIENT_SECRETに各値を設定
2. `.env`のAZURE_CLIENT_ID,AZURE_CLIENT_SECRETに各値を設定
3. CosmosDBのデータベースとコレクションを作成
4. サービスプリンシパルにCosmosDBへのアクセス権の付与
4. サービスプリンシパルにCosmosDBへのアクセス権の付与
```shell
az cosmosdb sql role assignment create \
--account-name <CosmosDBのアカウント名> \
--resource-group <リソースグループ名> \
--scope "/" \
--principal-id <EntraIDのエンタープライズアプリケーションの該当アプリケーション(サービスプリンシパル)のオブジェクトID> \
--role-definition-id <ロールid=00000000-0000-0000-0000-000000000002>
```
```
Comment on lines +219 to +232
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Azure 事前準備の環境変数が不足の可能性(デプロイ失敗リスク)

.envAZURE_CLIENT_IDAZURE_CLIENT_SECRET だけだと、Makefile/Infra(Terraform など)が要求する ARM_/AZURE_* 変数(例: AZURE_TENANT_IDARM_SUBSCRIPTION_ID)が不足しデプロイが失敗する可能性があります。ツール連携に必要な正確なキーを README に列挙してください。

以下のスクリプトで Makefile/infra から参照される Azure 関連の環境変数を棚卸しできます。検出結果に基づき README の前提を更新してください。

さらに、--role-definition-id の GUID はロールごとに固定ですが、記載の 00000000-0000-0000-0000-000000000002 が意図したロールかを念のため公式ドキュメントで再確認をお願いします。


🏁 Script executed:

#!/bin/bash
# Azure 変数の参照を探索
rg -n -C2 -g 'Makefile' -g 'infra/**' -e 'AZURE_|ARM_|TENANT|SUBSCRIPTION|CLIENT_ID|CLIENT_SECRET'
# deploy ターゲット確認
rg -n -C2 -g 'Makefile' -e 'deploy-azure|create-infra-azure|azure'

Length of output: 875


🌐 Web query:

Azure Cosmos DB の「Built-in Data Contributor」等の roleDefinitionId が正しいか確認

💡 Result:

はい。Azure Cosmos DB のデータプレーン組み込みロールの roleDefinitionId はドキュメントで固定の値が示されています。主な参照は次のとおりです。

  • Cosmos DB Built-in Data Reader — ID: 00000000-0000-0000-0000-000000000001。参照(NoSQL 版)。[1]
  • Cosmos DB Built-in Data Contributor — ID: 00000000-0000-0000-0000-000000000002。参照(NoSQL / Table 版)。[1][2]
  • これらは Cosmos DB の「データプレーン」ロール定義であり、Azure ポータル上の通常の Azure RBAC (Microsoft.Authorization) の組み込みロールとは別扱いです(割当時は Microsoft.DocumentDB の API を使う等の注意点あり)。[3]

参考:

  1. Azure Cosmos DB for NoSQL — Data plane built-in roles reference(Cosmos DB Built-in Data Reader / Contributor の ID を明記)。[1]
  2. Azure Cosmos DB for Table — Data plane built-in roles reference(同 ID を掲載)。[2]
  3. Cosmos DB のデータプレーン RBAC の割当説明(roleDefinition の取得/割当方法の例)。[3]

必要なら、あなたの環境で実際に roleDefinition を取得する az / PowerShell コマンド例と確認手順を出しますか?


README: .env に Makefile が参照する Azure 環境変数を追記してください(デプロイ失敗防止)

Makefile の deploy-azure ターゲットが AZURE_RESOURCE_GROUP と AZURE_LOCATION を参照しているため、README の前準備でこれらを .env に明記して下さい。検索では AZURE_TENANT_ID / ARM_SUBSCRIPTION_ID は infra/** や Makefile から見つかりませんでした。roleDefinitionId 00000000-0000-0000-0000-000000000002 は Cosmos DB Built-in Data Contributor の正しい ID です。参照箇所: Makefile (deploy-azure) — --resource-group (line 189, 193), --location (line 190).

🤖 Prompt for AI Agents
In README.md around lines 219 to 232, the pre-setup instructions omit
environment variables referenced by the Makefile's deploy-azure target; update
the .env instructions to include AZURE_RESOURCE_GROUP and AZURE_LOCATION (with
example values or placeholders) so the Makefile can run without failing, and
retain the note that AZURE_TENANT_ID and ARM_SUBSCRIPTION_ID were not found in
infra/** or the Makefile; also keep the existing roleDefinitionId comment as-is.

cf. https://learn.microsoft.com/ja-jp/azure/cosmos-db/how-to-setup-rbac
5. `make deploy-azure`でContainer Appsにデプロイ
6. (オプション)Application Insightsを作成
7. (オプション)Application Insightsなどの監視/ログからアラートを設定

#### デプロイ

```bash
make deploy-azure
```

#### 後処理

1. (オプション)Application Insightsを作成
2. (オプション)Application Insightsなどの監視/ログからアラートを設定
cf. https://yotiky.hatenablog.com/entry/azure_exceptionsalert
Loading