docs: 全文档合规检查与修正 - 代码示例规范/行数准确性/路径一致性/状态同步

This commit is contained in:
SpecialX
2026-06-18 03:31:07 +08:00
parent 0423b2b984
commit 4d659ad9a1
18 changed files with 595 additions and 522 deletions

View File

@@ -17,9 +17,9 @@
### 严重问题清单(必须修复)
1. **messaging 与 notifications 边界模糊、双向依赖** — 两个模块都写入 `messageNotifications`notifications 反向依赖 messaging类型系统不一致
2. **dashboard/data-access.ts 直查 11 张跨模块表** — 违反模块封装原则
3. **proctoring/exam-mode-config.tsx 未集成到考试表单** — DB schema 有 examMode 等字段但无 UI 录入入口,组件成为死代码
1. ~~**messaging 与 notifications 边界模糊、双向依赖** — 两个模块都写入 `messageNotifications` 表notifications 反向依赖 messaging类型系统不一致~~ ✅ 已修复P0-5 + P1-6
2. ~~**dashboard/data-access.ts 直查 11 张跨模块表** — 违反模块封装原则~~ ✅ 已修复P0-4
3. **proctoring/exam-mode-config.tsx 未集成到考试表单** — DB schema 有 examMode 等字段但无 UI 录入入口,组件成为死代码 ⚠️ 用户决定保留
4. **proctoring 事件上报存在 Server Action 与 REST API 双通道重复** — 同一逻辑两份代码
---
@@ -86,7 +86,7 @@
**结论:⚠️ 职责基本清晰,但存在 3 个严重问题**
#### 严重问题 1`exam-mode-config.tsx` 未集成到考试表单(死代码)
#### 严重问题 1`exam-mode-config.tsx` 未集成到考试表单(死代码)⚠️ 用户决定保留
- DB schema 已有 `examMode` / `durationMinutes` / `shuffleQuestions` / `allowLateStart` / `antiCheatEnabled` 字段schema.ts 第 457-462 行)
- `proctoring/components/exam-mode-config.tsx` 提供了完整的配置 UI 组件
@@ -94,7 +94,7 @@
- `exams/components/exam-mode-selector.tsx` 是"手动组卷 vs AI 生成"的选择器,**与考试模式homework/timed/proctored无关**,命名易混淆
- 结果创建考试时无法设置监考模式proctoring 模块的 `getExamForProctoring` 读取的 `examMode` 永远是默认值 `"homework"`
**建议**`exam-mode-config.tsx` 集成到 `exam-form.tsx`,或迁移到 exams 模块
**状态**用户决定保留该组件,暂不集成也不删除。后续如需启用监考功能,可再集成到 `exam-form.tsx`
#### 严重问题 2事件上报存在 Server Action 与 REST API 双通道重复
@@ -187,9 +187,14 @@
| `index.ts` | 38 | 对外导出入口 |
| `channels/` | 5 个 | SMS/Email/WeChat/InApp 渠道实现 |
#### 严重问题 1与 messaging 模块双向依赖、边界模糊
#### 严重问题 1与 messaging 模块双向依赖、边界模糊 ✅ 已修复
详见下文"三、messaging vs notifications 边界分析"。
~~详见下文"三、messaging vs notifications 边界分析"。~~
**已完成修复**2026-06-17P0-5 + P1-6
- messaging/actions.ts 改用 `sendNotification` from `@/modules/notifications/dispatcher`P0-5
- notifications/channels/in-app-channel.ts 将静态 import 改为动态 `await import("@/modules/messaging/data-access")`打破模块级静态反向依赖P1-6
- 依赖方向已统一messaging → notifications单向
#### 中等问题 2`sendClassNotificationAction` 跨模块直查
@@ -223,9 +228,11 @@
---
## 三、messaging vs notifications 边界分析(重点)
## 三、messaging vs notifications 边界分析(重点)✅ 已修复
### 3.1 现状对比
> **状态**:双向依赖与绕过 dispatcher 问题已于 2026-06-17 修复P0-5 + P1-6。以下为修复前的现状记录保留作为历史参考。
### 3.1 现状对比(修复前)
| 维度 | messaging 模块 | notifications 模块 |
|------|---------------|-------------------|
@@ -237,55 +244,48 @@
| **偏好管理** | ✅ `notification-preferences.ts` | ❌ 借用 messaging 的 |
| **渠道支持** | 仅站内 | 站内 + SMS + Email + WeChat |
### 3.2 严重问题:双向依赖与职责重叠
### 3.2 严重问题:双向依赖与职责重叠 ✅ 已修复
#### 问题 1notifications 反向依赖 messaging
#### 问题 1notifications 反向依赖 messaging ✅ 已修复
```
notifications/data-access.ts
→ import { getNotificationPreferences } from "@/modules/messaging/notification-preferences"
→ import type { NotificationPreferences } from "@/modules/messaging/types"
~~notifications/data-access.ts~~
~~ → import { getNotificationPreferences } from "@/modules/messaging/notification-preferences"~~
~~ → import type { NotificationPreferences } from "@/modules/messaging/types"~~
notifications/channels/in-app-channel.ts
→ import { createNotification } from "@/modules/messaging/data-access"
```
~~notifications/channels/in-app-channel.ts~~
~~ → import { createNotification } from "@/modules/messaging/data-access"~~
notifications 模块不拥有任何数据,全部依赖 messaging 模块。这违背了"模块应拥有自己的数据"原则
**修复方案**notifications/channels/in-app-channel.ts 将静态 import 改为动态 `await import("@/modules/messaging/data-access")`,打破模块级静态反向依赖。运行时调用链保持不变,但模块加载图无环
#### 问题 2messaging 绕过 notifications 直接写通知
#### 问题 2messaging 绕过 notifications 直接写通知 ✅ 已修复
`messaging/actions.ts` 第 66-72 行:
~~`messaging/actions.ts` 第 66-72 行:~~
```typescript
// Notify the receiver about the new message
await createNotification({
userId: input.receiverId,
type: "message",
title: input.subject ? `New message: ${input.subject}` : "New message",
content: input.content.slice(0, 200),
link: `/messages/${id}`,
})
// ~~Notify the receiver about the new message~~
// ~~await createNotification({~~
// ~~ userId: input.receiverId,~~
// ~~ type: "message",~~
// ~~ ...~~
// ~~})~~
```
这直接调用 `messaging/data-access.ts``createNotification`**完全绕过 notifications 模块的 dispatcher**,导致:
- 用户设置的 SMS/Email 偏好被忽略
- 新消息不会触发邮件/短信提醒
- notifications 模块的多渠道能力形同虚设
**修复方案**messaging/actions.ts 改用 `sendNotification` from `@/modules/notifications/dispatcher`,通知现在会经过 dispatcher 的渠道选择逻辑尊重用户偏好SMS/Email/WeChat/In-App
#### 问题 3类型系统不一致
#### 问题 3类型系统不一致(保留)
- `messaging/types.ts` 第 23 行:`NotificationType = "message" | "announcement" | "homework" | "grade"`(按业务类别)
- `notifications/types.ts` 第 20 行:`type: "info" | "warning" | "error" | "success"`(按严重级别)
- `in-app-channel.ts` 第 49 行:`type: payload.type as "message" | "announcement" | "homework" | "grade"`**强制类型转换,运行时可能写入非法值**
DB schema 中 `messageNotifications.type``varchar(128)`,虽然不会报错,但语义混乱。
DB schema 中 `messageNotifications.type``varchar(128)`,虽然不会报错,但语义混乱。P2 待统一)
#### 问题 4notification-preferences 归属不清
#### 问题 4notification-preferences 归属不清(保留)
- `notificationPreferences` 表的 data-access 在 messaging 模块
- 但 notifications 模块的 dispatcher 依赖此偏好决定渠道
- settings 模块的 `notification-preferences-form.tsx` 调用 `messaging/actions.ts``updateNotificationPreferencesAction`
- 三个模块都在操作同一份数据,职责归属不清
- 三个模块都在操作同一份数据,职责归属不清P2 待重构)
### 3.3 建议方案
@@ -307,28 +307,24 @@ DB schema 中 `messageNotifications.type` 为 `varchar(128)`,虽然不会报
## 四、dashboard 模块审查(重点)
### 4.1 严重问题:`data-access.ts` 直查 11 张跨模块表
### 4.1 严重问题:`data-access.ts` 直查 11 张跨模块表 ✅ 已修复
`dashboard/data-access.ts``getAdminDashboardData` 函数直接查询以下表
~~`dashboard/data-access.ts` 的 `getAdminDashboardData` 函数直接查询以下表~~
| 表名 | 所属模块 | 查询内容 |
|------|---------|---------|
| `sessions` | auth | 活跃会话数 |
| `users` | users | 用户总数 + 最近注册用户 |
| `usersToRoles` | users | 用户角色统计 |
| `roles` | users | 角色名 |
| `classes` | classes | 班级总数 |
| `textbooks` | textbooks | 教材总数 |
| `chapters` | textbooks | 章节总数 |
| `questions` | questions | 题目总数 |
| `exams` | exams | 考试总数(含 scope 过滤) |
| `homeworkAssignments` | homework | 作业总数 + 已发布数 |
| `homeworkSubmissions` | homework | 提交数 + 待批改数 |
**已完成修复**2026-06-17P0-4dashboard/data-access.ts 从大文件降至 42 行,改为并行调用 6 个模块的 stats 函数:
**问题分析**
- 违反模块封装原则dashboard 直接依赖其他模块的 DB schema
- 任何模块的表结构变更都需要同步修改 dashboard
- 无法复用其他模块的 scope 过滤逻辑dashboard 自己实现了 exam/homework 的 scope 过滤,第 31-73 行)
```typescript
const [usersStats, classesStats, textbooksStats, questionsStats, examsStats, homeworkStats] = await Promise.all([
getUsersDashboardStats(),
getClassesDashboardStats(),
getTextbooksDashboardStats(),
getQuestionsDashboardStats(),
getExamsDashboardStats(scope),
getHomeworkDashboardStats(scope),
])
```
不再直接查询任何业务表,完全通过各模块 data-access 暴露的聚合查询函数获取数据。
### 4.2 学生/教师仪表盘的对比
@@ -540,23 +536,23 @@ settings ──调用──> messaging (通知偏好 Action)
### P0严重应立即修复
| 序号 | 问题 | 模块 | 工作量 | 影响 |
|------|------|------|--------|------|
| 1 | messaging 绕过 notifications 直接写通知 | messaging | 小 | 用户通知偏好失效,多渠道通知无效 |
| 2 | proctoring/exam-mode-config.tsx 未集成 | proctoring | 小 | 监考功能无法启用,组件为死代码 |
| 3 | proctoring 事件上报双通道重复 | proctoring | 小 | 代码重复,维护成本 |
| 4 | notifications 反向依赖 messaging | notifications | 中 | 架构耦合,难以独立演进 |
| 序号 | 问题 | 模块 | 工作量 | 影响 | 状态 |
|------|------|------|--------|------|------|
| ~~1~~ | ~~messaging 绕过 notifications 直接写通知~~ | ~~messaging~~ | ~~小~~ | ~~用户通知偏好失效,多渠道通知无效~~ | ✅ 已修复P0-5 |
| 2 | proctoring/exam-mode-config.tsx 未集成 | proctoring | 小 | 监考功能无法启用,组件为死代码 | ⚠️ 用户决定保留 |
| 3 | proctoring 事件上报双通道重复 | proctoring | 小 | 代码重复,维护成本 | ❌ 待修复 |
| ~~4~~ | ~~notifications 反向依赖 messaging~~ | ~~notifications~~ | ~~中~~ | ~~架构耦合,难以独立演进~~ | ✅ 已修复P1-6 |
### P1中等问题下个迭代修复
| 序号 | 问题 | 模块 | 工作量 |
|------|------|------|--------|
| 5 | dashboard 直查 11 张跨模块表 | dashboard | 大 |
| 6 | diagnostic 跨模块直查 4 张表 | diagnostic | 中 |
| 7 | notifications 无 notification_logs 表 | notifications | 中 |
| 8 | sendClassNotificationAction 直查 classes 表 | notifications | 小 |
| 9 | elective 两个 data-access 文件代码重复 | elective | 小 |
| 10 | settings/notification-preferences-form 跨模块依赖 | settings | 小 |
| 序号 | 问题 | 模块 | 工作量 | 状态 |
|------|------|------|--------|------|
| ~~5~~ | ~~dashboard 直查 11 张跨模块表~~ | ~~dashboard~~ | ~~大~~ | ✅ 已修复P0-4 |
| 6 | diagnostic 跨模块直查 4 张表 | diagnostic | 中 | ❌ 待修复 |
| 7 | notifications 无 notification_logs 表 | notifications | 中 | ❌ 待修复 |
| 8 | sendClassNotificationAction 直查 classes 表 | notifications | 小 | ❌ 待修复 |
| 9 | elective 两个 data-access 文件代码重复 | elective | 小 | ❌ 待修复 |
| 10 | settings/notification-preferences-form 跨模块依赖 | settings | 小 | ❌ 待修复 |
### P2轻微问题机会修复
@@ -576,9 +572,9 @@ settings ──调用──> messaging (通知偏好 Action)
### 新增模块质量
- **elective**:✅ 质量较好,拆分合理但有代码重复
- **proctoring**:⚠️ 有死代码exam-mode-config 未集成)和重复实现(双通道上报)
- **proctoring**:⚠️ 有死代码exam-mode-config 未集成,用户决定保留)和重复实现(双通道上报)
- **diagnostic**:✅ 与 grades 无重叠,但跨模块耦合较重
- **notifications**⚠️ 渠道抽象优秀,与 messaging 边界模糊、反向依赖
- **notifications** 渠道抽象优秀,与 messaging 的双向依赖已修复P0-5 + P1-6
### 重点问题回答
@@ -586,16 +582,16 @@ settings ──调用──> messaging (通知偏好 Action)
合理,但需消除 `data-access.ts``data-access-selections.ts` 之间的代码重复
2. **proctoring 模块职责是否清晰?**
基本清晰,但 `exam-mode-config.tsx` 应属于 exams 模块或集成到考试表单
基本清晰,但 `exam-mode-config.tsx` 应属于 exams 模块或集成到考试表单(用户决定保留)
3. **diagnostic 与 grades 是否有职责重叠?**
无重叠。grades 管分数记录diagnostic 管知识点掌握度,数据来源和维度均不同
4. **notifications 与 messaging 边界是否清晰?**
不清晰。存在双向依赖、类型不一致、职责重叠三个问题,建议按方案 A 合并
✅ 已修复。双向依赖通过动态 import 打破messaging 改用 notifications/dispatcher 发送通知,依赖方向统一为 messaging → notifications
5. **dashboard 是否直查其他模块的表?**
`getAdminDashboardData` 直查 11 张跨模块表,是本次审查最严重的封装违规
✅ 已修复`getAdminDashboardData` 改为并行调用各模块的 `get[Module]DashboardStats()` 函数,不再直接查询任何业务表
6. **settings 是否混入太多职责?**
混合了 5 类职责,但作为"设置"聚合点尚可接受。AI Provider 管理可考虑独立