Files
CICD/docs/design/006_homework_module_implementation.md
SpecialX 13e91e628d
Some checks failed
CI / build-and-test (push) Failing after 3m34s
CI / deploy (push) Has been skipped
Merge exams grading into homework
Redirect /teacher/exams/grading* to /teacher/homework/submissions; remove exam grading UI/actions/data-access; add homework student workflow and update design docs.
2025-12-31 11:59:03 +08:00

154 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 作业模块实现设计文档Homework Module
**日期**: 2025-12-31
**模块**: Homework (`src/modules/homework`)
---
## 1. 概述
作业模块提供“由试卷派发作业”的完整生命周期:
- 教师从已存在的 Exam 派发 Homework Assignment冻结当时的结构与题目引用
- 指定作业目标学生Targets
- 学生开始一次作答Submission保存答案Answers并最终提交
- 教师在提交列表中查看并批改(按题给分/反馈,汇总总分)
核心目标是:在不破坏 Exam 本体数据的前提下,为作业提供可追溯、可批改、可统计的独立域模型。
**说明(合并调整)**:教师端“阅卷/批改”统一通过 Homework submissions 完成,`/teacher/exams/grading*` 相关路由已重定向到 `/teacher/homework/submissions`
---
## 2. 数据架构
### 2.1 核心实体
- `homework_assignments`: 作业实例(从 exam 派生)
- `homework_assignment_questions`: 作业与题目关系score/order
- `homework_assignment_targets`: 作业目标学生列表
- `homework_submissions`: 学生作业尝试attempt_no/status/时间/是否迟交)
- `homework_answers`: 每题答案answer_content/score/feedback
数据库变更记录见:[schema-changelog.md](file:///c:/Users/xiner/Desktop/CICD/docs/db/schema-changelog.md#L34-L77)
### 2.2 设计要点:冻结 Exam → Homework Assignment
- `homework_assignments.source_exam_id` 保存来源 Exam
- `homework_assignments.structure` 在 publish 时复制 `exams.structure`(冻结当时的呈现结构)
- 题目关联使用 `homework_assignment_questions`(仍引用 `questions` 表,作业侧记录分值与顺序)
---
## 3. 路由与页面
### 3.1 教师端
- `/teacher/homework/assignments`: 作业列表
实现:[assignments/page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/teacher/homework/assignments/page.tsx)
- `/teacher/homework/assignments/create`: 从 Exam 派发作业
实现:[create/page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/teacher/homework/assignments/create/page.tsx)
- `/teacher/homework/assignments/[id]`: 作业详情
实现:[[id]/page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/teacher/homework/assignments/%5Bid%5D/page.tsx)
- `/teacher/homework/assignments/[id]/submissions`: 作业提交列表(按作业筛选)
实现:[[id]/submissions/page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/teacher/homework/assignments/%5Bid%5D/submissions/page.tsx)
- `/teacher/homework/submissions`: 全部提交列表
实现:[submissions/page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/teacher/homework/submissions/page.tsx)
- `/teacher/homework/submissions/[submissionId]`: 批改页
实现:[[submissionId]/page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/teacher/homework/submissions/%5BsubmissionId%5D/page.tsx)
关联重定向:
- `/teacher/exams/grading``/teacher/homework/submissions`
实现:[grading/page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/teacher/exams/grading/page.tsx)
- `/teacher/exams/grading/[submissionId]``/teacher/homework/submissions`
实现:[grading/[submissionId]/page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/teacher/exams/grading/%5BsubmissionId%5D/page.tsx)
### 3.2 学生端
- `/student/learning/assignments`: 作业列表
实现:[page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/student/learning/assignments/page.tsx)
- `/student/learning/assignments/[assignmentId]`: 作答页(开始/保存/提交)
实现:[[assignmentId]/page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/student/learning/assignments/%5BassignmentId%5D/page.tsx)
---
## 4. 数据访问层Data Access
数据访问位于:[data-access.ts](file:///c:/Users/xiner/Desktop/CICD/src/modules/homework/data-access.ts)
### 4.1 教师侧查询
- `getHomeworkAssignments`:作业列表(可按 creatorId/ids
- `getHomeworkAssignmentById`:作业详情(含目标人数、提交数统计)
- `getHomeworkSubmissions`:提交列表(可按 assignmentId
- `getHomeworkSubmissionDetails`:提交详情(题目内容 + 学生答案 + 分值/顺序)
### 4.2 学生侧查询
- `getStudentHomeworkAssignments(studentId)`:只返回“已派发给该学生、已发布、且到达 availableAt”的作业
- `getStudentHomeworkTakeData(assignmentId, studentId)`进入作答页所需数据assignment + 当前/最近 submission + 题目列表 + 已保存答案)
### 4.3 开发模式用户选择Demo
为了在未接入真实 Auth 的情况下可演示学生端页面,提供:
- `getDemoStudentUser()`:优先选取最早创建的 student若无 student则退化到任意用户
---
## 5. Server Actions
实现位于:[actions.ts](file:///c:/Users/xiner/Desktop/CICD/src/modules/homework/actions.ts)
### 5.1 教师侧
- `createHomeworkAssignmentAction`:从 exam 创建 assignment可写入 targets可选择 publish默认 true
- `gradeHomeworkSubmissionAction`:按题写入 score/feedback并汇总写入 submission.score 与 status=graded
### 5.2 学生侧
- `startHomeworkSubmissionAction`:创建一次 submissionattemptNo + startedAt并校验
- assignment 已发布
- student 在 targets 中
- availableAt 已到
- 未超过 maxAttempts
- `saveHomeworkAnswerAction`:保存/更新某题答案upsert 到 homework_answers
- `submitHomeworkAction`:提交作业(校验 dueAt/lateDueAt/allowLate写入 submittedAt/isLate/status=submitted
---
## 6. UI 组件
### 6.1 教师批改视图
- [HomeworkGradingView](file:///c:/Users/xiner/Desktop/CICD/src/modules/homework/components/homework-grading-view.tsx)
- 左侧:学生答案只读展示
- 右侧:按题录入分数与反馈,并提交批改
### 6.2 学生作答视图
- [HomeworkTakeView](file:///c:/Users/xiner/Desktop/CICD/src/modules/homework/components/homework-take-view.tsx)
- Start开始一次作答
- Save按题保存
- Submit提交提交前会先保存当前题目答案
- 题型支持:`text` / `judgment` / `single_choice` / `multiple_choice`
题目 content 约定与题库一致:`{ text, options?: [{ id, text, isCorrect? }] }`(作答页仅消费 `id/text`)。
---
## 7. 类型定义
类型位于:[types.ts](file:///c:/Users/xiner/Desktop/CICD/src/modules/homework/types.ts)
- 教师侧:`HomeworkAssignmentListItem` / `HomeworkSubmissionDetails`
- 学生侧:`StudentHomeworkAssignmentListItem` / `StudentHomeworkTakeData`
---
## 8. 校验
- `npm run typecheck`: 通过
- `npm run lint`: 0 errors仓库其他位置存在 warnings与本模块新增功能无直接关联