Browse Source

test(R221): 测试闭环汇报 — 后端全量4415例91.91%(契约336+存量17零漂移第35次) + lg@251 43/43首次全绿 + 测试侧修EnergyLedgerGuard off-by-one(13/13) + 189首跑5/5

Test Lead 10 hours ago
parent
commit
8582fac19d

+ 11 - 5
cfc-backend/src/test/java/com/etotem/cfc/unit/EnergyLedgerGuardContractTest.java

@@ -174,15 +174,19 @@ class EnergyLedgerGuardContractTest extends EnergyContractTestBase {
         consistent.add(energyLog(3L, 50L, 5L, -3, 12, "wish", 300L));
         int breachesConsistent = referenceCountBreaches(consistent); // = 0
 
-        // 断点序列:第2条 balanceAfter=16,而 prev(10)+amount(5)=15 → 1 处断点
+        // 断点序列:第2条 balanceAfter=16,而 prev(10)+amount(5)=15 → 1 处断点。
+        // 第3条取 13(= 断点余额 16 + amount -3),使"只有第2条错、其下游自洽"的语义成立;
+        // 若沿用历史值 12,则第3条自身也构成第2处断点(16-3=13≠12),与"1 处断点"的用例语义矛盾。
         List<EnergyLog> broken = new ArrayList<>();
         broken.add(energyLog(1L, 50L, 5L, 10, 10, "task", 100L));
         broken.add(energyLog(2L, 50L, 5L, 5, 16, "checkin", 200L));
-        broken.add(energyLog(3L, 50L, 5L, -3, 12, "wish", 300L));
-        int breachesBroken = referenceCountBreaches(broken); // = 1
+        broken.add(energyLog(3L, 50L, 5L, -3, 13, "wish", 300L));
+        List<Long> breachesBrokenIds = referenceCountBreachesDetail(broken); // = [2]
 
         assertEquals(0, breachesConsistent, "参考算法前置:一致序列必须检出 0 处断点");
-        assertEquals(1, breachesBroken, "参考算法前置:断点序列必须检出 1 处断点,且能定位到具体流水");
+        assertEquals(1, breachesBrokenIds.size(), "参考算法前置:断点序列必须检出 1 处断点,且能定位到具体流水");
+        assertEquals(Arrays.asList(2L), breachesBrokenIds,
+                "参考算法前置:断点必须精确落在第2条流水(id=2,balanceAfter=16 ≠ prev10+amount5)");
 
         // 契约:宿主 EnergyService 应暴露等价对账入口(TC-X-20-E:不一致报警并定位断点,不静默通过)
         boolean hasPublicReconcile = false;
@@ -385,7 +389,9 @@ class EnergyLedgerGuardContractTest extends EnergyContractTestBase {
         for (int i = 0; i < sorted.size(); i++) {
             EnergyLog log = sorted.get(i);
             if (i == 0) {
-                prevBalance = log.getBalanceAfter() == null ? 0 : log.getBalanceAfter() - (log.getAmount() == null ? 0 : log.getAmount());
+                // 首条无前序流水:只能把它当作对账锚点(期初余额未知,不可反推为 balanceAfter-amount,
+                // 否则会把首条之后的正常序列整体判为断点——历史 off-by-one 缺陷根因)。
+                prevBalance = log.getBalanceAfter() == null ? 0 : log.getBalanceAfter();
                 continue;
             }
             int expected = prevBalance + (log.getAmount() == null ? 0 : log.getAmount());

+ 43 - 0
docs/tdd/orchestration/notice-2026-11-15-R221-研发通知.md

@@ -0,0 +1,43 @@
+# 研发通知 · R221 测试闭环(2026-11-15 20:35)
+
+> 发件:测试负责人(软件测试专家团)|收件:研发 / 运维|关联报告:`docs/tdd/orchestration/report-test-2026-11-15-R221.md`
+> 基线:`origin/cfclub` `d39aa5282`(窗口 2 提交,含 **S-cfc-390 五维能量账本一致性守卫**,7 个 src/main 文件 +243/−1)
+
+## 一、本轮结论:不通过(有条件,较上轮明显正向)
+
+- 后端**全量实跑 40:06**:505 类 / **4415 例** / 4058 过 / **353 红** / 4 跳 = **91.91%**(剔 skip 92.00%;**剔 336 契约前瞻 = 99.58%**)。
+- langgraph@251:**43/43 全绿**(186.56s,上轮 35/43)。
+- 浏览器 E2E:本机 **28 过 + 2 跳**;189 admin **5/5 首跑即绿**。
+- 前端 Jest:web 124/134、fe 644/4/12/660、根级 7/16/23 — **逐例零漂移**。
+
+## 二、需要研发处置的问题(按优先级)
+
+| # | 编号 | 优先级 | 问题 | 位置 | 建议修法 |
+|---|---|---|---|---|---|
+| 1 | **B-218-1** | **P0** | `@Resource` 字段名与 `DimensionScoreService` Bean 名相同 → 运行期 `BeanNotOfRequiredTypeException`,butler/coach 链路不可启动 | `CoachRecommendService.java:71-72`(另查 `ButlerResourceMatchService.followUpMapper`、`HealthDataSourceBridgeService.dimensionScoreService`) | 字段改名或 `@Resource(name="...")` 显式限定;守卫用例 `ResourceBeanNameCollisionGuardTest` 1/1 红即为未修 |
+| 2 | **B-218-2** | **P1(资金)** | 支付配置缺失仍落 131400 分待支付订单 | `MembershipPaySwitchTest` 1F、`PaymentServiceORDRoutingTest` 1F | 下单前强校验 `pay.channel`;未知 payScene 抛业务异常 |
+| 3 | **G11** | **P1(门禁)** | CI 已知红类清单 **33 类 vs 实测 70 红类** → 漏拦 **63**、陈旧 **26**,`backend-blocking-junit` 必红 | `.gitlab-ci.yml:61 BACKEND_OBSERVED_CLASSES` | 由 `target/surefire-reports/*.xml` 自动生成清单,job 内先生成后门禁 |
+| 4 | **B-221-4** | **P2(流程)** | 189 节点仓库 HEAD 停在 `1e3bea680`(`cfclub` 被 worktree 占用 + 无法 ff) → 节点跑的不是本轮基线 spec | `_r203_189_dispatch.cjs` 的 `E2E_CMD` | 节点改用独立 worktree/detach 拉取,派发输出须打印 HEAD 供核对 |
+| 5 | **B-218-10** | **P1(AI 服务)** | pytest 打印 summary 后进程不退出(第 22 轮),残留进程已 `pkill` 清理 | `cfc-langgraph` `JavaClient`(`RuntimeWarning: coroutine 'JavaClient._get_client' was never awaited`) | 补 `await client.aclose()`;派发器加 `timeout -k 10 900` |
+| 6 | **B-221-5** | **P2(装置)** | 后端全量 40:06,慢类 Top1 `ActivityControllerTest` 148.5s | controller 层 `@SpringBootTest` 全上下文 + 无 `application-test.yml` | 新增 `application-test.yml`(关 scheduler),慢类改 `@WebMvcTest` 切片 |
+| 7 | **B-36** | **P2(测试环境)** | 根级黑盒 16 红全部 `ECONNREFUSED 127.0.0.1:9082`(第 98 轮) | `tests/integration/*.spec.js` 硬编码 BASE_URL | 改 `process.env.BASE_URL` 可覆盖 |
+| 8 | **B-DX-1** | **P1(部署)** | `/api/health/data-sources/bridge/list`、`/sync-status` 持续 404(第 55 轮) | D/X 桥接未部署 | 按规格 `2026-11-08-dx-health-bridge.md` 实现或标注 `blocked` |
+| 9 | **B-218-3** | **P1(运维)** | 线上 `/api/**` 502 窗口**第 4 轮复现**(19:36 前后,health 首跑 4 例 502,同刻 curl 3/3=401) | 网关 → 9082 链路 | 查连接池/超时/重试;连续 3 轮无 502 销号 |
+
+## 三、已闭环/无需处置
+
+| 编号 | 说明 |
+|---|---|
+| **B-221-1** | `EnergyLedgerGuardContractTest` 参考对账算法 off-by-one(首条流水误把期初余额反推为 `balanceAfter-amount`)+ 断点夹具第 3 条不自洽 → **测试侧已修**:首条锚定 `prevBalance = balanceAfter`、夹具改 13、断言强化为 `Arrays.asList(2L)` → **13/13 绿**(`S-cfc-390` 契约链路完整,无需研发动作) |
+| **B-221-3** | 251 派发模型 `axon/deepseek3.2` 已下线(`provider.no-route`)→ 改 `opencode/deepseek-v4.1-flash-free` 并支持 `LG_MODEL_ID/LG_PROVIDER_ID` 覆盖,派发恢复 |
+| **B-216-3/B-220-1** | langgraph 上游 429/401/ConnectError 本轮**未复现**(43/43)→ 转观察 1/3,连续 3 轮全绿后销号 |
+
+## 四、正向变化(建议记录)
+
+1. **S-cfc-390 契约闭环**:`EnergyLedgerGuardContractTest` 13 例全绿(含 `isMemberInFamily` 403 归属守卫、`isAlreadyApplied` 幂等、`reconcileLedger` 对账、`@Version` 乐观锁、`uk_energy_idempotency` 唯一键)。
+2. **lg 首次全绿**:43/43,说明上游网关与 key 状态恢复。
+3. **189 admin 首跑 5/5**:双节点互备稳定(B-208-1 观察 2/3)。
+
+## 五、复评条件
+
+B-218-1 守卫绿 → B-218-2 两键 9 例绿 → 实红由 33 降为 16(存量)→ G11 清单自动生成 → G2 达 0(剔预期红)。lg 需连续 3 轮全绿方可判「上游稳定」。

+ 359 - 0
docs/tdd/orchestration/report-test-2026-11-15-R221.md

@@ -0,0 +1,359 @@
+# 测试负责人工作汇报 R221(2026-11-15 20:35 GMT+8 · 自动化闭环)
+
+> 测试负责人:陆谨(软件测试专家团 · 测试架构师)|执行档:**review(离线白名单)+ 内网浏览器 E2E(实跑)+ 远程节点派发(251 langgraph / 189 admin)**|静默无人值守,全程未提问
+> 基线:`origin/cfclub` **`d39aa5282`**(HTTP 通道 fetch,SSH 失效 B-203-3);本机 HEAD `6c8ac19cc`(R220)。窗口 `28eb1221c..d39aa5282` **2 提交**(1 功能 + 1 auto bump),**含 src/main 变更 7 文件 +243/−1**(S-cfc-390 五维能量账本一致性守卫)
+> **本轮头条:① 后端全量实跑 40:06 —— 505 类 / 4415 例 / 4058 过 / 353 红 / 4 跳 = 91.91%,红集归因「契约前瞻 336 + 存量 17(零漂移第 35 次)」;② langgraph@251 **43/43 首次全绿**(186.56s,上轮 35/43);③ 测试侧自修 1 处用例缺陷(`EnergyLedgerGuardContractTest` 参考对账算法 off-by-one + 断点夹具不自洽)→ 13/13 绿;④ health 鉴权首跑 4 红(实测 502 窗口)→ 复跑 13/13,**B-218-3 第 4 轮复现**;⑤ 189 admin 首跑 5/5 全绿(B-208-1 好转);⑥ G11 CI 清单 33 类 vs 实测 70 红类 → 漏拦 63 / 陈旧 26**
+
+---
+
+## 0. 历史审查记录(对照,非本次结论依据)
+
+| 项 | 内容 |
+|---|---|
+| 上次审查 | **R220(2026-11-15 19:25)**,结论「不通过」;lg@251 35/43(8 红环境型)、189 admin 首跑 3/5→复跑 5/5、后端**承采 R218**(503 类/4393 例/89.96%) |
+| 本次 | **第 221 轮,非首次审查**(记忆库停在 R218,仓库实际已到 R220;本轮以 git 真相为基线) |
+| 历史遗留 → 本次状态 | **B-218-1(P0 Bean 撞名)** → **仍红**(`ResourceBeanNameCollisionGuardTest` 1/1 F,承袭第 2 轮)<br>**B-218-2(P1 支付开关)** → **仍红**(`MembershipPaySwitchTest` 1F + `PaymentServiceORDRoutingTest` 1F)<br>**B-218-3(P1 线上瞬时 502)** → **第 4 轮复现**(health 首跑 4 例 502,复跑全绿)<br>**B-216-3/B-220-1(lg 上游配额/key/连接)** → **本轮未复现**(43/43 全绿),观察 1/3<br>**B-218-10(lg 进程不退出)** → **第 22 轮复现**(summary 后 2 进程存活,已 kill -9)<br>**B-36(本机 9082 未起)** → 第 98 轮(根级 7/16)<br>**B-DX-1(dx 2 跳 404)** → 第 55 轮 |
+| 本次新增 | **B-221-1(P2 用例缺陷·已闭环)** `EnergyLedgerGuardContractTest` 参考算法 off-by-one;**B-221-2(P1 环境)** 线上 `/api/**` 502 窗口 4 例假红;**B-221-3(P2 工具)** 251 派发模型路由 `axon/deepseek3.2` 已下线;**B-221-4(P2 流程)** 189 节点仓库 HEAD 落后(checkout 被并行 worktree 占用);**B-221-5(P2 度量)** 后端全量 40:06 慢类 Top1 148.5s |
+
+> 历史记忆只作对照:本轮**全部套件重新取证**(后端全量实跑、浏览器双节点、lg@251 实派、web/fe/根级 Jest、线上 API、台账刷新)。
+
+---
+
+## 1. 执行总览
+
+| 套件 | R221(本轮) | R220(上轮) | 漂移 |
+|---|---|---|---|
+| 基线 | `d39aa5282`(窗口 2 提交,**含 src/main 7 文件**) | `28eb1221c`(窗口 20 提交) | 窗口含功能变更 |
+| 后端 · 全量 | **实跑 40:06**:505 类 / 4415 例 / **4058 过** / 342F+11E=353 红 / 4 跳 = **91.91%**(剔 skip 92.00%) | 承采 R218 503 类/4393 例/89.96% | **首次在全量中纳入 S-cfc-390 新代码** |
+| 后端 · 定向 | `EnergyLedgerGuardContractTest` **13/13 绿**(测试侧修复后) | —(该键 12/13 红) | **闭环 B-221-1** |
+| 浏览器 E2E · admin(本机) | **5/5**(1.6m) | 5/5 | 实跑一致 |
+| 浏览器 E2E · admin(189) | **5/5 EXIT=0**(1.3m,**首跑即全绿**) | 首跑 3/5→复跑 5/5 | **B-208-1 好转** |
+| 浏览器 E2E · frontend(本机) | **6/6**(48.8s) | 6/6 | 一致 |
+| 浏览器 E2E · shop-api | **4/4**(6.5s) | 4/4 | 一致 |
+| 浏览器 E2E · health | **首跑 9/13(4×502)→ 复跑 13/13**(11.2s) | 13/13 | **B-218-3 第 4 轮复现,复跑闭环** |
+| 浏览器 E2E · dx-bridge | **2 跳**(404,第 55 轮) | 2 跳 | 一致 |
+| langgraph@251 | **43/43 全绿**(186.56s) | 35/43(8 红) | **★ 首次全绿(+8)** |
+| cfc-web Jest | **124 过 / 10 红 / 134**(21 套,31.5s) | 124/10/134 | 逐例零漂移 |
+| cfc-frontend Jest | **644 过 / 4 红 / 12 跳 / 660**(46 套,30.4s) | 644/4/12/660 | 逐例零漂移 |
+| 根级黑盒 Jest | **7 过 / 16 红 / 23**(8.4s,全 ECONNREFUSED 9082) | 7/16/23 | B-36 第 98 轮 |
+| 线上 API(点名 4 文件) | **25 过 / 0 红 / 7 跳 / 32 例**(17.6s) | 25/0/7 | 一致 |
+
+**全站合计(剔除口径见 §9)**:**5342 例 / 4935 过 / 382 红 / 25 跳 = 92.37%**(剔 skip 92.81%;剔 349 预期红 = **99.34%**,实红 **33**)
+
+**覆盖台账(本轮 discover + inventory 实跑刷新)**
+- 控制器 **374**|handler 方法 **2029(覆盖 557 = 27.4%)**|测试文件 **512(@Test 4399)**
+- 结构化用例 **947** + Playwright **571** + Python **48** + Java@Test **4399** + 场景文件 **11** = **5965**
+
+**测试结果有变化(R220 → R221)— 已触发提交与研发通知**
+- 🟢 **langgraph 43/43 首次全绿**(+8 例,B-216-3/B-220-1 本轮未复现,转「观察 1/3」)。
+- 🟢 **189 admin 首跑 5/5**(上轮首跑 3/5 需复跑)。
+- 🟢 **测试侧闭环 1 例(B-221-1)**:`EnergyLedgerGuardContractTest` 13/13,`S-cfc-390` 契约链路完整。
+- 🔴 **后端全量首次覆盖 S-cfc-390 新代码**:4415 例(+22 例 vs 承采口径),红 353,其中**存量 17 零漂移**、契约前瞻 336。
+- 🔴 **health 首跑 4 例 502**(B-218-3 第 4 轮),复跑全绿 → 环境型瞬态,非回归。
+
+---
+
+## 2. 项目画像(本轮视角)
+
+- **业务定位**:家庭教育 SaaS(五维能量 · 成长规划 · 测评订单 · 商城 · 健康报告解析 · 家庭工作台 · AI 教练),双端(小程序 H5 `cfc.iwintrue.com/frontend` + Web 管理端 `cfc.iwintrue.com/admin`)。
+- **技术栈**:Spring Boot 2.7.18 / Java 8 / MyBatis-Plus(9082)· uni-app Vue2(H5)· Vue2+Element(8082)· FastAPI+LangGraph(9000/生产 `ai.etotem.com.cn`)· Maven 3.9.9 + JDK1.8.0_25。
+- **节点探活(19:30~20:30)**:站点 `/admin` `/frontend` **302**;**本机** 4091=200、Chromium 1228 就位;**189** 4090=200(admin E2E 派发成功);**251** 4096=200(lg 派发成功)/**9000 CLOSED**(lg live 链路面不可实测);**251:3306 Open**(后端全量可连库,本轮因此可实跑)。
+- **通道**:fetch/push 全程 HTTP `http://git.iwintrue.com/liaoxg/cfc.git`(SSH 失效,承 B-203-3)。
+- **窗口事件**:`d39aa5282 feat(energy.ledger.guard): S-cfc-390` 改 7 个 src/main 文件(EnergyService +169、EnergyRuleEngine +33、JwtInterceptor +15、DatabaseInitializer +13、schema.sql、EnergyController、EnergyBalance),并自带契约测试 `EnergyLedgerGuardContractTest`(13 例)与守卫 `ResourceBeanNameCollisionGuardTest`。
+- **风险点**:① 69 个契约类前瞻(352 例);② **Bean 撞名 P0 仍红**(B-218-1,运行期阻断);③ 支付开关语义缺陷(B-218-2);④ 线上 502 周期窗口(B-218-3 第 4 轮);⑤ CI 清单严重失真(漏拦 63);⑥ lg 进程不退出(B-218-10 第 22 轮)。
+
+---
+
+## 3. 20 类测试覆盖矩阵
+
+| # | 测试类型 | 层次 | 状态 | 证据(本轮实测) |
+|---|---|---|---|---|
+| 1 | 单元测试 | 功能层次 | **已发现** | 后端全量 505 类 / 4415 例实跑;web 21 套 134 + fe 46 套 660(Jest) |
+| 2 | 组件测试 | 功能层次 | **已发现** | web/fe `__tests__/components`、views 级组件用例实跑零漂移 |
+| 3 | 集成测试 | 功能层次 | **已发现** | 后端 `integration/**` 实跑:`EnergySystemFlowTest` 6F、`GuideModuleIntegrationTest` 1E(存量) |
+| 4 | 契约测试 | 功能层次 | **已发现(红集主体)** | 61 个 `*Contract*` 类/336 例红(前瞻);本轮新增 `EnergyLedgerGuardContractTest` **13/13 绿**(修后) |
+| 5 | 接口 API 测试 | 功能层次 | **已发现** | 线上点名 4 文件 32 例 25 过 7 跳;shop 排序 4/4;health 13/13 全 401/403 |
+| 6 | 系统/端到端 | 功能保障 | **已发现(实跑)** | **本机 28 过 + 2 跳 + 189 admin 5/5**(首跑即绿) |
+| 7 | 验收 UAT | 功能保障 | **部分已发现** | 场景文件 11 份;无人工 UAT 签署记录 |
+| 8 | BDD 规格 | 功能保障 | **未发现** | 仓库无 `.feature`/cucumber → 缺口 |
+| 9 | 冒烟测试 | 功能保障 | **已发现** | `tests/e2e-live/api-smoke` 4/4 绿(线上) |
+| 10 | 回归测试 | 功能保障 | **已发现** | 后端全量 40:06 + web/fe/根级/浏览器逐例对照;**存量 16 例零漂移第 35 次** |
+| 11 | 探索性测试 | 功能保障 | **未发现** | 无人值守窗口不做 chartered 探索 |
+| 12 | 性能测试 | 非功能 | **未发现(未实测)** | 无 k6/JMeter;execute 档未授权 → 不写通过 |
+| 13 | 可靠性测试 | 非功能 | **部分已发现** | **health 首跑 4×502 → 复跑全绿**(B-218-3 第 4 轮);无故障注入 |
+| 14 | 安全测试 | 非功能 | **部分已发现** | 匿名 6 端点全 401;health 13/13 全 401/403;shop 非法排序列白名单;无 SAST/依赖扫描 |
+| 15 | 兼容性测试 | 非功能 | **部分已发现** | Chromium 双视口(1440×900 / 375×812 isMobile);无多浏览器矩阵 |
+| 16 | 可用性测试 | 非功能 | **未发现** | 无 SUS/任务完成率记录 |
+| 17 | 无障碍测试 | 非功能 | **未发现** | 无 axe/WCAG 断言 |
+| 18 | QA 流程 | 度量与流程 | **部分已发现** | 双节点 E2E 互备 + 派发脚本;CI 清单失真(G11 ❌) |
+| 19 | 质量指标 | 度量与流程 | **已发现** | 通过率/红例/覆盖率/场景映射四指标本轮全部刷新(§10 附录 C) |
+| 20 | 全项目代码审查 | 度量与流程 | **部分已发现** | 守卫用例 `ResourceBeanNameCollisionGuardTest` 静态审查 Bean 撞名(1 红);本轮未做全量源码通读 |
+
+---
+
+## 4. 测试方案(本轮实际执行)
+
+| 维度 | 范围 | 执行方式 | 结果 |
+|---|---|---|---|
+| 后端单元/集成/契约 | 全量 505 类 | `mvn -o -B clean test`(隔离 worktree,`d39aa5282`) | 4415 例,40:06 |
+| 后端定向 | `EnergyLedgerGuardContractTest` | `-Dtest=` 定向复跑 | 13/13 绿(修后) |
+| 浏览器 E2E | 本机 admin/fe/shop/health/dx | `playwright test -c live/health config`(单节点串行) | 28 过 + 2 跳 |
+| 浏览器 E2E(远端) | 189 admin | opencode `/api/shell` 派发 `admin-desktop` | 5/5 EXIT=0 |
+| AI 服务 | 251 langgraph pytest | opencode 会话派发 + 远端日志二次读取 | 43/43 |
+| 前端单元 | cfc-web / cfc-frontend / 根级 | `node node_modules/jest/bin/jest.js` | 134 / 660 / 23 |
+| 线上接口 | 点名 4 文件(api-smoke / nonfunc-security / nonfunc-perf-compat / traceability) | `playwright test -c playwright.config.api.js <files>` | 32 例 25/0/7 |
+| 安全/鉴权 | 匿名 6 端点 + health/yun 契约 | curl 直连 + Playwright | 6/6=401;13/13 401/403 |
+
+**排除项(并说明)**:性能压测(execute 档未授权)、多浏览器矩阵(无 Safari/Firefox 运行时)、BDD(仓库无规格资产)、UAT(需人工签署)、lg live 链路(251:9000 CLOSED)。
+
+---
+
+## 5. 执行档与授权
+
+- 实际执行档:**review(离线白名单)+ 内网实跑**。未安装依赖、未启停生产服务、未改任何 `src/main` 生产代码。
+- 联网动作仅限:访问 `cfc.iwintrue.com`(站点 E2E/接口契约)、`192.168.16.189:4090` 与 `192.168.16.251:4096`(节点派发)——均为任务书显式指定的测试通道。
+- 唯一代码改动:**测试源码 1 处**(`EnergyLedgerGuardContractTest` 参考算法 + 断点夹具),属测试侧自修,已在本报告 §8 问题 1 完整披露。
+
+---
+
+## 6. 覆盖缺口清单
+
+| 编号 | 缺口类型 | 现状 | 风险 | 建议测试设计 | 优先级 | 闭环方式 |
+|---|---|---|---|---|---|---|
+| G-221-1 | 性能测试 | 无压测资产,全量耗时 40:06 | 无法量化容量与劣化趋势 | 对 `/api/growth/**`、`/api/energy/**` 做 k6 基线(P95<800ms) | P1 | 需 execute 档 + 联网授权 |
+| G-221-2 | 可靠性 | 502 窗口复现 4 轮,无故障注入 | 瞬态 502 会被误判为用例回归(本轮 4 例) | 用例层加「5xx 视为环境不可用 → 重试 2 次后 skip 并标注」 | P1 | 改 4 个 spec 的断言健壮性 |
+| G-221-3 | 无障碍 | 无 WCAG 断言 | 管理端/小程序可访问性无证据 | Playwright + axe-core 扫描 admin 5 页 + fe 3 页 | P2 | 新增 `a11y.spec.js` |
+| G-221-4 | BDD | 仓库无 `.feature` | 场景与用例之间缺可执行桥梁 | 选 SC-P-85(会话互斥)做 3 条 feature 试点 | P2 | 引入 cucumber-js |
+| G-221-5 | 性能(用例层) | `@SpringBootTest` 慢类 Top1 148.5s(ActivityControllerTest) | 全量 40 分钟,反馈慢 | 慢类补 `application-test.yml` 或切片为 `@WebMvcTest` | P2 | 研发侧装置优化 |
+| G-221-6 | 覆盖率 | handler 覆盖 557/2029 = 27.4%(JaCoCo 未开) | 覆盖率不可度量 | 开启 JaCoCo 并在 CI 设 40% 门槛 | P1 | 研发加插件 |
+| G-221-7 | 场景映射 | 用例台账层 90/152 = 59.2% | 62 个 SC 无台账用例锚点 | 按 §10 清单逐条补 TC 或标注「由代码级用例覆盖」 | P2 | 台账补登 |
+| G-221-8 | CI 门禁 | 清单 33 类 vs 实测 70 红类 | `backend-blocking-junit` 必红,门禁形同虚设 | 由 surefire 红类自动生成清单(脚本化) | P1 | 研发改 `.gitlab-ci.yml` |
+| G-221-9 | lg 进程治理 | summary 后进程不退出(第 22 轮) | 残留进程污染下一轮 | 派发器加 `timeout -k 10 900`;产品侧 `await client.aclose()` | P1 | 派发器已可加参数 |
+| G-221-10 | 契约前瞻 | 61 类/336 例红 | 红集淹没真实缺陷 | 契约类红例单独 job,不阻塞主门禁 | P2 | CI 分层 |
+
+---
+
+## 7. 域结论表
+
+| 审查维度 | 负责专家 | 结论 | 关键证据 |
+|---|---|---|---|
+| 单元·组件级 | 苏雅 | **有条件通过**:4415 例实跑 91.91%,剔契约前瞻 99.58% | `_r221_backend_full.log`、505 份 surefire XML |
+| 集成·接口级 | 柯砚 | **不通过(局部)**:`EnergySystemFlowTest` 6F(HTTP 500)、`GuideModuleIntegrationTest` 1E(`platform_fee INT` 溢出)、线上 API 25/0/7 | 同上 + `_r221_api` |
+| 系统·验收级 | 白樾 | **通过(浏览器面)**:本机 28 过 + 2 跳、189 5/5、场景层 152/152 | `_r221_browser_local1/2.log`、189 派发输出 |
+| 测试保障级 | 闻朔 | **有条件通过**:回归逐例可比、冒烟 4/4;探索性/BDD 缺口 | Jest 三套 + API smoke |
+| 性能·可靠性 | 骆骋 | **不通过(未实测性能)**:无压测;可靠性仅 502 观察 | 40:06 全量耗时、慢类 Top6 |
+| 安全 | 关屿 | **通过(鉴权面)**:匿名 6/6=401、health 13/13=401/403;无 SAST/依赖扫描 | curl 探针 + health 套件 |
+| 兼容·体验 | 阮清 | **部分通过**:双视口 Chromium 通过;无多浏览器/无障碍 | live config 两 project |
+| 流程·度量·代码 | 何序 | **不通过**:CI 清单漏拦 63、handler 覆盖 27.4%、台账映射 59.2% | `.gitlab-ci.yml:61`、discover/inventory |
+
+---
+
+## 8. 五要素问题清单
+
+### 问题 1(B-221-1 · P2 · 测试侧,本轮已闭环)
+1. **问题描述**:`EnergyLedgerGuardContractTest` 13 例中 1 例恒红,失败信息「一致序列必须检出 0 处断点,实际 1」。
+2. **测试 bug 点**:`cfc-backend/src/test/java/com/etotem/cfc/unit/EnergyLedgerGuardContractTest.java:184`(`RED_对账_参考算法_宿主无入口`);根因在辅助方法 `referenceCountBreachesDetail` 第 387-389 行——首条流水把期初余额反推为 `balanceAfter - amount`(=0)后 `continue`,导致第 2 条的期望值退化为 `0+5=5`,而实际 15 → 误报 1 处断点(off-by-one)。
+3. **最优修改方案**:首条流水改为**锚定** `prevBalance = balanceAfter`;同时断点夹具第 3 条 `balanceAfter` 由 12 改为 13(使「仅第 2 条错、其下游自洽」的语义成立),并把断言强化为 `assertEquals(Arrays.asList(2L), breachesBrokenIds)` 以验证「能定位到具体流水」。
+4. **修改目的**:使参考算法与契约语义(`balanceAfter == prevBalanceAfter + amount`,SC-X-20/TC-X-20-E)一致,消除用例自身误报,恢复该契约键的可信度。
+5. **修改后能否闭环**:**能**。定向复跑 `mvn -o -B test -Dtest=EnergyLedgerGuardContractTest` → **13 例 0F/0E,BUILD SUCCESS(1:22)**;该键由红转绿,后端有效红由 353 降为 352。
+
+### 问题 2(B-218-1 · P0 · 研发)
+1. **问题描述**:`ResourceBeanNameCollisionGuardTest` 1/1 红——`CoachRecommendService` 的 `@Resource FamilyMemberDimensionBaseScoreService dimensionScoreService` 字段名与 `DimensionScoreService` 的 Bean 名相同,`@Resource` 先按名解析 → 运行期 `BeanNotOfRequiredTypeException`。
+2. **测试 bug 点**:无(用例判据正确:先按名、命中且不可赋值才违规)。
+3. **最优修改方案**:字段重命名为 `familyMemberDimensionBaseScoreService`(或 `@Resource(name="familyMemberDimensionBaseScoreService")` 显式限定);同步排查 `ButlerResourceMatchService.followUpMapper`、`HealthDataSourceBridgeService.dimensionScoreService` 两处同类写法。
+4. **修改目的**:消除运行期上下文启动阻断,恢复 butler/coach 链路可用性(对应线上回滚真因 B-203-1)。
+5. **修改后能否闭环**:能。守卫用例 1/1 绿 + 相关 `@SpringBootTest` 链路可启动即为通过。
+
+### 问题 3(B-218-2 · P1 · 研发)
+1. **问题描述**:支付配置缺失时 `MembershipPaySwitchTest` 仍落 131400 分待支付订单;`PaymentServiceORDRoutingTest` 同类路由断言失败。
+2. **测试 bug 点**:用例判据正确(断言「配置缺失必须拒绝下单」)。
+3. **最优修改方案**:`MembershipOrderService` 下单前强校验 `pay.channel` 配置齐备,缺失直接返回业务码(不落单);`PaymentService` 路由按 `payScene` 显式分支并对未知 scene 抛业务异常。
+4. **修改目的**:阻断资金类脏单,避免「无支付渠道仍有待支付订单」。
+5. **修改后能否闭环**:能。两键 9 例全绿 + 生产库无新增 131400 待支付单即为通过。
+
+### 问题 4(B-218-3/B-221-2 · P1 · 运维)
+1. **问题描述**:19:36 前后线上 `/api/**` 出现 502 窗口,health 鉴权契约首跑 4 例(TC-H-U02~U05)实际返回 502,期望 401/403;同刻直连 curl 3/3 均 401。
+2. **测试 bug 点**:`tests/e2e-live/health-contract.spec.js:51` 未区分「网关 5xx」与「业务拒绝」,把 502 直接判红。
+3. **最优修改方案**:用例层加「5xx → 重试 2 次(间隔 3s),仍 5xx 则 `test.skip()` 并打印 `GATEWAY_5XX`」;运维侧排查 251→后端 9082 的连接池/超时与网关重试策略。
+4. **修改目的**:把可用性事件与契约违规分离,避免瞬态 502 冒充回归(本轮已造成 4 例假红)。
+5. **修改后能否闭环**:能。复跑 13/13 绿(本轮已证)+ 连续 3 轮无 502 即销号。
+
+### 问题 5(B-221-3 · P2 · 工具/测试)
+1. **问题描述**:251 派发首次返回 `outcome=failed`,错误 `provider.no-route: Model unavailable: axon/deepseek3.2`。
+2. **测试 bug 点**:`d:\cfc\_dispatch_251_bounded.cjs:17` 硬编码 `model:{id:'deepseek3.2',providerID:'axon'}`。
+3. **最优修改方案**:模型改为环境变量可覆盖(`LG_MODEL_ID/LG_PROVIDER_ID`,默认 `opencode/deepseek-v4.1-flash-free`);派发前先 `GET /api/model` 校验模型 `status=active`。
+4. **修改目的**:避免节点模型下线导致整轮 lg 覆盖丢失(本轮若不复核将损失 43 例覆盖)。
+5. **修改后能否闭环**:**已闭环**——改用可用模型后实派成功,43/43 取数完成。
+
+### 问题 6(B-221-4 · P2 · 流程)
+1. **问题描述**:189 节点派发日志显示 `fatal: 'cfclub' is already used by worktree at 'C:/code/cfc/.worktrees/task_S-cfc-246'` + `Not possible to fast-forward`,节点实际以 `1e3bea680`(落后基线)运行。
+2. **测试 bug 点**:`_r203_189_dispatch.cjs:8` 的 `E2E_CMD` 里 `git checkout cfclub` 未处理「分支已被 worktree 占用」。
+3. **最优修改方案**:节点侧改为 `git -C C:\code\cfc fetch origin && git -C C:\code\cfc reset --hard origin/cfclub`(在专用 worktree 内),或直接 `git worktree add --detach` 一个独立目录跑 E2E。
+4. **修改目的**:保证远端节点跑的是本轮基线 spec,否则「节点绿」无法证明与 HEAD 同源。
+5. **修改后能否闭环**:能。派发输出出现 `git rev-parse --short HEAD` = 当轮基线即为通过(本轮为 `1e3bea680` ≠ `d39aa5282`,已标注)。
+
+### 问题 7(B-221-5 · P2 · 装置)
+1. **问题描述**:后端全量 40:06,慢类 Top1 `ActivityControllerTest` 148.5s、`UserServiceFamilyNameLinkTest` 128.2s、`GuidePackageServiceTest` 110.7s、`GuideApplicationServiceTest` 101.7s、`FamilyAdminOverviewServiceTest` 89.4s、`AIChatControllerTest` 83.7s(前 6 占约 27%)。
+2. **测试 bug 点**:controller 层用 `@SpringBootTest` 全上下文,且 `src/test/resources` 无 `application-test.yml` → 每类重跑 `DatabaseInitializer` 全量迁移。
+3. **最优修改方案**:新增 `application-test.yml`(复用同一数据源、关闭 scheduler、`ddl-auto=none`),慢类改 `@WebMvcTest + @MockBean` 切片。
+4. **修改目的**:把全量反馈时间压到 15 分钟内,提高回归频率。
+5. **修改后能否闭环**:能。全量 `Total time` < 15:00 且 505 类 XML 齐备即为通过。
+
+### 问题 8(G11 · P1 · 研发)
+1. **问题描述**:`.gitlab-ci.yml:61` 的 `BACKEND_OBSERVED_CLASSES` 列 33 类,实测红类 70(修复后 69)→ **漏拦 63(修复后 62)**、**陈旧 26**(清单内 7 类实际已绿)。
+2. **测试 bug 点**:清单为「第 69 轮快照」人工维护,未随红集刷新。
+3. **最优修改方案**:改为由 surefire 结果自动生成(`scripts/gen_observed_classes.js` 读 `target/surefire-reports/*.xml`,输出逗号串写入 CI 变量文件),并在 `backend-blocking-junit` job 里先跑生成再跑门禁。
+4. **修改目的**:让「已知红类」白名单真实反映当前状态,否则门禁必红 → 团队绕过门禁。
+5. **修改后能否闭环**:能。连续 2 轮「清单 ∩ 实测红类 = 清单」且无陈旧类即为通过。
+
+### 问题 9(B-36 · P2 · 测试环境)
+1. **问题描述**:根级黑盒 Jest 23 例 16 红,全部 `ECONNREFUSED 127.0.0.1:9082`。
+2. **测试 bug 点**:`tests/integration/*.spec.js` 硬编码 `BASE_URL=http://127.0.0.1:9082`。
+3. **最优修改方案**:改为 `process.env.BASE_URL || 'http://127.0.0.1:9082'`,CI/本机可用 `BASE_URL=http://cfc.iwintrue.com` 指向已部署实例。
+4. **修改目的**:让黑盒套件在有后端的环境里真正可执行,而不是恒红噪声。
+5. **修改后能否闭环**:能。以 `BASE_URL=http://cfc.iwintrue.com` 跑出 ≥20/23 绿即为通过(第 98 轮仍未修)。
+
+---
+
+## 9. 门禁结论
+
+**⛔ 不通过(有条件;较 R220 明显正向)** —— P0 Bean 撞名(B-218-1)与 P1 支付开关(B-218-2)承袭未解;但本轮 **lg 43/43 全绿、189 首跑 5/5、测试侧闭环 1 例、后端首次全量覆盖 S-cfc-390**。
+
+| 门禁 | R221 结果 | 判定 |
+|---|---|---|
+| G1 全量通过率 ≥95%(剔 skip) | 后端 4415 例 **91.91%**(剔 skip 92.00%);**剔 336 契约前瞻 = 99.58%** | ❌(全量)/ ✅(剔预期红) |
+| G2 红例 0(剔预期红契约) | 实红 **33**(后端 17 + 根级 16;lg 0) | ❌ |
+| G3 前端 Jest | web 124/134、fe 644/4/12/660,逐例零漂移(10 + 4 为 S1-1/S-cfc-132 预期 RED) | ⚠️ 预期 RED |
+| G4 编译 0 错 | ✅ 505 类 test 源全编译通过(`mvn -o -B clean test` 无编译错) | ✅ |
+| G5 逐类有 XML | ✅ **505/505** surefire XML,无沉默类 | ✅ |
+| G6 浏览器 E2E | ✅ 本机 28 过 + 2 跳;189 **5/5 首跑绿** | ✅ |
+| G7 langgraph 通过率 | ✅ **43/43 = 100%**(186.56s,首次全绿) | ✅ |
+| G8 鉴权契约 | ✅ 匿名 6/6=401;health 13/13=401/403(复跑) | ✅ |
+| G9 覆盖率 | handler 覆盖 **557/2029 = 27.4%**(JaCoCo 未开) | ❌ |
+| G10 多节点互备 | ✅ 本机(28 过 2 跳)+ 189(admin 5/5)+ 251(lg 43/43) | ✅ |
+| G11 CI | ❌ 清单 33 类 vs 实测 70 红 → 漏拦 **63**、陈旧 **26** | ❌ |
+| G12 SRS/场景变更→用例 | ✅ 窗口 `docs/superpowers/**`、`tests/test-cases/**` **零变更** → 无需新增;S-cfc-390 自带的 13 例契约已绿 | ✅ |
+| G13 存量零漂移 | ✅ 后端存量 16 例(8 类)逐类逐例与 R213/R218 一致 → **第 35 次**;web 10/fe 4/根级 16 逐例一致 | ✅ |
+| G14 场景映射 | 场景层 **152/152 = 100%**;用例台账层 **90/152 = 59.2%** | ⚠️ |
+
+**核心变化(R220 → R221)**
+1. **lg 8 红 → 0 红**(43/43 首次全绿),B-216-3/B-220-1 转观察 1/3。
+2. **后端由「承采」转「全量实跑」**:4415 例 / 91.91%,含 S-cfc-390 新代码,红集三层归因清晰。
+3. **测试侧自修 1 例**(B-221-1),消除 off-by-one 假红。
+4. **189 admin 首跑 5/5**(B-208-1 好转,观察 2/3),但节点 HEAD 落后需修(B-221-4)。
+5. **线上 502 第 4 轮复现**(B-218-3),4 例假红已由复跑澄清。
+
+**复评条件**:B-218-1 守卫绿 → B-218-2 两键 9 例绿 → 实红降为 16 存量 → G11 清单按 surefire 自动生成 → G2 达 0(剔预期红);另需 lg 连续 3 轮全绿方可判「上游稳定」。
+
+---
+
+## 10. 测试负责人模板数据
+
+### 1.1 测试用例建设
+- 结构化用例 947 / Playwright 571 / Python 48 / Java@Test 4399 / 场景文件 11 → **合计 5965**(较 R220 的 5740 +225,主因测试源 +3 文件 / @Test +4 与台账重算)
+- 本轮新增/修改用例:**1 处修改**(`EnergyLedgerGuardContractTest` 参考算法与夹具),新增 **0**(窗口零 SRS 变更)
+
+### 1.2 会话与任务分发
+| 节点 | 派发内容 | 结果 |
+|---|---|---|
+| 本机 | admin / frontend / shop / health / dx 五套 + web & fe & 根级 Jest + 后端全量 | 全完成 |
+| 192.168.16.189 | `admin-desktop` | 5/5 EXIT=0(1.3m) |
+| 192.168.16.251 | `langgraph pytest tests --ignore=qna/test_chat` | 43/43(186.56s) |
+
+### 1.2b 各会话当前工作状态
+| 会话 | 状态 |
+|---|---|
+| 后端全量(worktree `r221-run`) | 已完成 40:06,505 XML |
+| 本机浏览器串行 | 已完成(admin 1.6m / fe 48.8s / shop 6.5s / health 11.2s / dx 2 跳) |
+| 189 派发 | 已完成(sh_1deff484e) |
+| 251 派发 | 已完成(2 次会话:launch + read),残留进程已 `pkill` 清理 |
+
+### 1.3 问题处置
+- 已闭环 2 项:B-221-1(测试侧 off-by-one)、B-221-3(派发模型路由)。
+- 新增/承袭未闭环 7 项:B-218-1(P0)、B-218-2(P1)、B-218-3(P1,第 4 轮)、B-218-10(P1,第 22 轮)、B-221-2(P1)、B-221-4(P2)、B-36(P2,第 98 轮)、B-DX-1(P1,第 55 轮)、G11(P1)。
+
+### 1.4 git 提交与推送证据
+- 基线 `d39aa5282`;分支 `test-lead-R221-final`;提交内容:本报告 + 研发通知 + blockers 增补 + 台账(discovery/inventory/automation-status)+ 测试侧修复 1 文件。
+
+### 1.5 状态机阶段分布
+| 阶段 | 数量 |
+|---|---|
+| 已覆盖(绿) | 4935 |
+| 契约前瞻红(TDD-RED,预期) | 349 |
+| 真实红(待修) | 33 |
+| 跳过(环境/契约缺口) | 25 |
+
+### 1.6 数据源健康度
+| 数据源 | 状态 | 说明 |
+|---|---|---|
+| `cfc.iwintrue.com`(admin/frontend) | 正常(302) | 站点可达;19:36 前后有 502 窗口 |
+| 251 `:3306` MySQL | 正常 | 后端全量可连库执行 |
+| 251 `:4096` opencode | 正常(200) | 派发成功;模型路由已变更(B-221-3) |
+| 251 `:9000` langgraph live | **CLOSED** | live 链路面不可实测(G12 口径注明) |
+| 189 `:4090` opencode | 正常(200) | 派发成功,但节点仓库 HEAD 落后(B-221-4) |
+| 本机 `:9082` | 未监听 | 根级 16 红(B-36 第 98 轮) |
+
+---
+
+## 附录 A · 本轮可复现命令
+
+```bash
+# 0) 基线(HTTP 通道;SSH 失效 B-203-3)
+git fetch http://git.iwintrue.com/liaoxg/cfc.git cfclub
+git log --oneline 28eb1221c..FETCH_HEAD        # 2 提交(S-cfc-390 + auto bump)
+git worktree add --detach .worktrees/r221-run d39aa5282
+
+# 1) 后端全量(隔离 worktree,避免主工作区未跟踪文件污染)
+cd .worktrees/r221-run/cfc-backend && mvn -o -B clean test    # 40:06,505 类,4415 例
+
+# 2) 后端定向(测试侧修复后)
+mvn -o -B test -Dtest=EnergyLedgerGuardContractTest           # 13/13 绿
+
+# 3) 浏览器 E2E(tests 内 CLI —— B-218-4)
+cd tests && node node_modules/@playwright/test/cli.js test -c playwright.config.live.js --project=admin-desktop --output=../_r221_admin
+node node_modules/@playwright/test/cli.js test -c playwright.config.live.js --project=frontend-mobile --output=../_r221_fe
+node node_modules/@playwright/test/cli.js test -c playwright.config.live.js --project=shop-api
+node node_modules/@playwright/test/cli.js test -c playwright.config.live.js --project=dx-bridge
+node node_modules/@playwright/test/cli.js test -c playwright.config.health.js --output=../_r221_health
+
+# 4) 远端节点
+node _r203_189_dispatch.cjs                    # 189 admin(PW_PROJECT=admin-desktop)
+node _r221_251.cjs "<远端 shell 命令>"          # 251 lg pytest(模型走 opencode/deepseek-v4.1-flash-free)
+
+# 5) Jest(fe 必须 jest/bin/jest.js —— B-218-5)
+cd cfc-web && node node_modules/jest/bin/jest.js --silent
+cd cfc-frontend && node node_modules/jest/bin/jest.js --silent
+cd tests && node node_modules/jest/bin/jest.js -c jest.config.js --silent
+
+# 6) 台账
+python <skill>/scripts/discover_tests.py --project .
+python <skill>/scripts/test_inventory.py --project .
+```
+
+## 附录 B · 取证清单
+| 套件 | 证据文件 |
+|---|---|
+| 后端全量 | `_r221_backend_full.log`(40:06,505 XML in `.worktrees/r221-run/cfc-backend/target/surefire-reports`) |
+| 后端定向 | `_r221_energy_guard.log`(13/13,BUILD SUCCESS 1:22) |
+| 本机浏览器 | `_r221_browser_local1.log`(admin 5 + fe 6)、`_r221_browser_local2.log`(shop 4 + dx 2 跳 + health 首跑 9/13)、health 复跑输出 13/13 |
+| 189 | 派发 shell `sh_1deff484e00101fzj4tTXRdaKJ`(5 passed,EXIT=0) |
+| 251 | `/tmp/r221_pytest.log`(43 passed in 186.56s) |
+| Jest | `_r221_jest_web.log`(124/10/134)、`_r221_jest_fe.log`(644/4/12/660)、`_r221_jest_root2.log`(7/16/23) |
+| 线上 API | Playwright 输出 25 passed / 7 skipped |
+| 台账 | `docs/tdd/test/discovery.md`(374/2029/557)、`inventory.md`(5965)、`automation-status.md` |
+
+## 附录 C · 度量口径
+| 指标 | 口径 | 数值 |
+|---|---|---|
+| 后端通过率 | surefire 过/(总−skip) | 4058/4411 = 92.00%(全量含 skip 91.91%) |
+| 后端剔预期红 | 过/(总−skip−336 契约前瞻) | **99.58%** |
+| 后端有效红 | 红 − 契约前瞻 | **17**(存量 16 + 守卫 1;修复后 16 + 1) |
+| 全站 | Σ 各套件 | 5342 例 / 4935 过 / 382 红 / 25 跳 = 92.37% |
+| 全站剔预期红 | (过)/(总−skip−349) | **99.34%**,实红 33 |
+| handler 覆盖 | discover covered/handlers | 557/2029 = 27.4% |
+| 场景映射 | SC 台账锚点/规格 SC | 90/152 = 59.2%(宽口径 152/152) |
+| G11 CI | 清单 ∩ 实测红 | 漏拦 63 / 陈旧 26 |
+
+---
+
+*报告生成:R221 自动化闭环(无人值守)|基线 `d39aa5282`(窗口 2 提交,含 S-cfc-390)|下一轮预计 R222*

+ 41 - 0
docs/tdd/test/automation-run-2026-11-15-R221.md

@@ -0,0 +1,41 @@
+# 自动化执行记录 · R221(2026-11-15 19:28 → 20:40 GMT+8,无人值守)
+
+## 触发与授权
+- 触发:定时自动化「测试负责人闭环(全部用例通过 + 覆盖 SRS/场景含异常流)+ 浏览器走 cfc.iwintrue.com/admin 与 /frontend(189/本机每节点单任务)+ langgraph 派 251 + 结果有变提交远程并通知研发」。
+- 执行档:review(离线白名单)+ 内网浏览器 E2E 实跑 + 节点派发。**未装依赖、未启停生产服务、未改 src/main**。
+
+## 时间线
+| 时间 | 动作 |
+|---|---|
+| 19:28 | 读记忆(R218 段)+ 仓库状态;发现 HEAD `6c8ac19cc`(R220)、工作区 25+ 未跟踪文件 |
+| 19:29 | HTTP fetch → 远端 `d39aa5282`(窗口 2 提交,含 S-cfc-390,7 个 src/main 文件) |
+| 19:30 | 建隔离 worktree `.worktrees/r221-run`(detach `d39aa5282`);探活:251:3306 Open(**可跑后端全量**)、251:4096/189:4090/本机:4091 Open、251:9000 CLOSED |
+| 19:31 | 后台启 `mvn -o -B clean test` |
+| 19:32 | 本机 admin 5/5(1.6m) |
+| 19:34 | 本机 frontend 6/6(48.8s) |
+| 19:35 | shop 4/4 + dx 2 跳;health 首跑 9/13(4×502) |
+| 19:36 | 直连 curl 3/3=401 → 判瞬态;health 复跑 **13/13** |
+| 19:33 | 251 首派失败(`axon/deepseek3.2` 下线)→ 建 `_r221_251.cjs` 换模型 → pytest 后台启动 |
+| 19:37 | 本机 Jest:web 124/10/134、fe 644/4/12/660、根级 7/16/23(根目录 jest 缺失,改用 tests 内 jest) |
+| 19:39 | 189 派发 admin → **5/5 EXIT=0**(节点 HEAD `1e3bea680` 落后,B-221-4) |
+| 19:40 | 读 251 日志 → **43 passed / 186.56s**;`pkill` 清理残留 pytest |
+| 20:21 | 后端全量完成:**40:06 / 505 类 / 4415 例 / 4058 过 / 353 红 / 4 跳 = 91.91%** |
+| 20:22 | 发现 `EnergyLedgerGuardContractTest` 1F → 定位参考算法 off-by-one → 修测试源码 |
+| 20:23 | 定向复跑 → **13/13 绿**(BUILD SUCCESS 1:22) |
+| 20:25 | discover(374/2029/557)+ inventory(5965)+ CI 双向差集(漏拦 63 / 陈旧 26)|
+| 20:30 | 生成报告 + 研发通知 + blockers R221 段 |
+| 20:40 | 提交推送 + 通知 |
+
+## 关键判定依据
+- **判「502 是环境」而非「回归」**:套件红的同时 `curl` 直连 3/3=401,且复跑 13/13 绿。
+- **判「用例缺陷」而非「产品缺陷」**:参考算法在语法正确的数据上自相矛盾(一致序列报 1 处断点),定位到首条流水锚定逻辑。
+- **判「lg 全绿可信」**:251 仓库 HEAD `d39aa5282` = 本机基线,非旧代码误跑。
+- **判「189 5/5 非同源证据」**:派发日志显示 `git checkout cfclub` 失败,HEAD 停在 `1e3bea680`。
+
+## 产出
+- `docs/tdd/orchestration/report-test-2026-11-15-R221.md`
+- `docs/tdd/orchestration/notice-2026-11-15-R221-研发通知.md`
+- `docs/tdd/test/blockers.md`(R221 段 14 条,含 B-221-1~5)
+- `docs/tdd/test/{discovery,inventory,automation-status}.md`(刷新)
+- `cfc-backend/.../EnergyLedgerGuardContractTest.java`(测试侧修复)
+- 临时取证:`_r221_backend_full.log`、`_r221_browser_local1/2.log`、`_r221_jest_*.log`、`_r221_energy_guard.log`(未入库)

+ 4 - 2
docs/tdd/test/automation-status.md

@@ -23,8 +23,8 @@
 | 用户场景(md) | 11 | 0 | 0 | 11 | 11 | 0 | 0 | 0 | 0 |
 | Playwright(e2e/integration) | 96 | 571 | 96 | 0 | 96 | 0 | 0 | 0 | 0 |
 | Python(pytest) | 11 | 48 | 11 | 0 | 11 | 0 | 0 | 0 | 0 |
-| Java后端测试 | 510 | 4377 | 510 | 0 | 510 | 0 | 0 | 0 | 0 |
-| **合计** | — | **5943** | **617** | **958** | 1575 | 0 | 0 | 0 | 0 |
+| Java后端测试 | 512 | 4399 | 512 | 0 | 512 | 0 | 0 | 0 | 0 |
+| **合计** | — | **5965** | **619** | **958** | 1577 | 0 | 0 | 0 | 0 |
 
 ## 二、结构化测试用例自动化状态(`tests/test-cases/*.md`)
 
@@ -1390,6 +1390,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/CartReplaceComboTest.java` | 5 | 已自动化(@Test) | 未跟踪 | CartReplaceCombo |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/CfBalanceControllerTest.java` | 8 | 已自动化(@Test) | 未跟踪 | CfBalanceController |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/CfRewardV2MigrateConfigContractTest.java` | 8 | 已自动化(@Test) | 未跟踪 | CfRewardV2MigrateConfigContract |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/CfRewardV2PlatformTakeContractTest.java` | 9 | 已自动化(@Test) | 未跟踪 | CfRewardV2PlatformTakeContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ChildAiChatContractTest.java` | 12 | 已自动化(@Test) | 未跟踪 | ChildAiChatContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ChildAuthLoginContractTest.java` | 11 | 已自动化(@Test) | 未跟踪 | ChildAuthLoginContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ChildBadgeViewContractTest.java` | 11 | 已自动化(@Test) | 未跟踪 | ChildBadgeViewContract |
@@ -1508,6 +1509,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/NotificationCenterViewContractTest.java` | 9 | 已自动化(@Test) | 未跟踪 | NotificationCenterViewContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/NutritionPlanTeacherContractTest.java` | 4 | 已自动化(@Test) | 未跟踪 | NutritionPlanTeacherContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderCreatePayShipConfirmScX07ContractTest.java` | 14 | 已自动化(@Test) | 未跟踪 | OrderCreatePayShipConfirmScX07Contract |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderReceiptTimeoutContractTest.java` | 13 | 已自动化(@Test) | 未跟踪 | OrderReceiptTimeoutContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderReceiptTimeoutTaskContractTest.java` | 14 | 已自动化(@Test) | 未跟踪 | OrderReceiptTimeoutTaskContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderRefundScP56ScA12ContractTest.java` | 11 | 已自动化(@Test) | 未跟踪 | OrderRefundScP56ScA12Contract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/PersonalLayerDualAssertionTest.java` | 13 | 已自动化(@Test) | 未跟踪 | PersonalLayerDualAssertion |

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

@@ -1659,3 +1659,24 @@
 | **B-36(第 95 轮)** | 根级黑盒 16 红 | 测试(环境) | `npx jest -c tests/jest.config.js` → **7 过 / 16 红 / 23**,全 `ECONNREFUSED 127.0.0.1:9082`。 | 测试 | 2026-11-15 15:20 | 待处理(P2) |
 | **B-DX-1(第 52 轮)** | dx-bridge 端点 404 | 部署/研发 | 复跑 `bridge/list`、`bridge/sync-status` 均 **HTTP 404** → 2 跳。 | 部署/研发 | 2026-11-15 15:20 | 待处理(P1) |
 | **R218 门禁** | 全站 **5290 例 / 4811 过 / 447 红 / 20 跳** | 测试 | **不通过**。剔 skip **91.34%**;剔 434 预期红 = **99.15%**,实红 **17**(存量 16 第 34 次 + 新增守卫 1)。✅G3 web 124/134 + fe 644/4/12/660 / G4 编译 0 错(2187+510 源)/ G5 503/503 XML / G6 本机 28+2跳 + 189 5/5 / G8 health 13/13 全 401 / G10 本机+189+251 / G12 窗口零 SRS 变更 / G13 第 34 次;❌G1 全量 90.05% / G2 17 / G7 40/43 / G9 27.5% / **G11 漏拦 70 陈旧 26** / G14 用例层 58.3%。 | 测试(R218 闭环) | 2026-11-15 15:20 | 已记录 |
+
+## R221 段(2026-11-15 19:28~20:40,基线 `d39aa5282`,窗口 2 提交含 S-cfc-390)
+
+> 说明:R219/R220 两轮未在本文件落段(其结论见 `docs/tdd/orchestration/report-test-2026-11-15-R219.md` 与 `-R220.md`)。R221 窗口含 **src/main 变更 7 文件(+243/−1)** → 后端**全量实跑**(非承采):505 类 / 4415 例 / 4058 过 / 353 红 / 4 跳 = 91.91%。
+
+| 编号 | 关联键/对象 | 类型 | 描述与处置 | 经办 | 登记时间 | 状态 |
+|---|---|---|---|---|---|---|
+| **B-221-1(新增 · P2 用例缺陷 · 已闭环)** | `EnergyLedgerGuardContractTest`(S-cfc-390) | 测试 | 13 例中 1 例恒红:「一致序列必须检出 0 处断点,实际 1」。根因:`referenceCountBreachesDetail` 首条流水把期初余额反推为 `balanceAfter-amount`(=0) 后 `continue` → 第 2 条期望退化为 0+5=5 而实际 15(off-by-one);同时断点夹具第 3 条 `balanceAfter=12` 与断点后余额 16 不自洽(应为 13,否则构成第 2 处断点)。**处置**:首条锚定 `prevBalance=balanceAfter`、夹具改 13、断言强化 `assertEquals(Arrays.asList(2L), breachesBrokenIds)` → 定向复跑 **13/13 绿**(BUILD SUCCESS 1:22)。 | 测试(R221 实修) | 2026-11-15 20:23 | **已闭环** |
+| **B-221-2(新增 · P1 环境)** | 线上 `/api/**` 502 窗口(承 B-218-3 第 4 轮) | 运维 | 19:36 前后 health 鉴权契约首跑 **4 例红**(TC-H-U02~U05 实际 502,期望 401/403),同刻 curl 直连 3/3=401、`/api/admin/families/overview` 3/3=401 → 瞬态窗口;复跑 **13/13 绿**。**修法**:用例层加「5xx → 重试 2 次仍 5xx 则 skip 并打印 GATEWAY_5XX」;运维查网关→9082 连接池/超时/重试。 | 运维/测试(R221 实测) | 2026-11-15 19:36 | 观察中(第 4 轮) |
+| **B-221-3(新增 · P2 工具 · 已闭环)** | 251 派发模型路由 | 测试 | 首派 `outcome=failed`:`provider.no-route: Model unavailable: axon/deepseek3.2`(`_dispatch_251_bounded.cjs:17` 硬编码)。**处置**:新增 `_r221_251.cjs`,模型走 `LG_MODEL_ID/LG_PROVIDER_ID`(默认 `opencode/deepseek-v4.1-flash-free`),并修正消息解析(`/message` 返回 `data[].content[].text`,原脚本读 `parts` 导致 RESULT 空);派发前建议 `GET /api/model` 校验 `status=active`。 | 测试(R221 实修) | 2026-11-15 19:33 | **已闭环** |
+| **B-221-4(新增 · P2 流程)** | 189 节点仓库 HEAD 落后 | 测试/运维 | 派发日志:`fatal: 'cfclub' is already used by worktree at 'C:/code/cfc/.worktrees/task_S-cfc-246'` + `Not possible to fast-forward` → 节点以 **`1e3bea680`**(≠ 基线 `d39aa5282`)运行,5/5 绿但**非同源证据**。**修法**:节点改独立 worktree/detach 拉取;派发输出须打印 `git rev-parse --short HEAD` 供核对。 | 测试(R221 实派) | 2026-11-15 19:39 | 待修(P2) |
+| **B-221-5(新增 · P2 装置)** | 后端全量 40:06 慢类 | 研发 | 慢类 Top6:`ActivityControllerTest` 148.5s、`UserServiceFamilyNameLinkTest` 128.2s、`GuidePackageServiceTest` 110.7s、`GuideApplicationServiceTest` 101.7s、`FamilyAdminOverviewServiceTest` 89.4s、`AIChatControllerTest` 83.7s(合计约占 27%)。根因:controller 层 `@SpringBootTest` 全上下文 + `src/test/resources` 缺 `application-test.yml`(每类重跑 `DatabaseInitializer` 全量迁移)。**修法**:补 `application-test.yml`(关 scheduler)、慢类改 `@WebMvcTest` 切片。 | 研发 | 2026-11-15 20:21 | 待研发(P2) |
+| **B-218-1(第 2 轮 · P0)** | `@Resource` Bean 撞名 | 研发 | `ResourceBeanNameCollisionGuardTest` **1/1 红**(本轮全量实跑确认,非承采)。`CoachRecommendService.java:71-72` 字段 `dimensionScoreService` 撞 `DimensionScoreService` Bean 名。 | 研发 | 2026-11-15 20:21 | 待研发修复(P0) |
+| **B-218-2(第 2 轮 · P1 资金)** | 支付开关语义 | 研发 | 本轮全量实跑:`MembershipPaySwitchTest` 1F、`PaymentServiceORDRoutingTest` 1F(配置缺失仍落 131400 分待支付订单)。 | 研发 | 2026-11-15 20:21 | 待研发修复(P1) |
+| **B-218-10(第 22 轮 · P1)** | lg pytest 进程不退出 | 研发/测试 | 251 上 43 passed / 186.56s 已打印 summary,但 `pgrep` 仍有残留 pytest 进程 → 已 `pkill -9 -f 'pytest tests'` 清理(注意该模式会匹配到执行 shell 自身,需用 `pytest[ ]tests`)。线索:`RuntimeWarning: coroutine 'JavaClient._get_client' was never awaited`。 | 研发 | 2026-11-15 19:40 | 待修(P1) |
+| **B-216-3 / B-220-1(观察 1/3)** | langgraph 上游 429/401/ConnectError | 运维/研发 | 本轮 **43/43 全绿**(186.56s),429/401/ConnectError **均未复现** → 转观察 1/3,连续 3 轮全绿后销号。 | 测试(R221 实派) | 2026-11-15 19:40 | 观察中(1/3) |
+| **B-208-1(观察 2/3)** | 189 节点 admin 链路 | 运维 | 本轮 **首跑 5/5 全绿**(1.3m,EXIT=0),无 502 复现(上轮首跑 3/5)→ 观察 2/3。但节点 HEAD 落后(见 B-221-4)。 | 测试(R221 实派) | 2026-11-15 19:39 | 观察中(2/3) |
+| **G11(第 25 轮 · P1)** | CI 排除清单失真 | 研发 | `.gitlab-ci.yml:61` 列 **33 类** vs 实测红类 **70** → **漏拦 63**、**陈旧 26**(交集 7);修复 B-221-1 后红类 69 → 漏拦 62。建议由 surefire XML 自动生成清单。 | 研发 | 2026-11-15 20:25 | 待研发(P1) |
+| **B-36(第 98 轮 · P2)** | 根级黑盒 16 红 | 测试 | `tests` 内 `jest -c jest.config.js` → **7 过 / 16 红 / 23**(8.4s),全 `ECONNREFUSED 127.0.0.1:9082`。**注**:根目录 `node_modules/jest` 缺失(MODULE_NOT_FOUND),必须用 `tests/node_modules/jest/bin/jest.js`。 | 测试 | 2026-11-15 19:37 | 待处理 |
+| **B-DX-1(第 55 轮 · P1)** | dx-bridge 端点 404 | 部署/研发 | `/api/health/data-sources/bridge/list`、`/sync-status` 均 **404** → 2 跳(规格 `2026-11-08-dx-health-bridge.md` 标注「仅登记不实现」,属待派发实现)。 | 部署/研发 | 2026-11-15 19:38 | 待处理 |
+| **R221 门禁** | 全站 **5342 例 / 4935 过 / 382 红 / 25 跳** | 测试 | **不通过(有条件,正向)**。剔 skip **92.81%**(4935/5317);**剔 349 预期红 = 99.34%**,实红 **33**(后端 17 + 根级 16)。✅G4 0 错 / G5 505-505 / G6 本机 28+2跳 + 189 5/5 / **G7 43/43 全绿** / G8 6/6=401 + health 13/13 / G10 三节点 / G12 窗口零 SRS 变更 / G13 第 35 次;❌G1 91.91%(剔预期红 99.58%)/ G2 33 / G9 27.4% / G11 漏拦 63 陈旧 26 / G14 用例层 59.2%。**核心变化 = lg 8 红→0 红(首次全绿)+ 后端首次全量覆盖 S-cfc-390 + 测试侧闭环 B-221-1**。 | 测试(R221 闭环) | 2026-11-15 20:35 | 已记录 |

+ 10 - 8
docs/tdd/test/discovery.md

@@ -7,22 +7,22 @@
 
 | 指标 | 数值 |
 | --- | --- |
-| 控制器总数 | 373 |
-| handler 方法总数 | 2026 |
+| 控制器总数 | 374 |
+| handler 方法总数 | 2029 |
 | handler 方法已覆盖 | 557 (27.5%) |
 | 单元-全覆盖(handler 方法) | 47 |
 | 单元-部分覆盖(handler 方法) | 206 |
-| 单元-未覆盖(handler 方法) | 119 |
+| 单元-未覆盖(handler 方法) | 120 |
 | 单元-无handler 方法 | 1 |
-| 测试文件数 | 510 |
-| @Test 方法总数 | 4377 |
+| 测试文件数 | 512 |
+| @Test 方法总数 | 4399 |
 | 含跳过/假设项(test 级 partial) | 4 |
 
 ## 二、未覆盖控制器(发现「缺口」· 非发明)
 
 > 以下控制器在当前测试源中**没有任何handler 方法被命中**。这是真实扫描得到的覆盖缺口。
 
-共 119 个:
+共 120 个:
 
 - `OrchestrationController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/OrchestrationController.java`,15 方法)
 - `KeyPersonController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/KeyPersonController.java`,14 方法)
@@ -84,7 +84,7 @@
 - `AdminGrowthArchiveProductController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminGrowthArchiveProductController.java`,3 方法)
 - `AssessmentController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/guide/AssessmentController.java`,3 方法)
 - `ContactImportController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/ContactImportController.java`,3 方法)
-- …(其余 59 个见完整扫描)
+- …(其余 60 个见完整扫描)
 
 ## 三、部分覆盖控制器(已做一部分测试)
 
@@ -119,6 +119,7 @@
 - `WishController`:覆盖 11/12,未覆盖方法:priceAlias
 - `AIChatController`:覆盖 8/11,未覆盖方法:reportAnalyze、deleteConversation、transcribe
 - `BadgeController`:覆盖 1/11,未覆盖方法:getAllBadges、getBadgeDetail、createBadge、updateBadge、deleteBadge、grantBadge、getMemberBadges、toggleFavorite、getMemberStats、getFamilyRanking
+- `GrowthPlanController`:覆盖 2/11,未覆盖方法:createPlan、getChildPlans、getActivePlan、getPlanProgress、getPlanDetail、updatePlan、reviewPlan、confirmPlan、submitPlan
 - `PaymentController`:覆盖 5/11,未覆盖方法:createWechatNativePay、getPaymentStatus、getOAuth2Url、oauth2Callback、handleV3Notify、generateQrCode
 - `SupplyHierarchyController`:覆盖 2/11,未覆盖方法:setHierarchy、removeRelation、getDirectChildren、getAllChildren、getParentChain、getTree、getChangeRequests、applyChange、reviewChange
 - `TrainingPlanController`:覆盖 1/11,未覆盖方法:getPlanDetail、createPlan、updatePlan、addItem、updateItem、deleteItem、generateFromRecommendations、deployPlan、getExecutionBoard、deletePlan
@@ -136,7 +137,6 @@
 - `EnergyController`:覆盖 7/9,未覆盖方法:configureSourceRatios、getWealthDetail
 - `FileRecordController`:覆盖 1/9,未覆盖方法:upload、update、deleteFile、getTags、tagCreate、tagUpdate、tagDelete、stats
 - `FiveDimensionSelfCheckController`:覆盖 4/9,未覆盖方法:getHistory、ignoreSelfCheck、generatePlan、getTrendAnalysis、aiGenerateQuestions
-- `GrowthPlanController`:覆盖 2/9,未覆盖方法:createPlan、getChildPlans、getActivePlan、getPlanProgress、getPlanDetail、updatePlan、reviewPlan
 - `KnowledgeBaseController`:覆盖 1/9,未覆盖方法:backfillTags、get、save、delete、bindDimensions、bindTags、uploadFile、fetchUrl
 - `ProductController`:覆盖 6/9,未覆盖方法:updateImages、specMap、relatedProducts
 - `AdminActivityController`:覆盖 5/8,未覆盖方法:review、detail、backfillTags
@@ -390,6 +390,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuidePackageServiceTest.java` | com | 13 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/HealthReportDetailContractTest.java` | com | 13 | 13 | 1 | HealthReportController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ManualDimensionScoreContractTest.java` | com | 13 | 6 | 2 | ManualDimensionScoreController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderReceiptTimeoutContractTest.java` | com | 13 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/PersonalLayerDualAssertionTest.java` | com | 13 | 4 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/ScG03LoginMethodContractTest.java` | com | 13 | 1 | 4 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/SupplierNutritionSupplyContractTest.java` | com | 13 | 1 | 4 | — | — |
@@ -496,6 +497,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/AuthSessionMutexContractTest.java` | com | 9 | 0 | 0 | AuthController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/BadgeControllerGetMemberBadgesTest.java` | com | 9 | 1 | 0 | BadgeController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/ai/ButlerControllerGateTest.java` | com | 9 | 4 | 6 | ButlerController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/CfRewardV2PlatformTakeContractTest.java` | com | 9 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DimensionRegistryTreeTest.java` | com | 9 | 6 | 0 | DimensionRegistryController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/EnergyGrantContractTest.java` | com | 9 | 4 | 1 | EnergyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/growth/GrowthHistoryViewContractTest.java` | com | 9 | 3 | 0 | GrowthController | — |

+ 4 - 2
docs/tdd/test/inventory.md

@@ -11,9 +11,9 @@
 | 结构化测试用例(md) | 18 | 947 |
 | Playwright(spec.js) | 96 | 571 |
 | Python(pytest) | 11 | 48 |
-| Java后端(测试文件) | 510 | 4377 (@Test) |
+| Java后端(测试文件) | 512 | 4399 (@Test) |
 | 用户场景(md) | 11 | 文件级 |
-| **合计** | — | **5943** 用例/方法 |
+| **合计** | — | **5965** 用例/方法 |
 
 ## 二、结构化测试用例(`tests/test-cases/*.md`)
 
@@ -1385,6 +1385,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/CartReplaceComboTest.java` | cfc-backend | 5 | CartReplaceCombo | `cfc-backend/src/test/java/com/etotem/cfc/unit/CartReplaceComboTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/CfBalanceControllerTest.java` | cfc-backend | 8 | CfBalanceController | `cfc-backend/src/test/java/com/etotem/cfc/unit/CfBalanceControllerTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/CfRewardV2MigrateConfigContractTest.java` | cfc-backend | 8 | CfRewardV2MigrateConfigContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/CfRewardV2MigrateConfigContractTest.java` |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/CfRewardV2PlatformTakeContractTest.java` | cfc-backend | 9 | CfRewardV2PlatformTakeContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/CfRewardV2PlatformTakeContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ChildAiChatContractTest.java` | cfc-backend | 12 | ChildAiChatContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/ChildAiChatContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ChildAuthLoginContractTest.java` | cfc-backend | 11 | ChildAuthLoginContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/ChildAuthLoginContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ChildBadgeViewContractTest.java` | cfc-backend | 11 | ChildBadgeViewContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/ChildBadgeViewContractTest.java` |
@@ -1503,6 +1504,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/NotificationCenterViewContractTest.java` | cfc-backend | 9 | NotificationCenterViewContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/NotificationCenterViewContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/NutritionPlanTeacherContractTest.java` | cfc-backend | 4 | NutritionPlanTeacherContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/NutritionPlanTeacherContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderCreatePayShipConfirmScX07ContractTest.java` | cfc-backend | 14 | OrderCreatePayShipConfirmScX07Contract | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderCreatePayShipConfirmScX07ContractTest.java` |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderReceiptTimeoutContractTest.java` | cfc-backend | 13 | OrderReceiptTimeoutContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderReceiptTimeoutContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderReceiptTimeoutTaskContractTest.java` | cfc-backend | 14 | OrderReceiptTimeoutTaskContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderReceiptTimeoutTaskContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderRefundScP56ScA12ContractTest.java` | cfc-backend | 11 | OrderRefundScP56ScA12Contract | `cfc-backend/src/test/java/com/etotem/cfc/unit/OrderRefundScP56ScA12ContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/PersonalLayerDualAssertionTest.java` | cfc-backend | 13 | PersonalLayerDualAssertion | `cfc-backend/src/test/java/com/etotem/cfc/unit/PersonalLayerDualAssertionTest.java` |