Files
NextEdu/docs/architecture/audit/archive/school-grade-class-audit-report.md

17 KiB
Raw Blame History

学校/年级/班级管理模块审计报告 v2

审查范围:school(学校/学年/部门/年级 CRUDclasses(班级管理) 审查日期2026-06-22v2 复审) 审查依据项目规则三层架构、权限校验、i18n、TypeScript 严格模式、单文件行数限制、K12 行业优秀实践 审查方式:只读源码分析 + 架构图比对 + 行业对标


一、现有实现概要

1.1 v1 审计修复回顾

v1 审计报告识别了 14 个问题5 个 P0 + 6 个 P1 + 5 个 P2截至本次复审全部 14 个问题已修复

编号 问题 状态
P0-1 grade-management 死模块 已删除
P0-2 年级 CRUD 逻辑重复 统一到 school 模块
P0-3 classes/actions.ts 974 行 拆分为 6 个文件
P0-4 teacher/classes/* 无权限校验 4 个页面已加 requirePermission
P0-5 school 模块无 i18n 4 个组件已接入 useTranslations
P1-1 角色硬编码 改为 dataScope.type 判断
P1-2 school 无 i18n 文件 school.json 已创建413 行翻译键)
P1-3 school 缺 Error Boundary/Skeleton 已补充
P1-4 classes/types.ts 跨领域类型 保留并加注释说明
P1-5 school 未用组合模式 拆分为 4 个子组件
P1-6 data-access 无权限过滤 新增 getSchoolsForUser/getGradesForUser
P2-1~P2-5 各项优化 全部修复

1.2 当前模块文件分布

模块 核心文件 行数 职责
school actions.ts 457 13 个 Server ActionpromoteGradesAction
school data-access.ts 757 只读查询 + 12 个写操作 + 组织树 + 权限感知函数
school schema.ts / types.ts 51 / 90 Zod 校验 / 类型定义
school components/ (14 文件) 60~860 学校/学年/部门/年级视图 + 仪表盘 + 组织树
school hooks/use-school-data.ts 36 学校数据管理 hook
classes actions.ts (barrel) 51 re-export 入口
classes actions-{teacher,admin,grade,invitations,schedule,shared}.ts 60~448 按职责拆分的 6 个 Action 文件
classes data-access.ts 833 核心班级 CRUD + 邀请码 + 教师班级管理
classes data-access-{admin,stats,schedule,students,invitations}.ts 93~454 按领域拆分的 5 个 data-access
classes schema.ts / types.ts 152 / 177 Zod 校验 / 类型定义
classes components/ (14 文件) 137~499 班级列表/详情/学生/课表/邀请码

1.3 页面分布(共 13 个 page.tsx

路由分组 页面 权限校验 i18n Error Boundary Loading
admin/school/schools SCHOOL_MANAGE
admin/school/grades SCHOOL_MANAGE
admin/school/grades/insights SCHOOL_MANAGE
admin/school/departments SCHOOL_MANAGE
admin/school/academic-year SCHOOL_MANAGE
admin/school/classes SCHOOL_MANAGE
management/grade/classes GRADE_MANAGE
management/grade/insights GRADE_MANAGE
management/grade/dashboard GRADE_MANAGE
teacher/classes/my CLASS_READ
teacher/classes/my/[id] CLASS_READ
teacher/classes/schedule CLASS_READ (Suspense)
teacher/classes/students CLASS_READ (Suspense)

1.4 数据流概要

admin/school/* 页面(✅ 完整 i18n + Error Boundary + Skeleton
  └─→ school/data-access.getSchools() / getGrades() / getStaffOptions() / getGradeOverviewStats()
  └─→ school/components/*(✅ 全部使用 useTranslations
  └─→ school/actions.ts → createXxxAction / updateXxxAction / deleteXxxAction

management/grade/* 页面(✅ 完整 i18n + Error Boundary
  └─→ classes/data-access.getGradeManagedClasses() / getTeacherOptions()
  └─→ school/data-access.getGradesForStaff()
  └─→ classes/components/grade-classes-view.tsx❌ 无 i18n
  └─→ classes/actions.ts → createGradeClassAction / ...

teacher/classes/* 页面(❌ 组件无 i18n❌ 无 Error Boundary
  └─→ classes/data-access.getTeacherClasses() / getClassStudents() / getClassSchedule()
  └─→ classes/components/*(❌ 14 个组件中仅 1 个使用 useTranslations
  └─→ classes/actions.ts → createTeacherClassAction / ...

二、现存问题与原因分析v2 新发现)

2.1 国际化层面

P0-Aclasses 模块 13/14 个组件未接入 i18n

  • 位置
    • src/modules/classes/components/admin-classes-view.tsx — 16 处英文硬编码("Failed to create class"、"No classes"、"Select a school" 等)
    • src/modules/classes/components/grade-classes-view.tsx — 20+ 处英文硬编码("Homeroom Teacher"、"Subject Teachers"、"Select a grade" 等)
    • src/modules/classes/components/my-classes-grid.tsx — 15+ 处英文硬编码("Join New Class"、"Invitation Code"、"Cancel" 等)+ 1 处中文硬编码("教学科目"、"暂无可选科目"
    • src/modules/classes/components/schedule-view.tsx — 10+ 处英文硬编码
    • src/modules/classes/components/schedule-filters.tsx — 8 处英文硬编码
    • src/modules/classes/components/students-filters.tsx — 5 处英文硬编码
    • src/modules/classes/components/students-table.tsx — 英文硬编码
    • src/modules/classes/components/class-detail/*.tsx7 个文件)— 全部英文硬编码("Recent Homework"、"Weekly Schedule"、"Quick Actions" 等)
  • 问题14 个组件中仅 class-invitation-manager.tsx 使用 useTranslations,其余 13 个组件全部硬编码文本,且 my-classes-grid.tsx 中存在中英文混用
  • 违反规则:所有用户可见文本必须适配 i18n使用 next-intl提取翻译键
  • 原因v1 审计仅修复了 school 模块的 i18nclasses 模块的 i18n 遗留未处理
  • 后果teacher/management 视角下的班级管理页面无法支持多语言;中英文混用严重影响专业度

P0-Bclasses.json i18n 文件内容严重不足

  • 位置src/shared/i18n/messages/{zh-CN,en}/classes.json
  • 问题:当前仅 55 行,只覆盖 invitation.*class.*5 个基础字段)。缺少班级 CRUD 表单、列表、筛选器、详情页、学生管理、课表等全部场景的翻译键
  • 违反规则i18n 就绪规范
  • 后果:即使组件想接入 i18n也缺少翻译键可用

2.2 文件大小层面

P1-Agrades-view.tsx 860 行超出组件行数限制

  • 位置src/modules/school/components/grades-view.tsx860 行)
  • 问题:单个客户端组件文件 860 行,超过 React 组件建议上限 500 行(复杂表单可放宽至 800 行,但仍超)。包含年级列表 + 概览卡片 + 筛选器 + 创建/编辑表单 + 删除对话框 + 年级升级对话框全部逻辑
  • 违反规则单文件行数限制React 组件建议 ≤ 500 行,复杂表单/大型表格可放宽至 800 行)
  • 后果:可读性差,难以维护;筛选逻辑、表单校验逻辑、对话框状态管理全部耦合

P1-Bclasses/data-access.ts 833 行超出 data-access 限制

  • 位置src/modules/classes/data-access.ts833 行)
  • 问题:虽然已拆分为 5 个 data-access 子文件,但主 data-access.ts 仍达 833 行,超过 data-access 建议 800 行上限。包含核心班级 CRUD + 邀请码 + 教师班级管理 + 跨模块接口
  • 违反规则单文件行数限制Server Actions / Data Access 模块建议 ≤ 800 行)
  • 后果:接近硬上限,后续增加功能即超限

2.3 错误处理层面

P1-Cclasses 模块组件缺少 Error Boundary 和 Skeleton

  • 位置
    • src/app/(dashboard)/teacher/classes/my/[id]/page.tsx — 无 Error Boundary
    • src/app/(dashboard)/admin/school/classes/page.tsx — 无 Error Boundary
    • src/app/(dashboard)/management/grade/dashboard/page.tsx — 无 Error Boundary
    • src/modules/classes/components/* — 无骨架屏组件
  • 问题:对比 school 模块已有 school-error-boundary.tsx + school-skeleton.tsxclasses 模块完全没有错误边界和骨架屏组件
  • 违反规则:错误与边界处理(每个独立数据区块必须用 React Error Boundary 包裹;异步数据使用 React Suspense + 骨架屏)
  • 后果:数据加载失败时整页崩溃无降级;加载过程无反馈

2.4 组件质量层面

P1-Dclasses 组件未使用组合模式

  • 位置
    • src/modules/classes/components/admin-classes-view.tsx499 行)— 单体组件包含 Table + Dialog + AlertDialog + Select 全部逻辑
    • src/modules/classes/components/grade-classes-view.tsx408 行)— 同上
    • src/modules/classes/components/my-classes-grid.tsx390 行)— 单体组件包含卡片网格 + 加入班级对话框 + 邀请码管理
  • 问题:对比 school 模块已拆分为 SchoolListToolbar + SchoolFormDialog + SchoolDeleteDialog + useSchoolData hookclasses 模块仍是单体组件,无法复用子部件
  • 违反规则:组合优先(所有 UI 通过组件组合实现灵活性)
  • 后果admin/grade/teacher 三个视角的班级管理存在大量重复代码(表单、对话框、筛选器),无法复用

P1-Eclasses 模块缺少 hooks 抽取

  • 位置src/modules/classes/ — 无 hooks/ 目录
  • 问题:对比 school 模块已抽取 use-school-data hookclasses 模块的对话框状态管理、表单校验、筛选逻辑全部耦合在组件内部
  • 违反规则:可测试性(数据获取、计算、格式化等纯逻辑全部放入纯函数或 hooks与 UI 分离)
  • 后果:无法对筛选逻辑、表单校验逻辑进行独立单测

2.5 架构模式层面

P2-A缺少 Service 接口抽象和依赖注入

  • 位置:整个 school + classes 模块
  • 问题:组件直接 import data-access 函数,未通过 Service 接口抽象数据依赖。对比已删除的 grade-management 模块曾有完整的 GradeService 接口 + Context DI 模式
  • 违反规则:完全解耦(通过定义 TypeScript 接口抽象数据依赖,使用 React Context 注入数据服务)
  • 后果:组件与 data-access 直接耦合,难以 mock 测试;不同角色的差异通过 if/else 硬编码而非接口实现隔离

P2-B缺少角色配置驱动设计

  • 位置:整个 school + classes 模块
  • 问题admin/teacher/grade 三个视角的班级管理通过 3 套独立的组件实现(admin-classes-view / grade-classes-view / my-classes-grid),而非通过配置驱动同一套组件
  • 违反规则:可扩展性(采用配置驱动设计,通过角色配置决定渲染哪些 Widget
  • 后果:新增角色需复制整套组件;三套组件存在大量重复代码

三、行业差距对比

3.1 与优秀 K12 产品的差距v2 更新)

功能/交互 行业优秀实践 当前状态 影响
i18n 完整覆盖 所有角色所有页面支持多语言 school 模块 classes 模块 13/14 组件硬编码) classes 模块无法支持多语言
错误边界 每个数据区块独立 Error Boundary school 模块 classes 模块 classes 数据加载失败整页崩溃
骨架屏 加载时保持布局稳定 school 模块 classes 模块 classes 加载过程布局跳动
组件复用 三个角色共用一套可配置组件 三套独立组件admin/grade/teacher 代码重复,维护成本高
班级详情仪表盘 一页聚合基本信息 + 学生 + 课表 + 作业 + 成绩 teacher/classes/my/[id] 已有,但 admin/grade 视角无 admin/年级组长无法下钻
批量操作 批量导入学生、批量分配教师 已实现v1 P2-4 修复) 已达标
年级升级 学年末一键升级 已实现v1 P2-3 修复) 已达标
组织树导航 学校→年级→班级三级树 已实现v1 P2-2 修复) 已达标
邀请码加入 6 位码 + 有效期 + 次数 已实现 已达标
数据权限隔离 data-access 层结合用户权限过滤 已实现v1 P1-6 修复) 已达标

3.2 多角色体验差距

角色 优秀实践 当前状态
admin 统一管理面板i18n 完整,错误边界完整 school 模块 classes 模块 (无 i18n、无 Error Boundary
teacher 我的班级 + 邀请码 + 课表 + 学生i18n 完整 有基本功能,但 无 i18n、 无 Error Boundary
grade_head 年级班级管理 + 学情洞察i18n 完整 有基本功能,但 组件无 i18n
parent 查看孩子所在班级信息 无专属页面(依赖 dashboard 间接展示)
student 查看我的班级、同学名单、课表 有基本功能,但 无 i18n

四、改进优先级建议

P0紧急 — i18n 与错误处理)

编号 问题 改进方向
P0-A classes 模块 13/14 个组件未接入 i18n 为所有 classes 组件接入 useTranslations("classes"),提取全部硬编码文本到翻译键
P0-B classes.json i18n 文件内容不足 扩充 classes.json,覆盖班级 CRUD、列表、筛选器、详情页、学生管理、课表、详情子组件等全部场景

P1重要 — 代码质量与可维护性)

编号 问题 改进方向
P1-A grades-view.tsx 860 行 拆分为 GradeListSection + GradeOverviewSection + GradeFormDialog + GradeDeleteDialog + GradePromoteDialog + use-grade-data hook
P1-B classes/data-access.ts 833 行 将邀请码相关函数迁移至 data-access-invitations.ts,将教师班级管理迁移至 data-access-teacher.ts
P1-C classes 模块缺少 Error Boundary/Skeleton 新增 class-error-boundary.tsx + class-skeleton.tsx,为所有 classes 页面包裹
P1-D classes 组件未使用组合模式 admin-classes-view / grade-classes-view / my-classes-grid 拆分为可复用的 ClassListTable + ClassFormDialog + ClassDeleteDialog + ClassListToolbar
P1-E classes 模块缺少 hooks 抽取 use-class-data hook对话框状态管理+ use-class-filters hook筛选逻辑

P2优化 — 架构模式)

编号 问题 改进方向
P2-A 缺少 Service 接口抽象 定义 SchoolService / ClassService 接口,通过 Context DI 注入(中长期)
P2-B 缺少角色配置驱动 建立 CLASS_ROLE_CONFIG,通过配置决定不同角色渲染哪些 Widget中长期

五、架构图同步说明

5.1 需更新的节点

文档 需更新内容
004_architecture_impact_map.md §2.7 classes 更新组件 i18n 状态()、更新 Error Boundary 状态()、更新组合模式状态、更新文件行数
004_architecture_impact_map.md §2.8 school 更新 grades-view.tsx 行数860 → 拆分后)、更新组件拆分情况
005_architecture_data.json 更新 classes 模块的 i18n/errorBoundary/composition 状态标记

5.2 实施后同步

本次审计实施后,需同步更新:

  • classes 模块的 i18n 接入状态
  • classes 模块的 Error Boundary/Skeleton 新增
  • grades-view.tsx 拆分后的文件清单
  • classes/data-access.ts 拆分后的文件清单
  • classes 组件拆分后的文件清单

附录审计检查清单v2

检查项 school classes 状态
三层架构划分合理 v1 已修复
文件大小符合规范 ⚠️ grades-view 860 行 ⚠️ data-access 833 行 P1-A/P1-B
无跨模块直接依赖 v1 已修复
Server Action 权限校验 v1 已修复
前端无 role 硬编码 v1 已修复
i18n 适配 13/14 组件未接入 P0-A/P0-B
错误处理/边界 无 Error Boundary P1-C
骨架屏/空状态 ⚠️ 有空状态无骨架屏 P1-C
逻辑与 UI 分离 use-school-data 无 hooks P1-E
组合模式 三套单体组件 P1-D
配置驱动 P2-B中长期
审计日志完整 v1 已修复
监控埋点接口 P2中长期