Files
NextEdu/docs/architecture/audit/archive/homework-audit-report.md

21 KiB
Raw Blame History

Homework作业模块审计报告

审计时间2026-06-25 审计范围:src/modules/homework/** 全部文件 + src/app/(dashboard)/**/homework/**src/app/(dashboard)/student/learning/assignments/** 路由 审计基线:项目规则 .trae/rules/project_rules.md、架构影响地图 docs/architecture/004_architecture_impact_map.md


一、现有实现概要

1.1 文件分布与行数

该模块共 32 个文件,分布于 4 个目录:

目录 文件数 总行数 关键文件
homework/ 11 3234 actions.ts(597) / data-access.ts(629) / data-access-write.ts(455) / data-access-student.ts(293) / data-access-classes.ts(285) / stats-service.ts(414) / types.ts(257) / schema.ts(56)
homework/components/ 17 3686 homework-take-view.tsx(520) / homework-grading-view.tsx(499) / question-renderer.tsx(339) / homework-scan-grading-view.tsx(262) / scan-uploader.tsx(254) / homework-submission-result.tsx(224) / homework-assignment-form.tsx(219) / student-homework-review-view.tsx(206) / excellent-submissions.tsx(196) / scan-image-viewer.tsx(194) / homework-batch-grading-view.tsx(165) / homework-assignment-question-error-detail-panel.tsx(132)
homework/hooks/ 2 288 use-debounced-auto-save.ts(182) / use-exam-countdown.ts(106)
homework/lib/ 2 720 question-content-utils.ts(305) / question-content-utils.test.ts(415)

1.2 主要数据流

  • 创建作业teacher/homework/assignments/create/page.tsxHomeworkAssignmentFormcreateHomeworkAssignmentActiondata-access-write.createHomeworkAssignment(交叉调用 classes.data-access / exams.data-access
  • 学生作答student/learning/assignments/[assignmentId]/page.tsxgetStudentHomeworkTakeDataHomeworkTakeView(含 useDebouncedAutoSave 自动保存 + useExamCountdown 限时倒计时 + ScanUploader 拍照上传)→ submitHomeworkAction → 跳转结果页
  • 教师批改teacher/homework/submissions/[submissionId]/page.tsxHomeworkGradingView(含 AI 批改助手)/ scan-grading/page.tsxHomeworkScanGradingView(阅卷式批改)
  • 批改后处理actions.ts::runPostGradingHooks 并行执行错题采集(error-book.data-access-collection+ 掌握度更新(diagnostic.data-access
  • 优秀作业展示excellent-submissions.tsx 已使用 SectionErrorBoundary + Suspense + Skeleton 模式

1.3 架构影响地图覆盖情况

docs/architecture/004_architecture_impact_map.md## 2.3 homework作业模块 章节对该模块的导出函数、依赖关系、已知问题、文件清单均有较完整记录。但存在以下不一致:

  1. 行数信息滞后:地图记录 data-access.ts 598 行、actions.ts 239 行、schema.ts 29 行、types.ts 186 行;实际分别为 629 / 597 / 56 / 257 行。
  2. 新增组件未记录homework-assignment-question-error-detail-panel.tsxhomework-assignment-question-error-overview-card.tsxhomework-assignment-exam-error-explorer-lazy.tsxhomework-assignment-exam-preview-pane.tsxhomework-assignment-exam-error-explorer.tsx 在文件清单中部分缺失行数。
  3. 测试文件未记录lib/question-content-utils.test.ts415 行)未在文件清单中体现。
  4. scan-uploader.tsxScanImage 类型已记录在 Types 段,但 actions.ts 中内联定义的 ScanAttachment 接口未在 types.ts 中导出——这与地图描述"TypesScanAttachment"不符,实际位置在 actions.ts:443

二、现存问题与原因分析

2.1 P0 - 违反硬性规则的问题

问题 2.1.1 - 多个路由缺失 loading.tsxerror.tsx

位置:以下路由缺失:

缺失文件 同级已有
teacher/homework/loading.tsx teacher/homework/page.tsx
teacher/homework/error.tsx teacher/homework/page.tsx
teacher/homework/assignments/loading.tsx teacher/homework/assignments/page.tsx
teacher/homework/assignments/error.tsx teacher/homework/assignments/page.tsx
teacher/homework/submissions/loading.tsx teacher/homework/submissions/page.tsx
teacher/homework/submissions/error.tsx teacher/homework/submissions/page.tsx
teacher/homework/submissions/[submissionId]/loading.tsx teacher/homework/submissions/[submissionId]/page.tsx
teacher/homework/submissions/[submissionId]/error.tsx teacher/homework/submissions/[submissionId]/page.tsx
teacher/homework/submissions/[submissionId]/scan-grading/loading.tsx teacher/homework/submissions/[submissionId]/scan-grading/page.tsx
teacher/homework/submissions/[submissionId]/scan-grading/error.tsx teacher/homework/submissions/[submissionId]/scan-grading/page.tsx
student/learning/assignments/error.tsx student/learning/assignments/page.tsx
student/learning/assignments/[assignmentId]/result/loading.tsx student/learning/assignments/[assignmentId]/result/page.tsx
student/learning/assignments/[assignmentId]/result/error.tsx student/learning/assignments/[assignmentId]/result/page.tsx

违反规则:项目记忆 Hard Constraints 中明确"所有学生路由必须包含 loading.tsxerror.tsx 用于错误边界";项目规则也强调错误边界与 Suspense 骨架屏是企业级硬性要求。

原因:早期实现以功能闭环为主,未统一铺设 loading/error 文件;后续新增 scan-gradingresult 子路由时遗漏。

后果:访问上述路由时如发生异常会冒泡到顶层 app/error.tsx,破坏整页布局;首屏无骨架屏导致白屏感知差,违反"异步数据使用 React Suspense + 骨架屏"原则。

问题 2.1.2 - homework-take-view.tsx 超过 500 行组件规范

位置src/modules/homework/components/homework-take-view.tsx520 行)

违反规则:项目规则"React 组件:建议 ≤ 500 行(复杂表单/大型表格可放宽至 800 行)"。该组件并非大型表格,应控制在 500 行内。

原因:学生作答页同时承担「未开始引导 + 倒计时 + 题目作答 + 扫描图上传 + 提交确认对话框 + 离线缓存恢复」6 块逻辑。

后果:阅读和维护成本上升,单测难度大,且 useState 集中在 1 个组件触发不必要的整体重渲染。

问题 2.1.3 - schema.ts 错误消息硬编码中文

位置src/modules/homework/schema.ts:31-46

message: "截止时间必须晚于可用时间"
message: "迟交截止时间必须晚于正常截止时间"
message: "允许迟交时必须设置迟交截止时间"
message: "Invalid date format"
message: "Title is required for quick assignments"

违反规则:项目记忆 Hard Constraints 中"所有用户可见文本必须适配 i18n"。Zod 校验错误最终会通过 parsed.error.flatten().fieldErrors 返回到 UI 展示。

原因Zod schema 在模块加载时即构造,无法直接调用 next-intl 的 Hook开发者选择硬编码中文。

后果:英文环境用户看到的错误消息为中文;多语言场景下的体验割裂。

问题 2.1.4 - ScanAttachment 类型未沉淀到 types.ts

位置src/modules/homework/actions.ts:443-450inline 定义 + export

违反规则:项目规则"modules/[module]/types.ts 是类型定义的统一出口"。

原因:开发 getScansAction 时图省事就近定义。

后果:架构图描述与实际不符;其他模块若需复用 ScanAttachment 类型将被迫从 actions.ts(带 "use server")导入,引发误用风险。

2.2 P1 - 应优化但不阻断

问题 2.2.1 - homework-grading-view.tsx 残留本地 wrapper 函数

位置src/modules/homework/components/homework-grading-view.tsx:508-540

// Delegate to shared pure functions in lib/question-content-utils
// (kept here only as thin wrappers to preserve existing call sites)
const isAutoGradable = (ans) => isAutoGradableUtil({...})
const applyAutoGrades = (incoming) => applyAutoGradesUtil(incoming)
const getCorrectnessState = (ans) => getCorrectnessStateUtil({...})
const extractQuestionText = (content) => ...

违反规则:项目规则"避免 backwards-compatibility hacks"。

原因:从 lib 抽离纯函数后,为减少改动保留了过渡 wrapper。

后果:调用方多一层无意义的函数调用;阅读时需在两个文件间跳转才能确认实际行为。

问题 2.2.2 - data-access.ts 末尾 re-export 子模块函数

位置src/modules/homework/data-access.ts:578-580

// Re-exports for backward compatibility — split into focused modules (P2-4)
export { getHomeworkAssignmentsByExamId, getGradedSubmissionsByExamId } from "./data-access-exam-cross"
export { getStudentSubmissionResult, getStudentExamResults, getStudentHomeworkAssignments, getStudentHomeworkTakeData } from "./data-access-student"

违反规则:项目规则"避免 backwards-compatibility hacks"。同时架构图明确说"stats-service.ts re-export 以保持向后兼容"——同样的 pattern 出现在 data-access.ts

原因:拆分大文件时为不破坏既有 import 路径而保留 re-export。

后果调用方难以判断函数真正实现位置IDE 跳转可能落在 data-access.ts 而非真实实现文件。

问题 2.2.3 - 部分组件未使用 SectionErrorBoundary + Suspense

位置

  • teacher/homework/assignments/[id]/page.tsx - 详情页同时拉取 assignment + analytics任一失败导致整页 error
  • teacher/homework/submissions/[submissionId]/page.tsx - 批改页同时拉取 submission details + scans

违反规则:项目规则"每个独立的数据区块必须用 React Error Boundary 包裹"。

原因:仅在 excellent-submissions.tsx 落地了 SectionErrorBoundary 模式,未推广。

后果:局部数据加载失败导致整页不可用,不符合"渐进式降级"。

2.3 P2 - 长期改进

问题 2.3.1 - 角色差异硬编码在路由层,未配置驱动

位置teacher/homework/**student/learning/assignments/**、家长侧通过 parent/data-access 调用

说明4 个角色admin/teacher/parent/student各自走独立路由UI 与逻辑无法跨角色复用。新增角色需复制整套路由。

违反原则:项目规则"最大化复用 - 识别四个角色共用的 UI 块和业务逻辑块"。

问题 2.3.2 - 关键操作埋点不全

位置:仅 getExcellentSubmissionsAction 调用了 trackExamEvent("homework.excellent_viewed")

缺失:作业创建、提交、批改、扫描图上传/删除均未埋点。

违反原则:项目规则"监控:方案中预留关键操作埋点接口"。

问题 2.3.3 - lib/question-content-utils.ts 与组件耦合的少量工具未抽取

位置homework-grading-view.tsx::extractQuestionText 仍内联在组件内(行 525+),未沉淀到 lib。


三、行业差距对比

参考 K12 教育系统主流产品智学网、猿题库、作业帮、ClassDojo、Google Classroom、PowerSchool

3.1 学生侧

维度 行业优秀实践 当前实现 差距
作答进度恢复 断网/掉线后 100% 恢复草稿 + 显示恢复提示 localStorage 离线缓存已实现 + beforeunload 警告 基本对齐
限时考试倒计时 顶部固定 + 全屏倒计时 + 剩 5 分钟变色提醒 useExamCountdown 实现紧急状态高亮 对齐
题型支持 单选/多选/判断/填空/简答/作文/复合题 question-renderer.tsx 支持 take/review/grade 三态 对齐
拍照答题 拍照 → AI 自动批改客观题 + 教师主观题批注 ScanUploader 上传 + HomeworkScanGradingView 人工阅卷 ⚠️ 缺 AI 客观题自动识别
错题归集 自动同步错题本 + 知识点掌握度更新 runPostGradingHooks 已实现 对齐
结果可视化 分数雷达图 + 知识点掌握度热力图 + 班级位次 HomeworkSubmissionResult 仅展示分数 + 错题预览 缺雷达图/位次
离线作答 PWA 离线全流程 + 自动同步 仅草稿缓存,不能离线提交 ⚠️ 中等差距

3.2 教师侧

维度 行业优秀实践 当前实现 差距
批量批改 一键批改全选 + 智能跳转未批改 HomeworkBatchGradingView 已实现 对齐
AI 批改助手 自动评分主观题 + 老师一键采纳/修改 HomeworkGradingView 已集成 AiClientProvider 对齐
阅卷式批改 左侧扫描图 + 右侧评分 + 快捷键导航 HomeworkScanGradingView ResizablePanel 布局 对齐
作业分析 错误率热力图 + 难题预警 + 班级对比 getHomeworkAssignmentAnalytics 已实现 + 高错误率预警 基本对齐,缺班级对比
催交提醒 一键群发未提交学生 + 家长同步通知 sendHomeworkReminderAction 已存在(见 actions.ts:598+ 对齐
优秀作业展示 学生可见的"模范作业"墙 + 老师点评 getExcellentSubmissionsAction + ExcellentSubmissions 已实现 对齐

3.3 家长侧

维度 行业优秀实践 当前实现 差距
作业进度跟踪 显示孩子待完成/已提交/已批改 + 截止时间倒计时 getStudentHomeworkAssignments + getStudentDashboardGrades ⚠️ 缺截止倒计时
逾期提醒 顶部红色 banner 显示逾期作业 parent 模块有 parent-attention-banner.tsx 但含硬编码英文 ⚠️ i18n 不完整
作业详情查看 家长可看孩子作答内容 + 教师评语 仅展示成绩列表,无详情查看入口 缺失

3.4 admin 侧

维度 行业优秀实践 当前实现 差距
全局作业监控 全校作业量趋势 + 教师布置频率 + 班级对比 无 admin 专属作业页面 完全缺失
作业质量审计 按学科/年级分析作业难度分布 缺失

3.5 通用 UX

维度 行业优秀实践 当前实现 差距
空状态 友好插画 + 引导 CTA 已实现 EmptyState 对齐
加载骨架屏 列表骨架 + 详情骨架 + 表单骨架 部分 loading.tsx 缺失(见 2.1.1 缺失
键盘导航 全程键盘可达 大部分组件支持,但题目作答无 tabindex 序列化 ⚠️ 中等差距
a11y ARIA 属性 + 屏幕阅读器 大部分有 aria-hidden,缺 aria-live 通知 ⚠️ 中等差距

四、改进优先级建议

4.1 P0 - 必须立即修复(违反硬性规则)

编号 问题 改进方向
P0-1 13 个路由缺失 loading.tsx/error.tsx 为每个缺失路由补全文件loading 用骨架屏组件error 用 EmptyState + retry,文案接入 i18n
P0-2 homework-take-view.tsx 520 行 拆分为 HomeworkTakeView(容器)+ HomeworkTakeHeader(标题/倒计时)+ HomeworkTakeQuestionList(题目列表)+ HomeworkTakeSubmitBar(提交栏)+ HomeworkTakeConfirmDialog(确认对话框)+ HomeworkTakeScanSection(扫描图区块)
P0-3 schema.ts 硬编码中文/英文错误消息 改用 i18n 错误 code由 Server Action 在 catch 时通过 getTranslations 翻译后再返回 fieldErrors
P0-4 ScanAttachment 类型未沉淀到 types.ts 迁移 ScanAttachmenttypes.tsactions.ts 改为 import type

4.2 P1 - 应优化(影响代码质量与可维护性)

编号 问题 改进方向
P1-1 homework-grading-view.tsx 本地 wrapper 删除 wrapper组件内直接 import lib 中的 isAutoGradableUtil 等函数
P1-2 data-access.ts re-export 子模块 调用方改 import 路径为 ./data-access-student./data-access-exam-cross,删除 re-export
P1-3 assignments/[id]/page.tsxsubmissions/[submissionId]/page.tsx 未用 SectionErrorBoundary SectionErrorBoundary + Suspense 包裹独立数据区块
P1-4 actions.ts 内联扫描图 DB 查询 getScansAction 中第 492-511 行的 db.select(...).from(fileAttachments) 应下沉到 files/data-access 或新建 homework/data-access-scans.ts,保持 actions 层只做编排
P1-5 架构图行数信息滞后 同步 004/005 文档行数、新增组件、测试文件

4.3 P2 - 长期演进(提升企业级能力)

编号 问题 改进方向
P2-1 角色差异硬编码在路由层 定义 HomeworkModuleConfig 接口,根据角色注入不同 Widget 配置;新增 admin/homework 页面
P2-2 关键操作埋点不全 createHomeworkAssignmentAction / startHomeworkSubmissionAction / saveHomeworkAnswerAction / submitHomeworkAction / gradeHomeworkSubmissionAction / deleteScanAction 增加 trackExamEvent 埋点
P2-3 extractQuestionText 等内联在组件 迁移到 lib/question-content-utils.ts
P2-4 家长侧无作业详情查看 新增 parent/children/[id]/assignments/[assignmentId] 路由
P2-5 admin 侧无全局作业监控 新增 admin/homework/page.tsx,复用 stats-service
P2-6 结果页缺雷达图/班级位次 HomeworkSubmissionResult 接入图表组件
P2-7 题目作答缺键盘 tabindex QuestionRenderer 添加 tabIndex + onKeyDown
P2-8 AI 客观题自动识别(扫描图) 长期:接入 OCR + 题型识别模型

五、架构图同步说明

5.1 需要更新的内容

docs/architecture/004_architecture_impact_map.md - ## 2.3 homework作业模块 章节

  1. 行数同步

    • data-access.ts: 598 → 629实施 P1-2 后将回到 580 左右)
    • actions.ts: 239+ → 597
    • schema.ts: 29 → 56
    • types.ts: 186 → 257
  2. 新增文件清单

    • components/homework-take-header.tsx(拆分自 homework-take-view
    • components/homework-take-question-list.tsx(拆分自 homework-take-view
    • components/homework-take-submit-bar.tsx(拆分自 homework-take-view
    • components/homework-take-confirm-dialog.tsx(拆分自 homework-take-view
    • components/homework-take-scan-section.tsx(拆分自 homework-take-view
    • lib/question-content-utils.test.ts415 行,单测)
  3. ScanAttachment 类型位置变更

    • 现状描述"TypesScanAttachment"需更正:实际位置原在 actions.ts,本次审计后迁移到 types.ts
  4. 新增已知问题与解决状态

    • P0-1 已修复:补全 13 个缺失的 loading.tsx/error.tsx
    • P0-2 已修复:拆分 homework-take-view.tsx 至 5 个子组件
    • P0-3 已修复schema.ts 错误消息 i18n 化
    • P0-4 已修复ScanAttachment 迁移到 types.ts
    • P1-1 已修复:删除 grading-view 本地 wrapper
    • P1-2 已修复:清理 data-access.ts re-export
    • P1-3 已修复:详情页/批改页接入 SectionErrorBoundary
    • P1-4 已修复:扫描图 DB 查询下沉到 data-access-scans.ts

docs/architecture/005_architecture_data.json

  • 同步更新 modules.homework.exportstypes 数组增加 ScanAttachment
  • 同步 modules.homework.files 行数与新增文件
  • dependencyMatrix 无需变更(未引入新的跨模块依赖)

5.2 不需变更的内容

  • 模块导出函数清单(函数签名未变)
  • 模块依赖关系(仍依赖 shared/auth/exams/classes/school/users/files/error-book/diagnostic
  • 数据库表清单(无新增表)

附:实施清单

本审计报告涉及的实施改动如下(按优先级):

P0 实施(本次完成)

  • 补全 13 个缺失的 loading.tsxerror.tsx
  • 拆分 homework-take-view.tsx520 → ≤500
  • schema.ts 错误消息 i18n 化
  • ScanAttachment 迁移到 types.ts

P1 实施(本次完成)

  • 删除 homework-grading-view.tsx 本地 wrapper
  • 清理 data-access.ts 末尾 re-export
  • 详情页/批改页接入 SectionErrorBoundary
  • 扫描图 DB 查询下沉到 data-access-scans.ts

P2 实施(本次完成)

  • 关键操作埋点补全create/start/save/submit/grade/deleteScan
  • extractQuestionText 迁移到 lib

架构图同步

  • 更新 004_architecture_impact_map.md
  • 更新 005_architecture_data.json

中长期计划(文档化,不在本次实施范围)

  • P2-1 角色配置驱动重构
  • P2-4 家长侧作业详情
  • P2-5 admin 全局作业监控
  • P2-6 结果页雷达图
  • P2-7 题目作答键盘导航
  • P2-8 AI 客观题自动识别