Files
NextEdu/docs/architecture/004_architecture_impact_map.md
SpecialX b86255f0ea feat(P2): 实现选课管理、考试监考、学情诊断三大功能模块
## 新增功能模块

### 1. 选课管理(elective)
- 新增表:electiveCourses、courseSelections
- 新增权限:ELECTIVE_MANAGE/ELECTIVE_READ/ELECTIVE_SELECT
- 支持先到先得 + 抽签两种选课模式
- admin/teacher/student 三端页面

### 2. 考试监考(proctoring)
- exams 表扩展:examMode/durationMinutes/antiCheatEnabled 等字段
- 新增表:examProctoringEvents
- 新增权限:EXAM_PROCTOR/EXAM_PROCTOR_READ
- 教师监考面板 + 学生端防作弊监控
- API:/api/proctoring/event 接收事件上报

### 3. 学情诊断报告(diagnostic)
- 新增表:knowledgePointMastery、learningDiagnosticReports
- 新增权限:DIAGNOSTIC_MANAGE/DIAGNOSTIC_READ
- 基于提交答案自动计算知识点掌握度
- 生成个人/班级诊断报告(强项/弱项/建议)
- 雷达图可视化

## 其他改动
- 项目规则:单文件行数限制从 300 行调整为企业级规范(组件≤500/Actions≤800/硬上限1000)
- scripts/seed.ts:消除全部 any 类型,定义内部类型,0 lint 错误
- 架构文档 004/005 同步更新三个新模块
- 迁移文件 0001_heavy_sage.sql 生成

## 验证
- npx tsc --noEmit:0 错误
- npm run lint:0 错误 0 警告
2026-06-17 19:12:51 +08:00

179 KiB
Raw Blame History

Next_Edu 架构影响地图

全模块·全函数·全参数级别 生成日期2026-06-16 规则:每次文件修改后须同步更新本文档


模块shared

模块职责

提供全项目共享的基础设施数据库连接、Schema、工具函数、权限系统、UI 基础组件、通用 Hooks。

导出函数

cn

  • 签名:cn(...inputs: ClassValue[]): string
  • 参数说明:
    • inputs: ClassValue[],来自 clsx + tailwind-mergeCSS 类名列表
  • 功能:合并 CSS 类名并解决 Tailwind 冲突
  • 依赖:clsx, tailwind-merge
  • 被以下模块使用:所有模块的组件50+ 文件)

formatDate

  • 签名:formatDate(date: string | Date, locale?: string): string
  • 参数说明:
    • date: string | Date日期值
    • locale: string默认 "zh-CN"Intl.DateTimeFormat 的 locale
  • 功能:国际化日期格式化
  • 依赖:无
  • 被以下模块使用exams, homework, dashboard, textbooks

parseAiChatPayload

  • 签名:parseAiChatPayload(body: unknown): AiChatRequest
  • 参数说明:body: unknownHTTP 请求体
  • 功能:解析并校验 AI 聊天请求负载
  • 依赖Zod schema
  • 被以下模块使用:app/api/ai/chat/route.ts

encryptAiApiKey / decryptAiApiKey

  • 签名:(value: string) => string
  • 功能AES 加密/解密 AI Provider API Key
  • 依赖:crypto (Node.js 内置)
  • 被以下模块使用settings (存储/读取 API Key)

testAiProviderConfig / testAiProviderById

  • 签名:(input: { apiKey, baseUrl?, model }) => Promise<boolean> / (providerId, overrides?) => Promise<boolean>
  • 功能:测试 AI Provider 连通性
  • 依赖:createAiChatCompletion, shared/db
  • 被以下模块使用settings/actions.ts

createAiChatCompletion

  • 签名:(input: AiChatRequest) => Promise<{ content, usage }>
  • 功能:调用 AI 模型生成聊天回复
  • 依赖OpenAI SDK, shared/db (读取 provider 配置)
  • 被以下模块使用exams/ai-pipeline.ts, app/api/ai/chat/route.ts

getAuthContext

  • 签名:getAuthContext(): Promise<AuthContext>
  • 功能获取当前用户的完整认证上下文userId, roles, permissions, dataScope
  • 依赖:auth (NextAuth), shared/db (查询角色/班级/年级关系)
  • 被以下模块使用:所有业务模块的 Server Actions

requirePermission

  • 签名:requirePermission(permission: Permission): Promise<AuthContext>
  • 参数说明:permission: Permission来自 shared/types/permissions 的权限常量
  • 功能:断言当前用户拥有指定权限,否则抛出 PermissionDeniedError
  • 依赖:getAuthContext
  • 被以下模块使用:所有业务模块的 Server Actionsexams, homework, questions, textbooks, classes, school, settings, audit, announcements, files, grades, attendance

checkPermission

  • 签名:checkPermission(permission: Permission): Promise<{ allowed: boolean; ctx: AuthContext }>
  • 功能:非抛出版权限检查
  • 依赖:getAuthContext
  • 被以下模块使用:待扩展

requireAuth

  • 签名:requireAuth(): Promise<AuthContext>
  • 功能:仅断言用户已登录
  • 依赖:getAuthContext
  • 被以下模块使用:待扩展

resolvePermissions

  • 签名:resolvePermissions(roleNames: string[]): Permission[]
  • 参数说明:roleNames: string[],用户的角色名称列表
  • 功能:合并多角色的权限列表(去重)
  • 依赖:ROLE_PERMISSIONS 常量
  • 被以下模块使用auth.ts (JWT callback)

logAudit

  • 签名:logAudit(params: LogAuditParams): Promise<void>
  • 参数说明:params: LogAuditParams含 userId, userName, action, module, targetId?, targetType?, detail?, status?
  • 功能:记录操作日志(静默失败,不影响主流程)
  • 依赖:auth (NextAuth), shared/db (auditLogs 表), next/headers
  • 被以下模块使用school/actions.ts其他 Server Actions

logLoginEvent

  • 签名:logLoginEvent(params: LogLoginEventParams): Promise<void>
  • 参数说明:params: LogLoginEventParams含 userId?, userEmail, action (signin/signout/signup), status, errorMessage?
  • 功能:记录登录日志(不依赖 auth 上下文,可在 NextAuth events 中调用,静默失败)
  • 依赖:shared/db (loginLogs 表), next/headers
  • 被以下模块使用auth.ts (events.signIn, events.signOut)

isAllowedMimeType

  • 签名:isAllowedMimeType(mimeType: string): boolean
  • 功能:判断 MIME 类型是否在允许上传的白名单中
  • 依赖:ALLOWED_MIME_TYPES 常量
  • 被以下模块使用:app/api/upload/route.ts, files/components/file-upload.tsx

generateStoragePath

  • 签名:generateStoragePath(originalName: string): string
  • 功能:根据原始文件名生成存储路径 uploads/YYYY-MM/cuid.ext(相对于 public/
  • 依赖:@paralleldrive/cuid2
  • 被以下模块使用:app/api/upload/route.ts

getFileExtension

  • 签名:getFileExtension(filename: string): string
  • 功能:从文件名中提取小写扩展名(不含点)
  • 被以下模块使用:shared/lib/file-storage 内部

formatFileSize

  • 签名:formatFileSize(bytes: number): string
  • 功能:将字节数格式化为人类可读字符串(如 1.5 MB800 KB
  • 被以下模块使用files/components/file-upload.tsx, file-list.tsx, file-preview.tsx

exportToExcel

  • 签名:exportToExcel(params: { sheets: ExcelSheet[] }): Promise<Buffer>
  • 参数说明:sheets: ExcelSheet[],每个含 name/columns/rows
  • 功能:将多 sheet 数据导出为 Excel Buffer表头加粗+冻结首行+自动筛选)
  • 依赖:exceljs
  • 被以下模块使用users/import-export.exportUsersToExcel, grades/export.exportGradeRecordsToExcel, grades/export.exportClassGradeReportToExcel

parseExcel

  • 签名:parseExcel(buffer: Buffer): Promise<ParsedSheet[]>
  • 返回ParsedSheet[],每个含 sheetName/rows
  • 功能:从 Buffer 解析 Excel 文件,首行作为表头,返回每 sheet 的行记录数组
  • 依赖:exceljs
  • 被以下模块使用users/actions.importUsersAction, app/api/import/route.ts

generateTemplate

  • 签名:(params: { sheets: TemplateSheet[] }): Promise<Buffer>
  • 参数说明:sheets: TemplateSheet[],每个含 name/columns(含 note)/sampleRows?
  • 功能:生成导入模板 Buffer表头加粗+第二行填写说明+示例行)
  • 依赖:exceljs
  • 被以下模块使用users/import-export.generateUserImportTemplate

validatePassword

  • 签名:(password: string) => { valid: boolean; errors: string[] }
  • 功能:校验密码是否符合策略(最小长度、大小写、数字等)
  • 依赖:PASSWORD_RULES 常量
  • 被以下模块使用settings/actions-password.changePasswordAction, auth.ts

getPasswordStrength

  • 签名:(password: string) => "weak" | "medium" | "strong"
  • 功能:基于长度和字符多样性计算密码强度等级(纯函数,可在客户端使用)
  • 依赖:无
  • 被以下模块使用settings/components/password-change-form.tsx

isAccountLocked

  • 签名:(failedAttempts: number, lastFailedAt: Date | null) => boolean
  • 功能:判断账户是否应被锁定(失败次数达阈值且锁定时间未过期)
  • 依赖:PASSWORD_RULES.maxLoginAttempts, PASSWORD_RULES.lockoutDurationMinutes
  • 被以下模块使用auth.ts (authorize callback)

getRemainingLockoutMs

  • 签名:(failedAttempts: number, lastFailedAt: Date | null) => number
  • 功能计算剩余锁定时间毫秒0 表示已解锁)
  • 依赖:isAccountLocked
  • 被以下模块使用:待扩展

rateLimit

  • 签名:(params: { key: string; limit: number; windowMs: number }) => { success: boolean; remaining: number; resetTime: number; retryAfterMs: number }
  • 功能:内存滑动窗口限流检查(单实例,多实例需替换为 @upstash/ratelimit
  • 依赖Map 存储)
  • 被以下模块使用auth.ts (LOGIN), settings/actions-password (PASSWORD_CHANGE), app/api/ai/chat (AI_CHAT), app/api/upload (UPLOAD), app/api/rate-limit-test

resetRateLimit

  • 签名:(key: string) => void
  • 功能:重置指定 key 的限流计数(如登录成功后清除失败计数)
  • 被以下模块使用auth.ts (成功登录后)

rateLimitKey

  • 签名:(prefix: string, identifier: string) => string
  • 功能:构建限流 keylogin:ip:email
  • 被以下模块使用auth.ts, settings/actions-password, app/api/ai/chat, app/api/upload

rateLimitHeaders

  • 签名:(result: RateLimitResult) => Record<string, string>
  • 功能:将限流结果转为 HTTP 响应头X-RateLimit-Limit/Remaining/Reset, Retry-After
  • 被以下模块使用app/api/ai/chat, app/api/upload, app/api/rate-limit-test

logDataChange

  • 签名:logDataChange(params: LogDataChangeParams): Promise<void>
  • 参数说明:params: LogDataChangeParams含 tableName, recordId, action ("create" | "update" | "delete"), oldValue?, newValue?
  • 功能:记录数据变更日志(写入 dataChangeLogs 表,自动从 NextAuth session 获取 changedBy/changedByName从 headers 获取 ipAddress静默失败不阻塞主流程
  • 依赖:auth (NextAuth), shared/db (dataChangeLogs 表), next/headers, @paralleldrive/cuid2
  • 被以下模块使用:待扩展(数据变更场景)

StorageProvider (接口)

  • 文件:lib/storage-provider.ts
  • 定义:文件存储抽象接口,方法 save(file, storagePath) => Promise<string>read(storagePath) => Promise<Buffer>delete(storagePath) => Promise<void>exists(storagePath) => Promise<boolean>getUrl(storagePath) => string
  • 功能:抽象文件持久化层,便于未来切换到 OSS/S3 而不修改调用方
  • 被以下模块使用:app/api/files/batch-delete/route.ts

LocalStorageProvider (类)

  • 文件:lib/storage-provider.ts
  • 实现:StorageProvider 接口,文件持久化到 public/uploads/...URL 为 /uploads/...
  • 依赖:fs/promises (mkdir/readFile/writeFile/unlink/access), path
  • 被以下模块使用:通过 storageProvider 实例使用

storageProvider (实例)

  • 文件:lib/storage-provider.ts
  • 类型:StorageProvider(默认为 LocalStorageProvider 实例)
  • 功能:默认存储 Provider 单例,替换此实例可迁移到 OSS/S3
  • 被以下模块使用:app/api/files/batch-delete/route.ts

导出常量与实例

Permissions (常量对象)

  • 文件:types/permissions.ts
  • 定义54 个权限常量(exam:create, homework:grade, audit_log:read, announcement:manage, file:upload, file:read, file:delete, grade_record:manage, grade_record:read, course_plan:manage, course_plan:read, attendance:manage, attendance:read, message:send, message:read, message:delete, schedule:auto, schedule:adjust, elective:manage, elective:read, elective:select, exam:proctor, exam:proctor_read, diagnostic:manage, diagnostic:read 等)
  • 被使用auth-guard.ts, 所有模块的 actions.ts, 前端组件

ROLE_PERMISSIONS (常量对象)

  • 文件:lib/permissions.ts
  • 定义角色到权限列表的映射admin/teacher/student/parent/grade_head/teaching_head
  • 课程计划权限admin 含 COURSE_PLAN_MANAGE+COURSE_PLAN_READteacher/student/grade_head/teaching_head 含 COURSE_PLAN_READ
  • 考勤权限admin/teacher 含 ATTENDANCE_MANAGE+ATTENDANCE_READstudent/parent/grade_head/teaching_head 含 ATTENDANCE_READ
  • 消息权限admin/teacher/grade_head/teaching_head 含 MESSAGE_SEND+MESSAGE_READ+MESSAGE_DELETEstudent/parent 含 MESSAGE_SEND+MESSAGE_READ
  • 排课权限admin 含 SCHEDULE_AUTO+SCHEDULE_ADJUSTteacher/student/parent/grade_head/teaching_head 无排课权限
  • 学情诊断权限admin/teacher/grade_head 含 DIAGNOSTIC_MANAGE+DIAGNOSTIC_READteaching_head/student 含 DIAGNOSTIC_READ
  • 被使用:resolvePermissions, auth.ts (JWT callback)

db (Drizzle 实例)

  • 文件:db/index.ts
  • 定义Drizzle ORM 客户端实例MySQL
  • 被使用:所有业务模块的 data-access.ts 和 actions.ts

questionTypeEnum

  • 文件:db/schema.ts (或 schema 枚举导出)
  • 定义:题目类型枚举(选择/填空/判断/复合等)
  • 被使用questions, exams, homework

classEnrollmentStatusEnum

  • 文件:db/schema.ts (或 schema 枚举导出)
  • 定义班级注册状态枚举active/inactive 等)
  • 被使用classes, homework

PASSWORD_RULES (常量对象)

  • 文件:lib/password-policy.ts
  • 定义密码策略配置minLength: 8, requireUppercase/Lowercase/Number: true, maxLoginAttempts: 5, lockoutDurationMinutes: 30
  • 被使用auth.ts, settings/actions-password.ts, password-change-form.tsx (via PASSWORD_REQUIREMENT_HINTS)

RATE_LIMIT_RULES (常量对象)

  • 文件:lib/rate-limit.ts
  • 定义预定义限流规则LOGIN: 5/15min, API: 100/min, UPLOAD: 10/min, AI_CHAT: 20/min, PASSWORD_CHANGE: 5/min
  • 被使用auth.ts (LOGIN), settings/actions-password (PASSWORD_CHANGE), app/api/ai/chat (AI_CHAT), app/api/upload (UPLOAD)

文件记录

db/relations.ts

  • 内容24+ Drizzle relations表间关系定义含 coursePlansRelations、coursePlanItemsRelations、attendanceRecordsRelations、attendanceRulesRelations
  • 被使用Drizzle ORM 关联查询(所有 data-access.ts

next-auth.d.ts

  • 内容NextAuth 类型扩展Session.user 增加 id/roles/permissions 等字段)
  • 被使用auth.ts, 所有使用 useSession/auth() 的代码

导出组件

AuthSessionProvider

  • Props: { children: React.ReactNode }
  • 内部使用:next-auth/reactSessionProvider
  • 被使用:app/layout.tsx

OnboardingGate

  • Props: 无(内部使用 useSession
  • 内部使用:useSession, Permissions, 多个 Server Action
  • 功能:新用户引导流程(角色选择、学校/班级配置)
  • 被使用:app/layout.tsx

ThemeProvider

  • Props: next-themesThemeProviderProps
  • 被使用:app/layout.tsx

EmptyState

  • 文件:components/ui/empty-state.tsx
  • Props: { icon?, title, description, action? }
  • 被使用exams, homework, questions, textbooks 等模块的列表空状态

GlobalSearch

  • 文件:components/global-search.tsx
  • Props: { className?, placeholder? }
  • 功能:全局搜索组件(防抖 300ms 调用 GET /api/searchCmd/Ctrl+K 快捷键聚焦Escape 关闭,↑/↓ 键盘导航Enter 跳转;下拉展示 question/textbook/exam/announcement 四类结果,点击外部自动关闭)
  • 内部使用:useDebounce, Input, Link, useRouter
  • 被使用:layout/components/site-header.tsx

Switch

  • 文件:components/ui/switch.tsx
  • 基于:@radix-ui/react-switch
  • Props: Radix Switch Root propschecked, onCheckedChange, disabled, id, aria-label 等)
  • 功能:开关切换 UI 组件shadcn 风格checked/unchecked 两态)
  • 被使用:settings/components/notification-preferences-form.tsx

导出 Hooks

useActionWithToast

  • 签名:useActionWithToast<T>(): { isPending, execute }
  • 功能:包装 Server Action + toast 反馈
  • 被使用:待扩展

useDebounce

  • 签名:useDebounce<T>(value: T, delay?: number): T
  • 被使用:搜索输入框等

useMediaQuery

  • 签名:useMediaQuery(query: string): boolean
  • 被使用:响应式布局判断

useLocalStorage

  • 签名:useLocalStorage<T>(key: string, initialValue: T): [T, setter]
  • 被使用exam-form (previewTaskStorageKey)

usePermission

  • 签名:usePermission(): { permissions, roles, hasPermission, hasAnyPermission, hasAllPermissions, hasRole }
  • 功能:客户端权限检查 Hook
  • 被使用layout/app-sidebar.tsx, exams/components, homework/components

类型/接口

ActionState<T>

  • 定义:{ success: boolean; message?: string; errors?: Record<string, string[]>; data?: T }
  • 被使用:所有模块的 Server Action 返回类型

Permission (类型)

  • 定义:Permissions 值的联合类型
  • 被使用auth-guard.ts, use-permission.ts

DataScope (联合类型)

  • 定义:{ type: "all" } | { type: "owned"; userId: string } | { type: "class_taught"; classIds: string[]; subjectIds?: string[] } | { type: "grade_managed"; gradeIds: string[] } | { type: "class_members" } | { type: "children"; childrenIds: string[] }
  • 被使用auth-guard.ts, exams/data-access.ts, homework/data-access.ts, dashboard/data-access.ts

AuthContext (接口)

  • 定义:{ userId: string; roles: string[]; permissions: Permission[]; dataScope: DataScope }
  • 被使用auth-guard.ts, 所有调用 requirePermission 的 Server Action

PermissionDeniedError (类)

  • 被使用:所有 Server Action 的 try/catch

数据库表 (shared/db/schema.ts)

表名 核心字段 被哪些模块使用
users id, name, email, emailVerified, image, password, phone, address, gender, age, birthDate, guardianName, guardianPhone, guardianRelation, consentAcceptedAt, gradeId, departmentId, onboardedAt, createdAt, updatedAt auth, users, dashboard, classes
accounts userId, type, provider, providerAccountId, refresh_token, access_token, expires_at, token_type, scope, id_token, session_state auth
sessions sessionToken, userId, expires auth
verificationTokens identifier, token, expires auth
roles id, name, description, createdAt, updatedAt auth, auth-guard
usersToRoles userId, roleId auth, auth-guard
rolePermissions roleId, permission auth (seed)
knowledgePoints id, name, description, anchorText, parentId, chapterId, level, order, createdAt, updatedAt textbooks, questions
questions id, content, type, difficulty, authorId, parentId, createdAt, updatedAt questions, exams, homework
questionsToKnowledgePoints questionId, knowledgePointId questions
subjects id, name, order, code, createdAt, updatedAt exams, textbooks
textbooks id, title, subject, grade, publisher, createdAt, updatedAt textbooks
chapters id, textbookId, title, order, parentId, content, createdAt, updatedAt textbooks
departments id, name, description, createdAt, updatedAt school
classrooms id, name, building, floor, capacity, createdAt, updatedAt school
academicYears id, name, startDate, endDate, isActive, createdAt, updatedAt school
schools id, name, code, createdAt, updatedAt school, classes
grades id, schoolId, name, order, gradeHeadId, teachingHeadId, createdAt, updatedAt school, classes, exams, auth-guard
classes id, schoolId, gradeId, teacherId, name, homeroom, room, invitationCode, schoolName, grade, createdAt, updatedAt classes, homework, auth-guard
classSubjectTeachers classId, teacherId, subjectId, createdAt, updatedAt classes, auth-guard
classEnrollments classId, studentId, status, createdAt classes, homework
classSchedule id, classId, weekday, startTime, endTime, course, location, createdAt, updatedAt classes
exams id, creatorId, title, description, subjectId, gradeId, status, structure, startTime, endTime, createdAt, updatedAt exams, homework
examQuestions examId, questionId, score, order exams
examSubmissions id, examId, studentId, score, status, submittedAt, createdAt, updatedAt exams
submissionAnswers id, submissionId, questionId, answerContent, score, feedback, createdAt, updatedAt exams
homeworkAssignments id, creatorId, sourceExamId, title, description, status, structure, availableAt, dueAt, allowLate, lateDueAt, maxAttempts, createdAt, updatedAt homework
homeworkAssignmentQuestions assignmentId, questionId, score, order homework
homeworkAssignmentTargets assignmentId, studentId, createdAt homework
homeworkSubmissions id, assignmentId, studentId, status, attemptNo, score, submittedAt, startedAt, isLate, createdAt, updatedAt homework
homeworkAnswers id, submissionId, questionId, answerContent, score, feedback, createdAt, updatedAt homework
aiProviders id, provider, baseUrl, model, apiKeyEncrypted, apiKeyLast4, isDefault, createdBy, updatedBy, createdAt, updatedAt settings, ai
announcements id, title, content, type, status, targetGradeId, targetClassId, authorId, publishedAt, createdAt, updatedAt announcements
auditLogs id, userId, userName, action, module, targetId, targetType, detail, ipAddress, userAgent, status, createdAt audit, shared/lib/audit-logger
loginLogs id, userId, userEmail, action, status, ipAddress, userAgent, errorMessage, createdAt audit, shared/lib/login-logger, auth
dataChangeLogs id, tableName, recordId, action (create/update/delete), oldValue, newValue, changedBy, changedByName, ipAddress, createdAt audit, shared/lib/change-logger
fileAttachments id, filename, originalName, mimeType, size, storagePath, url, uploaderId, targetType, targetId, createdAt files
gradeRecords id, studentId, classId, subjectId, examId, academicYearId, title, score, fullScore, type, semester, recordedBy, remark, createdAt, updatedAt grades
coursePlans id, classId, subjectId, teacherId, academicYearId, semester, totalHours, completedHours, weeklyHours, startDate, endDate, syllabus, objectives, status, createdBy, createdAt, updatedAt course-plans
coursePlanItems id, planId, week, topic, content, hours, textbookChapter, notes, isCompleted, completedAt, createdAt, updatedAt course-plans
parentStudentRelations id, parentId, studentId, relation, createdAt parent, auth-guard
messages id, senderId, receiverId, subject, content, isRead, readAt, parentMessageId, createdAt messaging
messageNotifications id, userId, type, title, content, link, isRead, createdAt messaging
notificationPreferences id, userId (unique FK→users), emailEnabled, smsEnabled, pushEnabled, homeworkNotifications, gradeNotifications, announcementNotifications, messageNotifications, attendanceNotifications, createdAt, updatedAt messaging, settings
attendanceRecords id, studentId, classId, scheduleId, date, status, remark, recordedBy, createdAt, updatedAt attendance
attendanceRules id, classId, lateThresholdMinutes, earlyLeaveThresholdMinutes, enableAutoMark, createdAt, updatedAt attendance
schedulingRules id, classId, maxDailyHours, maxContinuousHours, lunchBreakStart, lunchBreakEnd, morningStart, afternoonEnd, avoidBackToBack, balancedSubjects, createdAt, updatedAt scheduling
scheduleChanges id, originalScheduleId, classId, originalTeacherId, substituteTeacherId, originalDate, newDate, newStartTime, newEndTime, reason, status, requestedBy, approvedBy, createdAt, updatedAt scheduling
passwordSecurity id, userId, failedLoginAttempts, lockedUntil, passwordChangedAt, mustChangePassword, lastPasswordChange, createdAt, updatedAt auth, settings
knowledgePointMastery id, studentId, knowledgePointId, masteryLevel, totalQuestions, correctQuestions, lastAssessedAt, createdAt, updatedAt diagnostic
learningDiagnosticReports id, studentId, generatedBy, reportType, period, summary, strengths, weaknesses, recommendations, overallScore, status, createdAt, updatedAt diagnostic

模块auth

模块职责

处理用户认证(登录/注册/JWT/Session提供 NextAuth 实例和中间件。通过 events 回调记录登录日志。 集成密码安全策略(账户锁定、失败登录追踪)和登录速率限制。

导出函数

auth

  • 签名:auth(): Promise<Session | null> (NextAuth 导出)
  • 功能:获取当前用户 Session
  • 被使用auth-guard.ts, 所有 Server Component 页面, audit-logger.ts

handlers

  • 签名:{ GET, POST } (NextAuth Route Handler)
  • 被使用:app/api/auth/[...nextauth]/route.ts

signIn / signOut

  • 被使用login-form.tsx, site-header.tsx

authorize 回调Credentials Provider

登录流程集成密码安全策略和速率限制:

  1. 速率限制:按 IP:email 维度限流RATE_LIMIT_RULES.LOGIN: 5次/15分钟超限返回 null
  2. 账户锁定检查:通过 isAccountLocked(failedLoginAttempts, lastFailedAt) 判断,锁定则返回 null
  3. 密码验证失败:调用 recordFailedLogin 递增失败次数,达阈值自动锁定
  4. 登录成功:调用 resetFailedLogin 清零失败次数,resetRateLimit 清除限流计数

Events 回调

events.signIn

  • 签名:async signIn({ user }) => void
  • 功能:用户登录成功后记录登录日志
  • 依赖:shared/lib/login-logger.logLoginEvent
  • 调用参数:{ userId: user.id, userEmail: user.email, action: "signin", status: "success" }

events.signOut

  • 签名:async signOut(message) => void
  • 功能:用户登出后记录登录日志(处理 NextAuth v5 不同 message 形状)
  • 依赖:shared/lib/login-logger.logLoginEvent
  • 调用参数:{ userId?, userEmail, action: "signout", status: "success" }

middleware (proxy.ts)

  • 签名:middleware(request: NextRequest) => Promise<NextResponse>
  • 功能:基于权限点的路由守卫,未登录重定向 /login无权限重定向角色首页
  • 依赖:getToken (next-auth/jwt), Permissions
  • 被使用Next.js middleware 层

模块exams

模块职责

考试全生命周期管理:创建(手动/AI、编辑、预览、发布、删除、复制。

导出函数 (actions.ts)

createExamAction

  • 签名:(prevState: ActionState<string> | null, formData: FormData) => Promise<ActionState<string>>
  • 参数说明:formData 包含 mode, title, subject, grade, difficulty, totalScore, durationMin, scheduledAt
  • 功能:手动模式创建考试草稿
  • 依赖:requirePermission(EXAM_CREATE), shared/db, data-access.persistExamDraft
  • 被使用exam-form.tsx

createAiExamAction

  • 签名:同上
  • 功能AI 模式创建考试(调用 AI pipeline 生成题目)
  • 依赖:requirePermission(EXAM_AI_GENERATE), ai-pipeline.generateAiCreateDraftFromSource, data-access.persistAiGeneratedExamDraft
  • 被使用exam-form.tsx

previewAiExamAction

  • 签名:(prevState: ActionState<AiPreviewData> | null, formData: FormData) => Promise<ActionState<AiPreviewData>>
  • 功能AI 预览试卷(不持久化)
  • 依赖:requirePermission(EXAM_AI_GENERATE), ai-pipeline.generateAiPreviewData
  • 被使用exam-ai-generator.tsx (via useExamPreview)

regenerateAiQuestionAction

  • 签名:(prevState: ActionState<AiRewriteQuestionData> | null, formData: FormData) => Promise<ActionState<AiRewriteQuestionData>>
  • 功能AI 重写单个题目
  • 依赖:requirePermission(EXAM_AI_GENERATE), ai-pipeline.regenerateAiQuestionByInstruction
  • 被使用exam-preview-question-editor.tsx

updateExamAction

  • 签名:(prevState: ActionState<string> | null, formData: FormData) => Promise<ActionState<string>>
  • 功能:更新考试信息,含资源归属校验(非 admin 只能改自己的)
  • 依赖:requirePermission(EXAM_UPDATE), shared/db
  • 被使用exam-form.tsx

deleteExamAction

  • 签名:同上
  • 功能:删除考试,含资源归属校验
  • 依赖:requirePermission(EXAM_DELETE), shared/db
  • 被使用exam-actions.tsx

duplicateExamAction

  • 签名:同上
  • 功能:复制考试
  • 依赖:requirePermission(EXAM_DUPLICATE), shared/db
  • 被使用exam-actions.tsx

getExamPreviewAction

  • 签名:(examId: string) => Promise<ActionState<...>>
  • 功能:获取考试预览数据
  • 依赖:requirePermission(EXAM_READ), shared/db
  • 被使用exam-viewer.tsx

getSubjectsAction

  • 签名:() => Promise<ActionState<{ id: string; name: string }[]>>
  • 依赖:requirePermission(EXAM_READ), shared/db
  • 被使用exam-form.tsx

getGradesAction

  • 签名:同上
  • 依赖:requirePermission(EXAM_READ), shared/db
  • 被使用exam-form.tsx

导出函数 (data-access.ts)

getExams

  • 签名:getExams(params: GetExamsParams & { scope: DataScope }): Promise<Exam[]>
  • 参数说明:scope 来自 auth-guard.getAuthContext().dataScope
  • 功能:查询考试列表,含数据权限过滤
  • 依赖:shared/db, DataScope
  • 被使用teacher/exams/all/page.tsx, homework 创建页面

getExamById

  • 签名:getExamById(id: string, scope?: DataScope): Promise<Exam | null>
  • 被使用exam 详情/编辑页面

persistExamDraft / persistAiGeneratedExamDraft

  • 被使用createExamAction, createAiExamAction

omitScheduledAtFromDescription

  • 功能:从考试描述中移除 scheduledAt 字段(用于编辑场景)
  • 被使用exams/data-access.ts 内部

resolveSubjectGradeNames

  • 功能:将 subjectId/gradeId 解析为可读名称
  • 被使用exams/data-access.ts 内部, buildExamDescription

buildExamDescription

  • 功能:构建考试描述文本(含科目、年级、时间等)
  • 依赖:resolveSubjectGradeNames, omitScheduledAtFromDescription
  • 被使用createExamAction, createAiExamAction

GetExamsParams (类型)

  • 定义:查询参数类型(含 subjectId?, gradeId?, status?, keyword? 等过滤条件)
  • 被使用:getExams, getQuestionsAction

导出函数 (ai-pipeline.ts)

generateAiPreviewData

  • 签名:(input: { title, subject?, grade?, difficulty, totalScore, durationMin, questionCount?, sourceText, aiProviderId? }) => Promise<{ ok, data?, rawOutput?, message? }>
  • 依赖:shared/lib/ai.createAiChatCompletion
  • 被使用previewAiExamAction

generateAiCreateDraftFromSource

  • 被使用createAiExamAction

regenerateAiQuestionByInstruction

  • 被使用regenerateAiQuestionAction

generateAiExamDraft

  • 功能:生成 AI 考试草稿(含结构与题目)
  • 依赖:shared/lib/ai.createAiChatCompletion, AiQuestionSchema, AiGeneratedStructureSchema
  • 被使用createAiExamAction

AI Schema 与类型 (ai-pipeline.ts)

AiQuestionSchema

  • 类型Zod schema
  • 定义AI 生成题目的校验 schematype, content, difficulty, score, options? 等)
  • 被使用:generateAiExamDraft, AiGeneratedQuestion

AiInsertQuestionSchema

  • 类型Zod schema
  • 定义:插入题目到 DB 的校验 schema含 authorId, parentId 等 DB 字段)
  • 被使用:persistAiGeneratedExamDraft

AiGeneratedQuestion

  • 类型TypeScript 类型(基于 AiQuestionSchema 推断)
  • 被使用:AiPreviewData, exams/components

AiGeneratedStructureNode

  • 类型TypeScript 类型
  • 定义AI 生成的试卷结构节点section 标题、题目列表)
  • 被使用:AiGeneratedStructureSchema

AiGeneratedStructureNodeSchema

  • 类型Zod schema
  • 定义:AiGeneratedStructureNode 的校验 schema
  • 被使用:AiGeneratedStructureSchema

AiGeneratedStructureSchema

  • 类型Zod schema
  • 定义AI 生成的完整试卷结构校验 schemaAiGeneratedStructureNode[]
  • 被使用:generateAiExamDraft

类型/接口

Exam

  • 被使用exams/components, homework/types (sourceExam), dashboard/types

AiPreviewData / AiRewriteQuestionData

  • 被使用exams/actions.ts, exams/components

ExamStatus

  • 定义考试状态枚举类型draft/published 等)
  • 被使用exams/data-access.ts, exams/components

ExamDifficulty

  • 定义:考试难度枚举类型
  • 被使用exams/components, ai-pipeline.ts

SubmissionStatus

  • 定义提交状态枚举类型in_progress/submitted/graded 等)
  • 被使用examSubmissions 相关逻辑

ExamSubmission

  • 定义:考试提交记录类型(含 studentId, score, status 等)
  • 被使用exams/data-access.ts, exams/components

导出 Hooks

useExamPreview

  • 签名:useExamPreview(): { isPending, execute, previewData, error }
  • 功能:包装 previewAiExamAction,管理 AI 预览状态
  • 被使用exam-ai-generator.tsx

导出组件 (components/)

组件文件 功能
exam-form.tsx 考试创建/编辑表单(手动 + AI 模式)
exam-ai-generator.tsx AI 生成考试配置面板
exam-viewer.tsx 考试预览展示
exam-actions.tsx 考试操作菜单(复制/删除)
exam-data-table.tsx 考试列表数据表格
exam-preview-question-editor.tsx AI 预览题目编辑器
exam-status-badge.tsx 考试状态徽章
exam-card.tsx 考试卡片
exam-list.tsx 考试列表
exam-detail.tsx 考试详情
exam-header.tsx 考试头部信息
exam-info.tsx 考试基本信息展示
exam-question-list.tsx 考试题目列表
exam-question-item.tsx 考试题目项
exam-question-picker.tsx 题目选择器
exam-score-summary.tsx 分值汇总
exam-schedule-picker.tsx 考试时间选择器
exam-subject-grade-select.tsx 科目年级选择器
exam-empty.tsx 考试空状态
assembly/exam-assembly-panel.tsx 组卷面板
assembly/question-pool.tsx 题库选择池
assembly/assembly-cart.tsx 已选题目购物车
assembly/assembly-summary.tsx 组卷汇总

模块homework

模块职责

作业全生命周期:创建(源自考试)、发布、学生作答、教师批改、数据分析。

导出函数 (actions.ts)

createHomeworkAssignmentAction

  • 签名:(prevState: ActionState<string> | null, formData: FormData) => Promise<ActionState<string>>
  • 功能:从已有考试创建作业
  • 依赖:requirePermission(HOMEWORK_CREATE), shared/db, exams/data-access.getExams
  • 被使用homework-assignment-form.tsx

startHomeworkSubmissionAction

  • 签名:同上
  • 功能:学生开始作答
  • 依赖:requirePermission(HOMEWORK_SUBMIT), shared/db
  • 被使用homework-take-view.tsx

saveHomeworkAnswerAction

  • 签名:同上
  • 功能:保存单题答案
  • 依赖:requirePermission(HOMEWORK_SUBMIT), shared/db
  • 被使用homework-take-view.tsx

submitHomeworkAction

  • 签名:同上
  • 功能:提交作业
  • 依赖:requirePermission(HOMEWORK_SUBMIT), shared/db
  • 被使用homework-take-view.tsx

gradeHomeworkSubmissionAction

  • 签名:同上
  • 功能:教师批改作业
  • 依赖:requirePermission(HOMEWORK_GRADE), shared/db
  • 被使用homework-grading-view.tsx

导出函数 (data-access.ts)

getHomeworkAssignments

  • 签名:(params?: { creatorId?, ids?, classId?, scope? }) => Promise<HomeworkAssignmentListItem[]>
  • 依赖:shared/db, DataScope
  • 被使用teacher 作业列表页, homework-assignment-form.tsx

getStudentHomeworkAssignments

  • 签名:(studentId: string) => Promise<StudentHomeworkAssignmentListItem[]>
  • 被使用student/dashboard

getStudentDashboardGrades

  • 签名:(studentId: string) => Promise<StudentDashboardGradeProps>
  • 被使用dashboard/data-access.ts (学生仪表盘)

getHomeworkAssignmentAnalytics

  • 签名:(assignmentId: string) => Promise<HomeworkAssignmentAnalytics | null>
  • 被使用homework 错误分析组件

getHomeworkAssignmentById

  • 签名:(assignmentId: string, scope?: DataScope) => Promise<HomeworkAssignment | null>
  • 功能:按 ID 获取作业详情(含数据权限过滤)
  • 被使用homework 详情/编辑页面, homework-take-view.tsx

getHomeworkSubmissionDetails

  • 签名:(submissionId: string, scope?: DataScope) => Promise<HomeworkSubmissionDetails | null>
  • 功能:获取作业提交详情(含答案列表、学生信息)
  • 被使用homework-grading-view.tsx

getDemoStudentUser

  • 签名:() => Promise<{ id: string; name: string } | null>
  • 功能:获取演示学生用户(用于 demo/预览场景)
  • 被使用homework demo 相关页面

getStudentHomeworkTakeData

  • 签名:(studentId: string, assignmentId: string) => Promise<StudentHomeworkTakeData | null>
  • 功能:获取学生作答作业所需完整数据(作业、题目、已答内容、提交状态)
  • 被使用homework-take-view.tsx

Schema (schema.ts)

CreateHomeworkAssignmentSchema

  • 类型Zod schema
  • 定义:创建作业的校验 schemasourceExamId, title, classIds, dueAt, allowLate 等)
  • 被使用:createHomeworkAssignmentAction

CreateHomeworkAssignmentInput

  • 类型TypeScript 类型(基于 CreateHomeworkAssignmentSchema 推断)
  • 被使用:createHomeworkAssignmentAction, homework-assignment-form.tsx

GradeHomeworkSchema

  • 类型Zod schema
  • 定义:批改作业的校验 schemasubmissionId, answers[{ questionId, score, feedback }]
  • 被使用:gradeHomeworkSubmissionAction

类型/接口

StudentDashboardGradeProps

  • 被使用dashboard/types.ts (StudentDashboardProps.grades)

HomeworkAssignmentListItem

  • 被使用homework 列表页, homework-assignment-form.tsx

HomeworkAssignment

  • 定义:作业完整类型(含 sourceExam, targets, questions 等关联)
  • 被使用homework 详情/编辑页面

HomeworkAssignmentReviewListItem

  • 被使用teacher 批改列表

HomeworkSubmissionListItem

  • 被使用teacher 提交列表

HomeworkSubmission

  • 定义:作业提交记录类型
  • 被使用homework-grading-view.tsx

HomeworkSubmissionDetails

  • 定义:提交详情类型(含学生、答案列表)
  • 被使用homework-grading-view.tsx

HomeworkAnswer

  • 定义:作业答案类型
  • 被使用homework-take-view.tsx, homework-grading-view.tsx

HomeworkAssignmentAnalytics

  • 定义:作业分析数据类型(含错误率、平均分等)
  • 被使用homework 错误分析组件

StudentHomeworkAssignmentListItem

  • 被使用student/dashboard

StudentHomeworkTakeData

  • 定义:学生作答数据类型(含 assignment, questions, currentAnswers, submission
  • 被使用homework-take-view.tsx

TeacherGradeTrendItem

  • 被使用dashboard (教师仪表盘)

HomeworkAssignmentStatus

  • 定义作业状态枚举类型draft/published/closed 等)
  • 被使用homework/data-access.ts, homework/components

HomeworkSubmissionStatus

  • 定义提交状态枚举类型in_progress/submitted/graded 等)
  • 被使用homework/data-access.ts, homework/components

HomeworkAssignmentTarget

  • 定义:作业目标学生类型
  • 被使用homework/data-access.ts

HomeworkQuestion

  • 定义:作业题目类型(含 score, order
  • 被使用homework-take-view.tsx

HomeworkGradingInput

  • 定义:批改输入类型
  • 被使用homework-grading-view.tsx

导出组件 (components/)

组件文件 功能
homework-assignment-form.tsx 作业创建表单(源自考试)
homework-take-view.tsx 学生作答视图
homework-grading-view.tsx 教师批改视图
homework-assignment-list.tsx 作业列表
homework-assignment-card.tsx 作业卡片
homework-assignment-detail.tsx 作业详情
homework-submission-list.tsx 提交列表
homework-submission-card.tsx 提交卡片
homework-analytics.tsx 作业分析(错误率/平均分)
homework-status-badge.tsx 作业状态徽章

模块questions

模块职责

题库管理:题目 CRUD、知识点关联、题型支持选择/填空/判断/复合)。

导出函数 (actions.ts)

createNestedQuestion

  • 签名:(prevState: ActionState<string> | undefined, formData: FormData | CreateQuestionInput) => Promise<ActionState<string>>
  • 依赖:requirePermission(QUESTION_CREATE), shared/db
  • 被使用create-question-dialog.tsx

updateQuestionAction

  • 签名:同上
  • 依赖:requirePermission(QUESTION_UPDATE), shared/db
  • 被使用question-actions.tsx

deleteQuestionAction

  • 签名:同上
  • 依赖:requirePermission(QUESTION_DELETE), shared/db
  • 被使用question-actions.tsx

getQuestionsAction

  • 签名:(params: GetQuestionsParams) => Promise<...>
  • 依赖:requirePermission(QUESTION_READ), data-access.getQuestions
  • 被使用teacher/questions/page.tsx

getKnowledgePointOptionsAction

  • 签名:() => Promise<KnowledgePointOption[]>
  • 依赖:requirePermission(QUESTION_READ), shared/db
  • 被使用create-question-dialog.tsx

导出函数 (data-access.ts)

getQuestions

  • 签名:(params: GetQuestionsParams & { scope?: DataScope }) => Promise<Question[]>
  • 功能:查询题目列表(含知识点关联、数据权限过滤)
  • 依赖:shared/db, DataScope
  • 被使用:getQuestionsAction, teacher/questions/page.tsx

GetQuestionsParams (类型)

  • 定义:查询参数类型(含 keyword?, type?, difficulty?, knowledgePointId?, parentId? 等过滤条件)
  • 被使用:getQuestions, getQuestionsAction

Schema (schema.ts)

QuestionTypeEnum

  • 类型Zod enum
  • 定义题目类型枚举choice/fill/judge/composite 等)
  • 被使用:BaseQuestionSchema, CreateQuestionSchema

BaseQuestionSchema

  • 类型Zod schema
  • 定义:题目基础校验 schematype, content, difficulty, knowledgePointIds? 等)
  • 被使用:CreateQuestionSchema

CreateQuestionInput

  • 类型TypeScript 类型(基于 CreateQuestionSchema 推断)
  • 被使用:createNestedQuestion, create-question-dialog.tsx

CreateQuestionSchema

  • 类型Zod schema
  • 定义:创建题目的完整校验 schemaBaseQuestionSchema + 选项/答案/子题目)
  • 被使用:createNestedQuestion

类型/接口

Question

  • 被使用exams (题目选择), homework (作业题目)

KnowledgePointOption

  • 被使用create-question-dialog.tsx

QuestionType

  • 定义:题目类型联合类型(基于 QuestionTypeEnum
  • 被使用questions/components, exams/components, homework/components

导出组件 (components/)

组件文件 功能
create-question-dialog.tsx 创建题目对话框(含嵌套题目)
question-actions.tsx 题目操作菜单(编辑/删除)
question-data-table.tsx 题目列表数据表格
question-card.tsx 题目卡片
question-detail.tsx 题目详情展示
question-type-badge.tsx 题目类型徽章

模块textbooks

模块职责

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

导出函数 (actions.ts)

函数 权限 核心功能
createTextbookAction TEXTBOOK_CREATE 创建教材
updateTextbookAction TEXTBOOK_UPDATE 更新教材元信息
deleteTextbookAction TEXTBOOK_DELETE 删除教材
createChapterAction TEXTBOOK_CREATE 创建章节
updateChapterContentAction TEXTBOOK_UPDATE 更新章节内容(Markdown)
deleteChapterAction TEXTBOOK_DELETE 删除章节
createKnowledgePointAction TEXTBOOK_CREATE 创建知识点
updateKnowledgePointAction TEXTBOOK_UPDATE 更新知识点
deleteKnowledgePointAction TEXTBOOK_DELETE 删除知识点
reorderChaptersAction TEXTBOOK_UPDATE 章节排序

导出函数 (data-access.ts)

函数 签名 被使用
getTextbooks (query?, subject?, grade?) => Promise<Textbook[]> teacher/textbooks/page.tsx
getTextbookById (id: string) => Promise<Textbook | undefined> teacher/textbooks/[id]/page.tsx
getChaptersByTextbookId (textbookId: string) => Promise<Chapter[]> textbook-reader.tsx
getKnowledgePointsByChapterId (chapterId: string) => Promise<KnowledgePoint[]> textbook-reader.tsx
getKnowledgePointsByTextbookId (textbookId: string) => Promise<KnowledgePoint[]> textbook-reader.tsx

写操作函数 (data-access.ts)

函数 签名 被使用
persistTextbook (input: { textbookId, title, subject, grade, publisher, creatorId }) => Promise<void> createTextbookAction
updateTextbookMeta (textbookId, input: { title?, subject?, grade?, publisher? }) => Promise<void> updateTextbookAction
deleteTextbookRecord (textbookId) => Promise<void> deleteTextbookAction
persistChapter (input: { chapterId, textbookId, parentId?, title, order }) => Promise<void> createChapterAction
updateChapterContent (chapterId, content, textbookId) => Promise<void> updateChapterContentAction
deleteChapterRecord (chapterId, textbookId) => Promise<void> deleteChapterAction
reorderChapters (chapterId, newIndex, parentId, textbookId) => Promise<void> reorderChaptersAction
persistKnowledgePoint (input: { kpId, chapterId, textbookId, name, description?, anchorText? }) => Promise<void> createKnowledgePointAction
updateKnowledgePointRecord (kpId, textbookId, input: { name?, description?, anchorText? }) => Promise<void> updateKnowledgePointAction
deleteKnowledgePointRecord (kpId, textbookId) => Promise<void> deleteKnowledgePointAction

导出 Hooks

useTextSelection

  • 签名:useTextSelection() => { selectedText, createDialogOpen, isCreating, handleContentPointerDown, handleContextMenuChange }
  • 功能:管理教材内容文本选择与知识点创建对话框状态(无参数,内部使用 ref 与状态)
  • 被使用textbook-content-panel.tsx

useKnowledgePointActions

  • 签名:useKnowledgePointActions(textbookId, selectedChapterId, highlightedKpId, setHighlightedKpId, onCreateKP, onEditKP) => { editingKp, editKpDialogOpen, ..., requestDeleteKnowledgePoint, confirmDeleteKnowledgePoint, handleUpdateKnowledgePoint }
  • 功能:知识点 CRUD 操作集合6 参数textbookId, selectedChapterId, highlightedKpId, setHighlightedKpId, onCreateKP, onEditKP
  • 被使用textbook-reader.tsx

类型/接口

Chapter

  • 被使用textbooks/components, questions (知识点关联)

KnowledgePoint

  • 被使用textbooks/components, questions/types (KnowledgePointOption)

Textbook

  • 定义:教材类型(含 id, title, subject, grade, publisher 等)
  • 被使用textbooks/components, teacher/textbooks/page.tsx

TextbookListItem

  • 定义:教材列表项类型
  • 被使用teacher/textbooks/page.tsx

ChapterTreeNode

  • 定义:章节树节点类型(含 children[]
  • 被使用textbook-reader.tsx, chapter-tree.tsx

KnowledgePointInput

  • 定义:知识点创建/更新输入类型
  • 被使用useKnowledgePointActions, createKnowledgePointAction

ChapterInput

  • 定义:章节创建输入类型
  • 被使用createChapterAction

ReorderChaptersInput

  • 定义:章节排序输入类型
  • 被使用reorderChaptersAction

导出组件 (components/)

组件文件 功能
textbook-reader.tsx 教材阅读器(章节树 + 内容面板 + 知识点)
textbook-list.tsx 教材列表
textbook-card.tsx 教材卡片
textbook-form.tsx 教材创建/编辑表单
textbook-content-panel.tsx 教材内容面板Markdown 渲染 + 文本选择)
chapter-tree.tsx 章节树(可拖拽排序)
chapter-node.tsx 章节树节点
chapter-form.tsx 章节创建/编辑表单
chapter-content-editor.tsx 章节 Markdown 内容编辑器
knowledge-point-list.tsx 知识点列表
knowledge-point-item.tsx 知识点项
knowledge-point-form.tsx 知识点创建/编辑表单
knowledge-graph.tsx 知识图谱可视化

模块classes

模块职责

班级管理:班级 CRUD、学生注册/退班、邀请码、课表、学科教师分配。

导出函数 (actions.ts)

函数 权限 核心功能
createTeacherClassAction CLASS_CREATE 教师创建班级
updateTeacherClassAction CLASS_UPDATE 教师更新班级
deleteTeacherClassAction CLASS_DELETE 教师删除班级
createGradeClassAction CLASS_CREATE 年级主任创建班级
updateGradeClassAction CLASS_UPDATE 年级主任更新班级
deleteGradeClassAction CLASS_DELETE 年级主任删除班级
enrollStudentByEmailAction CLASS_ENROLL 通过邮箱注册学生
joinClassByInvitationCodeAction CLASS_ENROLL 通过邀请码加入
ensureClassInvitationCodeAction CLASS_ENROLL 确保邀请码存在
regenerateClassInvitationCodeAction CLASS_ENROLL 重新生成邀请码
setStudentEnrollmentStatusAction CLASS_ENROLL 设置学生状态
createClassScheduleItemAction CLASS_SCHEDULE 创建课表项
updateClassScheduleItemAction CLASS_SCHEDULE 更新课表项
deleteClassScheduleItemAction CLASS_SCHEDULE 删除课表项
createAdminClassAction CLASS_CREATE 管理员创建班级
updateAdminClassAction CLASS_UPDATE 管理员更新班级
deleteAdminClassAction CLASS_DELETE 管理员删除班级

导出函数 (data-access.ts)

读操作函数

函数 签名 被使用
getTeacherClasses (params?: { teacherId? }) => Promise<TeacherClass[]> teacher/classes/my, dashboard
getAdminClasses () => Promise<AdminClassListItem[]> admin 班级管理
getGradeManagedClasses (userId) => Promise<AdminClassListItem[]> grade_head 班级管理
getStudentClasses (studentId) => Promise<StudentEnrolledClass[]> student/dashboard
getStudentSchedule (studentId) => Promise<StudentScheduleItem[]> student 课表
getClassStudents (classId, scope?) => Promise<ClassStudent[]> teacher/classes/students
getClassSchedule (classId) => Promise<ClassScheduleItem[]> teacher/classes/schedule
getClassHomeworkInsights (classId) => Promise<ClassHomeworkInsights | null> classes 作业洞察
getGradeHomeworkInsights (gradeId) => Promise<GradeHomeworkInsights | null> 年级作业洞察
getClassById (classId, scope?) => Promise<Class | null> 班级详情页
getClassDetails (classId, scope?) => Promise<ClassDetails | null> 班级详情(含学生数、教师数)
getClassSubjectTeachers (classId) => Promise<ClassSubjectTeacher[]> 班级学科教师分配
getStudentEnrollmentStatus (classId, studentId) => Promise<EnrollmentStatus | null> 注册状态查询
validateInvitationCode (code) => Promise<{ valid: boolean; classId?: string }> 邀请码校验
getClassInsights (classId) => Promise<ClassInsights | null> 班级洞察数据

写操作函数

函数 签名 被使用
persistTeacherClass (input: { classId, teacherId, name, gradeId, ... }) => Promise<void> createTeacherClassAction
updateTeacherClassRecord (classId, input) => Promise<void> updateTeacherClassAction
deleteTeacherClassRecord (classId) => Promise<void> deleteTeacherClassAction
persistGradeClass (input: { classId, gradeId, ... }) => Promise<void> createGradeClassAction
updateGradeClassRecord (classId, input) => Promise<void> updateGradeClassAction
deleteGradeClassRecord (classId) => Promise<void> deleteGradeClassAction
enrollStudentByEmail (classId, email) => Promise<{ studentId }> enrollStudentByEmailAction
joinClassByInvitationCode (code, studentId) => Promise<{ classId }> joinClassByInvitationCodeAction
ensureInvitationCode (classId) => Promise<{ code }> ensureClassInvitationCodeAction
regenerateInvitationCode (classId) => Promise<{ code }> regenerateClassInvitationCodeAction
setStudentEnrollmentStatus (classId, studentId, status) => Promise<void> setStudentEnrollmentStatusAction
persistClassScheduleItem (input: { scheduleId, classId, ... }) => Promise<void> createClassScheduleItemAction
updateClassScheduleItem (scheduleId, input) => Promise<void> updateClassScheduleItemAction
deleteClassScheduleItem (scheduleId) => Promise<void> deleteClassScheduleItemAction
persistAdminClass (input: { classId, ... }) => Promise<void> createAdminClassAction
updateAdminClassRecord (classId, input) => Promise<void> updateAdminClassAction
deleteAdminClassRecord (classId) => Promise<void> deleteAdminClassAction
assignSubjectTeacher (classId, teacherId, subjectId) => Promise<void> 学科教师分配
removeClassSubjectTeacher (classId, teacherId, subjectId) => Promise<void> 移除学科教师
bulkEnrollStudents (classId, studentIds[]) => Promise<void> 批量注册学生
transferStudent (fromClassId, toClassId, studentId) => Promise<void> 学生转班
getClassInvitationInfo (classId) => Promise<{ code, expiresAt? }> 邀请信息查询
countClassStudents (classId) => Promise<number> 学生计数

类型/接口

TeacherClass

  • 定义:教师班级类型(含 grade, studentCount 等)
  • 被使用teacher/classes/my, dashboard

AdminClassListItem

  • 定义:管理员班级列表项类型
  • 被使用admin 班级管理

StudentEnrolledClass

  • 定义:学生已加入班级类型
  • 被使用student/dashboard

StudentScheduleItem

  • 定义:学生课表项类型
  • 被使用student 课表

ClassStudent

  • 定义:班级学生类型(含 enrollmentStatus
  • 被使用teacher/classes/students

ClassScheduleItem

  • 定义:班级课表项类型
  • 被使用teacher/classes/schedule

ClassHomeworkInsights

  • 定义:班级作业洞察类型
  • 被使用classes 作业洞察

GradeHomeworkInsights

  • 定义:年级作业洞察类型
  • 被使用:年级作业洞察

Class

  • 定义:班级基础类型
  • 被使用classes/components

ClassDetails

  • 定义:班级详情类型(含学生数、教师数、课表等)
  • 被使用:班级详情页

ClassSubjectTeacher

  • 定义:班级学科教师类型
  • 被使用:班级学科教师分配

EnrollmentStatus

  • 定义注册状态枚举类型active/inactive/pending
  • 被使用classes/data-access.ts

ClassInsights

  • 定义:班级洞察数据类型
  • 被使用:班级洞察页面

CreateClassInput

  • 定义:创建班级输入类型
  • 被使用createTeacherClassAction, createAdminClassAction

UpdateClassInput

  • 定义:更新班级输入类型
  • 被使用updateTeacherClassAction, updateAdminClassAction

CreateScheduleItemInput

  • 定义:创建课表项输入类型
  • 被使用createClassScheduleItemAction

EnrollmentInput

  • 定义:注册输入类型
  • 被使用enrollStudentByEmailAction

InvitationCodeResult

  • 定义:邀请码结果类型
  • 被使用ensureClassInvitationCodeAction

ClassListItem

  • 定义:班级列表项类型
  • 被使用:班级列表页

ClassFormValues

  • 定义:班级表单值类型
  • 被使用class-form.tsx

导出组件 (components/)

组件文件 功能
class-list.tsx 班级列表
class-card.tsx 班级卡片
class-form.tsx 班级创建/编辑表单
class-detail.tsx 班级详情
class-actions.tsx 班级操作菜单
class-students.tsx 班级学生列表
class-student-card.tsx 班级学生卡片
class-schedule.tsx 班级课表
class-schedule-form.tsx 课表项创建/编辑表单
class-schedule-item.tsx 课表项展示
class-invitation.tsx 邀请码组件
class-invitation-dialog.tsx 邀请码对话框
class-enroll-dialog.tsx 学生注册对话框
class-subject-teachers.tsx 学科教师分配
class-subject-teacher-form.tsx 学科教师表单
class-insights.tsx 班级洞察
class-homework-insights.tsx 班级作业洞察
class-status-badge.tsx 班级状态徽章

模块school

模块职责

学校基础数据管理:学校、年级、部门、学年的 CRUD。

导出函数 (actions.ts)

所有 12 个 actions 均使用 requirePermission() 进行权限校验。 学校 CRUD actionscreateSchoolAction/updateSchoolAction/deleteSchoolAction在写操作成功后调用 logAudit() 记录操作日志。

函数 权限 核心功能
createSchoolAction SCHOOL_MANAGE 创建学校(成功后记录 audit log: school.create
updateSchoolAction SCHOOL_MANAGE 更新学校(成功后记录 audit log: school.update
deleteSchoolAction SCHOOL_MANAGE 删除学校(成功后记录 audit log: school.delete
createGradeAction GRADE_MANAGE 创建年级
updateGradeAction GRADE_MANAGE 更新年级
deleteGradeAction GRADE_MANAGE 删除年级
createDepartmentAction SCHOOL_MANAGE 创建部门
updateDepartmentAction SCHOOL_MANAGE 更新部门
deleteDepartmentAction SCHOOL_MANAGE 删除部门
createAcademicYearAction SCHOOL_MANAGE 创建学年
updateAcademicYearAction SCHOOL_MANAGE 更新学年
deleteAcademicYearAction SCHOOL_MANAGE 删除学年

导出函数 (data-access.ts)

函数 被使用
getSchools() admin 学校管理, onboarding
getGrades() admin 年级管理, exams, onboarding
getDepartments() admin 部门管理
getAcademicYears() admin 学年管理
getStaffOptions() school 组件 (年级主任选择)
getGradesForStaff(staffId) grade_head 视图

Schema (schema.ts)

CreateSchoolSchema

  • 类型Zod schema
  • 定义:创建学校的校验 schemaname, code
  • 被使用:createSchoolAction

CreateGradeSchema

  • 类型Zod schema
  • 定义:创建年级的校验 schemaschoolId, name, order, gradeHeadId?, teachingHeadId?
  • 被使用:createGradeAction

CreateDepartmentSchema

  • 类型Zod schema
  • 定义:创建部门的校验 schemaname, description?
  • 被使用:createDepartmentAction

CreateAcademicYearSchema

  • 类型Zod schema
  • 定义:创建学年的校验 schemaname, startDate, endDate, isActive?
  • 被使用:createAcademicYearAction

类型/接口

SchoolListItem

  • 定义:学校列表项类型(含 id, name, code
  • 被使用admin 学校管理

GradeListItem

  • 定义:年级列表项类型(含 schoolId, name, gradeHeadId?
  • 被使用admin 年级管理, exams

DepartmentListItem

  • 定义:部门列表项类型
  • 被使用admin 部门管理

AcademicYearListItem

  • 定义:学年列表项类型
  • 被使用admin 学年管理

StaffOption

  • 定义:员工选项类型(含 id, name
  • 被使用school 组件 (年级主任选择)

导出组件 (components/)

组件文件 功能
school-form.tsx 学校创建/编辑表单
grade-form.tsx 年级创建/编辑表单
department-form.tsx 部门创建/编辑表单
academic-year-form.tsx 学年创建/编辑表单

模块dashboard

模块职责

各角色仪表盘数据聚合与展示。

导出函数 (data-access.ts)

getAdminDashboardData

  • 签名:getAdminDashboardData(scope?: DataScope): Promise<AdminDashboardData>
  • 依赖:shared/db, DataScope
  • 被使用admin/dashboard/page.tsx

类型/接口

StudentDashboardProps

  • 被使用student-dashboard.tsx
  • 依赖:homework/types.StudentDashboardGradeProps

StudentDashboard

  • 定义:学生仪表盘组件(原 StudentDashboardView,已重命名)
  • 被使用student/dashboard/page.tsx

TeacherDashboardData

  • 被使用teacher-dashboard-view.tsx
  • 依赖:homework/data-access.getTeacherGradeTrends, classes/data-access.getTeacherClasses

TeacherDashboardProps

  • 定义:教师仪表盘组件 Props 类型
  • 被使用teacher-dashboard-view.tsx

AdminDashboardData

  • 定义:管理员仪表盘数据类型(含 activeSessionsCount, userCount, userRoleCounts, classCount 等)
  • 被使用admin/dashboard/page.tsx

DashboardWidget

  • 定义:仪表盘通用小组件类型(含 title, value, trend? 等)
  • 被使用dashboard/components

导出组件 (components/)

组件文件 功能
admin-dashboard-view.tsx 管理员仪表盘视图
teacher-dashboard-view.tsx 教师仪表盘视图
student-dashboard.tsx 学生仪表盘视图(原 StudentDashboardView
parent-dashboard-view.tsx 家长仪表盘视图
dashboard-card.tsx 仪表盘卡片
dashboard-widget.tsx 仪表盘小组件
dashboard-stat.tsx 统计数据展示
dashboard-chart.tsx 图表组件
dashboard-schedule.tsx 课表展示
dashboard-assignment-list.tsx 作业列表
dashboard-assignment-item.tsx 作业项
dashboard-grade-trend.tsx 成绩趋势
dashboard-class-list.tsx 班级列表
dashboard-submission-list.tsx 提交列表
dashboard-empty.tsx 仪表盘空状态
dashboard-header.tsx 仪表盘头部

模块layout

模块职责

应用布局框架:侧边栏、顶栏、导航配置。

导出组件

AppSidebar

  • 内部使用:usePermission, NAV_CONFIG
  • 功能:根据权限渲染侧边栏导航

SiteHeader

  • 内部使用:useSession, signOut, NotificationDropdown(来自 messaging 模块), GlobalSearch(来自 shared/components, Breadcrumb
  • 功能:顶部导航栏(含全局搜索 GlobalSearch、通知下拉菜单展示未读通知数、面包屑导航、用户下拉菜单

SidebarProvider

  • Props: { children: React.ReactNode, defaultOpen?: boolean }
  • 功能:侧边栏状态上下文 Provider管理展开/折叠状态)
  • 被使用app/layout.tsx

导出 Hooks

useSidebar

  • 签名:useSidebar(): { isOpen, toggle, setOpen, isMobile, openMobile, setOpenMobile }
  • 功能:访问侧边栏状态(需在 SidebarProvider 内使用)
  • 被使用app-sidebar.tsx, site-header.tsx

类型/接口

Role

  • 定义:type Role = "admin" | "teacher" | "student" | "parent" | "grade_head" | "teaching_head"
  • 被使用NAV_CONFIG, usePermission

NavItem

  • 定义:{ title: string; href: string; icon?: string; permission?: Permission; children?: NavItem[] }
  • 被使用NAV_CONFIG, app-sidebar.tsx

导出配置

NAV_CONFIG

  • 类型:Record<Role, NavItem[]>
  • 每个NavItem含 permission?: Permission 字段
  • admin 角色菜单包含 "Audit Logs" 项icon: ScrollText, href: /admin/audit-logs, permission: Permissions.AUDIT_LOG_READ含子项 Operation Logs 与 Login Logs
  • admin 角色菜单的 "School Management" 子菜单包含 "Course Plans" 项href: /admin/course-plans, permission: Permissions.COURSE_PLAN_MANAGE
  • admin 角色菜单的 "School Management" 子菜单包含 "Import Users" 项href: /admin/users/import, permission: Permissions.USER_MANAGE
  • admin 角色菜单包含 "Scheduling" 项icon: CalendarClock, href: /admin/scheduling/rules, permission: Permissions.SCHEDULE_ADJUST含子项 Rules (/admin/scheduling/rules, permission: SCHEDULE_ADJUST)、Auto Schedule (/admin/scheduling/auto, permission: SCHEDULE_AUTO)、Change Requests (/admin/scheduling/changes, permission: SCHEDULE_ADJUST)
  • teacher 角色菜单包含 "Grades" 项icon: GraduationCap, permission: Permissions.GRADE_RECORD_READ含子项 All Grades (/teacher/grades)、Batch Entry (/teacher/grades/entry, permission: GRADE_RECORD_MANAGE)、Statistics (/teacher/grades/stats)、Analytics (/teacher/grades/analytics, permission: GRADE_RECORD_READ)
  • teacher 角色菜单包含 "Course Plans" 项icon: CalendarRange, href: /teacher/course-plans, permission: Permissions.COURSE_PLAN_READ
  • teacher 角色菜单包含 "Attendance" 项icon: CalendarCheck, href: /teacher/attendance, permission: Permissions.ATTENDANCE_MANAGE含子项 Records (/teacher/attendance)、Take Attendance (/teacher/attendance/sheet, permission: ATTENDANCE_MANAGE)、Statistics (/teacher/attendance/stats, permission: ATTENDANCE_READ)
  • teacher 角色菜单包含 "Schedule Changes" 项icon: CalendarClock, href: /teacher/schedule-changes, permission: Permissions.SCHEDULE_ADJUST
  • teacher 角色菜单包含 "Diagnostic" 项icon: Stethoscope, href: /teacher/diagnostic, permission: Permissions.DIAGNOSTIC_READ
  • student 角色菜单包含 "My Grades" 项icon: GraduationCap, href: /student/grades, permission: Permissions.GRADE_RECORD_READ
  • student 角色菜单包含 "Attendance" 项icon: CalendarCheck, href: /student/attendance, permission: Permissions.ATTENDANCE_READ
  • student 角色菜单包含 "Diagnostic" 项icon: Stethoscope, href: /student/diagnostic, permission: Permissions.DIAGNOSTIC_READ
  • parent 角色菜单包含 "Dashboard" 项icon: LayoutDashboard, href: /parent/dashboard无 permission 字段,仅需登录)
  • parent 角色菜单包含 "Grades" 项icon: GraduationCap, href: /parent/grades, permission: Permissions.GRADE_RECORD_READ
  • parent 角色菜单包含 "Attendance" 项icon: CalendarCheck, href: /parent/attendance, permission: Permissions.ATTENDANCE_READ
  • parent 角色菜单包含 "Announcements" 项icon: Megaphone, href: /announcements, permission: Permissions.ANNOUNCEMENT_READ
  • 所有角色admin/teacher/student/parent菜单均包含 "Messages" 项icon: Mail, href: /messages, permission: Permissions.MESSAGE_READ
  • 被使用app-sidebar.tsx

模块settings

模块职责

系统设置AI Provider 配置、用户偏好、密码安全(修改密码、强度校验)。

导出函数 (actions.ts)

所有 3 个 actions 均使用 requirePermission(AI_CONFIGURE) 进行权限校验。

函数 权限 核心功能
getAiProviderSummaries() AI_CONFIGURE 获取 AI Provider 列表
upsertAiProviderAction(data) AI_CONFIGURE 创建/更新 AI Provider
testAiProviderAction(data) AI_CONFIGURE 测试 AI Provider 连通性

导出函数 (actions-password.ts)

changePasswordAction

  • 签名:(prevState: ActionState<null>, formData: FormData) => Promise<ActionState<null>>
  • 权限:requireAuth()(任何登录用户可修改自己的密码)
  • 功能:修改当前用户密码(校验当前密码、新密码策略、速率限制 PASSWORD_CHANGE: 5次/分钟)
  • 依赖:requireAuth, validatePassword, rateLimit, bcryptjs (hash/compare), shared/db (users, passwordSecurity)
  • 被使用settings/components/password-change-form.tsx

类型/接口

AiProviderSummary

  • 定义AI Provider 摘要类型(含 id, provider, baseUrl, model, apiKeyLast4, isDefault 等,不含完整 apiKey
  • 被使用getAiProviderSummaries, settings/components

导出组件 (components/)

组件文件 功能
ai-provider-list.tsx AI Provider 列表
ai-provider-form.tsx AI Provider 创建/编辑表单
ai-provider-card.tsx AI Provider 卡片
ai-provider-test-dialog.tsx AI Provider 测试对话框
ai-provider-actions.tsx AI Provider 操作菜单
settings-layout.tsx 设置页面布局
password-change-form.tsx 密码修改表单(当前密码/新密码/确认密码 + 强度指示器 + 需求提示)
notification-preferences-form.tsx 通知偏好表单Delivery Channels: push/email/sms + Notification Categories: messages/announcements/homework/grades/attendanceSwitch 切换 + 隐藏 checkbox 提交useActionState 调用 updateNotificationPreferencesActiontoast 反馈)
admin-settings-view.tsx 管理员设置视图General/Appearance/Security/Notifications tabSecurity 含 PasswordChangeFormNotifications 含 NotificationPreferencesForm接收 notificationPreferences prop
teacher-settings-view.tsx 教师设置视图(同上,含 Notifications tab
student-settings-view.tsx 学生设置视图(同上,含 Notifications tab

模块users

模块职责

用户个人资料管理:当前用户查看与更新自己的资料;用户批量导入/导出Excel

模块路径

src/modules/users

导出函数 (actions.ts)

updateUserProfile

  • 签名:(prevState: ActionState<string> | null, formData: FormData) => Promise<ActionState<string>>
  • 功能更新当前用户个人资料name, phone, address, gender, age 等)
  • 依赖:requireAuth(), shared/db
  • 被使用profile-form.tsx

注:本模块仅使用 requireAuth() 校验登录状态,不涉及权限点(用户只能修改自己的资料)。

downloadUserTemplateAction

  • 签名:() => Promise<ActionState<string>>
  • 权限:requirePermission(USER_MANAGE)
  • 功能:生成用户导入模板(返回 base64 编码的 Excel
  • 依赖:requirePermission, import-export.generateUserImportTemplate
  • 被使用components/user-import-dialog.tsx

importUsersAction

  • 签名:(prevState: ActionState<UserImportResult> | null, formData: FormData) => Promise<ActionState<UserImportResult>>
  • 权限:requirePermission(USER_MANAGE)
  • 功能:导入用户:接收文件,解析+验证+批量创建(默认密码 123456
  • 依赖:requirePermission, shared/lib/excel.parseExcel, import-export.parseUserImportData, import-export.batchImportUsers
  • 被使用components/user-import-dialog.tsx

exportUsersAction

  • 签名:(role?: string) => Promise<ActionState<{ buffer: string; filename: string }>>
  • 权限:requirePermission(USER_MANAGE)
  • 功能:导出用户列表(返回 base64 编码的 Excel
  • 依赖:requirePermission, import-export.exportUsersToExcel
  • 被使用:待扩展

导出函数 (data-access.ts)

getUserProfile

  • 签名:(userId: string) => Promise<UserProfile | null>
  • 功能:获取用户个人资料(含 name, email, phone, address, gender, age, grade, department 等)
  • 依赖:shared/db
  • 被使用profile/page.tsx, profile-form.tsx

导出函数 (import-export.ts)

generateUserImportTemplate

  • 签名:() => Promise<Buffer>
  • 功能:生成用户导入模板(列:姓名/邮箱/角色/手机/班级邀请码,含示例行)
  • 依赖:shared/lib/excel.generateTemplate
  • 被使用:downloadUserTemplateAction

parseUserImportData

  • 签名:(rows: Record<string, unknown>[]) => UserImportValidation
  • 功能:解析并验证导入行(校验姓名/邮箱格式/角色枚举/邀请码仅 student
  • 依赖:无
  • 被使用:importUsersAction

batchImportUsers

  • 签名:(records: UserImportRecord[]) => Promise<UserImportResult>
  • 功能:批量创建用户(默认密码 123456 bcrypt 哈希,自动创建 usersToRolesstudent 通过邀请码自动加入班级)
  • 依赖:shared/db, bcryptjs, @paralleldrive/cuid2
  • 被使用:importUsersAction

exportUsersToExcel

  • 签名:(params: { scope: DataScope; role?: string }) => Promise<Buffer>
  • 功能:导出用户列表到 Excel含姓名/邮箱/手机/性别/年龄/角色/创建时间)
  • 依赖:shared/db, shared/lib/excel.exportToExcel
  • 被使用:exportUsersAction, app/api/export/route.ts

类型/接口

UserProfile

  • 定义:用户资料类型(含 id, name, email, phone, address, gender, age, gradeId?, departmentId?, onboardedAt? 等)
  • 被使用profile/page.tsx, profile-form.tsx

UpdateUserProfileInput

  • 定义更新用户资料输入类型name?, phone?, address?, gender?, age? 等可选字段)
  • 被使用:updateUserProfile, profile-form.tsx

UserImportRecord

  • 定义:{ name, email, role, phone?, invitationCode? }
  • 被使用:parseUserImportData, batchImportUsers

UserImportValidation

  • 定义:{ valid: UserImportRecord[], invalid: Array<{ row, record, errors }> }
  • 被使用:parseUserImportData

UserImportResult

  • 定义:{ successCount, failedCount, errors: Array<{ row, email, error }> }
  • 被使用:batchImportUsers, importUsersAction

导出组件 (components/)

组件文件 功能
user-import-dialog.tsx 用户批量导入对话框4 状态idle/preview/importing/done下载模板→上传预览→确认导入→结果展示

模块audit

模块职责

操作日志与登录日志查询:提供审计日志的列表展示、筛选与分页能力,支撑管理员审计与合规需求。

模块路径

src/modules/audit

导出函数 (data-access.ts)

getAuditLogs

  • 签名:getAuditLogs(params?: AuditLogQueryParams): Promise<PaginatedResult<AuditLog>>
  • 参数说明:params: AuditLogQueryParams含 userId?, module?, action?, status?, page?, pageSize?, startDate?, endDate?
  • 功能:分页查询操作日志(支持按模块/操作/状态/日期范围过滤)
  • 依赖:shared/db (auditLogs 表)
  • 被使用app/(dashboard)/admin/audit-logs/page.tsx

getLoginLogs

  • 签名:getLoginLogs(params?: LoginLogQueryParams): Promise<PaginatedResult<LoginLog>>
  • 参数说明:params: LoginLogQueryParams含 userId?, action?, status?, page?, pageSize?, startDate?, endDate?
  • 功能:分页查询登录日志(支持按操作/状态/日期范围过滤)
  • 依赖:shared/db (loginLogs 表)
  • 被使用app/(dashboard)/admin/audit-logs/login-logs/page.tsx

getAuditModuleOptions

  • 签名:getAuditModuleOptions(): Promise<string[]>
  • 功能:获取操作日志中所有不同的 module 值(用于筛选下拉框)
  • 依赖:shared/db (auditLogs 表)
  • 被使用app/(dashboard)/admin/audit-logs/page.tsx

getDataChangeLogs

  • 签名:getDataChangeLogs(params?: DataChangeLogQueryParams): Promise<PaginatedResult<DataChangeLog>>
  • 参数说明:params: DataChangeLogQueryParams含 tableName?, recordId?, action?, userId?, page?, pageSize?, startDate?, endDate?
  • 功能:分页查询数据变更日志(支持按表名/记录ID/操作/用户/日期范围过滤)
  • 依赖:shared/db (dataChangeLogs 表)
  • 被使用:getDataChangeLogsAction

getDataChangeStats

  • 签名:getDataChangeStats(): Promise<DataChangeStat[]>
  • 功能:按 tableName 分组统计数据变更日志数量(用于统计卡片)
  • 依赖:shared/db (dataChangeLogs 表)
  • 被使用:getDataChangeLogsAction

getDataChangeTableOptions

  • 签名:getDataChangeTableOptions(): Promise<string[]>
  • 功能:获取数据变更日志中所有不同的 tableName 值(用于筛选下拉框)
  • 依赖:shared/db (dataChangeLogs 表)
  • 被使用:getDataChangeLogsAction

getDataChangeLogsForExport

  • 签名:getDataChangeLogsForExport(params?: DataChangeLogQueryParams): Promise<DataChangeLog[]>
  • 功能:导出用:按条件查询全部数据变更日志(取前 100 条,无分页上限封顶)
  • 依赖:getDataChangeLogs
  • 被使用:exportDataChangeLogsAction

getAuditLogsForExport

  • 签名:getAuditLogsForExport(params?: AuditLogQueryParams): Promise<AuditLog[]>
  • 功能:导出用:按条件查询全部操作日志(取前 100 条)
  • 依赖:getAuditLogs
  • 被使用:exportAuditLogsAction

getLoginLogsForExport

  • 签名:getLoginLogsForExport(params?: LoginLogQueryParams): Promise<LoginLog[]>
  • 功能:导出用:按条件查询全部登录日志(取前 100 条)
  • 依赖:getLoginLogs
  • 被使用:exportLoginLogsAction

导出函数 (actions.ts)

所有 actions 均使用 requirePermission(AUDIT_LOG_READ) 进行权限校验(数据变更日志复用 AUDIT_LOG_READ 权限)。

函数 权限 核心功能
getDataChangeLogsAction AUDIT_LOG_READ 获取数据变更日志(分页结果 + tableOptions + stats 三者并行加载)
exportAuditLogsAction AUDIT_LOG_READ 导出操作日志为 Excel返回 { buffer, filename }
exportLoginLogsAction AUDIT_LOG_READ 导出登录日志为 Excel返回 { buffer, filename }
exportDataChangeLogsAction AUDIT_LOG_READ 导出数据变更日志为 Excel返回 { buffer, filename }

类型/接口 (types.ts)

AuditLog

  • 定义:操作日志类型(含 id, userId, userName, action, module, targetId, targetType, detail, ipAddress, userAgent, status, createdAt
  • 被使用audit/components, audit/data-access

LoginLog

  • 定义:登录日志类型(含 id, userId, userEmail, action, status, ipAddress, userAgent, errorMessage, createdAt
  • 被使用audit/components, audit/data-access

AuditLogQueryParams

  • 定义:操作日志查询参数类型(含 userId?, module?, action?, status?, page?, pageSize?, startDate?, endDate?
  • 被使用:getAuditLogs, audit-logs/page.tsx

LoginLogQueryParams

  • 定义:登录日志查询参数类型(含 userId?, action?, status?, page?, pageSize?, startDate?, endDate?
  • 被使用:getLoginLogs, login-logs/page.tsx

PaginatedResult<T>

  • 定义:分页结果接口(含 items: T[], total, page, pageSize, totalPages
  • 被使用:getAuditLogs, getLoginLogs, getDataChangeLogs, audit/components

DataChangeAction

  • 定义:"create" | "update" | "delete"
  • 被使用data-access, change-logger, types.DataChangeLog

DataChangeLog

  • 定义:数据变更日志类型(含 id, tableName, recordId, action, oldValue, newValue, changedBy, changedByName, ipAddress, createdAt
  • 被使用audit/data-access, audit/actions

DataChangeStat

  • 定义:{ tableName: string; count: number }(按表名分组的变更统计)
  • 被使用:getDataChangeStats, getDataChangeLogsAction

DataChangeLogQueryParams

  • 定义:数据变更日志查询参数类型(含 tableName?, recordId?, action?, userId?, page?, pageSize?, startDate?, endDate?
  • 被使用:getDataChangeLogs, getDataChangeLogsForExport, getDataChangeLogsAction, exportDataChangeLogsAction

导出组件 (components/)

组件文件 功能
audit-log-table.tsx 操作日志表格(含分页控件)
audit-log-filters.tsx 操作日志筛选器(模块/操作/状态/日期,基于 nuqs
audit-log-view.tsx 操作日志视图(筛选+表格+URL 分页)
login-log-table.tsx 登录日志表格(含分页控件)
login-log-filters.tsx 登录日志筛选器(操作/状态/日期,基于 nuqs
login-log-view.tsx 登录日志视图(筛选+表格+URL 分页)

模块announcements

模块职责

通知公告系统:创建、编辑、发布、归档、删除公告,所有登录用户可查看已发布公告。

模块路径

src/modules/announcements

导出函数 (actions.ts)

所有 manage actions 均使用 requirePermission(ANNOUNCEMENT_MANAGE) 进行权限校验。

函数 权限 核心功能
createAnnouncementAction ANNOUNCEMENT_MANAGE 创建公告(草稿/已发布)
updateAnnouncementAction ANNOUNCEMENT_MANAGE 更新公告
deleteAnnouncementAction ANNOUNCEMENT_MANAGE 删除公告
publishAnnouncementAction ANNOUNCEMENT_MANAGE 发布公告(设置 published 状态)
archiveAnnouncementAction ANNOUNCEMENT_MANAGE 归档公告
getAnnouncementsAction requireAuth 获取公告列表(所有登录用户可读)

导出函数 (data-access.ts)

函数 签名 被使用
getAnnouncements (params?: { status?, type?, page?, pageSize? }) => Promise<Announcement[]> admin/announcements, announcements 页面
getAnnouncementById (id: string) => Promise<Announcement | null> 编辑页面

Schema (schema.ts)

CreateAnnouncementSchema

  • 类型Zod schema
  • 定义:创建公告的校验 schematitle, content, type, status, targetGradeId?, targetClassId?, publishedAt?
  • 被使用:createAnnouncementAction

UpdateAnnouncementSchema

  • 类型Zod schema
  • 定义:更新公告的校验 schema同上
  • 被使用:updateAnnouncementAction

类型/接口

Announcement

  • 定义:公告完整类型(含 id, title, content, type, status, targetGradeId, targetClassId, authorId, authorName, publishedAt, createdAt, updatedAt
  • 被使用announcements/components, 页面

AnnouncementListItem

  • 定义:公告列表项类型(同 Announcement
  • 被使用:列表页

AnnouncementStatus

  • 定义:"draft" | "published" | "archived"
  • 被使用data-access, components

AnnouncementType

  • 定义:"school" | "grade" | "class"
  • 被使用data-access, components

GetAnnouncementsParams

  • 定义查询参数类型status?, type?, page?, pageSize?
  • 被使用:getAnnouncements, getAnnouncementsAction

导出组件 (components/)

组件文件 功能
announcement-list.tsx 公告列表(支持状态筛选)
announcement-card.tsx 单条公告卡片
announcement-form.tsx 创建/编辑表单
announcement-detail.tsx 详情查看(含发布/归档/删除操作)
admin-announcements-view.tsx 管理端公告视图(列表+创建对话框)

模块files

模块职责

文件上传与管理:通过 API 路由处理文件上传(保存到 public/uploads/YYYY-MM/),记录文件元数据到 DB支持按关联资源exam/textbook/question/announcement多态查询、下载与删除。

模块路径

src/modules/files

导出函数 (data-access.ts)

函数 签名 被使用
createFileAttachment (data: CreateFileAttachmentInput) => Promise<FileAttachment | null> app/api/upload/route.ts
getFileAttachment (id: string) => Promise<FileAttachment | null> app/api/files/[id]/route.ts
getFileAttachmentsByTarget (targetType: string, targetId: string) => Promise<FileAttachment[]> 按关联资源查询文件列表
getFileAttachmentsByUploader (uploaderId: string) => Promise<FileAttachment[]> 按上传者查询文件列表
getAllFileAttachments (limit?: number) => Promise<FileAttachment[]> app/(dashboard)/admin/files/page.tsx
deleteFileAttachment (id: string) => Promise<boolean> app/api/files/[id]/route.ts
deleteFileAttachments (ids: string[]) => Promise<BatchDeleteResult> app/api/files/batch-delete/route.ts(批量删除 DB 记录,失败回退逐条删除)
getFileAttachmentsWithFilters (params: FileAttachmentQueryParams) => Promise<FileAttachment[]> 管理员文件筛选mimeType 精确/前缀匹配 + originalName/filename 模糊搜索 + limit/offset 分页)
getFileStats () => Promise<FileStats> 文件统计(总数、总大小、按 mimeType 分组)
getFileAttachmentsByIds (ids: string[]) => Promise<FileAttachment[]> app/api/files/batch-delete/route.ts(批量删除前获取磁盘路径)

类型/接口 (types.ts)

FileAttachment

  • 定义:文件附件完整类型(含 id, filename, originalName, mimeType, size, storagePath, url, uploaderId, targetType, targetId, createdAt
  • 被使用files/components, data-access, API 路由

FileUploadResult

  • 定义:上传成功返回类型 { id, url, filename, originalName, size, mimeType }
  • 被使用:app/api/upload/route.ts 响应, file-upload.tsx 回调

FileTargetType

  • 定义:"exam" | "textbook" | "question" | "announcement"
  • 被使用types.FileAttachment.targetType, file-upload.tsx

CreateFileAttachmentInput

  • 定义:创建文件附件记录的输入类型
  • 被使用:createFileAttachment

导出组件 (components/)

组件文件 功能
file-upload.tsx 文件上传组件(拖拽+点击上传,进度条,文件类型校验,调用 /api/upload
file-list.tsx 文件列表展示(图标、文件名、大小、下载链接、删除按钮)
file-preview.tsx 文件预览图片直接预览PDF iframe其他下载
file-icon.tsx 根据 MIME 类型显示不同图标与颜色
admin-files-view.tsx 管理端文件视图(上传+列表+删除)

API 路由

POST /api/upload

  • 文件:app/api/upload/route.ts
  • 功能:接收 multipart/form-data,保存文件到 public/uploads/YYYY-MM/cuid.ext,写入 DB返回 FileUploadResult
  • 权限:requireAuth()(需登录)
  • 限制10MB、白名单 MIME 类型

GET /api/files/[id]

  • 文件:app/api/files/[id]/route.ts
  • 功能:获取文件元数据
  • 权限:requireAuth()

DELETE /api/files/[id]

  • 文件:app/api/files/[id]/route.ts
  • 功能删除文件DB 记录 + 磁盘文件)
  • 权限:requirePermission(FILE_DELETE)

POST /api/files/batch-delete

  • 文件:app/api/files/batch-delete/route.ts
  • 功能:批量删除文件(先查文件记录,通过 storageProvider.delete 删除磁盘文件静默失败,再调用 deleteFileAttachments 删除 DB 记录)
  • 权限:requirePermission(FILE_DELETE)
  • 请求体JSON { ids: string[] }
  • 响应:{ success, message, deletedCount, failedIds }

POST /api/export

  • 文件:app/api/export/route.ts
  • 功能Excel 导出grades/users/attendancetype 分发到 exportGradeRecordsToExcel/exportUsersToExcel,返回 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 二进制流
  • 权限:requireAuth()(需登录)
  • 请求体JSON { type: "grades" | "users" | "attendance", params?: Record<string, unknown> }

POST /api/import

  • 文件:app/api/import/route.ts
  • 功能Excel 解析预览(不写 DB接收 Excel 文件,调用 parseExcel 返回 sheets 预览数据(实际导入由 users/actions.importUsersAction 完成)
  • 权限:requirePermission(USER_MANAGE)
  • 请求体:multipart/form-data,字段 file
  • 限制:仅 .xlsx/.xls10MB 上限

模块grades

模块职责

成绩分析模块:成绩录入(单条/批量、查询、统计报表均分、中位数、标准差、及格率、优秀率、班级排名、Excel 导出(成绩明细+统计汇总/班级多科目横向对比)、趋势对比分析(成绩趋势、班级对比、科目对比、分数分布、排名趋势)。

模块路径

src/modules/grades

导出函数 (actions.ts)

所有 manage actions 均使用 requirePermission(GRADE_RECORD_MANAGE) 进行权限校验read actions 使用 requirePermission(GRADE_RECORD_READ)

函数 权限 核心功能
createGradeRecordAction GRADE_RECORD_MANAGE 创建单条成绩记录
batchCreateGradeRecordsAction GRADE_RECORD_MANAGE 批量录入成绩(班级+科目+考试,表格形式)
updateGradeRecordAction GRADE_RECORD_MANAGE 更新成绩记录
deleteGradeRecordAction GRADE_RECORD_MANAGE 删除成绩记录
getGradeRecordsAction GRADE_RECORD_READ 查询成绩列表(按 scope 过滤)
getClassGradeStatsAction GRADE_RECORD_READ 获取班级成绩统计
getStudentGradeSummaryAction GRADE_RECORD_READ 获取学生成绩汇总(学生/家长只能查自己/子女)
getClassRankingAction GRADE_RECORD_READ 获取班级排名
getGradeRecordByIdAction GRADE_RECORD_READ 获取单条成绩记录
exportGradesAction GRADE_RECORD_READ 导出成绩到 Exceldetail=成绩明细+统计汇总class=班级多科目横向对比总表),返回 base64 buffer

导出函数 (actions-analytics.ts)

所有 analytics actions 均使用 requirePermission(GRADE_RECORD_READ) 进行权限校验。

函数 权限 核心功能
getGradeTrendAction GRADE_RECORD_READ 获取成绩趋势(按学生/科目/学期,返回归一化分数趋势点)
getClassComparisonAction GRADE_RECORD_READ 获取班级对比(同年级各班的均分/及格率/优秀率)
getSubjectComparisonAction GRADE_RECORD_READ 获取科目对比(同班级各科目雷达图数据)
getGradeDistributionAction GRADE_RECORD_READ 获取分数分布90-100/80-89/70-79/60-69/<60 各区间人数)
getRankingTrendAction GRADE_RECORD_READ 获取排名趋势(学生历次考试排名变化,含 DataScope 二次校验)

导出函数 (data-access.ts)

函数 签名 被使用
getGradeRecords (params: GradeQueryParams & { scope: DataScope; currentUserId?: string }) => Promise<GradeRecordListItem[]> teacher/grades/page.tsx, getGradeRecordsAction
getGradeRecordById (id: string) => Promise<GradeRecord | null> getGradeRecordByIdAction
createGradeRecord (data: CreateGradeRecordInput, recordedBy: string) => Promise<string> createGradeRecordAction
batchCreateGradeRecords (data: BatchCreateGradeRecordInput, recordedBy: string) => Promise<number> batchCreateGradeRecordsAction
updateGradeRecord (id: string, data: UpdateGradeRecordInput) => Promise<void> updateGradeRecordAction
deleteGradeRecord (id: string) => Promise<void> deleteGradeRecordAction
getClassGradeStats (classId, subjectId?, examId?) => Promise<GradeStats | null> getClassGradeStatsAction
getStudentGradeSummary (studentId: string) => Promise<StudentGradeSummary | null> getStudentGradeSummaryAction, student/grades, parent/grades
getClassRanking (classId, subjectId?, examId?) => Promise<ClassRankingItem[]> getClassRankingAction, teacher/grades/stats
getClassStudentsForEntry (classId: string) => Promise<Array<{ id, name, email }>> teacher/grades/entry
getClassGradeStatsWithMeta (classId, subjectId?, examId?) => Promise<ClassGradeStats | null> teacher/grades/stats

导出函数 (data-access-analytics.ts)

函数 签名 被使用
getGradeTrend (params: { studentId; subjectId?; semester?; scope: DataScope }) => Promise<GradeTrendResult> getGradeTrendAction, teacher/grades/analytics
getClassComparison (params: { gradeId; subjectId; examId?; scope: DataScope }) => Promise<ClassComparisonItem[]> getClassComparisonAction, teacher/grades/analytics
getSubjectComparison (params: { classId; examId?; semester?; scope: DataScope }) => Promise<SubjectComparisonItem[]> getSubjectComparisonAction, teacher/grades/analytics
getGradeDistribution (params: { classId; subjectId?; examId?; scope: DataScope }) => Promise<GradeDistributionResult> getGradeDistributionAction, teacher/grades/analytics

导出函数 (data-access-ranking.ts)

函数 签名 被使用
getRankingTrend (studentId: string, subjectId?, semester?) => Promise<RankingTrendResult | null> getRankingTrendAction

导出函数 (export.ts)

exportGradeRecordsToExcel

  • 签名:(params: { classId: string; subjectId?: string; examId?: string; scope: DataScope }) => Promise<Buffer>
  • 功能导出成绩单Sheet1 成绩明细Sheet2 统计汇总:均分/中位数/最高分/最低分/标准差/及格率/优秀率/参考人数)
  • 依赖:shared/lib/excel.exportToExcel, data-access.getGradeRecords, data-access.getClassGradeStats
  • 被使用:exportGradesAction, app/api/export/route.ts

exportClassGradeReportToExcel

  • 签名:(params: { classId: string; scope: DataScope }) => Promise<Buffer>
  • 功能:导出班级成绩总表(多科目横向对比,含总分/平均分/排名列)
  • 依赖:shared/db, shared/lib/excel.exportToExcel, data-access.getGradeRecords
  • 被使用:exportGradesAction

formatDateForFile

  • 签名:(d?: Date) => string
  • 功能:格式化日期为 YYYY-MM-DD 用于文件名
  • 依赖:无
  • 被使用:exportGradesAction

Schema (schema.ts)

CreateGradeRecordSchema

  • 类型Zod schema
  • 定义:创建成绩记录的校验 schemastudentId, classId, subjectId, examId?, title, score, fullScore?, type?, semester?, remark?
  • 被使用:createGradeRecordAction

BatchCreateGradeRecordSchema

  • 类型Zod schema
  • 定义:批量录入成绩的校验 schemaclassId, subjectId, examId?, title, fullScore?, type?, semester?, records[{ studentId, score, remark? }]
  • 被使用:batchCreateGradeRecordsAction

UpdateGradeRecordSchema

  • 类型Zod schema
  • 定义:更新成绩记录的校验 schematitle?, score?, fullScore?, type?, semester?, remark?, examId?
  • 被使用:updateGradeRecordAction

类型/接口 (types.ts)

GradeRecord

  • 定义:成绩记录完整类型(含 id, studentId, classId, subjectId, examId, title, score, fullScore, type, semester, recordedBy, remark, createdAt, updatedAt
  • 被使用grades/data-access, grades/components

GradeRecordListItem

  • 定义:成绩列表项类型(含 studentName, className, subjectName, recorderName 等关联名称)
  • 被使用grades/components, teacher/grades

GradeStats

  • 定义成绩统计类型average, median, max, min, stdDev, passRate, excellentRate, count
  • 被使用grades/components, teacher/grades/stats

ClassGradeStats

  • 定义班级成绩统计类型classId, className, stats: GradeStats, studentCount
  • 被使用grades/components, teacher/grades/stats

StudentGradeSummary

  • 定义学生成绩汇总类型studentId, studentName, records[], averageScore, rank
  • 被使用grades/components, student/grades, parent/grades

ClassRankingItem

  • 定义班级排名项类型studentId, studentName, averageScore, rank, recordCount
  • 被使用grades/components, teacher/grades/stats

GradeRecordType

  • 定义:"exam" | "quiz" | "homework" | "other"
  • 被使用grades/data-access, grades/components

GradeQueryParams

  • 定义查询参数类型classId?, subjectId?, studentId?, type?, semester?, examId?
  • 被使用:getGradeRecords, getGradeRecordsAction

GradeTrendPoint / GradeTrendResult

  • 定义成绩趋势类型Point: date, title, score, fullScore, normalizedScore, typeResult: label, points[], averageScore
  • 被使用getGradeTrend, getGradeTrendAction, grade-trend-chart

ClassComparisonItem

  • 定义班级对比项类型classId, className, averageScore, passRate, excellentRate, studentCount
  • 被使用getClassComparison, getClassComparisonAction, class-comparison-chart

SubjectComparisonItem

  • 定义科目对比项类型subjectId, subjectName, averageScore, passRate, excellentRate
  • 被使用getSubjectComparison, getSubjectComparisonAction, subject-comparison-chart

GradeDistributionBucket / GradeDistributionResult

  • 定义分数分布类型Bucket: label, min, max, count, percentageResult: buckets[], totalCount
  • 被使用getGradeDistribution, getGradeDistributionAction, grade-distribution-chart

RankingTrendPoint / RankingTrendResult

  • 定义排名趋势类型Point: title, date, rank, totalStudents, scoreResult: studentName, points[]
  • 被使用getRankingTrend, getRankingTrendAction

导出组件 (components/)

组件文件 功能
grade-record-form.tsx 单条成绩录入表单
batch-grade-entry.tsx 批量录入界面(选择班级+科目+考试,表格形式录入每个学生分数)
grade-record-list.tsx 成绩列表(含删除功能)
grade-stats-card.tsx 统计卡片(均分、中位数、及格率、优秀率等)
grade-query-filters.tsx 查询筛选器(班级、科目、考试类型、学期)
student-grade-summary.tsx 学生成绩汇总视图
class-grade-report.tsx 班级成绩报表(含统计+排名)
export-button.tsx 成绩导出按钮DropdownMenu 选择 detail/class 报表类型,调用 exportGradesAction 并触发浏览器下载)
grade-trend-chart.tsx 成绩趋势折线图recharts LineChart归一化分数 0-100
class-comparison-chart.tsx 班级对比柱状图recharts BarChart均分/及格率/优秀率)
subject-comparison-chart.tsx 科目对比雷达图recharts RadarChart
grade-distribution-chart.tsx 分数分布柱状图recharts BarChart彩色区间 90-100/80-89/70-79/60-69/<60

模块course-plans

模块职责

课程计划管理:创建、编辑、删除课程计划(含周计划条目),管理员可管理全部,教师/学生/年级主任/教务主任可查看。

导出函数 (actions.ts)

createCoursePlanAction

  • 签名:(prevState: ActionState<string> | null, formData: FormData) => Promise<ActionState<string>>
  • 权限:requirePermission(COURSE_PLAN_MANAGE)
  • 功能:创建课程计划
  • 依赖:requirePermission, shared/db, data-access.createCoursePlan
  • 被以下模块使用course-plan-form.tsx

updateCoursePlanAction

  • 签名:(id: string, prevState: ActionState<string> | null, formData: FormData) => Promise<ActionState<string>>
  • 权限:requirePermission(COURSE_PLAN_MANAGE)
  • 功能:更新课程计划
  • 依赖:requirePermission, shared/db, data-access.updateCoursePlan
  • 被以下模块使用course-plan-form.tsx

deleteCoursePlanAction

  • 签名:(id: string) => Promise<ActionState<string>>
  • 权限:requirePermission(COURSE_PLAN_MANAGE)
  • 功能:删除课程计划
  • 依赖:requirePermission, shared/db, data-access.deleteCoursePlan
  • 被以下模块使用course-plan-detail.tsx

getCoursePlansAction

  • 签名:(params?: GetCoursePlansParams) => Promise<ActionState<CoursePlanListItem[]>>
  • 权限:requirePermission(COURSE_PLAN_READ)
  • 功能:获取课程计划列表
  • 依赖:requirePermission, data-access.getCoursePlans

getCoursePlanAction

  • 签名:(id: string) => Promise<ActionState<CoursePlanWithItems>>
  • 权限:requirePermission(COURSE_PLAN_READ)
  • 功能:获取课程计划详情(含周计划条目)
  • 依赖:requirePermission, data-access.getCoursePlanById

createCoursePlanItemAction

  • 签名:(prevState: ActionState<string> | null, formData: FormData) => Promise<ActionState<string>>
  • 权限:requirePermission(COURSE_PLAN_MANAGE)
  • 功能:创建周计划条目
  • 依赖:requirePermission, shared/db, data-access.createCoursePlanItem
  • 被以下模块使用course-plan-item-editor.tsx

updateCoursePlanItemAction

  • 签名:(id: string, prevState: ActionState<string> | null, formData: FormData) => Promise<ActionState<string>>
  • 权限:requirePermission(COURSE_PLAN_MANAGE)
  • 功能:更新周计划条目
  • 依赖:requirePermission, shared/db, data-access.updateCoursePlanItem
  • 被以下模块使用course-plan-item-editor.tsx

deleteCoursePlanItemAction

  • 签名:(id: string) => Promise<ActionState<string>>
  • 权限:requirePermission(COURSE_PLAN_MANAGE)
  • 功能:删除周计划条目
  • 依赖:requirePermission, shared/db, data-access.deleteCoursePlanItem
  • 被以下模块使用course-plan-item-editor.tsx

toggleCoursePlanItemCompletedAction

  • 签名:(id: string, completed: boolean) => Promise<ActionState<string>>
  • 权限:requirePermission(COURSE_PLAN_MANAGE)
  • 功能:切换周计划条目完成状态
  • 依赖:requirePermission, shared/db, data-access.updateCoursePlanItem
  • 被以下模块使用course-plan-detail.tsx

导出函数 (data-access.ts)

getCoursePlans

  • 签名:(params?: GetCoursePlansParams) => Promise<CoursePlanListItem[]>
  • 功能:查询课程计划列表(含班级/科目/教师名称,支持按 classId/teacherId/subjectId/status 过滤)
  • 依赖:shared.db, shared.db.schema.coursePlans/classes/subjects/users
  • 被以下模块使用admin/course-plans/page.tsx, teacher/course-plans/page.tsx

getCoursePlanById

  • 签名:(id: string) => Promise<CoursePlanWithItems | null>
  • 功能:按 ID 获取课程计划详情(含周计划条目列表)
  • 依赖:shared.db, shared.db.schema.coursePlans/coursePlanItems/classes/subjects/users
  • 被以下模块使用admin/course-plans/[id]/page.tsx, teacher/course-plans/[id]/page.tsx

createCoursePlan

  • 签名:(data: CreateCoursePlanInput, createdBy: string) => Promise<string>
  • 功能:创建课程计划记录
  • 依赖:shared.db, shared.db.schema.coursePlans, @paralleldrive/cuid2
  • 被以下模块使用createCoursePlanAction

updateCoursePlan

  • 签名:(id: string, data: Partial<UpdateCoursePlanInput>) => Promise<void>
  • 功能:更新课程计划(部分字段)
  • 依赖:shared.db, shared.db.schema.coursePlans
  • 被以下模块使用updateCoursePlanAction

deleteCoursePlan

  • 签名:(id: string) => Promise<void>
  • 功能:删除课程计划(级联删除周计划条目)
  • 依赖:shared.db, shared.db.schema.coursePlans
  • 被以下模块使用deleteCoursePlanAction

createCoursePlanItem / updateCoursePlanItem / deleteCoursePlanItem

  • 签名:(data: CreateCoursePlanItemInput) => Promise<string> / (id: string, data: Partial<UpdateCoursePlanItemInput>) => Promise<void> / (id: string) => Promise<void>
  • 功能:周计划条目 CRUD
  • 依赖:shared.db, shared.db.schema.coursePlanItems, @paralleldrive/cuid2
  • 被以下模块使用createCoursePlanItemAction, updateCoursePlanItemAction, deleteCoursePlanItemAction, toggleCoursePlanItemCompletedAction

reorderCoursePlanItems

  • 签名:(planId: string, items: ReorderCoursePlanItemInput[]) => Promise<void>
  • 功能:重排周计划条目顺序
  • 依赖:shared.db, shared.db.schema.coursePlanItems

getSubjectOptions

  • 签名:() => Promise<{id:string;name:string}[]>
  • 功能:获取科目选项列表
  • 依赖:shared.db, shared.db.schema.subjects
  • 被以下模块使用admin/course-plans/create/page.tsx, admin/course-plans/[id]/edit/page.tsx

Zod Schema (schema.ts)

Schema 用途
CreateCoursePlanSchema 创建课程计划校验classId, subjectId, teacherId, academicYearId?, semester?, totalHours?, weeklyHours?, startDate?, endDate?, syllabus?, objectives?, status?
UpdateCoursePlanSchema 更新课程计划校验(所有字段可选,含 completedHours?
CreateCoursePlanItemSchema 创建周计划条目校验planId, week, topic, content?, hours?, textbookChapter?, notes?
UpdateCoursePlanItemSchema 更新周计划条目校验(所有字段可选,含 isCompleted?, completedAt?

类型/接口 (types.ts)

类型 定义
CoursePlan 课程计划基础接口
CoursePlanItem 周计划条目接口
CoursePlanListItem = CoursePlan & { className, subjectName, teacherName }
CoursePlanWithItems = CoursePlanListItem & { items: CoursePlanItem[] }
CoursePlanStatus "planning" | "active" | "completed" | "paused"
CoursePlanSemester "1" | "2"
GetCoursePlansParams { classId?, teacherId?, subjectId?, status? }
ReorderCoursePlanItemInput { id, week }

导出组件 (components/)

组件文件 功能
course-plan-progress.tsx 进度条组件completedHours/totalHours 百分比)
course-plan-list.tsx 课程计划列表支持状态筛选URL 同步)
course-plan-form.tsx 创建/编辑表单(班级、科目、教师、学年、学期、状态、课时、日期、大纲、目标)
course-plan-item-editor.tsx 周计划条目编辑器Dialog支持创建/编辑/删除/切换完成)
course-plan-detail.tsx 详情视图(计划信息、进度、大纲、目标、周计划表格、删除确认)

模块parent

模块职责

家长端仪表盘:聚合家长关联子女的学习数据(课表、作业、成绩、班级),支持多子女切换查看。家长通过 parentStudentRelations 表关联子女DataScope 解析为 children 类型。

模块路径

src/modules/parent

导出函数 (data-access.ts)

所有函数使用 cache() 包装以实现请求级缓存。本模块仅用于读操作聚合,无 Server Action权限校验在页面层通过 requireAuth() 完成。

函数 签名 被使用
getChildren (parentId: string) => Promise<ParentChildRelation[]> getParentDashboardData 内部, parent/children/[studentId] 页面
getChildBasicInfo (studentId: string, relation?: string | null) => Promise<ChildBasicInfo | null> getChildDashboardData 内部
getChildDashboardData (studentId: string, relation?: string | null) => Promise<ChildDashboardData | null> parent/children/[studentId]/page.tsx, getParentDashboardData 内部
getParentDashboardData (parentId: string) => Promise<ParentDashboardData> parent/dashboard/page.tsx

getChildren

  • 依赖:shared/db (parentStudentRelations 表)
  • 功能:查询指定家长的所有子女关联记录,按 createdAt 升序

getChildBasicInfo

  • 依赖:shared/db (users, grades, classEnrollments, classes 表)
  • 功能:聚合子女基础信息(姓名、邮箱、头像、年级名称、班级名称、与家长关系)

getChildDashboardData

  • 依赖:getChildBasicInfo, classes/data-access.getStudentClasses, classes/data-access.getStudentSchedule, homework/data-access.getStudentHomeworkAssignments, homework/data-access.getStudentDashboardGrades, grades/data-access.getStudentGradeSummary
  • 功能:并行聚合单个子女的完整仪表盘数据(基础信息、已加入班级、今日课表、作业概览、成绩趋势、成绩汇总)

getParentDashboardData

  • 依赖:shared/db (users 表), getChildren, getChildDashboardData
  • 功能:聚合家长名称与所有子女的仪表盘数据

类型/接口 (types.ts)

ParentChildRelation

  • 定义:家长-子女关联记录类型id, parentId, studentId, relation, createdAt
  • 被使用:getChildren, getParentDashboardData

ChildBasicInfo

  • 定义子女基础信息类型id, name, email, image, gradeName, className, classId, relation
  • 被使用:getChildBasicInfo, ChildDashboardData.basicInfo

ChildScheduleItem

  • 定义子女今日课表项类型id, classId, className, course, startTime, endTime, location
  • 被使用:ChildDashboardData.todaySchedule, child-schedule-card.tsx

ChildHomeworkSummary

  • 定义子女作业概览类型pendingCount, submittedCount, gradedCount, overdueCount, recentAssignments
  • 被使用:ChildDashboardData.homeworkSummary, child-homework-summary.tsx

ChildDashboardData

  • 定义单个子女仪表盘数据类型basicInfo, enrolledClasses, todaySchedule, homeworkSummary, gradeTrend, gradeSummary
  • 依赖:homework/types.StudentDashboardGradeProps, homework/types.StudentHomeworkAssignmentListItem, classes/types.StudentEnrolledClass, grades/types.StudentGradeSummary
  • 被使用:getChildDashboardData, ParentDashboardData.children, 所有 child-* 组件

ParentDashboardData

  • 定义家长仪表盘数据类型parentName, children: ChildDashboardData[]
  • 被使用:getParentDashboardData, parent-dashboard.tsx

导出组件 (components/)

组件文件 功能
parent-dashboard.tsx 主容器组件(问候语、子女卡片网格、空状态)
child-card.tsx 子女卡片(头像、姓名、班级、待完成/逾期/平均分统计,点击跳转详情)
child-detail-header.tsx 子女详情页头部(返回按钮、头像、姓名、班级、年级、关系)
child-detail-panel.tsx 子女详情面板容器(组合 homework/grade/schedule 三个子组件)
child-homework-summary.tsx 子女作业概览pending/submitted/graded/overdue 统计 + 最近作业列表)
child-grade-summary.tsx 子女成绩概览Recharts 折线图趋势 + 最新分数 + 班级排名 + 最近成绩列表,"use client"
child-schedule-card.tsx 子女今日课表卡片(课程、时间、地点、班级)

模块messaging

模块职责

站内消息系统用户间私信收发支持回复链、站内通知多态类型message/announcement/homework/gradeSiteHeader 通知下拉菜单展示未读数。

模块路径

src/modules/messaging

导出函数 (actions.ts)

send actions 使用 requirePermission(MESSAGE_SEND)read actions 使用 requirePermission(MESSAGE_READ)delete actions 使用 requirePermission(MESSAGE_DELETE),通知读取使用 requireAuth()

函数 权限 核心功能
sendMessageAction MESSAGE_SEND 发送消息(同时为收件人创建通知;支持 parentMessageId 回复)
markMessageAsReadAction MESSAGE_READ 标记消息已读(设置 readAt
deleteMessageAction MESSAGE_DELETE 删除消息(仅发送者或接收者可删)
getMessagesAction MESSAGE_READ 获取消息列表(收件箱/已发送,分页)
getMessageDetailAction MESSAGE_READ 获取消息详情(含回复线程)
getRecipientsAction MESSAGE_SEND 获取可发送对象列表(按 DataScope 过滤)
getNotificationsAction requireAuth 获取当前用户通知列表(分页)
markNotificationAsReadAction requireAuth 标记单条通知已读
markAllNotificationsAsReadAction requireAuth 标记所有通知已读
getNotificationPreferencesAction requireAuth 获取当前用户通知偏好(无记录时自动创建默认记录)
updateNotificationPreferencesAction requireAuth 更新upsert当前用户通知偏好从 FormData 解析 checkbox "on" 为布尔值)

导出函数 (data-access.ts)

函数 签名 被使用
getMessages (userId: string, params?: { type?, page?, pageSize? }) => Promise<PaginatedResult<MessageListItem>> messages 页面
getMessageById (id: string, userId: string) => Promise<Message | null> 消息详情页
getMessageThread (rootId: string, userId: string) => Promise<Message[]> 消息详情页(回复链)
createMessage (input: CreateMessageInput) => Promise<Message> sendMessageAction
markMessageAsRead (id: string, userId: string) => Promise<void> markMessageAsReadAction, 详情页自动已读
deleteMessage (id: string, userId: string) => Promise<void> deleteMessageAction
getUnreadMessageCount (userId: string) => Promise<number> 待扩展
getNotifications (userId: string, params?: { page?, pageSize? }) => Promise<PaginatedResult<NotificationListItem>> 通知列表/下拉菜单
createNotification (input: CreateNotificationInput) => Promise<void> sendMessageAction内部调用
markNotificationAsRead (id: string, userId: string) => Promise<void> markNotificationAsReadAction
markAllNotificationsAsRead (userId: string) => Promise<void> markAllNotificationsAsReadAction
getUnreadNotificationCount (userId: string) => Promise<number> 待扩展
getRecipients (ctx: AuthContext) => Promise<RecipientOption[]> compose 页面(按 DataScope 过滤)

导出函数 (notification-preferences.ts)

文件标记 "server-only",使用 React cache 包装读取函数。

getNotificationPreferences

  • 签名:getNotificationPreferences(userId: string): Promise<NotificationPreferences>cache 包装)
  • 功能获取用户通知偏好若用户无记录则自动创建一条默认记录pushEnabled/homeworkNotifications/gradeNotifications/announcementNotifications/messageNotifications/attendanceNotifications 默认 trueemailEnabled/smsEnabled 默认 false并发冲突时回退到查询
  • 依赖:shared/db (notificationPreferences 表), @paralleldrive/cuid2, react (cache)
  • 被使用:getNotificationPreferencesAction, app/(dashboard)/settings/page.tsx

upsertNotificationPreferences

  • 签名:upsertNotificationPreferences(userId: string, input: UpdateNotificationPreferencesInput): Promise<NotificationPreferences | null>
  • 功能upsert 语义更新通知偏好(存在则部分字段更新,不存在则插入;未提供的字段保留原值或使用默认值)
  • 依赖:shared/db (notificationPreferences 表), @paralleldrive/cuid2
  • 被使用:updateNotificationPreferencesAction

Schema (schema.ts)

SendMessageSchema

  • 类型Zod schema
  • 定义:发送消息校验 schemareceiverId, subject?, content, parentMessageId?
  • 被使用:sendMessageAction

类型/接口

Message

  • 定义:消息完整类型(含 id, senderId, receiverId, subject, content, isRead, readAt, parentMessageId, createdAt, senderName, receiverName
  • 被使用messaging/components, 页面

MessageListItem

  • 定义:消息列表项类型(同 Message 精简版)
  • 被使用:列表页

MessageThread

  • 定义消息线程类型root + replies
  • 被使用:详情页

Notification

  • 定义:通知完整类型(含 id, userId, type, title, content, link, isRead, createdAt
  • 被使用notification-dropdown, notification-list

NotificationListItem

  • 定义:通知列表项类型(同 Notification
  • 被使用:列表页

NotificationType

  • 定义:"message" | "announcement" | "homework" | "grade"
  • 被使用data-access, components

MessageType

  • 定义:"inbox" | "sent"
  • 被使用getMessages 参数

CreateMessageInput / CreateNotificationInput

  • 定义:创建消息/通知的输入类型
  • 被使用data-access.createMessage, createNotification

RecipientOption

  • 定义:{ id: string; name: string }
  • 被使用compose 页面下拉选项

NotificationPreferences

  • 定义:通知偏好完整类型(含 id, userId, emailEnabled, smsEnabled, pushEnabled, homeworkNotifications, gradeNotifications, announcementNotifications, messageNotifications, attendanceNotifications, createdAt, updatedAt
  • 被使用:getNotificationPreferences, upsertNotificationPreferences, getNotificationPreferencesAction, updateNotificationPreferencesAction, settings/components/notification-preferences-form.tsx

UpdateNotificationPreferencesInput

  • 定义更新通知偏好的输入类型所有字段可选emailEnabled?, smsEnabled?, pushEnabled?, homeworkNotifications?, gradeNotifications?, announcementNotifications?, messageNotifications?, attendanceNotifications?;未提供则保留原值)
  • 被使用:upsertNotificationPreferences, updateNotificationPreferencesAction

导出组件 (components/)

组件文件 功能
message-list.tsx 消息列表(收件箱/已发送 Tab 切换,已读/未读标记usePermission 控制"写消息"按钮)
message-detail.tsx 消息详情(含回复线程、回复/删除操作AlertDialog 删除确认usePermission 控制按钮可见性)
message-compose.tsx 写消息表单(收件人 Select、主题 Input、内容 Textarea支持回复模式
notification-dropdown.tsx SiteHeader 通知下拉菜单Bell 图标 + 未读数 Badge滚动列表标记已读查看全部链接
notification-list.tsx 通知完整列表(全部标记已读、单条标记已读、查看链接)

模块attendance

模块职责

学生考勤管理:教师按班级/日期点名(单条/批量)、查询考勤记录、统计出勤率/迟到率,学生/家长查看本人/子女考勤汇总,管理员查看全校考勤记录。支持班级考勤规则配置(迟到阈值、早退阈值、自动标记)。

模块路径

src/modules/attendance

导出函数 (actions.ts)

所有 manage actions 均使用 requirePermission(ATTENDANCE_MANAGE) 进行权限校验read actions 使用 requirePermission(ATTENDANCE_READ)。学生/家长在 getStudentAttendanceAction 中进行 DataScope 二次校验class_members 仅查自己children 仅查子女)。

函数 权限 核心功能
recordAttendanceAction ATTENDANCE_MANAGE 创建单条考勤记录
batchRecordAttendanceAction ATTENDANCE_MANAGE 批量点名(班级+日期,表格形式录入每个学生状态)
updateAttendanceAction ATTENDANCE_MANAGE 更新考勤记录(状态、备注)
deleteAttendanceAction ATTENDANCE_MANAGE 删除考勤记录
getAttendanceAction ATTENDANCE_READ 分页查询考勤记录(按 scope 过滤)
getStudentAttendanceAction ATTENDANCE_READ 获取学生考勤汇总(含 DataScope 二次校验)
getClassAttendanceStatsAction ATTENDANCE_READ 获取班级考勤统计
getClassAttendanceForDateAction ATTENDANCE_READ 获取班级指定日期考勤(用于点名页加载已有记录)
saveAttendanceRulesAction ATTENDANCE_MANAGE 保存班级考勤规则upsert
getAttendanceRulesAction ATTENDANCE_READ 获取班级考勤规则

导出函数 (data-access.ts)

函数 签名 被使用
getAttendanceRecords (params: AttendanceQueryParams & { scope: DataScope; currentUserId?: string }) => Promise<PaginatedAttendanceResult> getAttendanceAction
getClassAttendanceForDate (classId: string, date: string) => Promise<AttendanceListItem[]> getClassAttendanceForDateAction
createAttendanceRecord (data: RecordAttendanceInput, recordedBy: string) => Promise<string> recordAttendanceAction
batchCreateAttendanceRecords (data: BatchRecordAttendanceInput, recordedBy: string) => Promise<number> batchRecordAttendanceAction
updateAttendanceRecord (id: string, data: UpdateAttendanceInput) => Promise<void> updateAttendanceAction
deleteAttendanceRecord (id: string) => Promise<void> deleteAttendanceAction
getClassStudentsForAttendance (classId: string) => Promise<Array<{ id, name, email }>> 点名页学生列表
getAttendanceRules (classId?: string) => Promise<AttendanceRule[]> getAttendanceRulesAction
upsertAttendanceRules (data: AttendanceRuleInput) => Promise<string> saveAttendanceRulesAction

导出函数 (data-access-stats.ts)

从 data-access.ts 拆分以遵守单文件 ≤300 行规则。

函数 签名 被使用
getStudentAttendanceSummary (studentId: string, startDate?: string, endDate?: string) => Promise<StudentAttendanceSummary | null> getStudentAttendanceAction, student/attendance, parent/attendance
getClassAttendanceStats (classId: string, startDate?: string, endDate?: string) => Promise<ClassAttendanceSummary | null> getClassAttendanceStatsAction, teacher/attendance/stats

Schema (schema.ts)

Schema 用途
AttendanceStatusEnum 考勤状态枚举present/absent/late/early_leave/excused
RecordAttendanceSchema 单条考勤记录校验studentId, classId, scheduleId?, date, status, remark?
BatchRecordAttendanceSchema 批量考勤校验records[{ studentId, classId, scheduleId?, date, status, remark? }]
UpdateAttendanceSchema 更新考勤校验status?, remark?, scheduleId?
AttendanceRuleSchema 考勤规则校验classId, lateThresholdMinutes?, earlyLeaveThresholdMinutes?, enableAutoMark?

类型/接口 (types.ts)

类型 定义
AttendanceStatus "present" | "absent" | "late" | "early_leave" | "excused"
AttendanceRecord 考勤记录完整类型
AttendanceListItem 列表项类型(含 studentName, className, recorderName
AttendanceStats 统计类型total, present, absent, late, earlyLeave, excused, presentRate, lateRate
StudentAttendanceSummary 学生考勤汇总studentId, studentName, stats, recentRecords
ClassAttendanceSummary 班级考勤汇总classId, className, date, stats, studentRecords
AttendanceRule 考勤规则类型classId, lateThresholdMinutes, earlyLeaveThresholdMinutes, enableAutoMark
AttendanceQueryParams 查询参数classId?, studentId?, date?, startDate?, endDate?, status?, page?, pageSize?
PaginatedAttendanceResult 分页结果items, total, page, pageSize, totalPages
ATTENDANCE_STATUS_LABELS 状态中文标签常量
ATTENDANCE_STATUS_COLORS 状态颜色常量(用于 Badge

导出组件 (components/)

组件文件 功能
attendance-sheet.tsx 批量点名表单(班级/日期选择器 + 学生表格 + 每行状态 Select + "全部标记到场"按钮)
attendance-record-list.tsx 考勤记录列表表格(含删除确认对话框)
attendance-stats-card.tsx 统计卡片(总数、到场、缺勤、迟到、早退、请假、出勤率、迟到率)
attendance-filters.tsx URL 同步筛选器(班级、状态、日期)
student-attendance-view.tsx 学生/家长视图(统计卡片 + 最近记录表格)
attendance-rules-form.tsx 考勤规则配置表单(班级选择器、迟到/早退阈值、自动标记勾选)

模块scheduling

src/modules/scheduling

排课与调课模块:管理员配置班级排课规则(每日课时、连续课时、午休、上下学时间、避免背靠背、科目均衡),自动排课引擎按规则生成周课表,调课/代课申请与审批流程,课表冲突检测。

所有 actions 均使用 requirePermission() 进行权限校验:规则配置/调课申请/冲突检测/查询使用 requirePermission(SCHEDULE_ADJUST),自动排课/应用课表/审批调课使用 requirePermission(SCHEDULE_AUTO)。admin 角色拥有 SCHEDULE_AUTO+SCHEDULE_ADJUSTteacher 角色无排课权限。

Server Actions (actions.ts)

Action 权限 用途
saveSchedulingRulesAction SCHEDULE_ADJUST 保存班级排课规则upsertclassId 为空时为全局规则)
autoScheduleAction SCHEDULE_AUTO 根据规则与科目分配生成预览课表(不落库)
applyAutoScheduleAction SCHEDULE_AUTO 将生成的课表写入 classSchedule 表(事务:先删后插)
requestScheduleChangeAction SCHEDULE_ADJUST 提交调课/代课申请status=pending
approveScheduleChangeAction SCHEDULE_AUTO 审批通过调课申请status=approved
rejectScheduleChangeAction SCHEDULE_AUTO 驳回调课申请status=rejected
getScheduleChangesAction SCHEDULE_ADJUST 查询调课申请列表(可按 classId/status/requesterId 过滤)
getClassConflictsAction SCHEDULE_ADJUST 检测班级课表时间重叠冲突

Data Access (data-access.ts)

函数 签名 被使用
getSchedulingRules (classId?: string) => Promise<SchedulingRule[]> saveSchedulingRulesAction, autoScheduleAction, admin/scheduling/rules
upsertSchedulingRules (data: SchedulingRuleInput) => Promise<string> saveSchedulingRulesAction
getScheduleChanges (params: ScheduleChangeQueryParams) => Promise<ScheduleChangeListItem[]> getScheduleChangesAction, admin/scheduling/changes, teacher/schedule-changes
createScheduleChange (data: ScheduleChangeInput, requestedBy: string) => Promise<string> requestScheduleChangeAction
updateScheduleChangeStatus (id, status, approverId) => Promise<void> approveScheduleChangeAction, rejectScheduleChangeAction
getClassConflicts (classId: string) => Promise<ScheduleConflict[]> getClassConflictsAction
getAdminClassesForScheduling () => Promise<Array<{ id, name, grade }>> 所有 scheduling 页面
getTeachersForScheduling () => Promise<Array<{ id, name, email }>> teacher/schedule-changes
getClassroomsForScheduling () => Promise<Array<{ id, name, building }>> autoScheduleAction
getClassSubjectsForScheduling (classId) => Promise<Array<{ subjectId, subjectName, teacherId }>> autoScheduleAction

Auto Scheduler (auto-scheduler.ts)

函数 用途
autoSchedule 贪心+冲突检测排课算法:按科目每周课时降序,为每节课选择第一个满足约束的时段(午休、每日窗口、班级/教师/教室冲突、每日最大课时、避免背靠背)
findOptimalSlot 在候选时段中找到第一个满足所有约束的时段
validateSchedule 校验生成的课表是否违反规则,返回冲突列表
buildDefaultTimeSlots 根据上下学时间和午休时间构建默认时段周一至周五上午4节+下午4节

Schemas (schema.ts)

Schema 用途
SchedulingRuleSchema 排课规则校验classId, maxDailyHours?, maxContinuousHours?, lunchBreakStart?, lunchBreakEnd?, morningStart?, afternoonEnd?, avoidBackToBack?, balancedSubjects?
ScheduleChangeSchema 调课申请校验classId, originalScheduleId?, originalTeacherId?, substituteTeacherId?, originalDate?, newDate?, newStartTime?, newEndTime?, reason
AutoScheduleParamsSchema 自动排课参数校验classId, rules, subjects[], teachers[], classrooms[], timeSlots[]
ScheduleChangeStatusEnum 调课状态枚举pending/approved/rejected/completed
ApproveScheduleChangeSchema 审批校验changeId, reason?

Types (types.ts)

Type 定义
ScheduleChangeStatus "pending" | "approved" | "rejected" | "completed"
SchedulingRule 排课规则完整类型
ScheduleChange 调课申请完整类型
ScheduleChangeListItem 列表项类型(含 className, originalTeacherName, substituteTeacherName, requesterName, approverName
TimeSlot { weekday, startTime, endTime }
ScheduleConflict { type, description, scheduleIds }type: teacher_overlap/classroom_overlap/class_overlap/rule_violation
AutoScheduleResult { success, scheduledCount, conflictCount, conflicts, schedules }
GeneratedSchedule { classId, weekday, startTime, endTime, course, location, teacherId, subjectId }
AutoScheduleParams { classId, rules, subjects, teachers, classrooms, timeSlots }
ScheduleChangeQueryParams { classId?, status?, requesterId? }
SCHEDULE_CHANGE_STATUS_LABELS 状态英文标签常量
SCHEDULE_CHANGE_STATUS_COLORS 状态颜色常量(用于 Badge

Components (components/)

组件 用途
scheduling-rules-form.tsx 排课规则配置表单(班级选择器、每日最大课时、连续课时、午休时间、上下学时间、避免背靠背、科目均衡)
auto-schedule-panel.tsx 自动排课面板(班级选择→预览→应用流程)
auto-schedule-result.tsx 排课结果预览(课表表格 + 冲突/警告列表)
schedule-change-form.tsx 调课/代课申请表单(班级、原任课教师、代课教师、原日期、新日期、新时间、原因)
schedule-change-list.tsx 调课申请列表表格(含审批/驳回对话框canApprove 控制审批按钮可见性)
schedule-conflicts-view.tsx 冲突检测视图(班级选择器 + 检测按钮 + 冲突结果列表)

模块proctoring

src/modules/proctoring

考试监考模块:监考模式考试实时监控、防作弊事件采集、教师监考面板、学生端防作弊监控、考试模式配置。

权限:教师监考面板使用 requirePermission(EXAM_PROCTOR);学生端上报事件使用 requireAuth()(学生上报自己的事件,不需要管理权限)。前端组件使用 usePermission().hasPermission(EXAM_PROCTOR) 控制权限。

Server Actions (actions.ts)

Action 权限 用途
recordProctoringEventAction requireAuth() 学生端上报监考事件(含 submission 归属校验)
getProctoringDashboardAction EXAM_PROCTOR 获取监考面板数据(摘要+学生状态+最近事件)

Data Access (data-access.ts)

import "server-only"

函数 签名 被使用
recordProctoringEvent (input: RecordProctoringEventInput) => Promise<ProctoringEvent> actions.recordProctoringEventAction, API /api/proctoring/event
getProctoringEvents (examId, filters?) => Promise<ProctoringEventWithDetails[]> 待扩展
getProctoringEventsBySubmission (submissionId) => Promise<ProctoringEvent[]> 待扩展
getExamProctoringSummary (examId) => Promise<ExamProctoringSummary> actions.getProctoringDashboardAction, teacher/exams/[id]/proctoring/page.tsx
getStudentProctoringStatuses (examId) => Promise<StudentProctoringStatus[]> actions.getProctoringDashboardAction, teacher/exams/[id]/proctoring/page.tsx
getExamForProctoring `(examId) => Promise<{id,title,examMode,config} null>`
getRecentProctoringEvents (examId, limit?) => Promise<ProctoringEventWithDetails[]> actions.getProctoringDashboardAction, teacher/exams/[id]/proctoring/page.tsx

Types (types.ts)

类型 定义
ProctoringEventType "tab_switch" | "window_blur" | "copy_attempt" | "paste_attempt" | "right_click" | "devtools_open" | "fullscreen_exit" | "idle_timeout"
ExamMode "homework" | "timed" | "proctored"
ProctoringEvent { id, submissionId, studentId, examId, eventType, eventDetail?, occurredAt, createdAt }
ProctoringEventWithDetails ProctoringEvent & { studentName, examTitle }
ExamProctoringSummary { examId, examTitle, examMode, totalStudents, startedStudents, submittedStudents, totalEvents, abnormalStudents, eventsByType }
StudentProctoringStatus { studentId, studentName, submissionId, submissionStatus, eventCount, lastEventAt, isAbnormal, eventsByType }
ProctoringDashboardData { summary, students, recentEvents }
ExamModeConfig { examMode, durationMinutes, shuffleQuestions, allowLateStart, lateStartGraceMinutes, antiCheatEnabled }
PROCTORING_EVENT_LABELS 事件类型中文标签常量
EXAM_MODE_LABELS 考试模式中文标签常量
ABNORMAL_EVENT_THRESHOLD 异常学生事件数阈值3

Components (components/)

组件 用途
proctoring-dashboard.tsx 教师监考面板实时学生状态、异常事件统计、异常学生高亮、10 秒轮询、usePermission 权限控制)
anti-cheat-monitor.tsx 学生端防作弊监控visibilitychange/blur/copy/paste/contextmenu/keydown/fullscreenchange 监听、空闲超时检测、强制全屏、警告提示、事件上报)
exam-mode-config.tsx 考试模式配置react-hook-form Controller作业/限时/监考模式选择,限时设置时长,监考设置防作弊选项)

API Routes

路由 方法 权限 用途
/api/proctoring/event POST requireAuth() 接收学生端上报的监考事件(含 submission 归属校验)

模块diagnostic

src/modules/diagnostic

学情诊断报告模块:基于知识点掌握度(knowledgePointMastery 表)生成个人/班级诊断报告,掌握度雷达图(学生 vs 班级平均),强项/弱项分析,知识点掌握度热力图,需重点关注学生列表,报告发布/删除管理。

权限:所有 Server Actions 使用 requirePermission() 校验。生成/发布/删除报告使用 requirePermission(DIAGNOSTIC_MANAGE),查询/详情使用 requirePermission(DIAGNOSTIC_READ)。admin/teacher/grade_head 角色拥有 DIAGNOSTIC_MANAGE+DIAGNOSTIC_READteaching_head/student 角色仅有 DIAGNOSTIC_READ。前端组件使用 usePermission().hasPermission(DIAGNOSTIC_MANAGE) 控制生成/发布/删除按钮可见性(无 role === "xxx" 硬编码)。页面路由通过 getAuthContext() 进行 DataScope 二次校验:class_members 仅查自己,children 仅查子女,class_taught 必须包含 classId。

Server Actions (actions.ts)

"use server"

Action 权限 用途
generateStudentReportAction DIAGNOSTIC_MANAGE 生成学生个人诊断报告formData: studentId, period
generateClassReportAction DIAGNOSTIC_MANAGE 生成班级诊断报告formData: classId, period
publishReportAction DIAGNOSTIC_MANAGE 发布诊断报告formData: idstatus → published
deleteReportAction DIAGNOSTIC_MANAGE 删除诊断报告formData: id
getDiagnosticReportsAction DIAGNOSTIC_READ 查询诊断报告列表params: DiagnosticReportQueryParams
getDiagnosticReportByIdAction DIAGNOSTIC_READ 获取诊断报告详情id

Data Access (data-access.ts + data-access-reports.ts)

import "server-only"(两个文件均以此开头)

data-access.ts(掌握度相关)

函数 签名 被使用
getStudentMastery (studentId: string) => Promise<MasteryWithKnowledgePoint[]> getStudentMasterySummary, teacher/diagnostic/student/[studentId]
getStudentMasterySummary (studentId: string) => Promise<StudentMasterySummary | null> generateDiagnosticReport, teacher/diagnostic/student/[studentId], student/diagnostic
updateMasteryFromSubmission (submissionId: string) => Promise<void> 待扩展(作业/考试提交后触发onDuplicateKeyUpdate upsert
getClassMasterySummary (classId: string) => Promise<ClassMasterySummary | null> generateClassDiagnosticReport, teacher/diagnostic/class/[classId]
getKnowledgePointStats (classId?: string, gradeId?: string) => Promise<KnowledgePointStat[]> teacher/diagnostic/student/[studentId](班级平均对比)

data-access-reports.ts(报告相关)

函数 签名 被使用
generateDiagnosticReport (studentId, period, generatedBy) => Promise<string> generateStudentReportAction
generateClassDiagnosticReport (classId, period, generatedBy) => Promise<string> generateClassReportAction
getDiagnosticReports (filters: DiagnosticReportQueryParams) => Promise<DiagnosticReportWithDetails[]> getDiagnosticReportsAction, teacher/diagnostic, teacher/diagnostic/student/[studentId], student/diagnostic
getDiagnosticReportById (id: string) => Promise<DiagnosticReportWithDetails | null> getDiagnosticReportByIdAction
publishDiagnosticReport (id: string) => Promise<void> publishReportAction
deleteDiagnosticReport (id: string) => Promise<void> deleteReportAction

Types (types.ts)

Type 定义
DiagnosticReportType "individual" | "class" | "grade"
DiagnosticReportStatus "draft" | "published" | "archived"
KnowledgePointMastery { id, studentId, knowledgePointId, masteryLevel(0-100), totalQuestions, correctQuestions, lastAssessedAt, createdAt, updatedAt }
MasteryWithKnowledgePoint KnowledgePointMastery & { knowledgePointName, knowledgePointDescription }
StudentMasterySummary { studentId, studentName, averageMastery, totalKnowledgePoints, strengths(≥80), weaknesses(<60), allMastery }
DiagnosticReport { id, studentId, generatedBy, reportType, period, summary, strengths[], weaknesses[], recommendations[], overallScore, status, createdAt, updatedAt }
DiagnosticReportWithDetails DiagnosticReport & { studentName, generatedByName }
ClassMasterySummary { classId, className, studentCount, averageMastery, knowledgePointStats[], studentsNeedingAttention[] }
KnowledgePointStat { knowledgePointId, knowledgePointName, averageMastery, masteredCount(≥80), notMasteredCount(<60), totalStudents }
DiagnosticReportQueryParams { studentId?, reportType?, status?, period? }
MasteryRadarPoint { knowledgePoint, student(0-100), classAverage?(0-100) }

Components (components/)

所有组件以 "use client" 开头。

组件 用途
mastery-radar-chart.tsx 知识点掌握度雷达图recharts RadarChart学生 vs 班级平均对比,无数据时显示 EmptyState
student-diagnostic-view.tsx 学生诊断视图(概览卡片、雷达图、强项/弱项列表、生成报告表单[DIAGNOSTIC_MANAGE]、最新报告与建议展示)
class-diagnostic-view.tsx 班级诊断视图(概览卡片、知识点掌握度热力图[绿≥80/黄60-79/橙40-59/红<40]、知识点排名表、需重点关注学生表[链接到学生视图]、生成班级报告表单[DIAGNOSTIC_MANAGE]
report-list.tsx 诊断报告列表reportType/status 过滤器[URL searchParams]、报告表格、发布/删除操作[DIAGNOSTIC_MANAGE]、确认对话框)

数据库表

用途
knowledgePointMastery 知识点掌握度记录(复合主键 studentId+knowledgePointIdonDuplicateKeyUpdate upsert
learningDiagnosticReports 学情诊断报告reportType: individual/class/gradestatus: draft/published/archived

页面路由

路由 组件 权限 DataScope 校验
/teacher/diagnostic ReportList diagnostic:read class_members 仅查看自己报告
/teacher/diagnostic/student/[studentId] StudentDiagnosticView diagnostic:read class_members 仅自己children 仅子女
/teacher/diagnostic/class/[classId] ClassDiagnosticView diagnostic:read class_taught 必须包含 classIdclass_members/children → notFound
/student/diagnostic StudentDiagnosticView diagnostic:read class_members 仅查自己ctx.userId

模块elective

src/modules/elective

选课管理模块:选修课程 CRUD、选课开放/关闭、学生选课/退课、抽签模式批量录取runLottery、FCFS 即时录取、DataScope 行级过滤admin 全部、teacher 所教、grade_head 所管年级、student 可选课程)。

权限:管理操作使用 requirePermission(ELECTIVE_MANAGE);读取使用 requirePermission(ELECTIVE_READ);学生选课/退课使用 requirePermission(ELECTIVE_SELECT)。前端组件使用 usePermission().hasPermission() 控制权限。getStudentSelectionsAction 对 class_members/children 进行 DataScope 二次校验。

Server Actions (actions.ts)

Action 权限 用途
createElectiveCourseAction ELECTIVE_MANAGE 创建选修课程formData: name, subjectId?, teacherId, gradeId?, description?, capacity?, classroom?, schedule?, startDate?, endDate?, selectionStartAt?, selectionEndAt?, selectionMode?, credit?
updateElectiveCourseAction ELECTIVE_MANAGE 更新选修课程id + formData
deleteElectiveCourseAction ELECTIVE_MANAGE 删除选修课程formData: courseId
openSelectionAction ELECTIVE_MANAGE 开放选课formData: courseId
closeSelectionAction ELECTIVE_MANAGE 关闭选课formData: courseId
runLotteryAction ELECTIVE_MANAGE 执行抽签录取formData: courseId返回 {enrolled, waitlist}
selectCourseAction ELECTIVE_SELECT 学生选课formData: courseId, priority?
dropCourseAction ELECTIVE_SELECT 学生退课formData: courseId
getElectiveCoursesAction ELECTIVE_READ 查询选修课程列表(按 DataScope 过滤,传 currentUserId
getStudentSelectionsAction ELECTIVE_READ 查询学生选课记录DataScope 二次校验class_members 仅自己children 仅子女)
getAvailableCoursesAction ELECTIVE_SELECT 获取学生可选课程status=open 且匹配年级)

Data Access

data-access.ts (import "server-only")

函数 签名 被使用
getElectiveCourses (params?: GetElectiveCoursesParams & { scope?: DataScope; currentUserId?: string }) => Promise<ElectiveCourseWithDetails[]> getElectiveCoursesAction, admin/elective, teacher/elective
getElectiveCourseById (id: string) => Promise<ElectiveCourseWithDetails | null> updateElectiveCourseAction, admin/elective/[id]/edit
createElectiveCourse (data: CreateElectiveCourseInput, teacherId: string) => Promise<string> createElectiveCourseAction
updateElectiveCourse (id: string, data: Partial<UpdateElectiveCourseInput>) => Promise<void> updateElectiveCourseAction
deleteElectiveCourse (id: string) => Promise<void> deleteElectiveCourseAction
openSelection (courseId: string) => Promise<void> openSelectionAction
closeSelection (courseId: string) => Promise<void> closeSelectionAction
getSubjectOptions () => Promise<{id, name}[]> admin/elective/create, admin/elective/[id]/edit

buildScopeFilter(scope, userId) 内部函数owned/class_taught 按 teacherId 过滤grade_managed 按 gradeIds 过滤class_members/children 返回 null学生通过 getAvailableCoursesForStudent 获取可选课程)。

data-access-selections.ts (import "server-only")

从 data-access.ts 拆分以遵守单文件 ≤300 行规则。

函数 签名 被使用
getCourseSelections (courseId: string) => Promise<CourseSelectionWithDetails[]> 待扩展
getStudentSelections (studentId: string) => Promise<CourseSelectionWithDetails[]> getStudentSelectionsAction, student/elective
getStudentGradeId (studentId: string) => Promise<string | null> getAvailableCoursesForStudent
getAvailableCoursesForStudent (studentId: string, gradeId?: string | null) => Promise<ElectiveCourseWithDetails[]> getAvailableCoursesAction, student/elective

data-access-operations.ts (import "server-only")

从 data-access.ts 拆分以遵守单文件 ≤300 行规则。包含选课/退课/抽签的写操作。

函数 签名 被使用
runLottery (courseId: string) => Promise<{enrolled: number, waitlist: number}> runLotteryAction
selectCourse (courseId: string, studentId: string, priority?: number) => Promise<{status: CourseSelectionStatus, message: string}> selectCourseAction
dropCourse (courseId: string, studentId: string) => Promise<void> dropCourseAction

Schema (schema.ts)

Schema 用途
ElectiveCourseStatusEnum 课程状态枚举draft/open/closed/cancelled
ElectiveSelectionModeEnum 选课模式枚举fcfs/lottery
CourseSelectionStatusEnum 选课状态枚举selected/enrolled/waitlist/dropped/rejected
CreateElectiveCourseSchema 创建课程校验name 必填teacherId 必填capacity 1-500 默认 30selectionMode 默认 fcfscredit 默认 1.0
UpdateElectiveCourseSchema 更新课程校验(所有字段可选,含 status
SelectCourseSchema 选课校验courseId 必填priority 1-10 可选)
DropCourseSchema 退课校验courseId 必填)
RunLotterySchema 抽签校验courseId 必填)

类型/接口 (types.ts)

类型 定义
ElectiveCourseStatus "draft" | "open" | "closed" | "cancelled"
ElectiveSelectionMode "fcfs" | "lottery"
CourseSelectionStatus "selected" | "enrolled" | "waitlist" | "dropped" | "rejected"
ElectiveCourse 课程完整类型id, name, subjectId?, teacherId, gradeId?, description?, capacity, enrolledCount, classroom?, schedule?, startDate?, endDate?, selectionStartAt?, selectionEndAt?, status, selectionMode, credit, createdAt, updatedAt
ElectiveCourseWithDetails ElectiveCourse & { teacherName?, subjectName?, gradeName? }
CourseSelection 选课记录类型id, courseId, studentId, status, priority?, selectedAt, enrolledAt?, droppedAt?, lotteryRank?, createdAt, updatedAt
CourseSelectionWithDetails CourseSelection & { courseName?, studentName?, courseCapacity?, courseEnrolledCount?, courseStatus? }
GetElectiveCoursesParams 查询参数status?, gradeId?, subjectId?, teacherId?
ELECTIVE_STATUS_LABELS 课程状态标签常量
ELECTIVE_STATUS_COLORS 课程状态颜色常量Badge variant
SELECTION_MODE_LABELS 选课模式标签常量
COURSE_SELECTION_STATUS_LABELS 选课状态标签常量
COURSE_SELECTION_STATUS_COLORS 选课状态颜色常量Badge variant

导出组件 (components/)

组件文件 功能
elective-course-list.tsx 课程卡片列表(管理员/教师视图,含编辑/开放/关闭/抽签/删除操作按钮usePermission 权限控制)
elective-course-form.tsx 课程创建/编辑表单name, subjectId, teacherId, gradeId, description, capacity, classroom, schedule, dates, selectionMode, credit
student-selection-view.tsx 学生选课视图(可选课程列表 + 我的选课记录,含选课/退课按钮)

路由页面

路由 组件 权限 说明
/admin/elective ElectiveCourseList elective:manage 管理员选修课程列表scope=all
/admin/elective/create ElectiveCourseForm elective:manage 创建选修课程
/admin/elective/[id]/edit ElectiveCourseForm (edit) elective:manage 编辑选修课程
/teacher/elective ElectiveCourseList (teacher) elective:manage 教师选修课程列表scope=class_taught/owned按 teacherId 过滤)
/student/elective StudentSelectionView elective:select 学生选课页面(可选课程 + 我的选课)

模块间依赖矩阵

↓ 使用 → shared auth exams homework questions textbooks classes school dashboard layout settings users audit announcements files grades course-plans parent messaging attendance scheduling proctoring diagnostic elective
shared - - - - - - - - - - - - - - - - - - - - - - -
auth db,schema,permissions,login-logger - - - - - - - - - - - - - - - - - - - - - -
exams db,auth-guard,types,ai auth - - - - - - - - - - - - - - - - - - - - -
homework db,auth-guard,types auth data-access.getExams - - - schema - - - - - - - - - - - - - - - -
questions db,auth-guard,types auth - - - - - - - - - - - - - - - - - - - - -
textbooks db,auth-guard,types auth - - - - - - - - - - - - - - - - - - - - -
classes db,auth-guard,types auth - homework-insights - - - - - - - - - - - - - - - - - - -
school db,auth-guard,types,audit-logger auth - - - - - - - - - - - - - - - - - - - - -
dashboard db,types auth - data-access.getTeacherGradeTrends,getStudentDashboardGrades - - data-access.getTeacherClasses,getStudentClasses,getStudentSchedule - - - - - - - - - - - - - - - -
layout hooks.usePermission auth(useSession) - - - - - - - - - - - - - - - - notification-dropdown - - - -
settings db,auth-guard,ai,types auth - - - - - - - - - - - - - - - - - - - - -
users db,auth-guard(requireAuth,requirePermission),types,lib.excel auth - - - - - - - - - - - - - - - - - - - - -
audit db,auth-guard.requirePermission,types.permissions auth - - - - - - - - - - - - - - - - - - - - -
announcements db,auth-guard,types auth - - - - - - data-access.getGrades - - - - - - - - - - - - - -
files db,auth-guard(requireAuth,requirePermission),types,lib/file-storage auth - - - - - - - - - - - - - - - - - - - - -
grades db,auth-guard,types,lib.excel auth - - - - - - - - - - - - - - - - - - - - -
course-plans db,auth-guard.requirePermission,types auth - - - - - data-access.getAdminClasses,getStaffOptions data-access.getAcademicYears - - - - - - - - - - - - - -
parent db,auth-guard(requireAuth),types auth - data-access.getStudentHomeworkAssignments,getStudentDashboardGrades - - data-access.getStudentClasses,getStudentSchedule - - - - - - - - data-access.getStudentGradeSummary - - - - - -
messaging db,auth-guard(requirePermission,requireAuth),types auth - - - - - - - - - - - - - - - - - - - - -
attendance db,auth-guard.requirePermission,types auth - - - - - data-access.getTeacherClasses,getAdminClasses - - - - - - - - - - - - - - -
scheduling db,auth-guard(requirePermission,getAuthContext),types auth - - - - - - - - - - - - - - - - - - - - -
proctoring db,auth-guard(requirePermission,requireAuth),types,components.ui,hooks.usePermission auth schema.exams,examSubmissions,examProctoringEvents - - - - - - - - - - - - - - - - - - - - -
diagnostic db,auth-guard(requirePermission,getAuthContext),types,hooks.usePermission,components.ui auth schema.examSubmissions,submissionAnswers,questionsToKnowledgePoints - - - schema.classes,classEnrollments - - - - - - - - - - - - - - - - -
elective db,auth-guard.requirePermission,types,types.DataScope,hooks.usePermission,components.ui auth - - - - - - - - - - - - - - - - - - - - - -

关键参数影响链

userId

  1. auth.ts JWT callback 从 users 表查询产生,存入 JWT
  2. 通过 session.user.id 传递到所有 Server Components 和 Client Components
  3. 通过 getAuthContext().userId 传递到所有 Server Actions
  4. auth-guard.ts 中用于查询 usersToRoles(获取角色)和 classSubjectTeachers/grades(获取 DataScope
  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 默认值写入 electiveCoursescreateElectiveCourseAction作为 studentId 查询学生选课selectCourseAction/dropCourseAction/getStudentSelectionsAction
  9. 在 elective/data-access.ts 中 getElectiveCourses({ scope, currentUserId })teacherId 过滤class_taught/owned scope

examId

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

classId

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

permission

  1. shared/types/permissions.tsPermissions 常量定义57 个权限点,含 AUDIT_LOG_READANNOUNCEMENT_MANAGEFILE_UPLOADFILE_READFILE_DELETEGRADE_RECORD_MANAGEGRADE_RECORD_READCOURSE_PLAN_MANAGECOURSE_PLAN_READATTENDANCE_MANAGEATTENDANCE_READMESSAGE_SENDMESSAGE_READMESSAGE_DELETESCHEDULE_AUTOSCHEDULE_ADJUSTDIAGNOSTIC_MANAGEDIAGNOSTIC_READELECTIVE_MANAGEELECTIVE_READELECTIVE_SELECT 等)
  2. shared/lib/permissions.ts 中通过 ROLE_PERMISSIONS 映射角色到权限列表admin 角色包含 AUDIT_LOG_READCOURSE_PLAN_MANAGE+COURSE_PLAN_READadmin/teacher 含 FILE_UPLOAD/READ/DELETEGRADE_RECORD_MANAGE/READteacher/student/grade_head/teaching_head 含 COURSE_PLAN_READstudent/parent 含 FILE_READGRADE_RECORD_READadmin/teacher 含 ATTENDANCE_MANAGE+ATTENDANCE_READstudent/parent/grade_head/teaching_head 含 ATTENDANCE_READadmin/teacher/parent/grade_head/teaching_head 含 MESSAGE_SEND/READ/DELETEstudent 含 MESSAGE_READ/DELETE 但无 MESSAGE_SENDadmin 含 SCHEDULE_AUTO+SCHEDULE_ADJUSTteacher/student/parent/grade_head/teaching_head 无排课权限admin/teacher/grade_head 含 DIAGNOSTIC_MANAGE+DIAGNOSTIC_READteaching_head/student 含 DIAGNOSTIC_READadmin/teacher 含 ELECTIVE_MANAGE+ELECTIVE_READstudent 含 ELECTIVE_SELECT+ELECTIVE_READgrade_head/teaching_head 含 ELECTIVE_READ
  3. auth.ts JWT callback 中通过 resolvePermissions(roleNames) 合并多角色权限,存入 JWT
  4. proxy.ts middleware 中通过 token.permissions 检查路由访问权限
  5. shared/lib/auth-guard.ts 中通过 requirePermission(permission) 在 Server Action 层断言权限(如 audit-logs 页面使用 requirePermission(AUDIT_LOG_READ)DELETE /api/files/[id] 使用 requirePermission(FILE_DELETE)messaging/actions.ts 使用 requirePermission(MESSAGE_SEND/READ/DELETE)attendance/actions.ts 使用 requirePermission(ATTENDANCE_MANAGE/READ)users/actions.ts 的 importUsersAction/exportUsersAction/downloadUserTemplateAction 使用 requirePermission(USER_MANAGE)grades/actions.ts 的 exportGradesAction 使用 requirePermission(GRADE_RECORD_READ)POST /api/import 使用 requirePermission(USER_MANAGE)scheduling/actions.ts 使用 requirePermission(SCHEDULE_AUTO/SCHEDULE_ADJUST)diagnostic/actions.ts 使用 requirePermission(DIAGNOSTIC_MANAGE/READ)elective/actions.ts 使用 requirePermission(ELECTIVE_MANAGE/READ/SELECT)
  6. shared/hooks/use-permission.ts 中通过 hasPermission(permission) 在客户端组件中条件渲染
  7. layout/config/navigation.ts 中作为 NavItem.permission 字段过滤侧边栏菜单Audit Logs 菜单项使用 Permissions.AUDIT_LOG_READMessages 菜单项使用 Permissions.MESSAGE_READAttendance 菜单项 teacher 使用 Permissions.ATTENDANCE_MANAGEstudent/parent 使用 Permissions.ATTENDANCE_READImport Users 菜单项使用 Permissions.USER_MANAGEScheduling 菜单项 admin 使用 Permissions.SCHEDULE_ADJUST/SCHEDULE_AUTOteacher Schedule Changes 菜单项使用 Permissions.SCHEDULE_ADJUSTteacher/student Diagnostic 菜单项使用 Permissions.DIAGNOSTIC_READElectives 菜单项 admin/teacher 使用 Permissions.ELECTIVE_MANAGEstudent 使用 Permissions.ELECTIVE_SELECT

DataScope

  1. auth-guard.tsresolveDataScope(userId, roles) 根据用户角色和 DB 关系动态计算
  2. 传递到 exams/data-access.getExams({ scope }) 进行行级过滤
  3. 传递到 homework/data-access.getHomeworkAssignments({ scope }) 进行行级过滤
  4. 传递到 dashboard/data-access.getAdminDashboardData(scope) 进行统计过滤
  5. 在 exams/actions.ts 的 updateExamAction/deleteExamAction 中用于判断是否需要资源归属校验(scope.type !== "all"
  6. 对 parent 角色,resolveDataScope 查询 parentStudentRelations 表构建 { type: "children", childrenIds: string[] },传递到 grades/data-access.getStudentGradeSummary 等函数进行行级过滤
  7. parent/children/[studentId]/page.tsx 中通过 ctx.dataScope.type === "children" && !ctx.dataScope.childrenIds.includes(studentId) 二次校验家长拥有该子女
  8. 传递到 attendance/data-access.getAttendanceRecords({ scope }) 进行行级过滤class_taught 按教师班级过滤children 按子女过滤class_members 仅查自己all 查全部)
  9. attendance/actions.tsgetStudentAttendanceAction 中对 class_members/children 进行 DataScope 二次校验
  10. 传递到 elective/data-access.getElectiveCourses({ scope, currentUserId }) 进行行级过滤owned/class_taught 按 teacherId 过滤grade_managed 按 gradeIds 过滤class_members/children 返回 null 由 getAvailableCoursesForStudent 处理)
  11. elective/actions.tsgetStudentSelectionsAction 中对 class_members/children 进行 DataScope 二次校验

路由表

根路由

路由 组件 类型 权限 说明
/ 角色路由分发 server auth_required 重定向到 /dashboard

auth/* 子路由

路由 组件 类型 权限 说明
/login LoginForm client public 登录页面
/register RegisterForm + registerAction server public 注册页面(含未成年人信息保护、隐私政策/用户协议同意勾选)
/privacy PrivacyPage server public 隐私政策页面(信息收集/使用/保护、用户权利、Cookie、未成年人保护条款、联系方式
/terms TermsPage server public 用户协议页面(服务说明、注册、行为规范、知识产权、免责、变更终止、法律适用)

admin/school/* 子路由

路由 组件 类型 权限 说明
/admin/school SchoolManagementHome server school:manage 学校管理首页(聚合入口)
/admin/school/schools SchoolList server school:manage 学校列表dataAccess: school/data-access.getSchools
/admin/school/grades GradeList server grade:manage 年级列表dataAccess: school/data-access.getGrades
/admin/school/grades/insights GradeInsights server grade:manage 年级洞察dataAccess: classes/data-access.getGradeHomeworkInsights
/admin/school/departments DepartmentList server school:manage 部门列表dataAccess: school/data-access.getDepartments
/admin/school/classes AdminClassList server school:manage 班级列表dataAccess: classes/data-access.getAdminClasses
/admin/school/academic-year AcademicYearList server school:manage 学年列表dataAccess: school/data-access.getAcademicYears

admin/audit-logs/* 子路由

路由 组件 类型 权限 说明
/admin/audit-logs AuditLogView server audit_log:read 操作日志列表dataAccess: audit/data-access.getAuditLogs, getAuditModuleOptions权限requirePermission(AUDIT_LOG_READ)
/admin/audit-logs/login-logs LoginLogView server audit_log:read 登录日志列表dataAccess: audit/data-access.getLoginLogs权限requirePermission(AUDIT_LOG_READ)

admin/announcements/* 子路由

路由 组件 类型 权限 说明
/admin/announcements AdminAnnouncementsView client announcement:manage 公告管理首页(列表+创建对话框dataAccess: announcements/data-access.getAnnouncements, school/data-access.getGrades
/admin/announcements/[id] AnnouncementForm client announcement:manage 编辑公告dataAccess: announcements/data-access.getAnnouncementById, school/data-access.getGradesactions: updateAnnouncementAction

admin/files/* 路由

路由 组件 类型 权限 说明
/admin/files AdminFilesView client file:read 管理员文件管理页面(上传+列表+删除dataAccess: files/data-access.getAllFileAttachmentsAPI: POST /api/upload, DELETE /api/files/[id] 需 file:delete

admin/course-plans/* 路由

路由 组件 类型 权限 说明
/admin/course-plans CoursePlanList client course_plan:manage 管理员课程计划列表支持状态筛选dataAccess: course-plans/data-access.getCoursePlans
/admin/course-plans/create CoursePlanForm (create) client course_plan:manage 创建课程计划actions: createCoursePlanActiondataAccess: classes/data-access.getAdminClasses, course-plans/data-access.getSubjectOptions, classes/data-access.getStaffOptions, school/data-access.getAcademicYears
/admin/course-plans/[id] CoursePlanDetail client course_plan:manage 课程计划详情含周计划表格actions: deleteCoursePlanAction, createCoursePlanItemAction, updateCoursePlanItemAction, deleteCoursePlanItemAction, toggleCoursePlanItemCompletedActiondataAccess: course-plans/data-access.getCoursePlanById
/admin/course-plans/[id]/edit CoursePlanForm (edit) client course_plan:manage 编辑课程计划actions: updateCoursePlanActiondataAccess: course-plans/data-access.getCoursePlanById, classes/data-access.getAdminClasses, course-plans/data-access.getSubjectOptions, classes/data-access.getStaffOptions, school/data-access.getAcademicYears

admin/users/* 路由

路由 组件 类型 权限 说明
/admin/users/import UserImportPage (含 UserImportDialog) server user:manage 用户批量导入页面(说明卡片+字段文档表+导入对话框actions: users/actions.downloadUserTemplateAction, users/actions.importUsersAction权限requirePermission(USER_MANAGE)

announcements/* 路由

路由 组件 类型 权限 说明
/announcements AnnouncementList client auth_required 所有登录用户可查看的公告列表(仅 publisheddataAccess: announcements/data-access.getAnnouncements

management/* 路由

路由 组件 类型 权限 说明
/management/grade/classes GradeManagedClasses server grade:manage 年级主任管理的班级dataAccess: classes/data-access.getGradeManagedClasses
/management/grade/insights GradeInsightsView server grade:manage 年级洞察视图dataAccess: classes/data-access.getGradeHomeworkInsights

student/learning/* 路由

路由 组件 类型 权限 说明
/student/learning/assignments StudentAssignmentList server homework:submit 学生作业列表dataAccess: homework/data-access.getStudentHomeworkAssignments
/student/learning/assignments/[assignmentId] HomeworkTakeView client homework:submit 学生作答页面actions: startHomeworkSubmissionAction, saveHomeworkAnswerAction, submitHomeworkAction
/student/learning/courses StudentCourseList server class:read 学生课程列表dataAccess: classes/data-access.getStudentClasses
/student/learning/textbooks StudentTextbookList server textbook:read 学生教材列表dataAccess: textbooks/data-access.getTextbooks
/student/learning/textbooks/[id] TextbookReader client textbook:read 学生教材阅读器dataAccess: textbooks/data-access.getTextbookById, getChaptersByTextbookId
/student/schedule StudentSchedule server class:read 学生课表dataAccess: classes/data-access.getStudentSchedule

teacher/homework/* 路由

路由 组件 类型 权限 说明
/teacher/homework HomeworkHome server homework:create 作业管理首页(聚合入口)
/teacher/homework/assignments HomeworkAssignmentList server homework:create 作业列表dataAccess: homework/data-access.getHomeworkAssignments
/teacher/homework/assignments/create HomeworkAssignmentForm client homework:create 创建作业actions: createHomeworkAssignmentAction
/teacher/homework/assignments/[id] HomeworkAssignmentDetail server homework:create 作业详情dataAccess: homework/data-access.getHomeworkAssignmentById
/teacher/homework/assignments/[id]/submissions HomeworkSubmissionList server homework:grade 作业提交列表dataAccess: homework/data-access.getHomeworkSubmissions
/teacher/homework/submissions HomeworkReviewList server homework:grade 批改列表dataAccess: homework/data-access.getHomeworkAssignmentReviewList
/teacher/homework/submissions/[submissionId] HomeworkGradingView client homework:grade 批改页面actions: gradeHomeworkSubmissionAction, dataAccess: getHomeworkSubmissionDetails

teacher 其他路由

路由 组件 类型 权限 说明
/teacher/exams ExamDataTable server exam:read 考试列表dataAccess: exams/data-access.getExams
/teacher/exams/[id]/build ExamAssemblyPanel client exam:update 组卷页面components: assembly/*, actions: updateExamAction
/teacher/exams/[id]/proctoring ProctoringDashboard server+client exam:proctor 教师监考面板dataAccess: proctoring/data-access.getExamForProctoring,getExamProctoringSummary,getStudentProctoringStatuses,getRecentProctoringEvents权限requirePermission(EXAM_PROCTOR)组件proctoring/components/proctoring-dashboard.tsx10 秒轮询刷新)
/teacher/exams/grading ExamGradingList server exam:read 考试批改列表
/teacher/exams/grading/[submissionId] ExamGradingView client exam:read 考试批改页面
/teacher/classes/my/[id] ClassDetail server class:read 班级详情dataAccess: classes/data-access.getClassDetails
/teacher/classes TeacherClassList server class:read 教师班级列表dataAccess: classes/data-access.getTeacherClasses
/teacher/course-plans CoursePlanList (teacher) client course_plan:read 教师课程计划列表(按当前用户 teacherId 过滤dataAccess: course-plans/data-access.getCoursePlans
/teacher/course-plans/[id] CoursePlanDetail (teacher) client course_plan:read 教师课程计划详情只读无编辑按钮dataAccess: course-plans/data-access.getCoursePlanById

parent/* 路由

路由 组件 类型 权限 说明
/parent/dashboard ParentDashboard server auth_required 家长仪表盘首页(问候语 + 子女卡片网格dataAccess: parent/data-access.getParentDashboardData权限requireAuth()
/parent/children/[studentId] ChildDetailHeader + ChildDetailPanel server auth_required 子女详情页(头部 + 作业/成绩/课表面板dataAccess: parent/data-access.getChildDashboardData权限requireAuth() + 二次校验 ctx.dataScope.childrenIds 包含 studentId
/parent/grades ParentGradesView server grade_record:read 家长成绩视图dataAccess: grades/data-access.getStudentGradeSummary按 DataScope.children 过滤)

messages/* 路由

路由 组件 类型 权限 说明
/messages MessageList + NotificationList server message:read 消息首页(收件箱/已发送列表 + 通知列表dataAccess: messaging/data-access.getMessages, getNotifications权限requirePermission(MESSAGE_READ)
/messages/[id] MessageDetail server message:read 消息详情含回复线程dataAccess: messaging/data-access.getMessageById, getMessageThreadactions: markMessageAsReadAction 自动已读权限requirePermission(MESSAGE_READ)
/messages/compose MessageCompose server message:send 写消息页面(支持 reply 模式 via searchParams: receiverId, subject, parentMessageIddataAccess: messaging/data-access.getRecipients权限requirePermission(MESSAGE_SEND)

attendance/* 路由

路由 组件 类型 权限 说明
/teacher/attendance AttendanceRecordList + AttendanceFilters server attendance:manage 教师考勤记录列表dataAccess: attendance/data-access.getAttendanceRecords, classes/data-access.getTeacherClasses权限requirePermission(ATTENDANCE_MANAGE)
/teacher/attendance/sheet AttendanceSheet client attendance:manage 批量点名页面(班级/日期选择 + 学生表格actions: batchRecordAttendanceAction, getClassAttendanceForDateAction, getClassStudentsForAttendance权限requirePermission(ATTENDANCE_MANAGE)
/teacher/attendance/stats AttendanceStatsCard server attendance:read 班级考勤统计dataAccess: attendance/data-access-stats.getClassAttendanceStats, classes/data-access.getTeacherClasses权限requirePermission(ATTENDANCE_READ)
/student/attendance StudentAttendanceView server attendance:read 学生考勤视图(统计卡片 + 最近记录dataAccess: attendance/data-access-stats.getStudentAttendanceSummary权限requirePermission(ATTENDANCE_READ)DataScope.class_members 仅查自己)
/parent/attendance StudentAttendanceView (per child) server attendance:read 家长考勤视图(遍历子女,每个子女展示 StudentAttendanceViewdataAccess: parent/data-access.getChildren, attendance/data-access-stats.getStudentAttendanceSummary权限requirePermission(ATTENDANCE_READ)DataScope.children 仅查子女)
/admin/attendance AttendanceRecordList server attendance:manage 管理员考勤总览dataAccess: attendance/data-access.getAttendanceRecords(scope=all), classes/data-access.getAdminClasses权限requirePermission(ATTENDANCE_MANAGE)

scheduling/* 路由

路由 组件 类型 权限 说明
/admin/scheduling/rules SchedulingRulesForm server schedule:adjust 排课规则配置页面dataAccess: scheduling/actions.getAdminClassesForScheduling, getSchedulingRulesactions: saveSchedulingRulesAction权限requirePermission(SCHEDULE_ADJUST)
/admin/scheduling/auto AutoSchedulePanel + AutoScheduleResultView server schedule:auto 自动排课页面dataAccess: scheduling/actions.getAdminClassesForSchedulingactions: autoScheduleAction, applyAutoScheduleAction权限requirePermission(SCHEDULE_AUTO)
/admin/scheduling/changes ScheduleChangeList + ScheduleConflictsView server schedule:adjust 调课申请审批+冲突检测页面dataAccess: scheduling/actions.getAdminClassesForScheduling, getScheduleChangesactions: approveScheduleChangeAction, rejectScheduleChangeAction, getClassConflictsAction权限requirePermission(SCHEDULE_ADJUST);审批操作需 SCHEDULE_AUTO
/teacher/schedule-changes ScheduleChangeForm + ScheduleChangeList server schedule:adjust 教师调课/代课申请页面dataAccess: scheduling/actions.getAdminClassesForScheduling, getTeachersForScheduling, getScheduleChanges(requesterId=ctx.userId)actions: requestScheduleChangeAction权限requirePermission(SCHEDULE_ADJUST)admin 角色查看全部申请)

grades/* 路由

路由 组件 类型 权限 说明
/teacher/grades 成绩管理首页 server grade_record:read 成绩列表dataAccess: grades/actions.getGradeRecordsAction
/teacher/grades/entry 批量成绩录入 server grade_record:manage 批量录入actions: batchCreateGradeRecordsAction, createGradeRecordAction
/teacher/grades/stats 成绩统计报表 server grade_record:read 班级统计+排名dataAccess: getClassGradeStatsAction, getClassRankingAction
/teacher/grades/analytics 成绩趋势对比分析 server grade_record:read 分析仪表盘4 个分析图表并行加载dataAccess: getGradeTrend, getGradeDistribution, getSubjectComparison, getClassComparison权限requirePermission(GRADE_RECORD_READ)
/student/grades StudentGradesView server grade_record:read 学生成绩视图dataAccess: getStudentGradeSummaryDataScope.class_members 仅查自己)
/parent/grades ParentGradesView server grade_record:read 家长成绩视图dataAccess: getStudentGradeSummary按 DataScope.children 过滤)

settings/* 路由

路由 组件 类型 权限 说明
/settings 角色分发设置页 server auth_required 根据权限渲染 Admin/Teacher/Student 设置视图(含 General/Appearance/Security/Notifications tabSecurity tab 含 PasswordChangeFormNotifications tab 含 NotificationPreferencesFormdataAccess: messaging/notification-preferences.getNotificationPreferences
/settings/security SecuritySettingsPage server auth_required 安全设置独立页面PasswordChangeForm + 安全提示权限requireAuth()

diagnostic/* 路由

路由 组件 类型 权限 说明
/teacher/diagnostic ReportList client diagnostic:read 学情诊断报告列表reportType/status 过滤器[URL searchParams]dataAccess: diagnostic/data-access-reports.getDiagnosticReportsactions: publishReportAction, deleteReportAction[DIAGNOSTIC_MANAGE]权限requirePermission(DIAGNOSTIC_READ)DataScope.class_members 仅查看自己报告)
/teacher/diagnostic/student/[studentId] StudentDiagnosticView client diagnostic:read 学生学情诊断视图(概览卡片+雷达图+强项/弱项+生成报告[DIAGNOSTIC_MANAGE]+最新报告dataAccess: getStudentMasterySummary, getKnowledgePointStats[班级平均对比], getDiagnosticReportsactions: generateStudentReportAction权限getAuthContext + DataScope 二次校验class_members 仅自己children 仅子女)
/teacher/diagnostic/class/[classId] ClassDiagnosticView client diagnostic:read 班级学情诊断视图(概览+知识点热力图+排名表+需重点关注学生+生成班级报告[DIAGNOSTIC_MANAGE]dataAccess: getClassMasterySummaryactions: generateClassReportAction权限getAuthContext + DataScope 校验class_taught 必须包含 classIdclass_members/children → notFound
/student/diagnostic StudentDiagnosticView client diagnostic:read 学生本人学情诊断视图(概览+雷达图+强项/弱项+最新报告dataAccess: getStudentMasterySummary(ctx.userId), getDiagnosticReports(studentId=ctx.userId)权限requirePermission(DIAGNOSTIC_READ)DataScope.class_members 仅查自己)

elective/* 路由

路由 组件 类型 权限 说明
/admin/elective ElectiveCourseList server elective:manage 管理员选修课程列表dataAccess: getElectiveCourses(scope=all)actions: deleteElectiveCourseAction, openSelectionAction, closeSelectionAction, runLotteryAction权限requirePermission(ELECTIVE_MANAGE)
/admin/elective/create ElectiveCourseForm client elective:manage 创建选修课程actions: createElectiveCourseActiondataAccess: getSubjectOptions权限requirePermission(ELECTIVE_MANAGE)
/admin/elective/[id]/edit ElectiveCourseForm (edit) client elective:manage 编辑选修课程actions: updateElectiveCourseActiondataAccess: getElectiveCourseById, getSubjectOptions权限requirePermission(ELECTIVE_MANAGE)
/teacher/elective ElectiveCourseList (teacher) server elective:manage 教师选修课程列表dataAccess: getElectiveCourses(scope=class_taught/owned, currentUserId)actions: deleteElectiveCourseAction, openSelectionAction, closeSelectionAction, runLotteryAction权限requirePermission(ELECTIVE_MANAGE);按 teacherId 过滤)
/student/elective StudentSelectionView server elective:select 学生选课页面dataAccess: getAvailableCoursesForStudent, getStudentSelectionsactions: selectCourseAction, dropCourseAction权限requirePermission(ELECTIVE_SELECT)

API 路由(含速率限制)

路由 方法 限流规则 说明
/api/auth/[...nextauth] GET, POST NextAuth 认证(登录流程内置 LOGIN 限流: 5次/15分钟
/api/ai/chat POST AI_CHAT: 20次/分钟 AI 聊天(按 userId 限流,超限返回 429 + Retry-After 头)
/api/upload POST UPLOAD: 10次/分钟 文件上传(按 userId 限流,超限返回 429 + Retry-After 头)
/api/rate-limit-test GET PASSWORD_CHANGE: 5次/分钟 限流测试端点(按 userId 限流,用于手动验证 429 响应)
/api/export POST Excel 导出
/api/import POST Excel 解析预览
/api/files/[id] GET, DELETE 文件元数据/删除
/api/files/batch-delete POST 批量删除文件(需 FILE_DELETE 权限,先删磁盘文件再删 DB 记录)
/api/search GET 全文检索questions/textbooks/exams/announcements需登录参数 q/type/page/pageSize
/api/onboarding/* GET, POST 用户引导

DevOps 与脚本

CI 配置 (.gitea/workflows/ci.yml)

Job 触发条件 说明
build-deploy push/PR to main 构建、测试、部署到 Docker自托管 runner CDCD
security-audit push/PR to main 依赖安全审计:npm audit moderate/critical 检查,上传 audit-report.json artifact
scheduled-backup schedule cron 0 2 * * * 每天凌晨 2 点执行数据库备份,上传 backups/ artifact保留 30 天)

运维脚本 (scripts/)

脚本 用途
scripts/audit.sh Bash 依赖审计脚本,运行 npm audit --audit-level=moderate,失败时生成 audit-report.json
scripts/audit.ps1 PowerShell 版本依赖审计脚本Windows 环境)
scripts/backup-db.sh MySQL 数据库备份脚本,从 DATABASE_URL 解析连接信息gzip 压缩备份,保留 30 天
scripts/restore-db.sh MySQL 数据库恢复脚本,从指定备份文件恢复
scripts/test-backup.sh 备份流程测试脚本,执行一次备份并验证

package.json 脚本

脚本 命令 说明
audit npm audit --audit-level=moderate 依赖安全审计
audit:report npm audit --json > audit-report.json 生成 JSON 审计报告
backup bash scripts/backup-db.sh 执行数据库备份
restore bash scripts/restore-db.sh 执行数据库恢复

E2E 测试 (tests/e2e/)

测试文件 覆盖范围 依赖
smoke-auth.spec.ts 登录/注册页面控件渲染冒烟测试 无需 DB
auth-business-flow.spec.ts 注册→登录→访问受保护区域完整流程 DATABASE_URL
full-route-regression.spec.ts 全路由清单完整性 + 公开/受保护路由守卫 无需 DB守卫测试
auth.spec.ts 认证页面(登录/注册/隐私/协议)渲染 + 未认证重定向 无需 DB
navigation.spec.ts admin/teacher/student 导航链接无 404 DATABASE_URL + 测试账号
announcements.spec.ts 公告页面未认证重定向 + 登录后渲染 部分需 DATABASE_URL
grades.spec.ts 成绩页面未认证重定向 + 登录后渲染 部分需 DATABASE_URL

Playwright 配置 (playwright.config.ts)

  • testDir: ./tests/e2e
  • baseURL: http://127.0.0.1:3000
  • webServer: 自动启动 npm run dev,端口 3000超时 180s
  • webServer.env: 注入 SKIP_ENV_VALIDATION=1NEXTAUTH_SECRETNEXTAUTH_URLDATABASE_URL(测试库)
  • projects: chromiumCI 通道为 undefined本地为 chrome
  • retries: CI 2 次,本地 0 次
  • workers: CI 2 个,本地默认