零新表零迁移;三套管理全走家长端独立页;编辑不联动积分打卡。 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
5.6 KiB
5.6 KiB
家长端成绩与试卷管理 - 设计文档
日期:2026-08-19 状态:已批准
背景
家长端「课程管理」只有一张只读的最近 10 条周测成绩列表,考试板块(试卷+作答记录)在家长端完全没有入口。 用户要求:每周检测成绩、考试中心对应的数据都可管理(已确认:成绩记录编辑+删除、试卷内容管理一次全做)。
关键现状:
weekly_test:孩子周测自动写入(child+weekKey 唯一),达标联动发积分 + 当日英语打卡。exam_paper:试卷内容存库(meta + questions quiz JSON);exam_record:孩子作答(child+paperId 唯一),达标联动发积分 + 当日数学打卡。- 家长端已有内容编辑器成熟模式(grammar/words/math:列表页 → 详情编辑页,保存即生效)。
quiz-parse只提供extractQuiz(md)与QuizQ类型,无独立 JSON 校验器 → 校验在保存 action 内做形状校验。
需求(已与用户确认)
- 每周检测成绩管理:家长可编辑(分数 + 达标状态)、删除记录。
- 考试成绩记录管理:同款编辑 + 删除。
- 考试试卷内容管理:新增/编辑/删除试卷(元信息表单 + 题目 JSON 文本域,保存时校验)。
- 编辑成绩/达标不联动积分与打卡回滚(用户选定,简单优先)。
- 题目编辑用 JSON 文本域 + 保存时校验(用户选定,非结构化逐题表单)。
方案选择
- 方案 A(采用):三套管理全部进家长端独立页,零新表零迁移
- 成绩记录管理仿 wrongbook/family-manage 模式(server action + 行内编辑);试卷管理仿 grammar/math 编辑器(列表 → 详情编辑)。
- 方案 B(弃):结构化逐题表单编辑题目 → 表单工程量大,两倍工作量。
- 方案 C(弃):成绩管理塞进课程管理 Section 行内 → 交互空间挤、可扩展性差。
设计
1. 周测成绩管理 /parent/weekly-records
- 入口:课程管理 Section 的只读周测列表块删除,替换为「每周检测成绩管理」入口卡片(与课程编辑卡片同风格)。
- 页面(server component):鉴权同其它家长页;查询
weekly_testjoinusers(本家庭全部孩子),按 takenAt 倒序最近 100 条,按孩子分组展示。 - 每行:孩子名 · 周 key · 分数 · 达标徽标 · 日期;操作:编辑(行内展开分数输入 + 达标开关 + 保存/取消)、删除(按钮二次确认)。
- 分数编辑:整数 0-1000 表单校验;达标独立开关,不自动按 80 分计算(家长手动决定,与"不联动回滚"精神一致)。
- 删除后孩子端
getWeeklyRecord为空 → 可重测,唯一索引重建记录。
2. 考试成绩记录管理 /parent/exam-records
- 同款独立页。查询
exam_recordjoinusers(孩子)+exam_paper(left join,卷被删时 title 显示「已删试卷」)。 - 每行:孩子名 · 试卷标题 · 分数 · 达标 · 日期;编辑(分数+达标)+ 删除(确认)。
- 删除后孩子端
getExamRecord为空 → 可重考。
3. 考试试卷管理 /parent/exams
- 列表页:按月份分组(复用 exam 页 MONTH_LABEL 分组逻辑,固定 g7/s1/math,与孩子端一致),每组内每卷:标题 · 类型徽标 · 题数;编辑/删除按钮;顶部「+ 新建试卷」。
- 编辑页
/parent/exams/[paperId]:元信息表单(标题/考试类型/地区/年份/时长/满分/来源链接/考查说明/月份/序号)+ 题目 JSON 文本域(初始值JSON.stringify(questions, null, 2))。- 保存时校验(server action):
JSON.parse→ 必须是数组 → 每题形状校验(stem/type/answer/explain非空 + type 条件字段,如 fill 的answers、order/match 的answer数组、solve 的reference)→ 失败返回具体错误信息不保存。 - 文本域下方实时显示"共 N 题"统计(客户端解析,失败显示红色提示)。
- 保存时校验(server action):
- 新建页
/parent/exams/new:同表单,paperId 手填(校验格式[a-z0-9-]+、唯一),科目/年级/学期/月份/序号默认值。 - 删除试卷:允许(记录 left join 已容错);孩子端
/exam列表即时消失,已打开的卷页 404。
4. parent/actions.ts 新增 6 个 action(全部家长身份 + 家庭归属校验)
| action | 说明 |
|---|---|
updateWeeklyRecord(id, score, passed) / deleteWeeklyRecord(id) |
周测记录;按 id 查 childUserId → 归属校验 |
updateExamRecord(id, score, passed) / deleteExamRecord(id) |
考试记录;同上 |
saveExamPaper(formData) |
新增/更新试卷(带 paperId 唯一性检查 + 题目 JSON 校验) |
deleteExamPaper(paperId) |
删除试卷(仅家长 + 本家庭无需校验——试卷非家庭私有,家长即可) |
- 编辑/删除周测与考试记录后
revalidatePath("/parent")+ 对应管理页;试卷保存后revalidatePath("/parent/exams")+revalidatePath("/exam")(孩子端立即生效)。
5. 不改动
- DB schema(三张表已有足够的字段)、
weekly/actions.ts、exam/actions.ts、lib/weekly.ts、孩子端任何页面。 - 积分/打卡链路不动。
测试清单(手工,项目无自动化测试框架)
- 课程管理 Section:三张入口卡片(周测管理/考试记录管理/试卷管理)替代原只读周测块。
- 周测管理:编辑分数/达标 → 显示更新;删除 → 记录消失,孩子端 weekly 页可重测;越权孩子 id 篡改 → 拒绝。
- 考试记录管理:编辑/删除生效;删除试卷后再看记录 → 标题显示「已删试卷」。
- 试卷管理:新建试卷(JSON 合法)→ 孩子端 /exam 立即出现;编辑保留;JSON 非法 → 报错不保存;删除 → 孩子端消失;paperId 重复 → 报错。
- 孩子达标积分/当日打卡在编辑周测/考试记录后不变(不联动,预期行为)。
- 部署 jump.hn12301.net 后线上复验。