Procházet zdrojové kódy

feat(ui): 登录页品牌区重构 + TDD 台账更新

前端(cfc-frontend/components/login-sheet.vue):
- 登录页品牌区重构:brand-section(logo + 应用名 + 身份描述 + 标语)
- 移除轨道动画,改用 $brand-primary 令牌,五维标签调整

docs/tdd 台账(automation-status / discovery / inventory / test_blockers):
- 更新 TDD 巡检与发现记录

(注:INTERFACE_TEST_REPORT.md、playwright_smoke.log 本地为旧版,
 远端已有更新版本,本提交不包含,已恢复为远端内容)
Agnes Agent před 1 týdnem
rodič
revize
bb4040057b

+ 78 - 154
cfc-frontend/components/login-sheet.vue

@@ -6,17 +6,19 @@
       </view>
       <scroll-view scroll-y class="login-sheet-scroll" :show-scrollbar="false">
         <view class="login-sheet-content">
-          <!-- 品牌区(左上角锁定版式,与首页一致) -->
-          <view class="brand-bar">
-            <image class="brand-logo" src="/static/logo.png" mode="aspectFit" @error="handleImageError"></image>
-            <view class="brand-texts">
-              <text class="brand-name">浠艾福</text>
-              <text class="brand-tagline">您的专属家庭主动健康陪跑</text>
-            </view>
+          <!-- 品牌区 -->
+          <view class="brand-section">
+            <image class="logo" src="/static/logo.png" mode="aspectFit" @error="handleImageError"></image>
+            <text class="app-name">浠艾福</text>
+            <text class="identity">您的专属家庭主动健康管理师</text>
+            <text class="slogan">家里每个人的状态,你真的看见了?</text>
           </view>
 
           <!-- 理念卡 -->
           <view class="concept-card">
+            <view class="concept-desc">
+              不等问题发生,先一步<text class="concept-highlight">识别风险 · 主动干预 · 持续评估</text>,把全家健康管理融入每一天。
+            </view>
             <view class="loop-row">
               <view class="loop-pill loop-pill-indigo"><text>🔍</text><text class="loop-pill-text">提前识别</text></view>
               <text class="loop-arrow">→</text>
@@ -28,6 +30,15 @@
             </view>
           </view>
 
+          <!-- 五维标签 -->
+          <view class="dims-row">
+            <view class="dim-tag dim-tag-body"><text>🌏</text><text>身·健康</text></view>
+            <view class="dim-tag dim-tag-wisdom"><text>⚡</text><text>智·认知</text></view>
+            <view class="dim-tag dim-tag-wealth"><text>💧</text><text>富·创富</text></view>
+            <view class="dim-tag dim-tag-action"><text>🌿</text><text>行·和谐</text></view>
+            <view class="dim-tag dim-tag-mind"><text>🔥</text><text>心·大爱</text></view>
+          </view>
+
           <!-- 登录表单 -->
           <view class="login-form">
             <view class="phone-section">
@@ -40,8 +51,7 @@
                 :disabled="!agreed || loading || tapLock"
               >
                 <text class="phone-btn-icon">📱</text>
-                <text class="phone-btn-text">手机号快捷登录</text>
-                <text class="phone-arrows">›››</text>
+                <text>手机号快捷登录</text>
               </button>
             </view>
 
@@ -61,17 +71,6 @@
               <view class="skip-btn" @click="handleSkipLogin">暂不登录,先逛逛</view>
             </view>
           </view>
-
-          <!-- 五维能量轮盘(参照 Web 后台登录页动画风格) -->
-          <view class="dim-orbit">
-            <view class="orbit-ring"></view>
-            <view class="orbit-center">家</view>
-            <view class="orbit-node node-0"><text class="orbit-node-char">身</text></view>
-            <view class="orbit-node node-1"><text class="orbit-node-char">智</text></view>
-            <view class="orbit-node node-2"><text class="orbit-node-char">富</text></view>
-            <view class="orbit-node node-3"><text class="orbit-node-char">行</text></view>
-            <view class="orbit-node node-4"><text class="orbit-node-char">心</text></view>
-          </view>
         </view>
       </scroll-view>
     </view>
@@ -295,46 +294,34 @@ export default {
   box-sizing: border-box;
 }
 
-/* ===== 品牌区(左上角锁定版式,与首页一致) ===== */
-.brand-bar {
+/* ===== 品牌区 ===== */
+.brand-section {
   display: flex;
+  flex-direction: column;
   align-items: center;
-  gap: 20rpx;
-  padding: 4rpx 0;
-  box-sizing: border-box;
-}
-.brand-logo {
-  width: 80rpx;
-  height: 80rpx;
-  border-radius: 20rpx;
-  background: $app-surface;
-  box-shadow: 0 6rpx 16rpx rgba($brand-primary, 0.18);
-  flex-shrink: 0;
+  padding: 24rpx 0 8rpx;
 }
-.brand-texts {
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  min-width: 0;
-  padding-left: 20rpx;
-  border-left: 2rpx solid rgba($brand-primary, 0.28);
+.logo {
+  width: 128rpx;
+  height: 128rpx;
+  border-radius: 24rpx;
 }
-.brand-name {
-  font-size: calc(38rpx * var(--font-scale, 1));
+.app-name {
+  font-size: calc(44rpx * var(--font-scale, 1));
   font-weight: bold;
   color: $facade-text-strong;
-  letter-spacing: 3rpx;
-  line-height: 1.2;
+  margin-top: 16rpx;
 }
-.brand-tagline {
-  display: block;
-  font-size: calc(22rpx * var(--font-scale, 1));
-  font-weight: 500;
-  color: $brand-primary-deep;
-  margin-top: 6rpx;
-  letter-spacing: 1rpx;
-  line-height: 1.2;
-  white-space: nowrap;
+.identity {
+  font-size: calc(26rpx * var(--font-scale, 1));
+  color: $brand-primary;
+  margin-top: 8rpx;
+}
+.slogan {
+  font-size: calc(24rpx * var(--font-scale, 1));
+  color: $facade-text-muted;
+  margin-top: 12rpx;
+  text-align: center;
 }
 
 /* ===== 理念卡 ===== */
@@ -344,6 +331,15 @@ export default {
   padding: 24rpx;
   margin-top: 28rpx;
 }
+.concept-desc {
+  font-size: calc(26rpx * var(--font-scale, 1));
+  color: $facade-text-deep;
+  line-height: 1.6;
+}
+.concept-highlight {
+  color: $brand-primary;
+  font-weight: 600;
+}
 .loop-row {
   display: flex;
   flex-direction: row;
@@ -378,90 +374,33 @@ export default {
   flex-shrink: 0;  /* 箭头不被压缩 */
 }
 
-/* ===== 五维能量轮盘(参照 Web 后台登录页动画风格) ===== */
-.dim-orbit {
-  position: relative;
-  width: 340rpx;
-  height: 340rpx;
-  margin: 48rpx auto 8rpx;
-}
-/* 轨道环:缓慢旋转,呼应 Web 端虚线轨道 */
-.orbit-ring {
-  position: absolute;
-  left: 50%; top: 50%;
-  width: 240rpx; height: 240rpx;
-  margin-left: -120rpx; margin-top: -120rpx;
-  border: 2rpx dashed rgba(194, 112, 61, 0.35);
-  border-radius: 50%;
+/* ===== 五维标签 ===== */
+.dims-row {
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+  flex-wrap: nowrap;  /* 禁止换行,保持五维维度在一行 */
+  margin-top: 24rpx;
+  padding: 0 32rpx;  /* 左右留白,避免贴边 */
   box-sizing: border-box;
-  animation: orbitRingSpin 24s linear infinite;
-}
-@keyframes orbitRingSpin {
-  0%   { transform: rotate(0deg); }
-  100% { transform: rotate(360deg); }
-}
-/* 中心"家"徽章:金色脉冲,呼应 Web 端中心节点 */
-.orbit-center {
-  position: absolute;
-  left: 50%; top: 50%;
-  width: 84rpx; height: 84rpx;
-  margin-left: -42rpx; margin-top: -42rpx;
-  border-radius: 50%;
-  background: #F59E0B;
-  display: flex; align-items: center; justify-content: center;
-  color: #fff; font-size: calc(36rpx * var(--font-scale, 1)); font-weight: 700;
-  box-shadow: 0 0 20rpx rgba(245, 158, 11, 0.4);
-  animation: orbitCenterPulse 3s ease-in-out infinite;
-  z-index: 3;
-}
-@keyframes orbitCenterPulse {
-  0%, 100% { box-shadow: 0 0 20rpx rgba(245, 158, 11, 0.4); transform: scale(1); }
-  50%      { box-shadow: 0 0 36rpx rgba(245, 158, 11, 0.6); transform: scale(1.06); }
-}
-/* 五维公转节点:绕中心旋转,文字保持正立 */
-.orbit-node {
-  position: absolute;
-  left: 50%; top: 50%;
-  width: 76rpx; height: 76rpx;
-  margin-left: -38rpx; margin-top: -38rpx;
-  border-radius: 50%;
-  background: var(--node-color);
-  display: flex; align-items: center; justify-content: center;
-  color: #fff; font-size: calc(30rpx * var(--font-scale, 1)); font-weight: 700;
-  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
-  z-index: 2;
-  animation-duration: 15s;
-  animation-timing-function: linear;
-  animation-iteration-count: infinite;
-}
-.orbit-node-char { line-height: 1; }
-/* 五节点:颜色 + 起始角度 + 错峰延迟,与 Web 端一致 */
-.node-0 { --node-color: #FF8C42; animation-name: orbitNode0; animation-delay: 0s; }    /* 身 */
-.node-1 { --node-color: #1677FF; animation-name: orbitNode1; animation-delay: -3s; }   /* 智 */
-.node-2 { --node-color: #F59E0B; animation-name: orbitNode2; animation-delay: -6s; }   /* 富 */
-.node-3 { --node-color: #10B981; animation-name: orbitNode3; animation-delay: -9s; }   /* 行 */
-.node-4 { --node-color: #FF6B9D; animation-name: orbitNode4; animation-delay: -12s; }  /* 心 */
-
-@keyframes orbitNode0 {
-  0%   { transform: rotate(0deg)   translateX(120rpx) rotate(0deg); }
-  100% { transform: rotate(360deg) translateX(120rpx) rotate(-360deg); }
-}
-@keyframes orbitNode1 {
-  0%   { transform: rotate(72deg)   translateX(120rpx) rotate(-72deg); }
-  100% { transform: rotate(432deg)  translateX(120rpx) rotate(-432deg); }
-}
-@keyframes orbitNode2 {
-  0%   { transform: rotate(144deg)  translateX(120rpx) rotate(-144deg); }
-  100% { transform: rotate(504deg)  translateX(120rpx) rotate(-504deg); }
 }
-@keyframes orbitNode3 {
-  0%   { transform: rotate(216deg)  translateX(120rpx) rotate(-216deg); }
-  100% { transform: rotate(576deg)  translateX(120rpx) rotate(-576deg); }
-}
-@keyframes orbitNode4 {
-  0%   { transform: rotate(288deg)  translateX(120rpx) rotate(-288deg); }
-  100% { transform: rotate(648deg)  translateX(120rpx) rotate(-648deg); }
+.dim-tag {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  border-radius: 999rpx;
+  padding: 8rpx 14rpx;
+  font-size: calc(22rpx * var(--font-scale, 1));
+  color: $app-surface;
+  margin: 0 8rpx;  /* 使用 margin 替代 gap,微信小程序不支持 gap */
+  white-space: nowrap;
 }
+.dim-tag-body { background: $status-success; }
+.dim-tag-wisdom { background: $dim-wisdom; }
+.dim-tag-wealth { background: $dim-wealth; }
+.dim-tag-action { background: #14b8a6; }
+.dim-tag-mind { background: $status-danger; }
 
 /* ===== 登录表单 ===== */
 .login-form {
@@ -469,10 +408,10 @@ export default {
 }
 .phone-btn {
   width: 100%;
-  height: 82rpx;
+  height: 96rpx;
   border-radius: 24rpx;
-  background: linear-gradient(135deg, #FFC24A 0%, #FFA726 100%);
-  color: #14458F;
+  background: linear-gradient(135deg, $brand-primary, $brand-primary-light);
+  color: $app-surface;
   font-size: calc(32rpx * var(--font-scale, 1));
   font-weight: 600;
   display: flex;
@@ -480,32 +419,17 @@ export default {
   align-items: center;
   justify-content: center;
   border: none;
-  box-shadow: 0 8rpx 20rpx rgba(255, 167, 38, 0.32);
 }
 .phone-btn::after {
   border: none;
 }
 .phone-btn[disabled] {
-  background: #FFEFD0 !important;
-  color: #B57E2A !important;
+  background: #e0d8cc !important;
+  color: $text-ghost-soft !important;
 }
 .phone-btn-icon {
   margin-right: 8rpx;
 }
-.phone-btn-text {
-  color: #000000;
-}
-.phone-arrows {
-  margin-left: 10rpx;
-  font-weight: bold;
-  letter-spacing: 2rpx;
-  color: #000000;
-  animation: arrowBlink 1s ease-in-out infinite;
-}
-@keyframes arrowBlink {
-  0%, 100% { opacity: 1; }
-  50% { opacity: 0.15; }
-}
 
 /* ===== 暂不登录 ===== */
 .skip-section {

+ 216 - 276
docs/tdd/test/automation-status.md

@@ -19,12 +19,12 @@
 
 | 来源类型 | 文件数 | 用例/方法数 | 已自动化 | 待自动化 | 未跟踪 | 已执行 | 通过 | 失败 | 阻塞 |
 | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
-| 结构化测试用例(md) | 9 | 729 | 0 | 729 | 729 | 0 | 0 | 0 | 0 |
-| 用户场景(md) | 9 | 0 | 0 | 9 | 9 | 0 | 0 | 0 | 0 |
-| Playwright(e2e/integration) | 70 | 410 | 70 | 0 | 60 | 0 | 7 | 3 | 0 |
+| 结构化测试用例(md) | 9 | 678 | 0 | 678 | 678 | 0 | 0 | 0 | 0 |
+| 用户场景(md) | 8 | 0 | 0 | 8 | 8 | 0 | 0 | 0 | 0 |
+| Playwright(e2e/integration) | 70 | 410 | 70 | 0 | 67 | 0 | 1 | 2 | 0 |
 | Python(pytest) | 11 | 47 | 11 | 0 | 11 | 0 | 0 | 0 | 0 |
-| Java后端测试 | 195 | 1451 | 195 | 0 | 178 | 0 | 15 | 2 | 0 |
-| **合计** | — | **2637** | **276** | **738** | 987 | 0 | 22 | 5 | 0 |
+| Java后端测试 | 187 | 1395 | 187 | 0 | 187 | 0 | 0 | 0 | 0 |
+| **合计** | — | **2530** | **268** | **686** | 951 | 0 | 1 | 2 | 0 |
 
 ## 二、结构化测试用例自动化状态(`tests/test-cases/*.md`)
 
@@ -53,29 +53,29 @@
 | `tests/test-cases/admin.md#TC-A-21` | 网关/限流 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:接口防护;边界:误杀白名单|e2e:网关/限流 |
 | `tests/test-cases/admin.md#TC-A-22` | 模型管理 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:模型版本/开关;边界:下线前回退方案|e2e:模型管理 |
 | `tests/test-cases/admin.md#TC-A-23` | 知识库 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:维护营养知识;边界:同步失败重试|e2e:知识库 |
-| `tests/test-cases/admin.md#TC-A-01-E` | 认证 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:错误密码不签发 token 且提示次数限制/锁定;过期 token 401 跳登录;弱密码 400 拦截|e2e:AdminAuthController |
-| `tests/test-cases/admin.md#TC-A-02-E` | 统计 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时降级提示非500;无数据显示『暂无数据』;时间非法 400|e2e:StatsController |
-| `tests/test-cases/admin.md#TC-A-03-E` | 方案管理 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时降级非500;非法筛选 400;仅返回有权家庭数据不串|e2e:方案管理(全量) |
-| `tests/test-cases/admin.md#TC-A-04-E` | 方案激活 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非 reviewed 激活拦截;超时回滚不残半任务;并发幂等仅生成 1 次任务|e2e:方案激活 |
-| `tests/test-cases/admin.md#TC-A-05-E` | 报告解析 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时降级非500;重复 typeId 400 拒绝;路径非法 400|e2e:AdminReportParserController |
-| `tests/test-cases/admin.md#TC-A-06-E` | 报告解析 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复 typeId 拒绝;必填缺失 400;threshold 非法 400|e2e:报告类型注册 |
-| `tests/test-cases/admin.md#TC-A-07-E` | 报告解析 | 运营 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:超时降级非500;重名类型生成被拒/提示已存在|e2e:未知聚类自学习 |
-| `tests/test-cases/admin.md#TC-A-08-E` | 文章 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:同标题 400『标题已存在』;长文提交超时重试不丢稿;注入 400 或转义|e2e:文章发布-审核 |
-| `tests/test-cases/admin.md#TC-A-09-E` | 文章·去重 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复创建被拦截提示标题已存在;空/超长 400|e2e:文章标题去重 |
-| `tests/test-cases/admin.md#TC-A-10-E` | 关系类型 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重名拒绝;停用被引用类型提示先解绑;注入 400/转义;家长端选择器同步生效仍正确|e2e:关系类型 CRUD |
-| `tests/test-cases/admin.md#TC-A-11-E` | 勋章 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复 400/幂等;非法门槛 400;并发创建各自独立不串|e2e:勋章管理;黑盒回归 |
-| `tests/test-cases/admin.md#TC-A-12-E` | 供应商 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:同手机号拒绝/可控覆盖;非法格式 400;必填缺失 400;列表 name=昵称正确|e2e:供应商管理;黑盒回归 |
-| `tests/test-cases/admin.md#TC-A-13-E` | 活动 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:已发布再提交审核守卫拦截;非本人撤回 403;时间冲突 400;撤回退回草稿|e2e:活动审核撤回;黑盒回归 |
-| `tests/test-cases/admin.md#TC-A-14-E` | 知识库 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:被引用删除提示先解绑;不存在 404;并发删除幂等|e2e:知识库管理;黑盒回归 |
-| `tests/test-cases/admin.md#TC-A-15-E` | 数据迁移 | 运营 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:中断回滚+明确错误非500;锁等待超时提示;重复执行幂等/提示已迁移|e2e:多数据源/SfmsDataSourceConfig |
-| `tests/test-cases/admin.md#TC-A-16-E` | 参数校验 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:空 body 400 含具体字段提示;类型错配 400;超长 400;不再裸 500|e2e:统一 `Result<T>`+全局异常;黑盒回归 |
-| `tests/test-cases/admin.md#TC-A-17-E` | /api/admin/report-parser/* | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重名类目拒绝;未注册路径 400;先注册再解析|e2e:/api/admin/report-parser/* |
-| `tests/test-cases/admin.md#TC-A-18-E` | 优惠券/活动管理 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:时间冲突 400;名额超卖配置保护生效;重复提交幂等|e2e:优惠券/活动管理 |
-| `tests/test-cases/admin.md#TC-A-19-E` | 内容安全 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时降级非500;命中敏感词强制拦截不放行|e2e:内容安全 |
-| `tests/test-cases/admin.md#TC-A-20-E` | GDPR 工单 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:并发安全:注销与导出按序执行不冲突;越权工单 403|e2e:GDPR 工单 |
-| `tests/test-cases/admin.md#TC-A-21-E` | 网关/限流 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:白名单不被限流;非法阈值 400;规则生效可控|e2e:网关/限流 |
-| `tests/test-cases/admin.md#TC-A-22-E` | 模型管理 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:无回退方案拦截下线;非法版本 400;上下线版控正确|e2e:模型管理 |
-| `tests/test-cases/admin.md#TC-A-23-E` | 知识库 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:同步失败自动重试非500;并发 CRUD 乐观锁不互相覆盖|e2e:知识库 |
+| `tests/test-cases/admin.md#TC-A-01-E` | 认证 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:AdminAuthController |
+| `tests/test-cases/admin.md#TC-A-02-E` | 统计 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:StatsController |
+| `tests/test-cases/admin.md#TC-A-03-E` | 方案管理 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案管理(全量) |
+| `tests/test-cases/admin.md#TC-A-04-E` | 方案激活 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案激活 |
+| `tests/test-cases/admin.md#TC-A-05-E` | 报告解析 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:AdminReportParserController |
+| `tests/test-cases/admin.md#TC-A-06-E` | 报告解析 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:报告类型注册 |
+| `tests/test-cases/admin.md#TC-A-07-E` | 报告解析 | 运营 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:未知聚类自学习 |
+| `tests/test-cases/admin.md#TC-A-08-E` | 文章 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认|e2e:文章发布-审核 |
+| `tests/test-cases/admin.md#TC-A-09-E` | 文章·去重 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认|e2e:文章标题去重 |
+| `tests/test-cases/admin.md#TC-A-10-E` | 关系类型 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认|e2e:关系类型 CRUD |
+| `tests/test-cases/admin.md#TC-A-11-E` | 勋章 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:勋章管理;黑盒回归 |
+| `tests/test-cases/admin.md#TC-A-12-E` | 供应商 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认|e2e:供应商管理;黑盒回归 |
+| `tests/test-cases/admin.md#TC-A-13-E` | 活动 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认|e2e:活动审核撤回;黑盒回归 |
+| `tests/test-cases/admin.md#TC-A-14-E` | 知识库 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认|e2e:知识库管理;黑盒回归 |
+| `tests/test-cases/admin.md#TC-A-15-E` | 数据迁移 | 运营 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:多数据源/SfmsDataSourceConfig |
+| `tests/test-cases/admin.md#TC-A-16-E` | 参数校验 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:统一 `Result<T>`+全局异常;黑盒回归 |
+| `tests/test-cases/admin.md#TC-A-17-E` | /api/admin/report-parser/* | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:/api/admin/report-parser/* |
+| `tests/test-cases/admin.md#TC-A-18-E` | 优惠券/活动管理 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确|e2e:优惠券/活动管理 |
+| `tests/test-cases/admin.md#TC-A-19-E` | 内容安全 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:内容安全 |
+| `tests/test-cases/admin.md#TC-A-20-E` | GDPR 工单 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规|e2e:GDPR 工单 |
+| `tests/test-cases/admin.md#TC-A-21-E` | 网关/限流 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:网关/限流 |
+| `tests/test-cases/admin.md#TC-A-22-E` | 模型管理 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:模型管理 |
+| `tests/test-cases/admin.md#TC-A-23-E` | 知识库 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:知识库 |
 | `tests/test-cases/admin.md#TC-A-01-P` | 认证 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非 admin 角色访问管理端接口统一 401/403,不泄露后台数据|e2e:AdminAuthController |
 | `tests/test-cases/admin.md#TC-A-02-P` | 统计 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非 admin 角色访问管理端接口统一 401/403,不泄露后台数据|e2e:StatsController |
 | `tests/test-cases/admin.md#TC-A-03-P` | 方案管理 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非 admin 角色访问管理端接口统一 401/403,不泄露后台数据|e2e:方案管理(全量) |
@@ -99,12 +99,6 @@
 | `tests/test-cases/admin.md#TC-A-21-P` | 网关/限流 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非 admin 角色访问统一 401/403,不泄露后台数据|e2e:网关/限流 |
 | `tests/test-cases/admin.md#TC-A-22-P` | 模型管理 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非 admin 角色访问统一 401/403,不泄露后台数据|e2e:模型管理 |
 | `tests/test-cases/admin.md#TC-A-23-P` | 知识库 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非 admin 角色访问统一 401/403,不泄露后台数据|e2e:知识库 |
-| `tests/test-cases/admin.md#TC-A-25` | 维度/权重/上限配置 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:变更生效、后续能量按新配置;存量影响提示|e2e:DimensionConfigController`/`DimensionWeightController |
-| `tests/test-cases/admin.md#TC-A-26` | 能量/归因权重 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:全局生效;变更写审计;概览/沙盘/天盘影响可观测|e2e:EnergyController`/`AttributionWeights |
-| `tests/test-cases/admin.md#TC-A-25-E` | 维度/权重/上限配置 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 需确认/拒、不级联破坏存量 2. 400 拦截 3. 乐观锁/版本控制不互相覆盖|e2e:DimensionConfigController |
-| `tests/test-cases/admin.md#TC-A-26-E` | 能量/归因权重 | 运营 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 400 拦截 2. 展示兜底并提示、不静默错算|e2e:EnergyController`/`AttributionWeights |
-| `tests/test-cases/admin.md#TC-A-25-P` | 维度/权重/上限配置 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非 admin 操作 403|e2e:DimensionConfigController |
-| `tests/test-cases/admin.md#TC-A-26-P` | 能量/归因权重 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非 admin 改全局 403|e2e:EnergyController |
 | `tests/test-cases/admin.md#TC-A-N01` | 配置CRUD | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:列表 ≤ 2s;CRUD 即时生效|e2e:配置管理 |
 | `tests/test-cases/admin.md#TC-A-N02` | 报告解析中台 | 运营 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:单条 ≤ 30s;失败进未知聚类;监控可见积压|e2e:解析中台 |
 | `tests/test-cases/admin.md#TC-A-N03` | 登录统计 | 运营 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:聚合 ≤ 3s;支持分页/缓存;大数据不超时|e2e:统计聚合 |
@@ -137,29 +131,29 @@
 | `tests/test-cases/child.md#TC-C-21` | 舌诊情绪识别 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:拍照上传;边界:模糊/非照片拒绝;隐私标注|e2e:舌诊情绪识别 |
 | `tests/test-cases/child.md#TC-C-22` | MallController | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:用积分换;边界:积分不足拦截;重复兑换幂等|e2e:MallController |
 | `tests/test-cases/child.md#TC-C-23` | 客服 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:提反馈;边界:内容适龄过滤;敏感信息脱敏|e2e:客服 |
-| `tests/test-cases/child.md#TC-C-01-E` | 权限/双角色 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:缺失/过期 token 统一 401 跳登录;切换/家长路由被 role 校验 403 拦截;孩子端无任何切回家长入口;模拟登录仅测试环境生效|e2e:双角色铁律:孩子端不能切家长 |
-| `tests/test-cases/child.md#TC-C-02-E` | 任务 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:并发双点幂等仅计 1 次、仅 1 条流水;超期提交被拒;驳回→重做→再提交仅在重做后计 1 次|e2e:TaskController |
-| `tests/test-cases/child.md#TC-C-03-E` | 小游戏 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:异常分数 400 不计入;断网不计分不卡死;重复上报幂等不重复入榜|e2e:pages/games/* |
-| `tests/test-cases/child.md#TC-C-04-E` | 心愿 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:余额不足创建拦截;超长/注入 400 校验;重复创建提示已存在不双建|e2e:WishController |
-| `tests/test-cases/child.md#TC-C-05-E` | 心愿 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:余额不足拦截且不扣负;已驳回提示不可兑换;并发幂等仅扣 1 次|e2e:RewardController |
-| `tests/test-cases/child.md#TC-C-06-E` | 能量 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时降级空态提示非 500;权重 0 占比兜底(0%)显示不崩;能量不为负|e2e:EnergyController |
-| `tests/test-cases/child.md#TC-C-07-E` | 报告/权限 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:删除/编辑被 role 校验 403 拒绝;孩子端 UI 无编辑/删除入口;报告内容不被改动|e2e:报告查看权限隔离 |
-| `tests/test-cases/child.md#TC-C-08-E` | 打卡/方案 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时回滚不残半任务、进度不 +1;重复打卡幂等不重复计数;非本人任务 403|e2e:健康打卡/方案进度 |
-| `tests/test-cases/child.md#TC-C-09-E` | 勋章 | 孩子 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:重复达成不重复发推送/勋章;未达成领取 400/403 拒绝|e2e:RewardController |
-| `tests/test-cases/child.md#TC-C-10-E` | 勋章提醒 | 孩子 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:重复达成幂等仅 1 次推送;数据缺失降级不推送不 500|e2e:MedalController |
-| `tests/test-cases/child.md#TC-C-11-E` | 成长记录 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:关联已删项跳过不报错;其他成员数据 403 不可见|e2e:GrowthController |
-| `tests/test-cases/child.md#TC-C-12-E` | 食谱查看 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时 Fallback 通用食谱+提示非 500;无食谱空态不 500|e2e:饮食推荐 |
-| `tests/test-cases/child.md#TC-C-13-E` | AI 对话 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:不适龄/敏感词被过滤返回适龄话术;LangGraph 不可用 Fallback 兜底、多轮连续|e2e:AIChatController |
-| `tests/test-cases/child.md#TC-C-14-E` | 任务重做 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非驳回态重做入口不可见/拦截;重做提交进入待审核仅计 1 次|e2e:TaskController |
-| `tests/test-cases/child.md#TC-C-15-E` | 消息接收 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:越权消息 403 不可见;不存在 404;列表分页正常|e2e:消息服务 |
-| `tests/test-cases/child.md#TC-C-16-E` | 个人资料 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:代管字段 403 不可改;昵称注入/超长 400 校验|e2e:AuthController |
-| `tests/test-cases/child.md#TC-C-17-E` | 退出 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:旧 token 失效 401;网络中断退出仍清本地缓存、下次需重登|e2e:AuthController |
-| `tests/test-cases/child.md#TC-C-18-E` | 设备校验 | 孩子 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:异常设备二次验证/拦截;旧设备 token 失效 401|e2e:AuthController |
-| `tests/test-cases/child.md#TC-C-19-E` | 消息服务 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:不存在 404;越权标记 403 不生效|e2e:消息服务 |
-| `tests/test-cases/child.md#TC-C-20-E` | GrowthController | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:未成年导出 403 需家长代办;他人档案 403 不可见|e2e:GrowthController |
-| `tests/test-cases/child.md#TC-C-21-E` | 舌诊情绪识别 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非照片/模糊拒绝提示『请上传清晰舌苔照』;低置信度提示重拍;隐私标注不外露|e2e:舌诊情绪识别 |
-| `tests/test-cases/child.md#TC-C-22-E` | MallController | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:余额不足拦截不扣负;并发仅 1 次成功;重复兑换幂等仅 1 条|e2e:MallController |
-| `tests/test-cases/child.md#TC-C-23-E` | 客服 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:敏感信息脱敏存储;附件超限 400『附件不超过 10MB』|e2e:客服 |
+| `tests/test-cases/child.md#TC-C-01-E` | 权限/双角色 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:双角色铁律:孩子端不能切家长 |
+| `tests/test-cases/child.md#TC-C-02-E` | 任务 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:TaskController |
+| `tests/test-cases/child.md#TC-C-03-E` | 小游戏 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:pages/games/* |
+| `tests/test-cases/child.md#TC-C-04-E` | 心愿 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:WishController |
+| `tests/test-cases/child.md#TC-C-05-E` | 心愿 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:RewardController |
+| `tests/test-cases/child.md#TC-C-06-E` | 能量 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:EnergyController |
+| `tests/test-cases/child.md#TC-C-07-E` | 报告/权限 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:报告查看权限隔离 |
+| `tests/test-cases/child.md#TC-C-08-E` | 打卡/方案 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:健康打卡/方案进度 |
+| `tests/test-cases/child.md#TC-C-09-E` | 勋章 | 孩子 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:RewardController |
+| `tests/test-cases/child.md#TC-C-10-E` | 勋章提醒 | 孩子 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:MedalController |
+| `tests/test-cases/child.md#TC-C-11-E` | 成长记录 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:GrowthController |
+| `tests/test-cases/child.md#TC-C-12-E` | 食谱查看 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:饮食推荐 |
+| `tests/test-cases/child.md#TC-C-13-E` | AI 对话 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:AIChatController |
+| `tests/test-cases/child.md#TC-C-14-E` | 任务重做 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:TaskController |
+| `tests/test-cases/child.md#TC-C-15-E` | 消息接收 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:消息服务 |
+| `tests/test-cases/child.md#TC-C-16-E` | 个人资料 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:AuthController |
+| `tests/test-cases/child.md#TC-C-17-E` | 退出 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:AuthController |
+| `tests/test-cases/child.md#TC-C-18-E` | 设备校验 | 孩子 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:AuthController |
+| `tests/test-cases/child.md#TC-C-19-E` | 消息服务 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:消息服务 |
+| `tests/test-cases/child.md#TC-C-20-E` | GrowthController | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规|e2e:GrowthController |
+| `tests/test-cases/child.md#TC-C-21-E` | 舌诊情绪识别 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:舌诊情绪识别 |
+| `tests/test-cases/child.md#TC-C-22-E` | MallController | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确|e2e:MallController |
+| `tests/test-cases/child.md#TC-C-23-E` | 客服 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:客服 |
 | `tests/test-cases/child.md#TC-C-01-P` | 权限/双角色 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据|e2e:双角色铁律:孩子端不能切家长 |
 | `tests/test-cases/child.md#TC-C-02-P` | 任务 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据|e2e:TaskController |
 | `tests/test-cases/child.md#TC-C-03-P` | 小游戏 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据|e2e:pages/games/* |
@@ -183,12 +177,6 @@
 | `tests/test-cases/child.md#TC-C-21-P` | 舌诊情绪识别 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据|e2e:舌诊情绪识别 |
 | `tests/test-cases/child.md#TC-C-22-P` | MallController | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据|e2e:MallController |
 | `tests/test-cases/child.md#TC-C-23-P` | 客服 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据|e2e:客服 |
-| `tests/test-cases/child.md#TC-C-24` | 能量/小游戏·任务 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:对应维度 +amount、sourceType=game/task;B 自身能量页看到增长与流水|e2e:GameRecordService`/`TaskController |
-| `tests/test-cases/child.md#TC-C-25` | 能量/方案打卡 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:GrowthTaskService 打卡对应维度+;任务进度与能量同步刷新|e2e:GrowthTaskService |
-| `tests/test-cases/child.md#TC-C-24-E` | 能量/小游戏·任务 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 异常分数拦截不写能量 2. 重复上报幂等不重复加|e2e:GameRecordService |
-| `tests/test-cases/child.md#TC-C-25-E` | 能量/方案打卡 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 按业务允/拒、断言一致 2. 重复打卡幂等不重复加 3. 并发不重复计分|e2e:GrowthTaskService |
-| `tests/test-cases/child.md#TC-C-24-P` | 能量/小游戏·任务 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:1. 他人能量 403 2. 孩子端无编辑/扣减入口、直接调被拒|e2e:JwtInterceptor`+role |
-| `tests/test-cases/child.md#TC-C-25-P` | 能量/方案打卡 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:1. 非本人方案任务 403 2. 他人进度不可见|e2e:GrowthTaskService |
 | `tests/test-cases/child.md#TC-C-N01` | 任务打卡 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等;并发不重复计分;响应 ≤ 1s|e2e:TaskController |
 | `tests/test-cases/child.md#TC-C-N02` | 消息通知 | 孩子 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:列表渲染 ≤ 1.5s;标记已读即时|e2e:消息中心 |
 | `tests/test-cases/child.md#TC-C-N03` | 孩子端 | 孩子 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:功能一致;无错位;低龄设备流畅|e2e:孩子端 |
@@ -250,15 +238,6 @@
 | `tests/test-cases/cross-role-e2e.md#TC-X-16-P` | 跨角色 | P0 | 权限 | 文档用例(待自动化) | 未跟踪 | 设计:X-16|e2e:- |
 | `tests/test-cases/cross-role-e2e.md#TC-X-17-P` | 跨角色 | P1 | 权限 | 文档用例(待自动化) | 未跟踪 | 设计:X-17|e2e:- |
 | `tests/test-cases/cross-role-e2e.md#TC-X-18-P` | 跨角色 | P1 | 权限 | 文档用例(待自动化) | 未跟踪 | 设计:X-18|e2e:- |
-| `tests/test-cases/cross-role-e2e.md#TC-X-19` | 跨角色 | P0 | 功能 | 文档用例(待自动化) | 未跟踪 | 设计:X-19|e2e:- |
-| `tests/test-cases/cross-role-e2e.md#TC-X-20` | 跨角色 | P0 | 功能 | 文档用例(待自动化) | 未跟踪 | 设计:X-20|e2e:- |
-| `tests/test-cases/cross-role-e2e.md#TC-X-21` | 跨角色 | P0 | 功能 | 文档用例(待自动化) | 未跟踪 | 设计:X-21|e2e:- |
-| `tests/test-cases/cross-role-e2e.md#TC-X-19-E` | 跨角色 | P1 | 异常 | 文档用例(待自动化) | 未跟踪 | 设计:X-19|e2e:- |
-| `tests/test-cases/cross-role-e2e.md#TC-X-20-E` | 跨角色 | P1 | 异常 | 文档用例(待自动化) | 未跟踪 | 设计:X-20|e2e:- |
-| `tests/test-cases/cross-role-e2e.md#TC-X-21-E` | 跨角色 | P1 | 异常 | 文档用例(待自动化) | 未跟踪 | 设计:X-21|e2e:- |
-| `tests/test-cases/cross-role-e2e.md#TC-X-19-P` | 跨角色 | P0 | 权限 | 文档用例(待自动化) | 未跟踪 | 设计:X-19|e2e:- |
-| `tests/test-cases/cross-role-e2e.md#TC-X-20-P` | 跨角色 | P1 | 权限 | 文档用例(待自动化) | 未跟踪 | 设计:X-20|e2e:- |
-| `tests/test-cases/cross-role-e2e.md#TC-X-21-P` | 跨角色 | P1 | 权限 | 文档用例(待自动化) | 未跟踪 | 设计:X-21|e2e:- |
 | `tests/test-cases/cross-role-e2e.md#TC-X-N01` | 跨角色 | P0 | 性能 | 文档用例(待自动化) | 未跟踪 | 设计:X-01|e2e:- |
 | `tests/test-cases/cross-role-e2e.md#TC-X-N02` | 跨角色 | P0 | 性能 | 文档用例(待自动化) | 未跟踪 | 设计:X-03|e2e:- |
 | `tests/test-cases/cross-role-e2e.md#TC-X-N03` | 跨角色 | P0 | 性能 | 文档用例(待自动化) | 未跟踪 | 设计:X-15|e2e:- |
@@ -285,7 +264,7 @@
 | `tests/test-cases/deep-dive-plan-activation.md#TC-PA-06` | 拆任务/数据 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非当天过期(待确认设计)|e2e:G4 |
 | `tests/test-cases/guest.md#TC-G-01` | 启动/首页 | 游客 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:显示引流首页,不进入任何业务页;明显展示微信/手机号/邀请登录入口|e2e:JwtInterceptor 拦截 `/api/** |
 | `tests/test-cases/guest.md#TC-G-02` | 认证 | 游客 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:返回 Result 含 token+用户信息;角色默认 parent;跳转家长首页;首次登录建 User+family_members(memberType=login)|e2e:AuthController`/`API_REFERENCE` 1.1 |
-| `tests/test-cases/guest.md#TC-G-03` | 认证 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:验证码正确→登录下发 token;错误→提示失败且**不产生会话**;限流生效 ⚠ **API 兼容保留**:小程序端无入口(登录走 SC-G-02),2026-11-01 口径|e2e:统一 POST/JWT |
+| `tests/test-cases/guest.md#TC-G-03` | 认证 | 游客 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:验证码正确→登录下发 token;错误→提示失败且**不产生会话**;限流生效|e2e:统一 POST/JWT |
 | `tests/test-cases/guest.md#TC-G-04` | 家庭/邀请 | 游客 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:登录后自动归属对应家庭,成员列表出现该用户;令牌失效→「邀请已失效」|e2e:FamilyInviteController |
 | `tests/test-cases/guest.md#TC-G-05` | 权限 | 游客 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:业务页→401 跳登录,登录后回跳;商城/文章列表可见(公开);需登录详情被拦截|e2e:JWT;8 公开路径白名单(1.1) |
 | `tests/test-cases/guest.md#TC-G-06` | 权限 | 游客 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:JwtInterceptor 拦截(8 个公开路径除外);缺 token→401/403,不泄露内部错误堆栈|e2e:JwtInterceptor |
@@ -295,18 +274,18 @@
 | `tests/test-cases/guest.md#TC-G-10` | 注册 | 游客 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:引导至注册;已注册账号不重复建档|e2e:AuthController |
 | `tests/test-cases/guest.md#TC-G-11` | 协议页/AgreementController | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:合规告知;边界:未同意不可进入注册/核心流程|e2e:协议页/AgreementController |
 | `tests/test-cases/guest.md#TC-G-12` | config.js | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:非微信浏览器打开小程序链接;边界:探测失败给出明确引导|e2e:config.js |
-| `tests/test-cases/guest.md#TC-G-01-E` | 启动/首页 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 不白屏、提供"稍后"/手机号登录兜底 2. 超时给重试而非 500;不泄露内部堆栈|e2e:JwtInterceptor 拦截 `/api/** |
-| `tests/test-cases/guest.md#TC-G-02-E` | 认证 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 回退手机号登录、停留登录页不报错 2. 返回已有账号不重复建号 3. 超时提示重试、不建脏号|e2e:AuthController`/`API_REFERENCE` 1.1 |
-| `tests/test-cases/guest.md#TC-G-03-E` | 认证 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 提示失败且不签发 token 2. 格式校验 400 拦截 3. 限流提示"操作频繁" 4. 绝不产生会话|e2e:统一 POST/JWT |
-| `tests/test-cases/guest.md#TC-G-04-E` | 家庭/邀请 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 拒绝并提示"邀请已失效" 2. 按业务规则处理(加入或被拒)、不串家庭|e2e:FamilyInviteController |
-| `tests/test-cases/guest.md#TC-G-05-E` | 权限 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 统一 401 跳登录;登录后回跳 2. 重定向登录;仅 8 公开路径放行|e2e:JWT;8 公开路径白名单(1.1) |
-| `tests/test-cases/guest.md#TC-G-06-E` | 权限 | 游客 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:1. 统一 401/403、不泄露内部错误与结构 2. 公开路径正常返回、不误拦|e2e:JwtInterceptor |
-| `tests/test-cases/guest.md#TC-G-07-E` | 测试模式 | 游客 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:1. 生产强制真授权、模拟登录被拒 2. 测试模式仅测试环境生效、不污染生产数据|e2e:AGENTS.md 测试模式 |
-| `tests/test-cases/guest.md#TC-G-08-E` | 环境切换 | 游客 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:1. 回退默认 API 地址、功能可用 2. 不因识别失败崩溃/错连|e2e:config.js |
-| `tests/test-cases/guest.md#TC-G-09-E` | 认证 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 退出后接口 401、需重登 2. 本地 token/隐私数据已清除|e2e:AuthController |
-| `tests/test-cases/guest.md#TC-G-10-E` | 注册 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 明确"未注册"并引导注册 2. 已注册不重复建档、直接登录|e2e:AuthController |
-| `tests/test-cases/guest.md#TC-G-11-E` | 协议页 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 拦截并强制先同意 2. 加载失败给重试、不绕过同意|e2e:协议页/AgreementController |
-| `tests/test-cases/guest.md#TC-G-12-E` | config.js | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 给出"在微信内打开"明确引导 2. 降级静态页、核心流程可手机号兜底|e2e:config.js |
+| `tests/test-cases/guest.md#TC-G-01-E` | 启动/首页 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:JwtInterceptor 拦截 `/api/** |
+| `tests/test-cases/guest.md#TC-G-02-E` | 认证 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:AuthController`/`API_REFERENCE` 1.1 |
+| `tests/test-cases/guest.md#TC-G-03-E` | 认证 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:统一 POST/JWT |
+| `tests/test-cases/guest.md#TC-G-04-E` | 家庭/邀请 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:FamilyInviteController |
+| `tests/test-cases/guest.md#TC-G-05-E` | 权限 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:JWT;8 公开路径白名单(1.1) |
+| `tests/test-cases/guest.md#TC-G-06-E` | 权限 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:JwtInterceptor |
+| `tests/test-cases/guest.md#TC-G-07-E` | 测试模式 | 游客 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:AGENTS.md 测试模式 |
+| `tests/test-cases/guest.md#TC-G-08-E` | 环境切换 | 游客 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:config.js |
+| `tests/test-cases/guest.md#TC-G-09-E` | 认证 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:AuthController |
+| `tests/test-cases/guest.md#TC-G-10-E` | 注册 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:AuthController |
+| `tests/test-cases/guest.md#TC-G-11-E` | 协议页/AgreementController | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:协议页/AgreementController |
+| `tests/test-cases/guest.md#TC-G-12-E` | config.js | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:config.js |
 | `tests/test-cases/guest.md#TC-G-01-P` | 启动/首页 | 游客 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒|e2e:JwtInterceptor 拦截 `/api/** |
 | `tests/test-cases/guest.md#TC-G-02-P` | 认证 | 游客 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒|e2e:AuthController`/`API_REFERENCE` 1.1 |
 | `tests/test-cases/guest.md#TC-G-03-P` | 认证 | 游客 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒|e2e:统一 POST/JWT |
@@ -320,7 +299,7 @@
 | `tests/test-cases/guest.md#TC-G-11-P` | 协议页/AgreementController | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:统一 401/403,不泄露内部错误与数据;8 个公开路径除外|e2e:协议页/AgreementController |
 | `tests/test-cases/guest.md#TC-G-12-P` | config.js | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:统一 401/403,不泄露内部错误与数据;8 个公开路径除外|e2e:config.js |
 | `tests/test-cases/guest.md#TC-G-N01` | 落地页 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:首屏 ≤ 3s;骨架屏生效;CDN 资源命中;无白屏|e2e:落地页/邀请 |
-| `tests/test-cases/guest.md#TC-G-N02` | 浏览转化 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:布局一致;微信授权正常;兜底登录可用;无错位|e2e:登录注册(微信授权) |
+| `tests/test-cases/guest.md#TC-G-N02` | 浏览转化 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:布局一致;微信授权正常;兜底登录可用;无错位|e2e:登录注册 |
 | `tests/test-cases/guest.md#TC-G-N03` | 非微信H5 | 游客 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:功能可用;无微信 SDK 依赖报错;流程闭环|e2e:H5 兜底 |
 | `tests/test-cases/guest.md#TC-G-N04` | 落地页 | 游客 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:返回 401;不泄露数据与结构|e2e:接口鉴权 |
 | `tests/test-cases/guest.md#TC-G-N05` | 登录注册 | 游客 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:触发限流/锁定;验证码一次性;防爆破;无撞库成功|e2e:登录限流 |
@@ -410,92 +389,92 @@
 | `tests/test-cases/parent.md#TC-P-84` | 分享 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:共享;边界:链接失效/权限校验;越权分享被拒|e2e:分享 |
 | `tests/test-cases/parent.md#TC-P-85` | AuthController | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:同账号多设备;边界:异常设备风控;退出清 token|e2e:AuthController |
 | `tests/test-cases/parent.md#TC-P-86` | 勋章/排行 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:激励;边界:数据仅本家庭可见;排名实时性|e2e:勋章/排行 |
-| `tests/test-cases/parent.md#TC-P-01-E` | 家庭 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:名称空或超长返回 400 且 message 含『家庭名称』校验项;HTML/SQL 注入被转义,库内不落恶意串;不抛 500、不泄露堆栈|e2e:FamilyInviteController |
-| `tests/test-cases/parent.md#TC-P-02-E` | 家庭/成员 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非法手机号 400 提示格式;已占用账号提示『已存在家庭关系』;过期码提示『邀请已失效,请重新获取』;均不建立成员关系|e2e:FamilyInviteController |
-| `tests/test-cases/parent.md#TC-P-03-E` | 成员资料 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:未来生日 400;关系非法值拒绝;姓名特殊字符转义存储、不破坏查询;既有成员数据不被污染|e2e:FamilyMembersController |
-| `tests/test-cases/parent.md#TC-P-04-E` | 关系图 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复关系提示已存在、不新增节点;非法枚举 400;关系图不出现重复/幽灵节点|e2e:关系类型 CRUD/前端选择器 |
-| `tests/test-cases/parent.md#TC-P-05-E` | 任务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:频率非法 400;并发双发幂等,仅生成 1 条任务、仅 1 次能量预期;超期任务拒绝提交|e2e:TaskController |
-| `tests/test-cases/parent.md#TC-P-06-E` | 任务审核 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复审批幂等不双计积分;驳回→重做→再审批仅在重做后计 1 次;超期任务审批被拒|e2e:TaskController`/`PointsController |
-| `tests/test-cases/parent.md#TC-P-07-E` | 心愿 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:余额不足拦截且不扣负积分;已取消心愿兑换提示失效;并发幂等仅扣 1 次|e2e:WishController`/`RewardController |
-| `tests/test-cases/parent.md#TC-P-08-E` | 能量 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:查询超时降级为空态提示非 500;权重为 0 时占比按兜底(0%)显示不崩;首访空态正常|e2e:EnergyController |
-| `tests/test-cases/parent.md#TC-P-09-E` | 测评订单 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:回调验签失败订单保持 pending 不进待安排;余额不足回滚;重复回调幂等仅落 1 次已支付|e2e:AssessmentAppointmentController |
-| `tests/test-cases/parent.md#TC-P-10-E` | 健康报告 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:损坏文件识别失败进未知聚类并提示;非募极明确提示『请确认是募极生物肠道菌群报告』;超大/加密提示超限或密码保护,均非 500|e2e:健康报告上传解析 |
-| `tests/test-cases/parent.md#TC-P-11-E` | 报告查看 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:不存在/已删返回 404 提示『报告不存在』;解析中提示『报告解析中,请稍候』,不白屏不 500|e2e:报告解析 |
-| `tests/test-cases/parent.md#TC-P-12-E` | 饮食推荐 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:AiGateway Fallback 返回兜底食材清单+友好提示非 500;重复点击幂等仅生成 1 份、不重复扣费|e2e:饮食推荐系统 |
-| `tests/test-cases/parent.md#TC-P-13-E` | AI 方案 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:Fallback 兜底方案+提示;未购会员请求付费板块返回『请先开通会员』拦截,不白生成|e2e:AI 统一走 LangGraph;`AiGateway |
-| `tests/test-cases/parent.md#TC-P-14-E` | 方案提交 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:空方案提交拦截提示『方案未生成』;重复提交幂等不重复进审核|e2e:方案状态机 |
-| `tests/test-cases/parent.md#TC-P-15-E` | 双角色 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:缺失/过期 token 统一 401 跳登录;孩子端无切回家长入口;非法切换 403 被拒;模拟登录仅测试环境生效|e2e:POST /api/family/member/switch`(替代废弃 switch-mode);双角色铁律 |
-| `tests/test-cases/parent.md#TC-P-16-E` | 会员 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付超时订单回滚不解锁权益;重复购买幂等仅开通 1 次、不重复扣费|e2e:MembershipController`/`ProductOrderController |
-| `tests/test-cases/parent.md#TC-P-17-E` | 积分/成长 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:并发刷新总量一致不重复计;关联任务已删时该成长项跳过不报错,时间格式 yyyy-MM-dd HH:mm:ss|e2e:PointsController`/`GrowthController |
-| `tests/test-cases/parent.md#TC-P-18-E` | AI 对话 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超长消息 400 提示;敏感词按合规拦截;LangGraph 不可用 Fallback 兜底回答,多轮上下文不丢|e2e:AIChatController`;LangGraph RAG |
-| `tests/test-cases/parent.md#TC-P-19-E` | 能量配置 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:配置缺失展示兜底说明非 500;权重和非法 400 提示『权重合计需为 100%』|e2e:维度配置 |
-| `tests/test-cases/parent.md#TC-P-20-E` | 健康报告 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:损坏文件识别失败进未知聚类并提示;非募极明确提示『请确认是募极生物肠道菌群报告』;超大/加密提示超限或密码保护,均非 500|e2e:报告解析中台/`POST /api/media/upload |
-| `tests/test-cases/parent.md#TC-P-21-E` | 报告解析 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:未注册类型进未知聚类待运营自学习;0 字节文件提示『文件为空』;均非 500|e2e:/api/admin/report-parser/types |
-| `tests/test-cases/parent.md#TC-P-22-E` | 报告预览 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:异常值提示『数据异常,暂不入库』不入库;超时提示解析中,不白屏|e2e:解析中台 |
-| `tests/test-cases/parent.md#TC-P-23-E` | 报告入库 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:报告已删提示『报告不存在,确认失败』;并发确认幂等仅入库 1 次、七维仅刷新 1 次|e2e:解析中台 |
-| `tests/test-cases/parent.md#TC-P-24-E` | 报告管理 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:有方案时提示『请先解除关联方案』再删;不存在 id 返回 404 不崩|e2e:报告管理 |
-| `tests/test-cases/parent.md#TC-P-25-E` | 报告趋势 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:单报告提示『至少需要 2 份报告才能看趋势』;时间轴按真实时间升序,不倒挂|e2e:成长/报告 |
-| `tests/test-cases/parent.md#TC-P-26-E` | 饮食推荐 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:AiGateway Fallback 返回兜底食材清单+友好提示非 500;重复点击幂等仅生成 1 份、不重复扣费|e2e:饮食推荐系统 |
-| `tests/test-cases/parent.md#TC-P-27-E` | 家庭食谱 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时 Fallback 通用食谱+提示;过敏食材未排除时返回 400 提示『存在过敏冲突』重算|e2e:饮食推荐/家庭食谱 |
-| `tests/test-cases/parent.md#TC-P-28-E` | 食谱筛选 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:忌口冲突提示并停止生成;非法忌口值 400;重算生效|e2e:饮食推荐 |
-| `tests/test-cases/parent.md#TC-P-29-E` | 食谱收藏 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:替换后提示『超出营养目标』不静默;重复收藏幂等仅 1 条|e2e:饮食推荐 |
-| `tests/test-cases/parent.md#TC-P-30-E` | 食谱营养 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:超标明确标红提示『超出目标 X%』;未设目标提示先设目标,不除零|e2e:饮食推荐 |
-| `tests/test-cases/parent.md#TC-P-31-E` | 测评类型 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字典缺失时前端降级不白屏;非法 type 400;八类以字典为准|e2e:DanAssessmentController |
-| `tests/test-cases/parent.md#TC-P-32-E` | 测评规划师 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:未绑定提示『请先绑定规划师』;已解绑 T 不在可选列表,选则 400|e2e:测评订单 |
-| `tests/test-cases/parent.md#TC-P-33-E` | 测评下单 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:下架套餐 400『套餐不可售』;数量非法/库存不足拦截,不生成订单|e2e:AssessmentOrder |
-| `tests/test-cases/parent.md#TC-P-34-E` | 测评支付 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时回滚不生成额度;重复回调幂等仅生成 1 条额度|e2e:支付/`AssessmentQuota |
-| `tests/test-cases/parent.md#TC-P-35-E` | 测评额度 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:过期额度预约返回『额度已过期』不落预约;额度页加载降级非 500|e2e:AssessmentQuota |
-| `tests/test-cases/parent.md#TC-P-36-E` | 测评预约 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:无额度返回『额度不足或已过期』不建预约不发能量;并发双发仅落 1 条预约、能量仅发 1 次(幂等)|e2e:AssessmentAppointmentController |
-| `tests/test-cases/parent.md#TC-P-37-E` | 预约状态 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:状态机守卫拒绝非法跃迁返回 400;不存在预约 404;状态准确|e2e:AssessmentAppointmentController |
-| `tests/test-cases/parent.md#TC-P-38-E` | 预约取消 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:越权取消 403 被拒(CFC-AP);终态预约取消返回『不可取消』;不退款逻辑按配置|e2e:AssessmentAppointmentController |
-| `tests/test-cases/parent.md#TC-P-39-E` | DAN报告 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:未录入提示『结果待录入』不白屏;缺字段校验 400 提示缺哪项|e2e:DanAssessmentResultDTO |
-| `tests/test-cases/parent.md#TC-P-40-E` | AI方案 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:Fallback 兜底方案+提示;未购会员请求付费板块返回『请先开通会员』拦截,不白生成|e2e:AIChatController`/`AiGateway |
-| `tests/test-cases/parent.md#TC-P-41-E` | 方案迭代 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:断网 Fallback 保留其他板块不丢;连续点击幂等仅 1 次重生成|e2e:AIChatController |
-| `tests/test-cases/parent.md#TC-P-42-E` | 方案编辑 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超长 400 提示;越权编辑 403 被拒;编辑后状态标记已改|e2e:方案管理 |
-| `tests/test-cases/parent.md#TC-P-43-E` | 方案查看 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:空方案展示占位不白屏;不存在 404|e2e:方案管理 |
-| `tests/test-cases/parent.md#TC-P-44-E` | 方案确认 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:未确认激活拦截『请先确认』;重复确认幂等仅 1 次 reviewed|e2e:方案状态机 |
-| `tests/test-cases/parent.md#TC-P-45-E` | 方案发布 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:需审核配置时发布走审核流不直接 active;未 reviewed 发布拦截|e2e:方案管理 |
-| `tests/test-cases/parent.md#TC-P-46-E` | 方案激活 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:已激活再激活幂等不重复生成任务;超时回滚不残半任务,状态回 reviewed|e2e:方案激活任务分解 |
-| `tests/test-cases/parent.md#TC-P-47-E` | 方案任务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:删任务同步方案并提示;非法 id 400;任务增删与方案一致|e2e:GrowthPlanController |
-| `tests/test-cases/parent.md#TC-P-48-E` | 方案版本 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:历史版本只读返回 403『版本不可篡改』;不存在 404|e2e:方案管理 |
-| `tests/test-cases/parent.md#TC-P-49-E` | AI对话 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超长消息 400 提示;敏感词按合规拦截;LangGraph 不可用 Fallback 兜底回答,多轮上下文不丢|e2e:AIChatController |
-| `tests/test-cases/parent.md#TC-P-50-E` | 成长记录 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:关联已删项跳过不报错;首访空态正常,时间线不白屏|e2e:GrowthController |
-| `tests/test-cases/parent.md#TC-P-51-E` | 成长里程碑 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:重复标幂等仅 1 条;非法节点 400|e2e:GrowthController |
-| `tests/test-cases/parent.md#TC-P-52-E` | 商城浏览 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:注入被转义返回安全结果;下架商品不展示;不 500|e2e:MallController`/`danshop |
-| `tests/test-cases/parent.md#TC-P-53-E` | 商品详情 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:库存 0 提示『暂时缺货』;不存在 404|e2e:MallController |
-| `tests/test-cases/parent.md#TC-P-54-E` | 商城下单 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超库存拦截『库存不足』;重复提交幂等仅 1 单|e2e:MallController |
-| `tests/test-cases/parent.md#TC-P-55-E` | 订单支付 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时回滚订单保持待支付;重复通知幂等仅 1 次 paid|e2e:支付 |
-| `tests/test-cases/parent.md#TC-P-56-E` | 订单退款 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:已发货按规则处理/拒;重复退款拦截仅 1 次|e2e:订单服务 |
-| `tests/test-cases/parent.md#TC-P-57-E` | 优惠券 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:过期券不可用提示;未达门槛拦截『还差 X 元可用』;不重复抵扣|e2e:优惠券 |
-| `tests/test-cases/parent.md#TC-P-58-E` | 会员购买 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:失败回滚不解锁;重复购买幂等仅 1 次、不双扣|e2e:MemberController |
-| `tests/test-cases/parent.md#TC-P-59-E` | 会员权益 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:过期提示『会员已失效』;越权 403;权益随档位|e2e:MemberController |
-| `tests/test-cases/parent.md#TC-P-60-E` | 会员续费 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:未到期续费叠加计算正确(延期);负金额 400|e2e:MemberController |
-| `tests/test-cases/parent.md#TC-P-61-E` | 联系人 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复号码去重提示;非法格式 400;不建重复|e2e:ContactCard`/`contact-detail |
-| `tests/test-cases/parent.md#TC-P-62-E` | 联系人导入 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:错误行跳过并报告『第 N 行格式错误』;非 CSV 拒绝;正确行入库|e2e:ContactImport |
-| `tests/test-cases/parent.md#TC-P-63-E` | 联系人权限 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:越权查看 403;非法权限值 400;最小权限保底|e2e:ContactCard |
-| `tests/test-cases/parent.md#TC-P-64-E` | 个人资料 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:手机格式 400;昵称超长/非法字符拦截;保存生效|e2e:AuthController |
-| `tests/test-cases/parent.md#TC-P-65-E` | 通知设置 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:关键安全通知仍推送不被关;非法时间 400|e2e:消息服务 |
-| `tests/test-cases/parent.md#TC-P-66-E` | 隐私设置 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:非法范围 400;敏感字段最小权限保底不外露|e2e:隐私设置 |
-| `tests/test-cases/parent.md#TC-P-67-E` | 报告代传/report-proxy | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:越权代传他人孩子 403 被拒;报告归属校验失败不入档;授权令牌失效提示|e2e:报告代传/report-proxy |
-| `tests/test-cases/parent.md#TC-P-68-E` | 家庭天盘 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:缺失项降级展示不白屏;非成员访问 403;仅本家庭可见|e2e:家庭天盘 |
-| `tests/test-cases/parent.md#TC-P-69-E` | 精准营养 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:负/超上限 400『热量需在合理区间』;非数字 400;目标生效影响食谱|e2e:精准营养 |
-| `tests/test-cases/parent.md#TC-P-70-E` | 舌诊情绪识别 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非照片/模糊拒绝提示『请上传清晰舌苔照』;低置信度提示『识别不清晰,建议重拍』;隐私标注不外露|e2e:舌诊情绪识别 |
-| `tests/test-cases/parent.md#TC-P-71-E` | AuthController | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:有在途订单拦截『请先处理进行中订单』;注销后 token 失效 401 不可登录|e2e:AuthController |
-| `tests/test-cases/parent.md#TC-P-72-E` | 数据导出(GDPR) | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:越权导出 403;频次限制提示『导出过于频繁』;敏感字段脱敏|e2e:数据导出(GDPR) |
-| `tests/test-cases/parent.md#TC-P-73-E` | 家庭/成员 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非本家庭孩子不可选 400;切换保持各孩子上下文隔离不串|e2e:家庭/成员 |
-| `tests/test-cases/parent.md#TC-P-74-E` | 规划师绑定 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:在途未完成提示『请先处理在途服务』;非本家庭 T 绑定 400 被拒|e2e:规划师绑定 |
-| `tests/test-cases/parent.md#TC-P-75-E` | 优惠券 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:库存 0 提示『已领完』;重复领幂等仅入卡包 1 张|e2e:优惠券 |
-| `tests/test-cases/parent.md#TC-P-76-E` | 活动管理 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:并发超卖拦截仅 1 人成功(CFC 已修 bug 回归);满额拒『名额已满』;重复报名幂等|e2e:活动管理 |
-| `tests/test-cases/parent.md#TC-P-77-E` | 活动 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复打卡幂等仅计 1 次;刷量风控拦截;进度累计正确|e2e:活动 |
-| `tests/test-cases/parent.md#TC-P-78-E` | 消息服务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:越权消息不可见 403;不存在 404;分页正常|e2e:消息服务 |
-| `tests/test-cases/parent.md#TC-P-79-E` | 消息服务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:关键安全通知不可关;非法时间 400|e2e:消息服务 |
-| `tests/test-cases/parent.md#TC-P-80-E` | 会员/订单 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:已消费不退提示;重复退拦截;发票信息校验缺失字段 400|e2e:会员/订单 |
-| `tests/test-cases/parent.md#TC-P-81-E` | 方案/任务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:过期草稿提示『草稿已失效』;并发存后者覆盖且提示冲突|e2e:方案/任务 |
-| `tests/test-cases/parent.md#TC-P-82-E` | 搜索 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:越权结果过滤不可见;空结果不报错提示『请输入关键词』|e2e:搜索 |
-| `tests/test-cases/parent.md#TC-P-83-E` | 客服 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:敏感信息脱敏存储;附件超限 400『附件不超过 10MB』|e2e:客服 |
-| `tests/test-cases/parent.md#TC-P-84-E` | 分享 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:失效链接提示『分享已失效』;越权分享 403 被拒|e2e:分享 |
-| `tests/test-cases/parent.md#TC-P-85-E` | AuthController | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:异常设备二次验证/拦截;退出后旧 token 失效 401|e2e:AuthController |
-| `tests/test-cases/parent.md#TC-P-86-E` | 勋章/排行 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非本家庭榜不可见 403;排名仅本家庭数据,刷新即更新|e2e:勋章/排行 |
+| `tests/test-cases/parent.md#TC-P-01-E` | 家庭 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:FamilyInviteController |
+| `tests/test-cases/parent.md#TC-P-02-E` | 家庭/成员 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:FamilyInviteController |
+| `tests/test-cases/parent.md#TC-P-03-E` | 成员资料 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:FamilyMembersController |
+| `tests/test-cases/parent.md#TC-P-04-E` | 关系图 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认|e2e:关系类型 CRUD/前端选择器 |
+| `tests/test-cases/parent.md#TC-P-05-E` | 任务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:TaskController |
+| `tests/test-cases/parent.md#TC-P-06-E` | 任务审核 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:TaskController`/`PointsController |
+| `tests/test-cases/parent.md#TC-P-07-E` | 心愿 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:WishController`/`RewardController |
+| `tests/test-cases/parent.md#TC-P-08-E` | 能量 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:EnergyController |
+| `tests/test-cases/parent.md#TC-P-09-E` | 测评订单 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:AssessmentAppointmentController |
+| `tests/test-cases/parent.md#TC-P-10-E` | 健康报告 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:健康报告上传解析 |
+| `tests/test-cases/parent.md#TC-P-11-E` | 报告查看 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:报告解析 |
+| `tests/test-cases/parent.md#TC-P-12-E` | 饮食推荐 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:饮食推荐系统 |
+| `tests/test-cases/parent.md#TC-P-13-E` | AI 方案 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:AI 统一走 LangGraph;`AiGateway |
+| `tests/test-cases/parent.md#TC-P-14-E` | 方案提交 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案状态机 |
+| `tests/test-cases/parent.md#TC-P-15-E` | 双角色 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:POST /api/family/member/switch`(替代废弃 switch-mode);双角色铁律 |
+| `tests/test-cases/parent.md#TC-P-16-E` | 会员 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:MembershipController`/`ProductOrderController |
+| `tests/test-cases/parent.md#TC-P-17-E` | 积分/成长 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:PointsController`/`GrowthController |
+| `tests/test-cases/parent.md#TC-P-18-E` | AI 对话 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:AIChatController`;LangGraph RAG |
+| `tests/test-cases/parent.md#TC-P-19-E` | 能量配置 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:维度配置 |
+| `tests/test-cases/parent.md#TC-P-20-E` | 健康报告 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:报告解析中台/`POST /api/media/upload |
+| `tests/test-cases/parent.md#TC-P-21-E` | 报告解析 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:/api/admin/report-parser/types |
+| `tests/test-cases/parent.md#TC-P-22-E` | 报告预览 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:解析中台 |
+| `tests/test-cases/parent.md#TC-P-23-E` | 报告入库 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:解析中台 |
+| `tests/test-cases/parent.md#TC-P-24-E` | 报告管理 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:报告管理 |
+| `tests/test-cases/parent.md#TC-P-25-E` | 报告趋势 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:成长/报告 |
+| `tests/test-cases/parent.md#TC-P-26-E` | 饮食推荐 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:饮食推荐系统 |
+| `tests/test-cases/parent.md#TC-P-27-E` | 家庭食谱 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:饮食推荐/家庭食谱 |
+| `tests/test-cases/parent.md#TC-P-28-E` | 食谱筛选 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:饮食推荐 |
+| `tests/test-cases/parent.md#TC-P-29-E` | 食谱收藏 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:饮食推荐 |
+| `tests/test-cases/parent.md#TC-P-30-E` | 食谱营养 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:饮食推荐 |
+| `tests/test-cases/parent.md#TC-P-31-E` | 测评类型 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退|e2e:DanAssessmentController |
+| `tests/test-cases/parent.md#TC-P-32-E` | 测评规划师 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退|e2e:测评订单 |
+| `tests/test-cases/parent.md#TC-P-33-E` | 测评下单 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:AssessmentOrder |
+| `tests/test-cases/parent.md#TC-P-34-E` | 测评支付 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:支付/`AssessmentQuota |
+| `tests/test-cases/parent.md#TC-P-35-E` | 测评额度 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:AssessmentQuota |
+| `tests/test-cases/parent.md#TC-P-36-E` | 测评预约 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退|e2e:AssessmentAppointmentController |
+| `tests/test-cases/parent.md#TC-P-37-E` | 预约状态 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退|e2e:AssessmentAppointmentController |
+| `tests/test-cases/parent.md#TC-P-38-E` | 预约取消 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退|e2e:AssessmentAppointmentController |
+| `tests/test-cases/parent.md#TC-P-39-E` | DAN报告 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:DanAssessmentResultDTO |
+| `tests/test-cases/parent.md#TC-P-40-E` | AI方案 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:AIChatController`/`AiGateway |
+| `tests/test-cases/parent.md#TC-P-41-E` | 方案迭代 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:AIChatController |
+| `tests/test-cases/parent.md#TC-P-42-E` | 方案编辑 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案管理 |
+| `tests/test-cases/parent.md#TC-P-43-E` | 方案查看 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案管理 |
+| `tests/test-cases/parent.md#TC-P-44-E` | 方案确认 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案状态机 |
+| `tests/test-cases/parent.md#TC-P-45-E` | 方案发布 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案管理 |
+| `tests/test-cases/parent.md#TC-P-46-E` | 方案激活 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案激活任务分解 |
+| `tests/test-cases/parent.md#TC-P-47-E` | 方案任务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:GrowthPlanController |
+| `tests/test-cases/parent.md#TC-P-48-E` | 方案版本 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案管理 |
+| `tests/test-cases/parent.md#TC-P-49-E` | AI对话 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:AIChatController |
+| `tests/test-cases/parent.md#TC-P-50-E` | 成长记录 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:GrowthController |
+| `tests/test-cases/parent.md#TC-P-51-E` | 成长里程碑 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:GrowthController |
+| `tests/test-cases/parent.md#TC-P-52-E` | 商城浏览 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:MallController`/`danshop |
+| `tests/test-cases/parent.md#TC-P-53-E` | 商品详情 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:MallController |
+| `tests/test-cases/parent.md#TC-P-54-E` | 商城下单 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:MallController |
+| `tests/test-cases/parent.md#TC-P-55-E` | 订单支付 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:支付 |
+| `tests/test-cases/parent.md#TC-P-56-E` | 订单退款 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:订单服务 |
+| `tests/test-cases/parent.md#TC-P-57-E` | 优惠券 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:优惠券 |
+| `tests/test-cases/parent.md#TC-P-58-E` | 会员购买 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:MemberController |
+| `tests/test-cases/parent.md#TC-P-59-E` | 会员权益 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:MemberController |
+| `tests/test-cases/parent.md#TC-P-60-E` | 会员续费 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:MemberController |
+| `tests/test-cases/parent.md#TC-P-61-E` | 联系人 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:ContactCard`/`contact-detail |
+| `tests/test-cases/parent.md#TC-P-62-E` | 联系人导入 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:ContactImport |
+| `tests/test-cases/parent.md#TC-P-63-E` | 联系人权限 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:ContactCard |
+| `tests/test-cases/parent.md#TC-P-64-E` | 个人资料 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:AuthController |
+| `tests/test-cases/parent.md#TC-P-65-E` | 通知设置 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:消息服务 |
+| `tests/test-cases/parent.md#TC-P-66-E` | 隐私设置 | 家长 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:隐私设置 |
+| `tests/test-cases/parent.md#TC-P-67-E` | 报告代传/report-proxy | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:报告代传/report-proxy |
+| `tests/test-cases/parent.md#TC-P-68-E` | 家庭天盘 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:家庭天盘 |
+| `tests/test-cases/parent.md#TC-P-69-E` | 精准营养 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:精准营养 |
+| `tests/test-cases/parent.md#TC-P-70-E` | 舌诊情绪识别 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:舌诊情绪识别 |
+| `tests/test-cases/parent.md#TC-P-71-E` | AuthController | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规|e2e:AuthController |
+| `tests/test-cases/parent.md#TC-P-72-E` | 数据导出(GDPR) | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:数据导出(GDPR) |
+| `tests/test-cases/parent.md#TC-P-73-E` | 家庭/成员 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:家庭/成员 |
+| `tests/test-cases/parent.md#TC-P-74-E` | 规划师绑定 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规|e2e:规划师绑定 |
+| `tests/test-cases/parent.md#TC-P-75-E` | 优惠券 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确|e2e:优惠券 |
+| `tests/test-cases/parent.md#TC-P-76-E` | 活动管理 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确|e2e:活动管理 |
+| `tests/test-cases/parent.md#TC-P-77-E` | 活动 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确|e2e:活动 |
+| `tests/test-cases/parent.md#TC-P-78-E` | 消息服务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:消息服务 |
+| `tests/test-cases/parent.md#TC-P-79-E` | 消息服务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:消息服务 |
+| `tests/test-cases/parent.md#TC-P-80-E` | 会员/订单 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确|e2e:会员/订单 |
+| `tests/test-cases/parent.md#TC-P-81-E` | 方案/任务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活幂等不重复生成任务;失败回滚不残半任务|e2e:方案/任务 |
+| `tests/test-cases/parent.md#TC-P-82-E` | 搜索 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:搜索 |
+| `tests/test-cases/parent.md#TC-P-83-E` | 客服 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据|e2e:客服 |
+| `tests/test-cases/parent.md#TC-P-84-E` | 分享 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:分享 |
+| `tests/test-cases/parent.md#TC-P-85-E` | AuthController | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规|e2e:AuthController |
+| `tests/test-cases/parent.md#TC-P-86-E` | 勋章/排行 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:勋章/排行 |
 | `tests/test-cases/parent.md#TC-P-01-P` | 家庭 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒|e2e:FamilyInviteController |
 | `tests/test-cases/parent.md#TC-P-02-P` | 家庭/成员 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒|e2e:FamilyInviteController |
 | `tests/test-cases/parent.md#TC-P-03-P` | 成员资料 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒|e2e:FamilyMembersController |
@@ -582,27 +561,6 @@
 | `tests/test-cases/parent.md#TC-P-84-P` | 分享 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒|e2e:分享 |
 | `tests/test-cases/parent.md#TC-P-85-P` | AuthController | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒|e2e:AuthController |
 | `tests/test-cases/parent.md#TC-P-86-P` | 勋章/排行 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒|e2e:勋章/排行 |
-| `tests/test-cases/parent.md#TC-P-87` | 能量/任务 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:B 对应维度 balance/totalEarned +amount;EnergyLog.sourceType=task、balanceAfter 正确;概览/沙盘随新值刷新|e2e:EnergyRuleEngine`/`TaskController |
-| `tests/test-cases/parent.md#TC-P-88` | 能量/心愿 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:扣减成功,EnergyLog 负 amount、balanceAfter=balance-额;balance/totalSpent 同步;心愿已兑换|e2e:EnergyController`/`RewardController |
-| `tests/test-cases/parent.md#TC-P-89` | 能量/手动 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:指定维度 +amount;EnergyLog.sourceType=manual 留痕;balanceAfter 更新|e2e:EnergyController |
-| `tests/test-cases/parent.md#TC-P-90` | 能量/日上限 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:累计达 N 后新增触发不再累加(或截断到上限);跨日 00:00 清零可重新获取|e2e:DimensionDailyLimit |
-| `tests/test-cases/parent.md#TC-P-91` | 能量/健康报告 | 家长 | P0 | 文档用例(待自动化) | 未跟踪 | 设计:七维/六维评分刷新;概览/沙盘/score-history 按新值重算;时间序列反映改善|e2e:HealthReportController |
-| `tests/test-cases/parent.md#TC-P-92` | 能量/配置 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:按新口径重算并展示;存量重算提示|e2e:EnergyController`/维度配置 |
-| `tests/test-cases/parent.md#TC-P-93` | 能量/文章·活动 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:对应维度 +amount;sourceType=article/activity;balanceAfter 更新|e2e:ArticleService`/`ActivityService |
-| `tests/test-cases/parent.md#TC-P-87-E` | 能量/任务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 重复审批幂等不重复加、无第二条 EnergyLog 2. 无归因维度不 500、按规则落 sourceType 或不加 3. 参数非法统一 400、不改动能量 4. 规则异常告警、不写脏流水|e2e:EnergyRuleEngine |
-| `tests/test-cases/parent.md#TC-P-88-E` | 能量/心愿 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:1. 余额不足明确"能量不足"、心愿保持待审批、无负余额 2. 并发仅一次成功、二次幂等拒 3. 已兑换再提交拒、无负流水 4. 参数非法 400、不扣减|e2e:EnergyController`/`RewardController |
-| `tests/test-cases/parent.md#TC-P-89-E` | 能量/手动 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 400 拦截不发放 2. 400 不写脏数据 3. 按幂等/业务规则不重复加|e2e:EnergyController |
-| `tests/test-cases/parent.md#TC-P-90-E` | 能量/日上限 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 触顶后其余来源同维度受限 2. 手动口径断言一致 3. 以服务端日期为准、不绕过 4. 上限 0/负 拒绝配置或按 0、不崩溃|e2e:DimensionDailyLimit |
-| `tests/test-cases/parent.md#TC-P-91-E` | 能量/健康报告 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:1. 不刷新、原评分保留 2. 类型不一致不可比/提示、不串维度 3. 该维度保持上一值或空态、不 500 4. 重复入库幂等不重复刷新|e2e:HealthReportController |
-| `tests/test-cases/parent.md#TC-P-92-E` | 能量/配置 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 报警并拒或归一化、不静默错算 2. 展示兜底旧值并提示"同步中"、不显示错乱 3. 400 拦截|e2e:EnergyController`/维度配置 |
-| `tests/test-cases/parent.md#TC-P-93-E` | 能量/文章·活动 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 风控拦截不计能量 2. 触顶不累加 3. 按规则回收或保留、不双发 4. 参与被拒不发放|e2e:ArticleService`/`ActivityService |
-| `tests/test-cases/parent.md#TC-P-87-P` | 能量/任务 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:1. 非本家庭能量访问 403 2. 孩子端无 grant 入口、直接调被 role 校验拒|e2e:JwtInterceptor`+role |
-| `tests/test-cases/parent.md#TC-P-88-P` | 能量/心愿 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:1. 非本家庭心愿 403 2. 孩子端无扣减入口、直接调被拒|e2e:EnergyController |
-| `tests/test-cases/parent.md#TC-P-89-P` | 能量/手动 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:1. 非本家庭 grant 403 2. 孩子端拒|e2e:JwtInterceptor`+role |
-| `tests/test-cases/parent.md#TC-P-90-P` | 能量/日上限 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 他人累计不可见 403 2. 越权改配置 403|e2e:DimensionDailyLimit |
-| `tests/test-cases/parent.md#TC-P-91-P` | 能量/健康报告 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非本家庭健康维度数据 403、不泄露|e2e:HealthReportController |
-| `tests/test-cases/parent.md#TC-P-92-P` | 能量/配置 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非 admin 改全局 403|e2e:EnergyController |
-| `tests/test-cases/parent.md#TC-P-93-P` | 能量/文章·活动 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非本家庭流水 403|e2e:ArticleService`/`ActivityService |
 | `tests/test-cases/parent.md#TC-P-N01` | 健康报告 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:上传+解析 ≤ 30s;超时走 AiGateway 友好降级而非 500;进度可见|e2e:健康报告上传解析 |
 | `tests/test-cases/parent.md#TC-P-N02` | AI 方案 | 家长 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:各方案独立完整、数据不串;单请求 P95 ≤ 15s;LangGraph 超时回退 Fallback|e2e:AiGateway/LangGraph |
 | `tests/test-cases/parent.md#TC-P-N03` | 任务 | 家长 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:首屏 ≤ 2s;翻页流畅;分页/虚拟滚动生效|e2e:TaskController |
@@ -645,35 +603,35 @@
 | `tests/test-cases/teacher.md#TC-T-27` | 家庭天盘 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:给家庭看聚合视图并解读;边界:仅绑定家庭可见|e2e:家庭天盘 |
 | `tests/test-cases/teacher.md#TC-T-28` | 内容安全 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:复核 AI 敏感内容;边界:命中即拦截|e2e:内容安全 |
 | `tests/test-cases/teacher.md#TC-T-29` | 数据导出(GDPR) | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:导出客户数据;边界:授权/脱敏;越权拒|e2e:数据导出(GDPR) |
-| `tests/test-cases/teacher.md#TC-T-01-E` | 认证/双角色 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:缺失/过期 token 统一 401 跳登录;非绑定家庭路由 403 被拒;模拟登录开关仅在测试环境可开|e2e:AuthController`;规划师可切回家长 |
-| `tests/test-cases/teacher.md#TC-T-02-E` | 家庭绑定 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:错码/过期提示『邀请码无效或已失效』;重复绑定幂等不双建;注销家庭不可绑|e2e:FamilyInviteController |
-| `tests/test-cases/teacher.md#TC-T-03-E` | 健康报告 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:损坏/非募极提示明确(非募极提示请确认募极生物);超大超限提示;解析超时进草稿非500;非绑定孩子 403|e2e:报告上传解析;规划师代传 |
-| `tests/test-cases/teacher.md#TC-T-04-E` | 报告审核 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:已删草稿提示『不存在』;解析中确认提示稍候;非绑定家庭草稿 403 不可操作|e2e:报告审核 |
-| `tests/test-cases/teacher.md#TC-T-05-E` | 方案管理 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:列表超时降级提示非500;黑盒回归:函数不再未定义、不白屏;空列表正常占位|e2e:方案管理;黑盒回归项 |
-| `tests/test-cases/teacher.md#TC-T-06-E` | 方案审核 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非 generated 态批准拦截(状态机守卫);并发双批准幂等仅 1 次状态跃迁|e2e:方案状态机 |
-| `tests/test-cases/teacher.md#TC-T-07-E` | 方案激活 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时回滚不残半任务、状态回 reviewed;已激活再激活幂等不重复生成任务;非 reviewed 激活拦截|e2e:激活拆任务 |
-| `tests/test-cases/teacher.md#TC-T-08-E` | 方案激活·幂等 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:第二次幂等返回现状、不重复生成引导/模板任务;任务数与首次一致|e2e:幂等约束(黑盒回归) |
-| `tests/test-cases/teacher.md#TC-T-09-E` | 任务审核 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭 403;并发双审幂等仅计 1 次积分;超期任务审核被拒|e2e:TaskController |
-| `tests/test-cases/teacher.md#TC-T-10-E` | 测评录入 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:必填缺失 400 不生成半成品;重复录入覆盖非新增;越界 400 不写脏分;非指派 confirm 返回『您不是被指派测评师』|e2e:AssessmentAppointmentController`/`DanAssessmentController |
-| `tests/test-cases/teacher.md#TC-T-11-E` | 成长计划 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时降级非500;空列表正常;非绑定家庭 403|e2e:GrowthPlanController`;黑盒回归 |
-| `tests/test-cases/teacher.md#TC-T-12-E` | 套餐 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:空任务项拦截上架;审核超时回退草稿非500;重复提交幂等|e2e:GuidePackageController |
-| `tests/test-cases/teacher.md#TC-T-13-E` | 数据隔离 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭统一 403;不泄露他人数据;并发越权同样 403|e2e:控制器内 role 检查 |
-| `tests/test-cases/teacher.md#TC-T-14-E` | 方案编辑 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:归档方案编辑拦截;非绑定家庭 403;超长 400|e2e:方案管理 |
-| `tests/test-cases/teacher.md#TC-T-15-E` | 套餐任务 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重算超时降级提示非500;空套餐拦截;并发增删各自生效不丢项|e2e:GuidePackageController |
-| `tests/test-cases/teacher.md#TC-T-16-E` | 健康总览 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:缺失项降级展示不白屏;超时降级提示非500;仅绑定家庭数据|e2e:仪表板 |
-| `tests/test-cases/teacher.md#TC-T-17-E` | 计划进度 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:超时降级非500;进度按任务状态实时计算、一致|e2e:GrowthPlanController |
-| `tests/test-cases/teacher.md#TC-T-18-E` | 批量任务 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:部分失败不影响其他成员独立落库;并发批量各自独立不串|e2e:TaskController |
-| `tests/test-cases/teacher.md#TC-T-19-E` | 消息推送 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:已注销客户跳过不报错;内容转义不执行脚本;免打扰不推送|e2e:消息服务 |
-| `tests/test-cases/teacher.md#TC-T-20-E` | 退出/切换 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:旧 token 失效 401;网络中断退出清缓存、下次需重登;切回家长正常|e2e:AuthController |
-| `tests/test-cases/teacher.md#TC-T-21-E` | 报告对比 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:类型不一致提示不可比;不存在 id 404;差异清晰标注|e2e:报告管理 |
-| `tests/test-cases/teacher.md#TC-T-22-E` | 方案归档 | 规划师 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:归档后编辑/激活拦截;不存在 404|e2e:方案管理 |
-| `tests/test-cases/teacher.md#TC-T-23-E` | 报告代传/report-proxy | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭 403 拒;损坏/非募极提示明确;识别失败进草稿非500|e2e:报告代传/report-proxy |
-| `tests/test-cases/teacher.md#TC-T-24-E` | 规划师绑定 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:在途未完成提示先处理;非平台家庭绑定 400 拒|e2e:规划师绑定 |
-| `tests/test-cases/teacher.md#TC-T-25-E` | 舌诊情绪识别 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:类型校验拒绝(.php/.html)不执行;非照片/模糊拒;低置信度提示重拍|e2e:舌诊情绪识别 |
-| `tests/test-cases/teacher.md#TC-T-26-E` | 精准营养 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:负/超上限 400『热量需在合理区间』;脚本转义存储不执行|e2e:精准营养 |
-| `tests/test-cases/teacher.md#TC-T-27-E` | 家庭天盘 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭 403;缺失项降级展示不白屏|e2e:家庭天盘 |
-| `tests/test-cases/teacher.md#TC-T-28-E` | 内容安全 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:命中即拦截不放行;超时 Fallback 兜底、友好提示非500|e2e:内容安全 |
-| `tests/test-cases/teacher.md#TC-T-29-E` | 数据导出(GDPR) | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:越权导出 403;频次限制提示『导出过于频繁』;敏感字段脱敏|e2e:数据导出(GDPR) |
+| `tests/test-cases/teacher.md#TC-T-01-E` | 认证/双角色 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:AuthController`;规划师可切回家长 |
+| `tests/test-cases/teacher.md#TC-T-02-E` | 家庭绑定 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:FamilyInviteController |
+| `tests/test-cases/teacher.md#TC-T-03-E` | 健康报告 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:报告上传解析;规划师代传 |
+| `tests/test-cases/teacher.md#TC-T-04-E` | 报告审核 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:报告审核 |
+| `tests/test-cases/teacher.md#TC-T-05-E` | 方案管理 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案管理;黑盒回归项 |
+| `tests/test-cases/teacher.md#TC-T-06-E` | 方案审核 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案状态机 |
+| `tests/test-cases/teacher.md#TC-T-07-E` | 方案激活 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:激活拆任务 |
+| `tests/test-cases/teacher.md#TC-T-08-E` | 方案激活·幂等 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:幂等约束(黑盒回归) |
+| `tests/test-cases/teacher.md#TC-T-09-E` | 任务审核 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:TaskController |
+| `tests/test-cases/teacher.md#TC-T-10-E` | 测评录入 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退|e2e:AssessmentAppointmentController`/`DanAssessmentController |
+| `tests/test-cases/teacher.md#TC-T-11-E` | 成长计划 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:GrowthPlanController`;黑盒回归 |
+| `tests/test-cases/teacher.md#TC-T-12-E` | 套餐 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:GuidePackageController |
+| `tests/test-cases/teacher.md#TC-T-13-E` | 数据隔离 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:控制器内 role 检查 |
+| `tests/test-cases/teacher.md#TC-T-14-E` | 方案编辑 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案管理 |
+| `tests/test-cases/teacher.md#TC-T-15-E` | 套餐任务 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:GuidePackageController |
+| `tests/test-cases/teacher.md#TC-T-16-E` | 健康总览 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:仪表板 |
+| `tests/test-cases/teacher.md#TC-T-17-E` | 计划进度 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:GrowthPlanController |
+| `tests/test-cases/teacher.md#TC-T-18-E` | 批量任务 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500|e2e:TaskController |
+| `tests/test-cases/teacher.md#TC-T-19-E` | 消息推送 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:消息服务 |
+| `tests/test-cases/teacher.md#TC-T-20-E` | 退出/切换 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效|e2e:AuthController |
+| `tests/test-cases/teacher.md#TC-T-21-E` | 报告对比 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:报告管理 |
+| `tests/test-cases/teacher.md#TC-T-22-E` | 方案归档 | 规划师 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务|e2e:方案管理 |
+| `tests/test-cases/teacher.md#TC-T-23-E` | 报告代传/report-proxy | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:报告代传/report-proxy |
+| `tests/test-cases/teacher.md#TC-T-24-E` | 规划师绑定 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:规划师绑定 |
+| `tests/test-cases/teacher.md#TC-T-25-E` | 舌诊情绪识别 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:舌诊情绪识别 |
+| `tests/test-cases/teacher.md#TC-T-26-E` | 精准营养 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:精准营养 |
+| `tests/test-cases/teacher.md#TC-T-27-E` | 家庭天盘 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:家庭天盘 |
+| `tests/test-cases/teacher.md#TC-T-28-E` | 内容安全 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活幂等不重复生成任务;失败回滚不残半任务|e2e:内容安全 |
+| `tests/test-cases/teacher.md#TC-T-29-E` | 数据导出(GDPR) | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活幂等不重复生成任务;失败回滚不残半任务|e2e:数据导出(GDPR) |
 | `tests/test-cases/teacher.md#TC-T-01-P` | 认证/双角色 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒(高危越权修复)|e2e:AuthController`;规划师可切回家长 |
 | `tests/test-cases/teacher.md#TC-T-02-P` | 家庭绑定 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒(高危越权修复)|e2e:FamilyInviteController |
 | `tests/test-cases/teacher.md#TC-T-03-P` | 健康报告 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒(高危越权修复)|e2e:报告上传解析;规划师代传 |
@@ -703,15 +661,6 @@
 | `tests/test-cases/teacher.md#TC-T-27-P` | 家庭天盘 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒|e2e:家庭天盘 |
 | `tests/test-cases/teacher.md#TC-T-28-P` | 内容安全 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒|e2e:内容安全 |
 | `tests/test-cases/teacher.md#TC-T-29-P` | 数据导出(GDPR) | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒|e2e:数据导出(GDPR) |
-| `tests/test-cases/teacher.md#TC-T-30` | 测评/五维 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:八类分→五维刷新;生成 generated 方案;概览/沙盘刷新|e2e:AssessmentAppointmentService |
-| `tests/test-cases/teacher.md#TC-T-31` | 维度/手动 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:目标维度覆盖/调整并留痕;概览/沙盘随新值刷新|e2e:ManualDimensionScoreController |
-| `tests/test-cases/teacher.md#TC-T-32` | 五维/自评 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:自评微调并叠加;FiveDimensionSelfCheck 留记录;历史可查|e2e:FiveDimensionSelfCheckController |
-| `tests/test-cases/teacher.md#TC-T-30-E` | 测评/五维 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:1. 400 不生成半成品 2. 覆盖非新增、无重复记录 3. 越界 400 不写脏分|e2e:AssessmentAppointmentService |
-| `tests/test-cases/teacher.md#TC-T-31-E` | 维度/手动 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:1. 400 拦截 2. 幂等无重复痕迹;不影响其他维度(断言)|e2e:ManualDimensionScoreController |
-| `tests/test-cases/teacher.md#TC-T-32-E` | 五维/自评 | 规划师 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:400 拦截;不写脏分|e2e:FiveDimensionSelfCheckController |
-| `tests/test-cases/teacher.md#TC-T-30-P` | 测评/五维 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭录入 403|e2e:AssessmentAppointmentService |
-| `tests/test-cases/teacher.md#TC-T-31-P` | 维度/手动 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭 403|e2e:ManualDimensionScoreController |
-| `tests/test-cases/teacher.md#TC-T-32-P` | 五维/自评 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非绑定家庭 403|e2e:FiveDimensionSelfCheckController |
 | `tests/test-cases/teacher.md#TC-T-N01` | 健康报告 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:队列不堵;单份 ≤ 30s;失败重试不重复入库|e2e:报告解析中台 |
 | `tests/test-cases/teacher.md#TC-T-N02` | 方案审核 | 规划师 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:列表 ≤ 2s;筛选/排序生效|e2e:方案状态机 |
 | `tests/test-cases/teacher.md#TC-T-N03` | 绑定家庭 | 规划师 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:切换 ≤ 1.5s;数据隔离不串|e2e:绑定家庭 |
@@ -731,17 +680,17 @@
 | `tests/test-cases/vendor.md#TC-S-9` | 服务商集成/解析中台 | 服务商 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:提供解析能力;边界:跨商户隔离;鉴权|e2e:服务商集成/解析中台 |
 | `tests/test-cases/vendor.md#TC-S-10` | 食谱库 | 服务商 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:供食谱数据;边界:数据合规;格式校验|e2e:食谱库 |
 | `tests/test-cases/vendor.md#TC-S-11` | 合规 | 服务商 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:达成目标:授权内用数;边界:越授权拒;脱敏|e2e:合规 |
-| `tests/test-cases/vendor.md#TC-S-01-E` | 入驻 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:资质缺失驳回并说明缺项;重复申请幂等不双建;非法联系方式 400|e2e:ServiceRoleApplicationController`/`AdminEcomSupplierController |
-| `tests/test-cases/vendor.md#TC-S-02-E` | 商品 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:负价格/负库存/非法分类统一 400;并发改库存乐观锁不互相覆盖;下架后不可购买|e2e:ProductController`/`AdminProductController |
-| `tests/test-cases/vendor.md#TC-S-03-E` | 订单 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进已发货;重复发货幂等仅 1 次;核销码校验失败拒(防冒用)|e2e:ProductOrderController |
-| `tests/test-cases/vendor.md#TC-S-04-E` | 订单核销 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复核销幂等;超期提示不可核销;非本服务商 403|e2e:订单服务 |
-| `tests/test-cases/vendor.md#TC-S-05-E` | 库存 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:负库存 400 拦截;并发超卖保护不出现负库存;同步失败重试前台一致|e2e:库存服务 |
-| `tests/test-cases/vendor.md#TC-S-06-E` | 售后 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:重复退款拦截仅 1 次;超金额 400;非本服务商 403;流水可追溯|e2e:售后 |
-| `tests/test-cases/vendor.md#TC-S-07-E` | 活动报名 | 服务商 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:失效活动报名拒;重复报名幂等;非法参数 400|e2e:活动管理 |
-| `tests/test-cases/vendor.md#TC-S-08-E` | 对账 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:未到账期结算拒;重复结算幂等;异常金额告警不入账|e2e:结算 |
-| `tests/test-cases/vendor.md#TC-S-9-E` | 服务商集成/解析中台 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:跨商户隔离 403;损坏/超大文件明确提示非500;鉴权失效 401|e2e:服务商集成/解析中台 |
-| `tests/test-cases/vendor.md#TC-S-10-E` | 食谱库 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:格式校验 400;XSS 转义存储不执行;非本商户 403|e2e:食谱库 |
-| `tests/test-cases/vendor.md#TC-S-11-E` | 合规 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:越授权 403 拒;敏感字段强制脱敏;并发越权同样 403|e2e:合规 |
+| `tests/test-cases/vendor.md#TC-S-01-E` | 入驻 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈|e2e:ServiceRoleApplicationController`/`AdminEcomSupplierController |
+| `tests/test-cases/vendor.md#TC-S-02-E` | 商品 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:ProductController`/`AdminProductController |
+| `tests/test-cases/vendor.md#TC-S-03-E` | 订单 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:ProductOrderController |
+| `tests/test-cases/vendor.md#TC-S-04-E` | 订单核销 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:订单服务 |
+| `tests/test-cases/vendor.md#TC-S-05-E` | 库存 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:库存服务 |
+| `tests/test-cases/vendor.md#TC-S-06-E` | 售后 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:售后 |
+| `tests/test-cases/vendor.md#TC-S-07-E` | 活动报名 | 服务商 | P3 | 文档用例(待自动化) | 未跟踪 | 设计:标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认|e2e:活动管理 |
+| `tests/test-cases/vendor.md#TC-S-08-E` | 对账 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等|e2e:结算 |
+| `tests/test-cases/vendor.md#TC-S-9-E` | 服务商集成/解析中台 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:服务商集成/解析中台 |
+| `tests/test-cases/vendor.md#TC-S-10-E` | 食谱库 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」|e2e:食谱库 |
+| `tests/test-cases/vendor.md#TC-S-11-E` | 合规 | 服务商 | P2 | 文档用例(待自动化) | 未跟踪 | 设计:并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规|e2e:合规 |
 | `tests/test-cases/vendor.md#TC-S-01-P` | 入驻 | 服务商 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非本服务商资源操作被拒;核销码校验防冒用;跨商户数据隔离|e2e:ServiceRoleApplicationController`/`AdminEcomSupplierController |
 | `tests/test-cases/vendor.md#TC-S-02-P` | 商品 | 服务商 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非本服务商资源操作被拒;核销码校验防冒用;跨商户数据隔离|e2e:ProductController`/`AdminProductController |
 | `tests/test-cases/vendor.md#TC-S-03-P` | 订单 | 服务商 | P1 | 文档用例(待自动化) | 未跟踪 | 设计:非本服务商资源操作被拒;核销码校验防冒用;跨商户数据隔离|e2e:ProductOrderController |
@@ -774,13 +723,13 @@
 | `tests/e2e/admin-panel.spec.js` | 4 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/admin-promotion-config.spec.js` | 2 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/ai-plan-task-flow.spec.js` | 7 | 已自动化(e2e) | 未跟踪 | — |
-| `tests/e2e/api/api-smoke.spec.js` | 4 | 已自动化(e2e) | 通过 | — |
-| `tests/e2e/api/article-api.spec.js` | 7 | 已自动化(e2e) | 通过 | — |
-| `tests/e2e/api/contact-api.spec.js` | 6 | 已自动化(e2e) | 通过 | — |
-| `tests/e2e/api/energy-api.spec.js` | 8 | 已自动化(e2e) | 通过 | — |
-| `tests/e2e/api/family-member-api.spec.js` | 14 | 已自动化(e2e) | 通过 | — |
-| `tests/e2e/api/nonfunc-perf-compat.spec.js` | 5 | 已自动化(e2e) | 通过 | — |
-| `tests/e2e/api/nonfunc-security.spec.js` | 11 | 已自动化(e2e) | 失败 | — |
+| `tests/e2e/api/api-smoke.spec.js` | 4 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/api/article-api.spec.js` | 7 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/api/contact-api.spec.js` | 6 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/api/energy-api.spec.js` | 8 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/api/family-member-api.spec.js` | 14 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/api/nonfunc-perf-compat.spec.js` | 5 | 已自动化(e2e) | 未跟踪 | — |
+| `tests/e2e/api/nonfunc-security.spec.js` | 11 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/article-management.spec.js` | 5 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/assessment-appointment-functional.spec.js` | 7 | 已自动化(e2e) | 未跟踪 | — |
 | `tests/e2e/assessment-appointment.spec.js` | 6 | 已自动化(e2e) | 未跟踪 | — |
@@ -855,46 +804,40 @@
 
 | 来源 | 用例数 | 自动化状态 | 执行状态 | 目标类 |
 | --- | --- | --- | --- | --- |
-| `cfc-backend/src/test/java/com/etotem/cfc/common/AdminRolesTest.java` | 9 | 已自动化(@Test) | 通过 | AdminRoles |
+| `cfc-backend/src/test/java/com/etotem/cfc/common/AdminRolesTest.java` | 9 | 已自动化(@Test) | 未跟踪 | AdminRoles |
 | `cfc-backend/src/test/java/com/etotem/cfc/common/TestRoles.java` | 0 | 已自动化(@Test) | 未跟踪 | TestRoles.java |
-| `cfc-backend/src/test/java/com/etotem/cfc/config/AttributionStage1FoundationTest.java` | 7 | 已自动化(@Test) | 通过 | AttributionStage1Foundation |
-| `cfc-backend/src/test/java/com/etotem/cfc/config/DatabaseInitializerSeedTest.java` | 6 | 已自动化(@Test) | 通过 | DatabaseInitializerSeed |
-| `cfc-backend/src/test/java/com/etotem/cfc/config/FamilyAccessInterceptorTest.java` | 11 | 已自动化(@Test) | 通过 | FamilyAccessInterceptor |
-| `cfc-backend/src/test/java/com/etotem/cfc/config/JwtInterceptorLoginRequiredTest.java` | 5 | 已自动化(@Test) | 通过 | JwtInterceptorLoginRequired |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionControllerTest.java` | 1 | 已自动化(@Test) | 通过 | AttributionController |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionSurveyRoutingTest.java` | 3 | 已自动化(@Test) | 通过 | AttributionSurveyRouting |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/DanAssessmentControllerGetActiveMaterialTest.java` | 2 | 已自动化(@Test) | 未跟踪 | DanAssessmentControllerGetActiveMaterial |
+| `cfc-backend/src/test/java/com/etotem/cfc/config/AttributionStage1FoundationTest.java` | 7 | 已自动化(@Test) | 未跟踪 | AttributionStage1Foundation |
+| `cfc-backend/src/test/java/com/etotem/cfc/config/DatabaseInitializerSeedTest.java` | 6 | 已自动化(@Test) | 未跟踪 | DatabaseInitializerSeed |
+| `cfc-backend/src/test/java/com/etotem/cfc/config/FamilyAccessInterceptorTest.java` | 11 | 已自动化(@Test) | 未跟踪 | FamilyAccessInterceptor |
+| `cfc-backend/src/test/java/com/etotem/cfc/config/JwtInterceptorLoginRequiredTest.java` | 5 | 已自动化(@Test) | 未跟踪 | JwtInterceptorLoginRequired |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionControllerTest.java` | 1 | 已自动化(@Test) | 未跟踪 | AttributionController |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionSurveyRoutingTest.java` | 3 | 已自动化(@Test) | 未跟踪 | AttributionSurveyRouting |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/EnergyControllerGrantEnergyTest.java` | 3 | 已自动化(@Test) | 未跟踪 | EnergyControllerGrantEnergy |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthCheckinCfEarnCallSiteTest.java` | 6 | 已自动化(@Test) | 未跟踪 | HealthCheckinCfEarnCallSite |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthPlanDeleteControllerTest.java` | 6 | 已自动化(@Test) | 未跟踪 | HealthPlanDeleteController |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerCreateReportTest.java` | 5 | 已自动化(@Test) | 未跟踪 | HealthReportControllerCreateReport |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerListPaginationTest.java` | 4 | 已自动化(@Test) | 未跟踪 | HealthReportControllerListPagination |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerProxyParseBindingTest.java` | 6 | 已自动化(@Test) | 未跟踪 | HealthReportControllerProxyParseBinding |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/IndicatorControllerTest.java` | 2 | 已自动化(@Test) | 未跟踪 | IndicatorController |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/IndicatorFavoriteControllerTest.java` | 10 | 已自动化(@Test) | 未跟踪 | IndicatorFavoriteController |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminAuthWechatScanTest.java` | 11 | 已自动化(@Test) | 未跟踪 | AdminAuthWechatScan |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminProductControllerBatchShelveTest.java` | 4 | 已自动化(@Test) | 通过 | AdminProductControllerBatchShelve |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/ReportParserAdminControllerTest.java` | 3 | 已自动化(@Test) | 通过 | ReportParserAdminController |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/SupplyTeamControllerInviteTest.java` | 7 | 已自动化(@Test) | 未跟踪 | SupplyTeamControllerInvite |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerAddMemberTest.java` | 7 | 已自动化(@Test) | 未跟踪 | FamilyMembersControllerAddMember |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminProductControllerBatchShelveTest.java` | 4 | 已自动化(@Test) | 未跟踪 | AdminProductControllerBatchShelve |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/ReportParserAdminControllerTest.java` | 3 | 已自动化(@Test) | 未跟踪 | ReportParserAdminController |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerListTest.java` | 4 | 已自动化(@Test) | 未跟踪 | FamilyMembersControllerList |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerRenameFamilyTest.java` | 2 | 已自动化(@Test) | 未跟踪 | FamilyMembersControllerRenameFamily |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TeacherMessageControllerMyTest.java` | 1 | 已自动化(@Test) | 通过 | TeacherMessageControllerMy |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TrainingPlanControllerGetPlanListTest.java` | 10 | 已自动化(@Test) | 通过 | TrainingPlanControllerGetPlanList |
+| `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TeacherMessageControllerMyTest.java` | 1 | 已自动化(@Test) | 未跟踪 | TeacherMessageControllerMy |
 | `cfc-backend/src/test/java/com/etotem/cfc/dto/ActivityDTOTest.java` | 3 | 已自动化(@Test) | 未跟踪 | ActivityDTO |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/DailyCheckinStreakFlowTest.java` | 6 | 已自动化(@Test) | 未跟踪 | DailyCheckinStreakFlow |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/EnergySystemFlowTest.java` | 7 | 已自动化(@Test) | 未跟踪 | EnergySystemFlow |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/GrowthRecordSyncFlowTest.java` | 10 | 已自动化(@Test) | 未跟踪 | GrowthRecordSyncFlow |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/GuideModuleIntegrationTest.java` | 4 | 已自动化(@Test) | 未跟踪 | GuideModule |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/PlannerBindInviteFlowTest.java` | 9 | 已自动化(@Test) | 未跟踪 | PlannerBindInviteFlow |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AIChatControllerTest.java` | 17 | 已自动化(@Test) | 通过 | AIChatController |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ActivityControllerTest.java` | 16 | 已自动化(@Test) | 通过 | ActivityController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AIChatControllerTest.java` | 17 | 已自动化(@Test) | 未跟踪 | AIChatController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ActivityControllerTest.java` | 16 | 已自动化(@Test) | 未跟踪 | ActivityController |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AdminFamilyOverviewControllerTest.java` | 3 | 已自动化(@Test) | 未跟踪 | AdminFamilyOverviewController |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AdminSpecialPriceControllerTest.java` | 8 | 已自动化(@Test) | 未跟踪 | AdminSpecialPriceController |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleCategoryControllerTest.java` | 3 | 已自动化(@Test) | 通过 | ArticleCategoryController |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleControllerTest.java` | 11 | 已自动化(@Test) | 失败 | ArticleController |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AuthControllerTest.java` | 39 | 已自动化(@Test) | 失败 | AuthController |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DailyTaskControllerTest.java` | 2 | 已自动化(@Test) | 通过 | DailyTaskController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleCategoryControllerTest.java` | 3 | 已自动化(@Test) | 未跟踪 | ArticleCategoryController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleControllerTest.java` | 11 | 已自动化(@Test) | 未跟踪 | ArticleController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AuthControllerTest.java` | 39 | 已自动化(@Test) | 未跟踪 | AuthController |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DailyTaskControllerTest.java` | 2 | 已自动化(@Test) | 未跟踪 | DailyTaskController |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DimensionAdminControllerTest.java` | 13 | 已自动化(@Test) | 未跟踪 | DimensionAdminController |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/FamilyControllerTest.java` | 8 | 已自动化(@Test) | 未跟踪 | FamilyController |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/GuideFamilyTaskControllerTest.java` | 20 | 已自动化(@Test) | 未跟踪 | GuideFamilyTaskController |
@@ -920,7 +863,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/DimensionScoreServiceTest.java` | 21 | 已自动化(@Test) | 未跟踪 | DimensionScoreService |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FamilyFoodOverviewServiceTest.java` | 9 | 已自动化(@Test) | 未跟踪 | FamilyFoodOverviewService |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FiveDimensionSelfCheckServiceTest.java` | 2 | 已自动化(@Test) | 未跟踪 | FiveDimensionSelfCheckService |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodRecommendServiceTest.java` | 21 | 已自动化(@Test) | 未跟踪 | FoodRecommendService |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodRecommendServiceTest.java` | 18 | 已自动化(@Test) | 未跟踪 | FoodRecommendService |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodServiceTest.java` | 12 | 已自动化(@Test) | 未跟踪 | FoodService |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FortuneServiceTest.java` | 4 | 已自动化(@Test) | 未跟踪 | FortuneService |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuideApplicationServiceTest.java` | 8 | 已自动化(@Test) | 未跟踪 | GuideApplicationService |
@@ -964,7 +907,6 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/service/EnergyServiceWealthIncomeTest.java` | 4 | 已自动化(@Test) | 未跟踪 | EnergyServiceWealthIncome |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyAdminOverviewServiceTest.java` | 3 | 已自动化(@Test) | 未跟踪 | FamilyAdminOverviewService |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyJoinRequestServiceReferrerBindTest.java` | 5 | 已自动化(@Test) | 未跟踪 | FamilyJoinRequestServiceReferrerBind |
-| `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyMemberServiceIsChildTest.java` | 5 | 已自动化(@Test) | 未跟踪 | FamilyMemberServiceIsChild |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyPlatformPointsServiceCouponTest.java` | 5 | 已自动化(@Test) | 未跟踪 | FamilyPlatformPointsServiceCoupon |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/HealthReportServiceAuditConfirmTest.java` | 8 | 已自动化(@Test) | 未跟踪 | HealthReportServiceAuditConfirm |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/HealthReportServiceBackfillResilienceTest.java` | 5 | 已自动化(@Test) | 未跟踪 | HealthReportServiceBackfillResilience |
@@ -1049,7 +991,6 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TaskProgressUpdateTest.java` | 3 | 已自动化(@Test) | 未跟踪 | TaskProgressUpdate |
 | `cfc-backend/src/test/java/com/etotem/cfc/util/CfFormulaEvaluatorTest.java` | 8 | 已自动化(@Test) | 未跟踪 | CfFormulaEvaluator |
 | `cfc-backend/src/test/java/com/etotem/cfc/util/SpearmanUtilTest.java` | 6 | 已自动化(@Test) | 未跟踪 | SpearmanUtil |
-| `cfc-backend/src/test/java/com/etotem/cfc/util/UserUtilTest.java` | 6 | 已自动化(@Test) | 未跟踪 | UserUtil |
 
 ## 六、用户场景(`tests/user-scenarios/*.md`,上游输入)
 
@@ -1061,9 +1002,8 @@
 | `tests/user-scenarios/04-teacher.md` | 文件级 | 用户场景(待自动化) | 未跟踪 | 场景标题约 9 个 |
 | `tests/user-scenarios/05-admin.md` | 文件级 | 用户场景(待自动化) | 未跟踪 | 场景标题约 8 个 |
 | `tests/user-scenarios/06-vendor.md` | 文件级 | 用户场景(待自动化) | 未跟踪 | 场景标题约 4 个 |
-| `tests/user-scenarios/07-five-dimension.md` | 文件级 | 用户场景(待自动化) | 未跟踪 | 场景标题约 18 个 |
 | `tests/user-scenarios/README.md` | 文件级 | 用户场景(待自动化) | 未跟踪 | 场景标题约 4 个 |
-| `tests/user-scenarios/应用场景总览.md` | 文件级 | 用户场景(待自动化) | 未跟踪 | 场景标题约 29 个 |
+| `tests/user-scenarios/应用场景总览.md` | 文件级 | 用户场景(待自动化) | 未跟踪 | 场景标题约 23 个 |
 
 ## 七、回写与发布流程(本地侧车 → 共享台账)
 

+ 23 - 39
docs/tdd/test/discovery.md

@@ -8,27 +8,28 @@
 | 指标 | 数值 |
 | --- | --- |
 | 控制器总数 | 357 |
-| handler 方法总数 | 1935 |
-| handler 方法已覆盖 | 203 (10.5%) |
+| handler 方法总数 | 1933 |
+| handler 方法已覆盖 | 199 (10.3%) |
 | 单元-全覆盖(handler 方法) | 16 |
-| 单元-部分覆盖(handler 方法) | 72 |
-| 单元-未覆盖(handler 方法) | 268 |
+| 单元-部分覆盖(handler 方法) | 69 |
+| 单元-未覆盖(handler 方法) | 271 |
 | 单元-无handler 方法 | 1 |
-| 测试文件数 | 195 |
-| @Test 方法总数 | 1451 |
+| 测试文件数 | 182 |
+| @Test 方法总数 | 1379 |
 | 含跳过/假设项(test 级 partial) | 4 |
 
 ## 二、未覆盖控制器(发现「缺口」· 非发明)
 
 > 以下控制器在当前测试源中**没有任何handler 方法被命中**。这是真实扫描得到的覆盖缺口。
 
-共 268 个:
+共 271 个:
 
 - `AdminController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminController.java`,65 方法)
 - `DanAssessmentController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/DanAssessmentController.java`,29 方法)
 - `AdminArticleController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminArticleController.java`,22 方法)
 - `TaskController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/task/TaskController.java`,18 方法)
-- `AdminInventoryController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminInventoryController.java`,15 方法)
+- `FamilyUserController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/family/FamilyUserController.java`,17 方法)
+- `AdminInventoryController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminInventoryController.java`,16 方法)
 - `FamilyInviteController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/family/FamilyInviteController.java`,15 方法)
 - `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 方法)
@@ -46,6 +47,7 @@
 - `TeacherController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/guide/TeacherController.java`,10 方法)
 - `UserController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/UserController.java`,10 方法)
 - `AdminButlerController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminButlerController.java`,9 方法)
+- `FamilyMembersController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/family/FamilyMembersController.java`,9 方法)
 - `FileRecordController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/FileRecordController.java`,9 方法)
 - `GutHealthProjectController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/GutHealthProjectController.java`,9 方法)
 - `KnowledgeBaseController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/KnowledgeBaseController.java`,9 方法)
@@ -53,6 +55,7 @@
 - `PearlController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/PearlController.java`,9 方法)
 - `PpointConfigAdminController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/PpointConfigAdminController.java`,9 方法)
 - `AdminActivityController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminActivityController.java`,8 方法)
+- `AdminAuthController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminAuthController.java`,8 方法)
 - `ArticleCommentController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/content/ArticleCommentController.java`,8 方法)
 - `ContactController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/ContactController.java`,8 方法)
 - `DanReportController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/DanReportController.java`,8 方法)
@@ -67,7 +70,6 @@
 - `AdminUnlockGateController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminUnlockGateController.java`,7 方法)
 - `AssessmentAdminController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AssessmentAdminController.java`,7 方法)
 - `BeijingNutritionController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/nutrition/BeijingNutritionController.java`,7 方法)
-- `CartController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/cart/CartController.java`,7 方法)
 - `DanAssessmentExecutionController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/dan/DanAssessmentExecutionController.java`,7 方法)
 - `GrowthPlanController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/growth/GrowthPlanController.java`,7 方法)
 - `GuideActivityController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/guide/GuideActivityController.java`,7 方法)
@@ -82,21 +84,18 @@
 - `AdminHomeBannerController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminHomeBannerController.java`,6 方法)
 - `AdminNoticeController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminNoticeController.java`,6 方法)
 - `AdminPeriodicServiceController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminPeriodicServiceController.java`,6 方法)
-- `AdminPromotionTierController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminPromotionTierController.java`,6 方法)
-- `AdminSystemPromptController`(`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminSystemPromptController.java`,6 方法)
-- …(其余 208 个见完整扫描)
+- …(其余 211 个见完整扫描)
 
 ## 三、部分覆盖控制器(已做一部分测试)
 
 > 这些控制器**已有测试但只覆盖了部分handler 方法**——即用户要求的「已经做了一部分测试的情况,要能够找到」。
 
-共 72 个:
+共 69 个:
 
 - `HealthReportController`:覆盖 1/59,未覆盖方法:createReport、getLatestReport、listFamilyReports、listAllReports、getReportIndicatorsWithPrevious、listIndicators、getMemberIndicators、getGutFlora、rebuildIndicatorCurrent、getMemberIndicatorCurrent
 - `HealthKnowledgeBaseController`:覆盖 1/28,未覆盖方法:batchQuery、list、add、update、delete、importKnowledgeBase、queryBacteria、batchQueryBacteria、queryIndicator、queryFood
 - `ProductOrderController`:覆盖 7/19,未覆盖方法:myOrderCounts、vendorConfirm、reviewUpdate、ship、applyRefund、handlePaymentSuccess、notify、activityAudit、activitySignIn、activityComplete
 - `AuthController`:覆盖 14/18,未覆盖方法:setSwitchPassword、verifyToken、ssoTicket、ssoLogin
-- `FamilyUserController`:覆盖 1/17,未覆盖方法:getUserInfo、updateUserInfo、joinFamily、createFamily、switchMode、switchRole、switchToFamilyMember、switchBackToParent、switchBackVerify、createFamilyMember
 - `GuideManagementController`:覆盖 3/17,未覆盖方法:resubmitApplication、getUserApplications、getApplicationRecords、generateInviteCode、getInviteCodes、validateInviteCode、getChildGuides、getAllChildGuides、getParentGuide、getGuidePackageTemplates
 - `MembershipController`:覆盖 4/17,未覆盖方法:getAllLevels、getMyMembership、getUpgradeRecords、upgradeOrder、activateTrial、createOrder、continueOrder、getPricingPlans、getMembershipCompare、paymentNotify
 - `ArticleController`:覆盖 4/16,未覆盖方法:relatedProducts、related、relatedByProduct、getArticleAudio、reportReadingTime、readingStats、dailyTip、aiQuestions、submitAnswers、publish
@@ -109,9 +108,7 @@
 - `StatsController`:覆盖 4/12,未覆盖方法:getDashboardSummary、getRevenueStats、getMembershipStats、childOverview、familySummary、pointsRanking、getTrafficAnalytics、recordProductView
 - `WishController`:覆盖 11/12,未覆盖方法:priceAlias
 - `PaymentController`:覆盖 5/11,未覆盖方法:createWechatNativePay、getPaymentStatus、getOAuth2Url、oauth2Callback、handleV3Notify、generateQrCode
-- `AdminAuthController`:覆盖 2/10,未覆盖方法:sendCode、login、getAdminInfo、changePassword、updateInfo、resetPassword、loginByPassword、accountRoles
 - `AdminVirtualTeamController`:覆盖 1/10,未覆盖方法:list、create、update、toggle、addMember、removeMember、updateMember、userTeams、tree
-- `FamilyMembersController`:覆盖 1/10,未覆盖方法:listMembers、switchToMember、kickMember、leaveFamily、recycleMember、updateMember、renameFamily、checkEditable、logs
 - `GuideFamilyTaskController`:覆盖 8/10,未覆盖方法:unbindFamily、getDashboardStats
 - `SubscriptionController`:覆盖 1/10,未覆盖方法:getPlans、createOrder、subscribe、cancel、setAutoRenew、getMyBenefits、checkBenefit、getTier、updateTier
 - `AIChatController`:覆盖 3/9,未覆盖方法:reportAnalyze、deleteConversation、sendNutritionMessage、sendHealthCoachMessage、sendHealthButlerMessage、transcribe
@@ -119,11 +116,11 @@
 - `EnergyController`:覆盖 5/9,未覆盖方法:configureSourceRatios、getScoreHistory、getFamilyScoreHistory、getWealthDetail
 - `FiveDimensionSelfCheckController`:覆盖 3/9,未覆盖方法:submit、getHistory、ignoreSelfCheck、generatePlan、getTrendAnalysis、aiGenerateQuestions
 - `ProductController`:覆盖 6/9,未覆盖方法:updateImages、specMap、relatedProducts
+- `SupplyTeamController`:覆盖 1/9,未覆盖方法:listCustomers、bindCustomer、getRelation、serviceAssign、serviceTasks、customerServices、updateServiceTask、serviceCandidates
 - `CognitiveController`:覆盖 1/8,未覆盖方法:getChildCognitiveScores、getFamilyCognitiveScores、updateCognitiveScore、getRecommendations、createTaskFromRecommendation、getNorms、submitSelfTest
 - `GuideTeamController`:覆盖 6/8,未覆盖方法:checkStatus、leaveTeam
 - `DoaController`:覆盖 1/7,未覆盖方法:createStage、stageDetail、cancelStage、submitPlan、submitReview、weekList
 - `EmotionCheckinController`:覆盖 2/7,未覆盖方法:create、list、stats、weeklyReport、recognizeEmotion
-- `SupplyTeamController`:覆盖 1/7,未覆盖方法:listCustomers、bindCustomer、getRelation、getInviteCode、getInviteInfo、joinByInviteCode
 - `AdminEnergyConfigController`:覆盖 1/6,未覆盖方法:sourceList、sourceSave、sourceDelete、dailyLimits、dailyLimitSave
 - `AdminGuidePopupController`:覆盖 1/6,未覆盖方法:list、create、update、delete、stats
 - `AdminPlannerExamController`:覆盖 1/6,未覆盖方法:papers、createPaper、updatePaper、deletePaper、saveQuestions
@@ -176,11 +173,11 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfBalanceServiceTest.java` | com | 25 | 0 | 0 | CfBalanceController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/IndicatorChangeServiceTest.java` | com | 23 | 0 | 0 | IndicatorController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/DimensionScoreServiceTest.java` | com | 21 | 0 | 0 | — | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodRecommendServiceTest.java` | com | 21 | 1 | 0 | FoodRecommendController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/GuideRolePermissionTest.java` | com | 21 | 6 | 9 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/GuideFamilyTaskControllerTest.java` | com | 20 | 11 | 8 | GuideFamilyTaskController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/IndicatorChangeServiceSemanticTest.java` | com | 20 | 0 | 0 | IndicatorController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ProductOrderControllerTest.java` | com | 20 | 3 | 7 | ProductOrderController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodRecommendServiceTest.java` | com | 18 | 0 | 0 | FoodRecommendController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/SupplySystemServiceTest.java` | com | 18 | 0 | 0 | SupplySystemController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/AIChatControllerTest.java` | com | 17 | 17 | 3 | AIChatController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/MembershipServiceTest.java` | com | 17 | 0 | 0 | MembershipController | — |
@@ -200,7 +197,6 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodServiceTest.java` | com | 12 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/IndicatorTimelineServiceTest.java` | com | 12 | 24 | 0 | IndicatorController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/PaymentControllerTest.java` | com | 12 | 17 | 5 | PaymentController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminAuthWechatScanTest.java` | com | 11 | 11 | 2 | AdminAuthController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleControllerTest.java` | com | 11 | 7 | 4 | ArticleController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfReferralServiceSalesTierTest.java` | com | 11 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfSpendDispatchServiceTest.java` | com | 11 | 0 | 0 | — | — |
@@ -209,13 +205,12 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/PdfParseServiceTest.java` | com | 11 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/ActivityAdminServiceTest.java` | com | 10 | 9 | 0 | ActivityController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ActivityAuditTest.java` | com | 10 | 4 | 0 | ActivityController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/ComboServiceTest.java` | com | 10 | 3 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/GrowthRecordSyncFlowTest.java` | com | 10 | 9 | 4 | GrowthController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuideHierarchyServiceTest.java` | com | 10 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/HealthPlanReviewGuardTest.java` | com | 10 | 0 | 0 | HealthPlanController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/IndicatorFavoriteControllerTest.java` | com | 10 | 8 | 3 | IndicatorFavoriteController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TrainingPlanControllerGetPlanListTest.java` | com | 10 | 0 | 0 | TrainingPlanController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/common/AdminRolesTest.java` | com | 9 | 0 | 0 | AdminController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/BundlePricingCalculatorTest.java` | com | 9 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FamilyFoodOverviewServiceTest.java` | com | 9 | 9 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/GuideFamilyAccessGuardTest.java` | com | 9 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/GuideTeamControllerTest.java` | com | 9 | 6 | 5 | GuideTeamController | — |
@@ -231,7 +226,6 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/CfBalanceControllerTest.java` | com | 8 | 7 | 3 | CfBalanceController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfEarnDispatchServiceTest.java` | com | 8 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/util/CfFormulaEvaluatorTest.java` | com | 8 | 0 | 0 | — | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/ComboOfferCalculatorTest.java` | com | 8 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/FamilyControllerTest.java` | com | 8 | 1 | 3 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuideApplicationServiceTest.java` | com | 8 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/GuideOrderControllerTest.java` | com | 8 | 11 | 3 | GuideOrderController | — |
@@ -243,10 +237,8 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/config/AttributionStage1FoundationTest.java` | com | 7 | 11 | 0 | AttributionController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/EnergySystemFlowTest.java` | com | 7 | 22 | 5 | EnergyController | skip×1、⚠部分 |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/FamilyMemberDimensionBaseScoreServiceTest.java` | com | 7 | 10 | 0 | FamilyController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerAddMemberTest.java` | com | 7 | 1 | 1 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuideFamilyServiceTest.java` | com | 7 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/orchestration/OrchestrationIntegrationTest.java` | com | 7 | 0 | 0 | OrchestrationController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/SupplyTeamControllerInviteTest.java` | com | 7 | 7 | 0 | SupplyTeamController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/task/TaskCheckinWebhookReminderTaskTest.java` | com | 7 | 0 | 0 | TaskController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/ActivityRegistrationQuotaConcurrencyTest.java` | com | 6 | 0 | 0 | ActivityController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/ActivityServicePublishTest.java` | com | 6 | 0 | 0 | ActivityController | — |
@@ -272,25 +264,23 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ServiceRoleApproveTest.java` | com | 6 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/util/SpearmanUtilTest.java` | com | 6 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/StatsControllerTest.java` | com | 6 | 10 | 2 | StatsController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/util/UserUtilTest.java` | com | 6 | 0 | 0 | UserController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/WithdrawalServiceTest.java` | com | 6 | 0 | 0 | WithdrawalController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/ActivityTagServiceTest.java` | com | 5 | 1 | 0 | ActivityController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/AttributionAdjustServiceTest.java` | com | 5 | 3 | 0 | AttributionController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/CartReplaceComboTest.java` | com | 5 | 0 | 0 | CartController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/BundlePricingServiceTest.java` | com | 5 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfLegacyLedgerWiringTest.java` | com | 5 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CommissionServiceReferralF24Test.java` | com | 5 | 0 | 0 | CommissionController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/DimensionEnergySyncServiceTest.java` | com | 5 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyJoinRequestServiceReferrerBindTest.java` | com | 5 | 0 | 0 | FamilyController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyMemberServiceIsChildTest.java` | com | 5 | 0 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/FamilyNamingSupportTest.java` | com | 5 | 0 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyPlatformPointsServiceCouponTest.java` | com | 5 | 0 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/HealthPlanLazyBackfillTest.java` | com | 5 | 0 | 0 | HealthPlanController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerCreateReportTest.java` | com | 5 | 2 | 0 | HealthReportController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/HealthReportServiceBackfillResilienceTest.java` | com | 5 | 7 | 0 | HealthReportController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/config/JwtInterceptorLoginRequiredTest.java` | com | 5 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/MiniGameServiceTest.java` | com | 5 | 0 | 0 | MiniGameController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/NumSoulCalculatorTest.java` | com | 5 | 0 | 0 | — | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/ProductUpdateClearTest.java` | com | 5 | 0 | 0 | ProductController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/service/ProductOrderComboStockTest.java` | com | 5 | 0 | 0 | ProductController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/ProductSkuComboServiceTest.java` | com | 5 | 0 | 0 | ProductSkuController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/RelationshipQuestionnaireServiceTest.java` | com | 5 | 0 | 0 | RelationshipQuestionnaireController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/TaskServiceMinigameTest.java` | com | 5 | 0 | 0 | TaskController | skip×1、⚠部分 |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/UserServiceEffectiveFamilyIdsTest.java` | com | 5 | 0 | 0 | UserController | — |
@@ -300,7 +290,6 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/ChallengeScoreServiceTest.java` | com | 4 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CommissionDistService410Test.java` | com | 4 | 0 | 0 | CommissionController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/EnergyServiceWealthIncomeTest.java` | com | 4 | 0 | 0 | EnergyController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/FamilyMemberServiceRenameTest.java` | com | 4 | 0 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerListTest.java` | com | 4 | 1 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FortuneServiceTest.java` | com | 4 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/GuideFamilyQueryServiceTest.java` | com | 4 | 4 | 0 | GuideController | — |
@@ -322,16 +311,15 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/service/ArticleAudioServiceChunkFilterTest.java` | com | 3 | 0 | 0 | ArticleController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/ArticleCategoryControllerTest.java` | com | 3 | 0 | 1 | ArticleCategoryController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionSurveyRoutingTest.java` | com | 3 | 5 | 1 | AttributionController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/CartServiceTest.java` | com | 3 | 0 | 0 | CartController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfLegacyLedgerMigrationServiceTest.java` | com | 3 | 0 | 0 | — | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/ComboOrderStockTest.java` | com | 3 | 0 | 0 | — | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/EnergyControllerGrantEnergyTest.java` | com | 3 | 4 | 1 | EnergyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyAdminOverviewServiceTest.java` | com | 3 | 4 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/GuideFamilyServiceBindTest.java` | com | 3 | 0 | 0 | GuideController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/HealthReportServiceIndicatorsTest.java` | com | 3 | 26 | 0 | HealthReportController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/NormalizeIndicatorPipelineTest.java` | com | 3 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/task/OrderTimeoutCancelTaskSpecialDealTest.java` | com | 3 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/PaymentServiceORDRoutingTest.java` | com | 3 | 1 | 0 | PaymentController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/ProductDTOMappingTest.java` | com | 3 | 0 | 0 | ProductController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/ProductOrderServiceTest.java` | com | 3 | 0 | 0 | ProductController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/ProductOrderServiceUpdateExpressFieldTest.java` | com | 3 | 0 | 0 | ProductController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/RepeatTaskGeneratorPassThroughTest.java` | com | 3 | 0 | 0 | — | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/ReportParserAdminControllerTest.java` | com | 3 | 0 | 1 | ReportParserAdminController | — |
@@ -345,13 +333,10 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CfCommissionServiceTest.java` | com | 2 | 0 | 0 | CfCommissionController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/ConsigneeServiceBackfillTest.java` | com | 2 | 0 | 0 | ConsigneeController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/DailyTaskControllerTest.java` | com | 2 | 1 | 1 | DailyTaskController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/DanAssessmentControllerGetActiveMaterialTest.java` | com | 2 | 1 | 0 | DanAssessmentController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/EnergyServiceFamilyTest.java` | com | 2 | 0 | 0 | EnergyController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/service/EnergyServiceGrantEnergyTest.java` | com | 2 | 1 | 0 | EnergyController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerRenameFamilyTest.java` | com | 2 | 1 | 0 | FamilyController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FiveDimensionSelfCheckServiceTest.java` | com | 2 | 0 | 0 | FiveDimensionSelfCheckController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/IndicatorControllerTest.java` | com | 2 | 1 | 1 | IndicatorController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/ProductListNutritionTagFilterTest.java` | com | 2 | 0 | 0 | ProductController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/ProductUpdateClearTest.java` | com | 2 | 0 | 0 | ProductController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/UserAddressServiceBackfillTest.java` | com | 2 | 0 | 0 | UserController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/UserServiceFamilyNameLinkTest.java` | com | 2 | 0 | 0 | UserController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/AiGatewayTimeoutTest.java` | com | 1 | 2 | 0 | — | — |
@@ -360,9 +345,8 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/service/IndicatorCorrelationServiceTest.java` | com | 1 | 0 | 0 | IndicatorController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/IndicatorValueMapperTest.java` | com | 1 | 0 | 0 | IndicatorController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/controller/mind/MindFortuneControllerTest.java` | com | 1 | 1 | 0 | MindFortuneController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/unit/RecommendationNutritionTagTest.java` | com | 1 | 0 | 0 | RecommendController | — |
+| `cfc-backend/src/test/java/com/etotem/cfc/unit/ProductDTOMappingTest.java` | com | 1 | 0 | 0 | ProductController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/ReportSummaryServiceCompletenessTest.java` | com | 1 | 0 | 0 | ReportSummaryController | — |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TeacherMessageControllerMyTest.java` | com | 1 | 1 | 0 | TeacherController | — |
 | `cfc-backend/src/test/java/com/etotem/cfc/common/TestRoles.java` | com | 0 | 0 | 0 | — | — |
 
 ## 五、使用说明

+ 193 - 255
docs/tdd/test/inventory.md

@@ -8,12 +8,12 @@
 
 | 来源类型 | 文件数 | 用例/方法数 |
 | --- | --- | --- |
-| 结构化测试用例(md) | 9 | 729 |
-| Playwright(spec.js) | 70 | 410 |
+| 结构化测试用例(md) | 9 | 678 |
+| Playwright(spec.js) | 70 | 411 |
 | Python(pytest) | 11 | 47 |
-| Java后端(测试文件) | 195 | 1451 (@Test) |
-| 用户场景(md) | 9 | 文件级 |
-| **合计** | — | **2637** 用例/方法 |
+| Java后端(测试文件) | 185 | 1390 (@Test) |
+| 用户场景(md) | 8 | 文件级 |
+| **合计** | — | **2526** 用例/方法 |
 
 ## 二、结构化测试用例(`tests/test-cases/*.md`)
 
@@ -44,29 +44,29 @@
 | `TC-A-21` | 网关/限流 | 运营 | P1 | 功能 | `tests/test-cases/admin.md#TC-A-21` | 网关/限流 | 达成目标:接口防护;边界:误杀白名单 |
 | `TC-A-22` | 模型管理 | 运营 | P1 | 功能 | `tests/test-cases/admin.md#TC-A-22` | 模型管理 | 达成目标:模型版本/开关;边界:下线前回退方案 |
 | `TC-A-23` | 知识库 | 运营 | P1 | 功能 | `tests/test-cases/admin.md#TC-A-23` | 知识库 | 达成目标:维护营养知识;边界:同步失败重试 |
-| `TC-A-01-E` | 认证 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-01-E` | AdminAuthController | 错误密码不签发 token 且提示次数限制/锁定;过期 token 401 跳登录;弱密码 400 拦截 |
-| `TC-A-02-E` | 统计 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-02-E` | StatsController | 超时降级提示非500;无数据显示『暂无数据』;时间非法 400 |
-| `TC-A-03-E` | 方案管理 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-03-E` | 方案管理(全量) | 超时降级非500;非法筛选 400;仅返回有权家庭数据不串 |
-| `TC-A-04-E` | 方案激活 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-04-E` | 方案激活 | 非 reviewed 激活拦截;超时回滚不残半任务;并发幂等仅生成 1 次任务 |
-| `TC-A-05-E` | 报告解析 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-05-E` | AdminReportParserController | 超时降级非500;重复 typeId 400 拒绝;路径非法 400 |
-| `TC-A-06-E` | 报告解析 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-06-E` | 报告类型注册 | 重复 typeId 拒绝;必填缺失 400;threshold 非法 400 |
-| `TC-A-07-E` | 报告解析 | 运营 | P3 | 异常 | `tests/test-cases/admin.md#TC-A-07-E` | 未知聚类自学习 | 超时降级非500;重名类型生成被拒/提示已存在 |
-| `TC-A-08-E` | 文章 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-08-E` | 文章发布-审核 | 同标题 400『标题已存在』;长文提交超时重试不丢稿;注入 400 或转义 |
-| `TC-A-09-E` | 文章·去重 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-09-E` | 文章标题去重 | 重复创建被拦截提示标题已存在;空/超长 400 |
-| `TC-A-10-E` | 关系类型 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-10-E` | 关系类型 CRUD | 重名拒绝;停用被引用类型提示先解绑;注入 400/转义;家长端选择器同步生效仍正确 |
-| `TC-A-11-E` | 勋章 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-11-E` | 勋章管理;黑盒回归 | 重复 400/幂等;非法门槛 400;并发创建各自独立不串 |
-| `TC-A-12-E` | 供应商 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-12-E` | 供应商管理;黑盒回归 | 同手机号拒绝/可控覆盖;非法格式 400;必填缺失 400;列表 name=昵称正确 |
-| `TC-A-13-E` | 活动 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-13-E` | 活动审核撤回;黑盒回归 | 已发布再提交审核守卫拦截;非本人撤回 403;时间冲突 400;撤回退回草稿 |
-| `TC-A-14-E` | 知识库 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-14-E` | 知识库管理;黑盒回归 | 被引用删除提示先解绑;不存在 404;并发删除幂等 |
-| `TC-A-15-E` | 数据迁移 | 运营 | P3 | 异常 | `tests/test-cases/admin.md#TC-A-15-E` | 多数据源/SfmsDataSourceConfig | 中断回滚+明确错误非500;锁等待超时提示;重复执行幂等/提示已迁移 |
-| `TC-A-16-E` | 参数校验 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-16-E` | 统一 `Result<T>`+全局异常;黑盒回归 | 空 body 400 含具体字段提示;类型错配 400;超长 400;不再裸 500 |
-| `TC-A-17-E` | /api/admin/report-parser/* | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-17-E` | /api/admin/report-parser/* | 重名类目拒绝;未注册路径 400;先注册再解析 |
-| `TC-A-18-E` | 优惠券/活动管理 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-18-E` | 优惠券/活动管理 | 时间冲突 400;名额超卖配置保护生效;重复提交幂等 |
-| `TC-A-19-E` | 内容安全 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-19-E` | 内容安全 | 超时降级非500;命中敏感词强制拦截不放行 |
-| `TC-A-20-E` | GDPR 工单 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-20-E` | GDPR 工单 | 并发安全:注销与导出按序执行不冲突;越权工单 403 |
-| `TC-A-21-E` | 网关/限流 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-21-E` | 网关/限流 | 白名单不被限流;非法阈值 400;规则生效可控 |
-| `TC-A-22-E` | 模型管理 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-22-E` | 模型管理 | 无回退方案拦截下线;非法版本 400;上下线版控正确 |
-| `TC-A-23-E` | 知识库 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-23-E` | 知识库 | 同步失败自动重试非500;并发 CRUD 乐观锁不互相覆盖 |
+| `TC-A-01-E` | 认证 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-01-E` | AdminAuthController | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-A-02-E` | 统计 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-02-E` | StatsController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-A-03-E` | 方案管理 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-03-E` | 方案管理(全量) | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-A-04-E` | 方案激活 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-04-E` | 方案激活 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-A-05-E` | 报告解析 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-05-E` | AdminReportParserController | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-A-06-E` | 报告解析 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-06-E` | 报告类型注册 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-A-07-E` | 报告解析 | 运营 | P3 | 异常 | `tests/test-cases/admin.md#TC-A-07-E` | 未知聚类自学习 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-A-08-E` | 文章 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-08-E` | 文章发布-审核 | 标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认 |
+| `TC-A-09-E` | 文章·去重 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-09-E` | 文章标题去重 | 标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认 |
+| `TC-A-10-E` | 关系类型 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-10-E` | 关系类型 CRUD | 标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认 |
+| `TC-A-11-E` | 勋章 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-11-E` | 勋章管理;黑盒回归 | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-A-12-E` | 供应商 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-12-E` | 供应商管理;黑盒回归 | 标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认 |
+| `TC-A-13-E` | 活动 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-13-E` | 活动审核撤回;黑盒回归 | 标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认 |
+| `TC-A-14-E` | 知识库 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-14-E` | 知识库管理;黑盒回归 | 标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认 |
+| `TC-A-15-E` | 数据迁移 | 运营 | P3 | 异常 | `tests/test-cases/admin.md#TC-A-15-E` | 多数据源/SfmsDataSourceConfig | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-A-16-E` | 参数校验 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-16-E` | 统一 `Result<T>`+全局异常;黑盒回归 | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-A-17-E` | /api/admin/report-parser/* | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-17-E` | /api/admin/report-parser/* | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-A-18-E` | 优惠券/活动管理 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-18-E` | 优惠券/活动管理 | 支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确 |
+| `TC-A-19-E` | 内容安全 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-19-E` | 内容安全 | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-A-20-E` | GDPR 工单 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-20-E` | GDPR 工单 | 并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规 |
+| `TC-A-21-E` | 网关/限流 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-21-E` | 网关/限流 | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-A-22-E` | 模型管理 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-22-E` | 模型管理 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-A-23-E` | 知识库 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-23-E` | 知识库 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
 | `TC-A-01-P` | 认证 | 运营 | P1 | 权限 | `tests/test-cases/admin.md#TC-A-01-P` | AdminAuthController | 非 admin 角色访问管理端接口统一 401/403,不泄露后台数据 |
 | `TC-A-02-P` | 统计 | 运营 | P1 | 权限 | `tests/test-cases/admin.md#TC-A-02-P` | StatsController | 非 admin 角色访问管理端接口统一 401/403,不泄露后台数据 |
 | `TC-A-03-P` | 方案管理 | 运营 | P1 | 权限 | `tests/test-cases/admin.md#TC-A-03-P` | 方案管理(全量) | 非 admin 角色访问管理端接口统一 401/403,不泄露后台数据 |
@@ -90,12 +90,6 @@
 | `TC-A-21-P` | 网关/限流 | 运营 | P1 | 权限 | `tests/test-cases/admin.md#TC-A-21-P` | 网关/限流 | 非 admin 角色访问统一 401/403,不泄露后台数据 |
 | `TC-A-22-P` | 模型管理 | 运营 | P1 | 权限 | `tests/test-cases/admin.md#TC-A-22-P` | 模型管理 | 非 admin 角色访问统一 401/403,不泄露后台数据 |
 | `TC-A-23-P` | 知识库 | 运营 | P1 | 权限 | `tests/test-cases/admin.md#TC-A-23-P` | 知识库 | 非 admin 角色访问统一 401/403,不泄露后台数据 |
-| `TC-A-25` | 维度/权重/上限配置 | 运营 | P1 | 功能 | `tests/test-cases/admin.md#TC-A-25` | DimensionConfigController`/`DimensionWeightController | 变更生效、后续能量按新配置;存量影响提示 |
-| `TC-A-26` | 能量/归因权重 | 运营 | P1 | 功能 | `tests/test-cases/admin.md#TC-A-26` | EnergyController`/`AttributionWeights | 全局生效;变更写审计;概览/沙盘/天盘影响可观测 |
-| `TC-A-25-E` | 维度/权重/上限配置 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-25-E` | DimensionConfigController | 1. 需确认/拒、不级联破坏存量 2. 400 拦截 3. 乐观锁/版本控制不互相覆盖 |
-| `TC-A-26-E` | 能量/归因权重 | 运营 | P2 | 异常 | `tests/test-cases/admin.md#TC-A-26-E` | EnergyController`/`AttributionWeights | 1. 400 拦截 2. 展示兜底并提示、不静默错算 |
-| `TC-A-25-P` | 维度/权重/上限配置 | 运营 | P1 | 权限 | `tests/test-cases/admin.md#TC-A-25-P` | DimensionConfigController | 非 admin 操作 403 |
-| `TC-A-26-P` | 能量/归因权重 | 运营 | P1 | 权限 | `tests/test-cases/admin.md#TC-A-26-P` | EnergyController | 非 admin 改全局 403 |
 | `TC-A-N01` | 配置CRUD | 运营 | P1 | 性能 | `tests/test-cases/admin.md#TC-A-N01` | 配置管理 | 列表 ≤ 2s;CRUD 即时生效 |
 | `TC-A-N02` | 报告解析中台 | 运营 | P0 | 性能 | `tests/test-cases/admin.md#TC-A-N02` | 解析中台 | 单条 ≤ 30s;失败进未知聚类;监控可见积压 |
 | `TC-A-N03` | 登录统计 | 运营 | P1 | 性能 | `tests/test-cases/admin.md#TC-A-N03` | 统计聚合 | 聚合 ≤ 3s;支持分页/缓存;大数据不超时 |
@@ -128,29 +122,29 @@
 | `TC-C-21` | 舌诊情绪识别 | 孩子 | P1 | 功能 | `tests/test-cases/child.md#TC-C-21` | 舌诊情绪识别 | 达成目标:拍照上传;边界:模糊/非照片拒绝;隐私标注 |
 | `TC-C-22` | MallController | 孩子 | P1 | 功能 | `tests/test-cases/child.md#TC-C-22` | MallController | 达成目标:用积分换;边界:积分不足拦截;重复兑换幂等 |
 | `TC-C-23` | 客服 | 孩子 | P1 | 功能 | `tests/test-cases/child.md#TC-C-23` | 客服 | 达成目标:提反馈;边界:内容适龄过滤;敏感信息脱敏 |
-| `TC-C-01-E` | 权限/双角色 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-01-E` | 双角色铁律:孩子端不能切家长 | 缺失/过期 token 统一 401 跳登录;切换/家长路由被 role 校验 403 拦截;孩子端无任何切回家长入口;模拟登录仅测试环境生效 |
-| `TC-C-02-E` | 任务 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-02-E` | TaskController | 并发双点幂等仅计 1 次、仅 1 条流水;超期提交被拒;驳回→重做→再提交仅在重做后计 1 次 |
-| `TC-C-03-E` | 小游戏 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-03-E` | pages/games/* | 异常分数 400 不计入;断网不计分不卡死;重复上报幂等不重复入榜 |
-| `TC-C-04-E` | 心愿 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-04-E` | WishController | 余额不足创建拦截;超长/注入 400 校验;重复创建提示已存在不双建 |
-| `TC-C-05-E` | 心愿 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-05-E` | RewardController | 余额不足拦截且不扣负;已驳回提示不可兑换;并发幂等仅扣 1 次 |
-| `TC-C-06-E` | 能量 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-06-E` | EnergyController | 超时降级空态提示非 500;权重 0 占比兜底(0%)显示不崩;能量不为负 |
-| `TC-C-07-E` | 报告/权限 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-07-E` | 报告查看权限隔离 | 删除/编辑被 role 校验 403 拒绝;孩子端 UI 无编辑/删除入口;报告内容不被改动 |
-| `TC-C-08-E` | 打卡/方案 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-08-E` | 健康打卡/方案进度 | 超时回滚不残半任务、进度不 +1;重复打卡幂等不重复计数;非本人任务 403 |
-| `TC-C-09-E` | 勋章 | 孩子 | P3 | 异常 | `tests/test-cases/child.md#TC-C-09-E` | RewardController | 重复达成不重复发推送/勋章;未达成领取 400/403 拒绝 |
-| `TC-C-10-E` | 勋章提醒 | 孩子 | P3 | 异常 | `tests/test-cases/child.md#TC-C-10-E` | MedalController | 重复达成幂等仅 1 次推送;数据缺失降级不推送不 500 |
-| `TC-C-11-E` | 成长记录 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-11-E` | GrowthController | 关联已删项跳过不报错;其他成员数据 403 不可见 |
-| `TC-C-12-E` | 食谱查看 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-12-E` | 饮食推荐 | 超时 Fallback 通用食谱+提示非 500;无食谱空态不 500 |
-| `TC-C-13-E` | AI 对话 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-13-E` | AIChatController | 不适龄/敏感词被过滤返回适龄话术;LangGraph 不可用 Fallback 兜底、多轮连续 |
-| `TC-C-14-E` | 任务重做 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-14-E` | TaskController | 非驳回态重做入口不可见/拦截;重做提交进入待审核仅计 1 次 |
-| `TC-C-15-E` | 消息接收 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-15-E` | 消息服务 | 越权消息 403 不可见;不存在 404;列表分页正常 |
-| `TC-C-16-E` | 个人资料 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-16-E` | AuthController | 代管字段 403 不可改;昵称注入/超长 400 校验 |
-| `TC-C-17-E` | 退出 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-17-E` | AuthController | 旧 token 失效 401;网络中断退出仍清本地缓存、下次需重登 |
-| `TC-C-18-E` | 设备校验 | 孩子 | P3 | 异常 | `tests/test-cases/child.md#TC-C-18-E` | AuthController | 异常设备二次验证/拦截;旧设备 token 失效 401 |
-| `TC-C-19-E` | 消息服务 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-19-E` | 消息服务 | 不存在 404;越权标记 403 不生效 |
-| `TC-C-20-E` | GrowthController | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-20-E` | GrowthController | 未成年导出 403 需家长代办;他人档案 403 不可见 |
-| `TC-C-21-E` | 舌诊情绪识别 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-21-E` | 舌诊情绪识别 | 非照片/模糊拒绝提示『请上传清晰舌苔照』;低置信度提示重拍;隐私标注不外露 |
-| `TC-C-22-E` | MallController | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-22-E` | MallController | 余额不足拦截不扣负;并发仅 1 次成功;重复兑换幂等仅 1 条 |
-| `TC-C-23-E` | 客服 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-23-E` | 客服 | 敏感信息脱敏存储;附件超限 400『附件不超过 10MB』 |
+| `TC-C-01-E` | 权限/双角色 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-01-E` | 双角色铁律:孩子端不能切家长 | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-C-02-E` | 任务 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-02-E` | TaskController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-C-03-E` | 小游戏 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-03-E` | pages/games/* | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-C-04-E` | 心愿 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-04-E` | WishController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-C-05-E` | 心愿 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-05-E` | RewardController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-C-06-E` | 能量 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-06-E` | EnergyController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-C-07-E` | 报告/权限 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-07-E` | 报告查看权限隔离 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-C-08-E` | 打卡/方案 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-08-E` | 健康打卡/方案进度 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-C-09-E` | 勋章 | 孩子 | P3 | 异常 | `tests/test-cases/child.md#TC-C-09-E` | RewardController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-C-10-E` | 勋章提醒 | 孩子 | P3 | 异常 | `tests/test-cases/child.md#TC-C-10-E` | MedalController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-C-11-E` | 成长记录 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-11-E` | GrowthController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-C-12-E` | 食谱查看 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-12-E` | 饮食推荐 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-C-13-E` | AI 对话 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-13-E` | AIChatController | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-C-14-E` | 任务重做 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-14-E` | TaskController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-C-15-E` | 消息接收 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-15-E` | 消息服务 | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-C-16-E` | 个人资料 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-16-E` | AuthController | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-C-17-E` | 退出 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-17-E` | AuthController | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-C-18-E` | 设备校验 | 孩子 | P3 | 异常 | `tests/test-cases/child.md#TC-C-18-E` | AuthController | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-C-19-E` | 消息服务 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-19-E` | 消息服务 | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-C-20-E` | GrowthController | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-20-E` | GrowthController | 并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规 |
+| `TC-C-21-E` | 舌诊情绪识别 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-21-E` | 舌诊情绪识别 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-C-22-E` | MallController | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-22-E` | MallController | 支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确 |
+| `TC-C-23-E` | 客服 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-23-E` | 客服 | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
 | `TC-C-01-P` | 权限/双角色 | 孩子 | P1 | 权限 | `tests/test-cases/child.md#TC-C-01-P` | 双角色铁律:孩子端不能切家长 | 孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据 |
 | `TC-C-02-P` | 任务 | 孩子 | P1 | 权限 | `tests/test-cases/child.md#TC-C-02-P` | TaskController | 孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据 |
 | `TC-C-03-P` | 小游戏 | 孩子 | P1 | 权限 | `tests/test-cases/child.md#TC-C-03-P` | pages/games/* | 孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据 |
@@ -174,12 +168,6 @@
 | `TC-C-21-P` | 舌诊情绪识别 | 孩子 | P1 | 权限 | `tests/test-cases/child.md#TC-C-21-P` | 舌诊情绪识别 | 孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据 |
 | `TC-C-22-P` | MallController | 孩子 | P1 | 权限 | `tests/test-cases/child.md#TC-C-22-P` | MallController | 孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据 |
 | `TC-C-23-P` | 客服 | 孩子 | P1 | 权限 | `tests/test-cases/child.md#TC-C-23-P` | 客服 | 孩子端无编辑/删除/切家长入口;直接调用被 role 校验拒绝(403/401),不越权操作家庭数据 |
-| `TC-C-24` | 能量/小游戏·任务 | 孩子 | P1 | 功能 | `tests/test-cases/child.md#TC-C-24` | GameRecordService`/`TaskController | 对应维度 +amount、sourceType=game/task;B 自身能量页看到增长与流水 |
-| `TC-C-25` | 能量/方案打卡 | 孩子 | P1 | 功能 | `tests/test-cases/child.md#TC-C-25` | GrowthTaskService | GrowthTaskService 打卡对应维度+;任务进度与能量同步刷新 |
-| `TC-C-24-E` | 能量/小游戏·任务 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-24-E` | GameRecordService | 1. 异常分数拦截不写能量 2. 重复上报幂等不重复加 |
-| `TC-C-25-E` | 能量/方案打卡 | 孩子 | P2 | 异常 | `tests/test-cases/child.md#TC-C-25-E` | GrowthTaskService | 1. 按业务允/拒、断言一致 2. 重复打卡幂等不重复加 3. 并发不重复计分 |
-| `TC-C-24-P` | 能量/小游戏·任务 | 孩子 | P1 | 权限 | `tests/test-cases/child.md#TC-C-24-P` | JwtInterceptor`+role | 1. 他人能量 403 2. 孩子端无编辑/扣减入口、直接调被拒 |
-| `TC-C-25-P` | 能量/方案打卡 | 孩子 | P1 | 权限 | `tests/test-cases/child.md#TC-C-25-P` | GrowthTaskService | 1. 非本人方案任务 403 2. 他人进度不可见 |
 | `TC-C-N01` | 任务打卡 | 孩子 | P1 | 性能 | `tests/test-cases/child.md#TC-C-N01` | TaskController | 重复提交幂等;并发不重复计分;响应 ≤ 1s |
 | `TC-C-N02` | 消息通知 | 孩子 | P2 | 性能 | `tests/test-cases/child.md#TC-C-N02` | 消息中心 | 列表渲染 ≤ 1.5s;标记已读即时 |
 | `TC-C-N03` | 孩子端 | 孩子 | P1 | 兼容 | `tests/test-cases/child.md#TC-C-N03` | 孩子端 | 功能一致;无错位;低龄设备流畅 |
@@ -241,15 +229,6 @@
 | `TC-X-16-P` | 跨角色 | P0 | 权限 | 已登录(默认 跨角色);相关前置数据就绪 | `tests/test-cases/cross-role-e2e.md#TC-X-16-P` | - | X-16 |
 | `TC-X-17-P` | 跨角色 | P1 | 权限 | 已登录(默认 跨角色);相关前置数据就绪 | `tests/test-cases/cross-role-e2e.md#TC-X-17-P` | - | X-17 |
 | `TC-X-18-P` | 跨角色 | P1 | 权限 | 已登录(默认 跨角色);相关前置数据就绪 | `tests/test-cases/cross-role-e2e.md#TC-X-18-P` | - | X-18 |
-| `TC-X-19` | 跨角色 | P0 | 功能 | 家庭1(A+B+C)、绑定家庭 F2(T)、无关家庭 F9 | `tests/test-cases/cross-role-e2e.md#TC-X-19` | - | X-19 |
-| `TC-X-20` | 跨角色 | P0 | 功能 | 成员 B 混合来源流水(任务/打卡/心愿扣减/手动) | `tests/test-cases/cross-role-e2e.md#TC-X-20` | - | X-20 |
-| `TC-X-21` | 跨角色 | P0 | 功能 | B 某维度当日未触顶;多触发同时到达 | `tests/test-cases/cross-role-e2e.md#TC-X-21` | - | X-21 |
-| `TC-X-19-E` | 跨角色 | P1 | 异常 | 家庭1 / F2 / F9 | `tests/test-cases/cross-role-e2e.md#TC-X-19-E` | - | X-19 |
-| `TC-X-20-E` | 跨角色 | P1 | 异常 | B 混合流水 + 造"不一致断点""负流水无对应" | `tests/test-cases/cross-role-e2e.md#TC-X-20-E` | - | X-20 |
-| `TC-X-21-E` | 跨角色 | P1 | 异常 | B 维度当日接近上限 | `tests/test-cases/cross-role-e2e.md#TC-X-21-E` | - | X-21 |
-| `TC-X-19-P` | 跨角色 | P0 | 权限 | 家庭1 / F2 / F9 | `tests/test-cases/cross-role-e2e.md#TC-X-19-P` | - | X-19 |
-| `TC-X-20-P` | 跨角色 | P1 | 权限 | 家庭1 + F9 | `tests/test-cases/cross-role-e2e.md#TC-X-20-P` | - | X-20 |
-| `TC-X-21-P` | 跨角色 | P1 | 权限 | 家庭1 + F9 | `tests/test-cases/cross-role-e2e.md#TC-X-21-P` | - | X-21 |
 | `TC-X-N01` | 跨角色 | P0 | 性能 | 多家庭并发(≥10 家庭) | `tests/test-cases/cross-role-e2e.md#TC-X-N01` | - | X-01 |
 | `TC-X-N02` | 跨角色 | P0 | 性能 | 多家庭同时生成方案 | `tests/test-cases/cross-role-e2e.md#TC-X-N02` | - | X-03 |
 | `TC-X-N03` | 跨角色 | P0 | 性能 | 活动名额 100,瞬时 500 请求 | `tests/test-cases/cross-role-e2e.md#TC-X-N03` | - | X-15 |
@@ -276,7 +255,7 @@
 | `TC-PA-06` | 拆任务/数据 | 规划师 | P2 | 数据 | `tests/test-cases/deep-dive-plan-activation.md#TC-PA-06` | G4 | 非当天过期(待确认设计) |
 | `TC-G-01` | 启动/首页 | 游客 | P1 | 功能 | `tests/test-cases/guest.md#TC-G-01` | JwtInterceptor 拦截 `/api/** | 显示引流首页,不进入任何业务页;明显展示微信/手机号/邀请登录入口 |
 | `TC-G-02` | 认证 | 游客 | P0 | 接口 | `tests/test-cases/guest.md#TC-G-02` | AuthController`/`API_REFERENCE` 1.1 | 返回 Result 含 token+用户信息;角色默认 parent;跳转家长首页;首次登录建 User+family_members(memberType=login) |
-| `TC-G-03` | 认证 | 游客 | P2 | 接口 | `tests/test-cases/guest.md#TC-G-03` | 统一 POST/JWT | 验证码正确→登录下发 token;错误→提示失败且**不产生会话**;限流生效 ⚠ **API 兼容保留**:小程序端无入口(登录走 SC-G-02),2026-11-01 口径 |
+| `TC-G-03` | 认证 | 游客 | P0 | 接口 | `tests/test-cases/guest.md#TC-G-03` | 统一 POST/JWT | 验证码正确→登录下发 token;错误→提示失败且**不产生会话**;限流生效 |
 | `TC-G-04` | 家庭/邀请 | 游客 | P1 | 功能 | `tests/test-cases/guest.md#TC-G-04` | FamilyInviteController | 登录后自动归属对应家庭,成员列表出现该用户;令牌失效→「邀请已失效」 |
 | `TC-G-05` | 权限 | 游客 | P0 | 权限 | `tests/test-cases/guest.md#TC-G-05` | JWT;8 公开路径白名单(1.1) | 业务页→401 跳登录,登录后回跳;商城/文章列表可见(公开);需登录详情被拦截 |
 | `TC-G-06` | 权限 | 游客 | P0 | 权限 | `tests/test-cases/guest.md#TC-G-06` | JwtInterceptor | JwtInterceptor 拦截(8 个公开路径除外);缺 token→401/403,不泄露内部错误堆栈 |
@@ -286,18 +265,18 @@
 | `TC-G-10` | 注册 | 游客 | P1 | 功能 | `tests/test-cases/guest.md#TC-G-10` | AuthController | 引导至注册;已注册账号不重复建档 |
 | `TC-G-11` | 协议页/AgreementController | 游客 | P2 | 功能 | `tests/test-cases/guest.md#TC-G-11` | 协议页/AgreementController | 达成目标:合规告知;边界:未同意不可进入注册/核心流程 |
 | `TC-G-12` | config.js | 游客 | P2 | 功能 | `tests/test-cases/guest.md#TC-G-12` | config.js | 达成目标:非微信浏览器打开小程序链接;边界:探测失败给出明确引导 |
-| `TC-G-01-E` | 启动/首页 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-01-E` | JwtInterceptor 拦截 `/api/** | 1. 不白屏、提供"稍后"/手机号登录兜底 2. 超时给重试而非 500;不泄露内部堆栈 |
-| `TC-G-02-E` | 认证 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-02-E` | AuthController`/`API_REFERENCE` 1.1 | 1. 回退手机号登录、停留登录页不报错 2. 返回已有账号不重复建号 3. 超时提示重试、不建脏号 |
-| `TC-G-03-E` | 认证 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-03-E` | 统一 POST/JWT | 1. 提示失败且不签发 token 2. 格式校验 400 拦截 3. 限流提示"操作频繁" 4. 绝不产生会话 |
-| `TC-G-04-E` | 家庭/邀请 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-04-E` | FamilyInviteController | 1. 拒绝并提示"邀请已失效" 2. 按业务规则处理(加入或被拒)、不串家庭 |
-| `TC-G-05-E` | 权限 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-05-E` | JWT;8 公开路径白名单(1.1) | 1. 统一 401 跳登录;登录后回跳 2. 重定向登录;仅 8 公开路径放行 |
-| `TC-G-06-E` | 权限 | 游客 | P1 | 异常 | `tests/test-cases/guest.md#TC-G-06-E` | JwtInterceptor | 1. 统一 401/403、不泄露内部错误与结构 2. 公开路径正常返回、不误拦 |
-| `TC-G-07-E` | 测试模式 | 游客 | P3 | 异常 | `tests/test-cases/guest.md#TC-G-07-E` | AGENTS.md 测试模式 | 1. 生产强制真授权、模拟登录被拒 2. 测试模式仅测试环境生效、不污染生产数据 |
-| `TC-G-08-E` | 环境切换 | 游客 | P3 | 异常 | `tests/test-cases/guest.md#TC-G-08-E` | config.js | 1. 回退默认 API 地址、功能可用 2. 不因识别失败崩溃/错连 |
-| `TC-G-09-E` | 认证 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-09-E` | AuthController | 1. 退出后接口 401、需重登 2. 本地 token/隐私数据已清除 |
-| `TC-G-10-E` | 注册 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-10-E` | AuthController | 1. 明确"未注册"并引导注册 2. 已注册不重复建档、直接登录 |
-| `TC-G-11-E` | 协议页 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-11-E` | 协议页/AgreementController | 1. 拦截并强制先同意 2. 加载失败给重试、不绕过同意 |
-| `TC-G-12-E` | config.js | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-12-E` | config.js | 1. 给出"在微信内打开"明确引导 2. 降级静态页、核心流程可手机号兜底 |
+| `TC-G-01-E` | 启动/首页 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-01-E` | JwtInterceptor 拦截 `/api/** | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-G-02-E` | 认证 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-02-E` | AuthController`/`API_REFERENCE` 1.1 | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-G-03-E` | 认证 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-03-E` | 统一 POST/JWT | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-G-04-E` | 家庭/邀请 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-04-E` | FamilyInviteController | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-G-05-E` | 权限 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-05-E` | JWT;8 公开路径白名单(1.1) | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-G-06-E` | 权限 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-06-E` | JwtInterceptor | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-G-07-E` | 测试模式 | 游客 | P3 | 异常 | `tests/test-cases/guest.md#TC-G-07-E` | AGENTS.md 测试模式 | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-G-08-E` | 环境切换 | 游客 | P3 | 异常 | `tests/test-cases/guest.md#TC-G-08-E` | config.js | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-G-09-E` | 认证 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-09-E` | AuthController | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-G-10-E` | 注册 | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-10-E` | AuthController | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-G-11-E` | 协议页/AgreementController | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-11-E` | 协议页/AgreementController | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-G-12-E` | config.js | 游客 | P2 | 异常 | `tests/test-cases/guest.md#TC-G-12-E` | config.js | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
 | `TC-G-01-P` | 启动/首页 | 游客 | P1 | 权限 | `tests/test-cases/guest.md#TC-G-01-P` | JwtInterceptor 拦截 `/api/** | 非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒 |
 | `TC-G-02-P` | 认证 | 游客 | P1 | 权限 | `tests/test-cases/guest.md#TC-G-02-P` | AuthController`/`API_REFERENCE` 1.1 | 非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒 |
 | `TC-G-03-P` | 认证 | 游客 | P1 | 权限 | `tests/test-cases/guest.md#TC-G-03-P` | 统一 POST/JWT | 非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒 |
@@ -311,7 +290,7 @@
 | `TC-G-11-P` | 协议页/AgreementController | 游客 | P2 | 权限 | `tests/test-cases/guest.md#TC-G-11-P` | 协议页/AgreementController | 统一 401/403,不泄露内部错误与数据;8 个公开路径除外 |
 | `TC-G-12-P` | config.js | 游客 | P2 | 权限 | `tests/test-cases/guest.md#TC-G-12-P` | config.js | 统一 401/403,不泄露内部错误与数据;8 个公开路径除外 |
 | `TC-G-N01` | 落地页 | 游客 | P2 | 性能 | `tests/test-cases/guest.md#TC-G-N01` | 落地页/邀请 | 首屏 ≤ 3s;骨架屏生效;CDN 资源命中;无白屏 |
-| `TC-G-N02` | 浏览转化 | 游客 | P2 | 兼容 | `tests/test-cases/guest.md#TC-G-N02` | 登录注册(微信授权) | 布局一致;微信授权正常;兜底登录可用;无错位 |
+| `TC-G-N02` | 浏览转化 | 游客 | P2 | 兼容 | `tests/test-cases/guest.md#TC-G-N02` | 登录注册 | 布局一致;微信授权正常;兜底登录可用;无错位 |
 | `TC-G-N03` | 非微信H5 | 游客 | P2 | 兼容 | `tests/test-cases/guest.md#TC-G-N03` | H5 兜底 | 功能可用;无微信 SDK 依赖报错;流程闭环 |
 | `TC-G-N04` | 落地页 | 游客 | P0 | 安全 | `tests/test-cases/guest.md#TC-G-N04` | 接口鉴权 | 返回 401;不泄露数据与结构 |
 | `TC-G-N05` | 登录注册 | 游客 | P0 | 安全 | `tests/test-cases/guest.md#TC-G-N05` | 登录限流 | 触发限流/锁定;验证码一次性;防爆破;无撞库成功 |
@@ -401,92 +380,92 @@
 | `TC-P-84` | 分享 | 家长 | P1 | 功能 | `tests/test-cases/parent.md#TC-P-84` | 分享 | 达成目标:共享;边界:链接失效/权限校验;越权分享被拒 |
 | `TC-P-85` | AuthController | 家长 | P1 | 功能 | `tests/test-cases/parent.md#TC-P-85` | AuthController | 达成目标:同账号多设备;边界:异常设备风控;退出清 token |
 | `TC-P-86` | 勋章/排行 | 家长 | P1 | 功能 | `tests/test-cases/parent.md#TC-P-86` | 勋章/排行 | 达成目标:激励;边界:数据仅本家庭可见;排名实时性 |
-| `TC-P-01-E` | 家庭 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-01-E` | FamilyInviteController | 名称空或超长返回 400 且 message 含『家庭名称』校验项;HTML/SQL 注入被转义,库内不落恶意串;不抛 500、不泄露堆栈 |
-| `TC-P-02-E` | 家庭/成员 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-02-E` | FamilyInviteController | 非法手机号 400 提示格式;已占用账号提示『已存在家庭关系』;过期码提示『邀请已失效,请重新获取』;均不建立成员关系 |
-| `TC-P-03-E` | 成员资料 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-03-E` | FamilyMembersController | 未来生日 400;关系非法值拒绝;姓名特殊字符转义存储、不破坏查询;既有成员数据不被污染 |
-| `TC-P-04-E` | 关系图 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-04-E` | 关系类型 CRUD/前端选择器 | 重复关系提示已存在、不新增节点;非法枚举 400;关系图不出现重复/幽灵节点 |
-| `TC-P-05-E` | 任务 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-05-E` | TaskController | 频率非法 400;并发双发幂等,仅生成 1 条任务、仅 1 次能量预期;超期任务拒绝提交 |
-| `TC-P-06-E` | 任务审核 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-06-E` | TaskController`/`PointsController | 重复审批幂等不双计积分;驳回→重做→再审批仅在重做后计 1 次;超期任务审批被拒 |
-| `TC-P-07-E` | 心愿 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-07-E` | WishController`/`RewardController | 余额不足拦截且不扣负积分;已取消心愿兑换提示失效;并发幂等仅扣 1 次 |
-| `TC-P-08-E` | 能量 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-08-E` | EnergyController | 查询超时降级为空态提示非 500;权重为 0 时占比按兜底(0%)显示不崩;首访空态正常 |
-| `TC-P-09-E` | 测评订单 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-09-E` | AssessmentAppointmentController | 回调验签失败订单保持 pending 不进待安排;余额不足回滚;重复回调幂等仅落 1 次已支付 |
-| `TC-P-10-E` | 健康报告 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-10-E` | 健康报告上传解析 | 损坏文件识别失败进未知聚类并提示;非募极明确提示『请确认是募极生物肠道菌群报告』;超大/加密提示超限或密码保护,均非 500 |
-| `TC-P-11-E` | 报告查看 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-11-E` | 报告解析 | 不存在/已删返回 404 提示『报告不存在』;解析中提示『报告解析中,请稍候』,不白屏不 500 |
-| `TC-P-12-E` | 饮食推荐 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-12-E` | 饮食推荐系统 | AiGateway Fallback 返回兜底食材清单+友好提示非 500;重复点击幂等仅生成 1 份、不重复扣费 |
-| `TC-P-13-E` | AI 方案 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-13-E` | AI 统一走 LangGraph;`AiGateway | Fallback 兜底方案+提示;未购会员请求付费板块返回『请先开通会员』拦截,不白生成 |
-| `TC-P-14-E` | 方案提交 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-14-E` | 方案状态机 | 空方案提交拦截提示『方案未生成』;重复提交幂等不重复进审核 |
-| `TC-P-15-E` | 双角色 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-15-E` | POST /api/family/member/switch`(替代废弃 switch-mode);双角色铁律 | 缺失/过期 token 统一 401 跳登录;孩子端无切回家长入口;非法切换 403 被拒;模拟登录仅测试环境生效 |
-| `TC-P-16-E` | 会员 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-16-E` | MembershipController`/`ProductOrderController | 支付超时订单回滚不解锁权益;重复购买幂等仅开通 1 次、不重复扣费 |
-| `TC-P-17-E` | 积分/成长 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-17-E` | PointsController`/`GrowthController | 并发刷新总量一致不重复计;关联任务已删时该成长项跳过不报错,时间格式 yyyy-MM-dd HH:mm:ss |
-| `TC-P-18-E` | AI 对话 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-18-E` | AIChatController`;LangGraph RAG | 超长消息 400 提示;敏感词按合规拦截;LangGraph 不可用 Fallback 兜底回答,多轮上下文不丢 |
-| `TC-P-19-E` | 能量配置 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-19-E` | 维度配置 | 配置缺失展示兜底说明非 500;权重和非法 400 提示『权重合计需为 100%』 |
-| `TC-P-20-E` | 健康报告 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-20-E` | 报告解析中台/`POST /api/media/upload | 损坏文件识别失败进未知聚类并提示;非募极明确提示『请确认是募极生物肠道菌群报告』;超大/加密提示超限或密码保护,均非 500 |
-| `TC-P-21-E` | 报告解析 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-21-E` | /api/admin/report-parser/types | 未注册类型进未知聚类待运营自学习;0 字节文件提示『文件为空』;均非 500 |
-| `TC-P-22-E` | 报告预览 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-22-E` | 解析中台 | 异常值提示『数据异常,暂不入库』不入库;超时提示解析中,不白屏 |
-| `TC-P-23-E` | 报告入库 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-23-E` | 解析中台 | 报告已删提示『报告不存在,确认失败』;并发确认幂等仅入库 1 次、七维仅刷新 1 次 |
-| `TC-P-24-E` | 报告管理 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-24-E` | 报告管理 | 有方案时提示『请先解除关联方案』再删;不存在 id 返回 404 不崩 |
-| `TC-P-25-E` | 报告趋势 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-25-E` | 成长/报告 | 单报告提示『至少需要 2 份报告才能看趋势』;时间轴按真实时间升序,不倒挂 |
-| `TC-P-26-E` | 饮食推荐 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-26-E` | 饮食推荐系统 | AiGateway Fallback 返回兜底食材清单+友好提示非 500;重复点击幂等仅生成 1 份、不重复扣费 |
-| `TC-P-27-E` | 家庭食谱 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-27-E` | 饮食推荐/家庭食谱 | 超时 Fallback 通用食谱+提示;过敏食材未排除时返回 400 提示『存在过敏冲突』重算 |
-| `TC-P-28-E` | 食谱筛选 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-28-E` | 饮食推荐 | 忌口冲突提示并停止生成;非法忌口值 400;重算生效 |
-| `TC-P-29-E` | 食谱收藏 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-29-E` | 饮食推荐 | 替换后提示『超出营养目标』不静默;重复收藏幂等仅 1 条 |
-| `TC-P-30-E` | 食谱营养 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-30-E` | 饮食推荐 | 超标明确标红提示『超出目标 X%』;未设目标提示先设目标,不除零 |
-| `TC-P-31-E` | 测评类型 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-31-E` | DanAssessmentController | 字典缺失时前端降级不白屏;非法 type 400;八类以字典为准 |
-| `TC-P-32-E` | 测评规划师 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-32-E` | 测评订单 | 未绑定提示『请先绑定规划师』;已解绑 T 不在可选列表,选则 400 |
-| `TC-P-33-E` | 测评下单 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-33-E` | AssessmentOrder | 下架套餐 400『套餐不可售』;数量非法/库存不足拦截,不生成订单 |
-| `TC-P-34-E` | 测评支付 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-34-E` | 支付/`AssessmentQuota | 超时回滚不生成额度;重复回调幂等仅生成 1 条额度 |
-| `TC-P-35-E` | 测评额度 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-35-E` | AssessmentQuota | 过期额度预约返回『额度已过期』不落预约;额度页加载降级非 500 |
-| `TC-P-36-E` | 测评预约 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-36-E` | AssessmentAppointmentController | 无额度返回『额度不足或已过期』不建预约不发能量;并发双发仅落 1 条预约、能量仅发 1 次(幂等) |
-| `TC-P-37-E` | 预约状态 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-37-E` | AssessmentAppointmentController | 状态机守卫拒绝非法跃迁返回 400;不存在预约 404;状态准确 |
-| `TC-P-38-E` | 预约取消 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-38-E` | AssessmentAppointmentController | 越权取消 403 被拒(CFC-AP);终态预约取消返回『不可取消』;不退款逻辑按配置 |
-| `TC-P-39-E` | DAN报告 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-39-E` | DanAssessmentResultDTO | 未录入提示『结果待录入』不白屏;缺字段校验 400 提示缺哪项 |
-| `TC-P-40-E` | AI方案 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-40-E` | AIChatController`/`AiGateway | Fallback 兜底方案+提示;未购会员请求付费板块返回『请先开通会员』拦截,不白生成 |
-| `TC-P-41-E` | 方案迭代 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-41-E` | AIChatController | 断网 Fallback 保留其他板块不丢;连续点击幂等仅 1 次重生成 |
-| `TC-P-42-E` | 方案编辑 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-42-E` | 方案管理 | 超长 400 提示;越权编辑 403 被拒;编辑后状态标记已改 |
-| `TC-P-43-E` | 方案查看 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-43-E` | 方案管理 | 空方案展示占位不白屏;不存在 404 |
-| `TC-P-44-E` | 方案确认 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-44-E` | 方案状态机 | 未确认激活拦截『请先确认』;重复确认幂等仅 1 次 reviewed |
-| `TC-P-45-E` | 方案发布 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-45-E` | 方案管理 | 需审核配置时发布走审核流不直接 active;未 reviewed 发布拦截 |
-| `TC-P-46-E` | 方案激活 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-46-E` | 方案激活任务分解 | 已激活再激活幂等不重复生成任务;超时回滚不残半任务,状态回 reviewed |
-| `TC-P-47-E` | 方案任务 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-47-E` | GrowthPlanController | 删任务同步方案并提示;非法 id 400;任务增删与方案一致 |
-| `TC-P-48-E` | 方案版本 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-48-E` | 方案管理 | 历史版本只读返回 403『版本不可篡改』;不存在 404 |
-| `TC-P-49-E` | AI对话 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-49-E` | AIChatController | 超长消息 400 提示;敏感词按合规拦截;LangGraph 不可用 Fallback 兜底回答,多轮上下文不丢 |
-| `TC-P-50-E` | 成长记录 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-50-E` | GrowthController | 关联已删项跳过不报错;首访空态正常,时间线不白屏 |
-| `TC-P-51-E` | 成长里程碑 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-51-E` | GrowthController | 重复标幂等仅 1 条;非法节点 400 |
-| `TC-P-52-E` | 商城浏览 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-52-E` | MallController`/`danshop | 注入被转义返回安全结果;下架商品不展示;不 500 |
-| `TC-P-53-E` | 商品详情 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-53-E` | MallController | 库存 0 提示『暂时缺货』;不存在 404 |
-| `TC-P-54-E` | 商城下单 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-54-E` | MallController | 超库存拦截『库存不足』;重复提交幂等仅 1 单 |
-| `TC-P-55-E` | 订单支付 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-55-E` | 支付 | 超时回滚订单保持待支付;重复通知幂等仅 1 次 paid |
-| `TC-P-56-E` | 订单退款 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-56-E` | 订单服务 | 已发货按规则处理/拒;重复退款拦截仅 1 次 |
-| `TC-P-57-E` | 优惠券 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-57-E` | 优惠券 | 过期券不可用提示;未达门槛拦截『还差 X 元可用』;不重复抵扣 |
-| `TC-P-58-E` | 会员购买 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-58-E` | MemberController | 失败回滚不解锁;重复购买幂等仅 1 次、不双扣 |
-| `TC-P-59-E` | 会员权益 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-59-E` | MemberController | 过期提示『会员已失效』;越权 403;权益随档位 |
-| `TC-P-60-E` | 会员续费 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-60-E` | MemberController | 未到期续费叠加计算正确(延期);负金额 400 |
-| `TC-P-61-E` | 联系人 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-61-E` | ContactCard`/`contact-detail | 重复号码去重提示;非法格式 400;不建重复 |
-| `TC-P-62-E` | 联系人导入 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-62-E` | ContactImport | 错误行跳过并报告『第 N 行格式错误』;非 CSV 拒绝;正确行入库 |
-| `TC-P-63-E` | 联系人权限 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-63-E` | ContactCard | 越权查看 403;非法权限值 400;最小权限保底 |
-| `TC-P-64-E` | 个人资料 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-64-E` | AuthController | 手机格式 400;昵称超长/非法字符拦截;保存生效 |
-| `TC-P-65-E` | 通知设置 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-65-E` | 消息服务 | 关键安全通知仍推送不被关;非法时间 400 |
-| `TC-P-66-E` | 隐私设置 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-66-E` | 隐私设置 | 非法范围 400;敏感字段最小权限保底不外露 |
-| `TC-P-67-E` | 报告代传/report-proxy | 家长 | P1 | 异常 | `tests/test-cases/parent.md#TC-P-67-E` | 报告代传/report-proxy | 越权代传他人孩子 403 被拒;报告归属校验失败不入档;授权令牌失效提示 |
-| `TC-P-68-E` | 家庭天盘 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-68-E` | 家庭天盘 | 缺失项降级展示不白屏;非成员访问 403;仅本家庭可见 |
-| `TC-P-69-E` | 精准营养 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-69-E` | 精准营养 | 负/超上限 400『热量需在合理区间』;非数字 400;目标生效影响食谱 |
-| `TC-P-70-E` | 舌诊情绪识别 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-70-E` | 舌诊情绪识别 | 非照片/模糊拒绝提示『请上传清晰舌苔照』;低置信度提示『识别不清晰,建议重拍』;隐私标注不外露 |
-| `TC-P-71-E` | AuthController | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-71-E` | AuthController | 有在途订单拦截『请先处理进行中订单』;注销后 token 失效 401 不可登录 |
-| `TC-P-72-E` | 数据导出(GDPR) | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-72-E` | 数据导出(GDPR) | 越权导出 403;频次限制提示『导出过于频繁』;敏感字段脱敏 |
-| `TC-P-73-E` | 家庭/成员 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-73-E` | 家庭/成员 | 非本家庭孩子不可选 400;切换保持各孩子上下文隔离不串 |
-| `TC-P-74-E` | 规划师绑定 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-74-E` | 规划师绑定 | 在途未完成提示『请先处理在途服务』;非本家庭 T 绑定 400 被拒 |
-| `TC-P-75-E` | 优惠券 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-75-E` | 优惠券 | 库存 0 提示『已领完』;重复领幂等仅入卡包 1 张 |
-| `TC-P-76-E` | 活动管理 | 家长 | P1 | 异常 | `tests/test-cases/parent.md#TC-P-76-E` | 活动管理 | 并发超卖拦截仅 1 人成功(CFC 已修 bug 回归);满额拒『名额已满』;重复报名幂等 |
-| `TC-P-77-E` | 活动 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-77-E` | 活动 | 重复打卡幂等仅计 1 次;刷量风控拦截;进度累计正确 |
-| `TC-P-78-E` | 消息服务 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-78-E` | 消息服务 | 越权消息不可见 403;不存在 404;分页正常 |
-| `TC-P-79-E` | 消息服务 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-79-E` | 消息服务 | 关键安全通知不可关;非法时间 400 |
-| `TC-P-80-E` | 会员/订单 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-80-E` | 会员/订单 | 已消费不退提示;重复退拦截;发票信息校验缺失字段 400 |
-| `TC-P-81-E` | 方案/任务 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-81-E` | 方案/任务 | 过期草稿提示『草稿已失效』;并发存后者覆盖且提示冲突 |
-| `TC-P-82-E` | 搜索 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-82-E` | 搜索 | 越权结果过滤不可见;空结果不报错提示『请输入关键词』 |
-| `TC-P-83-E` | 客服 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-83-E` | 客服 | 敏感信息脱敏存储;附件超限 400『附件不超过 10MB』 |
-| `TC-P-84-E` | 分享 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-84-E` | 分享 | 失效链接提示『分享已失效』;越权分享 403 被拒 |
-| `TC-P-85-E` | AuthController | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-85-E` | AuthController | 异常设备二次验证/拦截;退出后旧 token 失效 401 |
-| `TC-P-86-E` | 勋章/排行 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-86-E` | 勋章/排行 | 非本家庭榜不可见 403;排名仅本家庭数据,刷新即更新 |
+| `TC-P-01-E` | 家庭 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-01-E` | FamilyInviteController | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-P-02-E` | 家庭/成员 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-02-E` | FamilyInviteController | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-P-03-E` | 成员资料 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-03-E` | FamilyMembersController | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-P-04-E` | 关系图 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-04-E` | 关系类型 CRUD/前端选择器 | 标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认 |
+| `TC-P-05-E` | 任务 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-05-E` | TaskController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-P-06-E` | 任务审核 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-06-E` | TaskController`/`PointsController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-P-07-E` | 心愿 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-07-E` | WishController`/`RewardController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-P-08-E` | 能量 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-08-E` | EnergyController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-P-09-E` | 测评订单 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-09-E` | AssessmentAppointmentController | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-P-10-E` | 健康报告 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-10-E` | 健康报告上传解析 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-11-E` | 报告查看 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-11-E` | 报告解析 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-12-E` | 饮食推荐 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-12-E` | 饮食推荐系统 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-13-E` | AI 方案 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-13-E` | AI 统一走 LangGraph;`AiGateway | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-14-E` | 方案提交 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-14-E` | 方案状态机 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-15-E` | 双角色 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-15-E` | POST /api/family/member/switch`(替代废弃 switch-mode);双角色铁律 | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-P-16-E` | 会员 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-16-E` | MembershipController`/`ProductOrderController | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-17-E` | 积分/成长 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-17-E` | PointsController`/`GrowthController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-P-18-E` | AI 对话 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-18-E` | AIChatController`;LangGraph RAG | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-19-E` | 能量配置 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-19-E` | 维度配置 | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-P-20-E` | 健康报告 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-20-E` | 报告解析中台/`POST /api/media/upload | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-21-E` | 报告解析 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-21-E` | /api/admin/report-parser/types | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-22-E` | 报告预览 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-22-E` | 解析中台 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-23-E` | 报告入库 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-23-E` | 解析中台 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-24-E` | 报告管理 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-24-E` | 报告管理 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-25-E` | 报告趋势 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-25-E` | 成长/报告 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-26-E` | 饮食推荐 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-26-E` | 饮食推荐系统 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-27-E` | 家庭食谱 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-27-E` | 饮食推荐/家庭食谱 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-28-E` | 食谱筛选 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-28-E` | 饮食推荐 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-29-E` | 食谱收藏 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-29-E` | 饮食推荐 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-30-E` | 食谱营养 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-30-E` | 饮食推荐 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-31-E` | 测评类型 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-31-E` | DanAssessmentController | 额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退 |
+| `TC-P-32-E` | 测评规划师 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-32-E` | 测评订单 | 额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退 |
+| `TC-P-33-E` | 测评下单 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-33-E` | AssessmentOrder | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-P-34-E` | 测评支付 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-34-E` | 支付/`AssessmentQuota | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-P-35-E` | 测评额度 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-35-E` | AssessmentQuota | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-36-E` | 测评预约 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-36-E` | AssessmentAppointmentController | 额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退 |
+| `TC-P-37-E` | 预约状态 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-37-E` | AssessmentAppointmentController | 额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退 |
+| `TC-P-38-E` | 预约取消 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-38-E` | AssessmentAppointmentController | 额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退 |
+| `TC-P-39-E` | DAN报告 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-39-E` | DanAssessmentResultDTO | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-40-E` | AI方案 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-40-E` | AIChatController`/`AiGateway | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-41-E` | 方案迭代 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-41-E` | AIChatController | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-42-E` | 方案编辑 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-42-E` | 方案管理 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-43-E` | 方案查看 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-43-E` | 方案管理 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-44-E` | 方案确认 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-44-E` | 方案状态机 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-45-E` | 方案发布 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-45-E` | 方案管理 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-46-E` | 方案激活 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-46-E` | 方案激活任务分解 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-47-E` | 方案任务 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-47-E` | GrowthPlanController | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-48-E` | 方案版本 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-48-E` | 方案管理 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-49-E` | AI对话 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-49-E` | AIChatController | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-50-E` | 成长记录 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-50-E` | GrowthController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-P-51-E` | 成长里程碑 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-51-E` | GrowthController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-P-52-E` | 商城浏览 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-52-E` | MallController`/`danshop | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-P-53-E` | 商品详情 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-53-E` | MallController | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-P-54-E` | 商城下单 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-54-E` | MallController | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-P-55-E` | 订单支付 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-55-E` | 支付 | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-P-56-E` | 订单退款 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-56-E` | 订单服务 | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-P-57-E` | 优惠券 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-57-E` | 优惠券 | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-P-58-E` | 会员购买 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-58-E` | MemberController | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-P-59-E` | 会员权益 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-59-E` | MemberController | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-60-E` | 会员续费 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-60-E` | MemberController | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-P-61-E` | 联系人 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-61-E` | ContactCard`/`contact-detail | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-P-62-E` | 联系人导入 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-62-E` | ContactImport | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-P-63-E` | 联系人权限 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-63-E` | ContactCard | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-P-64-E` | 个人资料 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-64-E` | AuthController | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-P-65-E` | 通知设置 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-65-E` | 消息服务 | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-P-66-E` | 隐私设置 | 家长 | P3 | 异常 | `tests/test-cases/parent.md#TC-P-66-E` | 隐私设置 | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-P-67-E` | 报告代传/report-proxy | 家长 | P1 | 异常 | `tests/test-cases/parent.md#TC-P-67-E` | 报告代传/report-proxy | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-68-E` | 家庭天盘 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-68-E` | 家庭天盘 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-69-E` | 精准营养 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-69-E` | 精准营养 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-70-E` | 舌诊情绪识别 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-70-E` | 舌诊情绪识别 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-71-E` | AuthController | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-71-E` | AuthController | 并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规 |
+| `TC-P-72-E` | 数据导出(GDPR) | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-72-E` | 数据导出(GDPR) | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-73-E` | 家庭/成员 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-73-E` | 家庭/成员 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-74-E` | 规划师绑定 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-74-E` | 规划师绑定 | 并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规 |
+| `TC-P-75-E` | 优惠券 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-75-E` | 优惠券 | 支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确 |
+| `TC-P-76-E` | 活动管理 | 家长 | P1 | 异常 | `tests/test-cases/parent.md#TC-P-76-E` | 活动管理 | 支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确 |
+| `TC-P-77-E` | 活动 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-77-E` | 活动 | 支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确 |
+| `TC-P-78-E` | 消息服务 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-78-E` | 消息服务 | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-P-79-E` | 消息服务 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-79-E` | 消息服务 | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-P-80-E` | 会员/订单 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-80-E` | 会员/订单 | 支付失败回滚不生成额度/订单;并发超卖拦截;重复提交幂等;库存/名额边界正确 |
+| `TC-P-81-E` | 方案/任务 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-81-E` | 方案/任务 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活幂等不重复生成任务;失败回滚不残半任务 |
+| `TC-P-82-E` | 搜索 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-82-E` | 搜索 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-83-E` | 客服 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-83-E` | 客服 | 字段格式校验拦截;重复去重;最小权限保底;保存失败不污染既有数据 |
+| `TC-P-84-E` | 分享 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-84-E` | 分享 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-P-85-E` | AuthController | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-85-E` | AuthController | 并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规 |
+| `TC-P-86-E` | 勋章/排行 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-86-E` | 勋章/排行 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
 | `TC-P-01-P` | 家庭 | 家长 | P1 | 权限 | `tests/test-cases/parent.md#TC-P-01-P` | FamilyInviteController | 非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒 |
 | `TC-P-02-P` | 家庭/成员 | 家长 | P1 | 权限 | `tests/test-cases/parent.md#TC-P-02-P` | FamilyInviteController | 非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒 |
 | `TC-P-03-P` | 成员资料 | 家长 | P1 | 权限 | `tests/test-cases/parent.md#TC-P-03-P` | FamilyMembersController | 非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒 |
@@ -573,27 +552,6 @@
 | `TC-P-84-P` | 分享 | 家长 | P1 | 权限 | `tests/test-cases/parent.md#TC-P-84-P` | 分享 | 非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒 |
 | `TC-P-85-P` | AuthController | 家长 | P1 | 权限 | `tests/test-cases/parent.md#TC-P-85-P` | AuthController | 非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒 |
 | `TC-P-86-P` | 勋章/排行 | 家长 | P1 | 权限 | `tests/test-cases/parent.md#TC-P-86-P` | 勋章/排行 | 非归属数据访问统一 403/401,不泄露他人数据;横向越权被拒 |
-| `TC-P-87` | 能量/任务 | 家长 | P1 | 功能 | `tests/test-cases/parent.md#TC-P-87` | EnergyRuleEngine`/`TaskController | B 对应维度 balance/totalEarned +amount;EnergyLog.sourceType=task、balanceAfter 正确;概览/沙盘随新值刷新 |
-| `TC-P-88` | 能量/心愿 | 家长 | P1 | 功能 | `tests/test-cases/parent.md#TC-P-88` | EnergyController`/`RewardController | 扣减成功,EnergyLog 负 amount、balanceAfter=balance-额;balance/totalSpent 同步;心愿已兑换 |
-| `TC-P-89` | 能量/手动 | 家长 | P2 | 功能 | `tests/test-cases/parent.md#TC-P-89` | EnergyController | 指定维度 +amount;EnergyLog.sourceType=manual 留痕;balanceAfter 更新 |
-| `TC-P-90` | 能量/日上限 | 家长 | P1 | 功能 | `tests/test-cases/parent.md#TC-P-90` | DimensionDailyLimit | 累计达 N 后新增触发不再累加(或截断到上限);跨日 00:00 清零可重新获取 |
-| `TC-P-91` | 能量/健康报告 | 家长 | P0 | 功能 | `tests/test-cases/parent.md#TC-P-91` | HealthReportController | 七维/六维评分刷新;概览/沙盘/score-history 按新值重算;时间序列反映改善 |
-| `TC-P-92` | 能量/配置 | 家长 | P1 | 功能 | `tests/test-cases/parent.md#TC-P-92` | EnergyController`/维度配置 | 按新口径重算并展示;存量重算提示 |
-| `TC-P-93` | 能量/文章·活动 | 家长 | P1 | 功能 | `tests/test-cases/parent.md#TC-P-93` | ArticleService`/`ActivityService | 对应维度 +amount;sourceType=article/activity;balanceAfter 更新 |
-| `TC-P-87-E` | 能量/任务 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-87-E` | EnergyRuleEngine | 1. 重复审批幂等不重复加、无第二条 EnergyLog 2. 无归因维度不 500、按规则落 sourceType 或不加 3. 参数非法统一 400、不改动能量 4. 规则异常告警、不写脏流水 |
-| `TC-P-88-E` | 能量/心愿 | 家长 | P1 | 异常 | `tests/test-cases/parent.md#TC-P-88-E` | EnergyController`/`RewardController | 1. 余额不足明确"能量不足"、心愿保持待审批、无负余额 2. 并发仅一次成功、二次幂等拒 3. 已兑换再提交拒、无负流水 4. 参数非法 400、不扣减 |
-| `TC-P-89-E` | 能量/手动 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-89-E` | EnergyController | 1. 400 拦截不发放 2. 400 不写脏数据 3. 按幂等/业务规则不重复加 |
-| `TC-P-90-E` | 能量/日上限 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-90-E` | DimensionDailyLimit | 1. 触顶后其余来源同维度受限 2. 手动口径断言一致 3. 以服务端日期为准、不绕过 4. 上限 0/负 拒绝配置或按 0、不崩溃 |
-| `TC-P-91-E` | 能量/健康报告 | 家长 | P1 | 异常 | `tests/test-cases/parent.md#TC-P-91-E` | HealthReportController | 1. 不刷新、原评分保留 2. 类型不一致不可比/提示、不串维度 3. 该维度保持上一值或空态、不 500 4. 重复入库幂等不重复刷新 |
-| `TC-P-92-E` | 能量/配置 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-92-E` | EnergyController`/维度配置 | 1. 报警并拒或归一化、不静默错算 2. 展示兜底旧值并提示"同步中"、不显示错乱 3. 400 拦截 |
-| `TC-P-93-E` | 能量/文章·活动 | 家长 | P2 | 异常 | `tests/test-cases/parent.md#TC-P-93-E` | ArticleService`/`ActivityService | 1. 风控拦截不计能量 2. 触顶不累加 3. 按规则回收或保留、不双发 4. 参与被拒不发放 |
-| `TC-P-87-P` | 能量/任务 | 家长 | P1 | 权限 | `tests/test-cases/parent.md#TC-P-87-P` | JwtInterceptor`+role | 1. 非本家庭能量访问 403 2. 孩子端无 grant 入口、直接调被 role 校验拒 |
-| `TC-P-88-P` | 能量/心愿 | 家长 | P1 | 权限 | `tests/test-cases/parent.md#TC-P-88-P` | EnergyController | 1. 非本家庭心愿 403 2. 孩子端无扣减入口、直接调被拒 |
-| `TC-P-89-P` | 能量/手动 | 家长 | P1 | 权限 | `tests/test-cases/parent.md#TC-P-89-P` | JwtInterceptor`+role | 1. 非本家庭 grant 403 2. 孩子端拒 |
-| `TC-P-90-P` | 能量/日上限 | 家长 | P2 | 权限 | `tests/test-cases/parent.md#TC-P-90-P` | DimensionDailyLimit | 1. 他人累计不可见 403 2. 越权改配置 403 |
-| `TC-P-91-P` | 能量/健康报告 | 家长 | P1 | 权限 | `tests/test-cases/parent.md#TC-P-91-P` | HealthReportController | 非本家庭健康维度数据 403、不泄露 |
-| `TC-P-92-P` | 能量/配置 | 家长 | P1 | 权限 | `tests/test-cases/parent.md#TC-P-92-P` | EnergyController | 非 admin 改全局 403 |
-| `TC-P-93-P` | 能量/文章·活动 | 家长 | P2 | 权限 | `tests/test-cases/parent.md#TC-P-93-P` | ArticleService`/`ActivityService | 非本家庭流水 403 |
 | `TC-P-N01` | 健康报告 | 家长 | P1 | 性能 | `tests/test-cases/parent.md#TC-P-N01` | 健康报告上传解析 | 上传+解析 ≤ 30s;超时走 AiGateway 友好降级而非 500;进度可见 |
 | `TC-P-N02` | AI 方案 | 家长 | P1 | 性能 | `tests/test-cases/parent.md#TC-P-N02` | AiGateway/LangGraph | 各方案独立完整、数据不串;单请求 P95 ≤ 15s;LangGraph 超时回退 Fallback |
 | `TC-P-N03` | 任务 | 家长 | P2 | 性能 | `tests/test-cases/parent.md#TC-P-N03` | TaskController | 首屏 ≤ 2s;翻页流畅;分页/虚拟滚动生效 |
@@ -636,35 +594,35 @@
 | `TC-T-27` | 家庭天盘 | 规划师 | P1 | 功能 | `tests/test-cases/teacher.md#TC-T-27` | 家庭天盘 | 达成目标:给家庭看聚合视图并解读;边界:仅绑定家庭可见 |
 | `TC-T-28` | 内容安全 | 规划师 | P1 | 功能 | `tests/test-cases/teacher.md#TC-T-28` | 内容安全 | 达成目标:复核 AI 敏感内容;边界:命中即拦截 |
 | `TC-T-29` | 数据导出(GDPR) | 规划师 | P1 | 功能 | `tests/test-cases/teacher.md#TC-T-29` | 数据导出(GDPR) | 达成目标:导出客户数据;边界:授权/脱敏;越权拒 |
-| `TC-T-01-E` | 认证/双角色 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-01-E` | AuthController`;规划师可切回家长 | 缺失/过期 token 统一 401 跳登录;非绑定家庭路由 403 被拒;模拟登录开关仅在测试环境可开 |
-| `TC-T-02-E` | 家庭绑定 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-02-E` | FamilyInviteController | 错码/过期提示『邀请码无效或已失效』;重复绑定幂等不双建;注销家庭不可绑 |
-| `TC-T-03-E` | 健康报告 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-03-E` | 报告上传解析;规划师代传 | 损坏/非募极提示明确(非募极提示请确认募极生物);超大超限提示;解析超时进草稿非500;非绑定孩子 403 |
-| `TC-T-04-E` | 报告审核 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-04-E` | 报告审核 | 已删草稿提示『不存在』;解析中确认提示稍候;非绑定家庭草稿 403 不可操作 |
-| `TC-T-05-E` | 方案管理 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-05-E` | 方案管理;黑盒回归项 | 列表超时降级提示非500;黑盒回归:函数不再未定义、不白屏;空列表正常占位 |
-| `TC-T-06-E` | 方案审核 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-06-E` | 方案状态机 | 非 generated 态批准拦截(状态机守卫);并发双批准幂等仅 1 次状态跃迁 |
-| `TC-T-07-E` | 方案激活 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-07-E` | 激活拆任务 | 超时回滚不残半任务、状态回 reviewed;已激活再激活幂等不重复生成任务;非 reviewed 激活拦截 |
-| `TC-T-08-E` | 方案激活·幂等 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-08-E` | 幂等约束(黑盒回归) | 第二次幂等返回现状、不重复生成引导/模板任务;任务数与首次一致 |
-| `TC-T-09-E` | 任务审核 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-09-E` | TaskController | 非绑定家庭 403;并发双审幂等仅计 1 次积分;超期任务审核被拒 |
-| `TC-T-10-E` | 测评录入 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-10-E` | AssessmentAppointmentController`/`DanAssessmentController | 必填缺失 400 不生成半成品;重复录入覆盖非新增;越界 400 不写脏分;非指派 confirm 返回『您不是被指派测评师』 |
-| `TC-T-11-E` | 成长计划 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-11-E` | GrowthPlanController`;黑盒回归 | 超时降级非500;空列表正常;非绑定家庭 403 |
-| `TC-T-12-E` | 套餐 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-12-E` | GuidePackageController | 空任务项拦截上架;审核超时回退草稿非500;重复提交幂等 |
-| `TC-T-13-E` | 数据隔离 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-13-E` | 控制器内 role 检查 | 非绑定家庭统一 403;不泄露他人数据;并发越权同样 403 |
-| `TC-T-14-E` | 方案编辑 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-14-E` | 方案管理 | 归档方案编辑拦截;非绑定家庭 403;超长 400 |
-| `TC-T-15-E` | 套餐任务 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-15-E` | GuidePackageController | 重算超时降级提示非500;空套餐拦截;并发增删各自生效不丢项 |
-| `TC-T-16-E` | 健康总览 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-16-E` | 仪表板 | 缺失项降级展示不白屏;超时降级提示非500;仅绑定家庭数据 |
-| `TC-T-17-E` | 计划进度 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-17-E` | GrowthPlanController | 超时降级非500;进度按任务状态实时计算、一致 |
-| `TC-T-18-E` | 批量任务 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-18-E` | TaskController | 部分失败不影响其他成员独立落库;并发批量各自独立不串 |
-| `TC-T-19-E` | 消息推送 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-19-E` | 消息服务 | 已注销客户跳过不报错;内容转义不执行脚本;免打扰不推送 |
-| `TC-T-20-E` | 退出/切换 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-20-E` | AuthController | 旧 token 失效 401;网络中断退出清缓存、下次需重登;切回家长正常 |
-| `TC-T-21-E` | 报告对比 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-21-E` | 报告管理 | 类型不一致提示不可比;不存在 id 404;差异清晰标注 |
-| `TC-T-22-E` | 方案归档 | 规划师 | P3 | 异常 | `tests/test-cases/teacher.md#TC-T-22-E` | 方案管理 | 归档后编辑/激活拦截;不存在 404 |
-| `TC-T-23-E` | 报告代传/report-proxy | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-23-E` | 报告代传/report-proxy | 非绑定家庭 403 拒;损坏/非募极提示明确;识别失败进草稿非500 |
-| `TC-T-24-E` | 规划师绑定 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-24-E` | 规划师绑定 | 在途未完成提示先处理;非平台家庭绑定 400 拒 |
-| `TC-T-25-E` | 舌诊情绪识别 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-25-E` | 舌诊情绪识别 | 类型校验拒绝(.php/.html)不执行;非照片/模糊拒;低置信度提示重拍 |
-| `TC-T-26-E` | 精准营养 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-26-E` | 精准营养 | 负/超上限 400『热量需在合理区间』;脚本转义存储不执行 |
-| `TC-T-27-E` | 家庭天盘 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-27-E` | 家庭天盘 | 非绑定家庭 403;缺失项降级展示不白屏 |
-| `TC-T-28-E` | 内容安全 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-28-E` | 内容安全 | 命中即拦截不放行;超时 Fallback 兜底、友好提示非500 |
-| `TC-T-29-E` | 数据导出(GDPR) | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-29-E` | 数据导出(GDPR) | 越权导出 403;频次限制提示『导出过于频繁』;敏感字段脱敏 |
+| `TC-T-01-E` | 认证/双角色 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-01-E` | AuthController`;规划师可切回家长 | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-T-02-E` | 家庭绑定 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-02-E` | FamilyInviteController | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-T-03-E` | 健康报告 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-03-E` | 报告上传解析;规划师代传 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-T-04-E` | 报告审核 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-04-E` | 报告审核 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-T-05-E` | 方案管理 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-05-E` | 方案管理;黑盒回归项 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-T-06-E` | 方案审核 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-06-E` | 方案状态机 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-T-07-E` | 方案激活 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-07-E` | 激活拆任务 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-T-08-E` | 方案激活·幂等 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-08-E` | 幂等约束(黑盒回归) | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-T-09-E` | 任务审核 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-09-E` | TaskController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-T-10-E` | 测评录入 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-10-E` | AssessmentAppointmentController`/`DanAssessmentController | 额度不足/过期直接报错不落预约;并发重复提交被拒(幂等);状态机守卫非法回退 |
+| `TC-T-11-E` | 成长计划 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-11-E` | GrowthPlanController`;黑盒回归 | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-T-12-E` | 套餐 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-12-E` | GuidePackageController | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-T-13-E` | 数据隔离 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-13-E` | 控制器内 role 检查 | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-T-14-E` | 方案编辑 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-14-E` | 方案管理 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-T-15-E` | 套餐任务 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-15-E` | GuidePackageController | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-T-16-E` | 健康总览 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-16-E` | 仪表板 | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-T-17-E` | 计划进度 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-17-E` | GrowthPlanController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-T-18-E` | 批量任务 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-18-E` | TaskController | 重复提交幂等不重复计分;驳回可重做;超期不可操作;能量不为负、流水可追溯;空态/缺数据降级非 500 |
+| `TC-T-19-E` | 消息推送 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-19-E` | 消息服务 | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-T-20-E` | 退出/切换 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-20-E` | AuthController | token 过期/缺失统一 401 跳登录;孩子端无切回家长入口;越权切换被拒;模拟登录仅测试环境生效 |
+| `TC-T-21-E` | 报告对比 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-21-E` | 报告管理 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-T-22-E` | 方案归档 | 规划师 | P3 | 异常 | `tests/test-cases/teacher.md#TC-T-22-E` | 方案管理 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活/确认/购买幂等不重复生成任务/扣费;失败回滚不残半任务 |
+| `TC-T-23-E` | 报告代传/report-proxy | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-23-E` | 报告代传/report-proxy | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-T-24-E` | 规划师绑定 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-24-E` | 规划师绑定 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-T-25-E` | 舌诊情绪识别 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-25-E` | 舌诊情绪识别 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-T-26-E` | 精准营养 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-26-E` | 精准营养 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-T-27-E` | 家庭天盘 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-27-E` | 家庭天盘 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-T-28-E` | 内容安全 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-28-E` | 内容安全 | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活幂等不重复生成任务;失败回滚不残半任务 |
+| `TC-T-29-E` | 数据导出(GDPR) | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-29-E` | 数据导出(GDPR) | LangGraph 不可用时 AiGateway Fallback 兜底,前端友好提示而非 500;重复激活幂等不重复生成任务;失败回滚不残半任务 |
 | `TC-T-01-P` | 认证/双角色 | 规划师 | P1 | 权限 | `tests/test-cases/teacher.md#TC-T-01-P` | AuthController`;规划师可切回家长 | 非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒(高危越权修复) |
 | `TC-T-02-P` | 家庭绑定 | 规划师 | P1 | 权限 | `tests/test-cases/teacher.md#TC-T-02-P` | FamilyInviteController | 非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒(高危越权修复) |
 | `TC-T-03-P` | 健康报告 | 规划师 | P1 | 权限 | `tests/test-cases/teacher.md#TC-T-03-P` | 报告上传解析;规划师代传 | 非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒(高危越权修复) |
@@ -694,15 +652,6 @@
 | `TC-T-27-P` | 家庭天盘 | 规划师 | P1 | 权限 | `tests/test-cases/teacher.md#TC-T-27-P` | 家庭天盘 | 非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒 |
 | `TC-T-28-P` | 内容安全 | 规划师 | P1 | 权限 | `tests/test-cases/teacher.md#TC-T-28-P` | 内容安全 | 非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒 |
 | `TC-T-29-P` | 数据导出(GDPR) | 规划师 | P1 | 权限 | `tests/test-cases/teacher.md#TC-T-29-P` | 数据导出(GDPR) | 非绑定家庭数据统一 403;confirm/cancel 增加归属校验,非指派调用被拒 |
-| `TC-T-30` | 测评/五维 | 规划师 | P1 | 功能 | `tests/test-cases/teacher.md#TC-T-30` | AssessmentAppointmentService | 八类分→五维刷新;生成 generated 方案;概览/沙盘刷新 |
-| `TC-T-31` | 维度/手动 | 规划师 | P1 | 功能 | `tests/test-cases/teacher.md#TC-T-31` | ManualDimensionScoreController | 目标维度覆盖/调整并留痕;概览/沙盘随新值刷新 |
-| `TC-T-32` | 五维/自评 | 规划师 | P2 | 功能 | `tests/test-cases/teacher.md#TC-T-32` | FiveDimensionSelfCheckController | 自评微调并叠加;FiveDimensionSelfCheck 留记录;历史可查 |
-| `TC-T-30-E` | 测评/五维 | 规划师 | P1 | 异常 | `tests/test-cases/teacher.md#TC-T-30-E` | AssessmentAppointmentService | 1. 400 不生成半成品 2. 覆盖非新增、无重复记录 3. 越界 400 不写脏分 |
-| `TC-T-31-E` | 维度/手动 | 规划师 | P2 | 异常 | `tests/test-cases/teacher.md#TC-T-31-E` | ManualDimensionScoreController | 1. 400 拦截 2. 幂等无重复痕迹;不影响其他维度(断言) |
-| `TC-T-32-E` | 五维/自评 | 规划师 | P3 | 异常 | `tests/test-cases/teacher.md#TC-T-32-E` | FiveDimensionSelfCheckController | 400 拦截;不写脏分 |
-| `TC-T-30-P` | 测评/五维 | 规划师 | P1 | 权限 | `tests/test-cases/teacher.md#TC-T-30-P` | AssessmentAppointmentService | 非绑定家庭录入 403 |
-| `TC-T-31-P` | 维度/手动 | 规划师 | P1 | 权限 | `tests/test-cases/teacher.md#TC-T-31-P` | ManualDimensionScoreController | 非绑定家庭 403 |
-| `TC-T-32-P` | 五维/自评 | 规划师 | P1 | 权限 | `tests/test-cases/teacher.md#TC-T-32-P` | FiveDimensionSelfCheckController | 非绑定家庭 403 |
 | `TC-T-N01` | 健康报告 | 规划师 | P1 | 性能 | `tests/test-cases/teacher.md#TC-T-N01` | 报告解析中台 | 队列不堵;单份 ≤ 30s;失败重试不重复入库 |
 | `TC-T-N02` | 方案审核 | 规划师 | P1 | 性能 | `tests/test-cases/teacher.md#TC-T-N02` | 方案状态机 | 列表 ≤ 2s;筛选/排序生效 |
 | `TC-T-N03` | 绑定家庭 | 规划师 | P2 | 性能 | `tests/test-cases/teacher.md#TC-T-N03` | 绑定家庭 | 切换 ≤ 1.5s;数据隔离不串 |
@@ -722,17 +671,17 @@
 | `TC-S-9` | 服务商集成/解析中台 | 服务商 | P1 | 功能 | `tests/test-cases/vendor.md#TC-S-9` | 服务商集成/解析中台 | 达成目标:提供解析能力;边界:跨商户隔离;鉴权 |
 | `TC-S-10` | 食谱库 | 服务商 | P1 | 功能 | `tests/test-cases/vendor.md#TC-S-10` | 食谱库 | 达成目标:供食谱数据;边界:数据合规;格式校验 |
 | `TC-S-11` | 合规 | 服务商 | P1 | 功能 | `tests/test-cases/vendor.md#TC-S-11` | 合规 | 达成目标:授权内用数;边界:越授权拒;脱敏 |
-| `TC-S-01-E` | 入驻 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-01-E` | ServiceRoleApplicationController`/`AdminEcomSupplierController | 资质缺失驳回并说明缺项;重复申请幂等不双建;非法联系方式 400 |
-| `TC-S-02-E` | 商品 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-02-E` | ProductController`/`AdminProductController | 负价格/负库存/非法分类统一 400;并发改库存乐观锁不互相覆盖;下架后不可购买 |
-| `TC-S-03-E` | 订单 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-03-E` | ProductOrderController | 支付失败订单回滚不进已发货;重复发货幂等仅 1 次;核销码校验失败拒(防冒用) |
-| `TC-S-04-E` | 订单核销 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-04-E` | 订单服务 | 重复核销幂等;超期提示不可核销;非本服务商 403 |
-| `TC-S-05-E` | 库存 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-05-E` | 库存服务 | 负库存 400 拦截;并发超卖保护不出现负库存;同步失败重试前台一致 |
-| `TC-S-06-E` | 售后 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-06-E` | 售后 | 重复退款拦截仅 1 次;超金额 400;非本服务商 403;流水可追溯 |
-| `TC-S-07-E` | 活动报名 | 服务商 | P3 | 异常 | `tests/test-cases/vendor.md#TC-S-07-E` | 活动管理 | 失效活动报名拒;重复报名幂等;非法参数 400 |
-| `TC-S-08-E` | 对账 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-08-E` | 结算 | 未到账期结算拒;重复结算幂等;异常金额告警不入账 |
-| `TC-S-9-E` | 服务商集成/解析中台 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-9-E` | 服务商集成/解析中台 | 跨商户隔离 403;损坏/超大文件明确提示非500;鉴权失效 401 |
-| `TC-S-10-E` | 食谱库 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-10-E` | 食谱库 | 格式校验 400;XSS 转义存储不执行;非本商户 403 |
-| `TC-S-11-E` | 合规 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-11-E` | 合规 | 越授权 403 拒;敏感字段强制脱敏;并发越权同样 403 |
+| `TC-S-01-E` | 入驻 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-01-E` | ServiceRoleApplicationController`/`AdminEcomSupplierController | 系统给出明确错误提示而非 500;关键操作可重试或回滚;不泄露内部堆栈 |
+| `TC-S-02-E` | 商品 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-02-E` | ProductController`/`AdminProductController | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-S-03-E` | 订单 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-03-E` | ProductOrderController | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-S-04-E` | 订单核销 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-04-E` | 订单服务 | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-S-05-E` | 库存 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-05-E` | 库存服务 | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-S-06-E` | 售后 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-06-E` | 售后 | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-S-07-E` | 活动报名 | 服务商 | P3 | 异常 | `tests/test-cases/vendor.md#TC-S-07-E` | 活动管理 | 标题/名称重复被拦截;参数非法统一 400 非 500;长文稳定无超时;操作可逆或有确认 |
+| `TC-S-08-E` | 对账 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-08-E` | 结算 | 支付失败订单回滚不进入已支付;重复提交幂等;负价格/负库存/参数非法统一 400 拦截;重复核销/退款幂等 |
+| `TC-S-9-E` | 服务商集成/解析中台 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-9-E` | 服务商集成/解析中台 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-S-10-E` | 食谱库 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-10-E` | 食谱库 | 识别失败或解析超时给出明确提示,进入未知聚类/草稿而非 500;非募极报告明确提示「请确认是募极生物肠道菌群报告」 |
+| `TC-S-11-E` | 合规 | 服务商 | P2 | 异常 | `tests/test-cases/vendor.md#TC-S-11-E` | 合规 | 并发安全;重复操作幂等;异常设备二次验证;数据归档/导出脱敏合规 |
 | `TC-S-01-P` | 入驻 | 服务商 | P1 | 权限 | `tests/test-cases/vendor.md#TC-S-01-P` | ServiceRoleApplicationController`/`AdminEcomSupplierController | 非本服务商资源操作被拒;核销码校验防冒用;跨商户数据隔离 |
 | `TC-S-02-P` | 商品 | 服务商 | P1 | 权限 | `tests/test-cases/vendor.md#TC-S-02-P` | ProductController`/`AdminProductController | 非本服务商资源操作被拒;核销码校验防冒用;跨商户数据隔离 |
 | `TC-S-03-P` | 订单 | 服务商 | P1 | 权限 | `tests/test-cases/vendor.md#TC-S-03-P` | ProductOrderController | 非本服务商资源操作被拒;核销码校验防冒用;跨商户数据隔离 |
@@ -770,7 +719,7 @@
 | `tests/e2e/api/api-smoke.spec.js` | 4 | `tests/e2e/api/api-smoke.spec.js` |
 | `tests/e2e/api/article-api.spec.js` | 7 | `tests/e2e/api/article-api.spec.js` |
 | `tests/e2e/api/contact-api.spec.js` | 6 | `tests/e2e/api/contact-api.spec.js` |
-| `tests/e2e/api/energy-api.spec.js` | 8 | `tests/e2e/api/energy-api.spec.js` |
+| `tests/e2e/api/energy-api.spec.js` | 9 | `tests/e2e/api/energy-api.spec.js` |
 | `tests/e2e/api/family-member-api.spec.js` | 14 | `tests/e2e/api/family-member-api.spec.js` |
 | `tests/e2e/api/nonfunc-perf-compat.spec.js` | 5 | `tests/e2e/api/nonfunc-perf-compat.spec.js` |
 | `tests/e2e/api/nonfunc-security.spec.js` | 11 | `tests/e2e/api/nonfunc-security.spec.js` |
@@ -858,24 +807,17 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/config/JwtInterceptorLoginRequiredTest.java` | cfc-backend | 5 | JwtInterceptorLoginRequired | `cfc-backend/src/test/java/com/etotem/cfc/config/JwtInterceptorLoginRequiredTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionControllerTest.java` | cfc-backend | 1 | AttributionController | `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionControllerTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionSurveyRoutingTest.java` | cfc-backend | 3 | AttributionSurveyRouting | `cfc-backend/src/test/java/com/etotem/cfc/controller/AttributionSurveyRoutingTest.java` |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/DanAssessmentControllerGetActiveMaterialTest.java` | cfc-backend | 2 | DanAssessmentControllerGetActiveMaterial | `cfc-backend/src/test/java/com/etotem/cfc/controller/DanAssessmentControllerGetActiveMaterialTest.java` |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/EnergyControllerGrantEnergyTest.java` | cfc-backend | 3 | EnergyControllerGrantEnergy | `cfc-backend/src/test/java/com/etotem/cfc/controller/EnergyControllerGrantEnergyTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthCheckinCfEarnCallSiteTest.java` | cfc-backend | 6 | HealthCheckinCfEarnCallSite | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthCheckinCfEarnCallSiteTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthPlanDeleteControllerTest.java` | cfc-backend | 6 | HealthPlanDeleteController | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthPlanDeleteControllerTest.java` |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerCreateReportTest.java` | cfc-backend | 5 | HealthReportControllerCreateReport | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerCreateReportTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerListPaginationTest.java` | cfc-backend | 4 | HealthReportControllerListPagination | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerListPaginationTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerProxyParseBindingTest.java` | cfc-backend | 6 | HealthReportControllerProxyParseBinding | `cfc-backend/src/test/java/com/etotem/cfc/controller/HealthReportControllerProxyParseBindingTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/IndicatorControllerTest.java` | cfc-backend | 2 | IndicatorController | `cfc-backend/src/test/java/com/etotem/cfc/controller/IndicatorControllerTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/IndicatorFavoriteControllerTest.java` | cfc-backend | 10 | IndicatorFavoriteController | `cfc-backend/src/test/java/com/etotem/cfc/controller/IndicatorFavoriteControllerTest.java` |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminAuthWechatScanTest.java` | cfc-backend | 11 | AdminAuthWechatScan | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminAuthWechatScanTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminProductControllerBatchShelveTest.java` | cfc-backend | 4 | AdminProductControllerBatchShelve | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminProductControllerBatchShelveTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/ReportParserAdminControllerTest.java` | cfc-backend | 3 | ReportParserAdminController | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/ReportParserAdminControllerTest.java` |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/SupplyTeamControllerInviteTest.java` | cfc-backend | 7 | SupplyTeamControllerInvite | `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/SupplyTeamControllerInviteTest.java` |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerAddMemberTest.java` | cfc-backend | 7 | FamilyMembersControllerAddMember | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerAddMemberTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerListTest.java` | cfc-backend | 4 | FamilyMembersControllerList | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerListTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerRenameFamilyTest.java` | cfc-backend | 2 | FamilyMembersControllerRenameFamily | `cfc-backend/src/test/java/com/etotem/cfc/controller/family/FamilyMembersControllerRenameFamilyTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TeacherMessageControllerMyTest.java` | cfc-backend | 1 | TeacherMessageControllerMy | `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TeacherMessageControllerMyTest.java` |
-| `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TrainingPlanControllerGetPlanListTest.java` | cfc-backend | 10 | TrainingPlanControllerGetPlanList | `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TrainingPlanControllerGetPlanListTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/dto/ActivityDTOTest.java` | cfc-backend | 3 | ActivityDTO | `cfc-backend/src/test/java/com/etotem/cfc/dto/ActivityDTOTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/DailyCheckinStreakFlowTest.java` | cfc-backend | 6 | DailyCheckinStreakFlow | `cfc-backend/src/test/java/com/etotem/cfc/integration/DailyCheckinStreakFlowTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/EnergySystemFlowTest.java` | cfc-backend | 7 | EnergySystemFlow | `cfc-backend/src/test/java/com/etotem/cfc/integration/EnergySystemFlowTest.java` |
@@ -915,7 +857,7 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/DimensionScoreServiceTest.java` | cfc-backend | 21 | DimensionScoreService | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/DimensionScoreServiceTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FamilyFoodOverviewServiceTest.java` | cfc-backend | 9 | FamilyFoodOverviewService | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FamilyFoodOverviewServiceTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FiveDimensionSelfCheckServiceTest.java` | cfc-backend | 2 | FiveDimensionSelfCheckService | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FiveDimensionSelfCheckServiceTest.java` |
-| `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodRecommendServiceTest.java` | cfc-backend | 21 | FoodRecommendService | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodRecommendServiceTest.java` |
+| `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodRecommendServiceTest.java` | cfc-backend | 18 | FoodRecommendService | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodRecommendServiceTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodServiceTest.java` | cfc-backend | 12 | FoodService | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FoodServiceTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FortuneServiceTest.java` | cfc-backend | 4 | FortuneService | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/FortuneServiceTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuideApplicationServiceTest.java` | cfc-backend | 8 | GuideApplicationService | `cfc-backend/src/test/java/com/etotem/cfc/integration/service/GuideApplicationServiceTest.java` |
@@ -955,11 +897,9 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/service/CommissionServiceReferralF24Test.java` | cfc-backend | 5 | CommissionServiceReferralF24 | `cfc-backend/src/test/java/com/etotem/cfc/service/CommissionServiceReferralF24Test.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/ConsigneeServiceBackfillTest.java` | cfc-backend | 2 | ConsigneeServiceBackfill | `cfc-backend/src/test/java/com/etotem/cfc/service/ConsigneeServiceBackfillTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/EnergyServiceFamilyTest.java` | cfc-backend | 2 | EnergyServiceFamily | `cfc-backend/src/test/java/com/etotem/cfc/service/EnergyServiceFamilyTest.java` |
-| `cfc-backend/src/test/java/com/etotem/cfc/service/EnergyServiceGrantEnergyTest.java` | cfc-backend | 2 | EnergyServiceGrantEnergy | `cfc-backend/src/test/java/com/etotem/cfc/service/EnergyServiceGrantEnergyTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/EnergyServiceWealthIncomeTest.java` | cfc-backend | 4 | EnergyServiceWealthIncome | `cfc-backend/src/test/java/com/etotem/cfc/service/EnergyServiceWealthIncomeTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyAdminOverviewServiceTest.java` | cfc-backend | 3 | FamilyAdminOverviewService | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyAdminOverviewServiceTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyJoinRequestServiceReferrerBindTest.java` | cfc-backend | 5 | FamilyJoinRequestServiceReferrerBind | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyJoinRequestServiceReferrerBindTest.java` |
-| `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyMemberServiceIsChildTest.java` | cfc-backend | 5 | FamilyMemberServiceIsChild | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyMemberServiceIsChildTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyPlatformPointsServiceCouponTest.java` | cfc-backend | 5 | FamilyPlatformPointsServiceCoupon | `cfc-backend/src/test/java/com/etotem/cfc/service/FamilyPlatformPointsServiceCouponTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/HealthReportServiceAuditConfirmTest.java` | cfc-backend | 8 | HealthReportServiceAuditConfirm | `cfc-backend/src/test/java/com/etotem/cfc/service/HealthReportServiceAuditConfirmTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/service/HealthReportServiceBackfillResilienceTest.java` | cfc-backend | 5 | HealthReportServiceBackfillResilience | `cfc-backend/src/test/java/com/etotem/cfc/service/HealthReportServiceBackfillResilienceTest.java` |
@@ -1044,7 +984,6 @@
 | `cfc-backend/src/test/java/com/etotem/cfc/unit/TaskProgressUpdateTest.java` | cfc-backend | 3 | TaskProgressUpdate | `cfc-backend/src/test/java/com/etotem/cfc/unit/TaskProgressUpdateTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/util/CfFormulaEvaluatorTest.java` | cfc-backend | 8 | CfFormulaEvaluator | `cfc-backend/src/test/java/com/etotem/cfc/util/CfFormulaEvaluatorTest.java` |
 | `cfc-backend/src/test/java/com/etotem/cfc/util/SpearmanUtilTest.java` | cfc-backend | 6 | SpearmanUtil | `cfc-backend/src/test/java/com/etotem/cfc/util/SpearmanUtilTest.java` |
-| `cfc-backend/src/test/java/com/etotem/cfc/util/UserUtilTest.java` | cfc-backend | 6 | UserUtil | `cfc-backend/src/test/java/com/etotem/cfc/util/UserUtilTest.java` |
 
 ## 六、用户场景(`tests/user-scenarios/*.md`,上游输入)
 
@@ -1056,7 +995,6 @@
 | `tests/user-scenarios/04-teacher.md` | `tests/user-scenarios/04-teacher.md` |
 | `tests/user-scenarios/05-admin.md` | `tests/user-scenarios/05-admin.md` |
 | `tests/user-scenarios/06-vendor.md` | `tests/user-scenarios/06-vendor.md` |
-| `tests/user-scenarios/07-five-dimension.md` | `tests/user-scenarios/07-five-dimension.md` |
 | `tests/user-scenarios/README.md` | `tests/user-scenarios/README.md` |
 | `tests/user-scenarios/应用场景总览.md` | `tests/user-scenarios/应用场景总览.md` |
 

+ 0 - 40
docs/tdd/test/test_blockers.md

@@ -30,15 +30,12 @@
 | R2 | API 契约疑似不一致 | 此前发现 `/api/articles/report-reading-time` 返回 `biz=500` 但 `message="success"`(字段语义矛盾);执行 E2E 进一步暴露:① butler 列表返回 `data.list` 而 activity 列表返回 `data.records`(F1);② `POST /api/admin/commission/config` 更新配置返回 **400**(F2,真实接口响应) | 自动化断言无法稳定判定成功/失败,易误报;写操作 E2E 大面积受 envelope 不一致牵连 | 研发在 `cfc.iwintrue.com` 复测确认,明确 `biz` 与 `message` 语义并修复或文档化契约;统一列表 envelopes(F1);排查 commission update config 400(F2) |
 | R3 | 测试环境无可用测试管理员账号 | `tests/e2e/admin-activity-review.spec.js` 等依赖 `/api/admin-auth/login-by-password` 登录取 `Bearer` token;仓库内已硬编码测试账号 `13800138000` | E2E 在登录步即失败,**无法推进带登录态的端到端测试** | **已解决(2026-11-01):已确认测试账号 `13800138000`,实跑 E2E 登录+鉴权+API 全部可达** |
 | R4 | 无 CI 流水线 / 无测试门禁 | 仓库无 `.github/workflows` 等 CI 配置;测试未纳入合并门禁 | 回归无自动拦截,已写测试随改动腐化 | 建 CI:`mvn test` + `pytest` + `playwright`(接 `cfc.iwintrue.com`)作为合并门禁 |
-| R5 | 未授权访问后台登录接口暴露 500 | `POST /api/admin-auth/login`(无 token / 空 body)返回 **500**(`message="手机号和验证码不能为空"`),应为 401/403 | 鉴权前置缺失,异常信息泄露;安全测试无法断言"被拒",存在 5xx 雪崩风险 | 在 `cfc.iwintrue.com` 复测;`admin-auth` 登录对未授权/非法请求统一返回 401/403,缺失参数走参数校验而非抛异常 |
-| R6 | 报告上传未做文件类型 / 安全校验 | `POST` 上传非 PDF(错误/恶意类型)内容**未被拒**(非 4xx) | 存在恶意文件上传与存储风险;安全合规测试无法断言"被拒" | 报告上传增加 MIME/扩展名/内容校验,非 PDF 或异常内容一律 4xx 拒绝 |
 
 ## 3. 新增测试侧阻碍(执行中暴露,直接处理)
 
 | 编号 | 阻碍 | 证据 | 处理 |
 |---|---|---|---|
 | T4 | 主配置 `globalSetup`(`e2e/helpers/db.js`)**强制**连内网 MySQL `192.168.16.251` 做 DB 重置+灌种子,无跳过开关,失败即 `process.exit(1)` | 远程只读 E2E 不需要重置内网库;本沙箱路由不到该内网地址 → `Access denied` 阻断一切 E2E | 已用**临时无重置配置**(`playwright.config.noreset.js`,不提交)绕过;**建议研发给 `db.js` 加 `SKIP_DB_RESET` 开关**,使针对远程测试环境的只读 E2E 可跳过本地库重置 |
-| T5 | 远程测试环境未托管前端 SPA | `cfc.iwintrue.com` 仅部署后端 API(Spring Boot);非 API 路径返回白标 404(见 `e2e/helpers/api.js` 注释) | 约 38 个依赖 `page.goto`/DOM 的 UI 级 `e2e/*.spec.js` 在远程无法运行,会全部失败于"无前端" | 已识别并**排除执行**,避免误导性失败噪音;UI 级 E2E 需在部署了前端的测试环境或本地执行 |
 
 ## 4. 已执行 E2E 结果(只读子集,2026-11-01)
 
@@ -91,40 +88,3 @@
 - **测试侧**:R3 已解决,T1/T2/T3 已执行,T4 已临时绕过(建议研发加 `SKIP_DB_RESET` 开关);写操作 E2E 已按授权跑完(见 §5)。可继续扩大 E2E 覆盖(其余 64 个 `e2e/*.spec.js`)或转向 Java 单测 / Python pytest(本机执行)。
 - **研发侧**:请认领 R1、R2(含 **F1** butler envelope 不一致、**F2** commission update config 400)、R4,并确认 F1/F2 的正确形态。
 - **本机执行项**(Java 单测 / Python pytest):按 `runbook.md` §3.1–§3.3 在开发机执行,结果回填 `.tdd/test-progress.json` 后刷新共享台账。
-
-## 7. 全量 API 级 E2E 实跑结果(2026-11-02,step 1 复跑)
-
-- 范围:对 `cfc.iwintrue.com` 跑**全部可在远程执行的 API 级 spec**(共 10 个:`e2e/api/` 下 7 个 + 3 个 `admin-*.spec.js`),使用测试账号 `13800138000` + 临时无重置配置 `playwright.config.noreset.js`。**69 个用例**,耗时 106s。
-- 权威统计(Playwright `stats`):`expected=59` / `unexpected=7` / `skipped=3`(**无 `passed`**)。
-  - `expected`(59) = 标注 `test.fail()`「预期失败」的用例——用例本就**预期失败**(documenting 已知缺陷),并非功能正常的正向确认。
-  - `unexpected`(7) = **真实失败**(预期应通过却失败,即真实缺陷)。
-  - **结论:整套 API 级 E2E 没有 1 个用例在正向确认功能可用**;59 个"预期失败"只是把已知缺陷固定为 `test.fail()` 标注,CI 即便跑过也是"绿灯"但功能实际是坏的。
-- 注:§4–§5(2026-11-01)按约定把 `test.fail()` 标注用例计为"通过";本次以 Playwright 真实 `stats` 重述:`admin-activity-review`(2)、`admin-butler-review`(2 预期+4 真实)、`admin-commission-config`(3 预期+1 真实) 等"通过"项实为**预期失败(已知缺陷)**,全 10 个 spec 无正向通过。
-
-### 7.1 真实缺陷(unexpected=7,需研发处理)
-
-| 文件 | 用例 | 实际失败 | 根因 / 归属 |
-|---|---|---|---|
-| admin-butler-review | list pending | 断言 `data.records`,接口返回 `data.list` | **F1 复跑确认**:butler 列表 envelope 不一致(R2/F1),**仍未修复** |
-| admin-butler-review | list approved for assignment | 同上 | F1,**仍未修复** |
-| admin-butler-review | review action (approve) | `data.records[0]` 取空崩溃(TypeError) | F1 连带:写请求卡在取数未发出,无副作用 |
-| admin-butler-review | assign member to approved butler | `data.records[0]` 取空崩溃 | F1 连带,无副作用 |
-| admin-commission-config | update config | `POST` 返回 **400**(期望 200) | **F2 复跑确认**:commission update config 400,**仍未修复**(真实接口响应) |
-| api/nonfunc-security | TC-A-N05 非管理员访问后台接口被拒 | 未登录 `/api/admin-auth/login` 返回 **500**(应为 401/403,msg=手机号和验证码不能为空) | **新缺陷 R5**:未授权/admin-auth 登录未做鉴权前置,异常暴露 500 |
-| api/nonfunc-security | TC-P-N11 报告上传非 PDF 被拒 | 上传非 PDF 报告未被拒(非 4xx) | **新缺陷 R6**:报告上传未做文件类型/安全校验 |
-
-### 7.2 测试侧阻碍更新
-
-- **T5(新增)**:`cfc.iwintrue.com` 仅部署后端 API,未托管前端 SPA(非 API 路径返回白标 404)。约 38 个依赖 `page.goto`/DOM 的 UI 级 `e2e/*.spec.js` 在远程**无法运行**,已排除执行;这些 UI 用例需在**部署了前端的测试环境**或**本地**执行。
-- T4 仍有效(建议研发给 `db.js` 加 `SKIP_DB_RESET` 开关)。
-
-### 7.3 测试成熟度结论(重要)
-
-当前 `e2e/api/*` 与 `admin-*` 全部以 `test.fail()` 标注运行:文章(7)/联系人(6)/能量(8)/家庭成员(13)/性能兼容(5)/安全(9) 等模块端到端**整体处于"预期失败"状态**,无正向断言确认功能可用。建议研发/测试协同:
-- 对**已修复**功能:翻转 `test.fail()` → 真实断言,使 CI 能回归拦截;
-- 对**确实缺陷**:保留 `test.fail()` 但单独登记为缺陷(如 F1/F2/R5/R6)跟踪,避免"绿灯但功能坏"的假象。
-
-### 7.4 下一步
-
-- 测试侧:T5 已识别;可转向本机执行 Java 单测 / Python pytest(runbook §3.1–§3.3),结果回填 sidecar。
-- 研发侧:认领 **R5(N05 500)、R6(N11 非 PDF 上传未拒)** 两个新安全/合规缺陷;**F1、F2 复跑确认仍未修复**(R2 项)。