# 機能設計書 21-QA Agent

## 概要

本ドキュメントは、Liam DBシステムにおけるQA Agent（品質保証支援エージェント）の機能設計を記述するものである。QA Agentは、LangGraphフレームワークを使用したAIエージェントシステムの一部として、データベーススキーマの品質検証とテストケース生成を自動化する機能を提供する。

### 本機能の処理概要

QA Agentは、Deep Modelingワークフローの一部として、データベーススキーマの品質保証を支援するサブグラフとして機能する。

**業務上の目的・背景**：データベース設計においてスキーマの品質保証は非常に重要である。手動でのテストケース作成と検証は時間がかかり、見落としが発生しやすい。QA Agentは、AIを活用してテストケースの自動生成と検証を行うことで、設計品質の向上と開発効率の改善を実現する。

**機能の利用シーン**：PM Agentによる要件分析、DB Agentによるスキーマ設計の後に実行され、生成されたスキーマが要件を満たしているかを検証するテストケースを自動生成する。デザインセッション画面でAIチャット形式で対話しながら、スキーマの品質検証が行われる。

**主要な処理内容**：
1. 分析済み要件（AnalyzedRequirements）からテストケースを抽出
2. Map-Reduceパターンで並列にテストケースSQLを生成
3. 生成されたSQLをスキーマに適用
4. pgTapテストを実行してスキーマを検証
5. テスト失敗時の分析と再生成を実施

**関連システム・外部連携**：OpenAI API（gpt-5-mini）を使用してテストケースSQLを生成する。Supabaseデータベースに対してpgTapテストを実行し、結果を永続化する。

**権限による制御**：QA Agentの実行には認証済みユーザーであることが必要であり、組織に紐づくデザインセッション内でのみ実行可能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | デザインセッション詳細画面 | 主画面 | AIチャット形式でQA Agentがテストケース生成と検証を実行 |

## 機能種別

計算処理 / データ連携 / バリデーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| schemaData | Schema | Yes | 検証対象のデータベーススキーマ | 空でないスキーマオブジェクト |
| analyzedRequirements | AnalyzedRequirements | Yes | PM Agentが分析した要件 | goal文字列とtestcasesオブジェクトを含む |
| designSessionId | string | Yes | デザインセッションの識別子 | UUID形式 |
| messages | BaseMessage[] | No | 会話履歴 | - |

### 入力データソース

- Lead Agentから渡されるワークフロー状態（WorkflowState）
- PM Agentが生成したAnalyzedRequirements
- DB Agentが生成したスキーマデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| messages | BaseMessage[] | AIエージェントの応答メッセージ |
| schemaIssues | SchemaIssue[] | スキーマの問題点一覧 |
| generatedSqls | Map<string, string> | テストケースID別の生成SQL |
| failureAnalysis | {failedSqlTestIds: string[], failedSchemaTestIds: string[]} | テスト失敗分析結果 |

### 出力先

- ワークフロー状態の更新
- ストリーミング応答によるリアルタイムUI更新
- Supabaseへのテスト結果永続化

## 処理フロー

### 処理シーケンス

```
1. continueToRequirements（並列分岐）
   └─ 未処理の要件を抽出し、Send APIで並列タスクを生成
2. testcaseGeneration（サブグラフ）
   └─ validateSchemaRequirements → generateTestcase → invokeSaveTool のループ
3. applyGeneratedSqls
   └─ 生成されたSQLをスキーマに適用
4. validateSchema
   └─ pgTapテスト実行のためのAIメッセージ生成
5. invokeRunTestTool
   └─ runTestToolを呼び出してテスト実行
6. analyzeTestFailures
   └─ テスト結果を分析し、失敗したテストを特定
7. routeAfterAnalyzeFailures
   └─ 失敗があれば再生成、なければ終了
```

### フローチャート

```mermaid
flowchart TD
    START[開始] --> A[continueToRequirements]
    A -->|並列実行| B[testcaseGeneration]
    B --> C[applyGeneratedSqls]
    C --> D[validateSchema]
    D --> E[invokeRunTestTool]
    E --> F[analyzeTestFailures]
    F --> G{テスト失敗?}
    G -->|Yes| H[resetFailedSqlTests]
    H --> A
    G -->|No| END[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-21-01 | テストケース並列生成 | 複数のテストケースはMap-Reduceパターンで並列生成される | 常時 |
| BR-21-02 | 再試行上限 | テスト失敗時の再生成は最大3回まで | テストが失敗した場合 |
| BR-21-03 | ツール呼び出し強制 | LLMは必ずsaveTestcaseToolを呼び出す | テストケース生成時 |

### 計算ロジック

- テストケース数: `Object.values(analyzedRequirements.testcases).reduce((count, testcases) => count + testcases.length, 0)`

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| テスト結果保存 | testcases（論理） | UPDATE | テストケースの実行結果を更新 |
| SQL保存 | artifacts | INSERT/UPDATE | 生成されたSQLをアーティファクトとして保存 |

### テーブル別操作詳細

#### artifacts

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | content | 生成されたテストSQL | saveTestcaseToolで保存 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| LLM_TIMEOUT | タイムアウト | LLM応答が120秒を超過 | リトライポリシーに従い再試行 |
| INVALID_SQL | バリデーションエラー | 生成されたSQLの構文が不正 | エラーメッセージをLLMに返し再生成 |
| TEST_EXECUTION_FAILED | 実行エラー | pgTapテスト実行失敗 | 失敗分析を実行し問題を特定 |

### リトライ仕様

RETRY_POLICY（errorHandling.ts）に従い、以下のノードでリトライを実施：
- testcaseGeneration
- validateSchema
- invokeRunTestTool

## トランザクション仕様

各ノードの処理は独立しており、LangGraphのチェックポイント機能により状態が永続化される。ワークフロー全体のアトミック性はチェックポイントサーバー（SupabaseCheckpointSaver）によって保証される。

## パフォーマンス要件

- テストケース生成: 1テストケースあたり120秒以内
- 並列処理: Map-Reduceパターンにより複数テストケースを同時処理
- 再帰上限: QA_AGENT_RECURSION_LIMIT（constants.tsで定義）

## セキュリティ考慮事項

- OpenAI APIキーは環境変数で管理
- デザインセッションは組織に紐づき、認証済みユーザーのみアクセス可能
- 生成されたSQLは検証後にのみ適用

## 備考

QA AgentはDeep Modelingワークフローの品質保証フェーズを担当し、PM Agent、DB Agentと連携して動作する。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、QA Agentが扱う状態のアノテーション定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | qaAgentAnnotation.ts | `frontend/internal-packages/agent/src/qa-agent/shared/qaAgentAnnotation.ts` | QA Agentの状態定義（schemaData, analyzedRequirements, schemaIssues, generatedSqls, failureAnalysis） |
| 1-2 | testcaseAnnotation.ts | `frontend/internal-packages/agent/src/qa-agent/testcaseGeneration/testcaseAnnotation.ts` | テストケース生成サブグラフの状態定義 |
| 1-3 | analyzedRequirements.ts | `frontend/internal-packages/agent/src/schemas/analyzedRequirements.ts` | PM Agentから受け取る要件スキーマ |

**読解のコツ**: LangGraphのAnnotation.Rootはreducerパターンでstate更新を行う。reducerが`(x, y) => y ?? x`の場合は後勝ち更新。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | createQaAgentGraph.ts | `frontend/internal-packages/agent/src/qa-agent/createQaAgentGraph.ts` | QA Agentのグラフ構築とノード・エッジ定義 |

**主要処理フロー**:
1. **13行目**: StateGraphの初期化（qaAgentAnnotation使用）
2. **16-29行目**: ノードの追加（testcaseGeneration, applyGeneratedSqls, validateSchema等）
3. **34行目**: START→continueToRequirementsの条件付きエッジ
4. **49-52行目**: analyzeTestFailures後のルーティング

#### Step 3: テストケース生成サブグラフを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `frontend/internal-packages/agent/src/qa-agent/testcaseGeneration/index.ts` | テストケース生成サブグラフの構造 |
| 3-2 | generateTestcaseNode.ts | `frontend/internal-packages/agent/src/qa-agent/testcaseGeneration/generateTestcaseNode.ts` | LLMによるテストケースSQL生成 |
| 3-3 | saveToolNode.ts | `frontend/internal-packages/agent/src/qa-agent/testcaseGeneration/saveToolNode.ts` | 生成SQLの保存処理 |

**主要処理フロー**:
- **19-28行目（generateTestcaseNode.ts）**: gpt-5-miniモデルの設定（tool_choice: 'required'で強制呼び出し）
- **59-72行目**: LLMストリーミング呼び出しとタイムアウト設定（120秒）

#### Step 4: テスト実行と失敗分析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | validateSchema/index.ts | `frontend/internal-packages/agent/src/qa-agent/validateSchema/index.ts` | スキーマ検証とpgTapテスト呼び出し準備 |
| 4-2 | analyzeTestFailuresNode.ts | `frontend/internal-packages/agent/src/qa-agent/nodes/analyzeTestFailuresNode.ts` | テスト失敗の分析 |
| 4-3 | routeAfterAnalyzeFailures.ts | `frontend/internal-packages/agent/src/qa-agent/routing/routeAfterAnalyzeFailures.ts` | 再試行or終了のルーティング判断 |

**主要処理フロー**:
- **32-45行目（analyzeTestFailuresNode.ts）**: 失敗テストの抽出とfailureAnalysis構造体の生成

### プログラム呼び出し階層図

```
createGraph (createGraph.ts)
    │
    └─ qaAgentSubgraph (createQaAgentGraph.ts)
           │
           ├─ continueToRequirements [条件付き分岐]
           │      └─ Send API で並列タスク生成
           │
           ├─ testcaseGeneration (サブグラフ)
           │      ├─ validateSchemaRequirementsNode
           │      ├─ generateTestcaseNode
           │      │      └─ ChatOpenAI.stream()
           │      └─ saveToolNode
           │
           ├─ applyGeneratedSqlsNode
           │
           ├─ validateSchemaNode
           │
           ├─ invokeRunTestToolNode
           │      └─ runTestTool
           │
           └─ analyzeTestFailuresNode
                  └─ routeAfterAnalyzeFailures
```

### データフロー図

```
[入力]                    [処理]                         [出力]

analyzedRequirements ──▶ continueToRequirements ──▶ Send objects
       │
schemaData ────────────▶ generateTestcaseNode ──────▶ AIMessage (tool_call)
       │                        │
       │                        ▼
       │                 saveToolNode ──────────────▶ generatedSqls
       │
       └───────────────▶ applyGeneratedSqlsNode ───▶ 更新されたスキーマ
                                │
                                ▼
                        validateSchemaNode ─────────▶ AIMessage
                                │
                                ▼
                        invokeRunTestToolNode ──────▶ テスト結果
                                │
                                ▼
                        analyzeTestFailuresNode ────▶ failureAnalysis
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| createQaAgentGraph.ts | `frontend/internal-packages/agent/src/qa-agent/createQaAgentGraph.ts` | ソース | QA Agentグラフのエントリーポイント |
| qaAgentAnnotation.ts | `frontend/internal-packages/agent/src/qa-agent/shared/qaAgentAnnotation.ts` | ソース | 状態アノテーション定義 |
| testcaseGeneration/index.ts | `frontend/internal-packages/agent/src/qa-agent/testcaseGeneration/index.ts` | ソース | テストケース生成サブグラフ |
| generateTestcaseNode.ts | `frontend/internal-packages/agent/src/qa-agent/testcaseGeneration/generateTestcaseNode.ts` | ソース | LLMテストケース生成ノード |
| prompts.ts | `frontend/internal-packages/agent/src/qa-agent/testcaseGeneration/prompts.ts` | ソース | プロンプトテンプレート |
| saveTestcaseTool.ts | `frontend/internal-packages/agent/src/qa-agent/tools/saveTestcaseTool.ts` | ソース | テストケース保存ツール |
| analyzeTestFailuresNode.ts | `frontend/internal-packages/agent/src/qa-agent/nodes/analyzeTestFailuresNode.ts` | ソース | 失敗分析ノード |
| routeAfterAnalyzeFailures.ts | `frontend/internal-packages/agent/src/qa-agent/routing/routeAfterAnalyzeFailures.ts` | ソース | ルーティング判断 |
| validateSchema/index.ts | `frontend/internal-packages/agent/src/qa-agent/validateSchema/index.ts` | ソース | スキーマ検証ノード |
| runTestTool.ts | `frontend/internal-packages/agent/src/tools/runTestTool.ts` | ソース | テスト実行ツール |
| errorHandling.ts | `frontend/internal-packages/agent/src/utils/errorHandling.ts` | ソース | リトライポリシー定義 |
| constants.ts | `frontend/internal-packages/agent/src/constants.ts` | 設定 | QA_AGENT_RECURSION_LIMIT等 |
