Przeglądaj źródła

docs(sdd): 记录任务 7 计划缺陷 24/25 并同步 PROJECT-OVERVIEW 进度

iwt 2 dni temu
rodzic
commit
5d782beff0

+ 1 - 1
docs/superpowers/PROJECT-OVERVIEW.md

@@ -383,7 +383,7 @@
 
 | 文件 | 状态 | 说明 |
 |------|:----:|------|
-| `2026-10-04-plan-review-workbench.md` | 🟡 进行中(15 任务,任务 0-6 已完成:0 修 test-compile 基线、1 GuideFamilyAccessGuard、2 confirmBind 重绑复位、3 七个端点接入绑定校验、4 rejectPlan 状态守卫 + getPlanForFamily IDOR 反查、5 approveAndPublish 返回 taskGenerated(新增 PlanApproveResultDTO)、6 GuidePlanReviewController 方案审核 4 端点(含 planId IDOR 反查,6/6 绿);任务 7 新增家庭查询端点 → 8 后端整体验证 → 9-13 前端 3 页面 + 分包注册 + families.vue 入口 → 14 文档同步与禁区检查) | 规划师审核工作台实现计划(拆 2 层编排:后端并行 + 前端并行;验收门为 `mvn test-compile` + 纯 Mockito 单测,不依赖真实数据库。⚠️ `pom.xml:28` 有 `<skipTests>true</skipTests>`,跑单测必须显式 `-DskipTests=false`,否则只输出 `Tests are skipped` 的假通过) |
+| `2026-10-04-plan-review-workbench.md` | 🟡 进行中(15 任务,任务 0-7 已完成:0 修 test-compile 基线、1 GuideFamilyAccessGuard、2 confirmBind 重绑复位、3 七个端点接入绑定校验、4 rejectPlan 状态守卫 + getPlanForFamily IDOR 反查、5 approveAndPublish 返回 taskGenerated(新增 PlanApproveResultDTO)、6 GuidePlanReviewController 方案审核 4 端点(含 planId IDOR 反查,6/6 绿)、7 GuideFamilyQueryService/Controller 新增 my-families + members 端点(授权源与 isBound 同源,4/4 绿);任务 8 后端整体验证 → 9-13 前端 3 页面 + 分包注册 + families.vue 入口 → 14 文档同步与禁区检查) | 规划师审核工作台实现计划(拆 2 层编排:后端并行 + 前端并行;验收门为 `mvn test-compile` + 纯 Mockito 单测,不依赖真实数据库。⚠️ `pom.xml:28` 有 `<skipTests>true</skipTests>`,跑单测必须显式 `-DskipTests=false`,否则只输出 `Tests are skipped` 的假通过。⚠️ 路由查重必须按「类级 @RequestMapping 前缀 + 方法级字面量」归一化比较,只比方法字面量会产生假阳性) |
 | `2026-09-10-report-quick-analyze.md` | 🟡 待执行(5 任务:Redis 依赖/配置 + AIChatController 抽 buildChatInputs 新增 report/analyze 端点 + api.js 封装 + report-detail 浮层 + 验证) | 报告快速分析实现计划 |
 | `2026-09-10-key-person-expansion-octopus.md` | 🟡 待执行(12 任务:迁移305-307 三表 + 3实体/Mapper/Service/Controller + 新 OctopusDiagram 三层画布 + 成效/关键人录入页 + action-detail 集成 + API 文档同步 + 旧章鱼图清理) | 关键人拓展章鱼图替换实现计划 |
 | `2026-08-18-homepage-health-funnel.md` | ✅ 已完成(登录态四段式重排 + 自测大卡 + 方法与计算属性 + 样式;未登录态零改动) | 首页健康漏斗实现计划 |

+ 3 - 1
docs/superpowers/plans/2026-10-04-plan-review-workbench.md

@@ -2679,4 +2679,6 @@ cd /sc-data/cfc && git diff --name-only HEAD~14 HEAD | grep -E "chat\.vue|schema
 20. 任务 4 测试辅助方法 `planWithStatus` 固定 `setId(5L)`,而 `getPlanForFamily_匹配返回方案` 用 `selectById(99L)` 打桩却断言 `getId()==99` → 必然失败(实测 `expected: <99> but was: <5>`)→ 该用例需显式 `plan.setId(99L)` 后再打桩。注意同一辅助方法在 `不属于该家庭返回null` 用例中无害(只断言 null)。
 21. 任务 5 步骤 3 预期「`cannot find symbol: class PlanApproveResultDTO`」**不可能发生**——步骤 1 已创建该 DTO。真实 RED 是 `incompatible types: com.etotem.cfc.entity.HealthPlan cannot be converted to com.etotem.cfc.dto.PlanApproveResultDTO`(因 `approveAndPublish` 仍返回 `HealthPlan`)。
 22. 任务 5 步骤 5 的安全性依据「`approvePlan` 无任何页面引用」**不准确**:`cfc-frontend/pages/health/health-plan-summary.vue:272` 确有 `import { ... approvePlan }`。但全仓检索 `approvePlan(` **无任何调用点**(死导入),故改返回类型确实不破坏前端。正确依据是「无调用」而非「无引用」。
-23. 任务 6 `resolvePlan` 的注释「用反查出的真实 familyId 再校验一次,防止路径与库内不一致绕过」**事实错误**:`getPlanForFamily(planId, familyId)` 本身已按 familyId 过滤,`plan.getFamilyId()` 必然等于上一行已通过 `checkFamilyAccess` 校验的 `familyId`,因此 recheck **永不拒绝任何请求**。真正的 IDOR 防线是第一道 `checkFamilyAccess` + `getPlanForFamily` 返回 null 即 403。recheck 调用予以保留(纵深防御、零成本),但注释必须改为「兜底重复校验,勿依赖它拦截路径不一致」,防止后人误判此处存在真实防护而在其他端点放弃校验。
+23. 任务 6 `resolvePlan` 的注释「用反查出的真实 familyId 再校验一次,防止路径与库内不一致绕过」**事实错误**:`getPlanForFamily(planId, familyId)` 本身已按 familyId 过滤,`plan.getFamilyId()` 必然等于上一行已通过 `checkFamilyAccess` 校验的 `familyId`,因此 recheck **永不拒绝任何请求**。真正的 IDOR 防线是第一道 `checkFamilyAccess` + `getPlanForFamily` 返回 null 即 403。recheck 调用予以保留(纵深防御、零成本),但注释必须改为「兜底重复校验,勿依赖它拦截路径不一致」,防止后人误判此处存在真实防护而在其他端点放弃校验。
+24. 任务 7 的 RED 步骤(步骤 3)**排在 Service 创建(步骤 1)之后**,故其预期的 `cannot find symbol: class GuideFamilyQueryService` 不可能出现——与任务 5 缺陷 21 同型。正确顺序:先写 `GuideFamilyQueryServiceTest` → 确认 RED(`cannot find symbol`,实测报错于 import 行与字段声明行)→ 再建 Service。
+25. 任务 7 步骤 7 的路由查重命令**会误报**:`grep -oP '@PostMapping\("\K[^"]*' | sort | uniq -d` 只比较方法级字面量、**忽略类级 `@RequestMapping` 前缀**,因此 `/create`、`/delete`、`/detail`、`/invite-code/generate`、`/list`、`/my`、`/stats`、`/update` 全被报成重复,而它们分属不同控制器、完整路径并不相同。有效查重必须把类级前缀与方法级字面量拼接后按 `METHOD+完整路径` 比较;按此归一化校验,全仓 1688 条映射**零重复**。