# 学情诊断（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 组件 WidgetBoundary（P0）

- **位置**：
  - [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 注入数据服务接口，提升可测试性。
