Files
NextEdu/docs/architecture/audit/dashboard-audit-report-v2.md
SpecialX e997abaf5e refactor(dashboard): V2 审计重构 — i18n 补齐 + 共享抽象 + 单测 + a11y
V2 审计报告(docs/architecture/audit/dashboard-audit-report-v2.md)发现并修复:

- P0 i18n:10 个子组件硬编码字符串全部接入 next-intl(teacher-quick-actions /
  teacher-classes-card / teacher-homework-card / teacher-schedule /
  recent-submissions / teacher-grade-trends / student-grades-card /
  student-today-schedule-card / student-upcoming-assignments-card /
  admin-dashboard),新增 ~50 个翻译键
- P1 共享抽象:新增 DashboardGreetingHeader 组件,消除 teacher/student
  头部 90% 重复代码,两个 Header 改为薄包装
- P2 单测:为 6 个纯函数添加 31 个单元测试
  (tests/integration/dashboard/dashboard-utils.test.ts)
- P2 a11y:admin 表格 caption、teacher/student 视图语义化标签
  (header / section aria-label / aside aria-label)
- 同步架构图 004/005
2026-06-22 17:01:00 +08:00

8.6 KiB
Raw Permalink Blame History

仪表盘模块审计报告 v2

审查日期2026-06-22第二轮 审查范围:基于 v1 重构后代码commit 868ac5f + 21c1e7a)的再次分析 前置报告:docs/architecture/audit/dashboard-audit-report.mdv1 架构图参考:docs/architecture/004_architecture_impact_map.md §2.12、docs/architecture/005_architecture_data.json


一、v1 重构成果回顾

v1 报告识别的 P0/P1/P2 项目已完成的部分:

# 项目 状态 证据
P0-1 权限校验 已完成 actions.ts 4 个 Server Action 均调用 requirePermission()
P0-2 根重定向角色硬编码 已完成 dashboard/page.tsx 改用 resolvePermissions()
P0-3 i18n 零覆盖 ⚠️ 部分完成 仅容器组件接入 i18n10 个子组件仍英文硬编码
P0-4 页面层越权编排 已完成 teacher/student/parent 编排下沉至 actions.ts
P1-1 业务逻辑耦合 UI 已完成 lib/dashboard-utils.ts 抽取 6 个纯函数
P1-3 仅路由级错误边界 已完成 dashboard-section.tsx 分区 Error Boundary + Suspense
P2-2 a11y 不足 未完成 仍缺语义化标签、表格 caption

二、v2 新发现问题

2.1 i18n 覆盖严重不完整P0 — v1 遗漏)

v1 仅对容器组件(admin-dashboard.tsxteacher-dashboard-view.tsxteacher-dashboard-header.tsxteacher-stats.tsxteacher-todo-card.tsxstudent-stats-grid.tsxstudent-dashboard-header.tsxparent-dashboard.tsxuser-growth-chart.tsx)接入 i18n10 个子组件仍全英文硬编码

# 文件 硬编码示例 违反规则
1 teacher-quick-actions.tsx L12-24 "Create Assignment" / "Grade" / "My Classes" "所有用户可见文本必须适配 i18n"
2 teacher-classes-card.tsx L15-27 "My Classes" / "View all" / "No classes yet" / "Create a class to start managing students and schedules." / "Create class" / "Homeroom" / "Room" 同上
3 teacher-homework-card.tsx L17-87 "Homework" / "Create new assignment" / "No assignments" / "Create an assignment to get started." / "Create" / "No due date" / "View all assignments" 同上
4 teacher-schedule.tsx L41-141 "Today's Schedule" / "No Classes Today" / "No timetable entries." / "View schedule" / "LIVE" / "Scroll for more" / "No more classes today" 同上
5 recent-submissions.tsx L22-105 "Recent Submissions" / "No New Submissions" / "All caught up!..." / "View All" / "View submissions" / "Student" / "Assignment" / "Submitted" / "Action" / "Late" / "Grade" 同上
6 teacher-grade-trends.tsx L25-69 "Class Performance" / "Average scores for the last X assignments" / "No data available" / "Publish assignments to see class performance trends." / "Average Score (%)" / "X/Y submitted" 同上
7 student-grades-card.tsx L30-101 "Recent Grades" / "No graded work yet" / "Finish and submit assignments to see your score trend." / "View all" / "Score (%)" / "Latest:" / "Points:" / "Assignment" / "Score" / "When" 同上
8 student-today-schedule-card.tsx L52-83 "Today's Schedule" / "View all" / "No classes today" / "Your timetable is clear for today." / "In Progress" / "Up Next" 同上
9 student-upcoming-assignments-card.tsx L17-22,49-72 "Review" / "View" / "Continue" / "Start" / "Upcoming Assignments" / "View all" / "No assignments" / "You have no assigned homework right now." / "Title" / "Status" / "Due" / "Score" / "Action" / "Late" 同上
10 admin-dashboard.tsx L212 {u.role ?? "unknown"} 硬编码 "unknown" 同上

后果:中文用户看到大量英文,体验割裂;无法切换语言;维护时需逐文件改字符串。

2.2 四角色仍零共享抽象P1 — v1 未处理)

维度 现状 期望
问候语头部 TeacherDashboardHeaderStudentDashboardHeader 代码 90% 重复(仅 props 名不同) 抽象为 DashboardGreetingHeader
快捷操作 admin 的 QuickActionCard内联、parent 的 QUICK_ENTRIES内联、teacher 的 TeacherQuickActions — 三套独立实现 抽象为 DashboardQuickActions
仪表盘布局容器 admin/teacher/student 各写一套 <div className="space-y-*"> 抽象为 DashboardLayout

违反规则"最大化复用:识别四个角色共用的 UI 块和业务逻辑块,抽象为泛型组件和 hooks"。

2.3 无单测P2 — v1 未处理)

lib/dashboard-utils.ts 抽取了 6 个纯函数但无任何单测

函数 测试覆盖 风险
toWeekday 周日映射错误未被发现
countStudentAssignments 边界条件(无截止日期/已批改)未验证
sortUpcomingAssignments 排序稳定性未验证
filterTodaySchedule 空课表/排序未验证
computeTeacherMetrics 提交率分母为零等边界未验证
getGreetingKey 时段边界12:00/18:00未验证

违反规则"数据获取、计算、格式化等纯逻辑全部放入纯函数或 hooks与 UI 分离;导出清晰的接口类型以便 mock" + "可测试性"。

2.4 a11y 不足P2 — v1 未处理)

位置 问题 违反规则
admin-dashboard.tsx 表格 <caption> "语义化标签、ARIA 属性、键盘导航"
recent-submissions.tsx 表格 <caption> 同上
student-upcoming-assignments-card.tsx 表格 <caption> 同上
teacher-dashboard-view.tsx 布局 <section> / <aside> 语义化标签 同上
student-dashboard-view.tsx 布局 同上 同上
teacher-schedule.tsx 时间线 aria-label 描述当前/过去/未来状态 同上

2.5 流式渲染未实现P1 — v1 未处理)

所有 page.tsxexport const dynamic = "force-dynamic" + Promise.all 等全部数据就绪后才渲染。虽然 DashboardSection 内部有 Suspense但 page 层已无 Suspense 边界,无法流式渲染首屏。


三、改进优先级v2

P0紧急 — v1 遗漏的 i18n

# 问题 改进方向
v2-P0-1 10 个组件英文硬编码 全部接入 useTranslations / getTranslations;补充翻译键

P1较严重 — 共享抽象 + 单测)

# 问题 改进方向
v2-P1-1 问候语头部重复 抽象 DashboardGreetingHeader 组件
v2-P1-2 纯函数无单测 lib/dashboard-utils.ts 6 个函数添加单测

P2优化 — a11y + 流式)

# 问题 改进方向
v2-P2-1 表格无 caption / 布局无语义化标签 补充 <caption> / <section> / aria-label

四、架构图同步说明

v2 修改完成后需同步更新:

4.1 004_architecture_impact_map.md

  • §2.12 dashboard 章节:补充新增共享组件(DashboardGreetingHeader)、单测文件(lib/dashboard-utils.test.ts

4.2 005_architecture_data.json

  • modules.dashboard.exports.components:新增 DashboardGreetingHeader
  • modules.dashboard.exports.lib:补充单测覆盖说明