Prechádzať zdrojové kódy

test(tdd): 第149轮闭环——后端强制实跑39:08=347类/2946例/2925过/99.29%/17红(与R148零漂移第9次)+langgraph 251实派51例48过/3红(B-74复燃:API key ****ab12 401+AgnesAI 429)+浏览器28/28(189实派5/5 blob一致)+web116/fe601过3红/根级7过16红+全量3782/3725=98.49%;SRS零变更G12合规;结果变化触发push+通知研发

E2E Test Bot 2 dní pred
rodič
commit
12481394b

+ 52 - 0
docs/tdd/automation-run-2026-11-11-R149.md

@@ -0,0 +1,52 @@
+# 自动化执行记录 · 测试负责人闭环 第 149 轮(2026-11-11 17:47–18:30 GMT+8)
+
+> 触发:定时自动化 32de5e1c-d38c-41f7-93a8-cde952b1ff18「测试负责人闭环(全部用例通过 + 覆盖 SRS/场景含异常流)+ 浏览器走 cfc.iwintrue.com/admin 与 /frontend(189/本机每节点单任务)+ langgraph 派 251 + 结果有变提交远程并通知研发」。
+> 执行档:review(离线)。全程只读:未装依赖、未启停服务、未改生产代码、未改测试断言。
+
+## 1. 时序
+
+| 时间 | 动作 | 结果 |
+|------|------|------|
+| 17:47 | 读自动化记忆 + git fetch | 本地 = origin = `1573d89e3`(0 落后);R148 窗口后研发合入 2 docs/chore 提交 |
+| 17:48 | 环境探针 | JDK 1.8.0_25 / Maven 3.6.1 / Node v22.22.2 / D: 93G 可用 → 全部可用 |
+| 17:49 | 后端全量 kick(后台) | `mvn -o -B clean test` 启动 |
+| 17:49 | 251 langgraph kick | `setsid nohup` + 落盘 `/tmp/r149_pytest.log` |
+| 17:49 | 189 admin-desktop 实派 | 5/5(99s,EXIT=0) |
+| 17:51 | 本机 fe / shop / health / dx | 6/6、4/4、13/13、2 skip(health 无 502 复现) |
+| 17:55 | 三套 Jest | web 116/116、fe 616(601/3/12)、根级 23(7/16) |
+| 17:58 | 线上探针 5+3+2 | 鉴权 5/5 = 401;`/api/admin/families/overview` = 200+code:400;`/admin` `/frontend` 302、`/` 404;251/189 200、204 000 |
+| 18:00 | 度量脚本 + 锚点扫描 | 场景 215 / 映射 155(72.1%);TC 837 / 异常流 498(59.5%);锚点 104(脚本) |
+| 18:03 | langgraph 读结果 | 51 例:48 过 / 3 红(test_auto_tag 3,根因 401 `****ab12` + 429 AgnesAI) |
+| 18:27 | 后端收尾 | **39:08**;347 类 / 2946 例 / 2925 过 / 16F+1E+4S = **99.29%** |
+| 18:30 | 报告 + 台账 + 通知 | 本记录 + `report-test-2026-11-11-R149.md` + `notice` + blockers/status 附录 |
+
+## 2. 关键判定
+
+- **后端强制实跑**(R148 已实跑;本轮窗口含研发版本 bump,继续实跑取证)→ 结果与 R148/R146 逐类逐例一致,**零回归第 9 次**。
+- **langgraph 漂泊**:R147 51/51 → R148 50/51 → 本轮 **48/51**(3 红全在 `test_auto_tag`)。根因:**API key `****ab12` → 401 Authentication Fails(B-74 复燃,曾于 R124 实锤、R127/R128 销号)+ AgnesAI 429 free rate limit** → 上游凭据/额度双重故障,非代码回归。
+- **B-142-2 不销号**:需连续 2 轮绿,本轮 3 红未达。
+- **新增复燃登记 B-74(B-149-1)**:`****ab12` key 401 再现 → 运维须轮换凭据。
+- **B-148-1 未复现**:health 13/13 直跑全绿,网关 502 观察项本轮无证据。
+- **B-189 维持可比**:189 spec blob `4703d73fb` = 本机。
+
+## 3. 与 R148 差异
+
+| 指标 | R148 | R149 | 差异 |
+|------|------|------|------|
+| 后端 | 实跑 99.29%(347/2946/17红) | **实跑 99.29%(同集合同数)** | 0(零漂移第 9 次) |
+| langgraph | 50/51(1 红 ConnectError) | **48/51(3 红 401+429)** | -2 过 |
+| 前端 | 601/3/12 | 601/3/12 | 0 |
+| 管理端 | 116/116 | 116/116 | 0 |
+| 根级 | 7/16 | 7/16 | 0 |
+| 浏览器 | 28/28 + 2 skip | 28/28 + 2 skip | 0 |
+| 全量 | 3782 / 3727 = 98.55% | **3782 / 3725 = 98.49%** | -2 过 / -0.06pp |
+| 门禁 | 有条件通过 | 有条件通过(G7 仍 ❌) | 持平 |
+
+## 4. 未实测 / 未授权项(如实记录)
+
+- 性能压测(k6/JMeter):无脚本 + 需联网/需目标环境 → **未实测**。
+- 依赖漏洞扫描(SCA)、DAST:需联网 → **未授权未执行**。
+- 变异测试(PIT):仓库未配置 → **未实测**。
+- 后端行覆盖(jacoco):`pom.xml` 无插件 → **无凭据**。
+- 多引擎兼容(webkit/firefox)、axe 无障碍:需联网装浏览器 → **未实测**。
+- 业务 UAT:无签署记录 → **待核实**。

+ 41 - 0
docs/tdd/notice-2026-11-11-R149-研发通知.md

@@ -0,0 +1,41 @@
+# 研发交接通知 · 测试负责人 第 149 轮(2026-11-11 18:30)
+
+> 发起:测试负责人(自动化闭环)|接收:研发负责人 / 后端 / 前端 / AI(LangGraph)/ 运维
+> 触发原因:**测试结果有变化**(langgraph 50/51 → 48/51,全量 98.55% → 98.49%),且 **B-74 复燃**(API key `****ab12` 401 再现)。
+
+## 一、本轮结论
+
+| 项 | 结果 |
+|---|---|
+| 门禁结论 | **⚠️ 有条件通过**(G2 / G7 / G9 / G11 未达阈值,无新增回归) |
+| 全量 | **3782 例 / 3725 过 = 98.49%**(剔 skip 98.96%);红 39 / 跳 18 |
+| 后端(实跑 39:08) | 347 类 / 2946 例 / **2925 过 / 17 红 / 4 跳 = 99.29%**,与 R148/R146 逐类逐例一致 → **零回归第 9 次** |
+| langgraph@251(151s) | **51 例 / 48 过 / 3 红** ← 唯一变化点 |
+| 浏览器 | **28/28 + dx 2 skip**(189 admin 5/5、本机 fe 6/6、shop 4/4、health 13/13) |
+| 三套 Jest | web 116/116 · fe 601/3/12(3 预期 RED)· 根级 7/16 |
+
+## 二、需研发处置(按优先级)
+
+| # | 编号 | 优先级 | 问题 | 归属 | 建议动作 |
+|---|------|--------|------|------|----------|
+| 1 | **B-74 复燃** | **P0** | langgraph 3 红日志:**API key `****ab12` → 401 Authentication Fails**(R124 实锤过、R127/R128 销号后**再现**)+ AgnesAI **429 free rate limit** → `/api/v1/chat` 恒 500 | 运维/AI | **轮换/校验 LLM API key**;升级或限额 AgnesAI 额度;服务侧上游故障返回 **503 + 结构化 code + 熔断**,不得裸露 500 |
+| 2 | B-142-2 | **P0** | 上游不可用形态漂移(ConnectError → 401/429),第 3 轮未绿,不销号 | 运维/AI | 同 #1;连续 2 轮全绿后方可销号 |
+| 3 | B-142-1 | **P1** | 匿名 `POST /api/admin/families/overview` → HTTP 200 + `code:400`(对照组 energy/health-plan/mind/huawei/xiaomi 全 401)——**第 8 轮未修** | 后端安全 | `JwtInterceptor` 放行清单收口至 8 个公开路径;补 admin 域鉴权契约用例 |
+| 4 | B-145-1 | **P1** | `schema.sql:5343` `nutrition_age_dosage` 含 `INDEX idx_product(product_id)` 但无该列 → 建表恒失败,`DatabaseInitializer` 静默吞错——**第 5 轮未修** | 后端 | 删无效索引或补列;建表失败改为抛错 |
+| 5 | 17 后端红(10 类) | **P0** | EnergySystem 6(5×500 + 1×5001)· Orchestration 2 · UserServiceWechatLogin 2 · MembershipPay 1 · PaymentORD 1 · TeamProfitCron 1 · DimensionRegistryMap 3(契约待裁决 P-9)· GuideModule 1(平台费截断) | 后端/产品 | EnergySystem 需先取堆栈定位(等于该链路零有效覆盖);P-9 需产品书面裁决 |
+| 6 | B-134-4 | P1 | `intent_classifier` 异常兜底默认 `chat`,把上游 429/401 伪装成分类正确 | AI | 异常路径返回 `degraded=True` + 结构化日志 |
+| 7 | B-DX-1 | P2 | dx-bridge `bridge/list`、`bridge/sync-status` 仍 404(2 例 skip)——第 11 轮 | 部署 | TR-24 待部署 |
+| 8 | B-95 | P2 | `192.168.16.204:4090` = 000(189/251 均 200)——第 20 轮 | 运维 | 节点恢复或从派发池摘除 |
+| 9 | B-36 | P3 | 根级黑盒 16 红全 `ECONNREFUSED 127.0.0.1:9082`——第 45 轮 | 测试 | 下轮改「探活失败即 skip 并输出原因」 |
+| 10 | B-148-1 | P3 | health 网关瞬抖 502 —— **本轮未复现(13/13 直跑全绿)**,维持观察 | 运维 | 网关侧稳定性 |
+
+## 三、结构性缺口(需排期,非单点修复)
+
+1. **G11 CI 全量门禁**:`.gitlab-ci.yml` 后端全量仍为 observed 非阻断 → 17+3 红可持续挂账。
+2. **G9 场景锚点 30.0%**(347 唯一 TC 中 104 可定位;严格口径 ~18.5%)→ 建议优先补 `parent.md`/`admin.md` 的 `TC-*` 注释。
+3. **G-149-4 后端覆盖率无凭据**:`pom.xml` 无 jacoco/pitest。
+4. **G-149-6 可靠性**:无故障注入用例;本轮 401+429 → 500 正是该类缺口实证。
+
+## 四、通知通道说明
+
+Agent Mail `GetMe` 返回 `not_bound`(连接器 connected,但邮箱未开通)→ 按纪律不重试。本通知以**仓库文件 + `blockers.md` 登记 + 推送 `origin/cfclub`** 作为送达载体。

+ 339 - 0
docs/tdd/orchestration/report-test-2026-11-11-R149.md

@@ -0,0 +1,339 @@
+# 测试负责人工作汇报(第 149 轮 · 2026-11-11 GMT+8)
+
+> 角色:cfc-tester(测试负责人)|执行档:**review(离线;内网 cfc.iwintrue.com/admin + /frontend 浏览器自动化;langgraph 实派 192.168.16.251;未联网装依赖、未启停服务、未改生产代码)**
+> 基线 HEAD:`1573d89e3`(跑前 = 跑后,与 origin/cfclub 零漂移)。窗口自 R148 后研发合入 2 个 docs/chore 提交(`ce6f76366` 研发汇报 + 版本 bump),**零功能源码**(`git diff --name-only` 实证)→ 后端本轮**强制实跑**(R148 已实跑,本轮窗口含版本 bump 变更,继续实跑取证)。
+> 节点分工:`189:4090` = 200 → **admin-desktop 实派 5/5**|`251:4096` = 200 → **langgraph pytest 实派 51 例**|`204:4090` = 000(B-95 第 20 轮)|本机 = fe/shop/health/dx + 三套 Jest + 根级黑盒
+> 结论:⚠️ **有条件通过** —— 后端 99.29%(17 红,与 R148/R146 逐类逐例一致 → **零回归第 9 次**);langgraph **48/51**(3 红为 LLM 上游 401+429,**B-74 复燃** + B-142-2 第 3 轮未绿 → **不销号**);浏览器 **28/28 + dx 2 skip**;全量 **3782 例 / 3725 过 = 98.49%**。
+> **变更触发**:langgraph 上轮 50/51 → 本轮 48/51(净 -2 过),全量 98.55% → 98.49% → **已 push + 通知研发**(见 §9)。
+
+---
+
+## 0. 基本信息(测试负责人模板)
+
+| 项目 | 内容 |
+|------|------|
+| 汇报人 | `cfc-tester`(测试负责人) |
+| 汇报周期 | 2026-11-11(第 149 轮,跑测窗口 17:47–18:28) |
+| 负责模块/单元 | cfc-backend(全量实跑) · cfc-frontend(Jest 实跑) · cfc-web(Jest 实跑) · cfc-langgraph(251 实派) · 浏览器 E2E(admin@189 / frontend·shop·health·dx@本机) · 根级黑盒(实跑) |
+| 执行档 | review(离线;未装依赖、未启停服务、未改生产代码) |
+
+### 0.1 测试用例建设与执行
+
+| 指标 | 数量 | 填写说明 |
+|------|------|----------|
+| **本轮新增测试用例数** | `0` 个 | `docs/superpowers/specs` / `tests/test-cases` / 场景池自 R148 起 **零变更**(`git diff --name-only` 空 → G12 合规),无需更新用例 |
+| **本轮验证执行测试数** | `3782` 个 | 后端 2946 + 前端 616 + 管理端 116 + 根级 23 + langgraph 51 + 浏览器 30(含 dx 2 skip) |
+| **用例通过率** | `98.49%`(3725/3782) | 剔 skip 口径 **98.96%**(3725/3764);红 39 = 后端 17 + 前端 3 + 根级 16 + langgraph 3 |
+| **新增覆盖资产** | `0` 项 | 无 SRS 变更、无新契约文件;本轮无资产入库 |
+
+### 0.2 会话与任务分发
+
+| 指标 | 数量 | 填写说明 |
+|------|------|----------|
+| **分派任务数** | `2` 个 | ① 189:admin-desktop E2E(99s,5/5,`EXIT=0`);② 251:langgraph pytest(151s,48/51);其余本机直跑 |
+| **恢复智能体会话数** | `0` 个 | 无中断/重建 |
+| **当前在用会话数** | `3` 个 | 本机(done)/ 189 = shell(done)/ 251 = shell(done) |
+
+### 0.2b 各会话当前工作状态
+
+| 会话标签 | 会话 ID | 当前状态 | 当前任务 | 耗时 | 工作目录 | 备注 |
+|----------|---------|----------|----------|------|----------|------|
+| 本机 | localhost | done | 浏览器 fe/shop/health/dx + Jest×3 + 根级 + 后端全量 | mvn 39:08 | `d:\cfc` | fe 6/6 (1.1m)、shop 4/4 (13.6s)、health 13/13 (8.5s) |
+| 189:4090 | `sh_1ca02306e…` | done | admin-desktop E2E | 99s | `C:\code\cfc\tests` | **5/5(EXIT=0)**;spec blob `4703d73fb` = 本机 |
+| 251:4096 | shell 直连(`setsid nohup` + 落盘) | done | langgraph pytest | 151s | `/sc-data/cfc/cfc-langgraph` | **48/51**;节点 HEAD `47958709e`(本机 R148 `1573d89e3` + 1 个 auto bump) |
+| 204:4090 | — | unknown(000) | 失联 | — | — | B-95 第 20 轮 |
+
+### 0.3 问题处置
+
+| 指标 | 数量 | 填写说明 |
+|------|------|----------|
+| **新测试发现问题数** | `1` 个 | **B-149-1 = B-74 复燃(P0 运维)**:langgraph 3 红日志出现 **API key `****ab12` → 401 Authentication Fails**(曾于 R127/R128 销号),叠加 AgnesAI **429 free rate limit** → `/api/v1/chat` 恒 500 |
+| **已解决测试相关问题数** | `0` 个 | 本轮无测试侧自闭环(零 SRS 变更、零装置类红) |
+| **待解决测试相关问题数** | `10` 类 | 后端 17 存量红 · 前端 3 预期 RED · 根级 16 环境红 · langgraph 3 上游红 · dx 2 端点 404(B-DX-1 第 11 轮)· 204 失联(B-95)· admin 鉴权门缺失(B-142-1 第 8 轮)· nutrition_age_dosage 建表失败(B-145-1 第 5 轮)· B-134-4 兜底伪装 · B-148-1 网关瞬抖(本轮未触发) |
+
+### 0.4 本轮 git 提交与推送证据
+
+| 提交 sha | 关联键 | 阶段 | 触及文件 | 目标分支 | 已推送远端 | 备注 |
+|----------|--------|------|----------|----------|------------|------|
+| 见 §9 | R149 报告 + 通知 + 台账追加 | 测试闭环 | `docs/tdd/**` | `cfclub` | 是 | 结果变化触发(langgraph -2 过、全量 98.55% → 98.49%) |
+
+---
+
+## 1. 项目画像(本轮复核)
+
+| 维度 | 内容 |
+|------|------|
+| 业务定位 | 家庭教育「浠艾福(XAF)」:家长端 / 孩子端 / 成长规划师端三视角 + 五维能量(身/心/智/行/富)+ 健康报告解析 + 商城 + 管理后台 |
+| 技术栈 | Spring Boot 2.7.18 + MyBatis-Plus(Java 8,`cfc-backend`,9082)· uni-app 小程序 Vue2(`cfc-frontend`)· Vue2 + Element UI(`cfc-web`,8082)· Python FastAPI + LangGraph(`cfc-langgraph`,9000)· 独立商城(`dan/danshop`,8888) |
+| 模块结构 | 后端 366 控制器 / 347 测试类 · 前端 40 套件 616 例 · 管理端 17 套件 116 例 · langgraph 51 例 · `tests/` 浏览器 30 + 根级黑盒 23 |
+| 关键路径 | 微信登录/建档 → 家庭与成员 → 五维能量 → 健康报告上传与解析 → 健康方案 → 任务编排 → 测评订单 → 支付/会员 → 管理端审核与配置 |
+| 测试现状 | 后端 347 类全量可跑(`-o -B clean test` 39:08);三套 Jest 全量可跑;浏览器 live 30 例;CI(`.gitlab-ci.yml`)存在但**后端全量为非阻塞**(阻断作业用 `-Dtest=!${OBSERVED}` 排除红类)→ G11 仍不达标 |
+| 质量目标 | 全量通过率 ≥98%、零未归因红、SRS 场景锚点可追溯、CI 全量门禁 |
+| 风险点 | ① 17 存量红长期挂账(EnergySystem 6 全 500 / 契约 3 / 支付会员 3 / 编排 2 / 平台费截断 1 / 分佣冷静期 1 / 微信登录 2);② 17 红中「产品类」已跨 9 轮零漂移 → 缺研发修复排期;③ `/api/admin/**` 鉴权门缺失 8 轮未修;④ **langgraph LLM 上游 key `****ab12` 401 + 429 双重故障(B-74 复燃)** |
+| 历史审查记录 | 上次 R148(17:40,HEAD `ffa97bf02`):**有条件通过** 98.55%(3782/3727),langgraph 50/51(1 红 ConnectError)、后端强制实跑 99.29% 零回归第 8 次。**本次为该对象第 149 次审查,非首次**;R148 遗留待复验项 = B-142-2(需连续 2 轮绿)。**本轮复验结果:48/51(3 红 401+429)→ 未达连续 2 轮绿 → 不销号**。历史结论仅作对照,本轮全部指标重新取证。 |
+
+---
+
+## 2. 20 类测试覆盖矩阵(三态 + 证据)
+
+> 「未发现」仅表示本轮扫描未命中,「待核实」表示证据不足或扫描受限;不得读作「项目没做」。
+
+| # | 测试类型 | 层次 | 判定 | 证据 |
+|---|----------|------|------|------|
+| 1 | 单元测试 | 功能层次 | 已发现 | `cfc-backend/src/test/java/**/unit` + service/controller 单测(347 类 / 2946 例实跑);前端 `__tests__/pages/**` 601 过 |
+| 2 | 组件测试 | 功能层次 | 已发现 | `cfc-frontend/__tests__/components/**`、`cfc-web/src/__tests__/views/**`(116 过);3 例预期 RED(健康方案摘要 / 收货人编辑 / 成长日分组) |
+| 3 | 集成测试 | 功能层次 | 已发现 | `integration/**`:`EnergySystemFlowTest` 6、`GuideModuleIntegrationTest` 1(E)、`OrchestrationIntegrationTest` 1 |
+| 4 | 契约测试 | 功能层次 | 已发现 | `DimensionRegistryMapContractTest` 3、`UserServiceWechatLoginContractTest` 1、`TeamProfitCronContractTest` 1、`tests/test-cases/*.md` 347 唯一 TC |
+| 5 | 接口 API 测试 | 功能层次 | 已发现 | `tests/playwright.config.api*.js` + `tests/e2e/api/**`(含 generated);线上 POST 鉴权探针 5/5 = 401 |
+| 6 | 冒烟测试 | 功能保障 | 已发现 | `playwright.config.smoke.js`、`tests/e2e-live/frontend-live.spec.js` TC-F-U01(首页可渲染)每轮执行 |
+| 7 | 回归测试 | 功能保障 | 已发现 | 本轮后端全量 347 类实跑 + 三套 Jest + 浏览器 30 例 = 全量回归;与 R148/R146 逐类逐例零漂移(第 9 次) |
+| 8 | 验收测试(UAT) | 功能保障 | 待核实 | `tests/test-cases/{parent,child,teacher,admin,vendor,guest,butler}.md` 有验收口径,但**无 UAT 执行记录/签署**;线上 admin 5/5 属技术验收非业务 UAT |
+| 9 | BDD / 场景规格 | 功能保障 | 待核实 | 场景池 215 条、被 TC 覆盖 155(72.1%)、spec 字面命中 33(15.3%);**无 Gherkin feature 文件**(`grep -c "Feature:"` 为空) |
+| 10 | 探索性测试 | 功能保障 | 未发现 | 无探索性会话章程/记录(仓库内零 charter 文档);本自动化未做人工探索 |
+| 11 | 性能测试 | 非功能 | 未发现 | 无 k6/JMeter/Gatling 脚本;仅有 `SLOW_REQUEST` 日志(本轮 16.00s chat)作被动感知;压测需联网未授权 |
+| 12 | 可靠性测试 | 非功能 | 待核实 | 有熔断/兜底代码(`AiGateway`)与 `OrchestrationPollingJob` 轮询,但**无故障注入/长稳测试**;本轮 langgraph 401+429 → 500 暴露兜底不足(3 例) |
+| 13 | 安全测试 | 非功能 | 已发现(含缺陷) | 线上匿名鉴权探针 5/5 = 401(mind/energy/health-plan/huawei/xiaomi);**`/api/admin/families/overview` 匿名 200 + code:400(B-142-1 第 8 轮)**;`SECURITY_REVIEW_2026-11.md` 存在;SAST 无流水线集成 |
+| 14 | 兼容性测试 | 非功能 | 未发现 | 无多浏览器/多设备矩阵(`playwright.config.live.js` 仅 chromium 单通道:admin-desktop / frontend-mobile 两种视口) |
+| 15 | 可用性测试 | 非功能 | 未发现 | 无真实用户可用性评估记录 |
+| 16 | 无障碍测试 | 非功能 | 未发现 | 无 axe-core / WCAG 规则集;浏览器用例未断言 aria 属性 |
+| 17 | 测试覆盖率 | 度量 | 已发现(含缺口) | 前端 `test:coverage` 可跑(管理端已产出 10.09/6.12/7.50/9.97);**后端 `pom.xml` 无 jacoco / pitest(`grep -c` = 0)** → 后端行覆盖无凭据 |
+| 18 | 变异测试 | 度量 | 未发现 | 无 PIT / Stryker 配置与报告 |
+| 19 | 质量指标与缺陷度量 | 度量 | 已发现 | `docs/tdd/test/blockers.md`(B-* 台账)、`automation-status.md`、`test_attr.py` 三层归因(装置/产品/数据) |
+| 20 | QA 流程与 CI/CD 门禁 | 流程 | 部分已发现 | `.gitlab-ci.yml` 存在(build/test/observed 多作业),但**后端全量为非阻断**、langgraph / Playwright 仅在 observed 作业 → G11 ❌ |
+
+**矩阵小结**:已发现 11 类、待核实 3 类(UAT / BDD / 可靠性)、未发现 6 类(探索性 / 性能 / 兼容性 / 可用性 / 无障碍 / 变异)。
+
+---
+
+## 3. 测试方案(本轮执行口径)
+
+| 项 | 内容 |
+|----|------|
+| 目标 | 全量用例可跑、红例可归因、SRS 零变更即零新增、双节点派发可用 |
+| 范围 | 后端全量(强制实跑)· 三套 Jest · 浏览器 live 30 · langgraph 51 · 根级 23 · 线上鉴权 5 探针 · 路由/根路径 3 探针 |
+| 执行档 | review(离线白名单);压测/漏洞库扫描需联网 → 未授权未执行 |
+| 排除项 | ① `tests/qna`(B-141-1:`from src.qna import` 缺模块,收集期中断);② `tests/test_chat.py`(口径与历轮一致,避免 LLM 抖动污染计数);③ dx-bridge 2 例(端点 404 → 设计为 skip) |
+| 节点约束 | 每节点单任务:189 仅 admin-desktop;251 仅 langgraph pytest;本机承担其余 |
+
+---
+
+## 4. 执行结果
+
+### 4.1 后端全量(实跑 · `mvn -o -B clean test`,JDK 1.8.0_25 + Maven 3.6.1)
+
+| 指标 | 数值 |
+|------|------|
+| 耗时 | **39:08**(主源 2121 编译 + 353 测试源 0 错) |
+| 类 / 例 | **347 类 / 2946 例** |
+| 通过 | **2925** |
+| 失败 / 错误 / 跳过 | 16 F + 1 E + 4 S |
+| 通过率 | **99.29%**(剔 skip 99.42%) |
+| 产物完整性 | 347/347 XML 全产出、`*.dump` = 0、编译 COMPILATION ERROR = 0 |
+| 红类集合 | 9 文件 17 红:EnergySystemFlowTest 6 · DimensionRegistryMapContractTest 3 · Orchestration 2 · UserServiceWechatLogin 2 · MembershipPay/PaymentORD 2 · TeamProfitCron 1 · GuideModuleIntegration 1 |
+| 与 R148/R146 对比 | 类/例/红完全一致,**红类集合差集为空 → 零漂移第 9 次** |
+
+### 4.2 其余套件
+
+| 套件 | 结果 | 备注 |
+|------|------|------|
+| cfc-web(Jest) | **116/116**(17 套件,180s) | 零漂移 |
+| cfc-frontend(Jest) | **616:601 过 / 3 红 / 12 跳**(60.8s) | 3 红全为 S-cfc-30/52/53 契约(预期 RED,组件未交付) |
+| 根级黑盒(tests/jest.config.js) | **23:7 过 / 16 红**(7.0s) | 16 红全 `ECONNREFUSED 127.0.0.1:9082`(本机后端未起)→ B-36 第 45 轮 |
+| langgraph@251(pytest) | **51:48 过 / 3 红**(151s) | 3 红全在 `test_auto_tag.py`(content_relevance / short_content / empty_content)→ chat 500 |
+| 浏览器 live@本机 | fe **6/6**(1.1m) · shop **4/4**(13.6s) · health **13/13**(8.5s) | 全绿,无 B-148-1 502 复现 |
+| 浏览器 live@189 | admin **5/5**(99s,`EXIT=0`) | spec blob `4703d73fb` = 本机 → 结论可比 |
+| dx-bridge | 2 skip | 端点 404(B-DX-1 第 11 轮) |
+
+### 4.3 langgraph 3 红根因(本轮核心变化)
+
+| 红例 | 断言点 | 日志证据 |
+|------|--------|----------|
+| `test_auto_tag_content_relevance` | `call_chat` 期望 200 实得 **500** | `recall 失败: 401 Authentication Fails, api key ****ab12 invalid`;`intent 分类失败: 429 You've reached the API rate limit for free users (AgnesAI)`;middleware `RateLimitError → 500`(8.68s) |
+| `test_auto_tag_short_content` | 同上 | 401 + 429(16.00s SLOW_REQUEST) |
+| `test_auto_tag_empty_content` | 同上 | 401 + 429(9.69s) |
+
+- **判定**:**B-74 复燃**(`****ab12` key 401 曾于 R124 实锤、R127/R128 连续两轮全绿后销号)+ **B-142-2 延续**(上游不可用形态从 ConnectError 漂移到 401/429)→ 均为**上游凭据与额度故障**,非代码回归;`intent_classifier` 兜底 `except → chat`(B-134-4)把故障伪装成「分类正常」的根因仍然成立。
+
+### 4.4 线上探针
+
+| 探针 | 结果 |
+|------|------|
+| 匿名 `POST /api/mind/fortune` | 401 |
+| 匿名 `POST /api/energy/overview` | 401 |
+| 匿名 `POST /api/health/plan/list` | 401 |
+| 匿名 `POST /api/huawei-health/auth-url` | 401 |
+| 匿名 `POST /api/xiaomi-health/auth-url` | 401 |
+| 匿名 `POST /api/admin/families/overview` | **200 + `{"code":400,"message":"请求参数格式错误"}`** → B-142-1 第 8 轮 |
+| `/admin` `/frontend` `/` | 302 / 302 / 404 |
+| `251:4096` / `251:9000` / `189:4090` / `204:4090` | 200 / 200 / 200 / **000** |
+
+---
+
+## 5. 覆盖缺口清单
+
+| 编号 | 缺口类型 | 现状 | 风险 | 建议测试设计 | 优先级 | 闭环方式 |
+|------|----------|------|------|--------------|--------|----------|
+| G-149-1 | 场景锚点(G9) | 唯一 TC **347**,脚本口径锚点 **104(30.0%)**;严格口径(仅测试资产、排除 generated)**64(18.5%)** | SRS 场景无自动化凭据,回归靠人工 | 按 `tests/test-cases/*.md` 逐条在 e2e-live / 契约测试内挂 `TC-*` 注释,优先 `parent.md`/`admin.md` | P1 | 每轮提升 ≥3pp,达 95% 封板 |
+| G-149-2 | 场景-用例映射 | 场景 215,被 TC 覆盖 155(72.1%);spec 字面 33(15.3%) | 60 条场景无用例,需求变更易漏测 | 先补 07-five-dimension / 08-butler 两域剩余场景的 TC 条目(各 17 / 10 条) | P1 | 映射率 ≥90% |
+| G-149-3 | 异常流覆盖 | TC 837 条,异常流 498(59.5%) | 异常分支漏测 | 对支付/会员/健康解析三条链路补异常流用例(超时、重复回调、非法载荷) | P2 | 异常流占比 ≥70% |
+| G-149-4 | 后端覆盖率凭据 | `pom.xml` 无 jacoco / pitest(grep = 0) | 无行/分支覆盖数据,无法判「测了但没断言」 | pom 增 jacoco 插件(离线可用),生成 `target/site/jacoco` | P1 | 每轮产出覆盖率报告并入库 |
+| G-149-5 | 变异测试 | 无 PIT / Stryker | 断言强度未知(`assertNotNull` 类弱断言可能放过缺陷) | 对 `service/**` 抽样 3 个包做 PIT(离线 mvn 插件) | P2 | 变异杀灭率 ≥60% |
+| G-149-6 | 性能/可靠性 | 无压测脚本、无故障注入 | 上游故障时 `chat` 直返 500(本轮 3 例实证) | ① 对 `/api/v1/chat` 做上游断开注入,断言降级响应而非 500;② 记录 P95 基线 | P1 | 故障注入用例 ≥6 条并全绿 |
+| G-149-7 | 兼容性/无障碍 | 仅 chromium 单通道、无 axe | 多设备/读屏不可用风险 | 增 `--project=webkit/mobile-safari` 与 axe-core 断言(需联网装浏览器 → 未授权) | P2 | 兼容矩阵 ≥3 引擎 |
+| G-149-8 | CI 全量门禁(G11) | `.gitlab-ci.yml` 后端全量为非阻断(`-Dtest=!${OBSERVED}`) | 红例不阻断合并 → 长期挂账 17+3 红 | 红例清零后把 `backend-observed-junit` 转 blocking;先加「新增红例即失败」基线条 | P0 | CI 阻断全量后端 |
+
+---
+
+## 6. 域结论表
+
+| 审查维度 | 负责专家 | 结论 | 关键证据 |
+|----------|----------|------|----------|
+| 单元·组件级 | 苏雅 | ⚠️ 有条件通过 | 后端 2925/2946(99.29%)、前端 601/616;3 例预期 RED;后端无 jacoco/pitest |
+| 集成·接口级 | 柯砚 | ❌ 不通过 | 集成红 8(EnergySystem 6 + Orchestration 2)、契约红 3、数据截断 1;线上鉴权 5/5 = 401 但 `/api/admin/**` 缺门 |
+| 系统·验收级 | 白樾 | ⚠️ 有条件通过 | 浏览器 28/28 + 2 skip;UAT 无签署记录;dx-bridge 2 端点 404 |
+| 测试保障级 | 闻朔 | ⚠️ 有条件通过 | 冒烟/回归齐备(每轮全量);探索性测试无章程;B-36 根级 16 红环境型 |
+| 性能·可靠性 | 骆骋 | ❌ 未实测(降级) | 无压测脚本;langgraph 401+429 → 500 暴露无降级;压测需联网未授权 |
+| 安全 | 关屿 | ⚠️ 有条件通过 | 5/5 探针 401;**B-142-1 admin 鉴权门缺失第 8 轮**;SAST 未入流水线 |
+| 兼容·体验 | 阮清 | ⚠️ 有条件通过 | 双视口(desktop/mobile)可跑;无多引擎/无障碍断言 |
+| 流程·度量·代码 | 何序 | ⚠️ 有条件通过 | 台账/归因齐备;CI 后端全量非阻断;8 轮未修项仍挂账 |
+
+---
+
+## 7. 五要素问题清单
+
+### 问题 1|LLM 上游 API key 失效 + 限流双故障(B-74 复燃 + B-142-2,第 3 轮未绿)
+1. **问题描述**:langgraph `test_auto_tag` 3 例全部 500;日志两级证据:`recall 记忆失败: 401 Authentication Fails, api key ****ab12 is invalid` + `intent 分类失败: 429 rate limit for free users (AgnesAI)`;middleware 抛 `RateLimitError → HTTP 500`。`****ab12` 恰为 R124 已实锤过、R127/R128 全绿后销号的 key → **B-74 复燃**。
+2. **测试 bug 点**:`cfc-langgraph/tests/test_auto_tag.py:93`(`assert resp.status_code == 200`,无「环境不可用」分流);`app/middleware.py:113` 把上游 401/429/ConnectError 一律抛成 500。
+3. **最优修改方案**:① 运维轮换/校验 `****ab12` key(AgnesAI 免费额度已耗尽 → 升级或限额);② 服务侧对上游故障统一返回 **503 + 结构化 code** 并熔断;③ 用例侧按 `pytest.mark.env` 把环境红与逻辑红分流。
+4. **修改目的**:解耦「上游凭据/额度」与「代码回归」,避免 B-74/B-142-2 反复以不同形态干扰门禁。
+5. **能否闭环**:能。复测:key 轮换 → 51/51 全绿连续 2 轮销号;故障注入 → 断言 503 而非 500。
+
+### 问题 2|`/api/admin/**` 鉴权门缺失(B-142-1,第 8 轮)
+1. **问题描述**:匿名 `POST /api/admin/families/overview` 返回 HTTP 200 + `code:400`,而同窗口对照组 `/api/energy/overview`、`/api/health/plan/list`、`/api/mind/fortune` 均 401。
+2. **测试 bug 点**:`cfc-backend/src/main/java/com/etotem/cfc/config/JwtInterceptor.java`(放行清单未覆盖 `/api/admin/families/**`);用例 `tests/e2e-live/health-contract.spec.js:41` 同类契约未覆盖 admin 域。
+3. **最优修改方案**:把 `/api/admin/**` 纳入拦截器保护(仅保留登录/验证码等 8 个公开路径),并在 `tests/e2e-live/` 增 `admin-auth-contract.spec.js` 断言 401。
+4. **修改目的**:消除越权面,保证「未鉴权一律 401」全局不变式。
+5. **能否闭环**:能。复测:匿名 POST 该端点 → 401;回归跑 admin-desktop 5 例 + 契约 1 例全绿。
+
+### 问题 3|`nutrition_age_dosage` 建表恒失败(B-145-1,第 5 轮)
+1. **问题描述**:`schema.sql:5343` 建表体含 `INDEX idx_product (product_id)`,但该表无 `product_id` 列 → DDL 恒失败;`DatabaseInitializer` catch 后仍打印「数据表检查完成」,表从未创建。
+2. **测试 bug 点**:`cfc-backend/src/main/resources/schema.sql:5354`;`DatabaseInitializer.runMigrations()` 缺失该表存在性校验。
+3. **最优修改方案**:删除无效索引(或补 `product_id BIGINT` 列 + 外键语义),并在 `DatabaseInitializer` 增「建表失败即抛错」严格模式。
+4. **修改目的**:保证 schema 与运行库一致,避免功能静默不可用。
+5. **能否闭环**:能。复测:启动日志零 `SQLSyntaxErrorException`;`SHOW TABLES LIKE 'nutrition_age_dosage'` 命中;增 1 条 DDL 自检用例。
+
+### 问题 4|`intent_classifier` 兜底把上游故障伪装成分类错误(B-134-4,第 12 轮)
+1. **问题描述**:`intent_classifier` 捕获异常后默认 `chat`,429/401 被伪装为「分类正确」;本轮上游 401+429 同样被吞(仅 middleware 记录后抛 500)。
+2. **测试 bug 点**:`cfc-langgraph/app/intent_classifier.py:62`(`except → return "chat"` 无告警上抛)。
+3. **最优修改方案**:异常路径返回 `degraded=True` 并写结构化日志(含状态码),用例断言 `degraded` 而非仅断 intent。
+4. **修改目的**:让「降级」可见,避免红例被静默转绿。
+5. **能否闭环**:能。复测:注入 429 → 响应含 `degraded:true` 且日志带 429;正常路径 intent 5/5 绿。
+
+### 问题 5|EnergySystem 集成 6 红(全 500)
+1. **问题描述**:`EnergySystemFlowTest` 6 例中 5 例期望 200 实得 500,1 例期望 500 实得业务码 5001。
+2. **测试 bug 点**:`cfc-backend/src/test/java/com/etotem/cfc/integration/EnergySystemFlowTest.java`(overview/logs/exchange/task 四链路)。
+3. **最优修改方案**:先取 surefire 堆栈定位根因(跨 9 轮未变,疑 DB 初始化或能量账户缺失),再决定修产品或修夹具;若为数据前置缺失,用例侧补 `@Sql` 造数。
+4. **修改目的**:恢复五维能量核心链路可验证性(当前等于该链路零有效覆盖)。
+5. **能否闭环**:能。复测:该类 6/6 绿,且全量红数 17 → 11。
+
+### 问题 6|DimensionRegistryMap 契约 3 红(P-9 第 11 轮,待裁决)
+1. **问题描述**:`map_emptyLegacy_returnsNullData` 期望 `data=null` 实得 `""`;`map_missingLegacy_returnsBadRequest` 期望 400 实得 200;`map_unknownLegacy_returnsNullData` 期望 null 实得原值透传。
+2. **测试 bug 点**:`cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DimensionRegistryMapContractTest.java`(3 例)。
+3. **最优修改方案**:由产品/研发就「缺参是否 400、未知 legacy 是否透传」拍板,按裁决要么改实现要么改契约断言(P-9 需给出书面结论)。
+4. **修改目的**:消除「契约未定 → 测试常红」的噪音,恢复红例可归因性。
+5. **能否闭环**:能。复测:该 3 例与裁决一致;红类数 10 → 9。
+
+### 问题 7|平台费字段截断(`MysqlDataTruncation`)
+1. **问题描述**:`GuideModuleIntegrationTest.testGuidePackageCreationFlow:63` 抛 `Data truncation: Out of range value`(平台费超列宽)。
+2. **测试 bug 点**:`cfc-backend/src/test/java/com/etotem/cfc/integration/GuideModuleIntegrationTest.java:63`;对应列定义在 `schema.sql` 分佣/平台费表。
+3. **最优修改方案**:列宽 `DECIMAL(10,2)` → `DECIMAL(18,4)`(或按金额上限评估),并同步 `schema.sql` 与迁移脚本。
+4. **修改目的**:金额计算不因列宽静默失败(财务类高风险)。
+5. **能否闭环**:能。复测:该类 1/1 绿;金额边界用例(1e8 级)新增 2 条。
+
+### 问题 8|前端 3 例预期 RED(S-cfc-30/52/53 契约)
+1. **问题描述**:`health-plan-summary.vue`、`consignee-edit.vue`、`growthHistory.dayGroupView` 契约测试引用的组件/方法未交付,3 例常红。
+2. **测试 bug 点**:`cfc-frontend/__tests__/pages/{health-plan,growth-main}/**`、`signature.consignee.test.js:172`。
+3. **最优修改方案**:研发按 S-cfc-30/52/53 交付组件;测试侧把 3 例标记 `test.todo` 或 `describe.skip`(带契约 ID),交付后解除。
+4. **修改目的**:让「预期 RED」与「真回归」在报表上可区分,避免污染 G3。
+5. **能否闭环**:能。复测:组件交付后 3 例转绿,前端 616/616。
+
+### 问题 9|根级黑盒 16 红(环境型,B-36 第 45 轮)
+1. **问题描述**:`tests/integration/*.spec.js` 16 例全 `ECONNREFUSED 127.0.0.1:9082`(本机未起后端)。
+2. **测试 bug 点**:`tests/jest.config.js` 的 baseURL 固定本机 9082,无 skip 条件或外部实例回退。
+3. **最优修改方案**:增「后端探活 → 不可达则 `describe.skip` 并输出 skip 原因」,或指向内网实例(`cfc.iwintrue.com`)。
+4. **修改目的**:避免 16 条环境红每轮刷屏,掩盖真实回归信号。
+5. **能否闭环**:能。复测:后端未起 → 输出 16 skip(带原因);起后端 → 16 通过。
+
+### 问题 10|网关瞬抖(B-148-1,本轮未触发)
+1. **问题描述**:R148 health 套件首跑 `TC-H-U01` 曾收 502;本轮直跑 **13/13 全绿**(8.5s),未复现 → 维持观察。
+2. **测试 bug 点**:`tests/e2e-live/health-contract.spec.js:51`(未区分「网关 5xx」与「鉴权放行」)。
+3. **最优修改方案**:断言前对 502/503 做 1 次重试(≤2 次,退避 1s),仍 5xx 则 `test.fixme` 并标注「网关不可用」。
+4. **修改目的**:区分部署/网关故障与鉴权缺陷,避免误报安全回归。
+5. **能否闭环**:能。复测:注入 502 → skip 且报告标注环境;正常 → 13/13 绿。
+
+---
+
+## 8. 门禁结论
+
+| 门禁 | 指标 | 阈值 | 实测 | 判定 |
+|------|------|------|------|------|
+| G1 | 全量通过率 | ≥98% | **98.49%**(3725/3782) | ✅ |
+| G2 | 零未归因红 | 0 | 39 红(已三层归因,但未清零) | ❌ |
+| G3 | 前端预期 RED | ≤3 | 3(S-cfc-30/52/53) | ⚠️ |
+| G4 | 管理端全绿 | 116/116 | 116/116 | ✅ |
+| G5 | 编译与产物完整性 | 0 错 / 全 XML | 2121+353 源 0 错;347/347 XML;dump 0 | ✅ |
+| G6 | 浏览器 live | 28/28 | 28/28 + 2 skip | ✅ |
+| G7 | langgraph | 0 红 | 48/51(3 红 401+429 上游) | ❌ |
+| G8 | 线上鉴权 | 5/5 = 401 | 5/5 = 401(admin 域另计) | ✅ |
+| G9 | SRS 场景锚点 | ≥95% | 30.0%(脚本口径 104/347) | ❌ |
+| G10 | 双节点派发 | 均可用 | 189 ✅ 5/5(99s)· 251 ✅ 51 例(151s) | ✅ |
+| G11 | CI 全量门禁 | 阻断 | 后端全量为 observed 非阻断 | ❌ |
+| G12 | SRS 变更合规 | 变更即更新 | 窗口零变更 → 零新增用例 | ✅ |
+
+**最终结论:⚠️ 有条件通过**
+
+- 通过依据:G1 98.49% ≥ 98%、G4/G5/G6/G8/G10/G12 达标;后端与 R148/R146 **逐类逐例零漂移(第 9 次)**,说明本轮无新增回归。
+- 保留条件:① G2 39 红须清零(17 后端红已挂账 9 轮 + 3 langgraph 上游红,需运维轮换 key + 研发排期);② G7 langgraph 3 红须上游修复后连续 2 轮绿方可销号(B-74 复燃 + B-142-2);③ G9 锚点、G11 CI 门禁属结构性缺口,需按 §5 逐项闭环。
+- **不放行结论**:G2/G7/G9/G11 四项未达阈值,故不判「通过」;但因无新增回归、核心链路(登录/家庭/能量/健康/商城/后台)均可用,判「有条件通过」,可否上线由用户与研发团队决定。
+
+---
+
+## 9. 变更、提交与通知
+
+| 项 | 内容 |
+|----|------|
+| 变更判定 | **有变化**:langgraph 50/51 → **48/51**(-2 过,401+429 上游故障);全量 98.55% → **98.49%**;B-74 复燃(key `****ab12` 401 再现);其余套件零漂移 |
+| 提交范围 | `docs/tdd/orchestration/report-test-2026-11-11-R149.md`、`docs/tdd/automation-run-2026-11-11-R149.md`、`docs/tdd/notice-2026-11-11-R149-研发通知.md`、`docs/tdd/test/blockers.md`(追加 R149 段)、`docs/tdd/test/automation-status.md`(附录 R149) |
+| 推送分支 | `origin/cfclub`(rebase 后推,核验 `git branch -r --contains`) |
+| 研发通知 | Agent Mail `GetMe` → 仍 `not_bound`(连接器 connected 但邮箱未开通,按纪律不重试)→ 以 `notice-2026-11-11-R149-研发通知.md` + `blockers.md` + 推送为通知载体 |
+
+---
+
+## 附录 A:本轮命令(可复现)
+
+```bash
+# 环境探针
+/d/jdk1.8.0_25/bin/java -version && /d/maven/apache-maven-3.6.1/bin/mvn -v   # 1.8.0_25 / 3.6.1
+# 后端全量
+cd cfc-backend && JAVA_HOME=/d/jdk1.8.0_25 /d/maven/apache-maven-3.6.1/bin/mvn -o -B clean test   # 39:08
+# 三套 Jest
+cd cfc-web && npx jest --silent                       # 116/116
+cd cfc-frontend && npx jest --silent                  # 616 = 601/3/12
+cd tests && npx jest -c jest.config.js --silent       # 23 = 7/16
+# 浏览器(必须在 tests/ 内跑,否则 @playwright/test 双版本报 test.describe() called here)
+cd tests && npx playwright test -c playwright.config.live.js --project=frontend-mobile --reporter=list  # 6/6
+cd tests && npx playwright test -c playwright.config.live.js --project=shop-api --reporter=list         # 4/4
+cd tests && npx playwright test -c playwright.config.health.js --reporter=list                          # 13/13
+node _r146_189.cjs admin    # 189 admin-desktop 实派 5/5(99s,EXIT=0)
+node _r149_lg.cjs kick && node _r149_lg.cjs read   # 251 langgraph pytest 实派 51 例(151s,48 过)
+# 度量
+python docs/tdd/tools/test_report_metrics.py --repo-root . --scene --out-json _r149/metrics.json
+```
+
+## 附录 B:口径声明
+
+- 后端红数口径:`Tests run: 2946, Failures: 16, Errors: 1, Skipped: 4`(surefire 汇总,与 347 XML 逐类核对一致)。
+- 后端基线纯度:`cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleTagsContractTest.java` 为**未跟踪文件**(仍被编译执行)→ 本轮「347 类」含该文件,HEAD 纯度为 **346 类 / 2935 例**;历轮同口径,未影响可比性。
+- langgraph 口径:`--ignore=tests/qna --ignore=tests/test_chat.py`(B-141-1 阻断 + 历轮排除项),51 例;节点 HEAD `47958709e` = 本机 `1573d89e3` + 1 个 auto bump(零源码差异)。
+- 浏览器口径:28 过 + dx 2 skip = 30。
+- G9 两套口径并存(脚本 30.0% / 严格口径沿用 R148 位置),差异根因见 B-124;本轮判定取脚本口径,仍远低于阈值。

+ 19 - 0
docs/tdd/test/automation-status.md

@@ -1291,3 +1291,22 @@
 | 线上鉴权 | 5/5 匿名 POST → 401 | G8 ✅;`/api/admin/families/overview` 匿名 200 + code:400(B-142-1 第 7 轮) |
 | 节点 | 189:4090 ✅ / 251:4096 ✅ / 204:4090 ✗ | **G10 双节点通过** |
 | 门禁 | ⚠️ **有条件通过** | G1/G4/G5/G6/G8/G10/G12 ✅;G2/G7/G9/G11 ❌;G3 ⚠️ |
+
+### 附录 R149(2026-11-11 18:30 · 后端强制实跑 + langgraph B-74 复燃)
+
+| 项 | 值 | 说明 |
+|---|---|---|
+| 后端全量 | **347 类 / 2946 例 / 2925 过 / 17 红 / 4 跳 = 99.29%** | `mvn -o -B clean test`,**39:08**;347/347 XML;2121 + 353 源编译 0 错;`*.dump` = 0 |
+| 红例三桶 | 产品 14 + 契约待裁决 3 + 数据 1 = 17 | 与 R148/R146 **逐类逐例一致 → 零回归(第 9 次)** |
+| 基线纯度 | 347 类 = HEAD 346 类 + 未跟踪 `ArticleTagsContractTest.java` | 历轮同口径 |
+| 前端 Jest | 616:601 过 / 3 红 / 12 跳(60.8s) | 3 红为 S-cfc-30/52/53 预期 RED |
+| 管理端 | 116/116(17 套件,180s) | 零漂移 |
+| 根级黑盒 | 23:7 过 / 16 红(7.0s) | B-36 第 45 轮,全 `ECONNREFUSED 9082` |
+| langgraph@251 | **51 例 / 48 过 / 3 红 / 151s** | 3 红全在 `test_auto_tag.py`(chat 500,**401 key `****ab12` + 429 AgnesAI**)→ **B-74 复燃** + B-142-2 第 3 轮未绿 |
+| 浏览器 | **28/28 + 2 skip** | 189 admin 5/5(99s)+ 本机 fe 6 / shop 4 / health 13;dx 2 skip(404) |
+| 全量 | **3782 例 / 3725 过 = 98.49%**(剔 skip 98.96%) | 红 39 / 跳 18 |
+| 新增用例数 | **0** | specs 201 / test-cases 15 窗口零变更(G12 ✅) |
+| TC 锚点 | 347 唯一 TC → 脚本口径 **104 = 30.0%**;严格口径(R148 位置)~18.5% | 两套口径并存(B-124 延续) |
+| 线上鉴权 | 5/5 匿名 POST → 401 | G8 ✅;`/api/admin/families/overview` 匿名 200 + code:400(B-142-1 第 8 轮) |
+| 节点 | 189:4090 ✅ / 251:4096 ✅ / 251:9000 ✅ / 204:4090 ✗ | **G10 双节点通过**(B-95 第 20 轮) |
+| 门禁 | ⚠️ **有条件通过** | G1/G4/G5/G6/G8/G10/G12 ✅;G2/G7/G9/G11 ❌;G3 ⚠️ |

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

@@ -744,3 +744,29 @@
 > **全量 3782 / 3727 过 = 98.55%**(剔 skip 99.02%)。
 > **结论**:⚠️ **有条件通过** —— G1 ✅ 98.55%、G4 ✅、G5 ✅、G6 ✅ 28/28、G8 ✅ 5/5、**G10 ✅ 双节点**、G12 ✅;❌ G2 37 红、**G7 langgraph 1 红(由上轮 ✅ 回落)**、G9 30.0%、G11 无 CI;⚠️ G3 3 预期 RED。
 > **变化点**:langgraph 0 红→1 红(B-142-2 复验未过、不销号)、全量 98.57%→98.55% → **已推送 + 通知研发**。
+
+## R149 轮(2026-11-11 18:30,HEAD `1573d89e3`,后端强制实跑 + langgraph B-74 复燃)
+
+| 编号 | 关联键 | 类型 | 描述 | 经办 | 登记时间 | 状态 |
+|---|---|---|---|---|---|---|
+| **B-74-复燃(第 1 轮)** | 251 LLM API key `****ab12` 401 + 429 | 运维/AI(P0) | **复燃(曾于 R127/R128 销号)**。langgraph **51 例 / 48 过 / 3 红 / 151s**;红例 `test_auto_tag_{content_relevance,short_content,empty_content}` → chat **500**,日志两级证据:`recall 记忆失败: 401 Authentication Fails, api key ****ab12 is invalid` + `intent 分类失败: 429 AgnesAI free rate limit` + middleware `RateLimitError → 500`。需运维**轮换 key + 升级额度**。 | 测试(R149 实派) | 2026-11-11 18:30 | 待处理(P0) |
+| **B-142-2-Update(第 3 轮未绿)** | 251 LLM 上游故障 | 运维/AI(P0) | **不销号(形态漂移 ConnectError→401/429)**。连续 2 轮绿方可销号,本轮 3 红未达。 | 测试(R149 实派) | 2026-11-11 18:30 | 待处理(观察 0/2) |
+| **B-142-1-Update(第 8 轮)** | `/api/admin/**` 鉴权门缺失 | 研发(P1 安全) | **延续(8 轮未修)**。匿名 `POST /api/admin/families/overview` → HTTP **200** + `code:400`;对照组 5 端点全 401。 | 测试(R149 巡检) | 2026-11-11 18:30 | 待处理 |
+| **B-145-1-Update(第 5 轮)** | `nutrition_age_dosage` 建表 SQL 无效 | 研发(P1 Schema) | **延续(5 轮未修)**。`schema.sql:5343` 无效索引 `idx_product(product_id)` → 表从未创建成功。 | 测试(R149 复核) | 2026-11-11 18:30 | 待处理 |
+| **B-134-4-Update(第 12 轮)** | intent_classifier 兜底伪装 | 研发/AI(P1) | **延续(缺陷仍在,本轮触发路径为 401+429)**。`app/intent_classifier.py:62` 异常 → 默认 `chat`。 | 测试(R149 实派) | 2026-11-11 18:30 | 待处理 |
+| **B-95-Update(第 20 轮)** | `192.168.16.204:4090` 失联 | 运维(P2) | **延续**。204:4090 → **000**;189:4090 = 200、251:4096/9000 = 200。 | 运维 | 2026-11-11 18:30 | 待处理 |
+| **B-DX-1-Update(第 11 轮)** | dx-bridge 端点 404 | 部署(P2) | **延续**。浏览器 dx-bridge 2 例 skip(端点 404)。 | 部署/运维 | 2026-11-11 18:30 | 待处理 |
+| **B-36-Update(第 45 轮零漂移)** | 根级黑盒门控 | 测试(P3) | **零漂移**。23 例 7 过 / 16 红,全 `ECONNREFUSED 127.0.0.1:9082`。 | 测试 | 2026-11-11 18:30 | 待处理(环境型) |
+| **B-138-3-Update(第 7 轮)** | 后端超慢测试类 | 研发(P3 效率) | **延续**。本轮全量 **39:08**(R148 51:57、R146 44m),慢类仍占大头。 | 测试(R149 实测) | 2026-11-11 18:30 | 待处理 |
+| **B-69-Update(第 12 轮销号维持)** | mind/fortune 匿名 200 | 研发(P1) | **维持销号**。匿名 POST 5 端点(mind/fortune、energy/overview、health/plan/list、huawei-health、xiaomi-health)**全 401**。 | 测试(R149 巡检) | 2026-11-11 18:30 | 已闭环 |
+| **B-148-1-Update(第 2 轮未复现)** | 网关瞬抖 502 | 运维(P3) | **未复现**。health 套件直跑 **13/13 全绿**(8.5s),无 502;维持观察。 | 测试(R149 巡检) | 2026-11-11 18:30 | 观察中 |
+| **B-141-3-Update** | 站点根 `/` 502 | 运维(P3) | **维持观察**。`/` = **404**、`/admin` = 302、`/frontend` = 302。 | 测试(R149 巡检) | 2026-11-11 18:30 | 观察中 |
+| **B-126-Update(第 10 轮)** | pytest 收尾 `EXIT=124` | 测试(P3) | **本轮正常收尾**:`/tmp/r149_pytest.log` 含 `3 failed, 48 passed, 8 warnings in 151.00s` 完整 summary,无挂起。 | 测试 | 2026-11-11 18:30 | 观察中 |
+| **B-141-1(延续)** | qna 收集期缺陷 | 研发(P1) | **延续(排除项)**。pytest 口径 `--ignore=tests/qna --ignore=tests/test_chat.py`。 | 测试(R149 实派) | 2026-11-11 18:30 | 待处理 |
+
+> **R149 口径**:后端**强制实跑**(窗口含研发版本 bump,继续实跑取证)。
+> 后端 **347 类 / 2946 例 / 2925 过 / 17 红 / 4 跳 = 99.29%**(39:08,347/347 XML;dump 0;与 R148/R146 逐类逐例一致 → **零回归第 9 次**)。
+> 浏览器 **28/28 + dx 2 skip**(189 admin 5/5 99s、本机 fe 6/shop 4/health 13);**langgraph 51 例 48 过 / 3 红(401 `****ab12` + 429,B-74 复燃)**;cfc-web 116/116;cfc-frontend 601/3/12;根级 23 = 7/16。
+> **全量 3782 / 3725 过 = 98.49%**(剔 skip 98.96%)。
+> **结论**:⚠️ **有条件通过** —— G1 ✅ 98.49%、G4 ✅、G5 ✅、G6 ✅ 28/28、G8 ✅ 5/5、**G10 ✅ 双节点**、G12 ✅;❌ G2 39 红、**G7 langgraph 3 红(B-74 复燃)**、G9 30.0%、G11 无 CI;⚠️ G3 3 预期 RED。
+> **变化点**:langgraph 1 红→3 红(B-74 复燃 + B-142-2 未绿)、全量 98.55%→98.49% → **已推送 + 通知研发**。