# 考试和作业模块审计报告

> 审计范围：`exams`（考试/试卷/AI 出题）、`homework`（作业/指派/作答/批改）、`proctoring`（监考/防作弊）三个相互耦合的模块，以及它们在 `app/(dashboard)` 下的对应路由页面。

---

## 一、现有实现概要

### 1.1 文件分布

| 层 | 模块 | 关键文件 | 行数 |
|----|------|----------|------|
| app 路由 | teacher/exams | `page.tsx` / `all/page.tsx` / `create/page.tsx` / `[id]/build/page.tsx` / `[id]/proctoring/page.tsx` / `grading/page.tsx`（重定向） / `grading/[submissionId]/page.tsx`（重定向） | - |
| app 路由 | teacher/homework | `assignments/page.tsx` / `assignments/create/page.tsx` / `assignments/[id]/page.tsx` / `assignments/[id]/submissions/page.tsx` | - |
| app 路由 | student/learning/assignments | `page.tsx` / `[assignmentId]/page.tsx` + `loading.tsx` | - |
| modules | exams | `actions.ts`(691) / `ai-pipeline.ts`(857) / `data-access.ts`(473) / `types.ts`(31) / `hooks/use-exam-preview.ts`(295) / `utils/normalize-structure.ts`(57) / `components/*`(18 文件) | - |
| modules | homework | `actions.ts`(239) / `data-access.ts`(598) / `data-access-write.ts`(285) / `data-access-classes.ts`(232) / `stats-service.ts`(425) / `schema.ts`(29) / `types.ts`(186) / `components/*`(11 文件) | - |
| modules | proctoring | `actions.ts`(139) / `data-access.ts`(409) / `types.ts`(136) / `components/*`(3 文件) | - |

### 1.2 主要数据流

1. **考试创建**：`teacher/exams/create` → `createExamAction` / `createAiExamAction` → `persistExamDraft` / `persistAiGeneratedExamDraft` → `db.insert(exams)`。
2. **组卷**：`teacher/exams/[id]/build` → `getExamById` + `getQuestions` → `ExamAssembly` → `updateExamAction`。
3. **作业下发**：`teacher/homework/assignments/create` → `createHomeworkAssignmentAction` → `getExamWithQuestionsForHomework`（跨模块调用 exams data-access）→ `createHomeworkAssignment`（事务写入 assignments + questions + targets）。
4. **学生作答**：`student/learning/assignments/[assignmentId]` → `getStudentHomeworkTakeData` → `HomeworkTakeView` → `startHomeworkSubmissionAction` / `saveHomeworkAnswerAction` / `submitHomeworkAction`。
5. **教师批改**：`teacher/homework/assignments/[id]/submissions` → `getHomeworkSubmissions` → 跳转 `[submissionId]` → `getHomeworkSubmissionDetails` → `HomeworkGradingView` → `gradeHomeworkSubmissionAction`。
6. **监考**：`teacher/exams/[id]/proctoring` → `getProctoringDashboardAction` → `getExamForProctoring` + `getExamProctoringSummary` + `getStudentProctoringStatuses` + `getRecentProctoringEvents`。

### 1.3 架构图覆盖情况

`docs/architecture/004_architecture_impact_map.md` 已记录 exams（§2.2）、homework（§2.3）、proctoring（§2.21）三个模块的导出函数、依赖关系、已知问题和文件清单。架构图信息基本完整，但以下细节未记录：

- `homework/components/homework-assignment-exam-error-explorer.tsx` 等错误分析组件未在文件清单中列出。
- `exams/components/assembly/*` 子目录的 4 个组件未单独记录行数。
- proctoring 的 `exam-mode-config.tsx` 死代码状态已在已知问题中标注，但未记录其与 `ExamForm` 的集成缺失原因。

---

## 二、现存问题与原因分析

### 2.1 国际化缺失（严重）

**问题**：该模块几乎所有用户可见文本均为硬编码，且中英文混杂。

**出现位置**：
- `src/modules/exams/components/exam-form.tsx`：硬编码英文 `"Exam draft created"`、`"Redirecting to exam builder..."`、`"Missing subject or grade configuration"`。
- `src/modules/exams/components/exam-columns.tsx`：硬编码 `"Exam Info"`、`"Status"`、`"Stats"`、`"Difficulty"`、`"Easy"`、`"Medium"`、`"Hard"`。
- `src/modules/exams/components/exam-actions.tsx`：硬编码 `"Preview Exam"`、`"Copy ID"`、`"Edit"`、`"Build"`、`"Publish"`、`"Archive"`、`"Delete"`、`"Are you absolutely sure?"`。
- `src/modules/homework/components/homework-take-view.tsx`：硬编码 `"Questions"`、`"Start Assignment"`、`"Submit Assignment"`、`"Save Answer"`、`"Due Date"`、`"Attempts"`、`"Description"`、`"Progress"`、`"Confirm Submission"`。
- `src/modules/homework/components/homework-grading-view.tsx`：硬编码 `"Grading Summary"`、`"Total Score"`、`"Correct"`、`"Incorrect"`、`"Partial"`、`"Submit Grades"`、`"Previous Student"`、`"Next Student"`。
- `src/modules/homework/components/homework-assignment-form.tsx`：硬编码中文 `"快速作业"`、`"考试派生作业"`、`"直接输入标题和描述，无需建题"`、`"从已有考试派生作业"`。
- `src/app/(dashboard)/teacher/homework/assignments/page.tsx`：硬编码中文 `"作业列表"`、`"管理作业，查看提交率与批改进度。"`、`"创建作业"`、`"暂无作业"`、`"按班级筛选："`、`"清除筛选"`、`"标题"`、`"状态"`、`"截止时间"`、`"提交率"`、`"平均分"`、`"逾期"`、`"来源考试"`、`"创建时间"`。
- `src/app/(dashboard)/teacher/homework/assignments/[id]/submissions/page.tsx`：硬编码英文 `"Submissions"`、`"Student"`、`"Status"`、`"Submitted"`、`"Score"`、`"Action"`、`"Grade"`、`"Back"`、`"Open Assignment"`。
- `src/app/(dashboard)/student/learning/assignments/page.tsx`：硬编码英文 `"Assignments"`、`"Your homework and practice assignments."`、`"No assignments"`、`"Pending"`、`"Completed"`、`"Overdue"`、`"Due"`、`"Attempts"`、`"Score"`、`"Start"`、`"Continue"`、`"View"`、`"Review"`。
- `src/modules/proctoring/components/exam-mode-config.tsx`：硬编码中文 `"考试模式"`、`"模式"`、`"考试时长（分钟）"`、`"题目乱序"`、`"启用防作弊监控"`、`"允许迟开始"`、`"迟到宽限时间（分钟）"`。

**问题原因**：模块在 v3 i18n 体系建立前已实现，后续未回填翻译键。

**违反规则**：项目规则"所有用户可见文本必须适配 i18n（使用 next-intl），提取翻译键"。

**直接后果**：
- 切换到英文 locale 后，作业列表页仍显示中文；考试列表页仍显示英文。多角色（admin/teacher/parent/student）无法获得一致的语言体验。
- 国际化交付阻塞，无法满足 K12 学校多语言场景。

### 2.2 类型安全问题

**问题**：多处使用 `as any` / `as unknown` 断言，违反 TypeScript 严格规范。

**出现位置**：
- `src/modules/exams/components/exam-form.tsx:38`：`resolver: zodResolver(formSchema) as any`（注释 `eslint-disable`）。
- `src/modules/exams/components/exam-form.tsx:163,168`：`form.handleSubmit(onSubmit as any)`（两处 `eslint-disable`）。
- `src/modules/exams/components/exam-actions.tsx:60`：`questionById.set(q.id, q as unknown as Question)`。
- `src/modules/exams/components/exam-actions.tsx:63`：`const hydrate = (nodes: any[]): ExamNode[]`（`eslint-disable`）。
- `src/modules/homework/components/homework-take-view.tsx:346-347`：`(prev[q.questionId]?.answer as string[])`。
- `src/modules/homework/components/homework-take-view.tsx:468`：`(answersByQuestionId[q.questionId]?.answer as unknown[])`。
- `src/modules/homework/components/homework-grading-view.tsx:199`：`(ans.questionContent.options as ChoiceOption[])`。
- `src/modules/homework/data-access.ts:484`：`structure: assignment.structure as unknown`。

**问题原因**：zodResolver 与 react-hook-form 类型不兼容时偷懒用 `as any`；题目内容为 `unknown` 时未做类型守卫直接断言。

**违反规则**：项目规则"禁止 `any`"、"禁止 `as` 断言（除非从 `unknown` 转换或测试中，需注释原因）"。

**直接后果**：类型系统形同虚设，运行时错误无法在编译期捕获；重构时易引入隐性 bug。

### 2.3 权限校验不完整

**问题**：`gradeHomeworkSubmissionAction` 未校验教师对该提交记录的访问权限。

**出现位置**：`src/modules/homework/actions.ts:249-292`。

**问题原因**：`gradeHomeworkSubmissionAction` 仅调用 `requirePermission(Permissions.HOMEWORK_GRADE)`，未校验当前教师是否为该作业的创建者、或该学生所在班级的任课教师。任意拥有 `HOMEWORK_GRADE` 权限的教师均可批改任意学生的任意作业。

**违反规则**：项目规则"所有敏感数据查询必须在 data-access 层结合当前用户权限过滤，Server Action 二次校验"。

**直接后果**：横向越权风险——教师 A 可批改教师 B 的学生作业，篡改成绩。

### 2.4 错误边界与加载状态缺失

**问题**：考试和作业模块的页面缺少 React Error Boundary 和 Suspense 骨架屏。

**出现位置**：
- `src/app/(dashboard)/teacher/exams/[id]/build/page.tsx`：无 `error.tsx`、无 `loading.tsx`，`getExamById` 失败时整页 500。
- `src/app/(dashboard)/teacher/exams/[id]/proctoring/page.tsx`：无 `error.tsx`、无 `loading.tsx`。
- `src/app/(dashboard)/teacher/homework/assignments/[id]/page.tsx`：无 `error.tsx`、无 `loading.tsx`。
- `src/app/(dashboard)/teacher/homework/assignments/[id]/submissions/page.tsx`：无 `error.tsx`、无 `loading.tsx`。
- `src/app/(dashboard)/teacher/homework/assignments/create/page.tsx`：无 `loading.tsx`。
- `src/app/(dashboard)/student/learning/assignments/[assignmentId]/page.tsx`：有 `loading.tsx` 但无 `error.tsx`。
- 仅 `exams/all` 和 `exams/create` 有 `loading.tsx`。

**问题原因**：页面开发时未配套错误边界；Suspense 仅在 `exams/all` 使用。

**违反规则**：项目规则"每个独立的数据区块必须用 React Error Boundary 包裹"、"异步数据使用 React Suspense + 骨架屏"、"明确处理空数据、无权限、网络异常等边界状态"。

**直接后果**：数据库连接抖动或单条记录缺失会导致整页崩溃，无法降级展示。

### 2.5 组件复用不足

**问题**：题目渲染逻辑在作答页、批改页、复习页三处重复实现。

**出现位置**：
- `src/modules/homework/components/homework-take-view.tsx:248-400`：渲染 `single_choice` / `multiple_choice` / `judgment` / `text` 四种题型。
- `src/modules/homework/components/homework-grading-view.tsx:155-328`：再次渲染同样四种题型（带正确答案高亮）。
- `src/modules/homework/components/student-homework-review-view.tsx`：第三次渲染同样四种题型（带批改反馈）。
- 三处都重复实现 `getQuestionText` / `getOptions` / `isRecord` 等工具函数。

**问题原因**：未抽象 `QuestionRenderer` / `QuestionAnswerInput` / `QuestionResultDisplay` 等复用组件。

**违反规则**：项目规则"最大化复用：识别四个角色共用的 UI 块和业务逻辑块，抽象为泛型组件和 hooks"、"组合优先：所有 UI 通过组件组合实现灵活性"。

**直接后果**：题型扩展（如填空、排序、拖拽）需改三处；样式不一致风险高；单测难以覆盖。

### 2.6 监考模块死代码

**问题**：`ExamModeConfig` 组件已实现但未集成到考试创建/编辑表单。

**出现位置**：`src/modules/proctoring/components/exam-mode-config.tsx`（230 行）从未被 import。

**问题原因**：架构图 §2.21 已标注"❌ P0：`exam-mode-config.tsx` 未集成到考试表单（死代码，监考功能无法启用）"，但至今未修复。

**违反规则**：项目规则"如果架构图未覆盖该模块的任何部分，必须优先补全架构图再继续"——此处架构图已记录但代码未修复。

**直接后果**：监考功能（防作弊、限时、全屏强制）完全不可用；`proctoring` 模块的 `recordProctoringEventAction` 无前端触发路径。

### 2.7 文件行数超限

**问题**：`ai-pipeline.ts` 857 行，超过 800 行建议值。

**出现位置**：`src/modules/exams/ai-pipeline.ts`。

**问题原因**：混合了 AI 请求构造、响应解析、Zod 校验、题目归一化、结构生成 5 类职责。

**违反规则**：项目规则"Server Actions / Data Access 模块：建议 ≤ 800 行"、"超过建议行数时应考虑拆分"。

**直接后果**：维护困难；AI 供应商切换需改动整个文件。

### 2.8 可访问性缺陷

**问题**：交互元素缺少 ARIA 属性，颜色作为唯一信息载体。

**出现位置**：
- `src/modules/homework/components/homework-grading-view.tsx:156-158`：用 `border-l-emerald-500` / `border-l-red-500` 表示对错，无文本替代。
- `src/modules/exams/components/exam-columns.tsx:110-121`：难度仅用色块表示，`text-[10px]` 标签为英文缩写。
- `src/modules/homework/components/homework-take-view.tsx:471-486`：题目导航按钮 `aria-label` 为英文 `Jump to question ${i+1}`，未 i18n。
- 批改页 `Correct`/`Incorrect` 按钮仅靠颜色区分状态。

**违反规则**：项目规则"可访问性（a11y）：语义化标签、ARIA 属性、键盘导航"。

**直接后果**：色盲教师无法区分对错；屏幕阅读器用户体验差。

### 2.9 性能问题

**问题**：`getHomeworkSubmissionDetails` 为获取前后导航 ID 拉取全部提交记录。

**出现位置**：`src/modules/homework/data-access.ts:540-548`。

```typescript
const allSubmissions = await db.query.homeworkSubmissions.findMany({
  where: eq(homeworkSubmissions.assignmentId, submission.assignmentId),
  orderBy: [desc(homeworkSubmissions.updatedAt)],
  columns: { id: true },
})
const currentIndex = allSubmissions.findIndex((s) => s.id === submissionId)
```

**问题原因**：未用 SQL 窗口函数或 `OFFSET`/`LIMIT` 获取相邻记录。

**违反规则**：项目规则"性能：优先使用 React Server Components 获取初始数据"——此处为 data-access 层低效查询。

**直接后果**：班级 50 人作业批改时，每次打开详情都拉取 50 条记录的 ID。

### 2.10 答案保存无防抖与离线支持

**问题**：学生作答时每题手动点击"Save Answer"，无自动保存、无离线缓存。

**出现位置**：`src/modules/homework/components/homework-take-view.tsx:139-151`。

**问题原因**：未实现自动保存（防抖）和 `localStorage` 离线缓存。

**违反规则**：项目规则"明确处理网络异常等边界状态"。

**直接后果**：网络抖动时学生答案丢失；刷新页面（尽管有 `beforeunload` 警告）仍可能丢失未保存答案。

---

## 三、行业差距对比

### 3.1 与主流 K12 考试系统对比

| 功能 | 行业主流（如智学网、猿题库、Google Classroom） | 当前实现 | 差距影响 |
|------|------|------|------|
| 限时考试 | 支持设定考试时长，到时自动提交 | `ExamModeConfig` 已实现但未集成 | 教师无法组织课堂限时测验 |
| 题目乱序 | 每位学生题目顺序随机 | `ExamModeConfig` 已实现但未集成 | 防作弊能力缺失 |
| 监考模式 | 切屏检测、强制全屏、AI 行为分析 | `proctoring` 模块后端已实现，前端无入口 | 远程考试无法防作弊 |
| 自动批改 | 选择题/判断题提交后即时出分 | `homework-grading-view` 有 `applyAutoGrades` 但仅在打开批改页时计算，不回写 | 学生提交后看不到即时成绩 |
| 批量批改 | 列表页勾选多份提交批量打分 | 仅支持逐份批改 | 50 人班级批改效率低 |
| 评分量规（Rubric） | 文本题按维度打分 | 仅支持单分数 | 主观题批改粗放 |
| 考试分析 | 题目难度、区分度、知识点掌握度 | `homework/stats-service` 有作业分析，考试无分析 | 考试后无法复盘教学质量 |
| 学生答案草稿 | 自动保存 + 离线缓存 | 手动保存，无离线 | 弱网环境答案易丢 |
| 部分分自动判分 | 多选题漏选得部分分 | 全对才得分 | 评分不够精细 |
| 重考与补考 | 支持重考流程与成绩记录 | `maxAttempts` 已支持但无补考入口 | 补考场景需手动创建新作业 |

### 3.2 多角色体验差距

| 角色 | 行业主流体验 | 当前实现 | 差距 |
|------|------|------|------|
| **教师** | 一站式工作台：创建→发布→监考→批改→分析 | 分散在 `/teacher/exams/*` 和 `/teacher/homework/*` 两个独立菜单 | 考试到作业的链路割裂 |
| **学生** | 统一"待办"入口：作业+考试+复习 | 仅 `/student/learning/assignments`，考试作答也走作业流程 | 考试与作业概念混淆 |
| **家长** | 查看孩子考试详情、错题本、趋势 | `parent` 模块仅有作业摘要，无考试详情 | 家长无法了解考试表现 |
| **管理员** | 全校考试统计、年级对比、教师工作量 | 无管理员视角的考试仪表盘 | 管理层无法宏观决策 |

### 3.3 UI/UX 差距

- **空状态**：`exams/all` 有空状态，但 `homework/assignments/[id]/submissions` 无空状态（无提交时显示空表格）。
- **加载骨架屏**：仅 `exams/all`、`exams/create`、`student/learning/assignments` 有；其余页面白屏加载。
- **错误降级**：全模块无 `error.tsx`，任何数据加载失败均导致整页 500。
- **移动端适配**：`homework-take-view` 和 `homework-grading-view` 使用 `lg:grid-cols-12`，移动端可正常显示但未优化触控体验（题目导航按钮过小）。

---

## 四、改进优先级建议

### P0（紧急，影响安全与核心功能）

1. **补全 `gradeHomeworkSubmissionAction` 权限校验**：在 data-access 层新增 `getHomeworkSubmissionForGrading(submissionId, teacherId, dataScope)`，校验教师对该作业的访问权（创建者或班级任课教师）。Server Action 二次校验。
2. **i18n 全量回填**：新建 `messages/zh-CN/exam-homework.json` 和 `messages/en/exam-homework.json`，提取该模块所有硬编码文本为翻译键；在 `i18n/request.ts` 注册新命名空间；组件改用 `useTranslations('examHomework')`。
3. **集成 `ExamModeConfig` 到考试表单**：在 `exam-form.tsx` 中引入 `ExamModeConfig`，将 `examMode` / `durationMinutes` / `shuffleQuestions` / `antiCheatEnabled` 等字段纳入 `ExamFormValues`，持久化到 `exams` 表；`proctoring` 模块读取这些配置启用监考。

### P1（重要，影响可维护性与体验）

4. **添加 Error Boundary 与 loading.tsx**：为 `exams/[id]/build`、`exams/[id]/proctoring`、`homework/assignments/[id]`、`homework/assignments/[id]/submissions`、`homework/assignments/create`、`student/learning/assignments/[assignmentId]` 配套 `error.tsx` + `loading.tsx`。
5. **抽象题目渲染组件**：新建 `homework/components/question-renderer.tsx`，导出 `QuestionRenderer`（只读展示）、`QuestionAnswerInput`（作答交互）、`QuestionGradingPanel`（批改面板），三处页面改用组合模式复用。
6. **清理类型断言**：`exam-form.tsx` 的 `as any` 改为正确泛型；`exam-actions.tsx` 的 `hydrate` 函数用类型守卫替代 `any[]`；`homework-take-view.tsx` / `homework-grading-view.tsx` 的 `as` 断言改为类型守卫。
7. **拆分 `ai-pipeline.ts`**：按职责拆为 `ai-pipeline/request.ts`（请求构造）、`ai-pipeline/parse.ts`（响应解析+校验）、`ai-pipeline/structure.ts`（结构生成），原文件作为 re-export 入口。
8. **优化 `getHomeworkSubmissionDetails` 相邻记录查询**：用 `LEAD`/`LAG` 窗口函数或两次 `LIMIT 1` 查询替代全量拉取。

### P2（增强，提升体验与可扩展性）

9. **学生答案自动保存 + 离线缓存**：`homework-take-view` 增加 `useDebouncedAutoSave` hook，答案变更后 3 秒自动保存；同时写入 `localStorage`，断网时队列化重试。
10. **考试分析仪表盘**：新增 `exams/components/exam-analytics-dashboard.tsx`，复用 `homework/stats-service` 模式，展示题目难度、区分度、知识点掌握度。
11. **批量批改 UI**：`homework/assignments/[id]/submissions` 增加多选 + 批量打分（全对/全错/自定义分数）。
12. **a11y 修复**：颜色指示器增加文本替代；题目导航按钮 `aria-label` i18n；批改页 `Correct`/`Incorrect` 按钮增加 `aria-pressed`。
13. **配置驱动的角色渲染**：定义 `ExamHomeworkRoleConfig` 接口，各角色模块仅组合复用单元，新增角色只改配置。

---

## 五、架构图同步说明

本次审计发现架构图需补充以下信息：

### 5.1 需补充的节点

1. **`004_architecture_impact_map.md` §2.2 exams 模块**：
   - 文件清单补充 `components/assembly/exam-paper-preview.tsx`、`question-bank-list.tsx`、`selected-question-list.tsx`、`structure-editor.tsx` 四个组件的行数与职责。
   - 已知问题补充：`exam-mode-config.tsx` 未集成（与 proctoring 模块联动缺失）。

2. **`004_architecture_impact_map.md` §2.3 homework 模块**：
   - 文件清单补充 `components/homework-assignment-exam-content-card.tsx`、`homework-assignment-exam-error-explorer.tsx`、`homework-assignment-exam-error-explorer-lazy.tsx`、`homework-assignment-exam-preview-pane.tsx`、`homework-assignment-question-error-detail-panel.tsx`、`homework-assignment-question-error-overview-card.tsx`、`student-homework-review-view.tsx` 七个组件的行数与职责。
   - 已知问题补充：`gradeHomeworkSubmissionAction` 权限校验不完整（P0 安全问题）。

3. **`004_architecture_impact_map.md` §2.21 proctoring 模块**：
   - 已知问题补充：`ExamModeConfig` 未集成的根因是 `ExamFormValues` 未包含 `examMode` 字段，需扩展表单 schema。

4. **`005_architecture_data.json`**：
   - `modules.exams.exports` 补充 `ExamModeConfig` 集成状态字段。
   - `modules.homework.knownIssues` 新增 `gradeHomeworkPermissionGap` 节点。
   - `dependencyMatrix` 补充 `proctoring → exams` 的 `examModeConfig` 依赖关系（当前仅记录 data-access 依赖，未记录 UI 集成依赖）。

### 5.2 无需修改的部分

- 三层架构依赖关系记录准确（`app → modules → shared`）。
- 跨模块 data-access 调用关系记录完整（exams ↔ homework ↔ proctoring）。
- 文件行数统计基本准确（`ai-pipeline.ts` 857 行已记录）。

---

## 六、重构方案设计（概要）

### 6.1 完全解耦

定义 `ExamHomeworkServicePort` 接口，抽象数据依赖：

```typescript
// modules/exam-homework/types/service-port.ts
export interface ExamHomeworkServicePort {
  getExams(scope: DataScope): Promise<ExamListItem[]>
  getExamById(id: string): Promise<ExamDetail | null>
  getHomeworkAssignments(scope: DataScope): Promise<HomeworkAssignmentListItem[]>
  getStudentHomeworkTakeData(assignmentId: string, studentId: string): Promise<StudentHomeworkTakeData | null>
  // ... 其余数据访问方法
}

export interface ExamHomeworkPermissionPort {
  canGradeSubmission(teacherId: string, submissionId: string): Promise<boolean>
  canViewExam(userId: string, examId: string, scope: DataScope): Promise<boolean>
}
```

通过 `ExamHomeworkServiceProvider`（React Context）注入实现，模块内部组件绝不 import 其他业务模块的 actions。

### 6.2 组合优先

抽象题目渲染组件：

```typescript
// modules/exam-homework/components/question-renderer.tsx
export function QuestionRenderer({
  question,
  mode,
  children,
}: {
  question: QuestionData
  mode: 'take' | 'grade' | 'review'
  children?: React.ReactNode
}) { ... }

export function QuestionAnswerInput({ question, value, onChange, disabled }: TakeProps) { ... }
export function QuestionGradingPanel({ answer, onScoreChange, onFeedbackChange }: GradeProps) { ... }
```

### 6.3 国际化就绪

翻译文件结构示例：

```json
// messages/zh-CN/exam-homework.json
{
  "exam": {
    "list": { "title": "考试列表", "create": "创建考试", "empty": "暂无考试" },
    "form": { "title": "考试标题", "subject": "科目", "grade": "年级", "difficulty": "难度" },
    "status": { "draft": "草稿", "published": "已发布", "archived": "已归档" },
    "actions": { "preview": "预览", "edit": "编辑", "build": "组卷", "publish": "发布", "duplicate": "复制", "delete": "删除" }
  },
  "homework": {
    "list": { "title": "作业列表", "create": "创建作业", "submissionRate": "提交率", "averageScore": "平均分", "overdue": "逾期" },
    "take": { "start": "开始作答", "submit": "提交作业", "saveAnswer": "保存答案", "confirmSubmit": "确认提交", "unansweredWarning": "您有 {{count}} 道题未作答" },
    "grade": { "summary": "批改摘要", "totalScore": "总分", "correct": "正确", "incorrect": "错误", "partial": "部分正确", "submitGrades": "提交成绩" }
  },
  "proctoring": {
    "mode": { "homework": "作业模式", "timed": "限时模式", "proctored": "监考模式" },
    "config": { "duration": "考试时长（分钟）", "shuffleQuestions": "题目乱序", "antiCheat": "启用防作弊监控" }
  }
}
```

### 6.4 错误与边界处理

- 每个页面配套 `error.tsx`（React Error Boundary）。
- 每个页面配套 `loading.tsx`（骨架屏）。
- `ExamHomeworkErrorBoundary` 组件区分 `NetworkError` / `PermissionDenied` / `NotFound` 三种状态。

### 6.5 可测试性

- 纯逻辑函数（`applyAutoGrades` / `computeIsCorrect` / `normalizeStructure`）已与 UI 分离，补充单测。
- 数据获取逻辑通过 `ServicePort` 接口可 mock。
- 新增 `__tests__/exam-homework-service.test.ts` 覆盖权限校验与数据流转。

### 6.6 可扩展性

配置驱动设计：

```typescript
// modules/exam-homework/config/role-config.ts
export const EXAM_HOMEWORK_ROLE_CONFIG: Record<Role, ExamHomeworkRoleConfig> = {
  admin: { widgets: ['stats', 'all-exams', 'all-homework'], canGrade: false },
  teacher: { widgets: ['my-exams', 'my-homework', 'grading-queue'], canGrade: true },
  parent: { widgets: ['child-exam-results', 'child-homework-summary'], canGrade: false },
  student: { widgets: ['pending-exams', 'pending-homework', 'results'], canGrade: false },
}
```

### 6.7 企业级补充

- **a11y**：颜色指示器增加 `sr-only` 文本；`aria-pressed` / `aria-label` 全覆盖。
- **性能**：RSC 获取初始数据（已实现）；客户端组件仅负责交互（已实现）；流式渲染（`Suspense` 已部分使用）。
- **安全**：data-access 层结合 `dataScope` 过滤（已实现）；Server Action 二次校验（P0 待补全）。
- **监控**：预留 `trackExamEvent(eventName, payload)` 接口，关键操作（创建/提交/批改）埋点。
