ソースを参照

docs(spec): 家庭挑战使用流程梳理 v1.0 - 现状基线 + 断点清单

Xiaogang Liao 1 ヶ月 前
コミット
4a851d76a3

+ 217 - 0
docs/superpowers/specs/2026-08-06-family-challenge-flow-design.md

@@ -0,0 +1,217 @@
+# 家庭挑战使用流程梳理(现状基线 + 断点清单)
+
+> **版本**:v1.0
+> **日期**:2026-08-06
+> **状态**:已确认,作为后续实现计划的基线
+> **范围**:只描述家庭挑战(`family_challenge`);圈子挑战(`circle_challenge`)不在本文档范围内
+> **读者**:产品 / 运营 / 新入职业务同学;开发同学作为基线参照
+> **基准**:按**当前代码事实**撰写,每项标注实现状态(🟢已实现 / 🟡半实现 / 🔴未实现);"未来期望"单列一节,不与现状混淆
+> **证据截止**:2026-08-06(以 `cfc-backend` / `cfc-frontend` 当前代码为准)
+
+---
+
+## 1. 背景与目标
+
+家庭挑战是 cfc(XAF)产品中"五维能量"体系下的**家庭共同行动**机制:通过设定带奖励的目标任务(全员打卡、运动、健康周等),让家庭成员共同完成。
+
+**现状一句话**:挑战由**家长在小程序手动创建 / 编辑 / 删除**;**打卡与奖励发放目前未接通**——见 §4.3 / §6 / §7。
+
+**为什么梳理**:
+- 功能已有多端实现,但**没有一份流程文档**,产品 / 运营讲不清现状
+- 存在**已实现但无人调用**(打卡前端入口缺失)、**已实现但触发不全**(到期自动结算缺失)、**完全未实现**(奖励发放)三类状态,需要一份基线文档区分
+- 后续开发(补打卡 / 补奖励 / 补权限)需要一份"现状基线"
+
+**成功标准**:产品 / 运营同事读完本文档,**不看代码也能复述**:哪些功能能用、哪些不能用、每个功能在哪个端、数据怎么流转。
+
+---
+
+## 2. 关键概念
+
+| 概念 | 定义 | 状态 |
+|---|---|---|
+| **挑战** | 家庭共同完成的目标任务,含起止日期与奖励配置 | 🟢 已实现 |
+| **挑战模板** | 预定义的挑战样例(标题/类型/目标/时长/奖励),是创建的"配方" | 🟢 已实现(7 种,含自定义) |
+| **挑战类型** | `full_checkin` 全员打卡 / `sports` 运动PK / `health_week` 健康周 / `reading` 阅读 / `no_screen` 无屏幕 / `gratitude` 感恩日记 / `custom` 自定义 | 🟢 已实现 |
+| **目标模式** | `aggregate` 集体总合目标(全家人合计达到目标值)/ `all_members` 全员个人目标(每个成员都达到目标值) | 🟢 已实现 |
+| **进度** | 每个成员在某挑战下的累计达标数值 | 🟢 已实现(后端累计逻辑存在) |
+| **打卡** | 成员主动上报完成动作,累加进度 | 🟡 **半实现**:后端接口有、前端无入口 |
+| **结算** | 挑战到期后判定完成情况 | 🟡 **半实现**:仅打卡触发,无到期自动结算 |
+| **奖励** | 能量点(rewardPoints)+ 成就徽章(rewardBadge) | 🔴 **未实现**:仅展示数字,无发放逻辑 |
+| **状态** | `active` 进行中 / `completed` 已完成 / `cancelled` 已取消 | 🟢 已实现(三态) |
+
+---
+
+## 3. 角色与权限(现状)
+
+### 家长(parent)
+
+| 能力 | 状态 | 说明 |
+|---|---|---|
+| 查看本家庭活跃 / 历史挑战列表 | 🟢 已实现 | `GET list / history` |
+| 查看每个成员的进度 | 🟢 已实现 | 卡片组件展示 |
+| 手动发起挑战(选模板 + 自定义标题/目标/时长/奖励) | 🟢 已实现 | `challenge-manage.vue` + `create` 接口 |
+| 编辑 / 删除(软删 cancelled)自己创建的挑战 | 🟢 已实现 | `update / delete` 接口 |
+| 进入"管理"页 | 🟢 已实现 | 家长首页 → "管理 →" |
+| 修改成员进度 | 🔴 未实现 | 现状:无任何角色校验,见 §7 |
+
+### 孩子(child)
+
+| 能力 | 状态 | 说明 |
+|---|---|---|
+| 查看本家庭活跃 / 历史挑战列表 | 🟢 已实现 | 与家长同 API |
+| 打卡 | 🟡 **半实现** | 后端接口存在,**前端无打卡按钮** |
+| 查看自己的历史奖励 | 🔴 未实现 | 奖励未实现 |
+| 权限隔离(只能打卡自己) | 🔴 未实现 | 无角色校验,孩子可调管理接口 |
+
+### 规划师(teacher)
+
+- 🔴 不参与家庭挑战(无相关代码)
+
+**权限边界一句话(现状)**:**无角色检查**——所有挑战接口任何登录角色可调;"孩子只能打卡自己"等约束**未落地**。
+
+---
+
+## 4. 挑战生命周期(现状)
+
+### 4.1 挑战从哪里来(重要修正)
+
+| 途径 | 状态 | 证据 |
+|---|---|---|
+| 家长手动创建 | 🟢 已实现 | `createChallenge` 接口 + `challenge-manage.vue` 创建弹窗 |
+| **后端按月自动创建** | 🔴 **未实现** | `autoCreateChallenges(familyId)` 方法存在,但 **Controller / 定时任务均无调用方**——仅 `CircleChallengeService` 有同名的圈子版自用 |
+
+> ⚠️ **结论**:挑战**只能由家长手动创建**。产品若宣传"系统按月自动派发挑战",当前**不成立**。
+
+### 4.2 三个状态
+
+```mermaid
+stateDiagram-v2
+    [*] --> active: 家长手动创建
+    active --> completed: 打卡触发结算判定(达成或到期)
+    active --> cancelled: 家长删除(软删)
+    completed --> [*]: 进入历史列表
+    cancelled --> [*]: 从活跃列表消失
+```
+
+| 状态 | 含义 | 进入方式 |
+|---|---|---|
+| `active` | 进行中,卡片展示在活跃列表 | 家长手动创建 |
+| `completed` | 已完成,进入历史列表 | 打卡时 `checkAndSettle` 判定达成或已到期 |
+| `cancelled` | 已取消,从活跃列表消失 | 家长删除(软删,**保留记录**) |
+
+### 4.3 结算规则(现状)
+
+- 🟡 **触发点**:仅"打卡更新进度"时执行 `checkAndSettle`
+- 🟡 **判定**:`aggregate` 全家合计 ≥ 目标 / `all_members` 每成员 ≥ 目标;或 `endDate` 已过
+- 🔴 **到期无打卡 = 永不结算**(`settleChallenge()` 无调用方)
+- 🔴 **奖励发放不存在**——结算只改状态,能量点 / 徽章不落账
+
+---
+
+## 5. 家长动线(现状)
+
+**入口**:家长首页(parent-index)→ "家庭挑战"区块 → 卡片列表 + "管理 →"
+
+**卡片上看到**(FamilyChallengeCard):
+- 标题、状态徽标(进行中 / 已完成)、描述
+- 目标模式:`aggregate` 显示全家总进度条 / `all_members` 显示成员列表(含 ✓ 完成标记)
+- 时长、截止日期、奖励分数(`+50分` 等,**仅展示**)
+
+**管理页可做**(challenge-manage.vue):
+- 🟢 查看模板列表(7 种)
+- 🟢 创建:选模板 / 自定义标题、目标模式、目标值、奖励分、时长
+- 🟢 编辑自己创建的 active 挑战
+- 🟢 删除自己创建的 active 挑战(软删)
+
+**家长不可做**(现状):
+- 🔴 无"打卡"操作(卡片无按钮)
+- 🔴 无"取消"菜单(删除即软删,无独立取消态)
+- 🔴 无通知 / 无复盘
+
+---
+
+## 6. 孩子动线(现状)
+
+**入口**:孩子的身维度首页(index-home)→ 同一 FamilyChallengeCard 组件
+
+**卡片上看到**:与家长端视觉一致(标题 / 状态 / 进度 / 奖励分),**无打卡按钮**
+
+**孩子可做**:
+- 🟢 查看挑战列表与进度
+- 🟡 打卡 —— **现状前端无入口**(后端 `/progress` 存在但无人调用)
+
+**孩子不可做**(现状):
+- 🔴 打卡(无 UI)
+- 🔴 查看奖励(未实现)
+- 🔴 权限隔离(无角色校验,理论上可调管理接口)
+
+**两端差异一句话(现状)**:**两端看到的东西几乎一样,都只能看不能"做"**——家长多了"管理"页,孩子连打卡都没有。
+
+---
+
+## 7. 现状问题清单(后续实现计划的输入)
+
+| # | 问题 | 影响 | 状态 |
+|---|---|---|---|
+| 1 | **打卡无前端入口**:api.js 有 `updateChallengeProgress`,无页面调用 | 孩子无法参与 | 🟡 半实现 |
+| 2 | **到期不自动结算**:`settleChallenge()` 无调用方 | 到期挑战停留在 active | 🟡 半实现 |
+| 3 | **奖励未发放**:结算只改状态 | 能量点 / 徽章不落账 | 🔴 未实现 |
+| 4 | **无角色检查**:list / progress / create / update / delete 均无角色校验 | 任何角色可调管理接口;孩子可刷任意成员进度 | 🔴 未实现 |
+| 5 | **前端展示 bug**:FamilyChallengeCard 将 `cancelled` 也显示为"已完成" | 已删挑战显示为完成 | 🔴 未修复 |
+| 6 | **无每日限次**:`updateProgress` 可无限叠加 | 可刷进度 | 🔴 未实现 |
+| 7 | **后端 autoCreate 无调用方**:方法存在但无人调用 | 宣传的"自动派发"不成立 | 🔴 未实现 |
+
+---
+
+## 8. 未来期望(明确标注"非现状")
+
+> 本节是**产品方向**,不代表当前可用;实现需另起 spec + plan。
+
+| 能力 | 说明 |
+|---|---|
+| 孩子打卡 UI | 卡片加"打卡"按钮 + 打卡表单 + 反馈 |
+| 到期自动结算 | 定时任务 / 查询时惰性结算 |
+| 奖励发放 | 结算时能量点入账 + 徽章授予(对接 EnergyService) |
+| 每日限次 | 同挑战每日 1 次打卡 |
+| 通知 | 开始前 / 即将到期 / 结算完成推送 |
+| 权限 | 角色校验:仅家长可管理,仅本人可打卡 |
+| 复盘 | 完成率 / 坚持天数 / 成长轨迹 |
+| 规划师视角 | 另起 spec |
+
+---
+
+## 9. 附录
+
+### A. 数据表
+
+| 表名 | 用途 |
+|---|---|
+| `family_challenge` | 挑战主表(含 creatorId) |
+| `family_challenge_progress` | 成员进度表 |
+| `circle_challenge` | 圈子挑战(不在本文档范围) |
+
+### B. API 清单(现状)
+
+| 路径 | 用途 | 前端是否调用 |
+|---|---|---|
+| `POST /api/health/challenge/list` | 活跃列表 | ✅ |
+| `POST /api/health/challenge/history` | 历史 | ✅ |
+| `POST /api/health/challenge/progress` | 打卡进度 | ❌ **无页面调用** |
+| `POST /api/health/challenge/templates` | 模板列表 | ✅ |
+| `POST /api/health/challenge/create` | 创建 | ✅ |
+| `POST /api/health/challenge/update/{id}` | 编辑 | ✅ |
+| `POST /api/health/challenge/delete/{id}` | 删除 | ✅ |
+
+### C. 术语表
+
+| 术语 | 定义 |
+|---|---|
+| 挑战 | 家庭共同完成的目标任务,含起止日期与奖励 |
+| 挑战模板 | 预定义的挑战配方,可选用或自定义 |
+| 挑战类型 | 全员打卡 / 运动PK / 健康周 / 阅读 / 无屏幕 / 感恩日记 / 自定义 |
+| 目标模式 | `aggregate` 全家合计 / `all_members` 每人目标 |
+| 进度 | 成员在某挑战下的累计达标数值 |
+| 打卡 | 成员主动上报完成动作(累加进度) |
+| 结算 | 挑战到期后判定完成情况 + 发放奖励 |
+| 奖励 | 能量点(rewardPoints)+ 成就徽章(rewardBadge) |
+| 状态 | `active` 进行中 / `completed` 已完成 / `cancelled` 已取消 |