Files
NextEdu/docs/architecture/004_architecture_impact_map.md
SpecialX 49291fcc31 refactor: fix all P0/P1/P2 bugs and architecture issues
Bug fixes (from bugs/ directory):

- Fix cross-module DB queries in 9 modules (homework, grades, parent, diagnostic, elective, proctoring, notifications, scheduling, classes) by routing through data-access functions

- Fix shared/lib <-> auth circular dependency via new session.ts module

- Fix divide-by-zero guard in grades data-access

- Fix audit export data truncation (paginated fetch for full datasets)

- Fix missing transactions in homework grading and elective lottery

- Fix missing revalidatePath in course-plans actions

- Fix frontend permission checks using requirePermission instead of requireAuth

- Fix dashboard role routing using session.user.roles

- Fix student auth pattern (migrate getDemoStudentUser to users module)

- Fix ActionState return type handling in components

Code quality fixes:

- Remove 60+ as type assertions (replace with type guards)

- Remove non-null assertions (use optional chaining or explicit checks)

- Convert dynamic imports to static imports (grades, diagnostic)

- Add React.cache() wrapping for read functions

- Parallelize independent queries with Promise.all

- Add explicit return types to 30+ arrow functions

- Replace any with unknown + type guards

- Fix import type for type-only imports

- Add Zod validation schemas for classes and diagnostic modules

- Extract duplicate code (normalizeRoleName, normalizeBcryptHash, logger IP extraction)

- Add console.error to silent catch blocks

- Fix permission naming consistency (exam:proctor_read -> exam:proctor:read)

Architecture doc sync:

- Update 004_architecture_impact_map.md and 005_architecture_data.json

- Update management-modules-audit.md for P0-7 cross-module fix

Moved deleted proctoring event route to deletes/ folder.
2026-06-19 05:13:34 +08:00

114 KiB
Raw Blame History

Next_Edu 架构影响地图

重写日期2026-06-17 目标:一次阅读即可直观理解整个项目架构 规则:源码修改后须同步更新本文档与 005_architecture_data.json 审查依据:docs/architecture/audit/ 下 4 份审查报告


目录


第一部分:全局架构概览

1.1 分层架构图

项目采用严格三层架构,依赖方向必须单向:app → modules → shared

┌─────────────────────────────────────────────────────────────────────┐
│  app/ (路由层)                                                       │
│  ─────────────────────────────────────────────────────────────────  │
│  (auth)/          login / register / privacy / terms                │
│  (dashboard)/     admin / teacher / student / parent / management   │
│  api/             REST API (auth, ai, upload, files, search, ...)   │
└──────────────────────────────┬──────────────────────────────────────┘
                               │ 调用 Server Actions / data-access
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│  modules/ (业务模块层)                                               │
│  ─────────────────────────────────────────────────────────────────  │
│  核心教学:  exams · homework · questions · textbooks · grades       │
│              · lesson-preparation                                     │
│  教学管理:  classes · school · scheduling · attendance · course-plans│
│  用户与沟通users · messaging · notifications · parent · audit      │
│  扩展功能:  elective · proctoring · diagnostic · dashboard          │
│  其他:      announcements · files · settings · auth · layout · student│
│                                                                     │
│  每个模块标准结构actions.ts (编排) → data-access.ts (DB) → schema.ts│
└──────────────────────────────┬──────────────────────────────────────┘
                               │ 依赖
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│  shared/ (基础设施层)                                                │
│  ─────────────────────────────────────────────────────────────────  │
│  db/              schema.ts (54 张表) + relations.ts + index.ts     │
│  lib/             auth-guard · permissions · ai · audit-logger ·    │
│                   change-logger · login-logger · password-policy ·  │
│                   rate-limit · excel · file-storage · ...           │
│  hooks/           use-permission · use-aria-live · ...              │
│  components/      ui/ (shadcn) · a11y/ · onboarding-gate · ...      │
│  types/           permissions · action-state                        │
└─────────────────────────────────────────────────────────────────────┘
                               ▲
                               │ 反向依赖(违规,见 1.2
┌──────────────────────────────┴──────────────────────────────────────┐
│  根模块src/auth.ts (NextAuth 配置) · src/proxy.ts (中间件)         │
│  ✅ shared/lib/{audit-logger, change-logger, auth-guard} 已通过       │
│     shared/lib/session.ts 单一入口获取 session不再直依赖 @/auth     │
│     (详见第三部分 P0-2                                              │
└─────────────────────────────────────────────────────────────────────┘

分层规则

  • app/ 只能调用 modules/ 的 Server Actions 和 data-access不直接访问 DB
  • modules/ 之间通过对方 data-access 通信,不直接查询对方表
  • shared/ 是被依赖方,不应反向依赖 app/modules/
  • src/auth.tssrc/proxy.ts 位于根目录,属于应用层

1.2 模块依赖关系图

下图展示模块间的实际依赖关系,标注依赖类型与合规性

图例

  • ───▶ 合理依赖(通过 data-access 或类型导入)
  • ═══▶ 违规依赖(直接查询对方 DB 表)
  • 循环依赖
  • ──▷ UI 组件组合(合理)

1.2.1 核心业务模块依赖

                    ┌──────────────┐
                    │  textbooks   │ ◀── 标杆模块(无跨模块 DB 访问)
                    └──────┬───────┘
                           │ ──▷ UI 组合knowledge-point-dialogs
                           │
            ┌──────────────┼──────────────┐
            │              │              │
            ▼              ▼              ▼
     ┌────────────┐  ┌──────────┐  ┌────────────┐
     │ questions  │  │  exams   │  │  homework  │
     └─────┬──────┘  └────┬─────┘  └─────┬──────┘
           │ ✅ P1-1      │ ✅ P1-1      │ ✅ P1-1 已修复
           │ 通过 textbooks│ 通过 questions│ 通过 exams/classes/
           │ data-access  │ data-access  │   school/users data-access
           │              │ 通过 classes  │
           │              │ data-access   │
           ┌─┴────────┐     │              │
           │ grades   │◀────┘ 仅外键引用(合理)
           │ (成绩)   │
           └────┬─────┘
                │ ✅ P1-1 已修复
                │ 通过 classes/school/users data-access
                ▼
           ┌──────────┐
           │ classes  │ ✅ P1-1 已修复:通过 homework/data-access-classes
           └────┬─────┘   获取作业数据,不再直查 homework/exams 表
                │ ✅ P0-1 已修复data-access.ts 已拆分为 5 文件
                │ ✅ P0-5 已修复classSchedule 写入口统一到 scheduling
                │
                    ┌─────────┼─────────┐
                    │         │         │
                    ▼         ▼         ▼
              ┌──────────┐ ┌──────┐ ┌──────────┐
              │scheduling│ │school│ │ attendance│
              └────┬─────┘ └──────┘ └──────────┘
                   │ ✅ P0-5 已修复
                   │ classSchedule 写入口统一到 scheduling
                   │ 通过 classes/data-access 校验归属
                   │ ✅ P1-1 已修复:通过 users data-access

1.2.2 扩展模块依赖

┌─────────────┐  ✅ P0-3 已修复:通过各模块 data-access    ┌──────────────┐
│ dashboard   │  获取数据getUsersDashboardStats 等)       │ users/classes│
│ (聚合层)    │──────────────────────────────────────▶│ /exams/...   │
└─────────────┘  ✅ P0-4 已修复Promise.all 并行调用     └──────────────┘

┌─────────────┐  ─── 调用 data-access合理   ┌──────────────┐
│ parent      │──────────────────────────────▶│ classes/      │
│ (聚合层)    │  ✅ P1-1 已修复:通过各模块     │ homework/grades│
└─────────────┘   data-access 获取数据          └──────────────┘

┌─────────────┐  ✅ P1-1 已修复:通过 exams/questions/      ┌──────────────┐
│ diagnostic  │  classes/users data-access 获取数据          │ exams/questions│
│             │──────────────────────────────────────▶│ /classes/users│
└─────────────┘                                       └──────────────┘

┌─────────────┐  ✅ P1-1 已修复:通过 exams/users           ┌──────────────┐
│ proctoring  │  data-access 获取数据                       │ exams/users   │
└─────────────┘──────────────────────────────────────▶└──────────────┘

┌─────────────┐  ─── 调用 notifications dispatcher     ┌──────────────┐
│ messaging   │  (通知偏好/CRUD 已迁移至 notifications│ notifications │
│             │──────────────────────────────────────▶│ (拥有         │
│             │  ✅ P0-4 / P1-5 已修复:单向依赖       │  messageNotif│
└─────────────┘                                       │  ications +  │
                                                      │  preferences)│
                                                      └──────────────┘

┌─────────────┐  ─── 调用 messaging Action       ┌──────────────┐
│ settings    │  (通知偏好表单)                 │ messaging     │
└─────────────┘──────────────────────────────▶└──────────────┘

┌─────────────────┐  ───▶ data-access合理       ┌──────────────┐
│ lesson-prep     │──────────────────────────────▶│ textbooks    │
│ (备课聚合层)    │  只读章节/知识点树              │ (章节/KP 树) │
│                 │──────────────────────────────▶└──────────────┘
│                 │──────────────────────────────▶┌──────────────┐
│                 │  创建/查询题目                  │ questions    │
│                 │──────────────────────────────▶└──────────────┘
│                 │──────────────────────────────▶┌──────────────┐
│                 │  创建 exam 草稿                │ exams        │
│                 │──────────────────────────────▶└──────────────┘
│                 │──────────────────────────────▶┌──────────────┐
│                 │  创建作业下发                  │ homework     │
│                 │──────────────────────────────▶└──────────────┘
│                 │──────────────────────────────▶┌──────────────┐
│                 │  查询教师班级                  │ classes      │
│                 │──────────────────────────────▶└──────────────┘
│                 │──────────────────────────────▶┌──────────────┐
│                 │  附件                          │ files        │
└─────────────────┘──────────────────────────────▶└──────────────┘

1.2.3 循环依赖详情 已修复

shared/lib/audit-logger.ts   ──┐
shared/lib/change-logger.ts  ──┼──▶ shared/lib/session.ts ──▶ (dynamic import) @/auth
shared/lib/auth-guard.ts     ──┘

src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
              ──▶ import { ... } from "@/shared/lib/login-logger"
              ──▶ import { ... } from "@/shared/lib/password-policy"
              ──▶ import { ... } from "@/shared/lib/rate-limit"
              ──▶ import { ... } from "@/shared/lib/role-utils"        # P1-3 拆出
              ──▶ import { ... } from "@/shared/lib/bcrypt-utils"      # P1-3 拆出
              ──▶ import { ... } from "@/shared/lib/http-utils"        # P1-3 拆出
              ──▶ import { ... } from "@/shared/lib/password-security-service"  # P1-3 拆出
              ──▶ import { db, schema } from "@/shared/db"

  ✅ 修复shared/lib/* 不再静态 import @/auth统一通过 session.ts 单一入口
     session.ts 内部使用 dynamic import("@/auth") 打破模块级静态循环
     运行时调用链保持不变,模块加载图无环

1.3 数据流向图(考试流程)

以"考试流程"为例,展示数据从创建到成绩统计的完整流向。

┌─────────────────────────────────────────────────────────────────────┐
│ 阶段 1教师创建考试                                                 │
│ ─────────────────────────────────────────────────────────────────  │
│ teacher/exams/create/page.tsx                                       │
│   └─▶ exams/actions.createExamAction                                │
│         ├─▶ requirePermission(EXAM_CREATE)  [shared/auth-guard]     │
│         ├─▶ persistExamDraft()              [exams/data-access]     │
│         │     └─▶ db.insert(exams)           [shared/db]            │
│         │     └─▶ db.insert(examQuestions)   [shared/db]            │
│         └─▶ revalidatePath("/teacher/exams")                        │
│                                                                     │
│ 数据写入exams 表 + examQuestions 表                                │
│ ✅ P0-1 已修复persistAiGeneratedExamDraft 改为调用 questions/data-access.createQuestionWithRelations不再直查 questions 表 │
└─────────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────────┐
│ 阶段 2学生作答作业化考试                                        │
│ ─────────────────────────────────────────────────────────────────  │
│ student/learning/assignments/[assignmentId]/page.tsx                │
│   └─▶ homework/actions.startHomeworkSubmissionAction                │
│         ├─▶ requirePermission(HOMEWORK_SUBMIT)                      │
│         ├─▶ data-access-write.startHomeworkSubmission  ✅ P1-2 已修复 │
│         │     └─▶ db.insert(homeworkSubmissions)  [shared/db]       │
│         └─▶ 返回 submissionId                                       │
│                                                                     │
│   └─▶ homework/actions.saveHomeworkAnswerAction                     │
│         └─▶ data-access-write.saveHomeworkAnswer  ✅ P1-2 已修复     │
│              └─▶ db.transaction(insert homeworkAnswers) [shared/db] │
│                                                                     │
│   └─▶ homework/actions.submitHomeworkAction                         │
│         └─▶ data-access-write.submitHomework  ✅ P1-2 已修复         │
│              └─▶ db.update(homeworkSubmissions.status="submitted")  │
│                                                                     │
│ 数据写入homeworkSubmissions 表 + homeworkAnswers 表                │
│ ✅ P1-2 已修复actions 层不再直接 DB 操作,已下沉到 data-access-write│
└─────────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────────┐
│ 阶段 3教师批改                                                     │
│ ─────────────────────────────────────────────────────────────────  │
│ teacher/homework/submissions/[submissionId]/page.tsx                │
│   └─▶ homework/actions.gradeHomeworkSubmissionAction                │
│         ├─▶ requirePermission(HOMEWORK_GRADE)                       │
│         └─▶ data-access-write.gradeHomeworkSubmission  ✅ P1-2 已修复│
│              └─▶ db.update(homeworkAnswers) 循环  [shared/db]       │
│                                                                     │
│ 数据更新homeworkAnswers.isCorrect / score / feedback               │
└─────────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────────┐
│ 阶段 4成绩统计与诊断                                               │
│ ─────────────────────────────────────────────────────────────────  │
│ teacher/grades/page.tsx                                             │
│   └─▶ grades/data-access.getGradeRecords                            │
│         └─▶ ✅ P1-1 已修复:通过 classes/school/users data-access    │
│                                                                     │
│ teacher/diagnostic/page.tsx                                         │
│   └─▶ diagnostic/data-access.updateMasteryFromSubmission            │
│         ├─▶ ✅ P1-1 已修复:通过 exams data-access 获取提交          │
│         ├─▶ ✅ P1-1 已修复:通过 questions data-access 获取知识点    │
│         └─▶ 更新 knowledgePointMastery                              │
│                                                                     │
│ 数据读取homeworkSubmissions → grades → knowledgePointMastery        │
└─────────────────────────────────────────────────────────────────────┘

关键观察:考试流程横跨 4 个模块exams → homework → grades → diagnostic P1-1 已修复:所有跨模块查询已改为通过对方 data-access 接口,模块封装性已恢复。


1.4 核心调用链路

1.4.1 调用链路:创建考试(含 AI 出题)

[Client] exam-form.tsx
   │ FormData
   ▼
[Route]  POST /teacher/exams/create (Server Action)
   │
   ▼
[Action] exams/actions.createAiExamAction
   │
   ├─▶ requirePermission(EXAM_CREATE)
   │     └─▶ shared/lib/auth-guard.getAuthContext()
   │           ├─▶ auth()  [src/auth.ts]
   │           ├─▶ db.query.usersToRoles  [shared/db]
   │           ├─▶ db.query.classSubjectTeachers
   │           └─▶ 返回 { userId, roles, permissions, dataScope }
   │
   ├─▶ generateAiCreateDraftFromSource()
   │     └─▶ exams/ai-pipeline.ts (912 行)
   │           ├─▶ shared/lib/ai.createAiChatCompletion()
   │           │     └─▶ OpenAI SDK + db.query.aiProviders
   │           └─▶ JSON 解析 + Zod 校验
   │
   ├─▶ persistAiGeneratedExamDraft()
   │     └─▶ exams/data-access.ts
   │           ├─▶ db.insert(exams)              ✅ 合理
   │           ├─▶ db.insert(examQuestions)      ✅ 合理
   │           └─▶ questions/data-access.createQuestionWithRelations  ✅ P0-1 已修复:通过 data-access
   │
   └─▶ revalidatePath("/teacher/exams")

1.4.2 调用链路:学生提交作业

[Client] homework-take-view.tsx
   │
   ▼
[Action] homework/actions.submitHomeworkAction
   │
   ├─▶ requirePermission(HOMEWORK_SUBMIT)
   │
   ├─▶ data-access-write.submitHomework  ✅ P1-2 已修复
   │     (校验 submission 归属 + 更新状态)
   │     └─▶ db.update(homeworkSubmissions)
   │           SET status = "submitted", submittedAt = now()
   │
   └─▶ 返回 ActionState<{ submissionId }>

1.4.3 调用链路:管理员仪表盘聚合

[Route]  /admin/dashboard/page.tsx (Server Component)
   │
   ▼
[DataAccess] dashboard/data-access.getAdminDashboardData
   │
   ├─▶ users/data-access.getUsersDashboardStats()           ✅ 通过模块 data-access
   │     ├─ userCount / activeSessionsCount / userRoleCounts
   │     └─ recentUsers (含角色解析)
   ├─▶ classes/data-access.getClassesDashboardStats()       ✅ 通过模块 data-access
   │     └─ classCount
   ├─▶ textbooks/data-access.getTextbooksDashboardStats()   ✅ 通过模块 data-access
   │     └─ textbookCount / chapterCount
   ├─▶ questions/data-access.getQuestionsDashboardStats()   ✅ 通过模块 data-access
   │     └─ questionCount
   ├─▶ exams/data-access.getExamsDashboardStats(scope?)     ✅ 通过模块 data-access
   │     └─ examCount (含 scope 过滤)
   └─▶ homework/stats-service.getHomeworkDashboardStats(scope?)  ✅ 通过模块 data-access
         ├─ homeworkAssignmentCount / homeworkAssignmentPublishedCount
         └─ homeworkSubmissionCount / homeworkSubmissionToGradeCount

   ✅ P0-4 已修复dashboard 改为并行调用各模块 dashboard stats 函数,不再直查跨模块表

第二部分:模块清单

每个模块包含:职责 · 导出函数 · 依赖关系 · 已知问题 · 文件清单

2.1 shared基础设施层

职责:提供全项目共享的 DB Schema、工具函数、权限系统、UI 基础组件、通用 Hooks。

导出函数(核心):

  • getAuthContext() / requirePermission(p) / requireAuth() — 认证与权限
  • resolvePermissions(roles) / resolveDataScope(userId, roles) — 权限解析
  • logAudit() / logLoginEvent() / logDataChange() — 日志记录
  • createAiChatCompletion() / parseAiChatPayload() — AI 调用
  • validatePassword() / isAccountLocked() / rateLimit() — 安全策略
  • exportToExcel() / parseExcel() / generateTemplate() — Excel 工具
  • cn() / formatDate() / formatFileSize() — 通用工具

依赖关系

  • 被依赖方:所有模块依赖 shared
  • 反向依赖已修复:shared/lib/{audit-logger, change-logger, auth-guard} 通过 shared/lib/session.ts 单一入口获取 session不再直接依赖 @/auth

已知问题

  • P0shared/lib/*@/auth 循环依赖 已修复(新增 shared/lib/session.ts 封装 session 获取3 个文件改为 import { getSession } from "@/shared/lib/session"
  • ⚠️ P1schema.ts 1111 行54 张表混合,超 1000 硬上限)
  • P1auth.ts 293 行混合 5 类职责 已拆分4 个辅助函数组迁移至 shared/lib/{role-utils,bcrypt-utils,http-utils,password-security-service}auth.ts 仅保留 NextAuth 配置)
  • P2-2 已修复:ai.ts 218 行混合 5 类职责 已拆分为 ai/ 目录payload-parser.ts/api-key-crypto.ts/provider-config.ts/client.ts/errors.ts/index.tsai.ts 保留为向后兼容的重导出文件9 行)
  • ⚠️ P2onboarding-gate.tsx 业务逻辑泄漏到 shared

文件清单

文件 行数 职责
db/schema.ts 1111 54 张表定义(超硬上限)
db/relations.ts - 表关系定义
db/index.ts - Drizzle 客户端
lib/auth-guard.ts - 认证上下文 + 权限校验 + DataScope
lib/permissions.ts - 角色-权限映射
lib/session.ts 38 session 获取单一入口getSessionserver-onlydynamic import 打破循环)
lib/ai.ts 9 向后兼容重导出P2-2 已拆分到 ai/ 目录)
lib/ai/payload-parser.ts 78 请求负载解析
lib/ai/api-key-crypto.ts 28 API Key 加密/解密
lib/ai/provider-config.ts 61 Provider 配置查询
lib/ai/client.ts 58 AI 客户端创建与调用
lib/ai/errors.ts 8 错误格式化
lib/ai/index.ts 5 聚合导出
lib/audit-logger.ts - 操作日志(通过 session.ts 获取 sessionhttp-utils 获取 IP/UA
lib/change-logger.ts - 数据变更日志(通过 session.ts 获取 sessionhttp-utils 获取 IP
lib/login-logger.ts - 登录日志(通过 http-utils 获取 IP/UA
lib/password-policy.ts - 密码策略纯函数
lib/rate-limit.ts - 内存滑动窗口限流
lib/role-utils.ts 31 角色规范化纯函数normalizeRole / resolvePrimaryRole
lib/bcrypt-utils.ts 18 bcrypt 哈希前缀规范化纯函数
lib/http-utils.ts 44 请求头解析resolveClientIp / getUserAgentserver-only
lib/password-security-service.ts 84 密码安全 DB 操作(账户锁定/失败登录追踪server-only
lib/excel.ts - Excel 导入导出
lib/file-storage.ts - 文件存储抽象
hooks/use-permission.ts - 客户端权限 Hook
components/ui/* 34 文件 shadcn/ui 标准组件
components/onboarding-gate.tsx 312 引导流程(业务泄漏)
components/global-search.tsx 221 全局搜索(业务泄漏)
types/permissions.ts 92 54 个权限点常量

2.2 exams考试模块

职责:考试全生命周期管理(创建/编辑/预览/发布/删除/复制)+ AI 辅助出题。

导出函数

  • ActionscreateExamAction / createAiExamAction / previewAiExamAction / regenerateAiQuestionAction / updateExamAction / deleteExamAction / duplicateExamAction / getExamPreviewAction / getSubjectsAction / getGradesAction P1-2 已修复actions 层不再直接访问 DB全部下沉到 data-access
  • Data-accessgetExams / getExamById / persistExamDraft / persistAiGeneratedExamDraft / buildExamDescription / resolveSubjectGradeNames / getExamCreatorId / updateExamWithQuestions / deleteExamById / duplicateExam / getExamPreview / getExamSubjects / getExamGrades(后 7 个为 P1-2 新增)
  • AI PipelinegenerateAiCreateDraftFromSource / generateAiPreviewData / regenerateAiQuestionByInstruction

依赖关系

  • 依赖:shared/*@/authquestions P0-1 已修复:通过 data-access.createQuestionWithRelationsclasses P0-2 已修复:通过 data-access.getClassGradeIdsByClassIdsschool P1-1 已修复:通过 school data-access.getSubjectOptions/getGradeOptions
  • 被依赖:homework(通过 sourceExamId 外键,合理)、dashboard(通过 data-accessP0-4 已修复)、proctoring P1-1 已修复:通过 exams data-accessdiagnostic P1-1 已修复:通过 exams data-access

已知问题

  • P0-1 已修复:persistAiGeneratedExamDraft 直接 insert 到 questions 改为调用 questions/data-access.createQuestionWithRelations,通过 ID 映射保持 structure 引用一致
  • P0-2 已修复:getExams/getExamById/getExamsDashboardStats 直查 classes 改为调用 classes/data-access.getClassGradeIdsByClassIds
  • P1-1 已修复:getSubjectsAction/getGradesAction 直查 subjects/grades 改为调用 school/data-access.getSubjectOptions / getGradeOptions
  • P1-2 已修复:actions.ts 832 行(超 800 建议),多处直接 DB 操作 DB 操作已下沉到 data-accessactions.ts 现 691 行
  • ⚠️ P1ai-pipeline.ts 857 行(超 800 建议),混合 4 类职责
  • P2 已修复:ai-pipeline.ts 中 3 处非空断言清理(draft.sections!.forEach → 安全守卫、aiParsed.sections!.flatMap?? []aiParsed.sections!.map?? []

文件清单

文件 行数 职责
actions.ts 691 10 个 Server ActionP1-2 已修复,无直接 DB 操作)
ai-pipeline.ts 857 AI 出题管线(超限)
data-access.ts 473 考试 CRUD含 P1-2 新增 7 个写/查询函数P0-1/P0-2 已修复:通过 questions/classes data-access 跨模块通信)
types.ts 31 类型定义
hooks/use-exam-preview.ts 295 预览 Hook
components/* 18 文件 考试表单/组卷/预览组件

2.3 homework作业模块

职责:作业全生命周期(创建/发布/作答/批改/分析)。

导出函数

  • ActionscreateHomeworkAssignmentAction / startHomeworkSubmissionAction / saveHomeworkAnswerAction / submitHomeworkAction / gradeHomeworkSubmissionAction P1-2 已修复actions 层不再直接访问 DB全部下沉到 data-access/data-access-write
  • Data-accessgetHomeworkAssignments / getHomeworkAssignmentById / getHomeworkSubmissions / getStudentHomeworkAssignments / getStudentHomeworkTakeData / getHomeworkAssignmentReviewList / getHomeworkSubmissionDetails / getDemoStudentUser(已迁移至 users 模块 getCurrentStudentUser,此处为 re-export 向后兼容)/ isRecord / toQuestionContent / getAssignmentMaxScoreById(后三者供 stats-service 使用)
  • Data-access-classesgetAssignmentIdsForStudents / getHomeworkAssignmentsWithSubject / getHomeworkAssignmentsByIds / getAssignmentTargetCounts / getHomeworkSubmissionsForStudents / getPublishedHomeworkAssignmentsWithSubject / getHomeworkSubmissionsForAssignmentsP0-7 新增,供 classes 模块跨模块调用,封装 homework/exams 表查询)
  • Data-access-write10 个写操作函数P1-2 新增,从 actions 下沉)
  • Stats-servicegetTeacherGradeTrends / getHomeworkAssignmentAnalytics / getStudentDashboardGrades(从 data-access.ts re-export 以保持向后兼容)

依赖关系

  • 依赖:shared/*@/authexams P1-1 已修复:通过 exams data-access.getExamIdsByGradeIds/getExamSubjectIdMap/getExamWithQuestionsForHomeworkclasses P1-1 已修复:通过 classes data-access.getStudentIdsByClassId 等 7 个函数)、school P1-1 已修复:通过 school data-access.getSubjectOptionsusers P1-1 已修复:通过 users data-access.getUserWithRole/getUserNamesByIds
  • 被依赖:dashboard(通过 data-access合理parent(通过 data-access合理classes P0-7 已修复classes 通过 homework/data-access-classes 获取作业数据,不再反向直查 homework/exams 表)

已知问题

  • P0 已解决:data-access.ts 已拆分至 598 行(原 1038 行超 1000 硬上限),统计函数迁移至 stats-service.ts
  • P0 已解决:getStudentDashboardGrades 排名计算逻辑迁移至 stats-service.ts
  • P0 已解决:getHomeworkAssignmentAnalytics 错误率统计逻辑迁移至 stats-service.ts
  • P0-7 已修复:新增 data-access-classes.ts,将 classes 模块对 homework/exams 表的直查封装为 homework 模块的导出函数,恢复三层架构
  • P1-1 已修复:5 处直查 exams 改为调用 exams/data-access.getExamIdsByGradeIds / getExamSubjectIdMap / getExamWithQuestionsForHomework
  • P1-2 已修复:actions.ts 多处直接 DB 操作(createHomeworkAssignmentAction 157 行) DB 操作已下沉到 data-access-write.tsactions.ts 现 239 行

文件清单

文件 行数 职责
data-access.ts 598 作业 CRUD + 学生视角 + 批改(含 re-export stats 函数)
data-access-write.ts 285 作业写操作P1-2 新增10 个写函数从 actions 下沉)
data-access-classes.ts 232 跨模块查询封装P0-7 新增,供 classes 模块调用,封装 homework/exams 表查询)
stats-service.ts 425 统计分析(教师趋势/作业分析/学生仪表盘成绩)
actions.ts 239 5 个 Server ActionP1-2 已修复,无直接 DB 操作)
types.ts 186 类型定义
schema.ts 29 Zod 校验

2.4 questions题库模块

职责:题库管理(题目 CRUD、知识点关联、题型支持

导出函数

  • ActionsgetQuestionsAction / createQuestionAction / updateQuestionAction / deleteQuestionAction / getKnowledgePointOptionsAction P1-2 已修复actions 层不再直接访问 DB全部下沉到 data-access
  • Data-accessgetQuestions / createQuestionWithRelations / updateQuestionById / deleteQuestionByIdRecursive / getKnowledgePointOptions(后 4 个为 P1-2 新增/迁移)

依赖关系

  • 依赖:shared/*@/authtextbooks P1-1 已修复:通过 textbooks data-access.getKnowledgePointOptions
  • 被依赖:exams(通过类型导入,合理)、textbooksUI 组合,合理)

已知问题

  • P1-2 已修复:写操作函数错放在 actions.tsinsertQuestionWithRelations / deleteQuestionRecursive 已下沉到 data-accesscreateQuestionWithRelations / updateQuestionById / deleteQuestionByIdRecursive / getKnowledgePointOptions
  • P1-1 已修复:getKnowledgePointOptionsAction 直查 textbooks 模块表 改为调用 textbooks/data-access.getKnowledgePointOptions
  • P2 已解决:data-access.ts 仅 129 行,写操作缺失 P1-2 后 data-access.ts 扩充至 260 行

文件清单

文件 行数 职责
actions.ts 149 5 个 Server ActionP1-2 已修复,无直接 DB 操作)
data-access.ts 260 题目 CRUD + 知识点选项(含 P1-2 新增 4 个写/查询函数)
schema.ts 18 Zod 校验
types.ts 34 类型定义

2.5 textbooks教材模块— 标杆模块

职责:教材与知识体系管理(教材/章节树形结构、知识点 CRUD、Markdown 内容编辑、知识图谱)。

导出函数

  • ActionsgetTextbooksAction / getTextbookByIdAction / createTextbookAction / updateTextbookAction / deleteTextbookAction / getChaptersAction / createChapterAction / updateChapterAction / deleteChapterAction / getKnowledgePointsAction / createKnowledgePointAction / updateKnowledgePointAction / deleteKnowledgePointAction
  • Data-access与 actions 一一对应的 data-access 函数

依赖关系

  • 依赖:shared/*@/auth
  • 被依赖:questions P1-1 已修复:通过 textbooks data-accessexams(通过类型)、dashboard(通过 data-accessP0-4 已修复)

已知问题

  • 无跨模块 DB 访问
  • actions 层编排模式标杆(权限校验 → 调用 data-access → revalidatePath
  • data-access 层职责单一
  • P2 已修复:data-access.tsbyId.get(pid)!.children.push 非空断言清理为安全守卫;or(...)! 非空断言清理为条件 push

文件清单

文件 行数 职责
actions.ts 276 13 个 Server Action标杆
data-access.ts 428 教材/章节/知识点 CRUD
types.ts 79 类型定义
hooks/use-knowledge-point-actions.ts 121 知识点操作 Hook
components/* 12 文件 教材编辑/知识图谱组件

2.6 grades成绩模块— 标杆模块(拆分范例)

职责:成绩分析(录入/查询/统计/导出/趋势对比分析)。

导出函数

  • ActionsgetGradeRecordsAction / createGradeRecordAction / updateGradeRecordAction / deleteGradeRecordAction / exportGradesAction / getGradeTrendAction / getClassComparisonAction / getSubjectComparisonAction / getGradeDistributionAction / getClassRankingAction / getRankingTrendAction
  • Data-accessgetGradeRecords / getStudentGradeSummary / getClassRanking / getClassStudentsForEntry / getClassGradeStats / getClassGradeStatsWithMeta / getGradeTrend / getClassComparison / getSubjectComparison / getGradeDistribution / getRankingTrend

依赖关系

  • 依赖:shared/*@/authclasses P1-1 已修复:通过 classes data-access.getClassExists/getClassNameById/getClassNamesByIds/getActiveStudentIdsByClassId/getStudentActiveClassId/getClassesByGradeIdschool P1-1 已修复:通过 school data-access.getSubjectOptions/getGradeOptionsusers P1-1 已修复:通过 users data-access.getUserNamesByIds
  • 被依赖:parent(通过 data-access合理dashboard

已知问题

  • P1-1 已修复:多处直查 classes/classEnrollments/subjects/users 改为调用对应模块 data-access 函数classes/school/users
  • ⚠️ P2统计计算业务逻辑混入 data-accessgetClassGradeStats / getGradeDistribution
  • actions 层无直接 DB 访问(标杆)
  • data-access 按职责拆分为 3 个文件(标杆)
  • P2 已修复:export.tsscoreMap.get(r.studentId)! 非空断言清理为安全守卫(if (!subjMap) continue

文件清单

文件 行数 职责
actions.ts 312 6 个 Server Action
actions-analytics.ts 133 5 个分析 Action
data-access.ts 419 成绩 CRUD + 统计
data-access-analytics.ts 293 趋势/对比分析
data-access-ranking.ts 121 排名查询
export.ts 214 Excel 导出
schema.ts 52 Zod 校验
types.ts - 类型定义

2.7 classes班级模块— 耦合最严重

职责:班级 CRUD + 学生/教师管理 + 邀请码注册。

导出函数

  • ActionscreateTeacherClassAction / updateTeacherClassAction / deleteTeacherClassAction / createAdminClassAction / updateAdminClassAction / deleteAdminClassAction / createGradeClassAction / updateGradeClassAction / deleteGradeClassAction
  • Data-accessgetAdminClasses / getTeacherClasses / getGradeManagedClasses / getStudentClasses / getClassDetails / getClassStudents / getClassSchedule / getClassHomeworkInsights / getGradeHomeworkInsights / getStudentsSubjectScores / verifyTeacherOwnsClass P0-5 已修复classSchedule 写函数 createClassScheduleItem/updateClassScheduleItem/deleteClassScheduleItem 已迁移至 scheduling/data-access-class-schedule.tsclasses 模块仅保留 classSchedule 读函数; P2 已修复:getAccessibleClassIdsForTeacher 使用 Promise.all 并行化 ownedIds 与 assignedIds 查询)
  • SchemaCreateTeacherClassSchema / UpdateTeacherClassSchema / DeleteTeacherClassSchema / CreateAdminClassSchema / UpdateAdminClassSchema / DeleteAdminClassSchema / CreateGradeClassSchema / UpdateGradeClassSchema / DeleteGradeClassSchema / CreateClassScheduleItemSchema / UpdateClassScheduleItemSchema / DeleteClassScheduleItemSchema / EnrollStudentByEmailSchema

依赖关系

  • 依赖:shared/*@/authschool P1-1 已修复:通过 school data-access.isGradeHead/isGradeManager/findGradeIdByHeadAndNamehomework P0-7 已修复:通过 homework/data-access-classes 暴露的函数获取作业数据,不再直查 homework/exams 表)
  • 被依赖:exams/homework/grades/attendance/scheduling/dashboard(通过 data-accessP0-4 已修复)/parent/course-plans/users P1-1 已修复8+ 处直查 classes 表改为通过 classes data-access

已知问题

  • P0-1 已修复:data-access.ts 已拆分为 5 个文件data-access/data-access-stats/data-access-schedule/data-access-students/data-access-admin所有文件均 ≤800 行
  • P0-5 已修复classSchedule 写函数createClassScheduleItem/updateClassScheduleItem/deleteClassScheduleItem已迁移至 scheduling/data-access-class-schedule.tsclasses 模块仅保留 classSchedule 读函数getStudentSchedule/getClassSchedule新增 verifyTeacherOwnsClass 供 scheduling 模块跨模块校验教师班级归属
  • P0-7 已修复:data-access-stats.tsdata-access-students.ts 不再直查 homeworkAssignmentQuestions/homeworkAssignmentTargets/homeworkAssignments/homeworkSubmissions/exams 表,改为调用 homework/data-access-classes.ts 暴露的函数(getAssignmentIdsForStudents/getHomeworkAssignmentsWithSubject/getHomeworkAssignmentsByIds/getAssignmentMaxScoreById/getAssignmentTargetCounts/getHomeworkSubmissionsForStudents/getPublishedHomeworkAssignmentsWithSubject/getHomeworkSubmissionsForAssignments
  • P1-1 已修复:actions.ts 直查 grades 表做权限校验 改为调用 school/data-access 函数
  • P1-1 已修复:getSessionTeacherId 在 data-access 调用 auth() 改为通过 shared/lib/auth-guard.getAuthContext() 获取
  • P2 已修复:data-access.tsidByName.get(name)! 非空断言清理为 flatMap 安全过滤;data-access-admin.ts 中同类非空断言清理

文件清单

文件 行数 职责
data-access.ts 548 核心班级 CRUD + 邀请码 + 教师班级管理(含 re-export 向后兼容)
data-access-stats.ts 513 作业统计查询(班级/年级作业洞察,通过 homework/data-access-classes 获取数据)
data-access-schedule.ts 93 课表查询(学生/班级课表只读P0-5 已修复:写函数已迁移至 scheduling 模块)
data-access-students.ts 253 学生相关查询(科目成绩、学生名单、学生班级,通过 homework/data-access-classes 获取数据)
data-access-admin.ts 406 管理员班级管理(管理员班级 CRUD、年级管理班级查询
actions.ts 785 17 个 Server Action三组重复使用 Zod schema 校验)
schema.ts 152 Zod 校验13 个 schema教师/管理员/年级班级 CRUD + 课表 CRUD + 邮箱注册)
types.ts 201 类型定义(含跨领域类型污染)

2.8 school学校模块

职责:学校/学年/部门/年级的 CRUD。

导出函数

  • ActionscreateSchoolAction / updateSchoolAction / deleteSchoolAction / createAcademicYearAction / updateAcademicYearAction / deleteAcademicYearAction / createDepartmentAction / updateDepartmentAction / deleteDepartmentAction / createGradeAction / updateGradeAction / deleteGradeAction(编排层:权限校验 + Zod 校验 + 调用 data-access + revalidatePath + after(logAudit)
  • Data-access只读查询getSchools / getGrades / getDepartments / getAcademicYears / getStaffOptions / getGradesForStaff+ 写操作(create/update/delete × Department/School/Grade/AcademicYear

依赖关系

  • 依赖:shared/*@/authusers⚠️ getStaffOptions 直查 users/roles可接受
  • 被依赖:exams P1-1 已修复:通过 school data-accesshomework P1-1 已修复:通过 school data-accessgrades P1-1 已修复:通过 school data-accessquestions P1-1 已修复:通过 textbooks data-accessclasses P1-1 已修复:通过 school data-accesscourse-plans(合理)

已知问题

  • P0-8 已修复:actions.ts 不再直接导入 db 和 schema所有 DB 写操作下沉到 data-access.ts,符合三层架构
  • P2 已修复:logAudit() 通过 Next.js after() 异步非阻塞执行
  • P2 已修复:data-access.ts 中 8 处 catch 块添加 console.error 输出错误上下文getDepartments/getAcademicYears/getSchools/getGrades/getStaffOptions/getGradesForStaff/getSubjectOptions/getGradeOptions
  • ⚠️ P2审计日志不一致仅 school 实体记录department/academicYear/grade 未记录)
  • ⚠️ P2getStaffOptions/getGrades 直查 users/roles展示用可接受

文件清单

文件 行数 职责
actions.ts 326 12 个 Server Action编排层无 DB 直访)
data-access.ts 320 只读查询 + 12 个写操作CRUD
schema.ts 51 Zod 校验
types.ts 96 类型定义(含 Insert/Update 入参类型)

2.9 scheduling排课模块

职责:自动排课算法 + 课表调整 + 排课规则管理。

导出函数

  • ActionsautoScheduleAction / applyAutoScheduleAction / getSchedulingRulesAction / updateSchedulingRulesAction / getScheduleChangesAction / createScheduleChangeAction / updateScheduleChangeAction / deleteScheduleChangeAction
  • Data-accessgetSchedulingRules / getScheduleChanges / getAdminClassesForScheduling / getTeachersForScheduling / getClassroomsForScheduling / getClassSubjectsForScheduling
  • Data-access-class-schedule P0-5 新增):createClassScheduleItem / updateClassScheduleItem / deleteClassScheduleItem(从 classes 模块迁移,含教师班级归属校验,通过 classes/data-access.verifyTeacherOwnsClass 跨模块校验)
  • Data-access低级写入insertClassScheduleItem / updateClassScheduleItemById / deleteClassScheduleItemById / replaceClassSchedule(统一 classSchedule DB 写入口)
  • 算法:findOptimalSlot / validateSchedule / autoSchedule / buildDefaultTimeSlots(纯函数,标杆)

依赖关系

  • 依赖:shared/*@/authclasses P0-5 已修复:通过 classes/data-access.verifyTeacherOwnsClass / getTeacherIdForMutations 校验教师班级归属,不再直写 classSchedule 表的写入口分散在 classes 模块)、school⚠️ 排课辅助查询,可接受)、users P1-1 已修复:通过 users data-access.getUserNamesByIds
  • 被依赖:classes/actions.ts P0-5 已修复:通过 scheduling/data-access-class-schedule 调用写函数)

已知问题

  • P0-5 已修复:applyAutoScheduleAction 直接 transaction 写 classSchedule 表(第三个写入口) 改为调用 replaceClassSchedule 统一写入口classSchedule 所有写函数统一在 scheduling 模块
  • P1-1 已修复:autoScheduleAction 直查 users 改为调用 users/data-access.getUserNamesByIds
  • ⚠️ P2actions.ts 末尾 re-export data-access 函数(反模式)
  • P2 已修复:data-access.ts 中 3 处非空断言清理(userIds[0]!rows[i]!rows[j]!auto-scheduler.ts 中 2 处非空断言清理(schedule[i]!schedule[j]!
  • auto-scheduler.ts 是算法独立化的最佳实践(纯函数、无 DB、可测试

文件清单

文件 行数 职责
auto-scheduler.ts 310 排课算法(纯函数,标杆)
actions.ts 302 8 个 Server Action
data-access.ts 398 排课辅助查询 + 规则/变更 CRUD + classSchedule 低级写入insert/update/delete/replace
data-access-class-schedule.ts 165 classSchedule 业务写入P0-5 新增,从 classes 模块迁移,含教师归属校验)
schema.ts - Zod 校验
types.ts - 类型定义(含 P0-5 迁移的 CreateClassScheduleItemInput / UpdateClassScheduleItemInput

2.10 attendance考勤模块— 结构典范

职责:考勤记录管理 + 统计分析。

导出函数

  • ActionsgetAttendanceRecordsAction / createAttendanceRecordAction / updateAttendanceRecordAction / deleteAttendanceRecordAction / getStudentAttendanceAction / getAttendanceStatsAction
  • Data-accessgetAttendanceRecords / createAttendanceRecord / updateAttendanceRecord / deleteAttendanceRecord / getClassStudentsForAttendance / getAttendanceStats

依赖关系

  • 依赖:shared/*@/authclasses P1-1 已修复:通过 classes data-access.getTeacherClasses/getAdminClasses
  • 被依赖:无

已知问题

  • P1-1 已修复:getClassStudentsForAttendance 直查 classEnrollments 改为通过 classes data-access 获取
  • stats 独立拆分为 data-access-stats.ts(拆分范例)
  • DataScope 完整接入 6 种 scope 类型
  • actions 层无直接 DB 访问

文件清单

文件 行数 职责
actions.ts 271 6 个 Server Action
data-access.ts 271 考勤 CRUD
data-access-stats.ts 145 统计逻辑(拆分范例)
schema.ts - Zod 校验
types.ts - 类型定义

2.11 users用户模块

职责:用户资料管理 + 批量导入导出。

导出函数

  • ActionsgetUserProfileAction / updateUserProfileAction / importUsersAction / exportUsersAction / downloadUserTemplateAction
  • Data-accessgetUserProfile / getCurrentStudentUser P2-20 已修复:从 homework 模块迁移而来6 个 student 页面通过此函数获取学生身份,不再依赖 homework 模块)
  • Import-exportgenerateUserImportTemplate / parseUserImportData / exportUsersToExcel+ re-export batchImportUsers / UserImportResult 保持向后兼容)
  • User-servicebatchImportUsers(用户创建 + 密码哈希 + 角色分配)
  • Class-registrationregisterStudentByInvitationCode(委托 classes/data-access 完成班级注册)

依赖关系

  • 依赖:shared/*(含 shared/lib/role-utils P2 已修复:删除本地 normalizeRoleName/resolvePrimaryRole/rolePriority,统一复用 shared/lib/role-utils.resolvePrimaryRole)、@/authclasses P1-4 已修复:通过 class-registration.ts 调用 classes/data-access.enrollStudentByInvitationCode,不再直写 classEnrollments
  • 被依赖:dashboard(通过 data-accessP0-4 已修复)、grades P1-1 已修复:通过 users data-accesshomework P1-1 已修复:通过 users data-accessscheduling P1-1 已修复:通过 users data-accessdiagnostic P1-1 已修复:通过 users data-accesselective P1-1 已修复:通过 users data-accessproctoring P1-1 已修复:通过 users data-accessparent P1-1 已修复:通过 users data-access

已知问题

  • P1 已解决:import-export.ts 四重职责已拆分为 import-export.ts(解析/生成)+ user-service.ts(用户创建)+ class-registration.ts(班级注册)
  • P1 已解决:batchImportUsers 不再跨模块直写 classEnrollments,改为调用 classes/data-access.enrollStudentByInvitationCode
  • P2 已解决:删除本地 normalizeRoleName/resolvePrimaryRole/rolePriority,统一复用 shared/lib/role-utils.resolvePrimaryRole,消除重复代码
  • P1-1 已修复:updateUserProfile 绕过 data-access 直接 DB 写 已下沉到 data-access
  • P2-20 已修复:新增 getCurrentStudentUser 函数(从 homework 模块迁移6 个 student 页面通过此函数获取学生身份,不再依赖 homework 模块
  • P2 已解决:data-access.ts 已扩充写操作updateUserProfile 已下沉)

文件清单

文件 行数 职责
import-export.ts 157 文件解析/生成(模板生成 + 解析校验 + Excel 导出)+ re-export 向后兼容
user-service.ts 82 用户创建(批量导入 + 密码哈希 + 角色分配)
class-registration.ts 21 班级注册(委托 classes/data-access
actions.ts 131 5 个 Server Action
data-access.ts 133 getUserProfile + 用户查询

2.12 dashboard仪表盘模块

职责:管理员/教师/学生仪表盘数据聚合。

导出函数

  • Data-accessgetAdminDashboardData / getTeacherDashboardData / getStudentDashboardData

依赖关系

  • 依赖:shared/*@/authclasses(通过 data-access合理homework(通过 data-access合理grades(合理)、users/textbooks/questions/exams(通过各模块 dashboard stats 函数P0-4 已修复)
  • 被依赖:无

已知问题

  • P0-4 已修复:getAdminDashboardData 改为并行调用各模块 dashboard stats 函数(getUsersDashboardStats/getClassesDashboardStats/getTextbooksDashboardStats/getQuestionsDashboardStats/getExamsDashboardStats/getHomeworkDashboardStats),不再直查跨模块表
  • P1-1 已修复:教师仪表盘直查 users 表获取教师姓名 改为通过 users data-access 获取
  • 学生/教师仪表盘正确通过各模块 data-access 获取数据

文件清单

文件 行数 职责
data-access.ts - 仪表盘数据聚合P0-4 已修复,通过各模块 data-access 获取数据)
types.ts - 类型定义
components/* 14 文件 三种角色仪表盘组件

2.13 messaging私信模块

职责站内私信messages 表 CRUD

导出函数

  • ActionssendMessageAction / getMessagesAction / getMessageAction / deleteMessageAction / getNotificationsAction / markNotificationReadAction / markAllNotificationsReadAction / getNotificationPreferencesAction / updateNotificationPreferencesAction
  • Data-accessgetMessages / getMessageById / getMessageThread / createMessage / markMessageAsRead / deleteMessage / getUnreadMessageCount / getRecipients(通知 CRUD 通过 re-export 从 notifications 模块重导出,保持向后兼容)
  • Notification-preferencesre-export shim实际逻辑在 notifications/preferences.ts

依赖关系

  • 依赖:shared/*@/authnotifications P0-4 / P1-5 已修复:通过 sendNotification dispatcher 发送通知,通知 CRUD 和偏好已迁移至 notifications 模块)
  • 被依赖:notifications 已消除反向依赖)、settings(通知偏好表单)、layout(通知下拉)

已知问题

  • P0-4 已修复:sendMessageAction 绕过 notifications dispatcher 直接调用 createNotification 改为调用 notifications.sendNotification,通知 CRUD 已迁移至 notifications 模块
  • P0 已修复:与 notifications 双向依赖 + 职责重叠 通知相关表messageNotifications / notificationPreferences所有权已移交 notifications 模块messaging 仅保留 messages 表
  • P1-5 已修复:同时管理 3 类数据messages + messageNotifications + notificationPreferences 仅管理 messages 表,通知相关数据由 notifications 模块管理
  • P1 已修复:通知相关 Action 使用 requireAuth() 而非 requirePermission() 5 个通知 ActiongetNotifications / markNotificationAsRead / markAllNotificationsAsRead / getNotificationPreferences / updateNotificationPreferences已改为 requirePermission(Permissions.MESSAGE_READ)
  • P1 已修复:markMessageAsReadAction / deleteMessageAction / getMessageDetailAction 缺少 Zod 校验 已添加 MessageIdSchema 校验 messageId 参数
  • P1 已修复:updateNotificationPreferencesAction 缺少 Zod 校验 已添加 UpdateNotificationPreferencesSchema 校验 8 个布尔字段
  • P2 已修复:data-access.ts 中 3 处 or(...)! 非空断言清理为安全守卫(条件 push

文件清单

文件 行数 职责
actions.ts 276 9 个 Server Action通知相关 Action 委托 notifications 模块)
data-access.ts 199 私信 CRUD + re-export 通知 CRUD向后兼容
notification-preferences.ts 11 re-export shim实际逻辑在 notifications/preferences.ts
schema.ts 41 私信发送校验 + messageId 校验 + 通知偏好更新校验
types.ts 72 私信类型 + re-export 通知类型(向后兼容)

2.14 notifications通知分发模块

职责多渠道通知分发SMS/Email/WeChat/InApp+ 站内通知 CRUD + 通知偏好管理。

导出函数

  • ActionssendNotificationAction / sendClassNotificationAction
  • DispatchersendNotification(payload) / sendBatchNotifications(payloads)
  • Data-accesscreateNotification / getNotifications / markNotificationAsRead / markAllNotificationsAsRead / getUnreadNotificationCount / getUserContactInfo / logNotificationSend / logNotificationSendBatch P0-4 / P1-5 修复后从 messaging 迁移)
  • PreferencesgetNotificationPreferences / upsertNotificationPreferences P0-4 / P1-5 修复后从 messaging 迁移)
  • ChannelsInAppChannelSender / SmsChannelSender / EmailChannelSender / WeChatChannelSender

依赖关系

  • 依赖:shared/*@/authclasses P1-1 已修复:通过 classes data-access.getClassExists/getStudentIdsByClassId
  • 被依赖:messaging P0-4 / P1-5 已修复messaging 通过 sendNotification dispatcher 发送通知,通知 CRUD 和偏好通过 re-export 保持向后兼容)

已知问题

  • P0-4 已修复:不拥有任何数据,全部依赖 messaging 模块 messageNotifications 和 notificationPreferences 表所有权已从 messaging 迁移至 notifications 模块
  • P0 已修复:与 messaging 双向依赖 notifications 不再反向依赖 messagingin-app-channel 改为静态导入本地 createNotification
  • P1-1 已修复:sendClassNotificationAction 直查 classes/classEnrollments 改为调用 classes/data-access.getClassExists / getStudentIdsByClassId
  • ⚠️ P1发送日志仅 consolenotification_logs
  • 渠道抽象优秀(接口 + 工厂 + Mock 实现)

文件清单

文件 行数 职责
dispatcher.ts 152 渠道选择 + 并行分发
data-access.ts 177 站内通知 CRUD + 用户联系方式 + 日志P0-4 / P1-5 修复后新增通知 CRUD
preferences.ts 166 通知偏好 CRUDP0-4 / P1-5 修复后从 messaging 迁移)
actions.ts 119 2 个 Server Action
types.ts 120 通知负载 + 渠道配置 + 通知记录 + 偏好类型P0-4 / P1-5 修复后扩充)
index.ts 61 对外导出入口
channels/* 5 文件 4 个渠道实现

2.15 audit审计模块

职责:操作日志 + 登录日志 + 数据变更日志查询与导出。

导出函数

  • ActionsgetAuditLogsAction / getLoginLogsAction / getDataChangeLogsAction / exportAuditLogsAction / exportLoginLogsAction / exportDataChangeLogsAction
  • Data-accessgetAuditLogs / getLoginLogs / getDataChangeLogs / getAuditModuleOptions

依赖关系

  • 依赖:shared/*@/auth
  • 被依赖:无

已知问题

  • ⚠️ P2Excel 导出逻辑内联在 actions 层(应抽取到 export.ts
  • ⚠️ P2三个导出 Action 结构高度重复
  • P2 已修复:data-access.ts 中 6 处 catch 块添加 console.error 输出错误上下文;toIso/clampPageSize/clampPage 工具函数补齐显式返回类型
  • data-access 职责清晰,无跨模块问题

文件清单

文件 行数 职责
actions.ts 212 6 个 Server Action含内联导出
data-access.ts 260 日志查询
types.ts - 类型定义

2.16 announcements公告模块

职责:公告 CRUD + 发布/归档。

导出函数

  • ActionsgetAnnouncementsAction / createAnnouncementAction / updateAnnouncementAction / deleteAnnouncementAction / publishAnnouncementAction / archiveAnnouncementAction P1-2 已修复actions 层不再直接访问 DB全部下沉到 data-access
  • Data-accessgetAnnouncements / getAnnouncementById / insertAnnouncement / updateAnnouncementById / deleteAnnouncementById / publishAnnouncementById / archiveAnnouncementById(后 5 个为 P1-2 新增)

依赖关系

  • 依赖:shared/*@/authschool(合理,获取年级列表)
  • 被依赖:无

已知问题

  • P1-2 已修复:所有写操作直接在 actions 层 db.insert/update/delete,未下沉到 data-access 写操作已下沉到 data-access5 个新函数)
  • ⚠️ P2死代码 void wasPublished
  • P2 已修复:getAnnouncementsAction 使用 requireAuth() 而非 requirePermission(ANNOUNCEMENT_READ) 改为 requirePermission(Permissions.ANNOUNCEMENT_READ)
  • P2 已修复:data-access.ts 中 2 处 catch 块添加 console.error 输出错误上下文getAnnouncements/getAnnouncementById

文件清单

文件 行数 职责
actions.ts 197 6 个 Server ActionP1-2 已修复,无直接 DB 操作)
data-access.ts 171 公告 CRUD + 发布/归档(含 P1-2 新增 5 个写函数)
schema.ts - Zod 校验
types.ts - 类型定义

2.17 files文件模块

职责:文件附件 CRUD + 批量删除 + 统计。

导出函数

  • Data-accessgetAllFileAttachments / getFileAttachmentsByOwner / getFileAttachmentById / createFileAttachment / updateFileAttachment / deleteFileAttachment / batchDeleteFileAttachments / getFileStats P2 已修复7 个读函数使用 React.cache() 包装实现请求级 memoizationgetFileAttachment / getFileAttachmentsByTarget / getFileAttachmentsByUploader / getAllFileAttachments / getFileAttachmentsWithFilters / getFileStats / getFileAttachmentsByIds

依赖关系

  • 依赖:shared/*@/auth
  • 被依赖:app/api/upload / app/api/files/[id] / app/api/files/batch-delete

已知问题

  • P2-13 已修复:所有函数 try-catch 吞错误返回空数组/null 所有 catch 块已添加 console.error 输出错误上下文
  • P2 已修复:getFileAttachmentsWithFiltersor(...)! 非空断言清理为安全守卫
  • ⚠️ P2actions.tsdata-access 被路由直接调用
  • 职责单一,不跨模块查询

文件清单

文件 行数 职责
data-access.ts 267 文件 CRUD + 批量删除 + 统计
types.ts - 类型定义
components/* 6 文件 上传/列表/预览/管理

2.18 course-plans课程计划模块

职责:课程计划 CRUD + 周计划项 CRUD + 排序。

导出函数

  • ActionsgetCoursePlansAction / getCoursePlanByIdAction / createCoursePlanAction / updateCoursePlanAction / deleteCoursePlanAction / createCoursePlanItemAction / updateCoursePlanItemAction / deleteCoursePlanItemAction / toggleCoursePlanItemCompletedAction
  • Data-access与 actions 对应

依赖关系

  • 依赖:shared/*@/authclasses合理getAdminClasses/getStaffOptionsschool合理getAcademicYears
  • 被依赖:无

已知问题

  • ⚠️ P2getSubjectOptions 直查 subjectssubjects 无独立模块,可接受)
  • P2 已修复:data-access.ts 中 3 处 catch 块添加 console.error 输出错误上下文getCoursePlans/getCoursePlanById/getSubjectOptions
  • actions 层使用 handleError/revalidatePlanPaths 辅助函数(良好范例)

文件清单

文件 行数 职责
data-access.ts 320 课程计划 + 周计划项 CRUD
actions.ts 265 9 个 Server Action
schema.ts - Zod 校验
types.ts - 类型定义

2.19 parent家长模块

职责:家长视角的子女数据聚合与展示。

导出函数

  • Data-accessgetChildren / getChildBasicInfo / getChildDashboardData P2 已修复:getChildBasicInfo 使用 Promise.all 并行化 gradeOptions 与 classId 查询,并添加 ChildBasicInfo 显式返回类型;getChildBasicInfo 使用 React.cache() 包装实现请求级 memoization

依赖关系

  • 依赖:shared/*@/authclasses(合理)、homework(合理)、grades(合理)
  • 被依赖:无

已知问题

  • P2 已修复:getChildBasicInfo 多次串行查询,可优化为 join 改为使用 Promise.all 并行化 gradeOptions 与 classId 查询
  • 职责单一,正确复用其他模块 data-access

文件清单

文件 行数 职责
data-access.ts 234 子女关系 + 仪表盘数据聚合
types.ts 57 类型定义
components/* 7 文件 子女卡片/详情/仪表盘

2.20 elective选课模块

职责:选修课程管理 + 学生选课 + 抽签。

导出函数

  • ActionsgetElectiveCoursesAction / createElectiveCourseAction / updateElectiveCourseAction / deleteElectiveCourseAction / getStudentSelectionsAction / selectCourseAction / dropCourseAction / runLotteryAction / getAvailableCoursesForStudentAction
  • Data-accessgetElectiveCourses / getElectiveCourseById / createElectiveCourse / updateElectiveCourse / deleteElectiveCourse / selectCourse / dropCourse / runLottery / getStudentSelections / getAvailableCoursesForStudent

依赖关系

  • 依赖:shared/*@/auth
  • 被依赖:无

已知问题

  • ⚠️ P1data-access.tsdata-access-selections.ts 重复定义 mapCourseRow/buildCourseSelect60 行重复)
  • ⚠️ P2runLottery 使用 Math.random(),结果不可复现
  • ⚠️ P2selectCourse FCFS 模式存在并发超卖风险
  • 权限校验完整ELECTIVE_MANAGE/SELECT/READ

文件清单

文件 行数 职责
actions.ts 304 11 个 Server Action
data-access.ts 242 课程 CRUD + scope 过滤
data-access-operations.ts 217 选课操作select/drop/lottery
data-access-selections.ts 189 选课记录查询
schema.ts 132 Zod 校验
types.ts 108 类型定义 + 标签常量

2.21 proctoring监考模块

职责:考试监考事件记录 + 防作弊监控 + 监考面板。

导出函数

  • ActionsrecordProctoringEventAction / getProctoringDashboardAction
  • Data-accessrecordProctoringEvent / getExamSubmissionForProctoring / getExamForProctoring / getExamProctoringSummary / getStudentProctoringStatuses / getRecentProctoringEvents P2 已修复:getExamProctoringSummary 使用 Promise.all 并行化考试信息与提交记录查询、事件类型统计与学生事件统计查询;合并两次 filter 为单次循环统计 started/submitted

依赖关系

  • 依赖:shared/*@/authexams P1-1 已修复:通过 exams data-access.getExamForProctoringCrossModule/getExamSubmissionForProctoringCrossModule/getExamSubmissionsForExam/getExamTitleByIdusers P1-1 已修复:通过 users data-access.getUserNamesByIds
  • 被依赖:无

已知问题

  • P0exam-mode-config.tsx 未集成到考试表单(死代码,监考功能无法启用)
  • P0-6 已修复:事件上报存在 Server Action 与 REST API 双通道重复 删除 /api/proctoring/event REST 路由(移至 deletes/Server Action recordProctoringEventAction 为唯一规范路径
  • P1-1 已修复:跨模块直查 exams/examSubmissions/users 改为通过 exams/users data-access 函数获取数据
  • P2 已修复:actions.ts 不再直接 import dbexamSubmissionssubmission 归属校验已下沉到 data-accessrecordProctoringEventAction 改用 requirePermission(EXAM_SUBMIT) 并增加 revalidatePath

文件清单

文件 行数 职责
data-access.ts 409 事件记录 + 查询 + 摘要统计 + submission 归属校验
actions.ts 139 2 个 Server Action
types.ts 136 类型定义 + 标签常量 + 阈值常量
components/anti-cheat-monitor.tsx - 学生端防作弊监控
components/exam-mode-config.tsx - 考试模式配置(未集成
components/proctoring-dashboard.tsx - 教师监考面板

2.22 diagnostic学情诊断模块

职责:知识点掌握度查询 + 诊断报告生成。

导出函数

  • ActionsgenerateStudentDiagnosticReportAction / generateClassDiagnosticReportAction / publishDiagnosticReportAction / deleteDiagnosticReportAction / getDiagnosticReportsAction / getStudentMasteryAction
  • Data-accessupdateMasteryFromSubmission / getStudentMastery / getClassMasteryOverview
  • Data-access-reportscreateDiagnosticReport / getDiagnosticReport / getDiagnosticReports / deleteDiagnosticReport / publishDiagnosticReport P2 已修复:getDiagnosticReportsgetDiagnosticReportById 使用 React.cache() 包装实现请求级 memoization
  • SchemaGenerateStudentReportSchema / GenerateClassReportSchema / PublishReportSchema / DeleteReportSchema / GetDiagnosticReportsSchema / GetDiagnosticReportByIdSchema

依赖关系

  • 依赖:shared/*@/authexams P1-1 已修复:通过 exams data-access.getExamSubmissionWithAnswersquestions P1-1 已修复:通过 questions data-access.getKnowledgePointsForQuestionsclasses P1-1 已修复:通过 classes data-access.getClassExists/getClassNameById/getActiveStudentIdsByClassIdusers P1-1 已修复:通过 users data-access.getUserNamesByIds/getUserIdsByGradeId
  • 被依赖:无

已知问题

  • P1-1 已修复:updateMasteryFromSubmission 跨模块直查 4 张表(与 exams/homework/questions 紧耦合) 改为调用 exams/data-access.getExamSubmissionWithAnswersquestions/data-access.getKnowledgePointsForQuestions
  • ⚠️ P2data-access-reports.ts 有未使用代码(round2
  • ⚠️ P2班级报告将生成者 ID 存入 studentId 字段schema 设计缺陷 workaround
  • 与 grades 模块无职责重叠grades 管分数diagnostic 管知识点掌握度)

文件清单

文件 行数 职责
data-access.ts 254 知识点掌握度查询 + 更新
data-access-reports.ts 202 诊断报告 CRUD
actions.ts 172 6 个 Server Action使用 Zod schema 校验)
schema.ts 56 Zod 校验6 个 schema生成/发布/删除/查询报告)
types.ts 97 类型定义
components/* 4 文件 学生/班级诊断视图 + 雷达图

2.23 settings设置模块

职责AI Provider 管理 + 密码修改 + 个人资料 + 主题偏好 + 通知偏好。

导出函数

  • ActionsgetAiProvidersAction / createAiProviderAction / updateAiProviderAction / deleteAiProviderAction / testAiProviderAction
  • Actions-passwordchangePasswordAction P1 已修复:使用 requirePermission(USER_PROFILE_UPDATE) + Zod 校验 + DB 操作下沉到 data-access
  • Data-accessgetAiProviderSummaries / countDefaultAiProviders / getAiProviderForUpdate / updateAiProvider / createAiProvider / getUserPasswordHash / getPasswordSecurityByUserId / updateUserPassword / upsertPasswordSecurityOnPasswordChangeP1 新增,从 actions 下沉)
  • TypesAiProviderSummary / AiProviderName / AiProviderExistingP1 新增,从 actions.ts 迁出)

依赖关系

  • 依赖:shared/*(含 shared/lib/bcrypt-utils P2 已修复:actions-password.ts 删除本地 normalizeBcryptHash,统一复用 shared/lib/bcrypt-utils.normalizeBcryptHash)、@/authmessaging(通知偏好表单调用 messaging Action
  • 被依赖:无

已知问题

  • ⚠️ P2混合 5 类职责AI Provider + 密码 + 资料 + 主题 + 通知偏好)
  • P1 已修复:data-access.tsactions.ts 直接使用 db 新建 data-access.ts,所有 DB 操作已下沉
  • P1 已修复:changePasswordAction 使用 requireAuth() 无 Zod 校验 改为 requirePermission(USER_PROFILE_UPDATE) + ChangePasswordSchema Zod 校验 + 并行查询优化
  • P2 已修复:actions-password.ts 删除本地 normalizeBcryptHash,统一复用 shared/lib/bcrypt-utils.normalizeBcryptHash,消除重复代码
  • ⚠️ P2notification-preferences-form.tsx 跨模块 UI 依赖
  • 密码修改有速率限制
  • AI Provider 操作有 AI_CONFIGURE 权限校验

文件清单

文件 行数 职责
actions.ts 178 AI Provider CRUD + 测试P1 已修复,无直接 DB 操作)
actions-password.ts 107 修改密码P1 已修复requirePermission + Zod + data-access
data-access.ts 175 AI Provider CRUD + 密码修改 DB 操作P1 新增)
types.ts 16 类型定义P1 新增AiProviderSummary 等)
components/* 8 文件 通用设置 + AI 配置 + 密码 + 主题 + 通知偏好

2.24 auth认证 UI 模块)

职责:认证页面 UI登录/注册/布局)。

导出函数:纯 UI 组件(LoginForm / RegisterForm / AuthLayout

依赖关系

  • 依赖:shared/*
  • 被依赖:app/(auth)/*

已知问题

  • 纯 UI 模块,无 data-access/actions/types
  • 认证逻辑由 NextAuth + shared/lib/auth-guard 统一处理

文件清单

文件 职责
components/auth-layout.tsx 认证页面布局
components/login-form.tsx 登录表单
components/register-form.tsx 注册表单

2.25 layout布局模块

职责:应用骨架(侧边栏 + 顶部导航 + 导航配置)。

导出函数AppSidebar / SidebarProvider / SiteHeader + navigation 配置

依赖关系

  • 依赖:shared/hooks/use-permission@/authuseSessionmessaging(通知下拉)
  • 被依赖:app/(dashboard)/layout.tsx

已知问题

  • ⚠️ P2用权限反推角色permissions.includes(HOMEWORK_SUBMIT) && !permissions.includes(EXAM_CREATE)),应改用 hasRole("student")
  • navigation.ts 无幽灵路由13 个已修复)

文件清单

文件 职责
components/app-sidebar.tsx 侧边栏(根据权限渲染)
components/sidebar-provider.tsx 侧边栏状态 Context
components/site-header.tsx 顶部导航(含通知下拉)
config/navigation.ts 导航配置4 个角色)

2.26 student学生 UI 模块)

职责:学生端 UI 组件(课程视图 + 课表筛选/视图)。

导出函数StudentCoursesView / StudentScheduleFilters / StudentScheduleView

依赖关系

  • 依赖:shared/*
  • 被依赖:app/(dashboard)/student/*

已知问题

  • ⚠️ P2与 classes 模块的 schedule-view.tsx/schedule-filters.tsx 可能功能重叠
  • 纯 UI 模块,数据由页面通过 classes data-access 获取

文件清单

文件 职责
components/student-courses-view.tsx 学生课程视图
components/student-schedule-filters.tsx 课表筛选器
components/student-schedule-view.tsx 学生课表视图

2.27 lesson-preparation备课模块

职责教师备课基于教材章节创建课案Block 编辑器),支持模板、版本管理、知识点标注、题目创建/拉取、作业发布。

导出函数

  • Data-accessdata-access.tsgetLessonPlans / getLessonPlanById / createLessonPlan / updateLessonPlanContent / softDeleteLessonPlan / duplicateLessonPlan / getTemplateById / buildInitialContent
  • Data-access-versionsdata-access-versions.tsgetLessonPlanVersions / createLessonPlanVersion / getVersionContent / revertToVersion / pruneAutoVersions
  • Data-access-templatesdata-access-templates.tsgetLessonPlanTemplates / saveAsTemplate / deletePersonalTemplate
  • Data-access-knowledgedata-access-knowledge.tsgetLessonPlansByKnowledgePoint / getLessonPlansByQuestion
  • Publish-servicepublish-service.tspublishLessonPlanHomework
  • AI-suggestai-suggest.tssuggestKnowledgePoints
  • ActionsgetLessonPlansAction / getLessonPlanByIdAction / createLessonPlanAction / updateLessonPlanAction / saveLessonPlanVersionAction / getLessonPlanVersionsAction / revertLessonPlanVersionAction / deleteLessonPlanAction / duplicateLessonPlanAction / getLessonPlanTemplatesAction / saveAsTemplateAction / deleteTemplateAction / suggestKnowledgePointsAction / publishLessonPlanHomeworkAction / getKnowledgePointOptionsAction

依赖关系

  • 依赖:shared/*@/authshared/lib/aitextbooks(只读章节/知识点树)、questions(创建/查询题目)、exams(创建 exam 草稿)、homework(创建作业下发)、classes(查询教师班级)、files(附件)
  • 被依赖:无

已知问题

  • 通过对方 data-access 调用跨模块数据,无直查跨模块表
  • data-access 按职责拆分为 4 个文件data-access/data-access-versions/data-access-templates/data-access-knowledge
  • actions 按职责拆分为 4 个文件actions/actions-publish/actions-ai/actions-kp

文件清单

文件 职责
types.ts 类型定义
constants.ts 常量定义
schema.ts Zod 验证
data-access.ts 课案 CRUD + 模板查询 + 初始内容构建
data-access-versions.ts 版本管理(创建/查询/回滚/清理)
data-access-templates.ts 个人模板 CRUD
data-access-knowledge.ts 按知识点/题目反查课案
actions.ts 课案 CRUD/版本/模板 Server Actions
actions-publish.ts 发布作业 Server Action
actions-ai.ts AI 知识点建议 Server Action
actions-kp.ts 知识点选项 Server Action
publish-service.ts 发布作业服务(编排 homework/exams/classes
ai-suggest.ts AI 知识点建议服务
seed-templates.ts 模板种子数据
hooks/use-lesson-plan-editor.ts 课案编辑器 Hook
components/lesson-plan-list.tsx 课案列表
components/lesson-plan-card.tsx 课案卡片
components/lesson-plan-filters.tsx 课案筛选器
components/lesson-plan-editor.tsx 课案编辑器
components/block-renderer.tsx Block 渲染器
components/template-picker.tsx 模板选择器
components/version-history-drawer.tsx 版本历史抽屉
components/knowledge-point-picker.tsx 知识点选择器
components/question-bank-picker.tsx 题库选择器
components/inline-question-editor.tsx 内联题目编辑器
components/publish-homework-dialog.tsx 发布作业对话框
components/blocks/rich-text-block.tsx 富文本 Block
components/blocks/text-study-block.tsx 课文研读 Block
components/blocks/exercise-block.tsx 练习 Block
components/blocks/reflection-block.tsx 反思 Block

第三部分:已知架构问题和技术债

3.1 P0 严重问题(必须立即修复)

P0-1文件超 1000 行硬上限3 个文件)

文件 行数 问题 拆分建议
classes/data-access.ts 2104 → 548 混入 homework/scheduling/grades 逻辑 已拆分 已拆为 5 个文件data-access.ts(548行) + data-access-stats.ts(531行) + data-access-schedule.ts(194行) + data-access-students.ts(244行) + data-access-admin.ts(406行),通过 re-export 保持向后兼容
homework/data-access.ts 1038 → 598 混入排名计算业务逻辑 已拆分 已拆为 data-access.ts(598行) + stats-service.ts(425行),统计函数迁移至 stats-service.ts
shared/db/schema.ts 1111 54 张表混合 按业务域拆分为 schema/auth.ts + schema/academic.ts + schema/exam.ts + ...,通过 index.ts 聚合

P0-2shared/lib ↔ auth 循环依赖 已修复

shared/lib/{audit-logger, change-logger, auth-guard} → @/auth → shared/lib/*

影响shared 层无法独立测试/复用;架构上基础设施不应反向依赖应用层。

修复方案(已实施):

  • 创建 shared/lib/session.ts 封装 session 获取(getSession()server-only
  • session.ts 内部使用 dynamic import("@/auth") 打破模块级静态循环
  • audit-logger.ts / change-logger.ts / auth-guard.ts 改为 import { getSession } from "@/shared/lib/session",不再直接依赖 @/auth
  • 运行时调用链保持不变,模块加载图无环

P0-3dashboard 跨模块直接查询 11 张表 已修复

dashboard/data-access.tsgetAdminDashboardData 原直查 sessions/users/usersToRoles/roles/classes/textbooks/chapters/questions/exams/homeworkAssignments/homeworkSubmissions。

修复方案(已实施):

  • 各模块新增 dashboard stats 函数:
    • users/data-access.tsgetUsersDashboardStats()userCount/activeSessionsCount/userRoleCounts/recentUsers
    • classes/data-access.tsgetClassesDashboardStats()classCount
    • textbooks/data-access.tsgetTextbooksDashboardStats()textbookCount/chapterCount
    • questions/data-access.tsgetQuestionsDashboardStats()questionCount
    • exams/data-access.tsgetExamsDashboardStats(scope?)examCount支持 scope 过滤)
    • homework/stats-service.tsgetHomeworkDashboardStats(scope?)4 个计数,支持 scope 过滤)
  • dashboard 改为并行调用:Promise.all([getUsersDashboardStats(), getClassesDashboardStats(), ...])
  • 返回值结构保持不变,调用方无需修改

P0-4messaging 绕过 notifications 直接写通知 已修复

messaging/actions.ts 原直接调用 createNotificationmessageNotifications 表,导致用户通知偏好失效、多渠道通知无效。notifications/data-access.tsin-app-channel.ts 反向依赖 messaging 模块。

修复方案(已实施):

  • messageNotifications 表的 CRUD 函数(createNotification / getNotifications / markNotificationAsRead / markAllNotificationsAsRead / getUnreadNotificationCount)从 messaging/data-access.ts 迁移到 notifications/data-access.ts
  • notificationPreferences 表的 CRUD 函数(getNotificationPreferences / upsertNotificationPreferences)从 messaging/notification-preferences.ts 迁移到新文件 notifications/preferences.ts
  • NotificationType / Notification / NotificationPreferences / UpdateNotificationPreferencesInput / CreateNotificationInput / GetNotificationsParams / PaginatedResult 类型从 messaging/types.ts 迁移到 notifications/types.ts
  • notifications/channels/in-app-channel.ts 改为静态导入本地 createNotification(不再动态 import messaging
  • notifications/dispatcher.ts 改为从 notifications/preferences.ts 导入 getNotificationPreferences(不再通过 getUserNotificationPreferences 包装器反向依赖 messaging
  • messaging 模块通过 re-export 保持向后兼容:messaging/data-access.ts re-export 通知 CRUDmessaging/notification-preferences.ts 转为 re-export shimmessaging/types.ts re-export 通知类型
  • 依赖方向变为单向messaging → notificationsmessaging 调用 sendNotification dispatcher 发送通知)

P0-5classSchedule 表三处写入口 已修复

  • classes/data-access.tscreateClassScheduleItem 等)
  • scheduling/actions.tsapplyAutoScheduleAction 直接 transaction 写入)
  • scheduling/data-access.ts(间接)

影响:数据完整性高风险。

修复方案(已实施):

  • 将 classSchedule 写函数(createClassScheduleItem / updateClassScheduleItem / deleteClassScheduleItem)从 classes/data-access-schedule.ts 迁移到新文件 scheduling/data-access-class-schedule.ts
  • classes 模块仅保留 READ 函数(getStudentSchedule / getClassSchedule),不再有任何 classSchedule 写入口
  • scheduling 模块通过 classes/data-access.verifyTeacherOwnsClass 跨模块校验教师班级归属(合理依赖)
  • classes/actions.ts 改为从 @/modules/scheduling/data-access-class-schedule 导入写函数
  • 类型 CreateClassScheduleItemInput / UpdateClassScheduleItemInputclasses/types.ts 迁移到 scheduling/types.ts
  • 所有 classSchedule DB 写入统一由 scheduling 模块管理(insertClassScheduleItem / updateClassScheduleItemById / deleteClassScheduleItemById / replaceClassSchedule

P0-6proctoring 死代码与重复实现

  • exam-mode-config.tsx 未集成到考试表单(监考功能无法启用)
  • 事件上报存在 Server Action 与 REST API 双通道重复 已修复

修复方案(已实施):

  • src/app/api/proctoring/event/route.ts 移至 deletes/api/proctoring/event/route.ts,消除事件上报的 REST API 重复通道
  • Server Action recordProctoringEventActionproctoring/actions.ts)为唯一规范路径
  • exam-mode-config.tsx 暂保留原位(集成到考试表单属于功能新增,不在本次修复范围)

3.2 P1 较严重问题(短期执行)

P1-1跨模块直接 DB 查询普遍存在 已修复

被访问表 访问次数 应归属模块 主要违规者
classes 8+ classes exams/homework/grades/dashboard 已改为通过 classes data-access
classEnrollments 6+ classes homework/grades/attendance/users 已改为通过 classes data-access
users 6+ users 多个模块已改为通过 users data-access
subjects 6+ school exams/homework/questions/grades 已改为通过 school data-access
exams 5+ exams homework/grades/dashboard/classes 已改为通过 exams data-access
homeworkAssignments 5+ homework classes反向直查已改为通过 homework/data-access-classes

修复方案(已实施):

  • 各模块 data-access 暴露查询接口:
    • classes/data-accessgetClassGradeIdsByClassIds 已实现 / getClassStudentsByClassId / getActiveClassStudents / getClassExists / getClassNameById / getClassNamesByIds / getActiveStudentIdsByClassId / getStudentActiveClassId / getClassesByGradeId / verifyTeacherOwnsClass / getTeacherIdForMutations
    • exams/data-accessgetExamForHomeworkCreation 已实现(getExamIdsByGradeIds / getExamSubjectIdMap / getExamWithQuestionsForHomework / getExamSubmissionWithAnswers / getExamForProctoringCrossModule / getExamSubmissionForProctoringCrossModule / getExamSubmissionsForExam / getExamTitleById
    • school/data-accessgetSubjectOptions / getGradeOptions 已实现
    • users/data-accessgetUserNameByIds / getStudentInfo 已实现(getUserNamesByIds / getUserWithRole / getUserBasicInfo / getUserIdsByGradeId / getCurrentStudentUser
    • textbooks/data-accessgetKnowledgePointOptions 已实现
    • questions/data-accessinsertQuestionWithRelations 已通过 createQuestionWithRelations 供 exams 调用 / getKnowledgePointsForQuestions
    • homework/data-access-classes 新增 7 个函数供 classes 模块跨模块调用

P1-2actions 层混入数据访问逻辑 已修复

已完成修复2026-06-17commit 84d66364 个模块的 actions 层 DB 操作全部下沉到 data-access

模块 问题 Action 修复内容
exams updateExamAction / deleteExamAction / duplicateExamAction / getExamPreviewAction / getSubjectsAction / getGradesAction 新增 7 个 data-access 函数getExamCreatorId/updateExamWithQuestions/deleteExamById/duplicateExam/getExamPreview/getExamSubjects/getExamGradesactions.ts 831→691 行data-access.ts 374→471 行
homework createHomeworkAssignmentAction157 行)/ startHomeworkSubmissionAction / saveHomeworkAnswerAction / submitHomeworkAction / gradeHomeworkSubmissionAction 新建 data-access-write.ts285 行10 个写函数actions.ts 387→239 行
questions createQuestionAction / updateQuestionAction / deleteQuestionAction / getKnowledgePointOptionsAction 新增 4 个 data-access 函数createQuestionWithRelations/updateQuestionById/deleteQuestionByIdRecursive/getKnowledgePointOptionsactions.ts 294→149 行data-access.ts 138→260 行
announcements 所有写操作 Action 新增 5 个 data-access 函数insertAnnouncement/updateAnnouncementById/deleteAnnouncementById/publishAnnouncementById/archiveAnnouncementByIdactions.ts 242→197 行data-access.ts 120→171 行

剩余未修复模块(不在本次 P1-2 范围):

  • usersupdateUserProfileAction 直接 db.update 已下沉到 data-accessP1-1 修复)
  • schedulingapplyAutoScheduleAction / autoScheduleAction 直接 db.transaction + db.select 已改为调用 replaceClassSchedule 统一写入口;autoScheduleAction 直查 users 表已改为通过 users data-accessP0-5 / P1-1 修复)

P1-3auth.ts 混合 5 类职责 已完成

src/auth.ts 原 293 行混合NextAuth 配置 + 密码安全 DB 操作 + 角色规范化 + IP 解析 + 回调函数。

已完成拆分auth.ts 现 193 行,仅保留 NextAuth 配置):

  • 密码安全 DB 操作 → shared/lib/password-security-service.tsgetOrCreatePasswordSecurity / recordFailedLogin / resetFailedLoginserver-only
  • 角色规范化 → shared/lib/role-utils.tsnormalizeRole / resolvePrimaryRole纯函数
  • bcrypt 哈希规范化 → shared/lib/bcrypt-utils.tsnormalizeBcryptHash纯函数
  • IP 解析 → shared/lib/http-utils.tsresolveClientIpserver-only

后续可选优化(未执行,需保持 NextAuth 配置不变原则下评估):

  • authorize 回调可进一步拆分为 checkRateLimit / checkAccountLockout / verifyPassword / loadUserRoles,使 auth.ts 降至 ≤150 行

P1-4users/import-export.ts 四重职责 已完成

users/import-export.ts 原 291 行混合:导入解析 + 导出 + 用户创建(含密码哈希)+ 班级注册(跨模块写 classEnrollments

已完成拆分import-export.ts 现 157 行,仅保留文件解析/生成):

  • 用户创建(含密码哈希、角色分配)→ user-service.tsbatchImportUsers82 行server-only
  • 班级注册 → class-registration.tsregisterStudentByInvitationCode21 行server-only
  • batchImportUsers 不再直写 classEnrollments,改为调用 classes/data-access.enrollStudentByInvitationCode
  • import-export.ts 通过 re-export batchImportUsers / UserImportResult 保持向后兼容(actions.tsapp/api/export/route.ts 无需修改)

P1-5notifications 反向依赖 messaging 已完成

notifications/data-access.tsin-app-channel.ts 原反向依赖 messaging 模块的偏好和 createNotification。

已完成修复(与 P0-4 一并解决):

  • messageNotificationsnotificationPreferences 表所有权移交 notifications 模块
  • notifications/data-access.ts 不再 import messaging 模块
  • notifications/channels/in-app-channel.ts 改为静态导入本地 createNotification(不再动态 import messaging
  • notifications/dispatcher.ts 改为从本地 preferences.ts 导入偏好函数
  • messaging 模块通过 re-export 保持向后兼容

P1-6三个 logger 重复实现 IP/Header 提取 已修复

audit-logger.ts / change-logger.ts / login-logger.ts / auth.ts 四处重复实现 IP/User-Agent 提取逻辑,且实现略有差异。

修复方案(已实施):

  • shared/lib/http-utils.ts 新增 getUserAgent() 函数(与已有 resolveClientIp() 配套)
  • audit-logger.ts / change-logger.ts / login-logger.ts 改为从 @/shared/lib/http-utils 导入 resolveClientIpgetUserAgent,删除本地重复实现
  • auth.ts 已在 P1-3 中改用 resolveClientIp
  • 四处实现统一,消除不一致风险(resolveClientIpx-forwarded-for 第一段,更准确)

3.3 P2 代码质量问题(机会修复)

序号 问题 模块
P2-1 exams/ai-pipeline.ts 857 行,混合 4 类职责 exams
P2-2 exams/actions.ts 832 行(超 800 建议) 已修复P1-2 后降至 691 行) exams
P2-3 shared/lib/ai.ts 218 行,混合 5 类职责 已修复P2-2 已拆分为 ai/ 目录) shared
P2-4 onboarding-gate.tsx 业务逻辑泄漏到 shared shared
P2-5 global-search.tsx 业务类型硬编码在 shared shared
P2-6 proxy.ts 硬编码权限字符串,未复用 Permissions 常量 proxy
P2-7 useA11yId Hook 错放在 lib/ 而非 hooks/ shared
P2-8 schema.ts 分节编号混乱section 12 出现在 14b 之后) shared/db
P2-9 audit/actions.ts Excel 导出逻辑内联 audit
P2-10 school 模块审计日志不一致(仅 school 实体记录) school
P2-11 announcements 死代码 void wasPublished announcements
P2-12 announcements 权限模式不一致requireAuth vs requirePermission 已修复 announcements
P2-13 files try-catch 吞错误 files
P2-14 elective runLottery 使用 Math.random elective
P2-15 elective selectCourse FCFS 并发超卖风险 elective
P2-16 diagnostic 班级报告 studentId 字段复用 diagnostic
P2-17 layout 用权限反推角色 layout
P2-18 scheduling/actions.ts 末尾 re-export data-access scheduling
P2-19 ExamAssembly / ExamPreviewQuestionEditor 10 个 props exams
P2-20 homework/data-access.getDemoStudentUser 使用 auth() 而非 auth-guard 已修复(已迁移至 users/data-access.getCurrentStudentUser6 个 student 页面改用 users 模块;elective 页面改用 getAuthContext()homework 保留 re-export 向后兼容) homework

3.4 解耦优先级路线图

立即执行P0

  1. 拆分 classes/data-access.ts2104 行 → 按职责拆 3-4 个文件) 已完成(拆为 5 个文件data-access.ts 548行 + data-access-stats.ts 531行 + data-access-schedule.ts 194行 + data-access-students.ts 244行 + data-access-admin.ts 406行
  2. 拆分 homework/data-access.ts1038 行 → 分离排名逻辑) 已完成(拆为 data-access.ts 598行 + stats-service.ts 425行
  3. 修复 shared/libauth 循环依赖 已完成(新增 shared/lib/session.ts 单一入口3 个 shared/lib 文件改为通过 getSession 获取 sessiondynamic import 打破静态循环)
  4. dashboard 改为通过各模块 data-access 获取数据 已完成P0-3 修复:并行调用各模块 dashboard stats 函数)
  5. messaging 写通知改为通过 notifications dispatcher 已完成P0-4 / P1-5 修复:通知 CRUD 和偏好迁移至 notifications 模块messaging 通过 dispatcher 发送通知)
  6. 统一 classSchedule 写入口到 scheduling 模块 已完成P0-5 修复classSchedule 写函数从 classes/data-access-schedule.ts 迁移至 scheduling/data-access-class-schedule.tsclasses 模块仅保留读函数)
  7. 集成 proctoring/exam-mode-config 到考试表单 部分完成P0-6 修复:删除重复的 /api/proctoring/event REST 路由Server Action 为唯一规范路径exam-mode-config.tsx 集成属于功能新增,暂保留原位)

短期执行P1

  1. actions 层移除直接 DB 操作exams/homework/questions/announcements/users/scheduling 已完成(全部 6 个模块均已修复)
  2. 拆分 auth.ts 已完成4 个辅助函数组迁移至 shared/libauth.ts 保留 NextAuth 配置)
  3. 拆分 users/import-export.ts 已完成(拆为 import-export.ts 157行 + user-service.ts 82行 + class-registration.ts 21行班级注册改为调用 classes/data-access
  4. 消除 notifications → messaging 反向依赖 已完成P0-4 / P1-5 修复:通知表所有权迁移至 notificationsin-app-channel 改为静态导入)
  5. 提取 shared/lib/http-utils.ts 统一 IP 提取 已完成(新增 getUserAgent,三个 logger 统一复用 resolveClientIp / getUserAgent
  6. 各模块暴露跨模块查询接口(见 P1-1 已完成(所有跨模块直查已改为通过对方 data-access 接口)

中期执行P2

  1. 建立模块间数据访问规范(通过对方 data-access 或导出查询函数) 已完成P1-1 修复)
  2. schema.ts 按业务域分节
  3. 拆分 exams/ai-pipeline.ts
  4. 拆分 shared/lib/ai.ts 已完成P2-2commit 6588f74拆分为 ai/ 目录 6 个文件,原 ai.ts 保留为重导出)
  5. shared 层业务逻辑下沉到 modules 层
  6. 代码质量问题逐项修复( 大部分已修复React.cache 包装、Promise.all 并行化、错误吞没清理、非空断言清理、函数返回类型补齐、重复代码提取、合并 filter 遍历、Set/Map 优化)

3.5 标杆实践(建议推广)

实践 模块 说明
算法纯函数化 scheduling/auto-scheduler.ts 无 DB 依赖,可独立测试,应作为算法抽取模板
stats 文件拆分 attendance/data-access-stats.ts 统计逻辑独立成文件classes 应效仿
data-access 多文件拆分 grades/data-access*.ts 按职责拆分为 3 个文件CRUD/分析/排名)
actions 辅助函数 course-plans/actions.ts handleError / revalidatePlanPaths 消除重复
actions 编排模式 textbooks/actions.ts 权限校验 → 调用 data-access → revalidatePath标杆
DataScope 接入 attendance/actions.ts 6 种数据范围完整支持
权限统一接入 school / attendance / course-plans 全部 Action 使用 requirePermission
跨模块解耦 grades 通过外键引用 exams/homework不直接访问其表
渠道抽象 notifications/channels/ 接口 + 工厂 + Mock 实现

附录 A模块间依赖矩阵

行表示使用方,列表示被使用方。 合理依赖, 违规直查, 循环依赖。 P1-1 已修复:所有跨模块直查已改为通过对方 data-access 接口。

↓ 使用 → shared auth exams homework questions textbooks classes school dashboard users grades messaging notifications lesson-prep 其他
shared - 已修复 - - - - - - - - - - - - -
auth(root) db/lib - - - - - - - - - - - - - -
exams - - data-access - data-access data-access - - - - - - -
homework data-access - 关系 - data-access data-access - data-access - - - - -
questions - - - data-access - - - - - - - - -
textbooks - - UI - - - - - - - - - -
classes data-access data-access - - - data-access - - - - - - schedulingP0-5data-access-class-schedule 写函数)
school - - - - - - - ⚠️可接受 - - - - -
grades 外键 外键 - - data-access data-access - data-access - - - - -
dashboard data-access data-access data-access data-access data-access - - data-access - - - - -
users - - - - data-access - - - - - - - -
messaging - - - - - - - - - - dispatcher - -
notifications - - - - data-access - - - - - - - -
attendance - - - - data-access - - - - - - - -
scheduling - - - - data-access - - data-access - - - - -
proctoring data-access - - - - - - data-access - - - - -
diagnostic data-access - data-access - data-access - - data-access - - - - -
parent - data-access - - data-access data-access - data-access data-access - - - -
elective - - - - data-access data-access - data-access - - - - -
course-plans - - - - - - - - - -
audit - - - - - - - - - - - - -
announcements - - - - - - - - - - - -
files - - - - - - - - - - - - -
settings - - - - - - - - - - - -
layout - - - - - - - - - - - -
lesson-preparation data-access data-access data-access data-access data-access - - - - - - - files/ai

附录 B关键参数影响链

userId

  1. auth.ts JWT callback 从 users 表查询产生,存入 JWT
  2. 通过 session.user.id 传递到所有 Server/Client Components
  3. 通过 getAuthContext().userId 传递到所有 Server Actions
  4. auth-guard.ts 中用于查询 usersToRoles(角色)和 classSubjectTeachers/gradesDataScope
  5. exams/actions.ts 中作为 creatorId 写入 exams
  6. homework/actions.ts 中作为 creatorId 写入 homeworkAssignments
  7. classes/data-access.ts 中查询 getTeacherClasses(teacherId) / getGradeManagedClasses(userId)
  8. elective/actions.ts 中作为 teacherId/studentId 用于选课过滤

examId

  1. exams/actions.createExamAction 产生CUID2写入 exams
  2. exams/data-access.getExamById(id) 读取
  3. exams/actionsupdateExamAction/deleteExamAction/duplicateExamAction 用于定位考试
  4. 传入 homework/actions.createHomeworkAssignmentActionsourceExamId 参数
  5. homeworkAssignments 表中作为外键关联到源考试
  6. homework/data-access.getHomeworkAssignmentAnalytics 用于追溯作业来源

classId

  1. classes/actionscreateTeacherClassAction/createAdminClassAction 产生
  2. classes/data-access.getClassStudents(classId) 读取学生列表
  3. classes/data-access.getClassSchedule(classId) 读取课表
  4. classes/data-access.getClassHomeworkInsights(classId) 读取作业洞察( P0-7 已修复:通过 homework/data-access-classes 获取数据)
  5. homework/data-access.getHomeworkAssignments({ classId }) 过滤作业列表
  6. auth-guard.ts 中通过 classSubjectTeachers 查询教师关联的 classIds构建 DataScope.class_taught

permission

  1. shared/types/permissions.tsPermissions 常量定义54 个权限点)
  2. shared/lib/permissions.ts 中通过 ROLE_PERMISSIONS 映射角色到权限列表
  3. auth.ts JWT callback 中通过 resolvePermissions(roleNames) 合并多角色权限,存入 JWT
  4. proxy.ts middleware 中通过 token.permissions 检查路由访问权限
  5. shared/lib/auth-guard.ts 中通过 requirePermission(permission) 在 Server Action 层断言权限
  6. shared/hooks/use-permission.ts 中通过 hasPermission(permission) 在客户端组件中条件渲染
  7. layout/config/navigation.ts 中作为 NavItem.permission 字段过滤侧边栏菜单

DataScope

  1. auth-guard.tsresolveDataScope(userId, roles) 根据用户角色和 DB 关系动态计算
  2. 支持类型:all / grade_managed / class_taught / class_members / children / owned
  3. 传递到 exams/homework/grades/attendance/elective/dashboard 的 data-access 进行行级过滤
  4. 对 parent 角色,查询 parentStudentRelations 表构建 { type: "children", childrenIds: string[] }
  5. parent/children/[studentId]/page.tsx 中通过 ctx.dataScope.childrenIds.includes(studentId) 二次校验

附录 C核心函数签名索引

完整函数签名见 005_architecture_data.json。本附录仅列出关键函数。

shared 层核心函数

// shared/lib/auth-guard.ts
getAuthContext(): Promise<AuthContext>
requirePermission(permission: Permission): Promise<AuthContext>
requireAuth(): Promise<AuthContext>
checkPermission(permission: Permission): Promise<{ allowed: boolean; ctx: AuthContext }>
resolveDataScope(userId: string, roleNames: string[]): Promise<DataScope>

// shared/lib/permissions.ts
resolvePermissions(roleNames: string[]): Permission[]

// shared/lib/audit-logger.ts
logAudit(params: LogAuditParams): Promise<void>

// shared/lib/login-logger.ts
logLoginEvent(params: LogLoginEventParams): Promise<void>

// shared/lib/change-logger.ts
logDataChange(params: LogDataChangeParams): Promise<void>

// shared/lib/session.ts (P0-2 新增session 获取单一入口)
getSession(): Promise<AppSession>

// shared/lib/http-utils.ts (P1-6 完成,统一 IP/UA 提取)
resolveClientIp(): Promise<string>
getUserAgent(): Promise<string>

// shared/lib/ai/ (P2-2 已拆分,原 ai.ts 保留为重导出)
// ai/client.ts
createAiChatCompletion(input: AiChatRequest): Promise<{ content, usage }>
// ai/payload-parser.ts
parseAiChatPayload(body: unknown): AiChatRequest
// ai/api-key-crypto.ts
encryptAiApiKey(value: string): string
decryptAiApiKey(value: string): string

// shared/lib/password-policy.ts
validatePassword(password: string): { valid: boolean; errors: string[] }
getPasswordStrength(password: string): "weak" | "medium" | "strong"
isAccountLocked(failedAttempts: number, lastFailedAt: Date | null): boolean

// shared/lib/rate-limit.ts
rateLimit(params: { key: string; limit: number; windowMs: number }): RateLimitResult
rateLimitKey(prefix: string, identifier: string): string
rateLimitHeaders(result: RateLimitResult): Record<string, string>

// shared/lib/excel.ts
exportToExcel(params: { sheets: ExcelSheet[] }): Promise<Buffer>
parseExcel(buffer: Buffer): Promise<ParsedSheet[]>
generateTemplate(params: { sheets: TemplateSheet[] }): Promise<Buffer>

// shared/lib/file-storage.ts
isAllowedMimeType(mimeType: string): boolean
generateStoragePath(originalName: string): string
formatFileSize(bytes: number): string

// shared/lib/utils.ts
cn(...inputs: ClassValue[]): string
formatDate(date: string | Date, locale?: string): string

业务模块核心 Actions

// exams/actions.ts
createExamAction(prevState: ActionState, formData: FormData): Promise<ActionState<Exam>>
createAiExamAction(prevState: ActionState, formData: FormData): Promise<ActionState<{ examId: string }>>
updateExamAction(prevState: ActionState, formData: FormData): Promise<ActionState>
deleteExamAction(prevState: ActionState, formData: FormData): Promise<ActionState>
duplicateExamAction(prevState: ActionState, formData: FormData): Promise<ActionState<{ examId: string }>>

// homework/actions.ts
createHomeworkAssignmentAction(prevState: ActionState, formData: FormData): Promise<ActionState>
startHomeworkSubmissionAction(prevState: ActionState, formData: FormData): Promise<ActionState<{ submissionId: string }>>
saveHomeworkAnswerAction(prevState: ActionState, formData: FormData): Promise<ActionState>
submitHomeworkAction(prevState: ActionState, formData: FormData): Promise<ActionState>
gradeHomeworkSubmissionAction(prevState: ActionState, formData: FormData): Promise<ActionState>

// classes/actions.ts
createTeacherClassAction(prevState: ActionState, formData: FormData): Promise<ActionState>
createAdminClassAction(prevState: ActionState, formData: FormData): Promise<ActionState>
createGradeClassAction(prevState: ActionState, formData: FormData): Promise<ActionState>
// + update/delete 各 3 个,共 9 个

// grades/actions.ts
getGradeRecordsAction(params: GetGradeRecordsParams): Promise<ActionState<GradeRecord[]>>
createGradeRecordAction(prevState: ActionState, formData: FormData): Promise<ActionState>
exportGradesAction(params: ExportGradesParams): Promise<ActionState<Buffer>>

// scheduling/actions.ts
autoScheduleAction(prevState: ActionState, formData: FormData): Promise<ActionState>
applyAutoScheduleAction(prevState: ActionState, formData: FormData): Promise<ActionState>

业务模块核心 Data-access

// exams/data-access.ts
getExams(params: GetExamsParams & { scope: DataScope }): Promise<{ items: Exam[]; total: number }>
getExamById(id: string, scope: DataScope): Promise<Exam | null>
persistExamDraft(input: ExamDraftInput): Promise<{ examId: string }>
persistAiGeneratedExamDraft(input: AiExamDraftInput): Promise<{ examId: string }>

// homework/data-access.ts
getHomeworkAssignments(params: GetHomeworkAssignmentsParams & { scope: DataScope }): Promise<{ items, total }>
getStudentHomeworkAssignments(studentId: string): Promise<StudentHomeworkAssignment[]>
getStudentDashboardGrades(studentId: string): Promise<StudentDashboardGrades>
getHomeworkAssignmentAnalytics(assignmentId: string): Promise<HomeworkAnalytics>

// classes/data-access.ts
getAdminClasses(scope: DataScope): Promise<Class[]>
getTeacherClasses(teacherId: string): Promise<Class[]>
getStudentClasses(studentId: string): Promise<Class[]>
getClassStudents(classId: string): Promise<Student[]>
getClassHomeworkInsights(classId: string): Promise<ClassHomeworkInsights>  // ✅ P0-7 已修复:通过 homework/data-access-classes 获取数据

// grades/data-access.ts
getGradeRecords(params: GetGradeRecordsParams & { scope: DataScope }): Promise<GradeRecord[]>
getStudentGradeSummary(studentId: string): Promise<StudentGradeSummary>
getClassRanking(classId: string, examId?: string): Promise<ClassRanking[]>

// scheduling/auto-scheduler.ts纯函数标杆
findOptimalSlot(input: FindOptimalSlotInput): ScheduleSlot | null
validateSchedule(schedule: ScheduleItem[]): ValidationResult
autoSchedule(input: AutoScheduleInput): AutoScheduleResult
buildDefaultTimeSlots(): TimeSlot[]

文档维护说明

  • 修改源码后:同步更新本文档对应模块章节 + 005_architecture_data.json
  • 新增模块:在第二部分添加模块清单 + 更新 1.1 分层架构图 + 更新附录 A 依赖矩阵
  • 新增/删除导出函数:更新对应模块的"导出函数"清单 + 附录 C
  • 修改依赖关系:更新 1.2 模块依赖关系图 + 附录 A 依赖矩阵
  • 新增路由:更新 005_architecture_data.jsonroutes 节点
  • 新增数据库表:更新 shared/db/schema.ts 分节 + 005dbTables 节点

完整路由表、DevOps 脚本、E2E 测试等信息见 005_architecture_data.json