docs: 全项目架构审查与文档体系重写
- 全项目逐文件审查: 4 份审计报告(shared/core-business/management/new-modules) - 重写 004 架构影响地图: 图优先 + 模块依赖图 + 数据流 + 调用链 + 问题分级 - 更新 005 结构化数据: 新增 architectureOverview/moduleDependencyGraph/knownIssues/dbTables 节点 - 更新 006 功能清单: 143 项功能标注实现状态, P0 覆盖率 80%->92% - 更新 007 差距审计: v2->v3, P0 完成 69%->84%, 新增架构技术债章节 - 更新 001 项目概览: 6 角色/54 权限/26 模块/54 表 - 新增 docs/README.md 文档索引 - 归档 11 份过时文档(002x2/003/designx8) 标注 - 更新 work_log
This commit is contained in:
417
docs/architecture/audit/core-business-audit.md
Normal file
417
docs/architecture/audit/core-business-audit.md
Normal file
@@ -0,0 +1,417 @@
|
||||
# 核心业务模块职责与耦合审查报告
|
||||
|
||||
> 审计日期:2026-06-17
|
||||
> 审计范围:`src/modules/exams`、`src/modules/homework`、`src/modules/questions`、`src/modules/textbooks`、`src/modules/grades`
|
||||
> 审计目标:识别职责不单一和过耦合问题,重点关注跨模块直接数据库查询(违反模块封装)
|
||||
> 审计依据:项目规则(`.trae/rules/project_rules.md`)、架构影响地图(004/005)
|
||||
|
||||
---
|
||||
|
||||
## 一、总体结论
|
||||
|
||||
| 维度 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| 模块职责边界 | ⚠️ 部分违规 | homework 混入考试/班级逻辑;grades 混入班级/用户逻辑 |
|
||||
| data-access 层职责 | ❌ 普遍违规 | 5 个模块均存在跨模块直接 DB 查询;homework/data-access.ts 混入排名业务逻辑 |
|
||||
| actions 层职责 | ⚠️ 部分违规 | exams/homework/questions 的 actions 直接访问 DB;textbooks/grades 的 actions 设计良好 |
|
||||
| 组件耦合 | ✅ 基本合规 | 组件层跨模块依赖均为类型导入或 UI 组合,无直接 data-access 调用 |
|
||||
| 跨模块依赖 | ⚠️ 存在风险 | 无循环依赖,但 exams→questions、homework→exams、grades→classes 的直接 DB 访问破坏封装 |
|
||||
| 文件行数 | ❌ 存在违规 | homework/data-access.ts 1038 行(超 1000 硬上限);exams/ai-pipeline.ts 912 行、exams/actions.ts 832 行(超 800 建议值) |
|
||||
|
||||
### 关键风险项
|
||||
|
||||
1. **homework/data-access.ts 超过 1000 行硬上限**(1038 行)—— 必须拆分
|
||||
2. **5 个模块均存在跨模块直接 DB 查询** —— 违反模块封装原则
|
||||
3. **exams/homework/questions 的 actions 层混入数据访问逻辑** —— 应只做编排
|
||||
4. **homework/data-access.ts 混入排名计算业务逻辑** —— data-access 应只负责数据存取
|
||||
|
||||
---
|
||||
|
||||
## 二、模块依赖关系图
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ textbooks │ ← 被引用方(知识点/章节)
|
||||
└──────┬───────┘
|
||||
│
|
||||
┌──────────────┼──────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌────────────┐ ┌──────────┐ ┌────────────┐
|
||||
│ questions │ │ exams │ │ homework │
|
||||
└─────┬──────┘ └────┬─────┘ └─────┬──────┘
|
||||
│ │ │
|
||||
│ ┌──────────┘ │
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌────────────────┐ ┌──────────┐
|
||||
│ grades │ │ classes │
|
||||
└────────────────┘ └──────────┘
|
||||
```
|
||||
|
||||
### 依赖关系明细
|
||||
|
||||
| 依赖方向 | 类型 | 合理性 | 问题 |
|
||||
|---------|------|--------|------|
|
||||
| exams → questions | data-access + 类型 + action | ⚠️ 部分合理 | 类型导入合理;但 `persistAiGeneratedExamDraft` 直接 insert 到 questions 表,应通过 questions/data-access |
|
||||
| exams → classes | data-access | ❌ 不合理 | `getExams`/`getExamById` 直接查询 classes 表获取教师 gradeIds,应通过 classes/data-access |
|
||||
| exams → school | actions | ❌ 不合理 | `getSubjectsAction`/`getGradesAction` 直接查询 subjects/grades 表,应通过 school/data-access |
|
||||
| homework → exams | data-access + 组件 | ⚠️ 部分合理 | 业务上 homework 引用 exam(sourceExamId)合理;但直接查询 exams 表应改为调用 exams/data-access |
|
||||
| homework → classes | data-access + actions | ❌ 不合理 | 直接查询 classes/classEnrollments/classSubjectTeachers 表,应通过 classes/data-access |
|
||||
| homework → questions | data-access | ✅ 合理 | 通过 Drizzle 关系查询 homeworkAssignmentQuestions.question,未直接访问 questions 表 |
|
||||
| grades → exams | 无 | ✅ 合理 | grades 仅通过 examId 外键引用,不直接查询 exams 表 |
|
||||
| grades → homework | 无 | ✅ 合理 | grades 仅通过 type 枚举值 "homework" 引用,不直接查询 homework 表 |
|
||||
| grades → classes | data-access | ❌ 不合理 | 多个 data-access 文件直接查询 classes/classEnrollments 表 |
|
||||
| grades → users/subjects | data-access | ❌ 不合理 | 直接查询 users/subjects 表获取关联名称,应通过对应模块 data-access |
|
||||
| questions → textbooks | actions | ❌ 不合理 | `getKnowledgePointOptionsAction` 直接查询 knowledgePoints/chapters/textbooks 表 |
|
||||
| textbooks → questions | 组件 | ✅ 合理 | `knowledge-point-dialogs.tsx` 导入 CreateQuestionDialog 组件,属于 UI 组合 |
|
||||
|
||||
### 循环依赖分析
|
||||
|
||||
- **无直接循环依赖**:模块间的 data-access 依赖是单向的
|
||||
- **潜在风险**:exams → questions(data-access)与 questions → textbooks(actions)与 textbooks → questions(组件)形成链式依赖,但因 textbooks→questions 仅为组件层导入,不构成 data-access 层的循环依赖
|
||||
|
||||
---
|
||||
|
||||
## 三、各模块审查明细
|
||||
|
||||
### 3.1 exams 模块
|
||||
|
||||
#### 文件行数
|
||||
|
||||
| 文件 | 行数 | 限制 | 状态 |
|
||||
|------|------|------|------|
|
||||
| actions.ts | 832 | ≤800 | ⚠️ 超限 |
|
||||
| ai-pipeline.ts | 912 | ≤800 | ⚠️ 超限 |
|
||||
| data-access.ts | 339 | ≤800 | ✅ |
|
||||
| types.ts | 31 | 无限制 | ✅ |
|
||||
| hooks/use-exam-preview.ts | 295 | ≤500 | ✅ |
|
||||
|
||||
#### 模块职责边界
|
||||
|
||||
- **职责**:考试全生命周期管理(创建/编辑/预览/发布/删除/复制)+ AI 辅助出题
|
||||
- **问题**:`getSubjectsAction`/`getGradesAction` 属于 school 模块职责,被放在 exams/actions.ts 中
|
||||
|
||||
#### data-access 层问题
|
||||
|
||||
| 函数 | 问题 | 严重程度 |
|
||||
|------|------|---------|
|
||||
| `getExams` | 直接查询 `classes` 表获取教师 gradeIds(第 71-78 行) | 高 |
|
||||
| `getExamById` | 直接查询 `classes` 表获取教师 gradeIds(第 155-159 行) | 高 |
|
||||
| `persistAiGeneratedExamDraft` | 直接 insert 到 `questions` 表(第 317-326 行) | 高 |
|
||||
|
||||
#### actions 层问题
|
||||
|
||||
| 函数 | 问题 | 严重程度 |
|
||||
|------|------|---------|
|
||||
| `updateExamAction` | 直接 `db.query.exams.findFirst` 做归属校验 + `db.delete`/`db.insert`/`db.update` 操作 examQuestions | 高 |
|
||||
| `deleteExamAction` | 直接 `db.query.exams.findFirst` 做归属校验 + `db.delete` | 高 |
|
||||
| `duplicateExamAction` | 直接 `db.query.exams.findFirst` + `db.transaction` 内联 insert exams/examQuestions | 高 |
|
||||
| `getExamPreviewAction` | 直接 `db.query.exams.findFirst` 查询考试预览数据 | 高 |
|
||||
| `getSubjectsAction` | 直接查询 `subjects` 表 —— 跨模块 DB 访问 | 高 |
|
||||
| `getGradesAction` | 直接查询 `grades` 表 —— 跨模块 DB 访问 | 高 |
|
||||
|
||||
#### 组件耦合
|
||||
|
||||
| 组件 | 问题 | 严重程度 |
|
||||
|------|------|---------|
|
||||
| `exam-assembly.tsx` | 调用 `getQuestionsAction`(questions 模块的 action) | 中 |
|
||||
| 8 个组件 | 导入 `Question` 类型自 questions/types | 低(类型导入合理) |
|
||||
| `ExamAssembly` | **10 个 props**(examId, title, subject, grade, difficulty, totalScore, durationMin, initialSelected, initialStructure, questionOptions) | 中 |
|
||||
| `ExamPreviewQuestionEditor` | **10 个 props** | 中 |
|
||||
|
||||
#### ai-pipeline.ts 问题
|
||||
|
||||
- 912 行,超过 800 行建议值
|
||||
- 混合了 Zod schema、AI prompt、JSON 解析修复、题目详情解析、并发控制等多种职责
|
||||
- 建议拆分为:`ai-schema.ts`(Zod schema)、`ai-prompts.ts`(prompt 常量)、`ai-parser.ts`(JSON 解析修复)、`ai-pipeline.ts`(核心生成逻辑)
|
||||
|
||||
---
|
||||
|
||||
### 3.2 homework 模块
|
||||
|
||||
#### 文件行数
|
||||
|
||||
| 文件 | 行数 | 限制 | 状态 |
|
||||
|------|------|------|------|
|
||||
| data-access.ts | **1038** | ≤1000 硬上限 | ❌ **必须拆分** |
|
||||
| actions.ts | 387 | ≤800 | ✅ |
|
||||
| schema.ts | 29 | 无限制 | ✅ |
|
||||
| types.ts | 186 | 无限制 | ✅ |
|
||||
|
||||
#### 模块职责边界
|
||||
|
||||
- **职责**:作业全生命周期(创建/发布/作答/批改/分析)
|
||||
- **问题**:`getStudentDashboardGrades` 包含班级排名计算逻辑(150+ 行),属于 dashboard 或 grades 模块职责
|
||||
|
||||
#### data-access 层问题(严重)
|
||||
|
||||
| 函数 | 问题 | 严重程度 |
|
||||
|------|------|---------|
|
||||
| `getStudentDashboardGrades` | 150+ 行排名计算业务逻辑混入 data-access | 高 |
|
||||
| `getHomeworkAssignmentAnalytics` | 145+ 行错误率/错误答案统计业务逻辑混入 data-access | 高 |
|
||||
| `getHomeworkAssignments` | 直接查询 `exams` 表(第 167-171 行) | 高 |
|
||||
| `getHomeworkAssignmentReviewList` | 直接查询 `exams` 表(第 227-233 行) | 高 |
|
||||
| `getHomeworkSubmissions` | 直接查询 `exams` 表(第 349-359 行) | 高 |
|
||||
| `getHomeworkAssignmentById` | 直接查询 `exams` 表(第 403-407 行) | 高 |
|
||||
| `getStudentHomeworkAssignments` | 直接 join `exams`/`subjects` 表(第 730-731 行) | 高 |
|
||||
| `getDemoStudentUser` | 直接查询 `users`/`roles`/`usersToRoles` 表 + 使用 `auth()` 而非 auth-guard | 高 |
|
||||
| `getStudentDashboardGrades` | 直接查询 `classEnrollments`/`users` 表 | 高 |
|
||||
|
||||
#### actions 层问题
|
||||
|
||||
| 函数 | 问题 | 严重程度 |
|
||||
|------|------|---------|
|
||||
| `createHomeworkAssignmentAction` | **157 行**,混合数据访问 + 业务逻辑 + 权限校验 | 高 |
|
||||
| 同上 | 直接查询 `classes`/`classSubjectTeachers`/`exams`/`classEnrollments` 表 | 高 |
|
||||
| 同上 | 内联 `db.transaction` insert homeworkAssignments/homeworkAssignmentQuestions/homeworkAssignmentTargets | 高 |
|
||||
| `startHomeworkSubmissionAction` | 直接 `db.query` + `db.insert` | 高 |
|
||||
| `saveHomeworkAnswerAction` | 直接 `db.query` + `db.transaction` | 高 |
|
||||
| `submitHomeworkAction` | 直接 `db.query` + `db.update` | 高 |
|
||||
| `gradeHomeworkSubmissionAction` | 直接 `db.update` 循环更新 homeworkAnswers | 高 |
|
||||
|
||||
#### 拆分建议
|
||||
|
||||
`data-access.ts`(1038 行)建议拆分为:
|
||||
- `data-access.ts`:基础 CRUD(getHomeworkAssignments, getHomeworkAssignmentById, getHomeworkSubmissions)
|
||||
- `data-access-student.ts`:学生视角查询(getStudentHomeworkAssignments, getStudentHomeworkTakeData, getStudentDashboardGrades)
|
||||
- `data-access-analytics.ts`:分析统计(getHomeworkAssignmentAnalytics, getTeacherGradeTrends)
|
||||
- `data-access-grading.ts`:批改相关(getHomeworkSubmissionDetails, getHomeworkAssignmentReviewList)
|
||||
|
||||
---
|
||||
|
||||
### 3.3 questions 模块
|
||||
|
||||
#### 文件行数
|
||||
|
||||
| 文件 | 行数 | 限制 | 状态 |
|
||||
|------|------|------|------|
|
||||
| actions.ts | 294 | ≤800 | ✅ |
|
||||
| data-access.ts | 129 | ≤800 | ✅ |
|
||||
| schema.ts | 18 | 无限制 | ✅ |
|
||||
| types.ts | 34 | 无限制 | ✅ |
|
||||
|
||||
#### 模块职责边界
|
||||
|
||||
- **职责**:题库管理(题目 CRUD、知识点关联、题型支持)
|
||||
- **问题**:`getKnowledgePointOptionsAction` 查询 textbooks 模块的表,属于 textbooks 模块职责
|
||||
|
||||
#### data-access 层问题
|
||||
|
||||
- ✅ 仅访问 `questions` 和 `questionsToKnowledgePoints` 表,无跨模块 DB 访问
|
||||
- ❌ **缺失写操作函数**:`insertQuestionWithRelations`、`deleteQuestionRecursive` 等 data-access 函数被错误地放在 actions.ts 中
|
||||
|
||||
#### actions 层问题
|
||||
|
||||
| 函数 | 问题 | 严重程度 |
|
||||
|------|------|---------|
|
||||
| `createNestedQuestion` | 内联 `db.transaction` + 调用 `insertQuestionWithRelations`(data-access 函数错放在 actions) | 高 |
|
||||
| `updateQuestionAction` | 内联 `db.transaction` 做 update/delete/insert | 高 |
|
||||
| `deleteQuestionAction` | 内联 `db.transaction` + 调用 `deleteQuestionRecursive`(data-access 函数错放在 actions) | 高 |
|
||||
| `getKnowledgePointOptionsAction` | 直接查询 `knowledgePoints`/`chapters`/`textbooks` 表 —— 跨模块 DB 访问 | 高 |
|
||||
| `getQuestionsAction` | ✅ 正确委托给 data-access.getQuestions | ✅ |
|
||||
|
||||
#### 组件耦合
|
||||
|
||||
- ✅ 无跨模块依赖
|
||||
|
||||
---
|
||||
|
||||
### 3.4 textbooks 模块(标杆模块)
|
||||
|
||||
#### 文件行数
|
||||
|
||||
| 文件 | 行数 | 限制 | 状态 |
|
||||
|------|------|------|------|
|
||||
| actions.ts | 276 | ≤800 | ✅ |
|
||||
| data-access.ts | 428 | ≤800 | ✅ |
|
||||
| types.ts | 79 | 无限制 | ✅ |
|
||||
| hooks/use-knowledge-point-actions.ts | 121 | ≤500 | ✅ |
|
||||
| hooks/use-text-selection.ts | - | ≤500 | ✅ |
|
||||
|
||||
#### 模块职责边界
|
||||
|
||||
- **职责**:教材与知识体系管理(教材/章节树形结构、知识点 CRUD、Markdown 内容编辑、知识图谱)
|
||||
- ✅ 职责单一,无越界
|
||||
|
||||
#### data-access 层评价
|
||||
|
||||
- ✅ 仅访问 `textbooks`、`chapters`、`knowledgePoints` 表
|
||||
- ✅ 无跨模块 DB 访问
|
||||
- ✅ 无业务逻辑混入
|
||||
|
||||
#### actions 层评价
|
||||
|
||||
- ✅ **标杆实现**:所有 action 均遵循"权限校验 → 调用 data-access → revalidatePath → 返回"模式
|
||||
- ✅ 无直接 DB 访问
|
||||
- ✅ 无业务逻辑混入
|
||||
|
||||
#### 组件耦合
|
||||
|
||||
- `knowledge-point-dialogs.tsx` 导入 `CreateQuestionDialog` 自 questions 模块 —— ✅ 合理的 UI 组合
|
||||
|
||||
#### hooks 评价
|
||||
|
||||
- `useKnowledgePointActions` 有 7 个参数(textbookId, selectedChapterId, selectedChapterTextbookId, highlightedKpId, setHighlightedKpId, onKpCreated)—— ✅ 在 8 个限制内
|
||||
|
||||
---
|
||||
|
||||
### 3.5 grades 模块
|
||||
|
||||
#### 文件行数
|
||||
|
||||
| 文件 | 行数 | 限制 | 状态 |
|
||||
|------|------|------|------|
|
||||
| actions.ts | 312 | ≤800 | ✅ |
|
||||
| actions-analytics.ts | 133 | ≤800 | ✅ |
|
||||
| data-access.ts | 419 | ≤800 | ✅ |
|
||||
| data-access-analytics.ts | 293 | ≤800 | ✅ |
|
||||
| data-access-ranking.ts | 121 | ≤800 | ✅ |
|
||||
| export.ts | 214 | ≤800 | ✅ |
|
||||
| schema.ts | 52 | 无限制 | ✅ |
|
||||
| types.ts | - | 无限制 | ✅ |
|
||||
|
||||
#### 模块职责边界
|
||||
|
||||
- **职责**:成绩分析(录入/查询/统计/导出/趋势对比分析)
|
||||
- ✅ 职责单一,未混入考试/作业逻辑
|
||||
- ✅ 通过 `examId` 外键引用考试,通过 `type` 枚举引用作业类型,未直接依赖 exams/homework 模块的 data-access
|
||||
|
||||
#### data-access 层问题
|
||||
|
||||
| 文件 | 函数 | 问题 | 严重程度 |
|
||||
|------|------|------|---------|
|
||||
| data-access.ts | `getGradeRecords` | 直接 join `classes`/`subjects`/`users` 表 | 高 |
|
||||
| data-access.ts | `getStudentGradeSummary` | 直接 join `classes`/`subjects`/`users` 表 | 高 |
|
||||
| data-access.ts | `getClassRanking` | 直接 join `users` 表 | 高 |
|
||||
| data-access.ts | `getClassStudentsForEntry` | 直接查询 `classEnrollments`/`users` 表 —— 应在 classes 模块 | 高 |
|
||||
| data-access.ts | `getClassGradeStatsWithMeta` | 直接查询 `classes`/`classEnrollments` 表 | 高 |
|
||||
| data-access.ts | `getClassGradeStats` | 统计计算业务逻辑(average/median/stdDev/passRate/excellentRate)混入 data-access | 中 |
|
||||
| data-access-analytics.ts | `getGradeTrend` | 直接 join `classes`/`subjects` 表 | 高 |
|
||||
| data-access-analytics.ts | `getClassComparison` | 直接查询 `classes` 表 + 统计计算业务逻辑 | 高 |
|
||||
| data-access-analytics.ts | `getSubjectComparison` | 直接 join `subjects` 表 + 统计计算业务逻辑 | 高 |
|
||||
| data-access-analytics.ts | `getGradeDistribution` | 分桶统计业务逻辑混入 data-access | 中 |
|
||||
| data-access-ranking.ts | `getRankingTrend` | 直接查询 `classEnrollments`/`users` 表 + 排名计算业务逻辑 | 高 |
|
||||
| export.ts | `exportClassGradeReportToExcel` | 直接查询 `classes`/`subjects`/`users` 表 + 排名计算业务逻辑 | 高 |
|
||||
|
||||
#### actions 层评价
|
||||
|
||||
- ✅ **标杆实现**:`actions.ts` 和 `actions-analytics.ts` 均遵循"权限校验 → 调用 data-access → 返回"模式
|
||||
- ✅ 无直接 DB 访问
|
||||
- ✅ 无业务逻辑混入
|
||||
|
||||
#### 组件耦合
|
||||
|
||||
- ✅ 无跨模块依赖
|
||||
|
||||
---
|
||||
|
||||
## 四、跨模块直接 DB 访问汇总
|
||||
|
||||
> 以下为违反模块封装原则的直接数据库查询,应改为通过对方模块的 data-access 函数调用。
|
||||
|
||||
### 4.1 按来源模块分类
|
||||
|
||||
| 来源模块 | 文件 | 被访问的表 | 应调用的模块 |
|
||||
|---------|------|-----------|-------------|
|
||||
| exams | data-access.ts | `classes` | classes/data-access |
|
||||
| exams | data-access.ts | `questions`(insert) | questions/data-access |
|
||||
| exams | actions.ts | `subjects`, `grades` | school/data-access |
|
||||
| homework | actions.ts | `classes`, `classSubjectTeachers`, `exams`, `classEnrollments` | classes/data-access, exams/data-access |
|
||||
| homework | data-access.ts | `exams`, `classEnrollments`, `subjects`, `users`, `roles`, `usersToRoles` | exams/data-access, classes/data-access, school/data-access |
|
||||
| questions | actions.ts | `knowledgePoints`, `chapters`, `textbooks` | textbooks/data-access |
|
||||
| grades | data-access.ts | `classes`, `classEnrollments`, `subjects`, `users` | classes/data-access, school/data-access |
|
||||
| grades | data-access-analytics.ts | `classes`, `subjects` | classes/data-access, school/data-access |
|
||||
| grades | data-access-ranking.ts | `classEnrollments`, `users` | classes/data-access |
|
||||
| grades | export.ts | `classes`, `subjects`, `users` | classes/data-access, school/data-access |
|
||||
|
||||
### 4.2 按被访问表分类(频次)
|
||||
|
||||
| 被访问表 | 访问次数 | 应归属模块 |
|
||||
|---------|---------|-----------|
|
||||
| `classes` | 8+ | classes |
|
||||
| `classEnrollments` | 6+ | classes |
|
||||
| `users` | 6+ | users |
|
||||
| `subjects` | 6+ | school |
|
||||
| `exams` | 5+ | exams |
|
||||
| `grades`(年级表) | 1 | school |
|
||||
| `classSubjectTeachers` | 1 | classes |
|
||||
| `knowledgePoints` | 1 | textbooks |
|
||||
| `chapters` | 1 | textbooks |
|
||||
| `textbooks` | 1 | textbooks |
|
||||
| `roles`, `usersToRoles` | 1 | users |
|
||||
| `questions`(insert) | 1 | questions |
|
||||
|
||||
---
|
||||
|
||||
## 五、改进建议
|
||||
|
||||
### 5.1 高优先级(P0)
|
||||
|
||||
1. **拆分 homework/data-access.ts**(1038 行 → 4 个文件)
|
||||
- 按职责拆分为 data-access.ts / data-access-student.ts / data-access-analytics.ts / data-access-grading.ts
|
||||
|
||||
2. **消除跨模块直接 DB 访问**
|
||||
- 在 classes/data-access 暴露 `getClassGradeIdsByClassIds`、`getClassStudentsByClassId`、`getActiveClassStudents` 等函数
|
||||
- 在 exams/data-access 暴露 `getExamForHomeworkCreation`(含 questions 关联)
|
||||
- 在 school/data-access 暴露 `getSubjectOptions`、`getGradeOptions`
|
||||
- 在 users/data-access 暴露 `getUserNameByIds`、`getStudentInfo`
|
||||
- 在 textbooks/data-access 暴露 `getKnowledgePointOptions`
|
||||
- 在 questions/data-access 暴露 `insertQuestionWithRelations`、`deleteQuestionRecursive`
|
||||
|
||||
3. **将 exams/actions.ts 中的 DB 操作下沉到 data-access**
|
||||
- `updateExamAction`、`deleteExamAction`、`duplicateExamAction`、`getExamPreviewAction` 的 DB 操作移至 data-access
|
||||
- 将 `getSubjectsAction`/`getGradesAction` 移至 school 模块或改为调用 school/data-access
|
||||
|
||||
4. **将 homework/actions.ts 中的 DB 操作下沉到 data-access**
|
||||
- `createHomeworkAssignmentAction`(157 行)拆分为:data-access 函数 + action 编排
|
||||
- 其他 action 的 DB 操作全部移至 data-access
|
||||
|
||||
5. **将 questions/actions.ts 中的 DB 操作下沉到 data-access**
|
||||
- `insertQuestionWithRelations`、`deleteQuestionRecursive` 移至 data-access
|
||||
- `getKnowledgePointOptionsAction` 改为调用 textbooks/data-access
|
||||
|
||||
### 5.2 中优先级(P1)
|
||||
|
||||
6. **拆分 exams/ai-pipeline.ts**(912 行 → 4 个文件)
|
||||
- ai-schema.ts(Zod schema)、ai-prompts.ts(prompt 常量)、ai-parser.ts(JSON 解析修复)、ai-pipeline.ts(核心生成逻辑)
|
||||
|
||||
7. **将 homework/data-access.ts 中的业务逻辑提取到独立服务层**
|
||||
- `getStudentDashboardGrades` 的排名计算逻辑提取到 `services/ranking-service.ts`
|
||||
- `getHomeworkAssignmentAnalytics` 的错误率统计逻辑提取到 `services/analytics-service.ts`
|
||||
|
||||
8. **将 grades/data-access.ts 中的统计计算逻辑提取到独立服务层**
|
||||
- `getClassGradeStats` 的统计计算提取到 `services/stats-service.ts`
|
||||
- `getGradeDistribution` 的分桶逻辑提取到 `services/distribution-service.ts`
|
||||
|
||||
9. **减少组件 props 数量**
|
||||
- `ExamAssembly`(10 props)和 `ExamPreviewQuestionEditor`(10 props)应考虑使用 Context 或组合模式减少 props
|
||||
|
||||
### 5.3 低优先级(P2)
|
||||
|
||||
10. **统一 auth 调用方式**
|
||||
- `homework/data-access.ts` 的 `getDemoStudentUser` 使用 `auth()` 而非 `auth-guard.getAuthContext()`,应统一
|
||||
|
||||
11. **补全 questions/data-access.ts 的写操作**
|
||||
- 当前 data-access 仅有 `getQuestions`,所有写操作错放在 actions.ts
|
||||
|
||||
---
|
||||
|
||||
## 六、标杆模块推荐
|
||||
|
||||
| 模块 | 推荐参考点 |
|
||||
|------|-----------|
|
||||
| **textbooks** | actions 层编排模式(权限校验 → 调用 data-access → revalidatePath) |
|
||||
| **textbooks** | data-access 层职责单一(仅访问本模块表,无业务逻辑) |
|
||||
| **grades** | actions 层拆分(actions.ts + actions-analytics.ts 按职责分文件) |
|
||||
| **grades** | data-access 层拆分(data-access.ts + data-access-analytics.ts + data-access-ranking.ts) |
|
||||
| **grades** | 跨模块解耦(通过外键引用 exams/homework,不直接访问其表) |
|
||||
|
||||
---
|
||||
|
||||
## 七、审查方法说明
|
||||
|
||||
- **审查范围**:5 个核心业务模块的 actions/data-access/schema/types/components/hooks 全量文件
|
||||
- **审查工具**:源码全量阅读 + Grep 跨模块依赖扫描 + PowerShell 行数统计
|
||||
- **审查依据**:项目规则中"Server Action 必须使用 requirePermission()"、"单文件行数规范"、"模块职责单一"等规则
|
||||
- **未覆盖项**:未运行 lint/typecheck(本次为只读审查,不修改代码);未审查组件内部实现细节(仅审查 props 数量和跨模块依赖)
|
||||
Reference in New Issue
Block a user