|
|
@@ -0,0 +1,116 @@
|
|
|
+# 研发负责人工作汇报(人工轮)
|
|
|
+
|
|
|
+> **说明**:本报告由研发负责人(Dev Lead)针对「任务池为空」人工盘点覆盖度断层,并处置用户实测反馈的两项会员缺陷。数据取自 `state.json`、`sc-key-map.md`、源码与 git 真理证据(`git merge-base --is-ancestor origin/cfclub`)。时间:2026-11-12 23:20。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 一、背景:池空触发覆盖度断层盘点
|
|
|
+
|
|
|
+自动化池空第 32/33 轮(148/149 轮汇报)确认目标池空。研发负责人按「需求变更人工复核 git + SC 台账交叉分析」纪律,对 241 SC 与状态机能力键做双向覆盖度核验,定位到**商城/会员/服务商域**为真实能力键断层(Controller 27+ 已合入 `origin/cfclub`,但状态机无对应 `shop.*` / `membership.*` / `supplier.*` 键)。
|
|
|
+
|
|
|
+### 1.1 覆盖度断层数据(盘点时基线 88 键)
|
|
|
+
|
|
|
+| 维度 | 数值 | 说明 |
|
|
|
+|------|------|------|
|
|
|
+| SC 台账 | 241 SC | 游客 12 / 家长 96 / 孩子 26 / 规划师 32 / 运营 25 / 服务商 11 / 跨角色 22 / AI 成长教练 10 / 真人管家 7 |
|
|
|
+| 累计已跑通 | 15 SC | O-3 收口 5(SC-G-02/06/P-03/10/11,sha 8051b64f1/df2364ba3/f1b0e3ed5/f41da2779/291955bce)+ 游客域 10(SC-G-01/03/04/05/07/08/09/10/11/12,sha dceeaaeaf) |
|
|
|
+| 未跑通 | 226 SC | 按角色:家长 93 / 规划师 32 / 孩子 26 / 运营 25 / 跨角色 22 / 服务商 11 / AI 教练 10 / 真人管家 7 |
|
|
|
+| 状态机能力键 | 88→**95** | RED 1 / YELLOW 71 / GREEN 8 / DONE 15(本轮 +7 新键) |
|
|
|
+| 台账↔状态机断层 | 双向 | 221 SC 键列为「—」;69 状态机键未被台账引用(guhe 15 / team 10 / admin 9 / family 16 / …) |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 二、本轮建键(7 条,RED→YELLOW 闭环推进)
|
|
|
+
|
|
|
+### 2.1 覆盖度断层入池(6 条,S-cfc-164~169,均已完成 RED 契约测试闭环)
|
|
|
+
|
|
|
+| 任务 | 能力键 | SC 溯源 | 设计溯源 | red_sha | 状态 |
|
|
|
+|------|--------|---------|----------|---------|------|
|
|
|
+| S-cfc-164 | `shop.product.browse` | SC-P-52(商品浏览/搜索)、SC-P-53(商品详情) | API_REFERENCE §4.8 商品与订单 /api/product/list, /api/product/detail | 07a992161 | YELLOW(red IN_CHAIN ✓) |
|
|
|
+| S-cfc-165 | `shop.order.create` | SC-P-54(加购/下单)、SC-P-55(订单支付) | §4.8 /api/product/order/create, /api/product/order/pay | 6d31293cf | YELLOW(red IN_CHAIN ✓) |
|
|
|
+| S-cfc-166 | `shop.order.queryRefund` | SC-P-56(订单查询/退款) | §4.8 /api/product/order/my, /api/product/order/refund/apply | 7b2eadd05 | YELLOW(red IN_CHAIN ✓) |
|
|
|
+| S-cfc-167 | `shop.coupon.apply` | SC-P-57(优惠券使用) | §4.32 优惠券 /api/coupon/list,my,apply,claim,available-templates | 7c16640cb | YELLOW(red IN_CHAIN ✓) |
|
|
|
+| S-cfc-168 | `membership.plan.purchase` | SC-P-58(购买会员/套餐)、SC-P-59(会员权益查看)、SC-P-60(会员续费) | §4.50 会员权益对比 /api/membership/compare + §4.43 赠会员 /api/membership/gift-membership-progress | 4d999a0fe | YELLOW(red IN_CHAIN ✓) |
|
|
|
+| S-cfc-169 | `supplier.order.fulfill` | SC-S-03(订单处理发货)、SC-S-04(订单核销到店)、SC-S-08(对账/结算) | §4.8 /api/product/order/vendor,vendor-confirm,ship | e812440b0 | YELLOW(red IN_CHAIN ✓) |
|
|
|
+
|
|
|
+### 2.2 用户反馈缺陷入池(1 条,S-cfc-178,RED 待派发)
|
|
|
+
|
|
|
+| 任务 | 能力键 | SC 溯源 | 设计溯源 | 处置 |
|
|
|
+|------|--------|---------|----------|------|
|
|
|
+| S-cfc-178 | `family.familyMembers.removeMember` | SC-P-06(移除/删除成员)+ 用户实测缺陷(见 §四) | API_REFERENCE §4.2 /api/family/member/kick, /api/family/member/leave(已合入 cfclub) | RED,pending 派发 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 三、台账回填(sc-key-map.md 13 处,commit 6b332da94 已推)
|
|
|
+
|
|
|
+按 O-2 方案 A(SC 编号入 requirement/design、能力键进台账),本轮把 13 处 SC 行由「—」回填为已建键:
|
|
|
+
|
|
|
+| SC | 能力键 | SC | 能力键 |
|
|
|
+|----|--------|----|--------|
|
|
|
+| SC-P-52 / 53 | `shop.product.browse` (RED) | SC-P-58 / 59 / 60 | `membership.plan.purchase` (RED) |
|
|
|
+| SC-P-54 / 55 | `shop.order.create` (RED) | SC-S-03 / 04 / 08 | `supplier.order.fulfill` (RED) |
|
|
|
+| SC-P-56 | `shop.order.queryRefund` (RED) | SC-P-06 | `family.familyMembers.removeMember` (RED) |
|
|
|
+| SC-P-57 | `shop.coupon.apply` (RED) | | |
|
|
|
+
|
|
|
+回填后剩余未映射 SC:215(241−13−13 已映射未跑通=215);状态机键数 88→95。commit `6b332da94a279b736750559e5731996052cedcdb`(单文件 `docs/tdd/orchestration/sc-key-map.md`,`git diff --name-status origin/cfclub <commit>` 仅 1 行 M,已 `git push origin <sha>:cfclub`,`merge-base --is-ancestor` 核验 IN_CHAIN ✓)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 四、用户实测反馈的两项会员缺陷(定位 + 处置)
|
|
|
+
|
|
|
+### 4.1 缺陷 #1:新用户「无开通会员入口」
|
|
|
+
|
|
|
+**现象**:新注册用户(`familyId == null`)反馈找不到开通会员的入口。
|
|
|
+
|
|
|
+**根因定位(源码证据)**:
|
|
|
+- 前端入口存在:`pages/profile-main/profile.vue` 78-91 行(会员卡「立即开通」按钮,`@click="goUpgrade"`)与 `pages/membership/index.vue` 37-40 行(会员中心「立即开通会员」按钮,`@click="goUpgrade"`),**均不依赖 `familyId` 渲染**——新用户可见入口。
|
|
|
+- 后端 `/api/membership/my`(`MembershipController:71-116`)对 `familyId == null` 返回 FREE 占位,**不报错**。
|
|
|
+- 后端 `/api/membership/plans`(`MembershipController:337-367`)**无 user 校验**,直接返回可购档位。
|
|
|
+- **真正断点**:`MembershipService.createOrder`(`MembershipService:394-397`)硬校验 `if (familyId == null) throw RuntimeException("请先创建或加入家庭后再购买会员")`;`/upgrade` 与 `/trial` 调用 `MembershipController.upgradeOrder/activateTrial` 时传入 `membershipService.getUserFamilyId(userId)`(**返回 null,不自动创建**)——**下单即失败**。用户观感「没有入口」实为「下单 100% 失败」。
|
|
|
+
|
|
|
+**修复方案(待主理人裁决)**:
|
|
|
+- **方案 A(推荐 · 最小改动 · 自助闭环)**:`/upgrade` 与 `/trial` 改用 `MembershipService.getOrCreateUserFamilyId(userId)`(`MembershipService:112`,已有方法),购买时 `familyId==null` 自动创建初始家庭(`"我的家庭"`,`isFamilyAdmin=true`),与 FamilyMemberService 中被踢用户迁移自有家庭的既有语义一致。购买后会员生效于自己一人,后续可邀请家人升级共享。风险低:不动前端、不动家庭业务主流程。
|
|
|
+- **方案 B(产品语义保守)**:前端识别 `familyId == null` 时引导用户先「创建/加入家庭」再购买。改动面大(新增引导页/弹窗/状态机),需产品确认交互。
|
|
|
+- **方案 C(维持现状 + 明确错误提示)**:后端返回明确业务错误码(前端已可透出 `请先创建或加入家庭后再购买会员`),配合方案 B 的引导。若产品认可「购买前必须有家庭」,则 #1 不是缺陷而是产品约束。
|
|
|
+
|
|
|
+**处置**:问题 #1 属于**实现/产品语义决策**(非能力键缺失),SC-P-58 已由 S-cfc-168 覆盖(YELLOW,契约测试已过但**未覆盖「无家庭用户购买」分支**)。待主理人裁决修复方向后,再决定是否:
|
|
|
+- 测试侧补「无家庭新用户购买」异常/正常流用例驱动 S-cfc-168 red → 重跑 mark-red;
|
|
|
+- 或直接派研发修复 `createOrder` 的 `familyId==null` 分支(方案 A 时改两行:`MembershipController.upgradeOrder` 与 `activateTrial` 中 `getUserFamilyId` → `getOrCreateUserFamilyId`)。
|
|
|
+
|
|
|
+### 4.2 缺陷 #2:被家庭会员家庭删除后未恢复免费
|
|
|
+
|
|
|
+**现象**:用户被从家庭会员家庭移除后,仍显示/享受家庭会员身份,未恢复免费。
|
|
|
+
|
|
|
+**根因链(源码证据)**:
|
|
|
+1. **家庭会员购买时写入个人缓存**:`MembershipService.syncMembershipToFamilyMembers`(`MembershipService:925-962`)把 `levelCode`/`expireTime` 写入**每个成员 `users` 表**(`u.setMemberLevel`/`u.setMemberExpireTime`),且 `getLevelOrder` 比较**只升不降**。
|
|
|
+2. **踢出/退出只迁移 familyId,不清缓存**:`FamilyMemberService.kickMember`(`FamilyMemberService:523-628`,关键段 580-628)微信用户 `targetUser.setFamilyId(ownFamilyId)`(迁至自有家庭,596-599 行)、非微信 `setFamilyId(null)`(607-609 行);`leaveFamily`(638-699 行)同样迁至自有家庭(686-691 行)。两者**均未重置被踢用户 `users.member_level` / `users.member_expire_time` 缓存**,仅调用 `membershipService.reconcileFamilyMembership(oldFamilyId)`(kick 620 行 / leave 694 行)重算**原家庭**(`downgradeFamilyMembers` 只降 `User.familyId == oldFamilyId` 的用户)。
|
|
|
+3. **被踢用户迁走后不在降级范围**:`downgradeFamilyMembers`(`MembershipService:968-1006`)只降 `familyId == oldFamilyId` 的用户;被踢用户已迁至新 familyId 或 null,**不在范围**,`users.member_level=FAMILY` 残留。
|
|
|
+4. **取高逻辑放大残留**:`MembershipService.getMemberLevel`(`MembershipService:1309-1332`)取 `personal`(`users.member_level` + `member_expire_time`)与 `family`(`getFamilyEffectiveLevel`,被踢后新家庭通常 FREE)**较高者**——残留 personal `FAMILY` 使被踢用户仍返回 FAMILY 身份。
|
|
|
+
|
|
|
+**修复方向(已建键 S-cfc-178 跟踪)**:
|
|
|
+- 在 `kickMember` / `leaveFamily` 中,对**被踢/退出用户**(kick 的 `targetUser`;leave 的 `user`)按**个人维度**重算会员缓存:调用与 `downgradeFamilyMembers` 同口径的「历史最高家庭级别」判定,**仅当用户无更高等级个人独立会员时清除/降级 `users.member_level` 与 `users.member_expire_time`**。建议封装为 `MembershipService.recalculatePersonalMembershipAfterFamilyExit(User user, Long exitedFamilyId)` 供 kick/leave 复用,避免与 `reconcileFamilyMembership` 的家庭维度重算逻辑混淆。
|
|
|
+- 契约测试覆盖:SC-P-06 移除成员 → 被踢用户 `getMemberLevel` 应返回 FREE(除非有更高个人独立会员);SC-P-58 购买场景不被回归。
|
|
|
+
|
|
|
+**处置**:已 `--add-task family.familyMembers.removeMember`(S-cfc-178,RED,pending 派发);sc-key-map.md SC-P-06 行已回填(commit 6b332da94)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 五、下一步(研发侧)
|
|
|
+
|
|
|
+| 优先级 | 事项 | 依赖 |
|
|
|
+|--------|------|------|
|
|
|
+| P0 | 7 条新键 S-cfc-164~169 + S-cfc-178 派发/回收(前 6 条契约测试已闭环 YELLOW,待 `--auto` 回填 yellow_sha;S-cfc-178 pending 派发) | 巡检调度 |
|
|
|
+| P0 | 缺陷 #1(familyId==null 门槛)修复方向主理人裁决 → 派发研发修复 | 主理人 |
|
|
|
+| P1 | 缺陷 #2(S-cfc-178)研发实现 + 测试 mark-red/green 闭环 | 编排侧 |
|
|
|
+| P1 | 覆盖度断层余项:221-13=208 SC 键列仍为「—」未映射能力键(不含本轮 13 处);状态机 69 键未回链台账。按需再盘点。 | — |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 附录:本轮 git 证据
|
|
|
+
|
|
|
+| 操作 | sha | 核验 |
|
|
|
+|------|-----|------|
|
|
|
+| sc-key-map.md 台账回填(单文件 commit-tree,不碰主工作树) | `6b332da94a279b736750559e5731996052cedcdb` | `git push origin <sha>:cfclub` 成功;`merge-base --is-ancestor <sha> origin/cfclub` IN_CHAIN ✓ |
|
|
|
+| 6 条契约测试 red_sha(前序自动化轮产出,本轮核验) | `07a992161` / `6d31293cf` / `7b2eadd05` / `7c16640cb` / `4d999a0fe` / `e812440b0` | 6 个全部 IN_CHAIN ✓ |
|
|
|
+
|
|
|
+> **结论**:本轮池空盘点识别 6 个覆盖度断层键 + 1 个用户反馈缺陷键,共 7 条入池;前 6 条已 RED→YELLOW 契约闭环(red_sha IN_CHAIN);缺陷 #2 已建键跟踪;缺陷 #1 待主理人裁决修复方向。台账 sc-key-map.md 已回填 13 处并推 `origin/cfclub`。
|