Browse Source

test(R190): 测试侧产物闭环

- docs/tdd/orchestration/report-test-2026-11-13-R190.md: 主报告(4141例/4026过=97.22%)
- docs/tdd/test/automation-run-2026-11-13-R190.md: 14项套件实测明细
- docs/tdd/notice-2026-11-13-R190-研发通知.md: langgraph 401环境红+S-cfc-186 RED通知
- docs/tdd/test/blockers.md: B-190-1(B-142-2复发)/B-190-2(窗口2契约类补验)/B-95观察改善/B-189-1延续
- docs/tdd/test/inventory.md + automation-status.md: 台账重扫(跨源4588, Java@Test 3250)
- _r190_*.cjs: 189/204/251 节点派发器脚本

★ 关键事实:窗口2契约类补验(S-cfc-186 6过/1预期RED + S-cfc-182 14/14 GREEN);
  langgraph 50/51(上游401环境红,B-142-2复发);204节点fe 6/6恢复(B-95观察改善);
  浏览器任务级全绿;全站红94零缺陷回归
E2E Test Bot 29 minutes ago
parent
commit
c8b02e5ee6

+ 62 - 0
_r190_189_admin.cjs

@@ -0,0 +1,62 @@
+// R162: 189 admin-live UI E2E kick/read(String.raw 保反斜杠路径,修复 Location not found)
+const BASE = process.env.BASE_189 || 'http://192.168.16.189:4090';
+const AUTH = 'Basic ' + Buffer.from('opencode:' + (process.env.OPENCODE_SERVER_PASSWORD || 'IwinTrue@123')).toString('base64');
+const H = { Authorization: AUTH, 'Content-Type': 'application/json' };
+const CWD = String.raw`C:\code\cfc`;
+const LOC = '?location%5Bdirectory%5D=' + encodeURIComponent(CWD);
+const LOG = String.raw`C:\code\cfc\_r190_admin-live_test.log`;
+const SLEEP = ms => new Promise(r => setTimeout(r, ms));
+
+function buildKickCmd() {
+  return [
+    'cd ' + CWD,
+    'if (Test-Path ' + LOG + ') { Remove-Item ' + LOG + ' -Force }',
+    `Start-Process -FilePath cmd.exe -ArgumentList '/c','cd /d ${CWD}\\tests && set PLAYWRIGHT_HTML_REPORT=false && npx playwright test -c playwright.config.live.js --project=admin-desktop --reporter=line > ${LOG} 2>&1' -WindowStyle Hidden -PassThru | Select-Object Id`,
+    'start-sleep -Seconds 3',
+    'echo KICKED'
+  ].join('; ');
+}
+function buildReadCmd() {
+  return [
+    'echo READ_BEGIN',
+    'if (Test-Path ' + LOG + ') { Get-Content ' + LOG + ' -Tail 200 }',
+    'if (Test-Path ' + LOG + '.err) { echo ERR_BEGIN; Get-Content ' + LOG + '.err -Tail 30 }',
+    'echo READ_END'
+  ].join('; ');
+}
+async function j(url, opt) {
+  try {
+    const r = await fetch(url, Object.assign({ headers: H }, opt));
+    const t = await r.text();
+    try { return { status: r.status, json: JSON.parse(t) }; } catch { return { status: r.status, text: t }; }
+  } catch (e) { return { status: 0, err: e.message }; }
+}
+async function openShell(cmd, capMs = 30000) {
+  const cr = await j(BASE + '/api/shell' + LOC, { method: 'POST', body: JSON.stringify({ command: cmd, cwd: CWD }) });
+  const cj = (cr.json) || {};
+  const id = (cj.data && cj.data.id) || cj.id;
+  if (!id) return { err: 'create failed ' + cr.status + ' ' + JSON.stringify(cj).slice(0, 200), id: null };
+  const t0 = Date.now();
+  while (Date.now() - t0 < capMs) {
+    await SLEEP(2000);
+    const s = await j(BASE + '/api/shell/' + id + LOC);
+    const d = (s.json && s.json.data) || null;
+    if (d && d.status && d.status !== 'running') return { id, status: d.status };
+    if (!d) continue;
+  }
+  return { id, status: 'timeout' };
+}
+(async () => {
+  const mode = process.argv[2] || 'kick';
+  if (mode === 'kick') {
+    const k = await openShell(buildKickCmd(), 30000);
+    console.log('KICK', k.err || ('id=' + k.id + ' status=' + k.status));
+    return;
+  }
+  const r = await openShell(buildReadCmd(), 30000);
+  if (r.err) { console.log('READ_ERR', r.err); process.exit(1); }
+  const o = await j(BASE + '/api/shell/' + r.id + '/output' + LOC + '&limit=200000');
+  console.log('OUT_BEGIN');
+  console.log((o.json && o.json.data && o.json.data.output) || '(empty)');
+  console.log('OUT_END');
+})().catch(e => { console.error('ERR', e.message); process.exit(1); });

+ 27 - 0
_r190_204_run.cjs

@@ -0,0 +1,27 @@
+const BASE = 'http://192.168.16.204:4091';
+const AUTH = 'Basic ' + Buffer.from('opencode:' + (process.env.OPENCODE_SERVER_PASSWORD || 'IwinTrue@123')).toString('base64');
+const H = { Authorization: AUTH, 'Content-Type': 'application/json' };
+const LOC = '?location%5Bdirectory%5D=' + encodeURIComponent('D:\\cfc');
+async function j(url, opt) { try { const r = await fetch(url, Object.assign({ headers: H }, opt)); const t = await r.text(); try { return { status: r.status, json: JSON.parse(t) }; } catch { return { status: r.status, text: t }; } } catch (e) { return { status: 0, err: e.message }; } }
+async function sh(cmd, capMs) {
+  const cr = await j(BASE + '/api/shell' + LOC, { method: 'POST', body: JSON.stringify({ command: cmd, cwd: 'D:\\cfc' }) });
+  const id = cr.json && cr.json.data && cr.json.data.id;
+  if (!id) return { err: 'create ' + cr.status + ' ' + JSON.stringify(cr).slice(0,200) };
+  const t0 = Date.now();
+  while (Date.now() - t0 < (capMs || 120000)) {
+    await new Promise(r=>setTimeout(r,3000));
+    const s = await j(BASE + '/api/shell/' + id + LOC);
+    const d = (s.json && s.json.data) || null;
+    if (!d) continue;
+    if (d.status && d.status !== 'running') {
+      const o = await j(BASE + '/api/shell/' + id + '/output' + LOC + '&limit=200000');
+      return { code: d.status, out: (o.json && o.json.data && o.json.data.output) || '' };
+    }
+  }
+  return { err: 'timeout' };
+}
+(async () => {
+  // 前台同步跑(不重定向,直接输出),用 POSIX 风格路径避免 PowerShell 反斜杠转义
+  const r = await sh('Set-Location D:/cfc/tests; $env:PLAYWRIGHT_HTML_REPORT="false"; npx playwright test -c playwright.config.live.js --project=frontend-mobile --reporter=line', 180000);
+  console.log(r.err ? 'ERR=' + r.err : 'CODE=' + r.code + '\n' + r.out.slice(-1800));
+})().catch(e=>{console.error('ERR',e.message);process.exit(1);});

+ 55 - 0
_r190_251_lg.cjs

@@ -0,0 +1,55 @@
+// R190: 251 langgraph 派发器(基于 R150/R173 修复版)
+const BASE = process.env.BASE || 'http://192.168.16.251:4096';
+const DIR = process.env.DIR || '/sc-data/cfc/cfc-langgraph';
+const LOG = process.env.LOG || '/tmp/r190_pytest.log';
+const AUTH = 'Basic ' + Buffer.from('opencode:' + (process.env.OPENCODE_SERVER_PASSWORD || 'IwinTrue@123')).toString('base64');
+const H = { Authorization: AUTH, 'Content-Type': 'application/json' };
+const LOC = '?location%5Bdirectory%5D=' + encodeURIComponent(DIR);
+async function j(url, opt) {
+  try {
+    const r = await fetch(url, Object.assign({ headers: H }, opt || {}));
+    const t = await r.text();
+    try { return { status: r.status, json: JSON.parse(t) }; } catch { return { status: r.status, text: t }; }
+  } catch (e) { return { status: 0, err: e.message }; }
+}
+async function sh(cmd, capMs) {
+  const cr = await j(BASE + '/api/shell' + LOC, { method: 'POST', body: JSON.stringify({ command: cmd, cwd: DIR }) });
+  const id = cr.json && cr.json.data && cr.json.data.id;
+  if (!id) return { err: 'create ' + cr.status + ' ' + JSON.stringify(cr).slice(0, 200) };
+  const t0 = Date.now();
+  while (Date.now() - t0 < (capMs || 60000)) {
+    await new Promise(r => setTimeout(r, 2500));
+    const s = await j(BASE + '/api/shell/' + id + LOC);
+    const d = (s.json && s.json.data) || null;
+    if (!d) continue;
+    if (d.status && d.status !== 'running') {
+      const o = await j(BASE + '/api/shell/' + id + '/output' + LOC + '&limit=200000');
+      return { code: d.status, out: (o.json && o.json.data && o.json.data.output) || '' };
+    }
+  }
+  return { err: 'timeout' };
+}
+(async () => {
+  const mode = process.argv[2] || 'kick';
+  if (LOG.includes(':') || LOG.includes('\\')) {
+    console.error('BAD_LOG_PATH=' + LOG + ' 请使用远端 POSIX 路径(如 /tmp/rX_pytest.log),不要经由本地 env 注入');
+    process.exit(2);
+  }
+  if (mode === 'kick') {
+    // 先清理残留 pytest 进程(B-177-1 经验),再启动
+    const clean = await sh("ps -eo pid,etime,cmd | grep -E 'pytest|local_report' | grep -v grep | awk '{print $1}' | xargs -r kill -9 2>/dev/null; echo CLEANED", 30000);
+    const h = await sh('cd ' + DIR + ' && git rev-parse --short HEAD; date', 30000);
+    const inner = "cd " + DIR + " && .venv/bin/python -m pytest -q --ignore=tests/qna --ignore=tests/test_chat.py > " + LOG + " 2>&1; rc=$?; echo EXIT=$rc >> " + LOG;
+    const cmd = "rm -f " + LOG + "; setsid nohup bash -c '" + inner + "' >/dev/null 2>&1 & echo KICKED";
+    const r = await sh(cmd, 40000);
+    console.log('CLEAN=' + JSON.stringify(clean).slice(0, 200));
+    console.log('KICK=' + JSON.stringify(r).slice(0, 400));
+    console.log('NODE_HEAD=' + ((h.out || h.err || '').trim()));
+  } else if (mode === 'read') {
+    const r = await sh('tail -c 4000 ' + LOG, 45000);
+    console.log(r.err ? 'READ_ERR=' + r.err : r.out);
+  } else if (mode === 'run') {
+    const r = await sh(process.argv[3], 120000);
+    console.log(r.err ? 'ERR=' + r.err : r.out);
+  }
+})();

+ 69 - 0
docs/tdd/notice-2026-11-13-R190-研发通知.md

@@ -0,0 +1,69 @@
+# R190 轮研发通知(2026-11-13)
+
+## 状态摘要
+
+| 项目 | 内容 |
+|------|------|
+| 汇报轮次 | **R190**(2026-11-13 11:45~12:35) |
+| 基线 → 收尾 | `2313791a8`(R189)→ `0e6f285da`(含并行会话 S-cfc-186/182 契约类提交) |
+| 全站覆盖率 | 4141 例 / 4026 过 / 94 红 / 21 跳 = **97.22%** |
+| 零回归确认 | ✅ 浏览器任务级全绿(本机 4 组 + 189 + **204 恢复**);API 0 红;fe/web 零漂移;后端存量 25 红零漂移 |
+| **本轮正向项** | **204 节点 frontend 6/6 恢复**(B-95 观察改善);**S-cfc-182 契约 14/14 GREEN**(可收尾) |
+| **本轮回退项** | langgraph 51/51 → **50/51**(上游 401 `key ****ab12 invalid`,环境型,非代码回归) |
+| 主要阻塞 | ① **251 上游 AgnesAI key(****ab12)失效**(B-142-2 复发);② 49 前瞻契约 RED 待实现(P1);③ git SSH 22 CLOSED(B-189-1 延续) |
+
+---
+
+## 一、优先级事项(⏰ 按序处理)
+
+### P1 · langgraph 上游凭据失效(最紧急,恢复即回 51/51)
+
+- **现象**:`test_auto_tag_valid_format` 标签数 0(空 answer);日志实证 `Error code: 401 - Authentication Fails, Your api key: ****ab12 is invalid`。
+- **判别**:节点 HEAD=基线 `2313791a` + 窗口源码零变更 → **非代码回归,为上游 AgnesAI 凭据失效(B-142-2 复发)**。
+- **行动**:**请更换/恢复 251 节点上游 AgnesAI API key(当前 ****ab12 已失效)**;恢复后测试侧将复跑,连续 2 轮 51/51 后 B-142-2 再销号。
+
+### P2 · 窗口 2 契约类实测结论(S-cfc-186 1 RED 需实现;S-cfc-182 已 GREEN)
+
+| SC-key | 提交 sha | 类名 | 例数 | 当前结果 | 预期 | 描述 |
+|--------|----------|------|------|----------|------|------|
+| **S-cfc-186** | 0e6f285da | TeacherFamilyOverviewContractTest | 7 | 6P/1F | RED 1/7 | **跨家庭 IDOR**:`GuideFamilyTaskController.getFamilyMemberTasks` 仅校验 `requireBound(guideId, familyId)`,**未校验 `memberId ∈ familyId`**——教师绑家庭 A 可读家庭 B 成员任务(SC-T-16/17/21/27) |
+| **S-cfc-182** | 5d67a62f6 | TeacherReportProxyContractTest | 14 | **14P/0F** | **GREEN** ✅ | teacher.report.proxy 已实现,**可直接收尾** |
+
+> **行动**:S-cfc-186 需在 `getFamilyMemberTasks` 增加 memberId 属主校验(拒绝跨家庭访问,不得进入 `taskService.getTaskHistoryByFamilyMember`),实现后复跑该类 7/7 绿;S-cfc-182 直接收 YELLOW/GREEN。
+
+### P3 · 存量 49 前瞻契约 RED(R189 48 + S-cfc-186 1,P1 承袭)
+
+- 类清单(R189 已下发,本轮维持):S-cfc-183 `PlanContentSafetyReview` 4F / S-cfc-184 `TeacherAssessmentRecord` 3F / S-cfc-188 `FamilyAutoCreateForPurchase` 4F / S-cfc-196 `TeacherPlanCreate` 4F / `TeacherMindRecord` 12F / `TeacherAppointmentGuard` 10F / `GuideFamilyTaskReview` 2F / `NutritionPlanTeacher` 3F / `TeacherDataIsolationScT13` 4F / `TeacherDimensionScore` 2F / 其余(含 176 幂等 1F)。
+- GREEN 四键(S-cfc-189 LoginSwitch 16、S-cfc-191 MessagePush 20、**S-cfc-182 14**、PlanActivate 15)已全绿,可直接收尾。
+- 行动:按计划逐键实现使绿。
+
+### P4 · git SSH 22 故障(B-189-1 延续,运维/平台侧)
+
+- 现象:`git.iwintrue.com` / 251 **SSH 22 CLOSED**(R188 09:39 起,本轮延续)。
+- 行动:**请运维检查 Gogs SSH 服务**(端口 22 / 251 sshd);本轮测试产物已经 HTTP 兜底推送(`http://git.iwintrue.com/liaoxg/cfc.git`)。
+
+### P5 · 存量 25 红后端(跨 25 轮承袭)
+
+- 类清单:`EnergySystemFlowTest` 6F / `DimensionRegistryMapContractTest` 3F / `OrchestrationEngineTest`·`OrchestrationIntegrationTest`·`MembershipPaySwitchTest`·`PaymentServiceORDRoutingTest`·`UserServiceWechatLoginTest`(×2)·`TeamProfitCronContractTest` 各 1F 等。
+- 行动:按计划逐类修复;优先 `TeamProfitCronContractTest`(平台费截断影响计费)。
+
+---
+
+## 二、本轮已闭环 / 观察推进
+
+- ✅ **B-95(204 节点失联)观察改善**:openCode 服务实际在 **204:4091**(历轮误判 4090=000),项目 `D:\cfc`;本轮 fe **6/6 恢复** → 观察改善,**连续 2 轮 6/6 后可销号**。
+- ⏳ **B-142-2(上游凭据)复发观察 1/2**:本轮 50/51(401 环境红);更换 key 后连续 2 轮 51/51 再销号。
+- ⏳ B-186-1(live chat 120s 挂死):独立观察。
+- ⏳ B-36 根级黑盒 16 红(9082 未起):承袭。
+- ⏳ B-DX-1 dx 桥接 2 例 skip(404):承袭。
+
+---
+
+## 三、证据链
+
+- 报告:`docs/tdd/orchestration/report-test-2026-11-13-R190.md`
+- 执行日志:`docs/tdd/test/automation-run-2026-11-13-R190.md`
+- blockers:`docs/tdd/test/blockers.md`(含 B-190-1/B-190-2 段)
+- 台账:`docs/tdd/test/{discovery,inventory,automation-status}.md`(已刷新)
+
+> 📤 推送状态:✅ 本轮经 HTTP 兜底推送完成(SSH 22 仍故障,见 §一 P4)。

+ 263 - 0
docs/tdd/orchestration/report-test-2026-11-13-R190.md

@@ -0,0 +1,263 @@
+# 测试负责人工作汇报(R190 轮)
+
+> 本汇报按《测试负责人工作汇报模板》填写。R190 为**实测轮 + 窗口契约验证轮**:基线 `cfclub @ 2313791a8`(R189 收口 11:45 的 auto-bump),当前 HEAD `0e6f285da`(12:28 并发 rebase 后;窗口含并行会话推入 **S-cfc-186 + S-cfc-182 两个契约测试类** + 2 份 docs)。
+> **拓扑(用户指令)**:浏览器经 `http://cfc.iwintrue.com/admin`(后台)+ `http://cfc.iwintrue.com/frontend`(小程序);189 与本机为浏览器节点(**每节点仅 1 个浏览器任务**,本机串行);langgraph 部署 251 → **本轮已实派 251 并实跑**。
+> **★ 本轮关键事实**
+> ① **窗口(2313791a8..0e6f285da)源码/SRS/场景/接口文档零变更**(`src`/`cfc-backend/src/main`/specs/test-cases/API_REFERENCE/场景 diff 命中 0)→ G12 ✅,用例无需由我更新;窗口唯一代码变更 = 并行会话新增 **2 个契约测试类**(S-cfc-186 `TeacherFamilyOverviewContractTest` 7 例 + S-cfc-182 `TeacherReportProxyContractTest` 14 例),本轮已**逐类定向实测取证**;
+> ② **窗口契约窗实测 21/21:S-cfc-186 6 过 / 1 预期 RED / 0 错**(RED = 「跨家庭 IDOR」:`GuideFamilyTaskController.getFamilyMemberTasks` 仅校验 `requireBound(guideId, familyId)` 而未校验 `memberId ∈ familyId`,教师绑家庭 A 可读家庭 B 成员任务)+ **S-cfc-182 14/14 GREEN ✅**(teacher.report.proxy 能力已实现落地);
+> ③ **langgraph@251 50/51**(唯一红 `test_auto_tag_valid_format` 标签数 0)——根因上游 `401 Authentication Fails, api key ****ab12 invalid`(B-142-2 复发,**环境型非代码回归**;节点 HEAD=基线 + 窗口源码零变更);
+> ④ **浏览器任务级全绿**:本机四件套 28/28(admin 5 + fe 6 + shop 4 + health 13);跨节点 **189 admin 5/5 EXIT=0**、**204 frontend 6/6(B-95 观察改善,节点恢复)**;dx 桥接 2 跳承袭(B-DX-1)。
+> ★ **全站可比:4141 例 / 4026 过 = 97.22%(剔 skip 97.72%),红 94**——红数环比 +2 全为**窗口新契约预期 RED(S-cfc-186,+1)**与**上游 401 环境红(B-142-2 复发,+1)**,**零缺陷回归**。
+
+---
+
+## 基本信息
+
+| 项目 | 内容 |
+|------|------|
+| 汇报人 | 测试负责人(自动化测试闭环任务 / 软件测试专家团·陆谨) |
+| 汇报周期 | 2026年11月13日 11:45 ~ 12:35(第 190 轮) |
+| 基线 | `cfclub @ 2313791a8`(R189 收口 auto-bump);本轮收尾 HEAD `0e6f285da`(12:28 并发 rebase 后,含 S-cfc-186 提交再落位 + S-cfc-182 merge + 2 docs) |
+| 窗口内需求变更 | **零** — `docs/superpowers/specs` / `tests/test-cases` / `API_REFERENCE.md` / 用户场景 窗口零变更(G12 ✅,未触发用例编写闸门) |
+| 窗口内源码变更 | **零** — `git diff --name-only 2313791a8..0e6f285da` 对 `src`、`cfc-backend/src/main`、需求、用例、接口文档命中 0;唯一变更 = 2 个契约测试类(S-cfc-186 `TeacherFamilyOverviewContractTest` +249 / S-cfc-182 `TeacherReportProxyContractTest`,均并行会话提交)+ 2 份 docs(`report-dev-2026-11-13-1210.md`、`sc-key-map.md`) |
+| 负责模块/单元 | 全站:管理端 admin@本机 + 189 · 小程序 H5 fe@本机 + **204(B-95 恢复)** · cfc-langgraph@251(**本轮实派**) · cfc-backend JUnit(全量采信 R189 + 窗口 2 契约类实测 21 例) · cfc-web/cfc-frontend Jest · 线上 API 非功能层 |
+
+---
+
+## 一、本轮工作数据汇总
+
+### 1.1 测试用例建设
+
+| 指标 | 数量 | 填写说明 |
+|------|------|----------|
+| **本轮新增测试用例数\*** | **0 个(由我新增);窗口并行会话 +21 例(S-cfc-186 7 + S-cfc-182 14)** | SRS/场景/接口文档窗口零变更,未触发用例编写闸门(G12 ✅);窗口内并行会话新增 `TeacherFamilyOverviewContractTest`(SC-T-16/17/21/27,7 例)与 `TeacherReportProxyContractTest`(S-cfc-182,14 例)已入库并于本轮逐类定向实测 |
+| **本轮验证执行测试数\*** | **4141 个** | 后端 **3265**(R189 全量采信 3244 + 窗口 2 契约类实测 21)+ 前端 Jest 740(fe 624 + web 116)+ 管理端 116 + langgraph 51(**251 实派**)+ 浏览器 30(唯一 28 过 + dx 2 跳承袭)+ 线上 API 32 + 根级 23 |
+| **用例通过率** | **97.22%**(4026/4141;剔除 skip **97.72%**) | 红 94 / 跳 21;环比 R189(97.16%)**+0.06pct**,红数 +2 全部为**窗口新契约预期 RED(S-cfc-186,+1)+ 上游 401 环境红(B-142-2 复发,+1)**,**零缺陷回归** |
+| **用例台账** | `discovery.md` / `inventory.md` 已重扫重写 | inventory 跨源 **4588**(md 719 / PW 571 / py 48 / Java @Test **3250** / 场景 11);Java 测试文件 390(较 R189 388 **+2**,即窗口 S-cfc-186 + S-cfc-182 两类) |
+
+### 1.2 会话与任务分发
+
+| 指标 | 数量 | 填写说明 |
+|------|------|----------|
+| **分派任务数\*** | **7 个** | R190-1 本机 `admin-desktop`(5/5);R190-2 本机 `frontend-mobile`(6/6);R190-3 本机 `shop-api`(4/4)+ `health`(13/13);R190-4 **189** `admin-desktop`(5/5 EXIT=0);R190-5 **251** `langgraph pytest`(**50/51**,269.16s);R190-6 **204** `frontend-mobile`(**6/6 恢复**,46.1s);R190-7 后端窗口 2 契约类定向(S-cfc-186 7 例 + S-cfc-182 14 例) |
+| **恢复智能体会话数\*** | 0 个 | 各节点实探 200/ok(189:4090、204:4091、251:4096、251:9000、本机 4091 全可达);未遇中断会话 |
+| **当前在用会话数** | 0 个 | 全部结束;251 残留 pytest 进程已清理(B-177-1 观察维持) |
+
+### 1.2b 各会话当前工作状态列表
+
+| 会话标签 | 会话 ID/地址 | 当前状态 | 当前任务 | 静默/空闲时长 | 工作目录 | 备注 |
+|----------|--------------|----------|----------|---------------|----------|------|
+| `local-admin` | 本机 Playwright | done | admin-desktop UI E2E | 1.4m | `d:\cfc\tests` | **5/5**;TC-A-U01~U05 全过 |
+| `local-frontend` | 本机 Playwright | done | frontend-mobile UI E2E | 46.2s | `d:\cfc\tests` | **6/6**;B-185 维持消除 |
+| `local-shop` | 本机 Playwright | done | shop-sort API E2E | 6.9s | `d:\cfc\tests` | **4/4** |
+| `local-health` | 本机 Playwright | done | health 鉴权契约 E2E | 4.2s | `d:\cfc\tests` | **13/13**(TC-HP-U01~03 全 401,B-61 维持) |
+| `remote-189` | 192.168.16.189:4090 | done | admin-desktop UI E2E | 1.3m | `D:\code\cfc\tests` | **5/5 EXIT=0**,跨节点可比 |
+| `remote-204` | 192.168.16.204:4091 | done | frontend-mobile UI E2E | 46.1s | `D:\cfc\tests` | **6/6 恢复**(B-95 观察改善:204 节点 openCode 服务在 4091,项目在 D:\cfc) |
+| `remote-251` | 192.168.16.251:4096 | done | langgraph pytest | 269.16s | `/sc-data/cfc/cfc-langgraph` | **50/51**;唯一红=上游 401 环境型;节点 HEAD `2313791a`(=基线) |
+| `local-jest` | 本机进程 | done | cfc-web + cfc-frontend + 根级 | fe 172s / web 209s | `cfc-web` / `cfc-frontend` / `tests` | web **116/116**、fe **609/3/12**(3 预期 RED)、根级 **7/16**(B-36) |
+| `local-backend` | 本机 mvn | done | 窗口 2 契约类定向(S-cfc-186 + S-cfc-182) | ~2m | `d:\cfc\cfc-backend` | **21 例 = S-cfc-186 6 过/1 预期 RED + S-cfc-182 14 过/0 红 / 0 错** |
+| `virtual` | dx-bridge | done | D/X 桥接鉴权契约 | 瞬时 | `d:\cfc\tests` | **2 skip**(端点 404,B-DX-1 维持,本轮承袭) |
+
+### 1.3 问题处置
+
+| 指标 | 数量 | 填写说明 |
+|------|------|----------|
+| **新测试发现问题数\*** | **2 个** | ① **B-190-1(P1 环境)**:**B-142-2 复发**——langgraph `test_auto_tag_valid_format` 标签数 0,日志实证 `Error code: 401 - Authentication Fails, Your api key: ****ab12 is invalid`(上游 AgnesAI 凭据失效)。判别:节点 HEAD=基线 `2313791a` + 窗口源码零变更 → **环境型,非代码回归**;② **B-190-2(P2 流程)**:窗口尾部并行会话推入 **2 个契约测试类**(S-cfc-186 `TeacherFamilyOverviewContractTest` 7 例 + S-cfc-182 `TeacherReportProxyContractTest` 14 例)**未逐类验证入库** → 本轮补验完成:S-cfc-186 6 过 / 1 预期 RED(跨家庭 IDOR) + S-cfc-182 14/14 GREEN ✅。 |
+| **已解决测试相关问题数\*** | **1 个** | **B-95(204 节点失联)观察改善**:历轮 `204:4090=000` 误判(openCode 实际服务在 **204:4091**,项目 `D:\cfc`),本轮 204 frontend **6/6 恢复** → 登记为「观察改善」,待连续 2 轮可复现后销号。 |
+| **待解决测试相关问题数** | P0×2 / P1×8 / P2×4 | ① B-152-1/2 CI 清单漏拦/陈旧;② S-cfc-183/184/188/196 + **S-cfc-186** 等 **49 前瞻契约 RED**(P1,需研发实现使绿);③ S-cfc-176 幂等 1F;④ B-177-1 pytest summary 后挂死;⑤ B-156-1/B-170-1 迁移 DDL;⑥ B-162-1 3 类未入库;⑦ B-178-1 反射装置 2F;⑧ B-36 根级 16 红(9082 未起);⑨ B-95 观察改善待销号;⑩ B-DX-1 dx 404;⑪ B-186-1 live chat 挂死;⑫ **B-189-1 git SSH 22 故障**;⑬ **B-142-2 复发观察 1/2**。 |
+
+### 1.4 本轮 git 提交与推送证据(真理证据)
+
+| 提交 sha | 关联任务/能力键 | 阶段 | 触及文件类型 | 目标分支 | 已推送远端 | 备注 |
+|----------|-----------------|------|--------------|----------|------------|------|
+| `(本轮)` | 全站巡检 R190 + 窗口 2 契约类补验(S-cfc-186/182)+ B-142-2 复发登记 + B-95 观察改善 + B-190-1/2 登记 | 汇报 | 报告 + 执行日志 + blockers + 研发通知 + 台账 + 派发器 | cfclub | ✅ 推送远端 `http://git.iwintrue.com/liaoxg/cfc.git`(SSH 22 仍故障,经 HTTP 兜底;B-189-1 延续) | 结果有变化 → 已提交并通知研发 |
+
+### 1.5 状态机阶段分布(全局进度,研发侧账本口径)
+
+| 阶段 | 键数 | 备注 |
+|------|------|------|
+| UNTRACKED | 0 | 窗口零新增规格(S-cfc-186/182 为并行会话契约用例) |
+| RED | 17(历轮承袭)+ 窗口 S-cfc-186 等 49 前瞻契约 RED | S-cfc-183/184/186/188/196 等 11 类已本轮实测取证;研发状态机口径另计 |
+| YELLOW | 72 | 研发负责人口径(第153轮) |
+| GREEN / DONE | 24(承袭)+ S-cfc-182 契约键 | S-cfc-182(teacher.report.proxy)14/14 GREEN 本轮取证 |
+| 合计 | 105+ | 研发侧状态机账本口径(本轮交付 `blockers` 后互联) |
+
+### 1.6 数据源健康度
+
+| 数据源 | 读取键数 | 是否正常 | 备注 |
+|--------|----------|----------|------|
+| 需求侧(⏳ wish) | 0 | 正常 | SRS 目标池未启用 |
+| 契约常量(contract) | 多组 | 正常 | 窗口 S-cfc-186/182 可收集可执行 |
+| 测试用例引用(test_case_map) | 308+ 唯一 TC | 正常 | 台账扫描正常 |
+| 执行结果回填(case_results) | 定向 21 + 全量采信 | 正常 | surefire XML 可聚合 |
+
+---
+
+## 二、历史审查记录(阶段 -1 记忆召回)
+
+| 项 | 内容 |
+|---|---|
+| 上次审查 | **R189(2026-11-13 11:30,`6124352d7`/`67fb0a1f5` 推送)**,结论「不通过(承袭,无回归、正向项明确)」,全站 4120/4003(97.16%),红 92;langgraph 51/51 连续第 2 轮(B-142-2 销号);浏览器六件套全绿;契约窗 13 类 133 例 85/48 |
+| 历史遗留 | 后端存量 25 红(12 类)· 根级 16 红(B-36)· fe 3 预期 RED(S-cfc-132/133)· CI 漏拦/陈旧(B-152-1/2)· B-177-1 · B-178-1 · B-186-1 live chat · B-189-1 SSH 22 |
+| 本次是否改善 | **204 节点 frontend 6/6 恢复(B-95 观察改善,正向)**;窗口新增 2 契约类已补验(S-cfc-186 6 过/1 预期 RED + **S-cfc-182 14/14 GREEN**);后端存量 25 红窗口零漂移;浏览器任务级全绿;其余承袭 |
+| 本次是否回退 | **langgraph 51/51 → 50/51(−1)**:唯一红 `test_auto_tag_valid_format` 为上游 **401(api key ****ab12 invalid)环境型**,节点 HEAD=基线 + 窗口源码零变更 → **非代码回归**;B-142-2 由「销号」转「复发观察 1/2」(需恢复 key 后连续 2 轮 51/51 再销号) |
+| 教训应用 | ① 窗口出现新增契约测试类必须逐类定向实测取证再入报告(B-190-2 复用 B-189-2 教训);② 上游 LLM 凭据失效时以「节点 HEAD=基线 + 窗口源码零变更」判别环境型(B-142-2 判别式);③ 204 节点失联须先探明实际端口(openCode 在 4091 而非 4090)再定位(B-95);④ 每节点仅 1 个浏览器任务、本机串行执行。 |
+
+> 本次为该对象**第 190 次**审查,有历史记录;上述内容仅作对照,**本轮前端/管理端/langgraph/浏览器/API/根级/契约窗全部本轮实测**;后端全量采信 R189(窗口 main 零变更)+ 窗口 2 契约类本轮实测。
+
+---
+
+## 三、项目画像与覆盖矩阵
+
+### 3.1 项目画像
+
+| 维度 | 内容 |
+|------|------|
+| 业务定位 | 家庭教育成长平台(五维能量 身/心/智/行/富):小程序家长端 + 规划师端 + 管理后台 + 独立商城 |
+| 技术栈 | Spring Boot 2.7.18 + MyBatis-Plus + Java 8(9082)/ uni-app 微信小程序(Vue2)/ Vue2 + Element UI(8082)/ FastAPI + LangGraph + ChromaDB(9000@251) |
+| 模块结构 | `cfc-backend`(366 控制器 / 390 测试源 / 369+15 测试类)/ `cfc-frontend`(42 测试文件 / 624 例)/ `cfc-web`(17 套件 / 116 例)/ `cfc-langgraph`(51 例 @251)/ `tests`(e2e-live 5 文件 + e2e/api 点名 4 文件) |
+| 关键路径 | 登录/家庭/成员 → 五维能量 → 任务/成长记录 → 健康报告上传解析 → 测评订单 → 商城/支付 → AI 对话(LangGraph) |
+| 测试现状 | **本轮实测**:浏览器 28(唯一)+ 跨节点 11(189 admin 5 + 204 fe 6)+ langgraph 51 + fe 624 + web 116 + 根级 23 + API 32 + 窗口契约类 21(S-cfc-186 7 + S-cfc-182 14)= **906 例实测**;后端全量 3244 采信 R189(窗口 main 零变更) |
+| 质量目标 | 全量用例全绿、覆盖 SRS 与用户场景(含异常流)、浏览器双节点可复现、结果变更即提交并通知研发 |
+| 风险点 | ① 后端存量 25 红(12 类)+ 契约窗 49 RED 待实现;② CI 清单双向失真;③ 上游 LLM 凭据失效(B-142-2 复发,**api key ****ab12 invalid**);④ 根级 16 红(9082 未起);⑤ 迁移 DDL 缺陷;⑥ pytest 进程不退出(B-177-1);⑦ **git SSH 22 故障(B-189-1)** |
+| 待核实项 | S-cfc-176 幂等分支排期 · 251 上游 key 更换(****ab12)· 204 恢复后续稳定性 · B-156-1/B-170-1 修复状态 · S-cfc-186 跨家庭 IDOR 研发排期 |
+
+### 3.2 20 类测试覆盖矩阵(全类不省略)
+
+| # | 测试类型 | 三态 | 证据(本轮实测) |
+|---|----------|------|------------------|
+| 1 | 单元测试 | ✅ 已发现 | 后端全量 3244(采信 R189)+ 窗口契约类 21(实测);前端 624;管理端 116 |
+| 2 | 测试覆盖率 | ⚠️ 部分 | 管理端 Jest 覆盖率可产出;后端未开 jacoco(未授权改 pom) |
+| 3 | 变异测试 | ❌ 未发现 | 全仓无 pitest/mutation 配置 |
+| 4 | 集成测试 | ✅ 已发现 | `integration/*` 存量执行结果承袭(EnergySystemFlow 6F、GuideModule 1E 等);本轮未重跑(main 零变更) |
+| 5 | 契约测试 | ✅ 已发现(本轮重点) | **窗口 2 契约类 21 例全实测**:S-cfc-186 7 例(6 过 / 1 预期 RED 跨家庭 IDOR)+ **S-cfc-182 14/14 GREEN**;R189 契约窗 13 类 133 例承袭(85/48);S-cfc-176 维持 1F |
+| 6 | 接口 API 测试 | ✅ 已发现 | 线上 API 32 例(**本轮实测**:25 过 / 7 跳 / 0 红,28s) |
+| 7 | 系统/端到端 | ✅ 已发现 | 浏览器 28 例唯一(**本轮实测**:admin 5 + fe 6 + shop 4 + health 13 全过)+ 跨节点 11(189 admin 5/5、204 fe 6/6)+ dx 2 跳承袭 |
+| 8 | 验收 UAT | ⚠️ 待核实 | 无独立 UAT 包;以浏览器 28 例作为系统级验收代理 |
+| 9 | BDD 规格 | ✅ 已发现 | 用例/场景 11 份(用户场景文件级,映射率 72.1% 承袭) |
+| 10 | 冒烟测试 | ✅ 已发现 | `api-smoke.spec.js` 本轮实测全绿(含自注册链路) |
+| 11 | 回归测试 | ✅ 已发现 | 存量红集合 12 类逐类零漂移(**第 25 次**);admin/frontend/shop/health 全绿;204 fe 恢复 |
+| 12 | 探索性测试 | ⚠️ 部分 | 历轮浏览器人工探索记录;本轮未安排新探索项 |
+| 13 | 性能测试 | ❌ 未实测 | 未授权联网压测;仅 API 时延观察(非功能 32 例内含超时断言) |
+| 14 | 可靠性测试 | ⚠️ 部分 | pytest 挂死(B-177-1 观察)为可靠性缺陷;本轮 269.16s 正常收口 |
+| 15 | 安全测试 | ✅ 已发现 | `nonfunc-security.spec.js` 11 例本轮全绿(XSS/越权/恶意文件);匿名 6 端点全 401 |
+| 16 | 兼容性测试 | ⚠️ 部分 | 双视口(desktop 1440 / mobile 375)实测通过;无多浏览器矩阵 |
+| 17 | 可用性测试 | ⚠️ 部分 | 登录-主框架-核心菜单旅程 5/5×2 节点;无专项可用性问卷 |
+| 18 | 无障碍测试 | ❌ 未发现 | 无 axe/pa11y 配置 |
+| 19 | QA 流程 | ⚠️ 部分 | 汇报/台账/blockers 闭环在跑;CI 清单失真(B-152-1/2)未修 |
+| 20 | 质量指标 | ⚠️ 部分 | 全站通过率 97.22%(G1 未达 98%);锚点率 20.1% 承袭 |
+
+---
+
+## 四、五要素问题清单
+
+| # | ① 问题描述 | ② 测试 bug 点 | ③ 最优修改方案 | ④ 修改目的 | ⑤ 闭环方式 |
+|---|-----------|--------------|----------------|-----------|-----------|
+| P1 | 后端存量 25 红(12 类,跨 25 轮)零漂移承袭 | `EnergySystemFlowTest` 6F / `DimensionRegistryMapContractTest` 3F / `OrchestrationEngineTest`·`OrchestrationIntegrationTest`·`MembershipPaySwitchTest`·`PaymentServiceORDRoutingTest`·`UserServiceWechatLoginTest`(×2)·`TeamProfitCronContractTest` 各 1F 等 | 按类逐条修;先修 `TeamProfitCronContractTest`(平台费截断,影响计费) | 后端回归全绿 → G2 闭环 | 修后 `mvn -o -B test -Dtest=<类>` 定向复跑,单类 0F 连续 2 轮 |
+| P2 | **窗口 49 前瞻契约 RED 待研发实现(TDD 先行态,本轮已取证)** | S-cfc-183 `PlanContentSafetyReviewContractTest` 4F / S-cfc-184 `TeacherAssessmentRecordContractTest` 3F / S-cfc-188 `FamilyAutoCreateForPurchaseContractTest` 4F / S-cfc-196 `TeacherPlanCreateContractTest` 4F / **S-cfc-186 `TeacherFamilyOverviewContractTest` 1F(跨家庭 IDOR:getFamilyMemberTasks 未校验 memberId∈familyId)** / TeacherMindRecordContractTest 12F / TeacherAppointmentGuardContractTest 10F / 其余 6 类 11F | 按 SC-T 界面对应实现(必填拦截、重复覆盖、权限门禁、自动建家庭、mind 记录、预约守卫、**memberId 属主校验**等);本报告 `notice` 已逐键下发 | 49 前瞻契约 RED 转绿 → RED 清零 | 实现后逐类定向复跑,单类 0F 即销 RED;GREEN 四键(189/191/182/Activate)已全绿可直接收尾 |
+| P3 | S-cfc-176 幂等分支未生效 | `MembershipPlanPurchaseContractTest.repeatPurchase_pendingOrderSamePlan_reuseNoDuplicate:201`(`NeverWantedButInvoked: paymentOrderMapper.insert`) | `findReusablePendingOrder` 命中后直接复用,不再 insert | 契约闭环(防重复下单) | 定向复跑该类 7/7 绿 |
+| P4 | 迁移 DDL 缺陷持续复现 | `schema.sql:5345` `INDEX idx_product (product_id)` 无该列;`DatabaseInitializer.java:2261` 带别名 UPDATE + 派生表引用被更新表 | 删索引或补列;改独立子查询写法 | 建表成功 + 计数列可写 | 启动日志 0 次 `SQLSyntaxErrorException` |
+| P5 | 未入库测试资产 3 类 | `config/GrowthPublicEndpointMappingTest.java`(`??` 未跟踪)等 | `git add` + push | 资产可追溯 | 入库后全量重跑该类 0E |
+| P6 | pytest 打印 summary 后进程不退出(B-177-1)| `tests/test_analyze.py` → `RuntimeWarning: coroutine 'JavaClient._get_client' was never awaited` | `app/main.py:84` 改用 lifespan 并 `await client.aclose()`;派发器加 `timeout -k 10 900` | 派发可判定成功、节点不残留 | 派发日志出现 `EXIT=0` 且 `ps` 无残留 |
+| P7 | 根级黑盒 16 红(B-36 第 74 轮) | `tests/integration/*`(全 `ECONNREFUSED 9082`) | 起本地 9082 或改指向测试环境 | 黑盒链路可测 | 9082 起来后重跑 23 例 |
+| P8 | CI 清单双向失真(B-152-1/2) | `.gitlab-ci.yml:61`(漏拦 6 + 陈旧 26) | 按实测红类集合精修 `BACKEND_OBSERVED_CLASSES`(接入本轮 S-cfc-186) | CI 硬门禁真实生效 | CI 在含红例分支上「必红」验证一次 |
+| P9 | 前端 3 例预期 RED | `signature.*`(AC-R1/AC-R2)+ `growthHistory.dayGroupView` RED-A7 | 交付 S-cfc-132/133 组件与分组逻辑 | 前端全绿 | `npx jest` 624/624 |
+| P10 | **langgraph 上游凭据失效(B-142-2 复发,环境型)** | `test_auto_tag_valid_format` 标签数 0;日志 `Error code: 401 - Authentication Fails, Your api key: ****ab12 is invalid` | **更换/恢复 251 上游 AgnesAI API key(****ab12)** | langgraph 51/51 回归 | 恢复后连续 2 轮 51/51 → B-142-2 再销号 |
+| P11 | **git SSH 22 故障(B-189-1,延续)** | `git.iwintrue.com` / `192.168.16.251:22` CLOSED(R188 09:39 起) | Gogs 侧恢复 SSH 服务/端口映射;故障期经 `http://git.iwintrue.com/liaoxg/cfc.git` 只读确认远端 HEAD | fetch/push 恢复正常 | `git fetch origin` 成功 + 本轮产物推送成功 |
+| P12 | 204 节点历史失联(B-95) | 历轮误判 `204:4090=000`(openCode 实际服务在 **204:4091**,项目 `D:\cfc`) | 更新节点拓扑登记(4091);本轮 fe 6/6 恢复 | 节点可比性重建 | 连续 2 轮 6/6 可复现后销号 |
+| P13 | dx 桥接 2 例 skip(404) | `dx-health-bridge-auth.spec.js`(端点 404) | 端点上线后自动转断言 | 覆盖空转消除 | 线上端点 200 后重跑转 401 断言 |
+
+---
+
+## 五、域结论表
+
+| 审查维度 | 负责专家 | 结论 | 关键证据 |
+|----------|----------|------|----------|
+| 单元·组件级 | 苏雅 | **改善** | 窗口 2 契约类 21 例全实测(S-cfc-186 6 过/1 预期 RED + **S-cfc-182 14/14 GREEN**);fe 609/3/12(3 预期 RED);web 116/116 |
+| 集成·接口级 | 柯砚 | **改善** | 线上 API 32 例 0 红;S-cfc-176 维持 1F;契约窗 GREEN 四键(189/191/**182**/Activate)可收尾 |
+| 系统·验收级 | 白樾 | **改善** | 浏览器 28 例唯一全过 + 跨节点 189 admin 5/5、**204 fe 6/6 恢复(B-95 观察改善)**;health 13/13(B-61 维持) |
+| 测试保障级 | 闻朔 | 改善 | 冒烟全绿;存量红集合零漂移(第 25 次);契约验证流程延续(B-190-2 补验窗口 2 契约类) |
+| 性能·可靠性 | 骆骋 | 承袭 | 后端全量采信(窗口零变更);langgraph 50/51 正常收口(上游 401 环境型)但 pytest 进程不退出仍为可靠性缺陷(B-177-1) |
+| 安全 | 关屿 | **改善** | 匿名端点全 401;nonfunc-security 11 例全绿(XSS/越权/恶意文件);S-cfc-186 暴露 IDOR 门禁缺口(预期 RED,待研发补 memberId 属主校验) |
+| 兼容·体验 | 阮清 | 稳定 | frontend 移动视口 6/6(本机+204);desktop 双节点 admin 5/5;无多浏览器矩阵 |
+| 流程·度量 | 何序 | 部分改善 | G12 ✅ 窗口零需求变更;G9 锚点 20.1% 承袭;CI 漏拦/陈旧未修(B-152-1/2) |
+
+---
+
+## 六、门禁结论
+
+**结论:不通过(承袭,无回归、正向项明确)** —— 全站 4141 例 / **4026 过 = 97.22%(剔 skip 97.72%)**,红 94。红数环比 +2 的全部来源为**窗口新增契约测试预期 RED(S-cfc-186,+1)**与**上游 401 环境红(B-142-2 复发,+1)**,均非缺陷回归;浏览器任务级全绿(含 **204 恢复**);API 零红;后端存量 25 红零漂移。阻断项为**存量红 + 49 前瞻契约 RED + CI 清单失真 + live chat 挂死 + 251 上游 key 失效**,均非本轮新增回归。
+
+| 门禁 | 判定 | 依据(本轮实测) |
+|------|------|------------------|
+| G1 全站通过率 ≥98% | ❌ **97.22%** | 4026/4141(剔 skip 97.72%);+0.06pct,红数 +2 为契约预期 RED + 环境红 |
+| G2 后端红归零/契约裁决 | ❌ **74 红** | 存量 25(12 类)+ **契约窗 49 预期 RED(11 类,含 S-cfc-186,需研发实现)** |
+| G3 前端双绿 | ⚠️ fe 609/624(3 预期 RED)+ web 116/116;**小程序 H5 浏览器 6/6(本机+204)** | 3 红全为 S-cfc-132/133 未交付 |
+| G4 编译可编译 | ✅ | 窗口 S-cfc-186/182 全量 test-compile + 定向执行无编译错 |
+| G5 结果完整性 | ✅ | 定向 21 例 surefire XML 完整;全量承袭 R189 388 XML 可聚合 |
+| G6 浏览器 E2E | ✅ **28 过 + 2 跳承袭** | admin 5/5(本机+189)、fe 6/6(本机+**204**)、shop 4/4、health 13/13、dx 2 跳 |
+| G7 langgraph | ⚠️ **50/51** | **B-142-2 复发(环境型)**:唯一红=上游 401 `key ****ab12 invalid`;节点 HEAD=基线 + 窗口源码零变更 |
+| G8 匿名鉴权 401 | ✅ | health 三端点全 401;API 安全套件 11 例全绿 |
+| G9 用例锚定 SRS | ❌ 20.1% | 承袭口径(本轮未变) |
+| G10 双/三节点可比 | ✅ 三节点 | 189 admin 5/5 + **204 fe 6/6(恢复)** + 本机 admin 5/5 + 251 langgraph 51 例 |
+| G11 CI 必红 | ❌ | 漏拦 6 + 陈旧 26 承袭(B-152-1/2) |
+| G12 用例锚定 SRS 变更 | ✅ | specs / test-cases / API_REFERENCE / 场景窗口零变更 → 用例零新增(我);S-cfc-186/182 为并行会话产出并已补验 |
+| G13 存量红零漂移 | ✅ **第 25 次** | 12 类逐类与 R189 一致;B-95 为唯一改善项(正向) |
+
+---
+
+## 七、变更触发动作(用户规则:结果有变 → 提交远程 + 通知研发)
+
+- **变更事实(本轮)**:① 窗口**新增 2 契约类共 21 例**(S-cfc-186 7 + S-cfc-182 14,并行会话提交)经定向实测取证:**S-cfc-186 6 过 / 1 预期 RED(跨家庭 IDOR)** + **S-cfc-182 14/14 GREEN**;② langgraph **51/51 → 50/51**:B-142-2 复发(上游 401 key 失效),**非代码回归**,需研发更换 key;③ **204 节点 frontend 6/6 恢复**(B-95 观察改善);④ 浏览器任务级全绿、API 零红、fe/web 零漂移;⑤ 全站口径 4141 例(+21)。
+- **动作**:本报告 + `automation-run-R190.md` + `blockers.md`(B-190-1/2 新增、B-142-2 复发观察 1/2、B-95 观察改善、B-189-1 延续)+ `notice-2026-11-13-R190-研发通知.md` + 台账三件套(discovery/inventory/automation-status)提交推送。
+- **推送状态**:✅ **已完成**。SSH 22 仍 CLOSED(B-189-1 延续),已将 push remote 切换至 `http://git.iwintrue.com/liaoxg/cfc.git` 执行 `git rebase FETCH_HEAD && git push origin cfclub`;fetch 仍须临时指定 HTTP URL。**请运维恢复 Gogs/251 sshd 服务(端口 22)**。
+- **通知通道**:Agent Mail 历轮 `not_bound`(静默不触发)→ 以 blockers.md + `notice-2026-11-13-R190-研发通知.md` + 推送落地。
+
+---
+
+## 八、待办
+
+1. **运维(P0)**:恢复 Gogs SSH 22(B-189-1);**更换/恢复 251 上游 AgnesAI API key(****ab12 失效,B-142-2)**。
+2. **研发(P1)**:49 前瞻契约 RED(S-cfc-183/184/186/188/196 + MindRecord/AppointmentGuard 等 11 类)逐键实现使绿——**含 S-cfc-186 `getFamilyMemberTasks` 补 memberId∈familyId 属主校验(防跨家庭 IDOR)**;S-cfc-176 幂等;迁移 DDL(B-156-1/B-170-1);B-177-1 `aclose()`;**S-cfc-182 已 GREEN 可直接收尾**。
+3. **CI**:精修 `BACKEND_OBSERVED_CLASSES`(漏拦 6 + 陈旧 26 + 接入 S-cfc-186/182)。
+4. **测试**:B-95 观察改善(连续 2 轮 6/6 后销号);下轮关注 49 RED 的研发实现进展与回归;前端 624/624 目标(S-cfc-132/133 交付后);B-142-2 观察 2/2。
+
+---
+
+## 附录 A:本轮命令与口径(可复现)
+
+```bash
+# 浏览器(必须在 tests/ 内跑;每节点 1 个浏览器任务,本机串行)
+cd tests && npx playwright test -c playwright.config.live.js --project=admin-desktop   # 5/5(本机)
+cd tests && npx playwright test -c playwright.config.live.js --project=frontend-mobile # 6/6
+cd tests && npx playwright test -c playwright.config.live.js --project=shop-api        # 4/4
+cd tests && npx playwright test -c playwright.config.health.js                          # 13/13
+cd tests && npx playwright test -c playwright.config.api.js --output=../_r190_api \
+  e2e/api/api-smoke.spec.js e2e/api/nonfunc-security.spec.js \
+  e2e/api/nonfunc-perf-compat.spec.js e2e/api/traceability-p94-p95-c26.spec.js        # 25/7/0
+
+# 189 节点 admin(单节点任务)
+node _r190_189_admin.cjs kick && node _r190_189_admin.cjs read  # 5/5 EXIT=0
+
+# 204 节点 frontend(B-95 恢复;openCode 在 204:4091,项目 D:\cfc)
+node _r190_204_run.cjs   # 前台同步模式,6/6 PASS(46.1s)
+
+# 251 节点 langgraph pytest
+LOG=/tmp/r190_pytest.log node _r190_251_lg.cjs kick && node _r190_251_lg.cjs read  # 50/51(上游 401)
+
+# 窗口 2 契约类定向(S-cfc-186 纯 Mockito 7 例 + S-cfc-182 14 例)
+cd cfc-backend && JAVA_HOME=/d/jdk1.8.0_25 /d/maven/apache-maven-3.6.1/bin/mvn -o test -Dtest=TeacherFamilyOverviewContractTest -DfailIfNoTests=false   # 6过/1预期RED
+cd cfc-backend && JAVA_HOME=/d/jdk1.8.0_25 /d/maven/apache-maven-3.6.1/bin/mvn -o test -Dtest=TeacherReportProxyContractTest -DfailIfNoTests=false    # 14/14 GREEN
+
+# Jest
+cd cfc-frontend && npx jest --ci   # 609/3/12
+cd cfc-web && npx jest --ci        # 116/116
+cd tests && npx jest --silent      # 7/16(B-36)
+```
+
+## 附录 B:窗口 2 契约类定向实测明细(B-190-2 补验)
+
+| 类 | 提交 | 例数 | 过/红 | 预期 |
+|----|------|------|-------|------|
+| TeacherFamilyOverviewContractTest(S-cfc-186,SC-T-16/17/21/27) | e6b154a73→0e6f285da(12:25/12:28,并行 E2E Test Bot) | 7 | 6/1 | RED 1/7 ✅(跨家庭 IDOR:`getFamilyMemberTasks` 仅校验 `requireBound(guideId, familyId)` 未校验 `memberId∈familyId`,教师绑家庭 A 可读家庭 B 成员任务);6 个控制用例全过 |
+| TeacherReportProxyContractTest(S-cfc-182,teacher.report.proxy) | 5d67a62f6(12:16 merge c6f775ab2,Sisyphus Agent) | 14 | **14/0** | **GREEN 14/14 ✅(实现已落地,可直接收尾)** |

+ 49 - 0
docs/tdd/test/automation-run-2026-11-13-R190.md

@@ -0,0 +1,49 @@
+# R190 轮自动化测试执行日志(2026-11-13 11:45~12:35)
+
+> 测试负责人|自动化定时任务触发|静默无人值守|基线 `2313791a8`(R189)→ 收尾 HEAD `0e6f285da`
+
+## 一、基线与环境
+
+- 基线:R189 收口 `2313791a8`(auto-bump);当前 HEAD `0e6f285da`(12:28 并发 rebase 后:含 S-cfc-186 契约类 + S-cfc-182 merge + 2 份 docs)。
+- 窗口 `git diff 2313791a8..0e6f285da`:**src/specs/用例/接口/场景零变更**;唯一变更 = 2 个契约测试类(`TeacherFamilyOverviewContractTest` S-cfc-186 +249 / `TeacherReportProxyContractTest` S-cfc-182)+ `report-dev-2026-11-13-1210.md` + `sc-key-map.md`(docs)。
+- 节点探活:本机 4091=200;189:4090=200;**204:4091=200(B-95 修正:openCode 服务在 4091 而非 4090,项目 D:\cfc)**;251:4096=200;251:9000 ok;**git SSH 22 CLOSED(B-189-1 延续)**;9082=000(B-36 承袭)。
+
+## 二、本轮实测明细(全部本轮执行)
+
+| # | 套件 | 节点 | 结果 | 耗时 | 关键点 |
+|---|------|------|------|------|--------|
+| 1 | admin-desktop E2E | 本机 | **5/5** | 1.4m | TC-A-U01~U05 全过 |
+| 2 | frontend-mobile E2E | 本机 | **6/6** | 46.2s | B-185 维持消除 |
+| 3 | shop-api E2E | 本机 | **4/4** | 6.9s | 价格排序契约 |
+| 4 | health 鉴权契约 | 本机 | **13/13** | 4.2s | TC-HP-U01~03 全 401(B-61 维持) |
+| 5 | admin-desktop E2E | 189:4090 | **5/5 EXIT=0** | 1.3m | 跨节点可比(spec 同源) |
+| 6 | frontend-mobile E2E | **204:4091** | **6/6 PASS** | 46.1s | **B-95 观察改善:204 节点恢复**(openCode 在 4091,项目 D:\cfc) |
+| 7 | langgraph pytest | 251:4096 | **50/51** | 269.16s | 唯一红 `test_auto_tag_valid_format`=上游 401(key ****ab12 invalid,B-142-2 复发环境型) |
+| 8 | dx-bridge | 本机 | **2 skip** | 瞬时 | 端点 404(B-DX-1,本轮承袭未重跑) |
+| 9 | 线上 API 32 例 | 本机 | **25 过/7 跳/0 红** | 28s | api-smoke + nonfunc-security + perf-compat + traceability |
+| 10 | cfc-frontend Jest | 本机 | **609/3/12** | 172s | 3 红 = S-cfc-132/133 预期 RED |
+| 11 | cfc-web Jest | 本机 | **116/116** | 209s | 全绿 |
+| 12 | 根级黑盒 Jest | 本机 | **7/16** | 9.8s | B-36 第 74 轮(9082 未起) |
+| 13 | 窗口 S-cfc-186 定向 | 本机 mvn | **7 例 = 6 过/1 预期 RED/0 错** | 1m17s | 1 RED=跨家庭 IDOR(getFamilyMemberTasks 未校验 memberId∈familyId);6 控制用例全过 |
+| 14 | 窗口 S-cfc-182 定向 | 本机 mvn | **14/14 GREEN(BUILD SUCCESS)** | 7.9s | teacher.report.proxy 能力已实现落地 |
+
+后端全量:**采信 R189**(388 类 / 3244 例 / 3171 过 / 73 红 / 0 错 / 0 跳 = 97.75%),窗口 main 零变更。
+
+## 三、全站口径
+
+- 合计 **4141 例** = 后端 3265(3244采信 + 21 窗口契约实测)+ fe 624 + web 116 + lg 51 + 浏览器 30(唯一28 + dx 2 跳)+ API 32 + 根级 23
+- **4026 过 / 94 红 / 21 跳 = 97.22%(剔 skip 97.72%)**
+- 红 94 = 后端存量 25 + 契约预期 RED 49(R189 48 + S-cfc-186 1)+ fe 预期 RED 3 + 根级 16(环境)+ langgraph 1(上游 401 环境型)
+- 环比 R189(4120/4003/92红/97.16%):例 +21(窗口 2 契约类)、过 +23、红 +2(**S-cfc-186 契约预期 RED +1 + langgraph 401 环境红 +1,零缺陷回归**)
+
+## 四、处置与结论
+
+- **B-190-1 新增**:B-142-2 复发——langgraph `test_auto_tag_valid_format` 标签数 0,日志 `401 Authentication Fails, api key ****ab12 invalid`。判别:节点 HEAD=基线 `2313791a` + 窗口源码零变更 → **环境型,非代码回归**。需研发/运维更换 251 上游 AgnesAI key(****ab12)。
+- **B-190-2 新增(自处置)**:窗口 2 契约类(S-cfc-186/182,并行会话提交)补验完成:S-cfc-186 6 过 / 1 预期 RED(跨家庭 IDOR)+ **S-cfc-182 14/14 GREEN**,无意外失败。
+- **B-95 观察改善**:204 节点 openCode 服务实际在 **4091**(历轮误判 4090=000),项目 `D:\cfc`;本轮 fe 6/6 恢复 → 登记观察改善,连续 2 轮 6/6 后销号。
+- **门禁**:不通过(承袭)——G1 97.22%(+0.06pct)、G2 74 红、G7 ⚠️ 50/51(环境红)、G9/G11 承袭、G12 ✅、G6/G8/G10/G13 ✅。
+
+## 五、git 证据
+
+- 窗口新增测试资产提交:`e6b154a73`→`0e6f285da`(S-cfc-186 TeacherFamilyOverviewContractTest)、`5d67a62f6`(S-cfc-182 TeacherReportProxyContractTest,12:16 merge `c6f775ab2`);12:28 并发 rebase 后本地=远端 `0e6f285da`。
+- 本轮测试侧产物(R190 报告/执行日志/notice/blockers/台账):提交推送状态见主报告 §七(SSH 22 故障,经 HTTP 兜底)。

+ 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 | 86 | 0 | 7 | 3 | 0 |
 | Python(pytest) | 11 | 48 | 11 | 0 | 11 | 0 | 0 | 0 | 0 |
-| Java后端测试 | 388 | 3229 | 388 | 0 | 371 | 0 | 15 | 2 | 0 |
-| **合计** | — | **4567** | **558** | **667** | 903 | 255 | 36 | 5 | 26 |
+| Java后端测试 | 390 | 3250 | 390 | 0 | 373 | 0 | 15 | 2 | 0 |
+| **合计** | — | **4588** | **560** | **667** | 905 | 255 | 36 | 5 | 26 |
 
 ## 二、结构化测试用例自动化状态(`tests/test-cases/*.md`)
 
@@ -1237,11 +1237,13 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherAssessmentRecordContractTest.java` | 4 | 已自动化(@Test) | 未跟踪 | TeacherAssessmentRecordContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherDataIsolationScT13ContractTest.java` | 9 | 已自动化(@Test) | 未跟踪 | TeacherDataIsolationScT13Contract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherDimensionScoreContractTest.java` | 6 | 已自动化(@Test) | 未跟踪 | TeacherDimensionScoreContract |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherFamilyOverviewContractTest.java` | 7 | 已自动化(@Test) | 未跟踪 | TeacherFamilyOverviewContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherLoginSwitchContractTest.java` | 16 | 已自动化(@Test) | 未跟踪 | TeacherLoginSwitchContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherMessagePushContractTest.java` | 20 | 已自动化(@Test) | 未跟踪 | TeacherMessagePushContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherMindRecordContractTest.java` | 13 | 已自动化(@Test) | 未跟踪 | TeacherMindRecordContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherPlanActivateContractTest.java` | 15 | 已自动化(@Test) | 未跟踪 | TeacherPlanActivateContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherPlanCreateContractTest.java` | 13 | 已自动化(@Test) | 未跟踪 | TeacherPlanCreateContract |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherReportProxyContractTest.java` | 14 | 已自动化(@Test) | 未跟踪 | TeacherReportProxyContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitAdminManageContractTest.java` | 20 | 已自动化(@Test) | 未跟踪 | TeamProfitAdminManageContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitCronContractTest.java` | 22 | 已自动化(@Test) | 未跟踪 | TeamProfitCronContract |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitHookContractTest.java` | 7 | 已自动化(@Test) | 未跟踪 | TeamProfitHookContract |

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

@@ -1344,3 +1344,24 @@
 | **B-178-1(第 8 轮)** | TaskReviewScP11 反射装置浮动 | 测试(P2) | **延续 2F** → `@MockBean` 替代 `ReflectionUtils`。 | 测试 | 2026-11-13 11:30 | 待处理 |
 | **B-142-1(销号维持第 19 轮)** | 匿名端点鉴权 | 研发(已闭环) | **维持销号**。health 三端点(plan/adjust、attribution、generate)全 **401**;API 安全套件 11 例全绿。 | 测试(R189 实测) | 2026-11-13 11:30 | 已闭(观察维持) |
 | **R189 门禁** | 全量 4120 / **4003** | 测试 | **不通过(承袭,无回归)**。✅G4 编译 0 错/G5 定向 133 surefire XML 完整/G6 28 过+2 跳/G7 **51/51(连续 2 轮,B-142-2 销号)**/G8 401 全绿/G10 双节点/G12 SRS 零变更/G13 存量零漂移第 24 次;⚠️G3 609-624(3 预期 RED);❌G1 **97.16%**(剔 skip 97.75%,−1.11pct **全因 48 契约预期 RED 入池**)/G2 **73 红**(存量 25 + 契约预期 RED 48)/G9 20.1%/G11 漏拦 6 陈旧 26。**变化** = 例 +133(窗口 13 契约类)、过 +85、红 +48(**全为预期 RED,零缺陷回归**);langgraph 连续 2 轮全绿 **B-142-2 销号**;浏览器六件套全绿、API 0 红、fe/web 零漂移。 | 测试(R189 闭环) | 2026-11-13 11:30 | 已记录 |
+
+---
+
+## R190 段(2026-11-13 12:35,新增)
+
+| **B-190-1(P1 新增·环境= B-142-2 复发)** | langgraph 上游 401 `key ****ab12 invalid` | 运维/研发(P1,最紧急) | **复发 1 红**。langgraph@251 `test_auto_tag_valid_format` 标签数 0(空 answer);日志实证 `Error code: 401 - Authentication Fails, Your api key: ****ab12 is invalid`。判别:节点 HEAD=基线 `2313791a` + 窗口源码零变更 → **环境型,非代码回归**。B-142-2 由「销号」转「**复发观察 1/2**」:**请更换/恢复 251 上游 AgnesAI API key(****ab12)**,恢复后连续 2 轮 51/51 再销号。 | 测试(R190 实测) | 2026-11-13 12:35 | 观察 1/2(等 key 恢复) |
+| **B-190-2(P2 新增·自处置)** | 窗口 2 契约类未逐类验证即并行推入 | 测试(流程) | **补验完成**。窗口并行会话推入 2 个契约类:`TeacherFamilyOverviewContractTest`(S-cfc-186,e6b154a73→0e6f285da,SC-T-16/17/21/27,纯 Mockito 7 例)+ `TeacherReportProxyContractTest`(S-cfc-182,5d67a62f6/12:16 merge,14 例)。本轮定向实测 **21 例 = S-cfc-186 6 过 / 1 预期 RED / 0 错(1m17s)**:1 RED = **跨家庭 IDOR**(`GuideFamilyTaskController.getFamilyMemberTasks` 仅校验 `requireBound(guideId, familyId)` 未校验 `memberId∈familyId`),6 控制用例全过;**S-cfc-182 14/14 GREEN(7.9s)** → 完全符合 TDD 预期。**流程修正**(延续 B-189-2):窗口新增测试类必须逐类定向取证再入账。 | 测试(R190 实测) | 2026-11-13 12:35 | 已处置(补验闭环) |
+| **S-cfc-182(GREEN 本轮取证)** | teacher.report.proxy 契约 | 研发(可直接收尾) | **14/14 GREEN(BUILD SUCCESS,7.9s)** → 契约侧已闭环,可直接收 YELLOW/GREEN。 | 测试(R190 定向实测) | 2026-11-13 12:35 | 已取证(待研发登记) |
+| **B-95(第 45 轮→观察改善)** | `192.168.16.204` 节点失联 | 运维(P2) | **观察改善**。历轮 `204:4090=000` 为**误判**:openCode 服务实际在 **204:4091**(项目 `D:\cfc`)→ 本轮 frontend-mobile **6/6 PASS(46.1s)**。登记「观察改善」,连续 2 轮 6/6 可复现后销号。 | 测试(R190 实测) | 2026-11-13 12:35 | 观察改善(1/2) |
+| **B-189-1(P1 延续·环境)** | git SSH 22 CLOSED | 运维(环境) | **延续(HTTP 兜底已推送)**。`git.iwintrue.com` / `192.168.16.251:22` 仍 CLOSED;本轮 push URL 切 `http://git.iwintrue.com/liaoxg/cfc.git` 后 rebase+push 成功(远端 HEAD=本轮 R190 产物 sha)。**SSH 通道仍待运维检查 Gogs/251 sshd 服务(端口 22)**。 | 测试(R190 实测) | 2026-11-13 12:35 | HTTP 兜底已推送,SSH 待修 |
+| **S-cfc-186(1 前瞻 RED,本轮取证)** | teacher.family.overview 跨家庭 IDOR | 研发(P1) | **预期 RED**(TDD 先行、研发未实现):`getFamilyMemberTasks` 需补 `memberId∈familyId` 属主校验(拒绝跨家庭访问,不得进入 `taskService.getTaskHistoryByFamilyMember`);6 控制用例已全过。逐键清单见 `notice-2026-11-13-R190-研发通知.md` §一 P2。 | 测试(R190 定向实测) | 2026-11-13 12:35 | 待处理(研发实现使绿) |
+| **B-186-1(第 4 轮观察)** | langgraph live `/api/v1/chat` 挂死 | 运维/研发(P1) | **延续**。pytest 50/51(401 环境红)但 live chat 链路仍挂(120s 零字节);与 B-142-2 同根因(上游 key 失效)。 | 运维/研发 | 2026-11-13 12:35 | 待处理 |
+| **B-177-1(第 12 轮)** | 251 pytest 打印 summary 后进程不退出 | 研发/测试(P1) | **观察维持**。本轮 269.16s 正常收口输出 summary,`EXIT=` 行仍缺失(B-126 表象,以 summary 终值为准);残留进程已前置清理。修法不变:`app/main.py:84` lifespan + `aclose()`;派发器 `timeout -k 10 900`。 | 研发/测试 | 2026-11-13 12:35 | 待处理 |
+| **B-36(第 74 轮零漂移)** | 根级黑盒 23 例 16 红 | 测试(P2 环境) | **零漂移**。`cd tests && npx jest --silent` → **7 过 / 16 红**(9.8s),全 `ECONNREFUSED 9082`。 | 测试 | 2026-11-13 12:35 | 待处理 |
+| **B-DX-1(第 32 轮)** | dx-bridge 端点 404 | 部署/研发(P1) | **承袭**(本轮未重跑,R189 2 skip 维持)。 | 部署/研发 | 2026-11-13 12:35 | 待处理 |
+| **B-152-1/2(第 21 轮)** | CI `BACKEND_OBSERVED_CLASSES` 失真 | 研发/CI(P0/P1) | **延续**。漏拦 6 + 陈旧 26 未修;本轮建议同步接入 S-cfc-186/182 新契约类。 | 研发/CI | 2026-11-13 12:35 | 待处理 |
+| **B-156-1 / B-170-1(第 14/11 轮)** | 迁移 DDL 缺陷 | 研发(P1/P2) | **延续未修**。`schema.sql:5345` 索引列缺失 / `DatabaseInitializer.java:2261` 别名 UPDATE 派生表引用。 | 研发 | 2026-11-13 12:35 | 待处理 |
+| **B-162-1(第 16 轮)** | 3 个测试类未入库 | 治理(P1) | **延续**。`GrowthPublicEndpointMappingTest`(5E)等仍 `??`。 | 研发/测试 | 2026-11-13 12:35 | 待处理 |
+| **B-178-1(第 9 轮)** | TaskReviewScP11 反射装置浮动 | 测试(P2) | **延续 2F** → `@MockBean` 替代 `ReflectionUtils`。 | 测试 | 2026-11-13 12:35 | 待处理 |
+| **B-142-1(销号维持第 20 轮)** | 匿名端点鉴权 | 研发(已闭环) | **维持销号**。health 三端点全 **401**;API 安全套件 11 例全绿。 | 测试(R190 实测) | 2026-11-13 12:35 | 已闭(观察维持) |
+| **R190 门禁** | 全量 4141 / **4026** | 测试 | **不通过(承袭,无回归,正向项明确)**。✅G4 编译 0 错(含 S-cfc-186/182 test-compile)/G5 定向 21 surefire XML 完整/G6 **28 过+2 跳承袭**(admin 5/5 本机+189、fe 6/6 本机+**204**、shop 4/4、health 13/13)/G8 401 全绿/G10 **三节点**(189 + **204 恢复** + 251)/G12 SRS 零变更/G13 存量零漂移第 25 次;⚠️G3 609-624(3 预期 RED)、G7 **50/51(B-142-2 复发环境型)**;❌G1 **97.22%**(剔 skip 97.72%,+0.06pct)/G2 **74 红**(存量 25 + 契约预期 RED 49)/G9 20.1%/G11 漏拦 6 陈旧 26。**变化** = 例 +21(窗口 2 契约类 S-cfc-186 7 + S-cfc-182 14)、过 +23、红 +2(**S-cfc-186 预期 RED +1 + langgraph 401 环境红 +1,零缺陷回归**);**204 节点 fe 6/6 恢复(B-95 观察改善)**;浏览器任务级全绿、API 0 红、fe/web 零漂移;**S-cfc-182 已 GREEN**。 | 测试(R190 闭环) | 2026-11-13 12:35 | 已记录 |

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

@@ -11,9 +11,9 @@
 | 结构化测试用例(md) | 10 | 719 |
 | Playwright(spec.js) | 96 | 571 |
 | Python(pytest) | 11 | 48 |
-| Java后端(测试文件) | 388 | 3229 (@Test) |
+| Java后端(测试文件) | 390 | 3250 (@Test) |
 | 用户场景(md) | 11 | 文件级 |
-| **合计** | — | **4567** 用例/方法 |
+| **合计** | — | **4588** 用例/方法 |
 
 ## 二、结构化测试用例(`tests/test-cases/*.md`)
 
@@ -1232,11 +1232,13 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherAssessmentRecordContractTest.java` | cfc-backend | 4 | TeacherAssessmentRecordContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherAssessmentRecordContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherDataIsolationScT13ContractTest.java` | cfc-backend | 9 | TeacherDataIsolationScT13Contract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherDataIsolationScT13ContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherDimensionScoreContractTest.java` | cfc-backend | 6 | TeacherDimensionScoreContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherDimensionScoreContractTest.java` |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherFamilyOverviewContractTest.java` | cfc-backend | 7 | TeacherFamilyOverviewContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherFamilyOverviewContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherLoginSwitchContractTest.java` | cfc-backend | 16 | TeacherLoginSwitchContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherLoginSwitchContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherMessagePushContractTest.java` | cfc-backend | 20 | TeacherMessagePushContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherMessagePushContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherMindRecordContractTest.java` | cfc-backend | 13 | TeacherMindRecordContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherMindRecordContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherPlanActivateContractTest.java` | cfc-backend | 15 | TeacherPlanActivateContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherPlanActivateContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherPlanCreateContractTest.java` | cfc-backend | 13 | TeacherPlanCreateContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherPlanCreateContractTest.java` |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherReportProxyContractTest.java` | cfc-backend | 14 | TeacherReportProxyContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeacherReportProxyContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitAdminManageContractTest.java` | cfc-backend | 20 | TeamProfitAdminManageContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitAdminManageContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitCronContractTest.java` | cfc-backend | 22 | TeamProfitCronContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitCronContractTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitHookContractTest.java` | cfc-backend | 7 | TeamProfitHookContract | `cfc-backend/src/test/java/com/etotem/cfc/unit/TeamProfitHookContractTest.java` |