tasks_backlog.json 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. {
  2. "version": 1,
  3. "updated": "2026-10-26",
  4. "note": "任务池(T13 盘点补充)。T01-T14 历史条目因仓库迁移丢失,此处从 T15 起重新建档,覆盖 T13 盘点确认的真实缺口;后续巡检补位以本文件为准。",
  5. "discipline": "git fetch origin cfclub → 基于 origin/cfclub 新建 feature/<slug> 分支(不要合并主干);只 git add 自己新增/修改的文件(禁止 git add .);先 mvn -pl cfc-backend -am compile 通过,再 cfc-web npm run build/lint 通过;不新增 DB 迁移,除非文档明确要求;任务完成后必须自行 git commit(提交信息写明任务号与改动摘要),并 git push -u origin feature/<slug>;完成后直接回报 commit 哈希、改动文件清单、编译/构建结果;无需等待主理人确认即可提交;不要自行合并 cfclub;若指定规格文档在 checkout 中不存在,请停止并在回复中说明,不要凭空实现。",
  6. "tasks": [
  7. {
  8. "id": "T15",
  9. "title": "规划师培训认证前端:认证中心/课程/题库管理端 + 小程序培训中心页",
  10. "priority": "P0",
  11. "module": "fullstack",
  12. "instance": "",
  13. "status": "done",
  14. "spec": "docs/superpowers/specs/2026-10-22-planner-learning-assessment-gate-design.md",
  15. "prompt": "规格文档 2026-10-22-planner-learning-assessment-gate-design.md 后端已全量落地(迁移394-401 九表 + PlannerCertificationService 认证状态机 + PlannerCertificationGuard 中央闸门 + 规划师端7接口 + 管理端26接口),但前端缺失,本任务补齐:①小程序规划师端「培训认证」中心页:展示类别(planner/nutritionist/assessor)认证状态、课程列表与学习进度(planner_courses/planner_course_progress)、考试入口(planner_exam_attempts)、线下课打卡(activity_checkins);②cfc-web 管理端三页:认证看板(审批/状态流转,对接管理端26接口)、课程管理(CRUD + 关联类别)、题库管理(题目/试卷维护);③引导计划:认证通过后 Guide.status=active 的联动说明与失败态提示。落点:cfc-frontend/pages/guide/ 新增 training 相关页面并注册 pages.json;cfc-web/src/views/ 新增 admin 认证管理页 + 路由 + perm 配置;utils/api.js 与 cfc-web/src/api/ 增加对应封装。验收要点:后端已存在的 7+26 接口全部被前端调用;认证状态机 init/learning→exam_passed→certified 在小程序可视可操作;管理端可完成课程/题库维护与认证审批;mvn clean compile 与两前端 node --check/build 通过;不触碰后端 Java 代码(除非发现接口缺口,需先回来汇报)。",
  16. "session_id": "ses_e9183f23cffe6q3vnmLOWy9lyq",
  17. "dispatched_at": "2026-10-24 23:16:26",
  18. "dispatched_to": "lan-248",
  19. "model": "axonhub/deepseek",
  20. "done_at": "2026-10-25 00:51:52"
  21. },
  22. {
  23. "id": "T16",
  24. "title": "后台多渠道发货对话框:按 deliveryType 切换快递/同城/自提/虚拟商品",
  25. "priority": "P1",
  26. "module": "fullstack",
  27. "instance": "",
  28. "status": "done",
  29. "spec": "docs/superpowers/specs/2026-10-22-fulfillment-multi-mode-design.md",
  30. "prompt": "规格 2026-10-22-fulfillment-multi-mode-design.md:管理端发货要对齐微信小程序后台四种方式——快递 logistics_type=1 / 同城配送 2(ProductOrder.deliveryMethod 的注释已含 6=同城配送)/ 用户自提 4(不再跳过微信同步)/ 虚拟商品 3(支付成功自动发货 autoShipVirtualOrder 幂等 fail-open)。现后端已具备 ship(orderNo, shipType, ...) 与 WechatService.uploadShippingInfo 按 logisticsType 1/2/3/4 分流;缺口在 cfc-web 发货对话框仍是旧的仅快递/自提二态(OrderManage.vue / OrderDetail.vue 中 deliveryMethod==2 才显示自提)。本任务:①OrderManage.vue 发货对话框按订单 deliveryMethod 切换表单字段(快递=物流公司+单号;同城配送=配送公司+运单;自提=仅确认提示,仍同步微信 logisticsType=4;虚拟商品=展示自动发货状态,按钮置灰并说明);②OrderDetail.vue 配送方式展示扩展为 1/2/3/4/5/6 全编码可读文案与图标;③确认发货后子订单明细同样是微信对照 logisticsType 传参。落点:cfc-web/src/views/admin/OrderManage.vue、OrderDetail.vue,必要时改 src/api/。验收要点:四类订单发货表单正确切换且微信同步参数类型正确(同城走 logistics_type=2 需单号公司、自提=4 无单号、虚拟=3 自动发货不弹表单);deliveryMethod=6 的订单显示「同城配送」而非「快递」;vue-cli-service build SUCCESS;微信 upload_shipping_info URL 带 /wxa 前缀;不改后端接口签名。",
  31. "session_id": "ses_e9183e8f9ffeXVXv6Wiv5TFKhk",
  32. "dispatched_at": "2026-10-24 23:16:28",
  33. "dispatched_to": "lan-248",
  34. "model": "axonhub/deepseek",
  35. "done_at": "2026-10-24 23:58:46"
  36. },
  37. {
  38. "id": "T17",
  39. "title": "报告快速分析:Redis 每日频控(免费1次/日)+ 付费多轮 + 配额联动",
  40. "priority": "P1",
  41. "module": "backend",
  42. "instance": "",
  43. "status": "done",
  44. "spec": "docs/superpowers/specs/2026-09-10-report-quick-analyze-design.md",
  45. "prompt": "规格 2026-09-10-report-quick-analyze-design.md 与扩展版 2026-09-13-report-quick-analyze-extend-design.md:报告详情页快速分析需免费版每日 1 次 Redis 计数、付费版多轮,复用 chat_graph + AiGateway/langgraph,LangGraph 零改动。现状:后端已有 POST /api/chat/report/analyze(AIChatController#report/analyze,与 /chat/send 共用 buildChatInputs),前端 report-detail.vue 已接入报告反馈入口,但「每日限次」与「付费多轮」尚未落地(代码检索未发现 reportAnalyzeLimit/多轮配额逻辑)。本任务:①引入 Redis 依赖与配置(application.yml 已有 redis 配置则复用),新增 ReportAnalyzeQuotaService:免费用户每日 1 次(key=report:analyze:{userId}:{yyyyMMdd},INCR+EXPIRE),会员按 membership levels features/maxDailyAnalyze 配置次数;②超限返回 Result 明确 message(区分「今日已用完/请升级会员」);③前端 report-detail.vue 消费限次结果:展示剩余次数、超限弹窗带升级入口(跳 membership 页);④付费多轮在同一订单/会话内计数,不可重复刷。落点:cfc-backend/src/main/java/com/etotem/cfc/service/ 新增 QuotaService + AIChatController 限流接线;cfc-frontend/pages/health/report-detail.vue 适配。验收要点:免费用户第 2 次调用被拒且 Redis key 到期后恢复;会员次数准确;mvn clean compile 通过;新增 2-3 个纯 Mockito 单测(不依赖真实 Redis,可用模拟);API_REFERENCE 4.x 同步限次语义。",
  46. "session_id": "ses_e9183dc8fffecmHzAeN1UWqMuu",
  47. "dispatched_at": "2026-10-24 23:16:32",
  48. "dispatched_to": "pub-iwintrue",
  49. "model": "etotem/deepseek",
  50. "done_at": "2026-10-25 00:21:24"
  51. },
  52. {
  53. "id": "T18",
  54. "title": "五维自检深度 AI 集成(P1-1 历史趋势解读 + P1-2 Chat 上下文注入)",
  55. "priority": "P1",
  56. "module": "fullstack",
  57. "instance": "",
  58. "status": "done",
  59. "spec": "docs/superpowers/specs/2026-08-31-self-check-ai-integration-design.md",
  60. "prompt": "规格 2026-08-31-self-check-ai-integration-design.md:P0-1 纯AI替换静态建议与 P0-2 用户点击生成健康计划已在 self-check-result.vue 落地(有 AI 解读区块、生成健康计划按钮、self-check-ai.vue AI出题页),P1-1 历史趋势AI解读与 P1-2 Chat 上下文注入未实现。本任务:①P1-1:自检结果页新增「历史趋势」区块,调后端聚合该成员历次自检得分(FiveDimensionSelfCheck 表按维度)→ 组装上下文 → 走 AiGateway/langgraph chat_graph 生成趋势解读(上升/下降/波动 + 建议),展示折线趋势与 AI 解读文字;②P1-2:AIChatController 或统一上下文中注入最近一次自检摘要(维度分 + 低分项),使 /chat/send 能针对自检结果连续对话;③后端零 LangGraph 改动,仅 Java 侧组装 prompt 上下文(遵循 AiGateway 熔断/超时/Fallback 规范)。落点:cfc-backend/src/main/java/com/etotem/cfc/service/ 新增 SelfCheckTrendService(或扩展 FiveDimensionSelfCheckService)+ AIChatController 上下文注入;cfc-frontend/pages/family/self-check-result.vue 新增趋势区块。验收要点:3 次以上自检记录可出趋势解读;无记录时优雅降级(隐藏区块或引导);Chat 提问「我上次自检哪项最低」能答对;mvn clean compile + node --check 通过;新增单测覆盖上下文拼装与历史聚合。",
  61. "session_id": "ses_e9183d076ffegxj0N2urb9YYoQ",
  62. "dispatched_at": "2026-10-24 23:16:34",
  63. "dispatched_to": "pub-iwintrue",
  64. "model": "etotem/deepseek",
  65. "done_at": "2026-10-25 04:29:24"
  66. },
  67. {
  68. "id": "T19",
  69. "title": "营养商品标注:Product 营养成分信息 + 管理端录入 + 小程序展示",
  70. "priority": "P2",
  71. "module": "fullstack",
  72. "instance": "",
  73. "status": "dispatched",
  74. "spec": "docs/superpowers/plans/2026-10-12-nutrition-product-tagging.md",
  75. "prompt": "实现计划 2026-10-12-nutrition-product-tagging.md:为商城商品补齐营养成分信息(热量/蛋白质/脂肪/碳水/膳食纤维等)与营养标签,支撑饮食推荐按营养学口径排序。现状:Product 实体无营养字段(grep 无 protein/calorie 等字段),Food 实体有 nutritionTags 与营养成分(AdminFoodController 已透出)但商品侧缺失。本任务:①Product 表迁移新增 nutrition 相关列(如 calories_kcal/protein_g/fat_g/carb_g/fiber_g + nutrition_tags JSON 或复用字符串逗号分隔),同步 schema.sql 与 DatabaseInitializer 幂等迁移;②管理端 ProductEdit.vue 加营养成分表单区块(可空,保存 NULL);③小程序 product-detail.vue 展示营养成分表(无数据隐藏区块),推荐接口可按标签过滤;④商品-营养同步:如 dan 商城已有营养数据可复用则做映射导入。落点:cfc-backend schema.sql/DatabaseInitializer + Product 实体/DTO + AdminProductController 保存链路;cfc-web/src/views/admin/ProductEdit.vue;cfc-frontend/pages/discover-detail/product-detail/product-detail.vue。验收要点:mvn clean compile 通过;迁移幂等可重复执行;管理端可保存/回显营养成分;小程序无值不显示、有值正确展示;新增 2-3 个单测(DTO 映射/默认值)。",
  76. "session_id": "ses_e91745133ffebXvnPFXhnF7SBM",
  77. "dispatched_at": "2026-10-24 23:33:31",
  78. "dispatched_to": "local-45278",
  79. "model": "axonhub/deepseek"
  80. },
  81. {
  82. "id": "T20",
  83. "title": "食材营养均衡分析链路落地(diet-ingredient-balance)",
  84. "priority": "P2",
  85. "module": "fullstack",
  86. "instance": "",
  87. "status": "done",
  88. "spec": "docs/superpowers/specs/2026-09-13-diet-ingredient-balance-design.md",
  89. "prompt": "规格 2026-09-13-diet-ingredient-balance-design.md 设计的是饮食均衡分析(按食材类别/营养素覆盖评估家庭成员食谱缺口),目前代码检索未发现对应实现(无 ingredientBalance 相关后端类与前端页面)。本任务按规格落地最小可用的 P0 范围:①后端新增 DietBalanceService:入参家庭成员的饮食偏好/忌口/近期打卡(diet_checkin / diet_preferences),输出五类食材(谷薯/蔬果/肉蛋奶/豆坚果/油盐)覆盖度与缺口建议(缺口建议可调用 AiGateway/langgraph 生成自然语言,失败降级为模板文案);暴露 POST /api/diet/balance 接口(Result 包装 + JWT 鉴权);②小程序新增或复用 diet 页展示均衡结果(雷达/环形 canvas 或纯文本卡片均可),入口放在 dial 打卡页或 diet-index;③涉及新表则优先 DB 迁移幂等,尽量复用现有表。落点:cfc-backend/src/main/java/com/etotem/cfc/service/DietBalanceService.java + controller/diet/DietBalanceController.java + 迁移(如需要);cfc-frontend/pages/diet/ 新增 balance 区块。验收要点:mvn clean compile 通过;接口可按成员返回均衡评分与缺口清单;无打卡数据时给出可用默认分析或友好空态;新增 2 个纯 Mockito 单测;API_REFERENCE 同步新增接口(4.x 递增)。",
  90. "session_id": "ses_e91742972ffeTwqN5eAge61gQp",
  91. "dispatched_at": "2026-10-24 23:33:40",
  92. "dispatched_to": "lan-204",
  93. "model": "axonhub/deepseek",
  94. "done_at": "2026-10-25 00:21:24"
  95. },
  96. {
  97. "id": "T21",
  98. "title": "团队层级树形可视化完善 + 富页面推荐码清理",
  99. "priority": "P2",
  100. "module": "frontend",
  101. "instance": "",
  102. "status": "done",
  103. "spec": "docs/superpowers/specs/2026-09-09-team-hierarchy-design.md",
  104. "prompt": "规格 2026-09-09-team-hierarchy-design.md:团队层级树从下往上生长 + 团队消费额分级统计 + 直推成员消费/CF明细 + 我的推荐人展示 + 去掉富页面推荐码。现状:promotion/team.vue 已有团队统计卡(团队规模/返佣比例/档位)、L1/L2 Tab、成员列表、成长曲线与消费曲线(canvas),后端 CommissionController 已提供 team/team/list/team/consumption/my-referrer/team/tree/team/growth-curve/team/all-members-consumption-curve 等接口;「我的推荐人展示」与「树形生长图」「富页面推荐码移除」未确认落地。本任务:①team.vue 增加「我的推荐人」区块(调 /my-referrer,无推荐人时展示邀请入口);②在现有列表/曲线基础上叠加层级树形视图(用后端 /team/tree 扁平数据递归渲染成员树,方向自下而上为符合规格,如 canvas 成本高可先以嵌套列表+缩进呈现,注明偏离);③检索并移除富(profile)页面的推荐码展示(规格明确要求去掉),并核对 promotion 页不受影响;④消费分级统计(按档位聚合)若接口已存在则前端展示。落点:cfc-frontend/pages/promotion/team.vue、profile 相关页面;必要时补 utils/api.js 封装(后端接口已存在则零后端改动)。验收要点:node --check 通过;我的推荐人/无推荐人引导正确;树形视图数据与 /team/tree 响应一致;富页面不再出现推荐码;不影响现有 L1/L2 列表与曲线。",
  105. "session_id": "ses_e9163b087ffefjmH21pIB4bieD",
  106. "dispatched_at": "2026-10-24 23:51:40",
  107. "dispatched_to": "local-45278",
  108. "model": "axonhub/deepseek",
  109. "done_at": "2026-10-25 10:02:27"
  110. },
  111. {
  112. "id": "T22",
  113. "title": "方案→任务全链路回流传真(plan_json.sections[].tasks 驱动任务中心,含删除/降级兜底验收)",
  114. "priority": "P2",
  115. "module": "fullstack",
  116. "instance": "",
  117. "status": "done",
  118. "spec": "docs/superpowers/plans/2026-09-04-plan-to-task-unification.md",
  119. "prompt": "实现计划 2026-09-04-plan-to-task-unification.md 与本仓库 AGENTS.md 所述:plan_json.sections[].tasks 是唯一事实源,配套 plan-standard-content(2026-08-28)已有 LangGraph 输出 tasks + 正则兜底 + 存量懒加载回填 + 规划师端结构化编辑 UI。任务要求对「方案→任务」全链路做一次端到端确认与收尾:①确认 approveAndPublish 后 HealthPlan 的 plan_json.sections[].tasks 是否正确生成 tasks 实例(source_type=plan,关联 taskId),缺失时是否有懒加载回填兜底;②确认方案删除(2026-10-17 已实施)与每日实例二次删除对 plan 任务同样生效;③确认小程序任务中心 tasks.vue 对 plan 来源任务的展示(来源标签/跳转方案页/完成回写);④管理端/schema:确认无孤儿任务(方案删任务留)与重复生成(重复发布同方案不应重复插任务,应幂等);⑤如发现缺口,修复修复,不做范围外重构。落点:cfc-backend TaskPlanService/GrowthTaskService/HealthPlanService 相关链路 + cfc-frontend/pages/tasks/tasks.vue。验收要点:发布含 tasks 的方案后任务中心可见 plan 任务且不重复;删除方案后其 tasks 级联删除(含每日实例);对存量无 plan_json.tasks 的方案懒加载回填生效;mvn clean compile 通过;补 2-3 个单测覆盖幂等与级联。",
  120. "session_id": "ses_e9163add7ffe5EmrvRRcAB3Adv",
  121. "dispatched_at": "2026-10-24 23:51:41",
  122. "dispatched_to": "local-45278",
  123. "model": "axonhub/deepseek",
  124. "done_at": "2026-10-25 02:23:36"
  125. },
  126. {
  127. "id": "F-8",
  128. "title": "F-8 清理",
  129. "priority": "P2",
  130. "module": "backend",
  131. "instance": "",
  132. "status": "done",
  133. "spec": "docs/superpowers/plans/2026-10-24-cf-value-unification-plan.md",
  134. "prompt": "实现「F-8 清理」。完整规格见仓库内设计文档 docs/superpowers/plans/2026-10-24-cf-value-unification-plan.md(请先读取该文档,定位到「F-8 清理」对应的批次/章节,按其口径实现)。\n\n纪律:\n- git fetch origin cfclub → 基于 origin/cfclub 新建 feature/<slug> 分支(不要合并主干);\n- 只 git add 自己新增/修改的文件;\n- 先 mvn -pl cfc-backend -am compile 通过,再 cfc-web npm run build/lint 通过;\n- 不新增 DB 迁移,除非文档明确要求;\n- 完成后 git push -u origin feature/<slug>,回报 commit 哈希、改动文件清单、编译/构建结果;\n- 不要自行合并 cfclub;\n- 若指定规格文档在 checkout 中不存在,请停止并在回复中说明,不要凭空实现。",
  135. "generated_from": "sync_design_tasks",
  136. "generated_at": "2026-10-25 13:17:06",
  137. "session_id": "ses_e8e7c1499ffe868UgJouwwo1jj",
  138. "dispatched_at": "2026-10-25 13:23:53",
  139. "dispatched_to": "local-45278",
  140. "model": "axonhub/deepseek",
  141. "done_at": "2026-10-25 15:59:37"
  142. },
  143. {
  144. "id": "AL-1",
  145. "title": "后台素材库(asset-library) 恢复续做(上一会话卡死已中断重派)",
  146. "priority": "P1",
  147. "module": "fullstack",
  148. "instance": "",
  149. "status": "done",
  150. "spec": "docs/superpowers/plans/2026-10-26-asset-library-design.md",
  151. "prompt": "规格见 docs/superpowers/plans/2026-10-26-asset-library-design.md;派发指令为 self-contained 内联版(已含 data-layer/后端接口/前端改造/纪律)。上一会话 ses_e8e8cdf6cffeeGoW3oCpGCaTg6 于 lan-248 卡死(24h+无活动、cost=0、未 push)已中断,本会话接手同 worktree /sc-data/cfc/.worktrees/asset-library 续做并 commit+push feature/asset-library。",
  152. "generated_from": "manual-recovery",
  153. "recovered_from": "ses_e8e8cdf6cffeeGoW3oCpGCaTg6",
  154. "session_id": "ses_e8e680a53ffejn9lEv1p5BvFbp",
  155. "dispatched_at": "2026-10-25 13:46:24",
  156. "dispatched_to": "lan-248",
  157. "model": "axonhub/deepseek",
  158. "done_at": "2026-10-25 14:47:13"
  159. },
  160. {
  161. "id": "T23",
  162. "title": "后台报告处理链路追踪 / 归因功能(report-trace)",
  163. "priority": "P1",
  164. "module": "fullstack",
  165. "instance": "",
  166. "status": "dispatched",
  167. "spec": "docs/superpowers/plans/2026-10-26-report-trace-design.md",
  168. "prompt": "实现后台「报告处理链路追踪 / 归因」功能。完整规格见仓库内设计文档 docs/superpowers/plans/2026-10-26-report-trace-design.md(请先读取该文档,按其 §四~§五 口径实现)。\n\n背景与根因(已源码确认):用户上传报告后小程序查不到、也无法对应到成员。根因有二——①链路 A(POST /api/report-parser/upload)建 HealthReportDraft 时 familyId=null、memberId=null,导致 ReportCollectService.insertReport 中 matchFamilyMemberByName(name, familyId) 因 familyId=null 恒返 null,健康报告落入 health_reports 时 family_id=null 且 subject_id=null,成为家庭成员维度不可见的孤儿报告;②现有后台 ReportParseAdminController 只查 health_report_drafts,看不到 DAN 上传(dan_report_uploads/dan_assessment_results)与未知上传(report_unknown_upload)的处理状态。\n\n范围(严格按文档):①后端新增 ReportTraceService + ReportTraceAdminController(/api/admin/report-trace 下 list/detail/retry/bind-member/unknown-list/stats 六接口),四表(health_report_drafts / health_reports / dan_report_uploads(+dan_assessment_results) / report_unknown_upload(+report_unknown_cluster))联查归一化为 TraceNode,展示解析服务(parseMethod/langgraph/opencode/dan_java/unknown_llm)、解析状态、是否已归因+原因、落地报告ID、解析数据摘要(指标数/菌群数/疾病风险数/综合分/items数);②健康报告孤儿(subject_id=null 或 family_id=null)可在后台手动归因:bind-member 调 HealthReportService.bindReportToMember + 回填 familyId + 刷新五维/食材推荐(复用 reassignReport 逻辑);③DAN/未知 重试路由:DAN→DanReportUploadService.reparseUpload,未知→重识别后入链;④前端 cfc-web/src/views/admin/ReportTrace.vue(筛选+表格+详情抽屉+重试/归因按钮),新增独立菜单项「报告链路追踪」,不动既有 report-parse 页。\n\n纪律:\n- git fetch origin cfclub → 基于 origin/cfclub 新建 feature/report-trace 分支(不要合并主干);\n- 只 git add 自己新增/修改的文件;不改动 ReportCollectService / DanReportUploadService / ReportParseAdminController 的公开行为(仅调用);\n- 先 mvn -pl cfc-backend -am compile 通过,再 cfc-web npm run build/lint 通过;\n- 不新增 DB 迁移(仅读现有表);\n- 完成后 git push -u origin feature/report-trace,回报 commit 哈希、改动文件清单、编译/构建结果;\n- 不要自行合并 cfclub;\n- 若指定规格文档在 checkout 中不存在,请停止并在回复中说明,不要凭空实现。\n- 关键源码落点(已核对):ReportCollectService.java:668-737(insertReport/matchFamilyMemberByName 调用)、HealthReportDraftService.java、HealthReportService.java:686(matchFamilyMemberByName)/1282(bindReportToMember)/1304(reassignReport)、DanReportUploadService.java:85(uploadAndParse)/296(reparseUpload)/184(confirmUpload)、ReportParseAdminController.java:43(list)、entity HealthReportDraft/HealthReport/DanReportUpload/ReportUnknownUpload/ReportUnknownCluster/ReportTypeRegistry。",
  169. "generated_from": "manual",
  170. "generated_at": "2026-10-26",
  171. "session_id": "ses_e8e651be9ffe1nrAL6aVGk07bi",
  172. "dispatched_at": "2026-10-25 13:48:59",
  173. "dispatched_to": "local-45278",
  174. "model": "axonhub/deepseek"
  175. },
  176. {
  177. "id": "T24",
  178. "title": "生产 bug:睡眠打卡 /complete 返回 500 + 双身份任务列表不同",
  179. "priority": "P0",
  180. "module": "fullstack",
  181. "instance": "",
  182. "status": "done",
  183. "spec": "docs/superpowers/plans/2026-10-25-task-complete-500-bug.md",
  184. "prompt": "修复生产环境(cfc.etotem.com.cn)两个关联 bug。完整诊断与证据链见 docs/superpowers/plans/2026-10-25-task-complete-500-bug.md,请先读取。根因一句话:睡眠打卡是每日进度型任务,POST /api/health/sleep/create 落库后由 HealthSleepController.create:76-86 以任务归属为准修正成员并调 TaskService.updateCheckinTaskProgress 自动置 completed(awardTaskCompletionRewards:918-921 真落库),但前端 cfc-frontend/pages/growth/sleep-checkin.vue:448-452 又冗余调 POST /api/tasks/{id}/complete(传 self.memberId);叠加双身份(family_members 同 user_id 存在多条「家长本人」重复记录,见 EnergyService:121/263;JwtInterceptor:177-182 用 LIMIT 1 非确定性解析),导致 /complete 命中 TaskService.completeTask:587(task.familyMemberId≠memberId)或 :591(已 completed)返回 null → TaskController:139 吐 500。\n\n分三块(按风险排序,逐一验收):\nA【后端热修·低危·必做】TaskService.completeTask(585-593) 对「本人已完成任务」幂等返回成功(复用既有 result 结构 pointsEarned=0/newBalance=当前积分/needReview=false/alreadyCompleted=true),不再返回 null→500;覆盖 587 与 591 两种触发。\nB【前端正本清源·低危·必做】删除 sleep-checkin.vue:448-452 冗余 /complete 调用(create 已自动完成);并全量排查 daily-checkin/diet-checkin/exercise-checkin/wealth-sub/checkin/emotion-checkin/body-detail/checkin 等打卡页是否存在「create 自动完成 + 再调 /complete」的同类冗余,一律移除或改为幂等。\nC【数据根治·双身份·中高危·需授权】先在备份/从库只读跑诊断 SQL(文档 §三 给出)确认受影响 (user_id, family_id) 重复行范围;再制定合并迁移方案(保留一条主成员、外键 tasks/task_executions/health_*/points_log 迁到保留行、删重复行、加 UNIQUE(user_id, family_id) 允许 user_id IS NULL 的 local 成员);JwtInterceptor:177-182 的 LIMIT 1 改为确定性取值(优先 status=active 且 userId 匹配的『主成员』);成员切换器(FamilyMemberVO.isSelf)对本人去重。\n\n纪律:git fetch origin cfclub → 基于 origin/cfclub 新建 feature/task-complete-500 分支(不要合并主干);只 git add 自己新增/修改的文件;先 mvn -pl cfc-backend -am compile 通过,再 cfc-web 与 cfc-frontend 各自 npm run build/lint 通过;A 不新增 DB 迁移,C 的迁移须在文档明确且经授权;任务完成后 git push -u origin feature/task-complete-500,回报 commit 哈希、改动文件清单、编译/构建结果;不要自行合并 cfclub;prod 部署(prod-etotem)属 manual_only,未经主理人显式授权不得 push 到 prod 分支或触发生产发布——本任务只完成代码与(若授权)迁移,生产发布单独拍板。",
  185. "generated_from": "manual",
  186. "generated_at": "2026-10-25",
  187. "session_id": "ses_e8e2fac76ffeHxTIZMUs8B1SN7",
  188. "dispatched_at": "2026-10-25 14:47:21",
  189. "dispatched_to": "lan-248",
  190. "model": "axonhub/deepseek",
  191. "done_at": "2026-10-25 17:01:01"
  192. },
  193. {
  194. "id": "T25",
  195. "title": "统一成员选择器组件(去重双身份,覆盖所有成员选择页)",
  196. "priority": "P1",
  197. "module": "frontend",
  198. "instance": "",
  199. "status": "done",
  200. "spec": "docs/superpowers/plans/2026-10-25-unified-member-selector.md",
  201. "prompt": "实现「统一成员选择器」组件,消除所有页面把同一用户显示成「本人 + 本人所对应的成员」两项的问题。完整设计见 docs/superpowers/plans/2026-10-25-unified-member-selector.md,先读。\n\n核心约束(务必先读 §一.3):纯前端去重会丢数据——两条重复 family_members 行各自挂着不同任务外键,隐藏一行会导致该行业务数据不可达。因此本任务必须与 T24-C 数据合并(合并重复行 + 外键迁移 + UNIQUE(user_id,family_id))配套;在本任务中组件层只做防御性去重,真正消除重复靠数据层。\n\n范围(严格按文档):\n①新增 cfc-frontend/utils/memberNormalize.js:入参(原始成员数组, viewer)→ 折叠同 user_id 多行为一条,canonical memberId 取 isSelf→active→外键最多→id 最小;保证每用户至多一条且 isSelf 唯一;统一身份键为 familyMemberId(id),userId 仅作折叠依据。\n②新增 cfc-frontend/components/MemberSelector.vue,variant 支持 strip(替代 FamilyMemberStrip)/tabs(替代 DimensionMemberTabs)/minimal(替代 food-query 等内联 member-bar,含家庭总览/个人/各成员);内部先 memberNormalize 再渲染;emit select 带 canonical memberId。\n③P1(用户可见 bug 页,必做):food-query.vue 迁 userId→memberId 主键并改用 MemberSelector;tasks.vue 改用 MemberSelector;用 MemberSelector 替代 FamilyMemberStrip(parent-index/child-index/member-home-detail/action-detail) 与 DimensionMemberTabs(body-detail/wisdom-detail/wealth/index/mind-detail),完整保留 FamilyMemberStrip 长按操作菜单(移除/切换/编辑)逻辑。\n④P2(其余内联选择器,文档 §四清单)逐页替换为 MemberSelector,消除 userId 作主键写法。\n⑤后端配合:/api/food/recommendation/members 等返回 familyMemberId 字段;若未合并数据,列表接口应先按 user_id 折叠下发(同 user 多行→一行 canonical id),避免重复。\n\n纪律:git fetch origin cfclub → 基于 origin/cfclub 新建 feature/unified-member-selector 分支(不合并主干);只 git add 自己新增/修改文件;先 mvn -pl cfc-backend -am compile 通过,再 cfc-frontend node --check / npm run build 通过;不新增 DB 迁移(数据合并在 T24-C);完成后 git push -u origin feature/unified-member-selector,回报 commit 哈希、改动文件清单、编译/构建结果;不要自行合并 cfclub。prod 发布属 manual_only,未经授权不得 push prod 分支。",
  202. "generated_from": "manual",
  203. "generated_at": "2026-10-25",
  204. "session_id": "ses_e8e14dfa7ffeXQdvfhbTOXHCOb",
  205. "dispatched_at": "2026-10-25 15:16:36",
  206. "dispatched_to": "lan-248",
  207. "model": "axonhub/deepseek",
  208. "done_at": "2026-10-25 20:16:33"
  209. },
  210. {
  211. "id": "A1",
  212. "title": "活动时间选择器:选择时即只显示 5 分钟粒度,删除「以 5 分钟为一个单元」提示文案",
  213. "priority": "P1",
  214. "module": "frontend",
  215. "instance": "",
  216. "status": "pending",
  217. "spec": "docs/superpowers/plans/2026-10-26-activity-create-page-ux-and-audience-design.md",
  218. "prompt": "改造小程序「创建活动」页的时间选择器,让 5 分钟粒度在【选择过程中】生效,而不是选中后才被改写。完整设计与代码证据见 docs/superpowers/plans/2026-10-26-activity-create-page-ux-and-audience-design.md 的 §一 与 §零 0.1,请先读。\n\n背景(一句话):现在 3 处时间字段都用微信原生 <picker mode=\"time\">,原生时间选择器不支持步长,只能按 60 分钟逐项滚动,选中后再由 onStartTimeChange/onEndTimeChange/onRegTimeChange 调 normalizeTimeTo5Min 把分钟向下取整到 5 的倍数(14:07→14:05);为此页面上还重复写了 3 句提示「以 5 分钟为一个单元(如 14:00、14:05)」(create.vue:27/39/51,另有 CSS 注释 create.vue:677)。用户明确不想要这句话,也不想要「选了 07 分却变 05 分」。\n\n范围(唯一文件 cfc-frontend/pages/activity/create.vue,只做这一件事):\n①把 3 处 <picker mode=\"time\">(行 24/36/48)改为原生 <picker mode=\"multiSelector\" :range=\"[hourOptions, minuteOptions]\" :value=\"[hourIdx, minuteIdx]\">,时列 ['00'..'23'] 共 24 项,分列严格只有 ['00','05','10','15','20','25','30','35','40','45','50','55'] 共 12 项,让用户在选择过程中就无法选中非 5 倍数分钟。\n②data 新增 hourOptions/minuteOptions 与 3 组时间各自的时/分索引(hourIdx/minuteIdx、endHourIdx/endMinuteIdx、regHourIdx/regMinuteIdx);新增 onStartTimeColChange/onEndTimeColChange/onRegTimeColChange(e) 取 e.detail.value(列索引数组)拼成 HH:MM 写入 timePart/endTimePart/regTimePart,再调用既有 syncStartTime/syncEndTime/syncRegDeadline。\n③日期逻辑完全不动:onStartDateChange/onEndDateChange/onRegDateChange → syncXxx 保持现状;提交串必须仍为 YYYY-MM-DDTHH:mm:00、秒恒 00。\n④删除 3 处 <text class=\"picker-hint\">…</text>(行 27/39/51);并删除行 677 那条「活动时间以 5 分钟为一个单元」的 CSS 注释。\n⑤索引与字符串必须双向同步:fmtTime 回填(create.vue:593-599)与 loadDetail 三处回填(create.vue:300-324)在 normalizeTimeTo5Min 之后要按 mi/5 反算分钟索引,否则 picker 会显示默认值 00:00。建议抽一个 applyTimeParts(timePart, hourIdxRef, minuteIdxRef) 供初始化与回填共用。\n⑥normalizeTimeTo5Min 必须保留作为兜底(历史脏数据、后台或接口写入非 5 倍数时仍能收敛),不要删。\n\n明确不做(超出范围,做了一定要停手汇报):不做结束时间≥开始时间、报名截止时间≤开始时间等业务校验(现状本来就没有);不动后台 cfc-web/src/views/admin/ActivityEdit.vue 的 element-ui datetime 面板(element-ui 2.x 不支持分钟步长,维持现状 @change 收敛);不动任何费用字段、不做适用人群(那是 A2/A3)。\n\n验收:①分列恰好 12 项且选择过程中无法选中非 5 倍数分钟;②grep \"以 5 分钟为一个单元\" cfc-frontend/pages/activity/create.vue 零命中(含 CSS 注释);③normalizeTimeTo5Min 1440 分钟全量扫描仍全部正确(可把 <script> 提取为 .mjs 跑 node --check + 全量灌入);④提交串恒为 YYYY-MM-DDTHH:mm:00、秒恒 00;⑤编辑既有活动且历史时间为非 5 倍数(如 14:07)时,回填后 picker 显示与提交值一致(均为 14:05);⑥<template> 经 vue-template-compiler 编译零 error。\n\n纪律:git fetch origin cfclub → 基于 origin/cfclub 新建 feature/activity-time-picker 分支(不要合并主干);只 git add 自己修改的这一个文件(禁止 git add .);完成后自行 git commit(提交信息写明任务号 A1 与改动摘要)并 git push -u origin feature/activity-time-picker,回报 commit 哈希、改动文件清单与验证结果;无需等待主理人确认即可提交;不要自行合并 cfclub;prod 发布属 manual_only,未经授权不得 push prod。若规格文档在 checkout 中不存在,请停止并在回复中说明。"
  219. },
  220. {
  221. "id": "A2",
  222. "title": "活动适用人群 + 费用模型重构(audienceScope/audienceType + 结算按参与者身份分类 + 仅会员硬门禁)",
  223. "priority": "P1",
  224. "module": "fullstack",
  225. "instance": "",
  226. "status": "pending",
  227. "spec": "docs/superpowers/plans/2026-10-26-activity-create-page-ux-and-audience-design.md",
  228. "prompt": "重构活动的人群与费用模型。完整设计、字段表、迁移写法与结算伪代码见 docs/superpowers/plans/2026-10-26-activity-create-page-ux-and-audience-design.md 的 §二(2.1–2.5)与 §零 0.2,请先读。\n\n现状两个必须修的缺陷:\n①两端口径分裂:小程序创建页只填 childFee/childMemberFee/parentFee/parentMemberFee(create.vue:67-85),后台管理端只填 price/memberPrice(cfc-web/.../ActivityEdit.vue:140-153),两套列互不互通,后台设的价小程序填不了、小程序填的价后台改不了。\n②结算语义错误:ActivityOrderService.java:81-84 用 boolean isChild = memberId != null 决定收 childFee 还是 parentFee,快照 type 写死 \"child\"/\"parent\"。在统一成员选择器(T25)之后 memberId 可以是儿童/长者/配偶等任意家庭成员,不能一律当「孩子」收费;快照 type 同理。\n\n实现(按 §二 2.1–2.5):\n①数据层:新增 audience_scope VARCHAR(20) DEFAULT 'all'(取值 all / member_only)、audience_type VARCHAR(20) DEFAULT 'adult'(取值 adult / include_child / include_elder / include_child_elder),用 DatabaseInitializer 既有的 information_schema.COLUMNS 存在性检查范式(参考行 2254-2266 的 visible_scope 迁移),ALTER TABLE 定位 AFTER visible_to。【长者价格列不新增】——长者复用成人价,audienceType 只留长者标签用于展示与筛选(D1 默认口径)。Activity 实体与 ActivityDTO 同步新增两个字段;ActivityRegistration 及报名参数不变。\n②表单(小程序 cfc-frontend/pages/activity/create.vue):新增 audienceScope 单选(全部用户 / 仅会员参加)与 audienceType 多选(成人 / 含儿童 / 含长者,成人恒选);新增「价格(元)」「会员价(元)」两个输入对应 price/memberPrice 并始终可见(当前完全缺失);孩子费用两档仅在 audienceType 含 child 时显示,隐藏时提交写 0;长者不出现独立价格输入。\n③结算(cfc-backend ActivityOrderService.java:81-91):删掉 isChild = memberId != null,改为按参与者身份分类 self(本人,memberId 为空)/child(age<18)/elder(age>=60)/adult(其他成年家庭成员),分别取 price|memberPrice、childFee|childMemberFee、price|memberPrice、price|memberPrice;会员判定沿用现有 membershipService.getMemberLevel(userId) 的 FAMILY/PREMIUM 口径;依据只用 FamilyMember 现有 age/generation/isSpouse,不新增角色字段。快照 type 改为 self/child/elder/adult(去掉 \"parent\" 这个语义)。关键回归点:FamilyMember.age 为空一律回落 adult,绝不可当 child 处理(否则会多收费)。\n④仅会员硬门禁(§二 2.5):audienceScope=member_only 时在下单入口既有校验块(ActivityOrderService.java:55-64)之后追加后端拦截,非会员返回「该活动仅会员可参加」;非登录用户(userId 为空)必须拒绝并走引导登录。前端提示仅作体验优化,不以前端为准。范式对齐 TaskController.java:48 的 task.memberOnly。\n⑤兼容存量(必须实现,§二 2.4):audience_type 为空视为 adult,成人档取值按「优先新列回退旧列」——非会员价 price>0?price:parentFee,会员价 memberPrice>0?memberPrice:parentMemberFee,儿童档 childFee/childMemberFee 原样保留。即 parentFee 降级为「成人非会员价」的历史别名,不做数据回迁,不改存量活动收费。\n\n本任务【不做】展示层改造(活动详情/列表/海报/报名弹窗的展示在 A3,避免两个会话同时改 activity-detail.vue);【不做】任何家长/孩子措辞清理(属 G1);【不做】child_id→member_id 列名迁移(属 G2)。\n\n验收:①information_schema 确认两列已建且 DEFAULT 生效;②mvn -pl cfc-backend -am compile 通过;③audienceScope=member_only + 非会员下单被拒并返回指定文案,非登录用户被引导登录;④报名人 age 为空时按成人档计费(不得误判为儿童);⑤老活动(audience_type 为空)结算金额与改造前逐分一致——用 price/parentFee/memberPrice/parentMemberFee 四个字段各非空、组合覆盖 4 种取值路径各测一例;⑥免费活动(totalAmount==0)的免报名快照分支行为不变;⑦小程序 <script> node --check 通过、模板 vue-template-compiler 零 error。\n\n纪律:git fetch origin cfclub → 基于 origin/cfclub 新建 feature/activity-audience-fee 分支(不要合并主干);只 git add 自己新增/修改的文件(禁止 git add .);先 mvn -pl cfc-backend -am compile 通过再改前端;完成后自行 git commit(提交信息写明 A2 与改动摘要)并 git push -u origin feature/activity-audience-fee,回报 commit 哈希、改动文件清单、编译结果与验收⑤的四例对比数据;无需等待主理人确认即可提交;不要自行合并 cfclub;prod 发布属 manual_only,未经授权不得 push prod。若规格文档在 checkout 中不存在,请停止并在回复中说明。"
  229. },
  230. {
  231. "id": "A3",
  232. "title": "活动费用展示层口径统一(小程序详情/列表/海报/报名弹窗 + 后台管理端适用人群)",
  233. "priority": "P1",
  234. "module": "fullstack",
  235. "instance": "",
  236. "status": "pending",
  237. "spec": "docs/superpowers/plans/2026-10-26-activity-create-page-ux-and-audience-design.md",
  238. "prompt": "把活动费用的展示层全部统一到「成人/儿童/长者 × 会员/非会员 + 适用人群」新口径。完整字段表、逐文件改造表与验收见 docs/superpowers/plans/2026-10-26-activity-create-page-ux-and-audience-design.md 的 §二 2.6,请先读。本任务依赖 A2 已合入(audience_scope / audience_type / price / memberPrice / childFee / childMemberFee 字段与后端分类逻辑已就绪),开始前先确认 A2 提交已在分支基线上。\n\n要改的地方(照 §二 2.6 表格逐条):\n①cfc-frontend/pages/activity/activity-detail/activity-detail.vue:61-62 现在恒显「孩子:¥…」「家长:¥…」——改为按 audienceType 条件渲染:成人档恒显,儿童/长者档仅当 audienceType 含该类别且对应价格 > 0 才显示;标签文案用「成人」「儿童」「长者」,不得再出现「家长」「孩子」。\n②同文件 827/829 海报价格文案「(家长)」「(孩子)」→ 按 audienceType 选「(成人)」「(儿童)」「(长者)」。\n③同文件 hasFee(977-985) / hasMemberPrice(982-985) 现在只读 4 个 child/parent 字段,必须纳入 price/memberPrice——否则只填成人价、childFee/parentFee 全 0 的付费活动会被误显为「免费」,这是必须修的真实 bug。\n④同文件 minFeeText(1008-1015) 取 4 费最小值 → 改为取「当前用户可用档位」的最小值(会员用会员价列,非会员用非会员价列)。\n⑤cfc-frontend/pages/activity/index.vue:852-857 normalizeActivity 现在用 4 个 child/parent 费用的最小值覆盖 act.price —— 改为不再覆盖 price,仅在 price 为空时回落 parentFee(兼容老活动)。\n⑥报名弹窗 activity-detail.vue:246-300:报名人目前只有姓名+手机+家庭成员勾选,看不出每个人按哪个价收费——为每个报名人加身份标签(成人/儿童/长者)与对应单价展示。\n⑦后台 cfc-web/src/views/admin/ActivityEdit.vue:在 140-153 的价格区之后追加 audienceScope(单选)与 audienceType(多选)表单项,条件显示儿童费用两档,字段读写对齐 A2 的 DTO 字段名,保存后回显正确;后台与小程序保存出来的活动数据必须一致。\n\n本任务【不做】时间选择器改造(属 A1);【不做】数据层与结算逻辑(属 A2);【不做】其他页面的家长/孩子措辞清理(属 G1,且 G1 明确排除 activity-detail.vue 与 create.vue,避免与本任务冲突)。\n\n验收:①audienceType=adult 的活动详情页完全不出现「儿童」「长者」「孩子」「家长」字样;②只填 price/memberPrice、childFee 与 parentFee 全 0 的付费活动,详情页正确显示价格且不再误显「免费」(这是回归重点);③报名弹窗按报名人身份显示对应单价;④后台可设置并回显 audienceScope/audienceType,两端数据一致;⑤海报价格文案无「家长」「孩子」;⑥小程序 node --check 与模板编译通过、cfc-web vue-cli-service build 通过。\n\n纪律:git fetch origin cfclub → 基于 origin/cfclub 新建 feature/activity-fee-display 分支(不要合并主干);只 git add 自己新增/修改的文件(禁止 git add .);先编译再构建;完成后自行 git commit(写明 A3 与改动摘要)并 git push -u origin feature/activity-fee-display,回报 commit 哈希、改动文件清单、构建结果与验收②的回归结论;无需等待主理人确认即可提交;不要自行合并 cfclub;prod 发布属 manual_only,未经授权不得 push prod。若规格文档在 checkout 中不存在,请停止并在回复中说明。"
  239. },
  240. {
  241. "id": "G1",
  242. "title": "全系统「家长/孩子」措辞清查:L1 文案层统一为本人/家庭成员/儿童/长者",
  243. "priority": "P2",
  244. "module": "fullstack",
  245. "instance": "",
  246. "status": "pending",
  247. "spec": "docs/superpowers/plans/2026-10-26-activity-create-page-ux-and-audience-design.md",
  248. "prompt": "清理全系统用户可见的「家长」「孩子」措辞,统一为中性口径。现状分布数据、分层策略与排除范围见 docs/superpowers/plans/2026-10-26-activity-create-page-ux-and-audience-design.md 的 §三,请先读。\n\n前提认知(重要):系统身份模型只有【登录用户】与【非登录用户】,家庭成员是家庭成员(FamilyMember 模型已是 nickname/age/generation/isSpouse 的中性口径)。因此「家长」「孩子」这类亲子关系表达只应作为【家庭成员的人群标签】出现(儿童/长者/成人),不应作为系统角色出现。数据模型本身没错,遗留集中在文案、API 名、页面目录名、后端方法名与日志文案。\n\n本任务只做 L1 文案层(低风险):\n①小程序前端 cfc-frontend/pages 与 components 下所有 .vue 的【用户可见文字】:「家长」→「本人」或「家庭成员」,「孩子」→「家庭成员」或按上下文用「儿童」,涉年龄的表述用「成人/儿童/长者」。已知命中较多的文件(cfclub tip 实测):body-detail/dimension-questionnaire.vue(17)、home-pages/parent-index.vue(11)、index-home/index.vue(9)、rewards/rewards.vue(8)、wealth/index.vue(7)、parent/child-detail.vue(6)、child/tasks.vue(6),以及 member-detail、child/rewards、teacher-profile、policy/privacy、mind-detail、wishes/detail、tasks/review、profile/components/ProfileHeader 等。请以 grep 结果为准全量覆盖,不要只看这个清单。\n②后端返回给前端的用户可见文案:toast / Result.error 提示语 / 消息模板 / 订阅消息模板 / 推送文案中的「家长」「孩子」同样替换。已知命中较多的:EnergyService(57)、WishService(28)、TaskService(25)、RewardService(25)、FamilyMemberService(24)、UserService(16)、WechatAlertTemplateService(11)、CircleMatchService(10) 等。DatabaseInitializer.java(66) 命中多但多为种子数据与注释,【只改其中会作为用户可见文案下发的种子字符串】,纯注释与列注释不动。\n\n严格排除(做了就超范围,必须停手汇报):\n①不改 DB 列名、不改 API 路径、不改页面目录、不改 pages.json 路径、不改 Java 方法名与变量名(这些属 G2);\n②不改 cfc-frontend/pages/activity/activity-detail/activity-detail.vue 与 pages/activity/create.vue(A2/A3 正在改这两个文件,会冲突);\n③不改 utils/api.js 的函数名(属 G2);\n④不改 dist/ 与 unpackage/ 构建产物;\n⑤不删除或改写 policy/privacy.vue 中涉及未成年人保护的合规表述(只把「家长」按语境替换为「监护人」这类合规词,如判断不清就保留原样并在回报中列出)。\n\n验收:①grep -rl \"家长\\|孩子\" cfc-frontend/pages cfc-frontend/components --include=\"*.vue\" 结果为空,或仅剩白名单文件(如 policy/privacy.vue 的合规表述)并在回报中逐个说明理由;②后端返回给前端的文案中无「家长」「孩子」(可用 grep 排除列注释后核对);③DB 列名、API 路径、页面目录、pages.json、Java 方法名 git diff 中【零改动】;④mvn -pl cfc-backend -am compile 与小程序 node --check / 模板编译全部通过。\n\n纪律:git fetch origin cfclub → 基于 origin/cfclub 新建 feature/terminology-neutralize-l1 分支(不要合并主干);只 git add 自己修改的文件(禁止 git add .);完成后自行 git commit(写明 G1 与改动摘要)并 git push -u origin feature/terminology-neutralize-l1,回报 commit 哈希、改动文件清单、验收①的白名单说明、编译结果;无需等待主理人确认即可提交;不要自行合并 cfclub;prod 发布属 manual_only,未经授权不得 push prod。若规格文档在 checkout 中不存在,请停止并在回复中说明。"
  249. },
  250. {
  251. "id": "G2",
  252. "title": "契约/目录/DB 列名中性化(L2 前端契约与页面目录 + L3 后端内部命名)",
  253. "priority": "P3",
  254. "module": "fullstack",
  255. "instance": "",
  256. "status": "pending",
  257. "spec": "docs/superpowers/plans/2026-10-26-activity-create-page-ux-and-audience-design.md",
  258. "prompt": "风险最高的一批:把 parent/child 命名从契约层与存储层清掉。必须先读 docs/superpowers/plans/2026-10-26-activity-create-page-ux-and-audience-design.md 的 §三 3.2 与 §三 3.3(冲突面提示),再读 T25 的设计文档 docs/superpowers/plans/2026-10-25-unified-member-selector.md 了解已完成的部分。\n\n前置条件(不满足就停止并回报,不要硬做):①T25「统一成员选择器」所有批次已完全收口合入主线;②G1 文案层已完成合入;③本任务开工前需主理人对 DB 列名迁移方案单独确认(本任务的 L3 包含活动报名表 child_id → member_id 的列迁移,属破坏性变更)。\n\n范围(照 §三 3.2 的 L2 + L3):\nL2 前端契约与页面层:①cfc-frontend/utils/api.js 为遗留函数增加中性别名(getChildren→getFamilyMembers、switchToChild→switchToFamilyMember、switchBackToParent→switchBackToSelf、getParentDashboard→getFamilyDashboard、getChildOverview→getMemberOverview、createChild→addFamilyMember 等),【旧函数名必须保留为转发别名】,不得直接删除(外部可能引用);②pages/parent/、pages/child/ 迁到 pages/family/,pages/home-pages/parent-index.vue 与 child-index.vue 改中性名,pages.json 同步;③【旧路径必须保留跳转壳】(wx.redirectTo 到新路径),因为小程序已发布版本仍在用旧路径;④cfc-web 侧同步(api/、router/index.js、views 下 admin 页面引用)。\nL3 后端内部层:①Java 方法名与变量名中性化(childId→memberId、isChild→isMinorMember、ParentController→FamilyMemberController 等);②ActivityRegistration 的 DB 列 child_id → member_id:新增 member_id 列 + 数据回填 + 双写过渡 + 旧列保留一个版本,外键引用面(activity_registrations 及相关查询)必须先出影响清单再动手;③DatabaseInitializer 中 child 语义的种子数据与列注释同步。\n\n严格禁止:①不得重做成员去重逻辑(T25 已完成,MemberSelector.vue / memberNormalize.js / member_normalize 相关代码只在必要处做重命名,不得改算法);②不得改动与成员语义无关的业务逻辑;③不得动 Activity.childFee/parentFee 的语义(已由 A2 降级为别名,不要再动)。\n\n验收:①旧 API 函数名全部仍可调用且转发到新别名(逐个 grep 确认调用点零断链);②旧页面路径重定向可用;③pages.json 与新目录一致;④child_id→member_id 迁移脚本可重复执行(幂等),迁移前后记录数一致且抽样行内容一致;⑤mvn clean compile、cfc-frontend node --check、cfc-web build 全部通过;⑥报名/取消/退款链路(ActivityRegistrationService.register/cancel/refund)回归通过。\n\n纪律:git fetch origin cfclub → 基于 origin/cfclub 新建 feature/terminology-neutralize-l2-l3 分支(不要合并主干);只 git add 自己新增/修改的文件(禁止 git add .);开工前先在回复里给出 child_id 影响面清单与迁移方案供主理人确认,确认后再动列名;完成后自行 git commit(写明 G2 与改动摘要)并 git push -u origin feature/terminology-neutralize-l2-l3,回报 commit 哈希、改动文件清单、编译构建结果与回归结论;无需等待主理人确认即可提交代码到特性分支;不要自行合并 cfclub;prod 发布属 manual_only,未经授权不得 push prod。若规格文档在 checkout 中不存在,请停止并在回复中说明。"
  259. }
  260. ]
  261. }