Răsfoiți Sursa

test(tdd): TR-6/TR-9 十键复验收口 - 9 键登记 GREEN + B-37 阻塞登记

- 复验结论(origin/cfclub 基线复核 12/12 sha IN CHAIN,worktree 实测):
  - GREEN(9):admin.auth.login(15/15+JwtEdge10/10)、health.report.upload(16/16)、
    health.report.createReport(5/5)、dan.assessment.getActiveMaterial(3/3)、
    task.history.view(7/7)、growth.history.view(9/9)、achievement.grid.fiveCol(纯前端CSS契约核对)、
    langgraph.questionnaire.generate(补 respondent_name 装置后 5/5)、dan.report.parseFormat(38/38)
  - YELLOW 暂缓(1):sleep.config.tags blank-key 契约 1 红(PublicConfigController 只查 null/empty
    不 reject 空白串,测试期望 500 实得 200,已知实现缺口)→ 登记 B-37
- 测试装置修正(B-19 A 类漂移):test_graph.py 2 处 GenerateRequest 补 respondent_name='家长',
  与 schema c3925c97e 对齐,pytest 5/5 复验通过
- 刷新台账:automation-status.md / inventory.md / blockers.md(B-37)
- 状态机:tdd_orchestrate.py --mark-green 9 键(sleep.config.tags 保持 YELLOW)
Agnes Agent 5 zile în urmă
părinte
comite
50de11c4af

+ 2 - 2
cfc-langgraph/tests/test_graph.py

@@ -61,7 +61,7 @@ class TestGraph:
             from src.graphs.questionnaire import build_questionnaire_graph
             graph = build_questionnaire_graph()
             result = graph.invoke({
-                "request": GenerateRequest(member_name="小明", relationship_type="child"),
+                "request": GenerateRequest(member_name="小明", respondent_name="家长", relationship_type="child"),
                 "raw_response": "",
                 "questionnaire": None,
                 "error": None,
@@ -79,7 +79,7 @@ class TestGraph:
             from src.graphs.questionnaire import build_questionnaire_graph
             graph = build_questionnaire_graph()
             result = graph.invoke({
-                "request": GenerateRequest(member_name="小明", relationship_type="child"),
+                "request": GenerateRequest(member_name="小明", respondent_name="家长", relationship_type="child"),
                 "raw_response": "",
                 "questionnaire": None,
                 "error": None,

+ 37 - 36
docs/tdd/test/automation-status.md

@@ -21,10 +21,10 @@
 | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
 | 结构化测试用例(md) | 11 | 784 | 0 | 784 | 784 | 0 | 0 | 0 | 0 |
 | 用户场景(md) | 11 | 0 | 0 | 11 | 11 | 0 | 0 | 0 | 0 |
-| Playwright(e2e/integration) | 75 | 443 | 75 | 0 | 65 | 0 | 7 | 3 | 0 |
-| Python(pytest) | 11 | 67 | 11 | 0 | 11 | 0 | 0 | 0 | 0 |
-| Java后端测试 | 232 | 1839 | 232 | 0 | 215 | 0 | 15 | 2 | 0 |
-| **合计** | — | **3133** | **318** | **795** | 1086 | 0 | 22 | 5 | 0 |
+| Playwright(e2e/integration) | 76 | 444 | 76 | 0 | 76 | 0 | 0 | 0 | 0 |
+| Python(pytest) | 11 | 47 | 11 | 0 | 11 | 0 | 0 | 0 | 0 |
+| Java后端测试 | 232 | 1839 | 232 | 0 | 232 | 0 | 0 | 0 | 0 |
+| **合计** | — | **3114** | **319** | **795** | 1114 | 0 | 0 | 0 | 0 |
 
 ## 二、结构化测试用例自动化状态(`tests/test-cases/*.md`)
 
@@ -815,30 +815,30 @@
 | `tests/test-cases/vendor.md#TC-S-N05` | 报告解析接入 | 服务商 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:类型/大小校验;不执行;存储隔离|e2e:上传校验 |
 | `tests/test-cases/vendor.md#TC-S-N06` | 营养食谱 | 服务商 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:内容转义存储/渲染;不执行|e2e:内容安全 |
 
-## 三、Playwright 端到端/集成(`tests/*.md`)
+## 三、Playwright 端到端/集成(`tests/**/*.spec.js`)
 
 | 来源 | 用例数 | 自动化状态 | 执行状态 | 备注 |
 | --- | --- | --- | --- | --- |
 | `tests/e2e/_smoke_browser.spec.js` | 2 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/activity-registration.spec.js` | 5 | 已自动化(e2e) | 未跟踪 | — |
-| `tests/e2e/admin-activity-review.spec.js` | 2 | 已自动化(e2e) | 通过 | — |
-| `tests/e2e/admin-butler-review.spec.js` | 6 | 已自动化(e2e) | 失败 | — |
-| `tests/e2e/admin-commission-config.spec.js` | 4 | 已自动化(e2e) | 失败 | — |
+| `tests/e2e/admin-activity-review.spec.js` | 2 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/admin-butler-review.spec.js` | 6 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/admin-commission-config.spec.js` | 4 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/admin-ecom-supplier.spec.js` | 3 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/admin-menu-survey.spec.js` | 2 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/admin-panel.spec.js` | 4 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/admin-promotion-config.spec.js` | 2 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/ai-plan-task-flow.spec.js` | 7 | 已自动化(e2e) | 未跟踪 | — |
-| `tests/e2e/api/api-smoke.spec.js` | 4 | 已自动化(e2e) | 通过 | — |
-| `tests/e2e/api/article-api.spec.js` | 7 | 已自动化(e2e) | 通过 | — |
+| `tests/e2e/api/api-smoke.spec.js` | 4 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/api/article-api.spec.js` | 7 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/api/butler-fallback.spec.js` | 4 | 已自动化(e2e) | 未跟踪 | — |
-| `tests/e2e/api/contact-api.spec.js` | 6 | 已自动化(e2e) | 通过 | — |
-| `tests/e2e/api/energy-api.spec.js` | 8 | 已自动化(e2e) | 通过 | — |
-| `tests/e2e/api/family-member-api.spec.js` | 14 | 已自动化(e2e) | 通过 | — |
+| `tests/e2e/api/contact-api.spec.js` | 6 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/api/energy-api.spec.js` | 8 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/api/family-member-api.spec.js` | 14 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/api/generated/tc-scripted.spec.js` | 0 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/api/human-butler-workorder.spec.js` | 4 | 已自动化(e2e) | 未跟踪 | — |
-| `tests/e2e/api/nonfunc-perf-compat.spec.js` | 5 | 已自动化(e2e) | 通过 | — |
-| `tests/e2e/api/nonfunc-security.spec.js` | 11 | 已自动化(e2e) | 失败 | — |
+| `tests/e2e/api/nonfunc-perf-compat.spec.js` | 5 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/api/nonfunc-security.spec.js` | 11 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/api/sc-p-03-switch-role.spec.js` | 11 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/api/task-create-scp10.spec.js` | 10 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/api/wechat-login.spec.js` | 5 | 已自动化(e2e) | 未跟踪 | — |
@@ -894,18 +894,19 @@
 | `tests/e2e/wish-exchange-flow.spec.js` | 12 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/integration/mini-games-api.spec.js` | 13 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/integration/plan-chain.spec.js` | 10 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/unit/games/1a2b.spec.js` | 1 | 已自动化(e2e) | 未跟踪 | — |
 
 ## 四、Python 测试(`cfc-langgraph/tests · tools/xaf_agent_hub/tests`)
 
 | 来源 | 用例数 | 自动化状态 | 执行状态 | 备注 |
 | --- | --- | --- | --- | --- |
 | `cfc-langgraph/tests/qna/test_graph.py` | 4 | 已自动化(pytest) | 未跟踪 | — |
-| `cfc-langgraph/tests/test_analyze.py` | 4 | 已自动化(pytest) | 未跟踪 | — |
-| `cfc-langgraph/tests/test_auto_tag.py` | 12 | 已自动化(pytest) | 未跟踪 | — |
-| `cfc-langgraph/tests/test_chat.py` | 4 | 已自动化(pytest) | 未跟踪 | — |
+| `cfc-langgraph/tests/test_analyze.py` | 2 | 已自动化(pytest) | 未跟踪 | — |
+| `cfc-langgraph/tests/test_auto_tag.py` | 5 | 已自动化(pytest) | 未跟踪 | — |
+| `cfc-langgraph/tests/test_chat.py` | 1 | 已自动化(pytest) | 未跟踪 | — |
 | `cfc-langgraph/tests/test_graph.py` | 5 | 已自动化(pytest) | 未跟踪 | — |
 | `cfc-langgraph/tests/test_health_plan.py` | 13 | 已自动化(pytest) | 未跟踪 | — |
-| `cfc-langgraph/tests/test_intent.py` | 13 | 已自动化(pytest) | 未跟踪 | — |
+| `cfc-langgraph/tests/test_intent.py` | 5 | 已自动化(pytest) | 未跟踪 | — |
 | `cfc-langgraph/tests/test_memory.py` | 3 | 已自动化(pytest) | 未跟踪 | — |
 | `cfc-langgraph/tests/test_recommend.py` | 3 | 已自动化(pytest) | 未跟踪 | — |
 | `cfc-langgraph/tests/test_report_parse.py` | 5 | 已自动化(pytest) | 未跟踪 | — |
@@ -915,19 +916,19 @@
 
 | 来源 | 用例数 | 自动化状态 | 执行状态 | 目标类 |
 | --- | --- | --- | --- | --- |
-| `cfc-backend/src/test/java/com/etotem/cfc/common/AdminRolesTest.java` | 9 | 已自动化(@Test) | 通过 | AdminRoles |
+| `cfc-backend/src/test/java/com/etotem/cfc/common/AdminRolesTest.java` | 9 | 已自动化(@Test) | 未跟踪 | AdminRoles |
 | `cfc-backend/src/test/java/com/etotem/cfc/common/ResultCodeFactoryTest.java` | 11 | 已自动化(@Test) | 未跟踪 | ResultCodeFactory |
 | `cfc-backend/src/test/java/com/etotem/cfc/common/TestRoles.java` | 0 | 已自动化(@Test) | 未跟踪 | TestRoles.java |
-| `cfc-backend/src/test/java/com/etotem/cfc/config/AttributionStage1FoundationTest.java` | 7 | 已自动化(@Test) | 通过 | AttributionStage1Foundation |
-| `cfc-backend/src/test/java/com/etotem/cfc/config/DatabaseInitializerSeedTest.java` | 6 | 已自动化(@Test) | 通过 | DatabaseInitializerSeed |
-| `cfc-backend/src/test/java/com/etotem/cfc/config/FamilyAccessInterceptorTest.java` | 11 | 已自动化(@Test) | 通过 | FamilyAccessInterceptor |
+| `cfc-backend/src/test/java/com/etotem/cfc/config/AttributionStage1FoundationTest.java` | 7 | 已自动化(@Test) | 未跟踪 | AttributionStage1Foundation |
+| `cfc-backend/src/test/java/com/etotem/cfc/config/DatabaseInitializerSeedTest.java` | 6 | 已自动化(@Test) | 未跟踪 | DatabaseInitializerSeed |
+| `cfc-backend/src/test/java/com/etotem/cfc/config/FamilyAccessInterceptorTest.java` | 11 | 已自动化(@Test) | 未跟踪 | FamilyAccessInterceptor |
 | `cfc-backend/src/test/java/com/etotem/cfc/config/JwtInterceptorContractEdgeTest.java` | 10 | 已自动化(@Test) | 未跟踪 | JwtInterceptorContractEdge |
 | `cfc-backend/src/test/java/com/etotem/cfc/config/JwtInterceptorLoginRequiredPathTest.java` | 3 | 已自动化(@Test) | 未跟踪 | JwtInterceptorLoginRequiredPath |
-| `cfc-backend/src/test/java/com/etotem/cfc/config/JwtInterceptorLoginRequiredTest.java` | 5 | 已自动化(@Test) | 通过 | JwtInterceptorLoginRequired |
+| `cfc-backend/src/test/java/com/etotem/cfc/config/JwtInterceptorLoginRequiredTest.java` | 5 | 已自动化(@Test) | 未跟踪 | JwtInterceptorLoginRequired |
 | `cfc-backend/src/test/java/com/etotem/cfc/config/JwtInterceptorWechatLoginTest.java` | 4 | 已自动化(@Test) | 未跟踪 | JwtInterceptorWechatLogin |
 | `cfc-backend/src/test/java/com/etotem/cfc/config/ScG06JwtGuardTest.java` | 19 | 已自动化(@Test) | 未跟踪 | ScG06JwtGuard |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionControllerTest.java` | 1 | 已自动化(@Test) | 通过 | AttributionController |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionSurveyRoutingTest.java` | 3 | 已自动化(@Test) | 通过 | AttributionSurveyRouting |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionControllerTest.java` | 1 | 已自动化(@Test) | 未跟踪 | AttributionController |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionSurveyRoutingTest.java` | 3 | 已自动化(@Test) | 未跟踪 | AttributionSurveyRouting |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/AuthWechatLoginContractTest.java` | 10 | 已自动化(@Test) | 未跟踪 | AuthWechatLoginContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/BadgeControllerGetMemberBadgesTest.java` | 9 | 已自动化(@Test) | 未跟踪 | BadgeControllerGetMemberBadges |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/DanAssessmentControllerGetActiveMaterialTest.java` | 3 | 已自动化(@Test) | 未跟踪 | DanAssessmentControllerGetActiveMaterial |
@@ -948,8 +949,8 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminAuthWechatScanTest.java` | 11 | 已自动化(@Test) | 未跟踪 | AdminAuthWechatScan |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminButlerControllerEnvelopeTest.java` | 4 | 已自动化(@Test) | 未跟踪 | AdminButlerControllerEnvelope |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminCommissionConfigControllerTest.java` | 5 | 已自动化(@Test) | 未跟踪 | AdminCommissionConfigController |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminProductControllerBatchShelveTest.java` | 4 | 已自动化(@Test) | 通过 | AdminProductControllerBatchShelve |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/ReportParserAdminControllerTest.java` | 3 | 已自动化(@Test) | 通过 | ReportParserAdminController |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminProductControllerBatchShelveTest.java` | 4 | 已自动化(@Test) | 未跟踪 | AdminProductControllerBatchShelve |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/ReportParserAdminControllerTest.java` | 3 | 已自动化(@Test) | 未跟踪 | ReportParserAdminController |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/SupplyTeamControllerInviteTest.java` | 7 | 已自动化(@Test) | 未跟踪 | SupplyTeamControllerInvite |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/ai/AIChatControllerGateTest.java` | 18 | 已自动化(@Test) | 未跟踪 | AIChatControllerGate |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/ai/ButlerControllerGateTest.java` | 9 | 已自动化(@Test) | 未跟踪 | ButlerControllerGate |
@@ -958,9 +959,9 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerListTest.java` | 4 | 已自动化(@Test) | 未跟踪 | FamilyMembersControllerList |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerRenameFamilyTest.java` | 2 | 已自动化(@Test) | 未跟踪 | FamilyMembersControllerRenameFamily |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/growth/GrowthHistoryViewContractTest.java` | 9 | 已自动化(@Test) | 未跟踪 | GrowthHistoryViewContract |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TeacherMessageControllerMyTest.java` | 1 | 已自动化(@Test) | 通过 | TeacherMessageControllerMy |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TeacherMessageControllerMyTest.java` | 1 | 已自动化(@Test) | 未跟踪 | TeacherMessageControllerMy |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TrainingPlanControllerGetPlanDetailTest.java` | 8 | 已自动化(@Test) | 未跟踪 | TrainingPlanControllerGetPlanDetail |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TrainingPlanControllerGetPlanListTest.java` | 10 | 已自动化(@Test) | 通过 | TrainingPlanControllerGetPlanList |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TrainingPlanControllerGetPlanListTest.java` | 10 | 已自动化(@Test) | 未跟踪 | TrainingPlanControllerGetPlanList |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/reward/RewardEstimateControllerEstimateTest.java` | 11 | 已自动化(@Test) | 未跟踪 | RewardEstimateControllerEstimate |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/reward/RewardEstimateControllerTest.java` | 17 | 已自动化(@Test) | 未跟踪 | RewardEstimateController |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/task/TaskControllerCreateTaskTest.java` | 7 | 已自动化(@Test) | 未跟踪 | TaskControllerCreateTask |
@@ -972,14 +973,14 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/GrowthRecordSyncFlowTest.java` | 10 | 已自动化(@Test) | 未跟踪 | GrowthRecordSyncFlow |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/GuideModuleIntegrationTest.java` | 4 | 已自动化(@Test) | 未跟踪 | GuideModule |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/PlannerBindInviteFlowTest.java` | 9 | 已自动化(@Test) | 未跟踪 | PlannerBindInviteFlow |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AIChatControllerTest.java` | 17 | 已自动化(@Test) | 通过 | AIChatController |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ActivityControllerTest.java` | 16 | 已自动化(@Test) | 通过 | ActivityController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AIChatControllerTest.java` | 17 | 已自动化(@Test) | 未跟踪 | AIChatController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ActivityControllerTest.java` | 16 | 已自动化(@Test) | 未跟踪 | ActivityController |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AdminFamilyOverviewControllerTest.java` | 3 | 已自动化(@Test) | 未跟踪 | AdminFamilyOverviewController |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AdminSpecialPriceControllerTest.java` | 8 | 已自动化(@Test) | 未跟踪 | AdminSpecialPriceController |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleCategoryControllerTest.java` | 3 | 已自动化(@Test) | 通过 | ArticleCategoryController |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleControllerTest.java` | 11 | 已自动化(@Test) | 失败 | ArticleController |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AuthControllerTest.java` | 39 | 已自动化(@Test) | 失败 | AuthController |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DailyTaskControllerTest.java` | 2 | 已自动化(@Test) | 通过 | DailyTaskController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleCategoryControllerTest.java` | 3 | 已自动化(@Test) | 未跟踪 | ArticleCategoryController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleControllerTest.java` | 11 | 已自动化(@Test) | 未跟踪 | ArticleController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AuthControllerTest.java` | 39 | 已自动化(@Test) | 未跟踪 | AuthController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DailyTaskControllerTest.java` | 2 | 已自动化(@Test) | 未跟踪 | DailyTaskController |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DimensionAdminControllerTest.java` | 13 | 已自动化(@Test) | 未跟踪 | DimensionAdminController |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DimensionRegistryMapContractTest.java` | 7 | 已自动化(@Test) | 未跟踪 | DimensionRegistryMapContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DimensionRegistryTreeTest.java` | 9 | 已自动化(@Test) | 未跟踪 | DimensionRegistryTree |

+ 1 - 0
docs/tdd/test/blockers.md

@@ -41,3 +41,4 @@
 | B-34 | LangGraph 问卷生成 100% 失败降级(`GenerateRequest` 缺 `prompt_template`) | 研发 | **P0 生产缺陷**。`c3925c97e feat(langgraph): 全部提示词迁移到Java后端可配置` 只给 `cfc-langgraph/src/schemas/tongue.py:14` 的 `TongueRequest` 加了 `prompt_template`,**未给 `src/schemas/questionnaire.py:39 GenerateRequest` 加**;而 `src/graphs/questionnaire.py:39 build_prompt` 直接读 `req.prompt_template` → 每次调用必抛 `AttributeError`。链路:Java `AiGateway:321` 恒发送 `prompt_template` → pydantic 静默丢弃额外字段 → 图节点必抛 → 接口 500 → `AiGateway` catch 后返回 null → 调用方**静默降级模板**。即 `/api/family/questionnaire` 的 AI 生成能力 100% 不可用。`c3925c97e` 已在 `origin/cfclub` 祖先链 → 现网同样受影响。65 轮 pytest 实测 2 例必红即此因。修复:`GenerateRequest` 增 `prompt_template: Optional[str] = Field(default=None, ...)`(与 `TongueRequest:14` 对齐);`build_prompt` 可加 `getattr` 防御。闭环:`pytest tests/test_graph.py` 2 例转绿 + `/api/v1/questionnaire/generate` 返回 200 且 `questionnaire_json` 非空 + `AiGateway` 不再打「调用失败」warn | 测试(65 轮实测登记) | 2026-11-07 02:15 | 待处理 |
 | B-35 | DAN 报告解析 A1/A2/B4 仍失效(修复提交未覆盖该版式) | 研发 | `DanReportParseServiceTest` 65 轮全量实测 **4 例红**:`testParseA2_standardCoreLiteracyFormat:262`(姓名 `expected 俊辰 but null`)、`testParseB4_regression:280`(仍走降级 `expected false but true`)、`testParseA1_shouldFallbackToGenericPattern`、`testParseA1_shouldExtractCognitiveDimensionFromDetailPage`(`expected not null`)。而 `c611ec55d fix(dan): 修复 A1/B4 认知维度解析失效` 声称已修 → **修复未覆盖这两种版式**(`testParseA2_regression` 同批绿、`standardCoreLiteracy` 版式红,说明是版式分支漏配)。健康报告解析为核心链路(AGENTS.md「健康报告 PDF 上传与解析」)。建议按真实样本补版式分支 + 回归样本入库。闭环:4 例转绿 + 用 3 份真实报告样本走 `/api/health/report/parse` 人工比对字段 | 测试(65 轮实测登记) | 2026-11-07 02:15 | 待处理 |
 | B-36 | 根级黑盒 API 套件由「12 恒红」转为「默认 skip」,接口层覆盖归零 | 测试/环境 | WIP 将 `tests/integration/mini-games-api.spec.js:6-11`、`plan-chain.spec.js:21-22` 改为 `CFC_API_E2E==='1' && CFC_API_TOKEN` 门控(原写死 `Bearer test-token` 打真服务 → 恒 401/500)。方向正确(消除 12 个伪红),但 65 轮实测 **23 例全部 skip、0 执行**(`Tests: 23 skipped`)→ 接口层验收从「假红」变「真空」,且 `plan-chain` 仍依赖空的 `ADMIN_PHONE/ADMIN_PASSWORD`。建议:新增 `tests/.env.test` + seed 账号,`globalSetup` 自动登录取 token 写入 `process.env.CFC_API_TOKEN`,CI 注入 `API_BASE_URL=http://127.0.0.1:9082`。闭环:本地 9082 在听时 `CFC_API_E2E=1 npm test` 23 例实跑且红例有归因;CI 出绿灯记录 | 测试(65 轮实测登记) | 2026-11-07 02:15 | 待处理 |
+| B-37 | sleep.config.tags blank-key 实现缺口(契约测试 1 红,阻断该键转 GREEN) | 研发 | 复验轮(TR-6 派发 10 键复验)`SleepConfigTagsMechanismContractTest` **9/10 绿 + 1 红**:`publicValue_blankKey_returnsError:99` 期望 blank key(`"   "`)→ 500 但实得 200。实现 `PublicConfigController.getValue`(L21-28)只查 `key==null||isEmpty()`,未 reject 全空白串 → blank key 被当作正常查询放行。测试由 `f11062b42`(提交信息注明「21绿/1红 blank-key 缺陷」)引入,属**已知实现缺口、非测试误报**。`HealthSleepControllerContractTest` 12/12 绿不受影响。该键 `--mark-green` 已**暂缓**、状态机保持 YELLOW。修复:`getValue` 校验改为 `key==null || key.trim().isEmpty()`(或判 `matches("\\s*")`),并确认无调用方依赖空白 key 语义。闭环:`SleepConfigTagsMechanismContractTest` 10/10 绿后再 `--mark-green sleep.config.tags` | 测试(复验派发登记) | 2026-11-07 05:50 | 待处理 |

+ 9 - 8
docs/tdd/test/inventory.md

@@ -9,11 +9,11 @@
 | 来源类型 | 文件数 | 用例/方法数 |
 | --- | --- | --- |
 | 结构化测试用例(md) | 11 | 784 |
-| Playwright(spec.js) | 75 | 443 |
-| Python(pytest) | 11 | 67 |
+| Playwright(spec.js) | 76 | 444 |
+| Python(pytest) | 11 | 47 |
 | Java后端(测试文件) | 232 | 1839 (@Test) |
 | 用户场景(md) | 11 | 文件级 |
-| **合计** | — | **3133** 用例/方法 |
+| **合计** | — | **3114** 用例/方法 |
 
 ## 二、结构化测试用例(`tests/test-cases/*.md`)
 
@@ -806,7 +806,7 @@
 | `TC-S-N05` | 报告解析接入 | 服务商 | P0 | 安全 | `tests/test-cases/vendor.md#TC-S-N05` | 上传校验 | 类型/大小校验;不执行;存储隔离 |
 | `TC-S-N06` | 营养食谱 | 服务商 | P1 | 安全 | `tests/test-cases/vendor.md#TC-S-N06` | 内容安全 | 内容转义存储/渲染;不执行 |
 
-## 三、Playwright 端到端 / 集成测试(`tests/*.md`)
+## 三、Playwright 端到端 / 集成测试(`tests/**/*.spec.js`)
 
 > 来源锚点 = `文件#用例标题`。用例标题列于 JSON(`inventory.json`)便于回写。
 
@@ -887,18 +887,19 @@
 | `tests/e2e/wish-exchange-flow.spec.js` | 12 | `tests/e2e/wish-exchange-flow.spec.js` |
 | `tests/integration/mini-games-api.spec.js` | 13 | `tests/integration/mini-games-api.spec.js` |
 | `tests/integration/plan-chain.spec.js` | 10 | `tests/integration/plan-chain.spec.js` |
+| `tests/unit/games/1a2b.spec.js` | 1 | `tests/unit/games/1a2b.spec.js` |
 
 ## 四、Python 测试(`cfc-langgraph/tests · tools/xaf_agent_hub/tests`)
 
 | 文件 | 用例数 | 来源 |
 | --- | --- | --- |
 | `cfc-langgraph/tests/qna/test_graph.py` | 4 | `cfc-langgraph/tests/qna/test_graph.py` |
-| `cfc-langgraph/tests/test_analyze.py` | 4 | `cfc-langgraph/tests/test_analyze.py` |
-| `cfc-langgraph/tests/test_auto_tag.py` | 12 | `cfc-langgraph/tests/test_auto_tag.py` |
-| `cfc-langgraph/tests/test_chat.py` | 4 | `cfc-langgraph/tests/test_chat.py` |
+| `cfc-langgraph/tests/test_analyze.py` | 2 | `cfc-langgraph/tests/test_analyze.py` |
+| `cfc-langgraph/tests/test_auto_tag.py` | 5 | `cfc-langgraph/tests/test_auto_tag.py` |
+| `cfc-langgraph/tests/test_chat.py` | 1 | `cfc-langgraph/tests/test_chat.py` |
 | `cfc-langgraph/tests/test_graph.py` | 5 | `cfc-langgraph/tests/test_graph.py` |
 | `cfc-langgraph/tests/test_health_plan.py` | 13 | `cfc-langgraph/tests/test_health_plan.py` |
-| `cfc-langgraph/tests/test_intent.py` | 13 | `cfc-langgraph/tests/test_intent.py` |
+| `cfc-langgraph/tests/test_intent.py` | 5 | `cfc-langgraph/tests/test_intent.py` |
 | `cfc-langgraph/tests/test_memory.py` | 3 | `cfc-langgraph/tests/test_memory.py` |
 | `cfc-langgraph/tests/test_recommend.py` | 3 | `cfc-langgraph/tests/test_recommend.py` |
 | `cfc-langgraph/tests/test_report_parse.py` | 5 | `cfc-langgraph/tests/test_report_parse.py` |