diff --git a/docs/superpowers/specs/2026-08-18-parent-wrongbook-design.md b/docs/superpowers/specs/2026-08-18-parent-wrongbook-design.md new file mode 100644 index 0000000..ae5d0cb --- /dev/null +++ b/docs/superpowers/specs/2026-08-18-parent-wrongbook-design.md @@ -0,0 +1,76 @@ +# 家长中心「待掌握错题」查看 - 设计文档 + +日期:2026-08-18 +状态:已批准 + +## 背景 + +家长中心「学习概览」tab 有一张「待掌握错题」计数卡片(显示某个孩子未掌握错题数 `wrongOpen`), +目前**不可点击**。家长希望点击后能查看该孩子的错题信息。 + +相关现状: + +- 孩子端已有完整错题本页 `/wrongbook`(仅 child 角色可进),展示组件 `WrongRow` 含 + 题干/标准答案/用户作答/解答题作答照片,并可「标记已掌握」。 +- 标记动作 `toggleMastered`(src/app/wrongbook/actions.ts)是 child 角色限定、按会话孩子 id 锁定。 +- 提交 ab84bec 移除了课程管理里的「孩子错题本」快照卡片,但概览 tab 的计数卡片仍在且不可点。 + +## 需求(已与用户确认) + +1. 点击概览页「待掌握错题」卡片 → 进入该孩子(当前选中孩子)的错题查看页。 +2. 页面**只展示待掌握(未掌握)的错题**,不含已掌握。 +3. 家长可以「标记已掌握」,返回概览后计数同步下降。 +4. 页面内不需要孩子切换(看别的孩子需返回概览重新点)。 + +## 方案选择 + +- **方案 A(采用):新建家长版错题页 `/parent/wrongbook?kid=`** + - 权限模型清晰(家长页 = 家庭归属校验),遵循现有 `/parent/grammar`、`/parent/words` 目录模式; + 孩子端逻辑零改动。 +- 方案 B(弃):放开孩子端 `/wrongbook` 允许家长进入 → 孩子页面被家长/孩子两套模式搅乱。 +- 方案 C(弃):概览页内点击后同页展开列表 → 破坏日历布局,无法分享/刷新。 + +## 设计 + +### 1. 入口:src/app/parent/overview-tab.tsx + +「待掌握错题」卡片包 ``,样式保留,加 hover 微动效。 + +### 2. 新页面:src/app/parent/wrongbook/page.tsx(server component) + +- 鉴权:未登录 `redirect("/login")`;非 parent `redirect("/kid")`(与其它家长页一致)。 +- 从 `searchParams.kid` 取孩子 id,校验 `familyId === 家长.familyId` 且 `role === child`, + 不合法一律 `redirect("/parent")` —— 防越权查看别的家庭孩子。 +- 数据:`listWrong(kidId)` 过滤 `mastered === false`(复用现有 lib,不加新查询层)。 +- 渲染:header「← 返回家长中心」+「待掌握错题」+ 孩子名 + 数量;无错题显示空态 + (🎉 没有待掌握错题);每题复用 `WrongRow`,解答题作答照片(OSS 签名 URL)逻辑同孩子端。 + +### 3. 新 action:src/app/parent/wrongbook/actions.ts + +- `markMastered(id: number, mastered: boolean)`: + 1. 取会话家长,非家长直接 return; + 2. 按错题 id 查记录拿 `childUserId`; + 3. 校验该孩子属于本家庭,否则 return; + 4. 调现有 `setMastered(id, childUserId, mastered)`; + 5. `revalidatePath("/parent")` + `revalidatePath("/parent/wrongbook")`。 + +### 4. 组件复用:src/app/wrongbook/wrong-row.tsx + +- `WrongRow` 增加可选 prop `markAction?: (id: number, mastered: boolean) => Promise`, + 缺省走现有孩子端 `toggleMastered`;家长页传入 `markMastered`。 +- 孩子端行为零变化;家长版因只过滤未掌握,revalidate 后已标记行自然消失, + 组件内不加任何分支逻辑。 + +### 5. 不改动 + +- DB schema(wrongBook 表已含 mastered 字段) +- src/lib/wrongbook.ts(listWrong / setMastered 已够用) + +## 测试清单(手工,项目无自动化测试框架) + +1. 家长登录 → 点卡片 → 看到该孩子待掌握错题(含解答题照片)。 +2. 标记已掌握 → 行消失;返回概览计数 -1。 +3. 多孩子:选中 A 孩子进入 A 的错题;篡改 `?kid=` 为别的家庭孩子 → 被重定向回 `/parent`。 +4. 全部掌握后 → 🎉 空态。 +5. 孩子账号 / 未登录访问 `/parent/wrongbook` → 正确重定向。 +6. 部署 jump.hn12301.net 后线上复验。 \ No newline at end of file