docs: 同步架构文档 004/005/007/audit 反映 P1-2/P2-2 解耦修复

This commit is contained in:
SpecialX
2026-06-18 02:55:17 +08:00
parent 6588f7484f
commit 0423b2b984
5 changed files with 368 additions and 100 deletions

View File

@@ -215,18 +215,20 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
│ student/learning/assignments/[assignmentId]/page.tsx │
│ └─▶ homework/actions.startHomeworkSubmissionAction │
│ ├─▶ requirePermission(HOMEWORK_SUBMIT) │
│ ├─▶ db.query.homeworkAssignments [⚠️ 直接 DB]
─▶ db.insert(homeworkSubmissions) [⚠️ 直接 DB]
│ ├─▶ data-access-write.startHomeworkSubmission ✅ P1-2 已修复
│ └─▶ db.insert(homeworkSubmissions) [shared/db]
│ └─▶ 返回 submissionId │
│ │
│ └─▶ homework/actions.saveHomeworkAnswerAction │
│ └─▶ db.transaction(insert homeworkAnswers) [⚠️ 直接 DB]
│ └─▶ data-access-write.saveHomeworkAnswer ✅ P1-2 已修复
│ └─▶ db.transaction(insert homeworkAnswers) [shared/db] │
│ │
│ └─▶ homework/actions.submitHomeworkAction │
│ └─▶ db.update(homeworkSubmissions.status="submitted")
│ └─▶ data-access-write.submitHomework ✅ P1-2 已修复
│ └─▶ db.update(homeworkSubmissions.status="submitted") │
│ │
│ 数据写入homeworkSubmissions 表 + homeworkAnswers 表 │
⚠️ 违规actions 层直接 DB 操作,下沉到 data-access
✅ P1-2 已修复actions 层不再直接 DB 操作,下沉到 data-access-write
└─────────────────────────────────────────────────────────────────────┘
@@ -236,7 +238,8 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
│ teacher/homework/submissions/[submissionId]/page.tsx │
│ └─▶ homework/actions.gradeHomeworkSubmissionAction │
│ ├─▶ requirePermission(HOMEWORK_GRADE) │
│ └─▶ db.update(homeworkAnswers) 循环 [⚠️ 直接 DB]
│ └─▶ data-access-write.gradeHomeworkSubmission ✅ P1-2 已修复
│ └─▶ db.update(homeworkAnswers) 循环 [shared/db] │
│ │
│ 数据更新homeworkAnswers.isCorrect / score / feedback │
└─────────────────────────────────────────────────────────────────────┘
@@ -308,11 +311,10 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
├─▶ requirePermission(HOMEWORK_SUBMIT)
├─▶ db.query.homeworkSubmissions.findFirst ❌ 应在 data-access
│ (校验 submission 归属)
├─▶ db.update(homeworkSubmissions) ❌ 应在 data-access
│ SET status = "submitted", submittedAt = now()
├─▶ data-access-write.submitHomework ✅ P1-2 已修复
│ (校验 submission 归属 + 更新状态
└─▶ db.update(homeworkSubmissions)
│ SET status = "submitted", submittedAt = now()
└─▶ 返回 ActionState<{ submissionId }>
```
@@ -370,7 +372,7 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
- ❌ P0`shared/lib/*``@/auth` 循环依赖
- ⚠️ P1`schema.ts` 1111 行54 张表混合,超 1000 硬上限)
- ✅ P1~~`auth.ts` 293 行混合 5 类职责~~ 已拆分4 个辅助函数组迁移至 `shared/lib/{role-utils,bcrypt-utils,http-utils,password-security-service}`auth.ts 仅保留 NextAuth 配置)
- ⚠️ P2`ai.ts` 218 行混合 5 类职责
- P2-2 已修复:~~`ai.ts` 218 行混合 5 类职责~~ 已拆分为 `ai/` 目录payload-parser.ts/api-key-crypto.ts/provider-config.ts/client.ts/errors.ts/index.ts`ai.ts` 保留为向后兼容的重导出文件12 行)
- ⚠️ P2`onboarding-gate.tsx` 业务逻辑泄漏到 shared
**文件清单**
@@ -381,7 +383,13 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
| `db/index.ts` | - | Drizzle 客户端 |
| `lib/auth-guard.ts` | - | 认证上下文 + 权限校验 + DataScope |
| `lib/permissions.ts` | - | 角色-权限映射 |
| `lib/ai.ts` | 218 | AI 调用 + Provider 配置 + 加密 |
| `lib/ai.ts` | 12 | 向后兼容重导出P2-2 已拆分到 `ai/` 目录) |
| `lib/ai/payload-parser.ts` | 96 | 请求负载解析 |
| `lib/ai/api-key-crypto.ts` | 34 | API Key 加密/解密 |
| `lib/ai/provider-config.ts` | 66 | Provider 配置查询 |
| `lib/ai/client.ts` | 67 | AI 客户端创建与调用 |
| `lib/ai/errors.ts` | 9 | 错误格式化 |
| `lib/ai/index.ts` | 7 | 聚合导出 |
| `lib/audit-logger.ts` | - | 操作日志 |
| `lib/change-logger.ts` | - | 数据变更日志 |
| `lib/login-logger.ts` | - | 登录日志 |
@@ -406,8 +414,8 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
**职责**:考试全生命周期管理(创建/编辑/预览/发布/删除/复制)+ AI 辅助出题。
**导出函数**
- Actions`createExamAction` / `createAiExamAction` / `previewAiExamAction` / `regenerateAiQuestionAction` / `updateExamAction` / `deleteExamAction` / `duplicateExamAction` / `getExamPreviewAction` / `getSubjectsAction` / `getGradesAction`
- Data-access`getExams` / `getExamById` / `persistExamDraft` / `persistAiGeneratedExamDraft` / `buildExamDescription` / `resolveSubjectGradeNames`
- Actions`createExamAction` / `createAiExamAction` / `previewAiExamAction` / `regenerateAiQuestionAction` / `updateExamAction` / `deleteExamAction` / `duplicateExamAction` / `getExamPreviewAction` / `getSubjectsAction` / `getGradesAction`(✅ P1-2 已修复actions 层不再直接访问 DB全部下沉到 data-access
- Data-access`getExams` / `getExamById` / `persistExamDraft` / `persistAiGeneratedExamDraft` / `buildExamDescription` / `resolveSubjectGradeNames` / `getExamCreatorId` / `updateExamWithQuestions` / `deleteExamById` / `duplicateExam` / `getExamPreview` / `getExamSubjects` / `getExamGrades`(后 7 个为 P1-2 新增)
- AI Pipeline`generateAiCreateDraftFromSource` / `generateAiPreviewData` / `regenerateAiQuestionByInstruction`
**依赖关系**
@@ -418,15 +426,15 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
- ❌ P0`persistAiGeneratedExamDraft` 直接 insert 到 `questions`
- ❌ P0`getExams`/`getExamById` 直查 `classes`
- ❌ P1`getSubjectsAction`/`getGradesAction` 直查 `subjects`/`grades` 表(应属 school 模块)
- P1`actions.ts` 832 行(超 800 建议),多处直接 DB 操作
- P1-2 已修复:~~`actions.ts` 832 行(超 800 建议),多处直接 DB 操作~~ DB 操作已下沉到 data-accessactions.ts 现 766 行
- ⚠️ P1`ai-pipeline.ts` 912 行(超 800 建议),混合 4 类职责
**文件清单**
| 文件 | 行数 | 职责 |
|------|------|------|
| `actions.ts` | 832 | 10 个 Server Action超限 |
| `actions.ts` | 766 | 10 个 Server ActionP1-2 已修复,无直接 DB 操作 |
| `ai-pipeline.ts` | 912 | AI 出题管线(超限) |
| `data-access.ts` | 339 | 考试 CRUD |
| `data-access.ts` | 524 | 考试 CRUD(含 P1-2 新增 7 个写/查询函数) |
| `types.ts` | 31 | 类型定义 |
| `hooks/use-exam-preview.ts` | 295 | 预览 Hook |
| `components/*` | 18 文件 | 考试表单/组卷/预览组件 |
@@ -438,8 +446,9 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
**职责**:作业全生命周期(创建/发布/作答/批改/分析)。
**导出函数**
- Actions`createHomeworkAssignmentAction` / `startHomeworkSubmissionAction` / `saveHomeworkAnswerAction` / `submitHomeworkAction` / `gradeHomeworkSubmissionAction`
- Actions`createHomeworkAssignmentAction` / `startHomeworkSubmissionAction` / `saveHomeworkAnswerAction` / `submitHomeworkAction` / `gradeHomeworkSubmissionAction`(✅ P1-2 已修复actions 层不再直接访问 DB全部下沉到 data-access/data-access-write
- Data-access`getHomeworkAssignments` / `getHomeworkAssignmentById` / `getHomeworkSubmissions` / `getStudentHomeworkAssignments` / `getStudentHomeworkTakeData` / `getHomeworkAssignmentReviewList` / `getHomeworkSubmissionDetails` / `getDemoStudentUser` / `isRecord` / `toQuestionContent` / `getAssignmentMaxScoreById`(后三者供 stats-service 使用)
- Data-access-write10 个写操作函数P1-2 新增,从 actions 下沉)
- Stats-service`getTeacherGradeTrends` / `getHomeworkAssignmentAnalytics` / `getStudentDashboardGrades`(从 data-access.ts re-export 以保持向后兼容)
**依赖关系**
@@ -451,14 +460,15 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
- ✅ P0 已解决:`getStudentDashboardGrades` 排名计算逻辑迁移至 `stats-service.ts`
- ✅ P0 已解决:`getHomeworkAssignmentAnalytics` 错误率统计逻辑迁移至 `stats-service.ts`
- ❌ P15 处直查 `exams`
- P1`actions.ts` 多处直接 DB 操作(`createHomeworkAssignmentAction` 157 行)
- P1-2 已修复:~~`actions.ts` 多处直接 DB 操作(`createHomeworkAssignmentAction` 157 行)~~ DB 操作已下沉到 `data-access-write.ts`actions.ts 现 239 行
**文件清单**
| 文件 | 行数 | 职责 |
|------|------|------|
| `data-access.ts` | 596 | 作业 CRUD + 学生视角 + 批改(含 re-export stats 函数) |
| `data-access-write.ts` | 285 | 作业写操作P1-2 新增10 个写函数从 actions 下沉) |
| `stats-service.ts` | 346 | 统计分析(教师趋势/作业分析/学生仪表盘成绩) |
| `actions.ts` | 387 | 5 个 Server Action |
| `actions.ts` | 239 | 5 个 Server ActionP1-2 已修复,无直接 DB 操作) |
| `types.ts` | 186 | 类型定义 |
| `schema.ts` | 29 | Zod 校验 |
@@ -469,23 +479,23 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
**职责**:题库管理(题目 CRUD、知识点关联、题型支持
**导出函数**
- Actions`getQuestionsAction` / `createQuestionAction` / `updateQuestionAction` / `deleteQuestionAction` / `getKnowledgePointOptionsAction`
- Data-access`getQuestions` / `insertQuestionWithRelations`(错放 actions/ `deleteQuestionRecursive`(错放 actions
- Actions`getQuestionsAction` / `createQuestionAction` / `updateQuestionAction` / `deleteQuestionAction` / `getKnowledgePointOptionsAction`(✅ P1-2 已修复actions 层不再直接访问 DB全部下沉到 data-access
- Data-access`getQuestions` / `createQuestionWithRelations` / `updateQuestionById` / `deleteQuestionByIdRecursive` / `getKnowledgePointOptions`(后 4 个为 P1-2 新增/迁移
**依赖关系**
- 依赖:`shared/*``@/auth``textbooks`(❌ actions 直查 knowledgePoints/chapters/textbooks
- 被依赖:`exams`(通过类型导入,合理)、`textbooks`UI 组合,合理)
**已知问题**
- P1写操作函数错放在 `actions.ts``insertQuestionWithRelations` / `deleteQuestionRecursive`
- P1-2 已修复:~~写操作函数错放在 `actions.ts``insertQuestionWithRelations` / `deleteQuestionRecursive`~~ 已下沉到 data-access`createQuestionWithRelations` / `updateQuestionById` / `deleteQuestionByIdRecursive` / `getKnowledgePointOptions`
- ❌ P1`getKnowledgePointOptionsAction` 直查 textbooks 模块表
- ⚠️ P2`data-access.ts` 仅 129 行,写操作缺失
- P2 已解决:~~`data-access.ts` 仅 129 行,写操作缺失~~ P1-2 后 data-access.ts 扩充至 299 行
**文件清单**
| 文件 | 行数 | 职责 |
|------|------|------|
| `actions.ts` | 294 | 5 个 Server Action含错放的 data-access 函数 |
| `data-access.ts` | 129 | 仅读查询 |
| `actions.ts` | 177 | 5 个 Server ActionP1-2 已修复,无直接 DB 操作 |
| `data-access.ts` | 299 | 题目 CRUD + 知识点选项(含 P1-2 新增 4 个写/查询函数) |
| `schema.ts` | 18 | Zod 校验 |
| `types.ts` | 34 | 类型定义 |
@@ -820,23 +830,23 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
**职责**:公告 CRUD + 发布/归档。
**导出函数**
- Actions`getAnnouncementsAction` / `createAnnouncementAction` / `updateAnnouncementAction` / `deleteAnnouncementAction` / `publishAnnouncementAction` / `archiveAnnouncementAction`
- Data-access`getAnnouncements` / `getAnnouncementById`
- Actions`getAnnouncementsAction` / `createAnnouncementAction` / `updateAnnouncementAction` / `deleteAnnouncementAction` / `publishAnnouncementAction` / `archiveAnnouncementAction`(✅ P1-2 已修复actions 层不再直接访问 DB全部下沉到 data-access
- Data-access`getAnnouncements` / `getAnnouncementById` / `insertAnnouncement` / `updateAnnouncementById` / `deleteAnnouncementById` / `publishAnnouncementById` / `archiveAnnouncementById`(后 5 个为 P1-2 新增)
**依赖关系**
- 依赖:`shared/*``@/auth``school`(合理,获取年级列表)
- 被依赖:无
**已知问题**
- P1所有写操作直接在 actions 层 `db.insert/update/delete`,未下沉到 data-access
- P1-2 已修复:~~所有写操作直接在 actions 层 `db.insert/update/delete`,未下沉到 data-access~~ 写操作已下沉到 data-access5 个新函数)
- ⚠️ P2死代码 `void wasPublished`
- ⚠️ P2`getAnnouncementsAction` 使用 `requireAuth()` 而非 `requirePermission(ANNOUNCEMENT_READ)`
**文件清单**
| 文件 | 行数 | 职责 |
|------|------|------|
| `actions.ts` | 242 | 6 个 Server Action直接 DB |
| `data-access.ts` | 120 | 仅 2 个只读函数 |
| `actions.ts` | 231 | 6 个 Server ActionP1-2 已修复,无直接 DB 操作 |
| `data-access.ts` | 186 | 公告 CRUD + 发布/归档(含 P1-2 新增 5 个写函数 |
| `schema.ts` | - | Zod 校验 |
| `types.ts` | - | 类型定义 |
@@ -1195,18 +1205,20 @@ shared/lib/{audit-logger, change-logger, auth-guard} → @/auth → shared/lib/*
- `textbooks/data-access``getKnowledgePointOptions`
- `questions/data-access``insertQuestionWithRelations` / `deleteQuestionRecursive`
### P1-2actions 层混入数据访问逻辑
### P1-2actions 层混入数据访问逻辑 ✅ 已修复
| 模块 | 问题 Action | 违规 |
|------|------------|------|
| exams | `updateExamAction` / `deleteExamAction` / `duplicateExamAction` / `getExamPreviewAction` | 直接 db.query + db.insert/update/delete |
| homework | `createHomeworkAssignmentAction`157 行)/ `startHomeworkSubmissionAction` / `saveHomeworkAnswerAction` / `submitHomeworkAction` / `gradeHomeworkSubmissionAction` | 直接 DB 操作 |
| questions | `createQuestionAction` / `updateQuestionAction` / `deleteQuestionAction` | 内联 db.transaction |
| announcements | 所有写操作 Action | 直接 db.insert/update/delete |
| users | `updateUserProfileAction` | 直接 db.update |
| scheduling | `applyAutoScheduleAction` / `autoScheduleAction` | 直接 db.transaction + db.select |
**已完成修复**2026-06-17commit 84d66364 个模块的 actions 层 DB 操作全部下沉到 data-access
**解耦建议**actions 层仅做"权限校验 → 解析 → 调用 data-access → revalidatePath → 返回",所有 DB 操作下沉到 data-access。
| 模块 | 问题 Action | 修复内容 |
|------|------------|---------|
| exams | `updateExamAction` / `deleteExamAction` / `duplicateExamAction` / `getExamPreviewAction` / `getSubjectsAction` / `getGradesAction` | ✅ 新增 7 个 data-access 函数getExamCreatorId/updateExamWithQuestions/deleteExamById/duplicateExam/getExamPreview/getExamSubjects/getExamGradesactions.ts 831→766 行data-access.ts 374→524 行 |
| homework | `createHomeworkAssignmentAction`157 行)/ `startHomeworkSubmissionAction` / `saveHomeworkAnswerAction` / `submitHomeworkAction` / `gradeHomeworkSubmissionAction` | ✅ 新建 `data-access-write.ts`285 行10 个写函数actions.ts 387→239 行 |
| questions | `createQuestionAction` / `updateQuestionAction` / `deleteQuestionAction` / `getKnowledgePointOptionsAction` | ✅ 新增 4 个 data-access 函数createQuestionWithRelations/updateQuestionById/deleteQuestionByIdRecursive/getKnowledgePointOptionsactions.ts 294→177 行data-access.ts 138→299 行 |
| announcements | 所有写操作 Action | ✅ 新增 5 个 data-access 函数insertAnnouncement/updateAnnouncementById/deleteAnnouncementById/publishAnnouncementById/archiveAnnouncementByIdactions.ts 242→231 行data-access.ts 120→186 行 |
**剩余未修复模块**(不在本次 P1-2 范围):
- users`updateUserProfileAction` 直接 db.update
- scheduling`applyAutoScheduleAction` / `autoScheduleAction` 直接 db.transaction + db.select
### P1-3auth.ts 混合 5 类职责 ✅ 已完成
@@ -1250,8 +1262,8 @@ shared/lib/{audit-logger, change-logger, auth-guard} → @/auth → shared/lib/*
| 序号 | 问题 | 模块 |
|------|------|------|
| P2-1 | `exams/ai-pipeline.ts` 912 行,混合 4 类职责 | exams |
| P2-2 | `exams/actions.ts` 832 行(超 800 建议) | exams |
| P2-3 | `shared/lib/ai.ts` 218 行,混合 5 类职责 | shared |
| ~~P2-2~~ | ~~`exams/actions.ts` 832 行(超 800 建议)~~ ✅ 已修复P1-2 后降至 766 行) | exams |
| ~~P2-3~~ | ~~`shared/lib/ai.ts` 218 行,混合 5 类职责~~ ✅ 已修复P2-2 已拆分为 `ai/` 目录) | shared |
| P2-4 | `onboarding-gate.tsx` 业务逻辑泄漏到 shared | shared |
| P2-5 | `global-search.tsx` 业务类型硬编码在 shared | shared |
| P2-6 | `proxy.ts` 硬编码权限字符串,未复用 Permissions 常量 | proxy |
@@ -1284,7 +1296,7 @@ shared/lib/{audit-logger, change-logger, auth-guard} → @/auth → shared/lib/*
7. 集成 proctoring/exam-mode-config 到考试表单
### 短期执行P1
8. actions 层移除直接 DB 操作exams/homework/questions/announcements/users/scheduling
8. ~~actions 层移除直接 DB 操作exams/homework/questions/announcements/users/scheduling~~ ✅ 部分完成exams/homework/questions/announcements 已修复users/scheduling 待处理)
9. ~~拆分 `auth.ts`~~ ✅ 已完成4 个辅助函数组迁移至 shared/libauth.ts 保留 NextAuth 配置)
10. ~~拆分 `users/import-export.ts`~~ ✅ 已完成(拆为 import-export.ts 177行 + user-service.ts 96行 + class-registration.ts 30行班级注册改为调用 classes/data-access
11. 消除 notifications → messaging 反向依赖
@@ -1295,8 +1307,9 @@ shared/lib/{audit-logger, change-logger, auth-guard} → @/auth → shared/lib/*
14. 建立模块间数据访问规范(通过对方 data-access 或导出查询函数)
15. `schema.ts` 按业务域分节
16. 拆分 `exams/ai-pipeline.ts`
17. shared 层业务逻辑下沉到 modules 层
18. 代码质量问题逐项修复
17. ~~拆分 `shared/lib/ai.ts`~~ ✅ 已完成P2-2commit 6588f74拆分为 `ai/` 目录 6 个文件,原 ai.ts 保留为重导出)
18. shared 层业务逻辑下沉到 modules 层
19. 代码质量问题逐项修复
---
@@ -1422,9 +1435,12 @@ logLoginEvent(params: LogLoginEventParams): Promise<void>
// shared/lib/change-logger.ts
logDataChange(params: LogDataChangeParams): Promise<void>
// shared/lib/ai.ts
// shared/lib/ai/ (P2-2 已拆分,原 ai.ts 保留为重导出)
// ai/client.ts
createAiChatCompletion(input: AiChatRequest): Promise<{ content, usage }>
// ai/payload-parser.ts
parseAiChatPayload(body: unknown): AiChatRequest
// ai/api-key-crypto.ts
encryptAiApiKey(value: string): string
decryptAiApiKey(value: string): string