Просмотр исходного кода

docs(spec): 通关解锁功能设计 - 自检门禁解锁能量沙盘+增值关卡+软引导

- 新增 specs/2026-08-10-unlock-gates-design.md
- 理念依据:《家的算法》书稿(测量先行→最小输入→循环→反馈→系统升级)
- 主线硬门禁:家庭级判据,任一成员完成五维自检解锁全家沙盘
- 增值关卡:下单菌群检测/DAN测评(无前置依赖,可先于主线完成)
- 软引导:微行动/打卡里程碑/复测趋势,推荐不锁死
- 管理端完整配置页:开关/顺序/奖励/条件,数据驱动
- 同步更新 PROJECT-OVERVIEW.md 功能表与文档索引
Xiaogang Liao 1 месяц назад
Родитель
Сommit
893e19c470
2 измененных файлов с 317 добавлено и 0 удалено
  1. 2 0
      docs/superpowers/PROJECT-OVERVIEW.md
  2. 315 0
      docs/superpowers/specs/2026-08-10-unlock-gates-design.md

+ 2 - 0
docs/superpowers/PROJECT-OVERVIEW.md

@@ -82,6 +82,7 @@
 | 行远页重要关系维护(通讯录) | Phase 1 | ✅ 已完成(action/ 5页面 2116行,含OctopusGraph+问卷+互动日志) | `specs/2026-06-14-action-page-relationship-design.md` |
 | 行远页重要关系维护(通讯录) | Phase 1 | ✅ 已完成(action/ 5页面 2116行,含OctopusGraph+问卷+互动日志) | `specs/2026-06-14-action-page-relationship-design.md` |
 | 登录前浏览体验(未登录可见内容) | Phase 1 | ✅ 已完成(多页面游客态+wuxing-sandbox preview模式) | `specs/2026-06-04-pre-login-discovery-design.md` |
 | 登录前浏览体验(未登录可见内容) | Phase 1 | ✅ 已完成(多页面游客态+wuxing-sandbox preview模式) | `specs/2026-06-04-pre-login-discovery-design.md` |
 | 新用户注册引导 + 个人信息按需补充/回写 | Phase 1 | ✅ 已实施(注册解耦最小集 + 个人中心卡片 + 功能场景就地补充自动回写 + 无家庭引导组件) | `specs/2026-08-04-registration-profile-backfill-design.md` + `plans/2026-08-04-registration-profile-backfill.md` |
 | 新用户注册引导 + 个人信息按需补充/回写 | Phase 1 | ✅ 已实施(注册解耦最小集 + 个人中心卡片 + 功能场景就地补充自动回写 + 无家庭引导组件) | `specs/2026-08-04-registration-profile-backfill-design.md` + `plans/2026-08-04-registration-profile-backfill.md` |
+| 通关解锁(测试门禁+引导解锁) | Phase 1 | 🟡 设计稿(书稿《家的算法》理念:测量先行→最小输入→循环→反馈;主线硬门禁=自检解锁能量沙盘,增值关卡=下单测评,后台可配置) | `specs/2026-08-10-unlock-gates-design.md` |
 
 
 ---
 ---
 
 
@@ -348,6 +349,7 @@
 | `2026-08-08-family-challenge-participation-design.md` | ✅ 设计已确认(2026-08-08 拍板:C3 只扣沟通,其余按默认) | 家庭挑战参与机制重构(任意成员发起/可选参与/全体同意后开始/方向性关系评分) |
 | `2026-08-08-family-challenge-participation-design.md` | ✅ 设计已确认(2026-08-08 拍板:C3 只扣沟通,其余按默认) | 家庭挑战参与机制重构(任意成员发起/可选参与/全体同意后开始/方向性关系评分) |
 | `2026-08-08-health-data-center-design.md` | ✅ 已实施(身维度首页改造+在线测评题库扩展+方案汇总页+health_plans后端全栈) | 健康数据中心 — 看见·主动健康闭环(Tab栏+四维雷达图+数据采集+数据查看+方案汇总+认知/心理/关系测评) |
 | `2026-08-08-health-data-center-design.md` | ✅ 已实施(身维度首页改造+在线测评题库扩展+方案汇总页+health_plans后端全栈) | 健康数据中心 — 看见·主动健康闭环(Tab栏+四维雷达图+数据采集+数据查看+方案汇总+认知/心理/关系测评) |
 | `2026-08-08-growth-intervention-center-design.md` | ✅ 已实施(迁移208-209/2实体/2Mapper/SurveyService/SurveyController/AdminSurveyController/调研问卷页/调研历史页/growth-main重构/SurveyTemplates管理端) | 成长页面重构为干预中心(今日干预进度卡+持续追踪Tab+里程碑+定期调研+后端调研系统全栈) |
 | `2026-08-08-growth-intervention-center-design.md` | ✅ 已实施(迁移208-209/2实体/2Mapper/SurveyService/SurveyController/AdminSurveyController/调研问卷页/调研历史页/growth-main重构/SurveyTemplates管理端) | 成长页面重构为干预中心(今日干预进度卡+持续追踪Tab+里程碑+定期调研+后端调研系统全栈) |
+| `2026-08-10-unlock-gates-design.md` | 🟡 设计稿 | 通关解锁功能(自检门禁解锁能量沙盘+增值关卡+软引导+管理端关卡配置,数据驱动) |
 
 
 ### 实施计划(plans/)
 ### 实施计划(plans/)
 
 

+ 315 - 0
docs/superpowers/specs/2026-08-10-unlock-gates-design.md

@@ -0,0 +1,315 @@
+# 通关解锁功能设计(Unlock Gates)
+
+**版本:** v1.0
+**日期:** 2026-08-10
+**定位:** 产品设计 + 技术方案
+**理念依据:** 《家的算法》书稿(`book/` 目录:第2章测量先行 / 第8章最小输入 / 第9章循环执行 / 第10章反馈校验 / 第11章系统升级)
+**关联文档:** `docs/需求分析/新用户引导与留存设计方案.md`(L1-L5 分层,本方案是其门禁机制的落地)
+
+---
+
+## 1. 背景与目标
+
+### 1.1 产品逻辑(书稿 → 功能)
+
+书稿定义的家庭改变算法:**看见 → 最小输入 → 循环 → 反馈 → 传播**。其中"看见从测量开始"(第2章)是起点——用户必须先完成一次测量(五维自检),才能"看见"自己的状态(能量沙盘)。
+
+当前现状:能量沙盘(`WuxingSandbox`)对所有用户可见,无任何前置门禁;五维自检(15题)是首页一张卡片,非必经路径。两者数据源分离(沙盘=能量流水快照,自检分数=独立存储),用户"测不测都能看沙盘",引导链断裂。
+
+### 1.2 本方案目标
+
+| 目标 | 说明 |
+|------|------|
+| 硬门禁 | 未完成五维自检的家庭,**任何入口都看不到能量沙盘**(家长端/孩子端/发现页/成员详情统一加门) |
+| 软引导 | 完成自检后,通过"关卡中心页 + 首页引导条"不断推荐下一步行动(微行动/打卡/复测),不硬锁 |
+| 商业转化 | 增值关卡:下单菌群检测/DAN测评(可先于主线完成),解锁增值内容 |
+| 可配置 | cfc-web 管理端完整配置关卡:开关/顺序/奖励/条件,数据驱动不写死 |
+
+### 1.3 已确认的产品决策(澄清结论)
+
+| 决策点 | 结论 |
+|--------|------|
+| 小测试 | 复用现有五维自检 15 题(`self-check.vue`),不新建测试 |
+| 驱动方式 | 行为驱动(完成动作解锁),非时间驱动 |
+| 主线形态 | **单硬关卡**(自检→沙盘)+ 后续**软引导**(推荐不锁死) |
+| 门禁范围 | 全家沙盘统一加门(parent-index / child-index / discover / member-detail / member-home-detail) |
+| 判据粒度 | **家庭级**:家庭内任一成员完成自检即解锁全家 |
+| 增值关卡 | 下单菌群检测/DAN测评,可选,可先于主线关卡完成 |
+| 后台配置 | 完整配置页:开关/顺序/奖励/条件 |
+
+---
+
+## 2. 架构设计
+
+### 2.1 分层架构
+
+```
+cfc-web 管理端 views/admin/gates.vue(关卡配置 CRUD)
+        ↓ 配置
+unlock_gates 表(关卡定义,数据驱动)
+        ↓
+GateService(统一判定引擎)
+        ├── SELF_CHECK    → 查 five_dimension_self_checks
+        ├── PURCHASE      → 查订单表(支付成功)
+        ├── MICRO_ACTION  → 查 micro_action_records
+        └── STREAK_DAYS   → 查 streak
+        ↓ 判定结果写入
+family_gate_progress 表(家庭通关记录 LOCKED → UNLOCKED)
+        ↓
+门禁拦截:/api/energy/sandbox 未通关返回 locked 标记 → 前端渲染锁定态
+状态查询:POST /api/unlock/status → 首页引导条 + 关卡中心页
+```
+
+### 2.2 核心规则
+
+1. **主线硬门禁**:`is_required=1 AND is_soft=0` 的关卡按 `sort_order` **顺序依赖**——必须依次解锁,当前锁定关卡是最小 sort_order 的未通关关卡;其 `unlock_target` 对应模块对全家锁定。
+2. **增值关卡**:`is_required=0`,**无前置依赖**,任何时刻可完成(满足"关2可在关1前完成")。
+3. **软引导**:`is_soft=1` 的关卡不锁任何功能,仅在关卡中心页/首页引导条展示为"推荐解锁",点击直达对应功能。
+4. **判据粒度**:所有判定基于 `family_id`(家庭级),与当前登录人无关。
+5. **可降级**:所有硬门禁关卡均被禁用(`enabled=0`)时,门禁系统整体失效,沙盘对全家开放——保证运营可随时撤回。
+
+---
+
+## 3. 数据模型
+
+### 3.1 unlock_gates(关卡定义表)
+
+```sql
+CREATE TABLE IF NOT EXISTS unlock_gates (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY,
+    gate_type VARCHAR(32) NOT NULL COMMENT '关卡类型: SELF_CHECK/PURCHASE/MICRO_ACTION/STREAK_DAYS',
+    name VARCHAR(50) NOT NULL COMMENT '关卡名称',
+    description VARCHAR(200) COMMENT '关卡说明',
+    icon VARCHAR(10) COMMENT '图标emoji',
+    sort_order INT DEFAULT 0 COMMENT '排序号(后台可调,主线顺序依赖依据)',
+    enabled TINYINT DEFAULT 1 COMMENT '启用/禁用: 1启用 0禁用',
+    is_required TINYINT DEFAULT 1 COMMENT '归属: 1主线必过 0增值可选',
+    is_soft TINYINT DEFAULT 0 COMMENT '形态: 1软引导(不锁功能) 0硬门禁(锁定功能)',
+    unlock_target VARCHAR(32) COMMENT '解锁目标模块: SANDBOX/MICRO_ACTION_DAILY/BADGE_MILESTONE/TREND_COMPARE/PREMIUM_MODULES',
+    condition_params VARCHAR(500) COMMENT '条件参数JSON: {"count":1} / {"days":3} / {"product_types":["dan","microbiome"]}',
+    reward_points INT DEFAULT 0 COMMENT '通关奖励积分',
+    reward_energy INT DEFAULT 0 COMMENT '通关奖励能量',
+    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    INDEX idx_sort (enabled, is_required, is_soft, sort_order)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通关解锁关卡定义';
+```
+
+### 3.2 family_gate_progress(家庭通关进度表)
+
+```sql
+CREATE TABLE IF NOT EXISTS family_gate_progress (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY,
+    family_id BIGINT NOT NULL COMMENT '家庭ID',
+    gate_id BIGINT NOT NULL COMMENT '关卡ID(unlock_gates.id)',
+    status VARCHAR(16) DEFAULT 'LOCKED' COMMENT '状态: LOCKED/UNLOCKED',
+    unlocked_by BIGINT COMMENT '解锁人user_id',
+    unlocked_at DATETIME COMMENT '解锁时间',
+    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+    UNIQUE KEY uk_family_gate (family_id, gate_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家庭关卡通关进度';
+```
+
+> **说明**:进度按家庭维度冗余存储(而非实时计算),一是支付回调等场景可直接写库触发,二是管理端可人工干预(解锁/重置),三是避免每次沙盘请求重复扫描各业务表。
+
+---
+
+## 4. GateService 设计
+
+### 4.1 类结构(`service/UnlockGateService.java`)
+
+```java
+public class UnlockGateService {
+    // 核心:判定家庭是否已通关某关卡(幂等,可重复调用)
+    // SELF_CHECK:    five_dimension_self_checks 存在 family 内任一 user 的记录,且记录数 >= condition_params.minCount(默认1)
+    // PURCHASE:      商城商品订单存在支付成功订单,且商品 product_type/domain 命中 condition_params.product_types
+    // MICRO_ACTION:  micro_action_records 中家庭成员的记录数 >= condition_params.count
+    // STREAK_DAYS:   家庭成员 streak >= condition_params.days
+    public boolean isGateUnlocked(Long familyId, UnlockGate gate);
+
+    // 计算家庭门禁状态:当前锁定的硬门禁关卡(无则返回 null)
+    public UnlockGate getCurrentLockGate(Long familyId);
+
+    // 重算家庭全部关卡进度并写 family_gate_progress(自检提交/支付回调后调用)
+    public void refreshFamilyGates(Long familyId);
+
+    // 查询家庭关卡全景(status 接口数据源)
+    public UnlockStatusDTO getFamilyUnlockStatus(Long familyId);
+}
+```
+
+### 4.2 判定逻辑细节
+
+| 类型 | 判定依据 | 备注 |
+|------|---------|------|
+| `SELF_CHECK` | `five_dimension_self_checks` 存在该 family 内任一 user_id 的记录,且记录数 ≥ minCount(默认 1) | minCount 来自 condition_params;复测关卡设 `{"minCount":2}` |
+| `PURCHASE` | **商城商品订单表**(ProductOrderController 对应订单表)存在支付成功的订单,且商品 `domain`/`product_type` 命中 condition_params.product_types(多类型 OR 匹配) | DAN测评/菌群检测以商城商品形式购买时走此判定;若 DAN测评走独立流程(`dan-assessment/record`),在实现计划中确认其订单接入点 |
+| `MICRO_ACTION` | `micro_action_records` 家庭内记录数 ≥ count | 按 family 聚合 |
+| `STREAK_DAYS` | 家庭成员最大 streak ≥ days | 复用现有 streak 计算 |
+
+### 4.3 触发钩子
+
+| 触发点 | 位置 | 动作 |
+|--------|------|------|
+| 登录成功 | `AuthController` 登录/角色切换 | `unlockGateService.refreshFamilyGates(familyId)`(兜底:老用户已自检但进度表未初始化时自动补齐;同时保证进度新鲜度) |
+| 自检提交成功 | `FiveDimensionSelfCheckController.submit()` | `unlockGateService.refreshFamilyGates(familyId)` |
+| 支付成功回调 | `PaymentController.wechat/callback、alipay/callback、wechat/v3-notify` | `refreshFamilyGates(familyId)` |
+| 管理端人工干预 | `AdminUnlockGateController` | 重置/手动解锁某家庭某关卡 |
+
+> **读路径**:`/api/unlock/status` 与 `/api/energy/sandbox` 只读 `family_gate_progress` 冗余表(不实时扫描业务表);`refreshFamilyGates` 由上述钩子触发重算写库,保证进度表与业务数据一致。存量家庭首次登录即被登录钩子预置,无需额外迁移。
+
+---
+
+## 5. 接口设计
+
+### 5.1 用户端
+
+```
+POST /api/unlock/status
+入参: 无(@RequestAttribute userId 取家庭)
+出参: {
+  currentLockGate: {id, name, description, icon, gateType} | null,   // 当前硬门禁(家庭级)
+  gates: [{id, gateType, name, description, icon, isRequired, isSoft,
+           status: LOCKED|UNLOCKED|CURRENT, rewardPoints, rewardEnergy}],
+  sandboxLocked: true/false     // 便捷标记,前端四处沙盘共用
+}
+说明: 未加入家庭时返回 sandboxLocked=false(不拦截,保持现有 noFamily 逻辑)
+```
+
+```
+POST /api/energy/sandbox  (改造)
+现有: 直接返回 EnergySandboxDTO
+改造后: 未通过当前硬门禁时返回:
+  { locked: true, gate: {id, name, description, icon}, code: 0 }
+通过时: 原逻辑 + sandbox 数据
+说明: 保持 code=0(非业务错误),前端以 data.locked 分支渲染锁定态;
+      门禁判定为家庭级,孩子端/发现页/成员详情调用同一接口自动生效
+```
+
+### 5.2 管理端
+
+```
+POST /api/admin/unlock-gates/list        — 关卡列表
+POST /api/admin/unlock-gates/save        — 新增/编辑关卡
+POST /api/admin/unlock-gates/delete      — 删除关卡(同时清理 family_gate_progress)
+POST /api/admin/unlock-gates/sort        — 批量排序
+POST /api/admin/unlock-gates/toggle      — 启停
+POST /api/admin/unlock-gates/reset-family — 重置某家庭进度(运营干预)
+```
+
+> 接口统一 `@PostMapping`,遵循项目规范。
+
+---
+
+## 6. 前端设计(小程序)
+
+### 6.1 锁定态组件 `components/gate-lock.vue`
+
+- 新组件,props: `gate`(当前锁定关卡信息)
+- 视觉:锁图标 + 关卡名 + 引导文案(*"完成五维自检,解锁能量沙盘"*)+ 主按钮(跳转对应功能:自检→`pages/family/self-check.vue`)
+- 替换位置(原 `v-if="sandboxData"` / error-state 逻辑):
+
+| 页面 | 现状 | 改造 |
+|------|------|------|
+| `pages/home-pages/parent-index.vue` | `v-if="sandboxData"` 渲染沙盘 | 门禁状态 sandboxLocked → 渲染 gate-lock;未加入家庭保持现状 |
+| `pages/home-pages/child-index.vue` | 渲染沙盘 | 同上 |
+| `pages/home-pages/member-home-detail.vue` | 渲染沙盘 | 同上 |
+| `pages/member-detail/member-detail.vue` | 渲染沙盘 | 同上 |
+| `pages/discover/index.vue` | 渲染沙盘 | 同上 |
+
+### 6.2 首页引导条 `components/gate-guide-bar.vue`
+
+- 家长首页 `parent-index.vue` 顶部(自检卡附近)展示:"🔓 解锁进度 1/4 · 完成五维自检解锁能量沙盘 →"
+- 数据源:`/api/unlock/status` 的 gates 列表(已解锁数/主线总数)
+- 全解锁后自动消失(避免打扰老用户)
+- 点击 → 关卡中心页
+
+### 6.3 关卡中心页 `pages/profile-extra/gates.vue`
+
+- 分区展示:
+  - **主线关卡**:锁态(🔒 灰)/ 当前(进行中高亮)/ 已解锁(✅)
+  - **增值关卡**:购买入口(跳商城对应商品/测评),已购显示已解锁
+  - **软引导**:推荐卡片(微行动/连续打卡/复测),点击直达
+- 每关展示:图标+名称+说明+奖励(+N 积分 · +N 能量)
+- 新页面需在 `pages.json` 注册(分包 profile-extra)
+
+### 6.4 沙盘叠加自检分数
+
+- 解锁后沙盘数据来源不变(energy/sandbox),新增叠加:自检结果页分数作为雷达叠加层(复用 self-check-result 的雷达图数据)
+- 实现位置:`WuxingSandbox` 组件扩展可选 props(selfCheckScores),首版仅家长端首页叠加,其余位置保持纯能量快照
+
+---
+
+## 7. 管理端设计(cfc-web)
+
+### 7.1 页面 `views/admin/gates.vue`
+
+- 路由:`/admin/gates`(菜单"系统管理"下"关卡配置")
+- 表格列:排序 | 图标 | 名称 | 类型 | 归属(主线/增值) | 形态(硬门禁/软引导) | 解锁目标 | 条件 | 奖励 | 状态 | 操作
+- 操作:编辑(弹窗表单)/ 启停开关 / 删除 / 上下移排序(或数字排序)
+- 表单字段(对应 unlock_gates):
+  - 类型下拉:五维自检 / 购买商品 / 微行动次数 / 连续打卡天数
+  - 条件参数按类型动态渲染:SELF_CHECK 无参数;PURCHASE 选商品类型(DAN测评/菌群检测/自定义 product_types 输入);MICRO_ACTION 填次数;STREAK_DAYS 填天数
+  - 奖励:积分 + 能量 两个数字输入
+  - 归属/形态:单选
+- 额外区块:**家庭进度管理**(输入 family_id 查看/重置该家庭关卡进度,运营干预)
+
+### 7.2 后端 `controller/admin/AdminUnlockGateController.java`
+
+- `@RequestMapping("/api/admin/unlock-gates")`,`@PostMapping` 各操作
+- 校验:同名关卡、sort_order 唯一、condition_params 按类型解析失败报错
+- 删除关卡时级联清理 family_gate_progress 对应记录
+
+---
+
+## 8. 首版默认关卡配置(DatabaseInitializer 种子数据)
+
+| 关卡 | gate_type | 归属 | 软/硬 | unlock_target | 条件 | 奖励 |
+|------|-----------|------|-------|---------------|------|------|
+| 五维自检 | SELF_CHECK | 主线 | 硬门禁 | SANDBOX | 完成1次 | +60积分 +10能量 |
+| 首次微行动 | MICRO_ACTION | 主线 | 软引导 | MICRO_ACTION_DAILY | count≥1 | +50积分 +5能量 |
+| 连续打卡3天 | STREAK_DAYS | 主线 | 软引导 | BADGE_MILESTONE | days≥3 | +30积分 +5能量 |
+| 复测对比 | SELF_CHECK | 主线 | 软引导 | TREND_COMPARE | minCount=2 | +60积分 +10能量 |
+| 菌群检测/DAN测评 | PURCHASE | 增值 | 硬门禁(增值) | PREMIUM_MODULES | 任一支付成功 | +100积分 +20能量 |
+
+> 种子数据写入方式:`DatabaseInitializer.runMigrations()` 迁移(参考项目迁移工作流,编号递增、幂等),管理端可随时增删改。
+
+---
+
+## 9. 风险与注意事项
+
+| 风险 | 缓解 |
+|------|------|
+| 强制自检导致新用户流失 | 自检入口直达 + 首页引导条强调"5分钟";门禁仅锁沙盘,其余功能(任务/心愿/成长)不受影响 |
+| 老用户(未自检)突然看不到沙盘 | 全部硬门禁关闭可整体失效(运营开关);上线前对存量家庭数据评估,必要时种子迁移按"有自检记录即解锁"批量预置 |
+| 增值关卡商品匹配口径不清 | condition_params.product_types 用商品 domain/product_type 精确匹配;管理端下拉选择避免手输 |
+| 门禁判定性能 | 判定结果冗余到 family_gate_progress(判定后写库),沙盘接口只读进度表,不重复扫描业务表 |
+| 孩子端首次进入无家庭 | 保持现有 noFamily 逻辑,不套门禁(家庭级判定前置条件:有 family_id) |
+| 多角色用户(parent+teacher) | 判据基于 family_id 与 family 内任一用户的自检记录,不依赖角色,天然兼容 |
+
+---
+
+## 10. 测试策略(tests/AGENTS.md 分层)
+
+| 层 | 内容 |
+|----|------|
+| 单元 | UnlockGateService 四类型判定(SELF_CHECK/PURCHASE/MICRO_ACTION/STREAK_DAYS)+ 边界(count=0、无记录、多记录);getCurrentLockGate 顺序依赖;禁用关卡降级 |
+| 集成 | `/api/unlock/status` 返回结构;`/api/energy/sandbox` 未通关返回 locked;自检 submit 后 refresh 生效;支付回调后 PURCHASE 关卡解锁 |
+| 前端 | gate-lock 组件渲染(锁定态/解锁态);gate-guide-bar 进度计算与消失条件;关卡中心页三区展示 |
+| E2E | 新用户注册→首页沙盘锁定→完成自检→沙盘解锁→关卡中心显示已解锁 |
+
+---
+
+## 11. 实施范围与工作量估算
+
+| 模块 | 内容 | 估算 |
+|------|------|------|
+| 后端 | 2 张表迁移 + UnlockGateService + UnlockController + AdminUnlockGateController + sandbox 改造 + 2 处钩子 + 种子数据 | 3-4 天 |
+| 小程序 | gate-lock 组件 + gate-guide-bar + gates.vue 关卡中心 + 4 处沙盘替换 + 自检分数叠加 | 3-4 天 |
+| 管理端 | gates.vue 配置页 + 家庭进度管理 | 1-2 天 |
+| 测试 | 单测/集成/前端/E2E | 1-2 天 |
+
+**里程碑验收:**
+- 后端完成:`/api/unlock/status` + sandbox 门禁可用(Postman 验证 locked 分支)
+- 前端完成:新用户动线"注册→沙盘锁定→自检→解锁"全链路走通
+- 管理端完成:新增关卡/调整顺序/禁用关卡实时生效