Files
NextEdu/docs/architecture/audit/diagnostic-audit-report.md
SpecialX 89b9e181d2 docs(audit): add audit reports for grades, homework, lesson-preparation, messaging, permissions, question-bank, settings, textbooks
- Add grades-audit-report

- Add homework-audit-report and homework-exams-audit-report

- Add lesson-preparation-audit-report-v3 and v4

- Add messaging-audit-report

- Add permissions-audit-report

- Add question-bank-audit-report

- Add settings-profile-audit-report-v3

- Add textbooks-audit-report-v3
2026-07-03 10:23:34 +08:00

302 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 学情诊断Diagnostic模块审计报告
> 审计日期2026-06-22
> 审计范围:`src/modules/diagnostic/**`、`src/app/(dashboard)/teacher/diagnostic/**`、`src/app/(dashboard)/student/diagnostic/**`、`src/app/(dashboard)/parent/diagnostic/**`
> 参照规则:`docs/architecture/004_architecture_impact_map.md` §2.22、`docs/architecture/005_architecture_data.json`、`.trae/rules/project_rules.md`
> 前置文档:[grades-diagnostic-audit-report-v4.md](./grades-diagnostic-audit-report-v4.md)v4 已完成 12 项 P1 数据安全修复)
---
## 一、现有实现概要
### 1.1 文件分布
| 层 | 文件 | 行数 | 职责 |
|------|------|------|------|
| 类型 | [types.ts](file:///e:/Desktop/CICD/src/modules/diagnostic/types.ts) | 109 | DiagnosticReport / Mastery / Summary 类型定义 |
| 数据访问 | [data-access.ts](file:///e:/Desktop/CICD/src/modules/diagnostic/data-access.ts) | 477 | 掌握度查询 + 从提交/成绩更新掌握度 |
| 数据访问 | [data-access-reports.ts](file:///e:/Desktop/CICD/src/modules/diagnostic/data-access-reports.ts) | 256 | 诊断报告 CRUD + DataScope 过滤 |
| 统计服务 | [stats-service.ts](file:///e:/Desktop/CICD/src/modules/diagnostic/stats-service.ts) | 388 | 12 个纯统计函数 |
| Server Actions | [actions.ts](file:///e:/Desktop/CICD/src/modules/diagnostic/actions.ts) | 274 | 5 个 Action生成/发布/删除/导出/按知识点筛选) |
| 校验 | [schema.ts](file:///e:/Desktop/CICD/src/modules/diagnostic/schema.ts) | 31 | 4 个 Zod schema |
| 导出 | [export.ts](file:///e:/Desktop/CICD/src/modules/diagnostic/export.ts) | 122 | Excel 导出 |
| 组件 | [components/class-diagnostic-view.tsx](file:///e:/Desktop/CICD/src/modules/diagnostic/components/class-diagnostic-view.tsx) | 448 | 班级诊断视图(热力图+筛选+排名+关注列表+生成) |
| 组件 | [components/student-diagnostic-view.tsx](file:///e:/Desktop/CICD/src/modules/diagnostic/components/student-diagnostic-view.tsx) | 293 | 学生诊断视图(概览+雷达+强弱项+报告+历史) |
| 组件 | [components/report-list.tsx](file:///e:/Desktop/CICD/src/modules/diagnostic/components/report-list.tsx) | 445 | 报告列表(过滤+表格+发布/删除/导出/分享) |
| 组件 | [components/mastery-radar-chart.tsx](file:///e:/Desktop/CICD/src/modules/diagnostic/components/mastery-radar-chart.tsx) | 85 | 雷达图封装 |
| 组件 | [components/confidence-utils.ts](file:///e:/Desktop/CICD/src/modules/diagnostic/components/confidence-utils.ts) | 31 | 置信度计算 |
| 页面 | [teacher/diagnostic/page.tsx](file:///e:/Desktop/CICD/src/app/(dashboard)/teacher/diagnostic/page.tsx) | 67 | 教师报告列表页 |
| 页面 | [teacher/diagnostic/student/[studentId]/page.tsx](file:///e:/Desktop/CICD/src/app/(dashboard)/teacher/diagnostic/student/[studentId]/page.tsx) | 86 | 教师查看学生诊断 |
| 页面 | [teacher/diagnostic/class/[classId]/page.tsx](file:///e:/Desktop/CICD/src/app/(dashboard)/teacher/diagnostic/class/[classId]/page.tsx) | 50 | 教师班级诊断 |
| 页面 | [student/diagnostic/page.tsx](file:///e:/Desktop/CICD/src/app/(dashboard)/student/diagnostic/page.tsx) | 40 | 学生自我诊断 |
| 页面 | [parent/diagnostic/page.tsx](file:///e:/Desktop/CICD/src/app/(dashboard)/parent/diagnostic/page.tsx) | 128 | 家长多子女诊断 |
| 骨架屏 | 5 个 `loading.tsx` | — | 各路由骨架屏 |
| 错误边界 | 5 个 `error.tsx` | — | 各路由错误边界 |
| i18n | [diagnostic.json](file:///e:/Desktop/CICD/src/shared/i18n/messages/zh-CN/diagnostic.json) | 204 | 中文翻译 |
### 1.2 数据流
```
page.tsx (RSC)
├─ getStudentMasterySummary / getClassMasterySummary / getKnowledgePointStats (data-access)
│ └─ db (drizzle) → knowledgePointMastery / knowledgePoints 表
├─ getDiagnosticReports (data-access-reports, 含 DataScope 过滤)
│ └─ db → learningDiagnosticReports 表
└─ <StudentDiagnosticView> / <ClassDiagnosticView> / <ReportList> (client)
└─ generateStudentReportAction / generateClassReportAction / publishReportAction / deleteReportAction / exportDiagnosticReportAction / getClassStudentsByKnowledgePointAction
```
### 1.3 架构图记录完整性
经核对 [004_architecture_impact_map.md](file:///e:/Desktop/CICD/docs/architecture/004_architecture_impact_map.md) §2.22 与 [005_architecture_data.json](file:///e:/Desktop/CICD/docs/architecture/005_architecture_data.json),架构图对诊断模块的记录**基本完整**,但存在以下偏差:
- 行数统计略有滞后:图记 `data-access.ts 179 行`,实际为 477 行(含 `updateMasteryFromHomeworkSubmission``updateMasteryFromExamScore` 两个大函数)。
- 未记录 `export.ts` 的存在(架构图文件清单缺少此文件)。
- 未记录 `confidence-utils.ts` 组件文件。
- 未记录跨模块 UI 依赖:`teacher/diagnostic/student/[studentId]/page.tsx``teacher/diagnostic/class/[classId]/page.tsx` 直接 import `@/modules/grades/components/widget-boundary`,架构图未标注此跨模块 UI 依赖。
---
## 二、现存问题与原因分析
### 2.1 架构解耦
#### 问题 2.1.1 跨模块直接 import UI 组件 WidgetBoundaryP0
- **位置**
- [teacher/diagnostic/student/[studentId]/page.tsx#L13](file:///e:/Desktop/CICD/src/app/(dashboard)/teacher/diagnostic/student/[studentId]/page.tsx#L13)
- [teacher/diagnostic/class/[classId]/page.tsx#L8](file:///e:/Desktop/CICD/src/app/(dashboard)/teacher/diagnostic/class/[classId]/page.tsx#L8)
- **现象**`import { WidgetBoundary } from "@/modules/grades/components/widget-boundary"`
- **违反规则**:项目规则"模块间只能通过对方 data-access 通信,禁止跨模块直接查询数据库表"的精神延伸——UI 组件跨模块直接 import 同样破坏模块独立性。WidgetBoundary 是通用错误边界组件,不应属于 grades 业务模块。
- **原因**WidgetBoundary 最初为 grades 模块创建diagnostic 模块复用时直接 import 了 grades 模块的实现,而非将其提升到 shared 层。
- **后果**grades 模块对 WidgetBoundary 的任何变更重命名、删除、props 修改)都会破坏 diagnostic 模块编译diagnostic 模块无法独立测试、独立部署。
#### 问题 2.1.2 组件直接 import actions无服务接口抽象P1
- **位置**
- [components/report-list.tsx#L42](file:///e:/Desktop/CICD/src/modules/diagnostic/components/report-list.tsx#L42)`import { publishReportAction, deleteReportAction, exportDiagnosticReportAction } from "../actions"`
- [components/class-diagnostic-view.tsx#L33](file:///e:/Desktop/CICD/src/modules/diagnostic/components/class-diagnostic-view.tsx#L33)`import { generateClassReportAction, getClassStudentsByKnowledgePointAction } from "../actions"`
- **现象**:客户端组件直接 import 并调用 Server Actions未通过接口抽象或依赖注入。
- **违反规则**:项目规则"通过定义 TypeScript 接口抽象数据依赖,使用 React Context 注入数据服务,模块内部组件绝不直接 import 其他业务模块的 actions 或 data-access"。
- **原因**:模块未采用依赖注入模式,组件与 actions 紧耦合。
- **后果**:组件无法独立测试(测试时必须 mock 整个 actions 模块);无法在不修改组件代码的情况下替换 actions 实现。
### 2.2 国际化
#### 问题 2.2.1 教师页面标题硬编码英文P0
- **位置**
- [teacher/diagnostic/page.tsx#L59-62](file:///e:/Desktop/CICD/src/app/(dashboard)/teacher/diagnostic/page.tsx#L59)`<h1>Learning Diagnostic</h1>` + `<p>View and manage diagnostic reports based on knowledge point mastery.</p>`
- [teacher/diagnostic/student/[studentId]/page.tsx#L70-74](file:///e:/Desktop/CICD/src/app/(dashboard)/teacher/diagnostic/student/[studentId]/page.tsx#L70)`Student Diagnostic` + `Knowledge point mastery analysis and diagnostic reports.`
- [teacher/diagnostic/class/[classId]/page.tsx#L38-42](file:///e:/Desktop/CICD/src/app/(dashboard)/teacher/diagnostic/class/[classId]/page.tsx#L38)`Class Diagnostic` + `Class-level knowledge point mastery overview and student attention list.`
- **违反规则**:项目规则"所有用户可见文本必须适配 i18n使用 next-intl提取翻译键"。
- **原因**:教师端 3 个页面未使用 `getTranslations` 获取翻译,直接硬编码英文文案。学生端和家端已正确使用 i18n。
- **后果**:中文环境下教师看到英文标题,与系统其他页面风格不一致。
#### 问题 2.2.2 teacher/diagnostic/error.tsx 硬编码中文P0
- **位置**[teacher/diagnostic/error.tsx#L17-22](file:///e:/Desktop/CICD/src/app/(dashboard)/teacher/diagnostic/error.tsx#L17)
- **现象**`title="学情诊断页面加载失败"` `description="抱歉,页面加载时发生了意外错误。请稍后重试。"` `label="重试"` 全部硬编码。
- **违反规则**:项目规则"所有用户可见文本必须适配 i18n"。
- **原因**error.tsx 是客户端组件但未使用 `useTranslations`
- **后果**:英文环境下错误页显示中文,国际化不一致。对比 student/diagnostic/error.tsx 已正确使用 i18n。
#### 问题 2.2.3 parent/diagnostic/page.tsx 错误卡片中英文混用P1
- **位置**[parent/diagnostic/page.tsx#L116-119](file:///e:/Desktop/CICD/src/app/(dashboard)/parent/diagnostic/page.tsx#L116)
- **现象**`{t("error.loadFailed")} for {item.studentName}.``Please refresh the page or contact the school administrator if the problem persists.` 混用 i18n key 和硬编码英文。
- **违反规则**:项目规则"所有用户可见文本必须适配 i18n"。
- **后果**:中文环境下显示"加载失败 for 张三.",中英文混杂,用户体验差。
#### 问题 2.2.4 报告内容硬编码中文P1
- **位置**[stats-service.ts#L280-353](file:///e:/Desktop/CICD/src/modules/diagnostic/stats-service.ts#L280)
- **现象**`buildStudentReportContent``buildClassReportContent` 生成中文报告内容,如 `"建议复习「${m.knowledgePointName}」知识点"``"学生 ${summary.studentName} 在 ${period} 期间整体掌握度"` 等。
- **违反规则**:项目规则"所有用户可见文本必须适配 i18n"。
- **原因**:纯函数层生成报告内容时直接硬编码中文,未通过 i18n。
- **后果**:英文环境下生成的诊断报告内容为中文,无法国际化。报告内容存储在数据库中,已生成的历史报告无法回溯翻译。
#### 问题 2.2.5 Excel 导出表头硬编码中文P1
- **位置**[export.ts#L40-99](file:///e:/Desktop/CICD/src/modules/diagnostic/export.ts#L40)
- **现象**Excel 表头如 `"学生姓名"``"报告周期"``"综合得分"``"知识点掌握度"` 等硬编码中文;文件名 `诊断报告_${safePeriod}_${formatDateForFile()}.xlsx` 也硬编码。
- **违反规则**:项目规则"所有用户可见文本必须适配 i18n"。
- **后果**:英文环境下导出的 Excel 文件表头和文件名为中文。
### 2.3 类型安全
#### 问题 2.3.1 as 类型断言P1
- **位置**[teacher/diagnostic/page.tsx#L24, L28](file:///e:/Desktop/CICD/src/app/(dashboard)/teacher/diagnostic/page.tsx#L24)
- **现象**`(v as DiagnosticReportType)``(v as DiagnosticReportStatus)` 使用 as 断言。
- **违反规则**:项目规则"禁止 as 断言(除非从 unknown 转换或测试中,需注释原因)"。
- **原因**:虽有类型守卫 `VALID_REPORT_TYPES.has(v)` 校验,但转换时使用了 as 而非类型守卫函数返回值收窄。
- **后果**:绕过 TypeScript 严格类型检查,潜在类型不安全。
### 2.4 错误处理与边界
#### 问题 2.4.1 分享链接指向不存在的路由P1
- **位置**[components/report-list.tsx#L157, L208](file:///e:/Desktop/CICD/src/modules/diagnostic/components/report-list.tsx#L157)
- **现象**`const url = \`${window.location.origin}/teacher/diagnostic/reports/${shareId}\`` 指向 `/teacher/diagnostic/reports/[id]` 路由,但该路由在项目中不存在(无对应 page.tsx
- **原因**:分享功能开发时未创建对应路由页面。
- **后果**:用户点击分享链接后得到 404 页面,功能不可用。
#### 问题 2.4.2 班级报告导出缺少明细P2
- **位置**[export.ts#L85-113](file:///e:/Desktop/CICD/src/modules/diagnostic/export.ts#L85)
- **现象**:班级报告仅导出概览 Sheet缺少知识点统计和需关注学生明细。代码注释明确说明"班级报告的 studentId 为 null需要从 period 反查 classId 不现实"。
- **原因**v4-P1 已为 `learningDiagnosticReports` 表新增 `classId` 字段,但 export.ts 未同步更新使用该字段查询班级明细。
- **后果**:教师导出班级报告时只能看到概览,无法获取知识点统计和需关注学生列表,导出功能不完整。
### 2.5 可复用性与配置驱动
#### 问题 2.5.1 角色差异通过 props 硬编码而非配置驱动P2
- **位置**[components/student-diagnostic-view.tsx#L32](file:///e:/Desktop/CICD/src/modules/diagnostic/components/student-diagnostic-view.tsx#L32)
- **现象**`practiceHrefBase` prop 区分角色(学生默认 `/student/learning/assignments`,教师传 `/teacher/questions`,家长传 `null`)。
- **违反规则**:项目规则"采用配置驱动设计,例如通过角色配置决定该模块渲染哪些 Widget/子模块"。
- **原因**:角色差异通过 props 传递,而非通过角色配置对象统一管理。
- **后果**:新增角色需修改组件 props 传递逻辑,而非仅修改配置。
#### 问题 2.5.2 无年级诊断报告生成入口P2
- **位置**[types.ts#L3](file:///e:/Desktop/CICD/src/modules/diagnostic/types.ts#L3)
- **现象**`DiagnosticReportType` 定义了 `"grade"` 类型,但 [actions.ts](file:///e:/Desktop/CICD/src/modules/diagnostic/actions.ts) 无 `generateGradeReportAction`[data-access-reports.ts](file:///e:/Desktop/CICD/src/modules/diagnostic/data-access-reports.ts) 无 `generateGradeDiagnosticReport` 函数。
- **原因**:年级报告功能定义了类型但未实现。
- **后果**管理员无法生成年级级别的诊断报告功能不完整。report-list 过滤器中可选"年级"类型但永远无数据。
### 2.6 可访问性
#### 问题 2.6.1 热力图色块缺少键盘导航P2
- **位置**[components/class-diagnostic-view.tsx#L190-201](file:///e:/Desktop/CICD/src/modules/diagnostic/components/class-diagnostic-view.tsx#L190)
- **现象**:热力图色块为 `<div>` 且仅有 `role="img"`,无 `tabIndex` 和键盘焦点样式,键盘用户无法逐个聚焦查看详情。
- **违反规则**:项目规则"可访问性a11y语义化标签、ARIA 属性、键盘导航"。
- **后果**:键盘用户无法通过 Tab 遍历热力图色块查看 tooltip/title 详情。
---
## 三、行业差距对比
对标 PowerSchool、Infinite Campus、Skyward、Alma、智学网、班级小管家等 K12 系统,本模块在以下方面存在差距:
| 维度 | 优秀实践 | 本模块现状 | 影响 |
|------|---------|-----------|------|
| **诊断趋势分析** | PowerSchool/智学网支持掌握度时间线,展示知识点掌握度随时间的变化趋势 | 仅展示当前快照,无历史趋势对比 | 教师无法判断学生是否在进步或退步 |
| **年级诊断报告** | Infinite Campus 支持年级级别诊断,对比班级间差异 | 类型已定义但无实现入口 | 管理员无法做年级层面决策 |
| **报告详情页** | 所有同类系统都有独立的报告详情页,支持分享链接 | 分享链接指向不存在的路由 | 分享功能不可用 |
| **班级报告导出明细** | PowerSchool/Infinite Campus 导出含知识点统计+学生列表 | 班级报告仅导出概览 | 教师无法离线分析 |
| **掌握度时间线** | 智学网展示每个知识点的掌握度变化曲线 | 无时间维度数据 | 无法评估教学干预效果 |
| **个性化学习路径** | Alma/智学网基于弱项推荐学习路径和资源 | 仅提供练习按钮跳转题目库 | 推荐不够精准 |
| **诊断报告模板** | PowerSchool 支持自定义报告模板 | 报告内容固定硬编码 | 无法按学校需求定制 |
| **多维度诊断** | Infinite Campus 结合成绩+出勤+行为做多维诊断 | 仅基于知识点掌握度 | 诊断维度单一 |
---
## 四、改进优先级建议
### P0紧急影响功能正确性或核心规范
| 编号 | 问题 | 改进方向 |
|------|------|---------|
| P0-1 | 跨模块 import WidgetBoundary | 将 WidgetBoundary 提升到 `shared/components/`diagnostic 和 grades 模块统一从 shared 引用 |
| P0-2 | 教师页面标题硬编码英文 | 3 个教师页面使用 `getTranslations("diagnostic")` 获取标题和描述 |
| P0-3 | teacher/diagnostic/error.tsx 硬编码中文 | 接入 `useTranslations("diagnostic")`,与其他 error.tsx 一致 |
### P1重要影响用户体验或类型安全
| 编号 | 问题 | 改进方向 |
|------|------|---------|
| P1-1 | parent 错误卡片中英文混用 | 提取完整 i18n 键,消除硬编码英文 |
| P1-2 | as 类型断言 | 改用类型守卫函数返回值收窄,消除 as |
| P1-3 | 分享链接指向不存在路由 | 移除分享功能或创建对应路由页面。鉴于当前无报告详情页需求,移除分享按钮避免 404 |
| P1-4 | 报告内容硬编码中文 | stats-service 的报告内容生成改为接收 i18n 翻译函数参数,或在 actions 层调用时注入翻译后的模板 |
| P1-5 | Excel 导出表头硬编码 | export.ts 接收 i18n 翻译参数,表头和文件名使用翻译键 |
### P2增强提升完整性
| 编号 | 问题 | 改进方向 |
|------|------|---------|
| P2-1 | 班级报告导出缺少明细 | 利用 v4-P1 新增的 classId 字段查询班级掌握度,导出知识点统计+需关注学生 Sheet |
| P2-2 | 角色差异通过 props 硬编码 | 定义角色配置对象,通过配置驱动 practiceHrefBase 等角色差异 |
| P2-3 | 无年级诊断报告入口 | 实现 generateGradeDiagnosticReport + 对应 Action中长期 |
| P2-4 | 热力图色块缺少键盘导航 | 添加 tabIndex={0} 和 focus-visible 样式 |
| P2-5 | 架构图行数统计滞后 | 同步 data-access.ts 实际行数,补充 export.ts 和 confidence-utils.ts 记录 |
---
## 五、架构图同步说明
本次审计发现架构图需同步以下内容:
### 004_architecture_impact_map.md §2.22
1. **文件清单更新**
- `data-access.ts` 行数从 179 更新为 477`updateMasteryFromHomeworkSubmission``updateMasteryFromExamScore`
- 补充 `export.ts`122 行Excel 导出)
- 补充 `components/confidence-utils.ts`31 行,置信度计算)
2. **已知问题新增**
- 记录 P0-1 跨模块 import WidgetBoundary 问题及修复
- 记录 P0-2/P0-3 i18n 遗漏问题及修复
- 记录 P1-3 分享链接 404 问题及修复
3. **依赖关系更新**:标注 WidgetBoundary 已从 grades 模块提升到 shared 层
### 005_architecture_data.json
1. `modules.diagnostic.exports` 补充 `export.ts``confidence-utils.ts` 文件记录
2. `modules.diagnostic.dependencies` 更新:移除对 `grades/components/widget-boundary` 的 UI 依赖,改为 `shared/components/widget-boundary`
3. `modules.diagnostic.fileList` 行数同步更新
---
## 六、实施状态2026-06-24 全部完成)
> 本章节记录审计报告中所有 P0/P1/P2 项的实施完成情况。所有项均已通过 `npx tsc --noEmit` 与 `npm run lint` 校验(诊断模块零错误)。
### 6.1 P0 项实施状态
| 编号 | 状态 | 实施内容 | 涉及文件 |
|------|------|---------|---------|
| P0-1 | ✅ 已完成 | WidgetBoundary 已从 `modules/grades/components/widget-boundary.tsx` 提升到 `shared/components/widget-boundary.tsx`diagnostic 与 grades 模块统一从 `@/shared/components/widget-boundary` 引用grades 模块原文件已删除 | `src/shared/components/widget-boundary.tsx`(新建)、`src/modules/grades/components/widget-boundary.tsx`(删除)、`src/app/(dashboard)/teacher/diagnostic/student/[studentId]/page.tsx``src/app/(dashboard)/teacher/diagnostic/class/[classId]/page.tsx` |
| P0-2 | ✅ 已完成 | 3 个教师页面(`teacher/diagnostic/page.tsx``teacher/diagnostic/student/[studentId]/page.tsx``teacher/diagnostic/class/[classId]/page.tsx`)均使用 `getTranslations("diagnostic")` 获取标题与描述,新增对应 i18n 键 `teacherTitle``teacherDescription``studentTitle``studentDescription``classTitle``classDescription` | 上述 3 个页面 + `src/shared/i18n/messages/zh-CN/diagnostic.json` + `src/shared/i18n/messages/en/diagnostic.json` |
| P0-3 | ✅ 已完成 | `teacher/diagnostic/error.tsx` 接入 `useTranslations("diagnostic")`,与 `student/diagnostic/error.tsx` 风格一致;新增 i18n 键 `errorTitle``errorDescription``errorRetry` | `src/app/(dashboard)/teacher/diagnostic/error.tsx` + 两个 i18n 文件 |
### 6.2 P1 项实施状态
| 编号 | 状态 | 实施内容 | 涉及文件 |
|------|------|---------|---------|
| P1-1 | ✅ 已完成 | `parent/diagnostic/page.tsx` 错误卡片中英文混用已消除;新增 i18n 键 `errorForStudent``errorContactAdmin`,使用 `t("errorForStudent", { name: item.studentName })` 替代硬编码 | `src/app/(dashboard)/parent/diagnostic/page.tsx` + 两个 i18n 文件 |
| P1-2 | ✅ 已完成 | `teacher/diagnostic/page.tsx``(v as DiagnosticReportType)``(v as DiagnosticReportStatus)` 已替换为类型守卫函数返回值收窄:`VALID_REPORT_TYPES.has(v) ? v : DEFAULT_REPORT_TYPE` 模式,消除 `as` 断言 | `src/app/(dashboard)/teacher/diagnostic/page.tsx` |
| P1-3 | ✅ 已完成 | `components/report-list.tsx` 中分享按钮与相关逻辑已移除(包括 `shareReportAction` 调用、`window.location.origin` URL 构造、分享对话框),避免 404保留发布/删除/导出三个核心操作 | `src/modules/diagnostic/components/report-list.tsx` |
| P1-4 | ✅ 已完成 | `stats-service.ts``buildStudentReportContent``buildClassReportContent` 已重构为接收 `ReportContentTranslations` 接口参数;新增 `getReportContentTranslations()` 在 data-access-reports 层调用 `getTranslations` 注入翻译;报告内容生成改为 i18n 驱动 | `src/modules/diagnostic/stats-service.ts``src/modules/diagnostic/data-access-reports.ts`、两个 i18n 文件 |
| P1-5 | ✅ 已完成 | `export.ts` 中 Excel 表头和文件名已改为接收 i18n 翻译参数;`exportDiagnosticReportAction` 在调用 `exportDiagnosticReportToExcel` 前通过 `getTranslations("diagnostic")` 注入翻译;新增 i18n 键 `sheetOverview``sheetClassStats``sheetAttentionStudents``colStudentName``colPeriod``colReportType``colStatus``colScore``colGeneratedAt``colSummary``colStrengths``colWeaknesses``colRecommendations``filenameDiagnosticReport` 等 | `src/modules/diagnostic/export.ts``src/modules/diagnostic/actions.ts`、两个 i18n 文件 |
### 6.3 P2 项实施状态
| 编号 | 状态 | 实施内容 | 涉及文件 |
|------|------|---------|---------|
| P2-1 | ✅ 已完成 | 班级报告导出已利用 v4-P1 新增的 `classId` 字段调用 `getClassMasterySummary`,导出包含三个 Sheet概览、知识点统计、需关注学生明细新增 i18n 键 `sheetClassStats``sheetAttentionStudents``metricClass``metricStudentCount``metricAttentionCount``colMasteredCount``colNotMasteredCount``colTotalStudents``colAverageMastery``colWeakCount``noAttentionStudents` | `src/modules/diagnostic/export.ts` + 两个 i18n 文件 |
| P2-2 | ✅ 已完成 | 新建 `src/modules/diagnostic/role-config.ts`,定义 `DiagnosticRole` 类型、`DiagnosticRoleConfig` 接口、`DIAGNOSTIC_ROLE_CONFIG` 记录student/teacher/parent 三角色配置)和 `getDiagnosticRoleConfig` 辅助函数;`StudentDiagnosticView` 组件新增 `role` prop内部通过 `getDiagnosticRoleConfig(role).practiceHrefBase` 解析配置;原 `practiceHrefBase` prop 标记 `@deprecated` 保留向后兼容(同时传入时 `role` 优先3 个调用点已迁移为 `role="student"` / `role="teacher"` / `role="parent"` | `src/modules/diagnostic/role-config.ts`(新建)、`src/modules/diagnostic/components/student-diagnostic-view.tsx``src/app/(dashboard)/student/diagnostic/page.tsx``src/app/(dashboard)/teacher/diagnostic/student/[studentId]/page.tsx``src/app/(dashboard)/parent/diagnostic/page.tsx` |
| P2-3 | ✅ 已完成 | 完整实现年级诊断报告纵向切片:① DB schema 新增 `gradeId` 字段 + `gradeIdx` 索引 + 迁移 SQL `0012_diagnostic_grade_id.sql`;② 类型新增 `GradeMasterySummary` 接口,`DiagnosticReport` 接口新增 `gradeId: string \| null`;③ data-access 新增 `getGradeMasterySummary`(缓存,并行查询年级名+学生 ID+掌握度行);④ stats-service 新增 `buildGradeMasterySummary``buildGradeReportContent` 纯函数;⑤ data-access-reports 新增 `generateGradeDiagnosticReport`,含 `GRADE_NOT_FOUND` / `GRADE_NO_MASTERY_DATA` 错误码;⑥ schema 新增 `GenerateGradeReportSchema`;⑦ actions 新增 `generateGradeReportAction` Server Action`requirePermission` + `revalidatePath`);⑧ i18n 新增 `gradeSummary``gradeRecommendation``gradeNoWeakness` 键 | `src/shared/db/schema.ts``drizzle/0012_diagnostic_grade_id.sql`(新建)、`src/modules/diagnostic/types.ts``src/modules/diagnostic/data-access.ts``src/modules/diagnostic/stats-service.ts``src/modules/diagnostic/data-access-reports.ts``src/modules/diagnostic/schema.ts``src/modules/diagnostic/actions.ts`、两个 i18n 文件 |
| P2-4 | ✅ 已完成 | 班级诊断视图热力图色块新增 `tabIndex={0}``focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2` 样式;外层容器 `role``"img"` 改为 `"group"`(因容器内现含可聚焦元素);保留每个色块的 `aria-label` 提供完整描述 | `src/modules/diagnostic/components/class-diagnostic-view.tsx` |
| P2-5 | ✅ 已完成 | 架构图 004 和 005 已同步:① `data-access.ts` 行数更新为实际值;② 补充 `export.ts``role-config.ts``confidence-utils.ts` 文件记录;③ 已知问题章节新增 11 条 P0-1 至 P2-4 修复记录;④ 依赖矩阵新增 `school` 模块依赖(`getGradeNameById``getUserIdsByGradeId`)和 `shared/components/widget-boundary`;⑤ `learningDiagnosticReports` 表描述补充 `gradeId` 字段;⑥ `modules.diagnostic.exports` 新增 `getGradeMasterySummary``generateGradeDiagnosticReport``buildGradeMasterySummary``buildGradeReportContent``generateGradeReportAction``GenerateGradeReportSchema` 等 | `docs/architecture/004_architecture_impact_map.md``docs/architecture/005_architecture_data.json` |
### 6.4 验证结果
- **TypeScript**`npx tsc --noEmit` 通过,诊断模块零错误(仅 `dashboard/services/dashboard-service.ts` 存在与本模块无关的预存语法错误)。
- **ESLint**`npm run lint` 通过,诊断模块零警告。
- **架构图一致性**004 与 005 两份架构文档已与源码同步,所有新增/修改的导出函数、类型、依赖关系、DB 表字段均已记录。
### 6.5 后续建议(未列入本次实施范围)
以下为审计过程中识别但未列入本次实施的长期增强项,建议后续按需推进:
1. **掌握度时间线**:新增 `knowledgePointMasteryHistory` 表记录每次掌握度变化,前端展示时间线图表。
2. **个性化学习路径推荐**:基于弱项知识点推荐具体学习资源(题目、视频、文档),而非仅跳转题目库。
3. **多维度诊断**:结合成绩、出勤、行为数据做多维综合诊断。
4. **报告模板自定义**:允许学校配置报告内容模板(如自定义推荐话术、评分区间)。
5. **报告详情页**:若未来需要分享功能,创建 `/teacher/diagnostic/reports/[id]` 路由页面。
6. **可测试性增强**:为 `stats-service.ts` 中 12 个纯函数补充单元测试,导出 `ReportContentTranslations` 接口便于 mock。
7. **依赖注入抽象**:将 `report-list.tsx``class-diagnostic-view.tsx` 中直接 import actions 的模式重构为通过 React Context 注入数据服务接口,提升可测试性。