- Add comprehensive audit report for exam and homework module - Create exam-homework i18n message files (zh-CN + en) and register namespace - Add permission check to gradeHomeworkSubmissionAction to prevent horizontal privilege escalation - Add Error Boundary + loading.tsx for 5 key pages (exam build/proctoring, homework assignment/submissions, student assignment) - Refactor exam-columns to createExamColumns(t) factory for i18n support - Refactor exam-data-table to manage columns internally via useTranslations - Replace hardcoded strings with i18n keys in all exam/homework components and pages - Add getHomeworkSubmissionForGrading data-access for secure grading flow
26 KiB
考试和作业模块审计报告
审计范围:
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 主要数据流
- 考试创建:
teacher/exams/create→createExamAction/createAiExamAction→persistExamDraft/persistAiGeneratedExamDraft→db.insert(exams)。 - 组卷:
teacher/exams/[id]/build→getExamById+getQuestions→ExamAssembly→updateExamAction。 - 作业下发:
teacher/homework/assignments/create→createHomeworkAssignmentAction→getExamWithQuestionsForHomework(跨模块调用 exams data-access)→createHomeworkAssignment(事务写入 assignments + questions + targets)。 - 学生作答:
student/learning/assignments/[assignmentId]→getStudentHomeworkTakeData→HomeworkTakeView→startHomeworkSubmissionAction/saveHomeworkAnswerAction/submitHomeworkAction。 - 教师批改:
teacher/homework/assignments/[id]/submissions→getHomeworkSubmissions→ 跳转[submissionId]→getHomeworkSubmissionDetails→HomeworkGradingView→gradeHomeworkSubmissionAction。 - 监考:
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。
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(紧急,影响安全与核心功能)
- 补全
gradeHomeworkSubmissionAction权限校验:在 data-access 层新增getHomeworkSubmissionForGrading(submissionId, teacherId, dataScope),校验教师对该作业的访问权(创建者或班级任课教师)。Server Action 二次校验。 - i18n 全量回填:新建
messages/zh-CN/exam-homework.json和messages/en/exam-homework.json,提取该模块所有硬编码文本为翻译键;在i18n/request.ts注册新命名空间;组件改用useTranslations('examHomework')。 - 集成
ExamModeConfig到考试表单:在exam-form.tsx中引入ExamModeConfig,将examMode/durationMinutes/shuffleQuestions/antiCheatEnabled等字段纳入ExamFormValues,持久化到exams表;proctoring模块读取这些配置启用监考。
P1(重要,影响可维护性与体验)
- 添加 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。 - 抽象题目渲染组件:新建
homework/components/question-renderer.tsx,导出QuestionRenderer(只读展示)、QuestionAnswerInput(作答交互)、QuestionGradingPanel(批改面板),三处页面改用组合模式复用。 - 清理类型断言:
exam-form.tsx的as any改为正确泛型;exam-actions.tsx的hydrate函数用类型守卫替代any[];homework-take-view.tsx/homework-grading-view.tsx的as断言改为类型守卫。 - 拆分
ai-pipeline.ts:按职责拆为ai-pipeline/request.ts(请求构造)、ai-pipeline/parse.ts(响应解析+校验)、ai-pipeline/structure.ts(结构生成),原文件作为 re-export 入口。 - 优化
getHomeworkSubmissionDetails相邻记录查询:用LEAD/LAG窗口函数或两次LIMIT 1查询替代全量拉取。
P2(增强,提升体验与可扩展性)
- 学生答案自动保存 + 离线缓存:
homework-take-view增加useDebouncedAutoSavehook,答案变更后 3 秒自动保存;同时写入localStorage,断网时队列化重试。 - 考试分析仪表盘:新增
exams/components/exam-analytics-dashboard.tsx,复用homework/stats-service模式,展示题目难度、区分度、知识点掌握度。 - 批量批改 UI:
homework/assignments/[id]/submissions增加多选 + 批量打分(全对/全错/自定义分数)。 - a11y 修复:颜色指示器增加文本替代;题目导航按钮
aria-labeli18n;批改页Correct/Incorrect按钮增加aria-pressed。 - 配置驱动的角色渲染:定义
ExamHomeworkRoleConfig接口,各角色模块仅组合复用单元,新增角色只改配置。
五、架构图同步说明
本次审计发现架构图需补充以下信息:
5.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 模块联动缺失)。
- 文件清单补充
-
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 安全问题)。
- 文件清单补充
-
004_architecture_impact_map.md§2.21 proctoring 模块:- 已知问题补充:
ExamModeConfig未集成的根因是ExamFormValues未包含examMode字段,需扩展表单 schema。
- 已知问题补充:
-
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.ts857 行已记录)。
六、重构方案设计(概要)
6.1 完全解耦
定义 ExamHomeworkServicePort 接口,抽象数据依赖:
// 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 组合优先
抽象题目渲染组件:
// 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 国际化就绪
翻译文件结构示例:
// 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 可扩展性
配置驱动设计:
// 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)接口,关键操作(创建/提交/批改)埋点。