# アプリケーション

以下のアプリケーションを実装しています。

- クライアントAPI
- 管理API
- コントラクトAPI
- Cognito トークン生成前トリガー（管理APIのアクセストークン生成時にテナントIDをカスタムクレームとして追加する）
- Cognito トークン生成前トリガー（コントラクトAPIのアクセストークン生成時にコントラクトプロバイダーIDをカスタムクレームとして追加する）
- Cognito カスタムメッセージトリガー（管理APIのパスワードリセット・管理者によるユーザー作成時に送信されるメールの件名/本文をカスタマイズする）

## コードマップ

```text
backend/
├── src/
│   ├── __types/                        # グローバルで利用する型
│   │   ├── error_responses.py          # エラーレスポンス関連の型定義
│   │   ├── errors.py                   # エラー関連の型定義
│   │   └── index.py                    # リテラルやDTOなどの一般的な型定義
│   ├── domain/                         # ドメイン層
│   │   ├── entities/                   # エンティティ層
│   │   │   └── *.py                    # エンティティのデータ構造およびビジネスルールを定義
│   │   └── services/                   # サービス層
│   │       └── *_service.py            # ドメインサービスの処理を定義
│   ├── infrastructure/                 # インフラストラクチャ層
│   │   ├── database/                   # データベース層
│   │   │   └── *.py             　　　　# DBセッションに対するテナントRLS設定など、DBアクセス時の制御処理を定義
│   │   ├── clients/                    # クライアント層（外部サービス通信）
│   │   │   └── *_client.py             # 外部サービスへの接続クライアント
│   │   ├── repositories/               # リポジトリ層
│   │   │   ├── *_repository.py         # 永続化データの取得/更新を定義
│   │   │   └── *_builder.py            # 複雑な操作命令の分割
│   │   └── *.py                        # 外部I/Oアダプタ（e.g. キュー投入、ストレージ保存）
│   ├── routers/                        # ルーター層 ※ 認可の方式等が異なるためエンドポイント毎にディレクトリ分割
│   │   ├── client/                     # クライアントAPIのルーター層
│   │   ├── management/                 # 管理APIのルーター層
│   │   │   ├── authorizer/             # 認可を行うモジュール群
│   │   │   ├── *_router.py             # インターフェース定義およびユースケースの呼び出し
│   │   │   ├── headers.py              # ヘッダー定義
│   │   │   ├── description.py          # API共通のドキュメント
│   │   │   └── connection.py           # DB接続を行うモジュール
│   │   ├── contract/                   # コントラクトAPIのルーター層
│   │   │   ├── *_router.py             # インターフェース定義およびユースケースの呼び出し
│   │   │   ├── description.py          # API共通のドキュメント
│   │   │   ├── authorizer.py           # 認可を行うモジュール
│   │   │   └── connection.py           # DB接続を行うモジュール
│   │   ├── *_helpers.py                # ルーター層で利用する入出力整形・認証補助などの共通処理
│   │   └── http_errors.py              # 共通HTTPエラーハンドリング
│   ├── tools/                          # 開発/運用向けユーティリティ
│   ├── usecases/                       # ユースケース層
│   │   └── *_usecase.py                # 各操作の手続きを定義
│   ├── const.py                        # 定数定義
│   ├── settings.py                     # 環境変数の定義
│   ├── logger.py                       # ログ設定
│   ├── tracer.py                       # トレーシング設定
│   ├── client_api.py                   # クライアントAPIのエントリーポイント
│   ├── management_api.py               # 管理APIのエントリーポイント
│   ├── contract_api.py                 # コントラクトAPIのエントリーポイント
│   ├── *_trigger.py                    # Cognitoトリガー用のエントリーポイント
│   └── usage_event_consumer.py         # usage_eventキューのコンシューマー
├── tests/                              # テストコード
│   ├── unit/                           # 単体テスト
│   ├── integration/                    # 結合テスト
│   └── requirements.txt                # テスト実行に必要なパッケージ一覧
├── README.md                           # backend開発ガイド
└── requirements.txt                    # アプリケーションの実行に必要なパッケージ一覧
```

## API定義

- [クライアントAPI](https://ai-unit.lab.works-hi.co.jp/redoc)
- [管理API](https://api.management.ai-unit.lab.works-hi.co.jp/redoc)
- [コントラクトAPI](https://contract.ai-unit.lab.works-hi.co.jp/redoc)

※ ユーザー/パスワードはdev/dev

## テスト

### VSCode テストエクスプローラー

サイドバーのテストエクスプローラー（ビーカーアイコン）から、テストの実行・デバッグが可能。

- テストツリーから個別のテスト関数、テストクラス、ファイル単位で実行できる
- ブレークポイントを設定した状態でデバッグ実行が可能
- 結合テストを実行する場合は、事前にDBが起動していること（後述）

※ 設定は `.vscode/settings.json` の `python.testing.*` で定義済み

### 単体テスト

```bash
pytest tests/unit/
```

外部依存はすべてモックで差し替えるため、DB起動は不要。

### 結合テスト

```bash
# DB起動（初回はマイグレーション・フィクスチャ投入が自動実行される）
docker compose down -v && docker compose up db

# テスト実行
pytest tests/integration
```

- devcontainer内ではDB接続情報（`POSTGRES_*`）が環境変数として自動設定されている
- フィクスチャの再投入が必要な場合は `fixture` コマンドを実行する
- テスト設計の詳細は [結合テストガイドライン](../docs/development/backend/backend_integration_test_guideline.md) を参照

### E2Eテスト（Postman）

PostmanによるアドホックなE2Eテスト

TBD

#### 　手順

1. テストを行いたいエンドポイントの`/openapi.json`にブラウザでアクセスし、定義をダウンロード

##### 補足情報

ローカル環境のクライアントAPIキー: `test.gen_ai_profile.test.46b7e57d4185a394eb5a90ea.m-sx73A01Z2wizMAvXeb9sWEHYv5VtOS-wLxVSbyTHg`
