@@ -11,82 +11,61 @@ F1(Extra Field Preservation)と F2(Corrupt File Isolation)は独立し
1111
1212## Tasks
1313
14- ### Task 1.1: Write F1 model-layer unit tests (Red)
15-
16- | Field | Value |
17- | -------| -------|
18- | ** File** | ` tests/test_design_models.py ` |
19- | ** Purpose** | extra フィールド保全の model 層テストを追加し、Red 状態を確立する |
20- | ** Leverage** | 既存テストの fixture パターン(` _base_design_data() ` )、` model_dump(mode="json") ` の既存テスト |
21- | ** Requirements** | REQ-1 (FR-1.1, FR-1.2) |
22- | ** Prompt** | Test Design の Unit-01〜06, Unit-12, Unit-13, Unit-16 を実装。全テストで ` model_dump(mode="json") ` を明示使用。Unit-16 は parametrize で 4 StrEnum の不正値を検証 |
23- | ** Dependencies** | None |
24-
25- ### Task 1.2: Implement ConfigDict(extra="allow") on 5 models (Green)
26-
27- | Field | Value |
28- | -------| -------|
29- | ** File** | ` src/insight_blueprint/models/design.py ` |
30- | ** Purpose** | 5つの BaseModel サブクラスに ` ConfigDict(extra="allow") ` を追加し、Task 1.1 のテストを Green にする |
31- | ** Leverage** | Pydantic v2 ` ConfigDict ` の標準機能。既存の全 validator・フィールド定義は変更なし |
32- | ** Requirements** | REQ-1 (FR-1.1, FR-1.2) |
33- | ** Prompt** | ` ExplanatoryVariable ` , ` Metric ` , ` ChartSpec ` , ` Methodology ` , ` AnalysisDesign ` の 5 クラスに ` model_config = ConfigDict(extra="allow") ` を追加。import に ` ConfigDict ` を追加。既存コードは一切変更しない |
34- | ** Dependencies** | 1.1 |
35-
36- ### Task 1.3: Write F1 service-layer verification tests (Verification)
37-
38- | Field | Value |
39- | -------| -------|
40- | ** File** | ` tests/test_designs.py ` |
41- | ** Purpose** | ` update_design() ` 経由の extra フィールド round-trip と ` referenced_knowledge ` merge との相互作用を検証する。Task 1.2 の model 変更のみで Green が期待される(service 層の変更なし) |
42- | ** Leverage** | 既存の ` service ` fixture、` write_yaml ` / ` read_yaml ` ヘルパー |
43- | ** Requirements** | REQ-1 (FR-1.3, FR-1.4) |
44- | ** Prompt** | Test Design の Unit-03, Unit-14, Integ-01 を実装。Unit-03: YAML に手動で extra field を追加後 ` update_design() ` で保持確認。Unit-14: ` referenced_knowledge ` merge 後に extra 保持確認。Integ-01: top-level + metrics-level の extra が YAML round-trip で保持される統合テスト。service 層の変更なしで全テスト Green になることを確認 |
45- | ** Dependencies** | 1.2 |
46-
47- ### Task 2.1: Write F2 service-layer unit tests (Red)
48-
49- | Field | Value |
50- | -------| -------|
51- | ** File** | ` tests/test_designs.py ` |
52- | ** Purpose** | corrupt ファイル隔離の service 層テストを追加し、Red 状態を確立する |
53- | ** Leverage** | 既存の ` service ` fixture、` write_yaml ` による corrupt ファイル直接書き込み。` yaml_syntax_error ` パターンは YAML ファイルに不正構文を直接書き込む(` write_yaml ` ではなく ` Path.write_text ` ) |
54- | ** Requirements** | REQ-2 (FR-2.1, FR-2.2, FR-2.3) |
55- | ** Prompt** | Test Design の Unit-07〜11, Unit-15 を実装。Unit-15 は pytest.mark.parametrize で 5 corrupt パターン(yaml_syntax_error, non_dict_root, missing_required, invalid_enum, invalid_nested_enum)を検証。` yaml_syntax_error ` と ` non_dict_root ` は ` Path.write_text() ` で直接ファイル書き込み(` read_yaml() ` レベルでエラーを起こすため)。Unit-08 は ` caplog ` で warning ログ出力を確認。Unit-10 は ` pytest.raises(ValidationError) ` |
56- | ** Dependencies** | None |
57-
58- ### Task 2.2: Implement corrupt file isolation in list_designs (Green)
59-
60- | Field | Value |
61- | -------| -------|
62- | ** File** | ` src/insight_blueprint/core/designs.py ` |
63- | ** Purpose** | ` list_designs() ` に per-file try/except + warning ログを追加し、Task 2.1 のテストを Green にする |
64- | ** Leverage** | 既存の ` list_designs() ` ループ構造に try/except を追加するだけ。` logging ` 標準ライブラリ |
65- | ** Requirements** | REQ-2 (FR-2.1, FR-2.2) |
66- | ** Prompt** | ` list_designs() ` の try/except を ` read_yaml(file_path) ` から ` AnalysisDesign(**data) ` まで包含するスコープで追加。理由: ` yaml_syntax_error ` は ` read_yaml() ` 段階で ` YAMLError ` を raise するため、` AnalysisDesign(**data) ` だけを囲むと不十分。` except Exception as exc ` で catch し(` YAMLError ` , ` ValidationError ` , ` TypeError ` 等を一括補足)、` logger.warning("Skipping corrupt design file %s: %s", file_path.name, exc) ` を出力して ` continue ` 。module-level で ` logger = logging.getLogger(__name__) ` を定義。` get_design() ` は変更なし(ValidationError はそのまま伝播) |
67- | ** Dependencies** | 2.1 |
68-
69- ### Task 2.3: Write F2 REST API test + implement ValidationError handler (Red → Green)
70-
71- | Field | Value |
72- | -------| -------|
73- | ** File** | ` tests/test_web.py ` , ` src/insight_blueprint/web.py ` |
74- | ** Purpose** | REST API で corrupt design → 422 レスポンスを返すテストと実装 |
75- | ** Leverage** | 既存の exception handler パターン(` ValueError → 400 ` )、既存の TestClient fixture |
76- | ** Requirements** | REQ-2 (FR-2.4) |
77- | ** Prompt** | Red: ` test_get_design_corrupt_returns_422 ` を追加。corrupt YAML を直接書き込み、` GET /api/designs/{id} ` で 422 + ` error ` フィールド確認。Green: ` web.py ` に ` @app.exception_handler(ValidationError) ` を追加。` from pydantic import ValidationError ` を import(web.py では ` from pydantic import BaseModel, Field ` が既にある箇所に追加)。status_code=422, content=` {"error": f"Invalid design data: {exc.error_count()} validation error(s)"} ` |
78- | ** Dependencies** | 2.1 |
79-
80- ### Task 3.1: Run regression tests + coverage confirmation
81-
82- | Field | Value |
83- | -------| -------|
84- | ** File** | (テスト実行のみ、ファイル変更なし) |
85- | ** Purpose** | 既存 681 テスト + 新規 18 テストの全 pass と ` models/design.py ` coverage 100% を確認する |
86- | ** Leverage** | ` uv run pytest -v ` + ` uv run pytest --cov=src/insight_blueprint/models/design --cov-report=term-missing ` |
87- | ** Requirements** | NFR-B.1, NFR-B.2, NFR-B.3 |
88- | ** Prompt** | ` uv run pytest -v ` で全テスト pass を確認。` uv run pytest --cov=src/insight_blueprint/models/design --cov-report=term-missing ` で design.py のカバレッジ 100% 維持を確認。` uv run ruff check . ` でリントエラーなしを確認 |
89- | ** Dependencies** | 1.3, 2.3 |
14+ - [x] 1.1. Write F1 model-layer unit tests (Red)
15+ - File: ` tests/test_design_models.py `
16+ - Purpose: extra フィールド保全の model 層テストを追加し、Red 状態を確立する
17+ - Leverage: 既存テストの fixture パターン(` _base_design_data() ` )、` model_dump(mode="json") ` の既存テスト
18+ - Requirements: REQ-1 (FR-1.1, FR-1.2)
19+ - Prompt: Test Design の Unit-01〜06, Unit-12, Unit-13, Unit-16 を実装。全テストで ` model_dump(mode="json") ` を明示使用。Unit-16 は parametrize で 4 StrEnum の不正値を検証
20+ - Dependencies: None
21+
22+ - [x] 1.2. Implement ConfigDict(extra="allow") on 5 models (Green)
23+ - File: ` src/insight_blueprint/models/design.py `
24+ - Purpose: 5つの BaseModel サブクラスに ` ConfigDict(extra="allow") ` を追加し、Task 1.1 のテストを Green にする
25+ - Leverage: Pydantic v2 ` ConfigDict ` の標準機能。既存の全 validator・フィールド定義は変更なし
26+ - Requirements: REQ-1 (FR-1.1, FR-1.2)
27+ - Prompt: ` ExplanatoryVariable ` , ` Metric ` , ` ChartSpec ` , ` Methodology ` , ` AnalysisDesign ` の 5 クラスに ` model_config = ConfigDict(extra="allow") ` を追加。import に ` ConfigDict ` を追加。既存コードは一切変更しない
28+ - Dependencies: 1.1
29+
30+ - [x] 1.3. Write F1 service-layer verification tests (Verification)
31+ - File: ` tests/test_designs.py `
32+ - Purpose: ` update_design() ` 経由の extra フィールド round-trip と ` referenced_knowledge ` merge との相互作用を検証する。Task 1.2 の model 変更のみで Green が期待される(service 層の変更なし)
33+ - Leverage: 既存の ` service ` fixture、` write_yaml ` / ` read_yaml ` ヘルパー
34+ - Requirements: REQ-1 (FR-1.3, FR-1.4)
35+ - Prompt: Test Design の Unit-03, Unit-14, Integ-01 を実装。Unit-03: YAML に手動で extra field を追加後 ` update_design() ` で保持確認。Unit-14: ` referenced_knowledge ` merge 後に extra 保持確認。Integ-01: top-level + metrics-level の extra が YAML round-trip で保持される統合テスト。service 層の変更なしで全テスト Green になることを確認
36+ - Dependencies: 1.2
37+
38+ - [x] 2.1. Write F2 service-layer unit tests (Red)
39+ - File: ` tests/test_designs.py `
40+ - Purpose: corrupt ファイル隔離の service 層テストを追加し、Red 状態を確立する
41+ - Leverage: 既存の ` service ` fixture、` write_yaml ` による corrupt ファイル直接書き込み。` yaml_syntax_error ` パターンは YAML ファイルに不正構文を直接書き込む(` write_yaml ` ではなく ` Path.write_text ` )
42+ - Requirements: REQ-2 (FR-2.1, FR-2.2, FR-2.3)
43+ - Prompt: Test Design の Unit-07〜11, Unit-15 を実装。Unit-15 は pytest.mark.parametrize で 5 corrupt パターン(yaml_syntax_error, non_dict_root, missing_required, invalid_enum, invalid_nested_enum)を検証。` yaml_syntax_error ` と ` non_dict_root ` は ` Path.write_text() ` で直接ファイル書き込み(` read_yaml() ` レベルでエラーを起こすため)。Unit-08 は ` caplog ` で warning ログ出力を確認。Unit-10 は ` pytest.raises(ValidationError) `
44+ - Dependencies: None
45+
46+ - [x] 2.2. Implement corrupt file isolation in list_designs (Green)
47+ - File: ` src/insight_blueprint/core/designs.py `
48+ - Purpose: ` list_designs() ` に per-file try/except + warning ログを追加し、Task 2.1 のテストを Green にする
49+ - Leverage: 既存の ` list_designs() ` ループ構造に try/except を追加するだけ。` logging ` 標準ライブラリ
50+ - Requirements: REQ-2 (FR-2.1, FR-2.2)
51+ - Prompt: ` list_designs() ` の try/except を ` read_yaml(file_path) ` から ` AnalysisDesign(**data) ` まで包含するスコープで追加。理由: ` yaml_syntax_error ` は ` read_yaml() ` 段階で ` YAMLError ` を raise するため、` AnalysisDesign(**data) ` だけを囲むと不十分。` except Exception as exc ` で catch し、` logger.warning("Skipping corrupt design file %s: %s", file_path.name, exc) ` を出力して ` continue ` 。module-level で ` logger = logging.getLogger(__name__) ` を定義。` get_design() ` は変更なし(ValidationError はそのまま伝播)
52+ - Dependencies: 2.1
53+
54+ - [x] 2.3. Write F2 REST API test + implement ValidationError handler (Red → Green)
55+ - File: ` tests/test_web.py ` , ` src/insight_blueprint/web.py `
56+ - Purpose: REST API で corrupt design → 422 レスポンスを返すテストと実装
57+ - Leverage: 既存の exception handler パターン(` ValueError → 400 ` )、既存の TestClient fixture
58+ - Requirements: REQ-2 (FR-2.4)
59+ - Prompt: Red: ` test_get_design_corrupt_returns_422 ` を追加。corrupt YAML を直接書き込み、` GET /api/designs/{id} ` で 422 + ` error ` フィールド確認。Green: ` web.py ` に ` @app.exception_handler(ValidationError) ` を追加。status_code=422, content=` {"error": f"Invalid design data: {exc.error_count()} validation error(s)"} `
60+ - Dependencies: 2.1
61+
62+ - [x] 3.1. Run regression tests + coverage confirmation
63+ - File: (テスト実行のみ、ファイル変更なし)
64+ - Purpose: 既存 681 テスト + 新規 25 テストの全 pass と ` models/design.py ` coverage 100% を確認する
65+ - Leverage: ` uv run pytest -v ` + ` uv run pytest --cov=src/insight_blueprint/models/design --cov-report=term-missing `
66+ - Requirements: NFR-B.1, NFR-B.2, NFR-B.3
67+ - Prompt: ` uv run pytest -v ` で全テスト pass を確認。` uv run pytest --cov=src/insight_blueprint/models/design --cov-report=term-missing ` で design.py のカバレッジ 100% 維持を確認。` uv run ruff check . ` でリントエラーなしを確認
68+ - Dependencies: 1.3, 2.3
9069
9170---
9271
@@ -119,3 +98,25 @@ Task 3.1 は両トラック完了後に実行。
11998| design.md の ` GET /api/designs ` corrupt 混在テストが test-design.md に未反映 | Important | Unit-07 で service 層をカバー済み。REST 層は ` list_designs() ` をそのまま呼ぶだけなので service テストで十分。Integration テスト追加は不要と判断 |
12099| Task 2.1 が大きい(分割検討) | Moderate | parametrize で共通 fixture を使うため分割すると重複が増える。現状維持 |
121100| Task 2.3 の依存が 2.2 だが独立可能 | Important | 依存を 2.1 に変更(REST handler は service 実装と独立) |
101+
102+ ## Team Review Results (2026-03-08)
103+
104+ ** Commit** : ` 8f156f6 ` (実装) + ` 382c262 ` (review 修正)
105+
106+ | カテゴリ | Critical | High | Medium | Low |
107+ | ---------| ----------| ------| --------| -----|
108+ | Security | 0 | 0 | 3 | 2 |
109+ | Quality | 0 | 0 | 1 | 7 |
110+ | Test | - | - | 2 | 3 |
111+ | Requirements | 12/12 ACs Covered | 11/11 NFRs Covered | - | - |
112+
113+ ### 修正済み (commit 382c262)
114+
115+ - ** S-05** : ` web.py ` の ` validation_error_handler ` に handler 優先順序の NOTE コメント追加
116+ - ** T-04** : ` test_list_designs_with_corrupt_returns_valid_only ` テスト追加 (707 tests)
117+
118+ ### 対応不要と判断
119+
120+ - ** S-02** : ` except Exception ` スコープ — design doc で意図的に選択。YAMLError/ValidationError/TypeError 一括捕捉のため
121+ - ** S-01** : ` extra="allow" ` 蓄積リスク — REST API request model は extra="allow" なし。侵入経路はローカルのみ
122+ - ** Q-01** : テスト ID 重複 — docstring のみ、実害なし
0 commit comments