Files
Edu/apps/portal-shell/docs/needtodo/teacher-NeedTodo.md
SpecialX 062d9e9582 feat(portal-shell): 管理域 §9.4 B5 全量迁移(24 + 21 补充批次共 44 页 + 42 features)
按 ARCHITECTURE.md §9.4 规划口径 + admin-NeedTodo.md §四补充批次完成管理域全量页面迁移:

【§9.4 规划 24 页(B5)】
- users(2) + roles(1) + permissions(1) + audit-logs(4) + invitation-codes(1)
- school(6: redirect/schools/classes/departments/academic-year/grades)
- announcements(1) + files(1) + ai-settings(1) + system(1) + viewports(1)
- students(1) + teachers(1) + organization(1) + plugins(1, config-service)
- 仪表盘已存在(/shell/admin/page.tsx)

【§四补充批次 21 页】
- course-plans(4) + elective(4) + questions(1) + lesson-plans(2) + error-book(1)
- scheduling(3: auto/changes/rules) + attendance(1) + curriculum-map(1)
- announcements 详情/编辑(2) + roles/[id] 详情(1) + users/import(1)

【实现要点】
- 全部使用 ListPageShell + loading/error/empty 三态规范(§11.3 DoD)
- 走 lib/api hooks;未就绪契约走 MSW + @contract-pending 注释(§11.4)
- 文案走 useTranslations(zh-CN + en 两份同步更新)
- 42 个 features/<domain>/transformations.ts 纯函数 + 配套 vitest 单测
- catch 块统一 notify.error;无空 catch;lint:tokens 通过
- 路由全部登记到 route-permissions.ts(39 EXACT + 8 PREFIX)

【验收】
- tsc --noEmit: 0 errors
- ESLint src: 0 errors (4 generated-files warnings, pre-existing)
- lint:tokens: 0 errors
- vitest: 1639/1639 passed (含 23 admin 测试文件 671 用例)
- check:routes: PASS (143 routes, 4 ghost entries pre-existing)
- check:pages: PASS (146 pages)
- check:codegen: PASS
- arch:scan: 24 modules, 8262 symbols

关联:ARCHITECTURE.md §9.4 / §10 P5 / §11.3 DoD / §11.6
2026-07-24 23:07:20 +08:00

580 lines
55 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.
# 教师域Teacher待完成功能分析
> 参考项目:`e:\desktop\CICD\src\app\(dashboard)\teacher\`53 个 page.tsx
> 当前项目:`e:\Desktop\Edu\apps\portal-shell\src\app\shell\teacher\`53 个 page.tsx
> 规划依据:`apps\portal-shell\ARCHITECTURE.md` §9.1(教师域 56 页B1+B2
> 分析日期2026-07-24
> 分析方式:逐页面对比 CICD 实现 vs portal-shell 实现,逐个读取 page.tsx + features/*-client.tsx
---
## 〇、方法论与对比基线
1. CICD 单体Next.js App Router + Server Actions + Drizzle作为**功能基线**,反映"老版单体已实现"的教师功能完整态。
2. portal-shell 作为**目标态**,遵循 ARCH §9.1 的契约与批次规划B1+B2+B2末
3. portal-shell 普遍采用「Server Component page.tsx 仅做 `<Suspense>` 边界包裹 + Client Component `*-client.tsx` 承载业务」的统一架构CICD 多为「Server Component 直接拉数据 + Rich Client Component 渲染」。
4. ARCH §9.1 规划 56 页portal-shell 已实现 53 页,**3 页缺口** = `exams/[id]/proctoring`B2末+ `notifications`B1 共享)+ `settings`B1 共享)。
5. CICD 中 `exams/page.tsx``classes/page.tsx``exams/grading/*``exams/create` 等为**重定向/等价路径**,不算独立功能缺口。
6. CICD 中 `diagnostic/student/[studentId]` 在 ARCH §9.1 中**未规划**ARCH 仅规划 `diagnostic` + `diagnostic/class/[classId]` 共 2 页),属 CICD 历史功能portal-shell 缺失但**不违反 ARCH**。
---
## 一、页面完成度总览
| 状态 | 数量 | 说明 |
| --------------------- | ---- | ---------------------------------------------------------------------------------------------------- |
| ✅ 已完成且功能完整 | 33 | 功能与 CICD 持平或为 ARCH 新建且实现完整(含 MSW 兜底契约页) |
| 🟡 已完成但功能不完整 | 14 | 页面存在但子功能/技术栈与 CICD 有差距 |
| ❌ 完全缺失 | 4 | `exams/[id]/proctoring``diagnostic/student/[studentId]``/shell/notifications``/shell/settings` |
### ✅ 已完成且功能完整33 页)
| 模块 | 页面 | 备注 |
| ---------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| dashboard | `/shell/teacher`teacher/page.tsx | 仪表盘4 StatCard + 班级概况 + 预警(注:标题用硬编码中文,违反 i18n但功能完整 |
| exams | `/shell/teacher/exams/[id]/analytics` | 汇总卡片 + 分数段分布图 + 每题正确率 + 学生排名,混合契约 ✅ `assignmentAnalysis` |
| homework | `/shell/teacher/homework/submissions/[submissionId]` | 单份提交批改,含题目分数/教师评语/AI 建议应用/上下导航/总反馈 |
| homework | `/shell/teacher/homework/submissions/[submissionId]/scan-grading` | 扫描批改 |
| homework | `/shell/teacher/homework/submissions` | 提交列表 |
| homework | `/shell/teacher/homework/assignments/[id]/submissions` | 作业子提交列表 |
| homework | `/shell/teacher/homework` | 作业列表 |
| grades | `/shell/teacher/grades` | 成绩列表 |
| grades | `/shell/teacher/grades/analytics` | 成绩分析,汇总 + 分布 + 排名,混合契约 |
| grades | `/shell/teacher/grades/stats` | 成绩统计 |
| grades | `/shell/teacher/grades/report-card` | 报告卡 |
| attendance | `/shell/teacher/attendance` | 考勤列表 |
| attendance | `/shell/teacher/attendance/report` | 考勤报告 |
| attendance | `/shell/teacher/attendance/stats` | 考勤统计 |
| classes | `/shell/teacher/classes` | 班级列表(含 gradeId/subjectId/q 筛选) |
| classes | `/shell/teacher/classes/schedule` | 班级课表 |
| students | (见 🟡 学生列表,因缺科目成绩) | — |
| course-plans | `/shell/teacher/course-plans``/[id]` | 2 页 |
| elective | `/shell/teacher/elective``/create``/[id]/edit` | 3 页 |
| error-book | `/shell/teacher/error-book` | ✅ `errorBookItems/Stats` 真实契约 |
| diagnostic | `/shell/teacher/diagnostic` | 诊断列表 |
| analytics | `/shell/teacher/analytics``/[studentId]` | ARCH 新建 2 页MSW 兜底 |
| ai | `/shell/teacher/ai/ai-assist``/ai-lesson-plan``/ai-report` | ARCH 新建 B2末 3 页,全 MSW 兜底,工作台布局完整 |
| knowledge-graph | `/shell/teacher/knowledge-graph` | ARCH 新建 B2末三栏工作台`knowledgePoint(id)` ✅ 真实 + 列表 MSW |
| questions | `/shell/teacher/questions` | 题库列表,🟡 `question(id)` |
| textbooks | `/shell/teacher/textbooks``/[id]` | 2 页,🟡 `textbook(id)` |
| lesson-plans | `/shell/teacher/lesson-plans``/new``/calendar``/heatmap``/library` | 5 页edit 见 🟡) |
| practice | `/shell/teacher/practice` | 练习 |
| leave | `/shell/teacher/leave` | 请假 |
| schedule-changes | `/shell/teacher/schedule-changes` | 调课 |
### 🟡 已完成但功能不完整14 页)
详见 §三。
### ❌ 完全缺失4 页)
详见 §二。
---
## 二、缺失页面清单
### 2.1 `/shell/teacher/exams/[id]/proctoring`(监考工作台)
- **CICD 参考实现**`e:\desktop\CICD\src\app\(dashboard)\teacher\exams\[id]\proctoring\page.tsx`
- **功能描述**:实时监考面板,包含 `ProctoringDashboard` 组件,并行拉取:
- `getExamForProctoring(id)` — 考试基础信息
- `getExamProctoringSummary(id)` — 监考汇总(应到/实到/异常数)
- `getStudentProctoringStatuses(id)` — 学生实时状态列表
- `getRecentProctoringEvents(id, 20)` — 最近 20 条监考事件
- **技术栈**Server Component + `requirePermission(Permissions.EXAM_PROCTOR)` + `ProctoringDashboard` 客户端组件(实时 WS 推送)
- **ARCHITECTURE.md 契约**schema 无,需 WS 契约工单 + MSW 先行)
- **批次**B2 末二期WS
- **建议**:✅ 必须补做。需先定 WS 协议契约push-gateway再写 MSW mock最后实现 `ProctoringDashboard` 客户端组件。这是 B2末 明确规划页。
### 2.2 `/shell/teacher/diagnostic/student/[studentId]`(学生诊断详情)
- **CICD 参考实现**`e:\desktop\CICD\src\app\(dashboard)\teacher\diagnostic\student\[studentId]\page.tsx`
- **功能描述**:单个学生的学情诊断页,包含:
- `StudentDiagnosticView` 组件,渲染 `MasteryRadarPoint` 雷达图(学生 vs 班级平均对比)
- `getStudentMasterySummary(studentId)` — 学生掌握度汇总
- `getDiagnosticReports({ studentId }, ctx.dataScope)` — 诊断报告列表(教师可看草稿)
- `getKnowledgePointStats(studentClassId)` — 班级平均掌握度(雷达图对比)
- DataScope 二次校验:`class_taught` scope 验师生关系,`class_members`/`children` scope 限制访问
- **技术栈**Server Component + `requirePermission(Permissions.DIAGNOSTIC_READ)` + `WidgetBoundary` + `StudentDiagnosticView` 客户端组件
- **ARCHITECTURE.md 契约**:🟡(`diagnosticReports` ✅,但单生维度查询未明确)— **注意ARCH §9.1 仅规划 2 页(`/diagnostic` + `/diagnostic/class/[classId]`),未含学生维度**
- **批次**B2CICD 历史功能ARCH 未规划)
- **建议**:⚠️ 建议补做。虽 ARCH §9.1 未明确规划,但 CICD 已有完整实现且属于教师核心诊断场景(查看单个学生的掌握度雷达图 + 班级对比)。补做时需同步更新 ARCH §9.1 + 004。
### 2.3 `/shell/notifications`通知中心B1 共享)
- **CICD 参考实现**`e:\desktop\CICD\src\app\(dashboard)\teacher\notifications\page.tsx`(教师角色入口)
- **功能描述**:通知中心,按 `userId` 拉取通知列表
- **技术栈**Server Component + `notifications(userId)` 查询
- **ARCHITECTURE.md 契约**:✅ `notifications(userId)` schema 已就绪
- **批次**B1共享所有角色共用
- **建议**:✅ 必须补做。B1 共享页schema 已就绪,缺页面入口。需在 `/shell/notifications/page.tsx` 实现,供教师/学生/家长/管理员共用。
### 2.4 `/shell/settings`设置B1 共享)
- **CICD 参考实现**`e:\desktop\CICD\src\app\(dashboard)\teacher\settings\page.tsx`
- **功能描述**:用户设置页(个人资料、偏好、安全等)
- **技术栈**Server Component
- **ARCHITECTURE.md 契约**:✅
- **批次**B1共享
- **建议**:✅ 必须补做。B1 共享页,需在 `/shell/settings/page.tsx` 实现。
### 2.5 不算缺失的"伪缺失"(路径合并/重定向)
以下 CICD 路径在 portal-shell 中通过路径合并或等价入口覆盖,**不算缺失**
| CICD 路径 | portal-shell 等价 | 说明 |
| --------------------------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `exams/page.tsx` | `/exams/page.tsx`(直接列表) | CICD 是 redirect 到 `/exams/all`portal-shell 直接渲染列表 |
| `exams/all/page.tsx` | `/exams/page.tsx`ExamsListClient | 同上,功能等价(但筛选/计数/分页有差距,见 §3.1 |
| `exams/create/page.tsx` | `/exams/new/page.tsx`NewExamClient | CICD 有 `/create`ExamForm 简单表单)+ `/new`ExamRichForm 富文本portal-shell 合并为 `/new`(简单表单),富文本编辑只在 `/[id]/edit`(见 §3.4 |
| `exams/grading/page.tsx` | 无CICD 自身是 redirect | CICD `grading/page.tsx``redirect("/teacher/homework/submissions")`,无实际功能 |
| `exams/grading/[submissionId]/page.tsx` | 无CICD 自身是 redirect | 同上,仅 redirect |
| `classes/page.tsx` | `/classes/page.tsx`ClassesListClient | CICD 是 redirect 到 `/classes/my`portal-shell 直接渲染列表 |
| `classes/my/page.tsx` | `/classes/page.tsx`ClassesListClient | 路径合并MyClassesGrid 改为 ClassesTable视觉差异功能等价 |
| `classes/my/[id]/page.tsx` | `/classes/[id]/page.tsx`ClassDetailClient | 路径合并,但功能差距大(见 §3.5 |
| `classes/students/page.tsx` | `/students/page.tsx`StudentsListClient | 路径从 `/classes/students` 迁到顶级 `/students`ARCH §9.1 规划),功能差距见 §3.6 |
---
## 三、功能不完整的页面
### 3.1 exams - 考试列表页 `/shell/teacher/exams`
- **路径**`/shell/teacher/exams`
- **portal-shell 实现**`exams/page.tsx` + `features/teacher/exams/exams-list-client.tsx`
- **CICD 实现**`exams/all/page.tsx` + `exam-filters.tsx` + `ExamDataTable` + `ExamFilters`
- **已有功能**
- 关键词搜索q、状态筛选status、客户端二次筛选
- 简单表格展示title/status/examDate/duration/totalScore/actions
- 状态徽章、新建按钮、EmptyState、ListPageShell 骨架
- ✅ 真实查询 `useExams(classId)`classId 默认 `cls-001`MSW 兜底)
- **缺失功能**
-**难度筛选**difficulty filter— CICD 有 difficulty 维度筛选
-**状态计数徽章**draft/published/archived 三个 Badge + 数字)— CICD 顶部统计栏
-**真正的分页控件** — portal-shell 仅显示 `total: N`无分页器CICD `ExamDataTable` 内置分页
-**高级 DataTable 组件** — CICD 用 `ExamDataTable`(含排序/列控制/分页portal-shell 是手写 `<table>`
-**EmptyState "清除筛选" action** — CICD 在有筛选时显示"清除筛选"按钮回到 `/exams/all`portal-shell 无
-**服务端筛选** — CICD 在 Server Component 内调 `getExams({ q, status, difficulty, scope })`portal-shell 是客户端二次过滤
-**DataScope 过滤** — CICD 用 `ctx.dataScope` 做权限过滤portal-shell 无
- **技术差距**
- CICDServer Component + Drizzle `getExams` + `ExamDataTable` + `ExamFilters` 组件
- portal-shell 需补:分页器组件、状态计数 Badge 行、difficulty 筛选 select、EmptyState clearFilters action、后续契约就绪后改服务端筛选
### 3.2 exams - 考试详情页 `/shell/teacher/exams/[id]`
- **路径**`/shell/teacher/exams/[id]`
- **portal-shell 实现**`exams/[id]/page.tsx` + `features/teacher/exams/exam-detail-client.tsx`
- **CICD 实现****CICD 无此页面**CICD `/exams/[id]/` 目录下只有 analytics/build/edit-rich/proctoring 子路由,无 `page.tsx`
- **已有功能**
- ✅ 真实查询 `useExam(examId)`schema 已就绪)
- 基本信息区title/description/examDate/duration/totalScore/classId/subjectId
- 状态信息区currentStatus/statusChangedAt/statusChangedBy/createdBy/createdAt/updatedAt
- 编辑按钮status 可编辑时显示,但 onClick 无路由跳转,**按钮无实际行为**
- **缺失功能**
- ⚠️ **编辑按钮未接路由**`<Button variant="outline">{t("detail.edit")}</Button>``asChild` / `href` / `onClick`,点击无反应,应跳 `/shell/teacher/exams/[id]/edit`
- 💡 **无提交列表预览** — CICD 在 homework 详情有提交列表exam 详情可考虑加 submissions 摘要CICD 无此页,属增量)
- 💡 **无分析入口卡片** — 可加"查看分析"快捷入口跳 `/analytics`
- **技术差距**
- 编辑按钮需补 `asChild` + `<Link href=".../edit">`
- ARCH §9.1 规划此页为 M 详情页portal-shell 已满足基本契约,但交互不完整
### 3.3 exams - 新建考试表单 `/shell/teacher/exams/new`
- **路径**`/shell/teacher/exams/new`
- **portal-shell 实现**`exams/new/page.tsx` + `features/teacher/exams/new-exam-client.tsx`
- **CICD 实现**`exams/new/page.tsx`ExamRichForm 富文本)+ `exams/create/page.tsx`ExamForm 简单)
- **已有功能**
- 简单表单classId/subjectId/title/description/examDate/duration/totalScore
- 内联校验classId/title/examDate 必填)
- ✅ mutation `useCreateExam` MSW 兜底
- 成功后 `router.push` 回列表
- **缺失功能**
-**富文本编辑器** — CICD `/exams/new``ExamRichForm`(含 Tiptap 富文本 + 题目结构portal-shell 是纯字段表单
-**班级/科目下拉选择器** — portal-shell 用 `<input type="text">`CICD 应为 selectCICD ExamRichForm 内部)
- 💡 **题目结构编辑** — CICD 富文本编辑器支持插入题目占位、分值、排序
- **技术差距**
- CICD`ExamRichForm` 客户端组件Tiptap + 结构化节点)
- portal-shell 把 CICD 的 `/exams/new`rich+ `/exams/create`basic合并为 `/exams/new`basic富文本能力下沉到 `/[id]/edit`
- **是否补做**:取决于产品决策。若新建时即需富文本,需补 Tiptap若新建只创建元数据、富文本在编辑页做则当前实现可接受
### 3.4 exams - 富文本试卷编辑 `/shell/teacher/exams/[id]/edit`
- **路径**`/shell/teacher/exams/[id]/edit`(对应 CICD `/exams/[id]/edit-rich`
- **portal-shell 实现**`exams/[id]/edit/page.tsx` + `features/teacher/exams/exam-edit-client.tsx`
- **CICD 实现**`exams/[id]/edit-rich/page.tsx` + `ExamRichForm` + `examNodesToEditorDoc` + `structureToEditorDoc`
- **已有功能**
- 三栏工作台:中栏富文本编辑器 + 右栏属性面板examId/totalScore/questionCount/updatedAt
- 工具栏B/I/U/H1/H2/H3/列表/P
- `useExamRichEditor` + `useSaveExamRichContent` MSW 兜底
- 保存为 HTML`editorRef.current.innerHTML`
- **缺失功能**
-**真正的 Tiptap 编辑器** — portal-shell 用 `contentEditable` + `document.execCommand`**deprecated**CICD 用 Tiptap JSON 结构化文档
-**题目结构加载** — CICD 在 Server Component 内调 `getExamById` + `getQuestions`,把 `exam.structure` + `questions` 转换为 `EditorDoc``examNodesToEditorDoc` + `structureToEditorDoc`portal-shell 完全无此逻辑
-**题目占位符插入** — CICD 富文本支持插入题目节点(含 order/options/contentportal-shell 仅纯文本 HTML
-**服务端初始数据预加载** — CICD Server Component 预加载 exam + questionsportal-shell 纯客户端 MSW
-**编辑模式 (mode="edit")** — CICD `ExamRichForm` 支持 create/edit 双模式portal-shell 仅 edit
- ⚠️ **dangerouslySetInnerHTML** — portal-shell 用 `dangerouslySetInnerHTML` 注入 HTML违反 §4 安全规范(如必须使用,先用 DOMPurify 清洗)
- **技术差距**
- CICDServer Component + Tiptap + `examNodesToEditorDoc`/`structureToEditorDoc` 转换层 + `ExamRichForm`
- portal-shell 需补:引入 Tiptap或 Lexical、编写 structure→EditorDoc 转换、Server Component 预加载、题目节点类型、DOMPurify 清洗
### 3.5 classes - 班级详情页 `/shell/teacher/classes/[id]`
- **路径**`/shell/teacher/classes/[id]`(对应 CICD `/classes/my/[id]`
- **portal-shell 实现**`classes/[id]/page.tsx` + `features/teacher/classes/class-detail-client.tsx`
- **CICD 实现**`classes/my/[id]/page.tsx` + 5 个 widget 组件
- **已有功能**
- ✅ 真实查询 `useClassInfo(classId)`schema 已就绪)
- 基本信息区name/gradeId/headTeacherId/description/createdAt/updatedAt
- 学生名单区studentNo/name/enrolledAtMSW 兜底)
- 任课老师区name/subjectName/roleMSW 兜底)
- **缺失功能**
-**ClassHeader** — CICD 有独立头部组件classId/name/grade/homeroom/room/schoolName/studentCount
-**ClassOverviewStats 概览统计** — 平均分、提交率、待批改数papersToGrade、逾期数overdueCount
-**ClassTrendsWidget 趋势 widget** — 作业趋势列表id/title/status/subject/isActive/isOverdue/dueAt/submittedCount/targetCount/avgScore/medianScore
-**ClassScheduleWidget 课表 widget** — 班级课表展示
-**ClassAssignmentsWidget 作业 widget** — 班级作业列表
-**学生科目成绩展示** — CICD 通过 `getClassStudentSubjectScoresV2` 拉取每个学生的科目成绩portal-shell 学生表只有 studentNo/name/enrolledAt
-**三栏布局** — CICD 是 2/3 主区 + 1/3 侧栏portal-shell 是单栏 DetailSection 堆叠
-**服务端并行数据预加载** — CICD `Promise.all([getClassHomeworkInsights, getClassStudents, getClassSchedule, getClassStudentSubjectScoresV2])`
- **技术差距**
- CICDServer Component + 4 个并行 data-access 查询 + 5 个 widget 组件 + `SectionErrorBoundary`
- portal-shell 需补5 个 widget 组件、4 个 data-access 查询(含 MSW 兜底)、三栏布局、概览统计计算逻辑
### 3.6 students - 学生列表页 `/shell/teacher/students`
- **路径**`/shell/teacher/students`(对应 CICD `/classes/students`
- **portal-shell 实现**`students/page.tsx` + `features/teacher/students/students-list-client.tsx`
- **CICD 实现**`classes/students/page.tsx` + `StudentsFilters` + `StudentsTable` + `students-filters.tsx`
- **已有功能**
- 关键词搜索q、classId/gradeId 筛选(**纯 text input**
- 表格studentNo/name/gender/className/gradeId/enrolledAt
- 性别徽章、EmptyState、ListPageShell
- **缺失功能**
-**班级下拉选择器** — CICD 用 `StudentsFilters` 组件(含 `<select>` 班级列表portal-shell 用 `<input type="text">` 让用户手输 classId
-**默认班级选择逻辑** — CICD 默认选中教师第一个班级(`defaultClassId = classes[0].id`portal-shell 无默认
-**学生科目成绩展示** — CICD 调 `getStudentsSubjectScores(studentIds)` 拉取每个学生科目成绩,`StudentsTable` 有科目成绩列portal-shell 无
-**服务端学生列表预加载** — CICD Server Component 调 `getClassStudents` + `getStudentsSubjectScores`portal-shell 纯客户端 MSW
-**状态筛选** — CICD 有 status 维度筛选active/inactive 等portal-shell 无
- **技术差距**
- CICDServer Component + `getTeacherClasses` + `getClassStudents` + `getStudentsSubjectScores` + `StudentsFilters`/`StudentsTable` 组件
- portal-shell 需补:班级 select 组件、默认班级逻辑、科目成绩列、status 筛选
### 3.7 homework - 作业详情页 `/shell/teacher/homework/[id]`
- **路径**`/shell/teacher/homework/[id]`(对应 CICD `/homework/assignments/[id]`
- **portal-shell 实现**`homework/[id]/page.tsx` + `features/teacher/homework/homework-detail-client.tsx`
- **CICD 实现**`homework/assignments/[id]/page.tsx` + `HomeworkAssignmentQuestionErrorOverviewCard` + `HomeworkAssignmentExamContentCard`
- **已有功能**
- ✅ 真实查询 `useHomework(homeworkId)`schema 已就绪)
- 基本信息区title/description/dueDate/gracePeriod/status/classId/subjectId/createdBy/updatedAt
- 提交列表区studentName/studentNo/status/submittedAt/totalScore/maxScore/actionsMSW 兜底)
- 内联批改表单studentId/score/feedbackMSW 兜底)
- 跳转"查看所有提交"按钮 → `/homework/assignments/[id]/submissions`
- **缺失功能**
-**头部统计行** — CICD 头部有 dueDate/targetCount/submissionCount/gradedCount 四个统计指标portal-shell 无
-**HomeworkAssignmentQuestionErrorOverviewCard 题目错误概览卡片** — CICD 用 `getHomeworkAssignmentAnalytics(id)` 拉取每题错误率,渲染分析卡片(带 Suspense + SectionErrorBoundary
-**HomeworkAssignmentExamContentCard 作业内容卡片** — CICD 渲染 `assignment.structure` + `questions`(含 gradedSampleCountportal-shell 无作业内容展示
-**服务端 analytics 预加载** — CICD 调 `getHomeworkAssignmentAnalytics(id)` 返回 `{ assignment, questions, gradedSampleCount }`
-**流式渲染** — CICD 用 `<Suspense fallback={<AnalyticsSkeleton />}>` 包裹 analytics 卡片portal-shell 无
- **技术差距**
- CICDServer Component + `getHomeworkAssignmentAnalytics` + 2 个分析卡片组件 + `SectionErrorBoundary` + Suspense 流式
- portal-shell 需补题目错误概览卡片、作业内容卡片structure + questions 渲染、头部统计、analytics 查询
### 3.8 homework - 布置作业表单 `/shell/teacher/homework/new`
- **路径**`/shell/teacher/homework/new`(对应 CICD `/homework/assignments/create`
- **portal-shell 实现**`homework/new/page.tsx` + `features/teacher/homework/new-homework-client.tsx`
- **CICD 实现**`homework/assignments/create/page.tsx` + `HomeworkAssignmentForm`
- **已有功能**
- 简单表单classId/subjectId/title/description/dueDate/gracePeriod
- 内联校验、MSW 兜底 mutation `useAssignHomework`
- 成功后回列表
- **缺失功能**
-**关联考试选择** — CICD Server Component 调 `getExams({ scope })` 拉取考试列表,传给 `HomeworkAssignmentForm` 作下拉选项作业可基于试卷结构生成portal-shell 无 examId 字段
-**班级下拉选择器** — CICD 调 `getTeacherClasses()` 拉取班级portal-shell 用 `<input type="text">` 手输 classId
-**EmptyState when no classes** — CICD 在 `classes.length === 0` 时显示 EmptyState 提示"无可用班级,去班级管理"portal-shell 无
-**HomeworkAssignmentForm 富表单** — CICD 用专门组件(含 exam 关联、班级 select、可能含题目结构选择
- **技术差距**
- CICDServer Component + `getExams` + `getTeacherClasses` + `HomeworkAssignmentForm` 组件 + EmptyState
- portal-shell 需补examId 字段 + 考试下拉、班级下拉、无班级 EmptyState
### 3.9 lesson-plans - 教案编辑工作台 `/shell/teacher/lesson-plans/[planId]/edit`
- **路径**`/shell/teacher/lesson-plans/[planId]/edit`
- **portal-shell 实现**`lesson-plans/[planId]/edit/page.tsx` + `features/teacher/lesson-plans/lesson-plan-edit-client.tsx`
- **CICD 实现**`lesson-plans/[planId]/edit/page.tsx` + `LessonPlanEditor` + `LessonPlanProviderSetup` + `AiClientProvider`
- **已有功能**
- 三栏工作台左栏大纲树LessonPlanOutlineTree+ 中栏富文本编辑器 + 右栏属性面板id/grade/subject/duration/status/updatedAt/resources
- 工具栏B/I/U/H1/H2/H3/列表/P
- `useLessonPlan` + `useUpdateLessonPlan` MSW 兜底
- 保存为 HTML
- **缺失功能**
-**真正的 Tiptap 编辑器** — portal-shell 用 `contentEditable` + `document.execCommand`**deprecated**CICD 用 `LessonPlanEditor`Tiptap
-**AI 集成** — CICD 包 `<AiClientProvider service={createCoreAiClientService()}>`,支持 AI 辅助生成/润色portal-shell 无
-**教材/章节上下文** — CICD Server Component 调 `getTextbookById` + `getChaptersByTextbookId` + `findChapterById`,把 textbookTitle/chapterTitle 传给编辑器工具栏显示portal-shell 无
-**LessonPlanProviderSetup** — CICD 有专门的 Provider 设置组件注入编辑器所需上下文portal-shell 无
-**服务端初始数据预加载** — CICD Server Component 预加载 plan + teacherClasses + textbook + chapterportal-shell 纯客户端 MSW
-**班级关联** — CICD 加载 `getTeacherClasses({ teacherId })` 传给编辑器教案可关联班级portal-shell 无
- ⚠️ **dangerouslySetInnerHTML** — 同 §3.4,违反 §4 安全规范
- **技术差距**
- CICDServer Component + Tiptap + AiClientProvider + LessonPlanProviderSetup + 4 个 data-access 查询
- portal-shell 需补Tiptap、AiClientProvider 接入、教材/章节加载、Provider 设置、班级关联、DOMPurify 清洗
### 3.10 grades - 成绩录入页 `/shell/teacher/grades/entry`
- **路径**`/shell/teacher/grades/entry`
- **portal-shell 实现**`grades/entry/page.tsx` + `features/teacher/grades/grade-entry-client.tsx`
- **CICD 实现**`grades/entry/page.tsx` + `BatchGradeEntryByExam` 组件
- **已有功能**
- **单学生单次录入**表单classId/studentId/examId/homeworkId/score/totalScore/feedback
- 内联校验、MSW 兜底 mutation `useCreateGrade`
- **缺失功能**
-**批量录入** — CICD 用 `BatchGradeEntryByExam` 组件,按考试批量录入全班成绩(一次选 exam + class列出所有学生逐题/逐生录入portal-shell 是单生单次
-**考试下拉选择器** — CICD 调 `getExamsForGradeEntry(ctx.dataScope)` 拉取可录入成绩的考试列表portal-shell 用 `<input type="text">` 手输 examId
-**班级下拉选择器** — CICD 调 `getTeacherClasses()` + scope 过滤 + `getClassGradeIdsByClassIds` 构建 classGradeMap用于按试卷年级过滤班级portal-shell 手输 classId
-**学生列表预加载** — CICD 调 `getClassStudentsForEntry(classId, ctx.dataScope)` 拉取班级学生portal-shell 手输 studentId
-**考试题目列表** — CICD 调 `getExamForGradeEntry(examId, ctx.dataScope)` 返回试卷详情含题目,支持按题录入
-**DataScope 过滤** — CICD 用 `ctx.dataScope.type === "class_taught"` 过滤班级portal-shell 无权限过滤
-**EmptyState when no exams** — CICD 在 `exams.length === 0` 时显示 EmptyState
-**按试卷年级过滤班级** — CICD 用 classGradeMap 客户端过滤
- **技术差距**
- CICDServer Component + 4 个 data-access 查询 + `BatchGradeEntryByExam` 客户端组件 + DataScope
- portal-shell 需补:批量录入组件、考试/班级下拉、学生列表、题目列表、scope 过滤、EmptyState
### 3.11 attendance - 考勤点名表 `/shell/teacher/attendance/sheet`
- **路径**`/shell/teacher/attendance/sheet`
- **portal-shell 实现**`attendance/sheet/page.tsx` + `features/teacher/attendance/attendance-sheet-client.tsx`
- **CICD 实现**`attendance/sheet/page.tsx` + `AttendanceSheet` 组件
- **已有功能**
- classId**text input**+ date 选择
- 学生表格studentName/status 按钮组/remark
- 4 种状态PRESENT/ABSENT/LATE/LEAVE点击切换
- MSW 兜底 `useAttendanceSheet` + `useSaveAttendanceSheet`
- 保存后回列表
- **缺失功能**
-**班级下拉选择器** — CICD Server Component 调 `getTeacherClasses()` 拉取班级,传给 `AttendanceSheet` 组件作下拉portal-shell 用 `<input type="text">` 手输 classId
-**服务端学生列表预加载** — CICD 调 `getClassStudentsForAttendance(defaultClassId)` 服务端预加载学生portal-shell 完全依赖 MSW mock
-**AttendanceSheet 组件** — CICD 有专门的客户端组件含班级切换、日期选择、批量标记、统计汇总portal-shell 是手写表格
- **技术差距**
- CICDServer Component + `getTeacherClasses` + `getClassStudentsForAttendance` + `AttendanceSheet` 客户端组件
- portal-shell 需补:班级 select、服务端学生预加载、AttendanceSheet 组件
### 3.12 diagnostic - 班级诊断详情 `/shell/teacher/diagnostic/class/[classId]`
- **路径**`/shell/teacher/diagnostic/class/[classId]`
- **portal-shell 实现**`diagnostic/class/[classId]/page.tsx` + `features/teacher/diagnostic/diagnostic-class-detail-client.tsx`
- **CICD 实现**`diagnostic/class/[classId]/page.tsx` + `ClassDiagnosticView` + `DiagnosticServiceProvider` + `DiagnosticMonitorProvider`
- **已有功能**
- 基本信息区title/reportType/status/className/studentCount/avgScore/summary/generatedAt
- 薄弱知识点表格kpTitle/mastery/errorCount
- 教学建议列表recommendations
- MSW 兜底 `useDiagnosticReport(classId)`
- **缺失功能**
-**ClassDiagnosticView 富视图组件** — CICD 用专门的 `ClassDiagnosticView`(含掌握度雷达图、知识点 drill-down、学生分布等丰富交互portal-shell 是基础详情页
-**DiagnosticServiceProvider** — CICD 注入诊断服务上下文(支持客户端 drill-down 查询portal-shell 无
-**DiagnosticMonitorProvider + 监控埋点** — CICD 用 `createMonitoredDiagnosticService(defaultDiagnosticService, noopDiagnosticMonitor)` 包装服务支持生产环境监控注入portal-shell 无
-**服务端数据预加载** — CICD Server Component 调 `getClassMasterySummary(classId)` 预加载portal-shell 纯客户端 MSW
-**DataScope 校验** — CICD 校验 `class_taught` scope教师只能查所教班级拒绝 `class_members`/`children` scopeportal-shell 无
-**WidgetBoundary** — CICD 用 `WidgetBoundary` 包裹局部降级portal-shell 用 DetailPageShell
- **技术差距**
- CICDServer Component + `getClassMasterySummary` + `ClassDiagnosticView` + Diagnostic Service Provider/Monitor + DataScope
- portal-shell 需补ClassDiagnosticView 组件、DiagnosticServiceProvider/MonitorProvider、服务端预加载、DataScope 校验、WidgetBoundary
### 3.13 dashboard - 教师仪表盘 `/shell/teacher`teacher/page.tsx
- **路径**`/shell/teacher`(根教师页)
- **portal-shell 实现**`shell/teacher/page.tsx`"use client"
- **CICD 实现**`dashboard/page.tsx`Server Component+ `TeacherDashboardView`
- **已有功能**
- 4 StatCardtotal_classes/total_students/class_avg_score/pending_homework_count
- 班级概况区class_name/student_count/average_score
- 近期预警区target_name/severity/warning_type/current_value/threshold
- ✅ 真实查询 `useTeacherDashboard`data-ana 聚合查询)
- loading/error 三态处理
- **缺失功能**
- ⚠️ **i18n 硬编码** — portal-shell 标题/描述用硬编码中文(`"教师仪表盘"``"今日教学概览"``"班级总数"` 等),违反 §3.10 设计令牌规范的 i18n 要求,应改 `useTranslations("dashboard")`CICD 用 `getTranslations("dashboard")`
-**流式渲染** — CICD Server Component 用 `getTeacherDashboardAction()` 返回未解析 Promise + `<TeacherDashboardView dataPromise={...}>`,视图内 `use()` 消费 + Suspense 流式渲染portal-shell 是客户端整体 loading
-**TeacherDashboardView 富视图** — CICD 用专门的 `TeacherDashboardView` 组件(可能含更多 widget课表/作业/考试/学生预警等portal-shell 仅 4 StatCard + 2 简单列表
-**更多 widget** — CICD 可能含课表、作业待批、考试安排、学生预警等 widget需读 TeacherDashboardView 确认portal-shell 仅基础展示
- **技术差距**
- CICDServer Component + Server Action + Suspense 流式 + `TeacherDashboardView` 组件
- portal-shell 需补i18n 化、TeacherDashboardView 组件、流式渲染、更多 widget待确认
### 3.14 classes - 班级列表页 `/shell/teacher/classes`(轻量不完整)
- **路径**`/shell/teacher/classes`
- **portal-shell 实现**`classes/page.tsx` + `features/teacher/classes/classes-list-client.tsx`
- **CICD 实现**`classes/my/page.tsx` + `MyClassesGrid` 组件
- **已有功能**
- ✅ 真实查询 `useClasses({ gradeId, subjectId, q })`MSW 兜底)
- 三筛选q/gradeId/subjectId、表格name/grade/headTeacher/studentCount/subjectCount/description/updatedAt/actions
- EmptyState、ListPageShell
- **缺失功能**
- ⚠️ **MyClassesGrid 卡片网格视图** — CICD 用 `MyClassesGrid` 组件卡片式展示portal-shell 用表格,视觉差异(功能等价,不算重大缺失)
- ⚠️ **subjectOptions 预加载** — CICD 调 `getClassSubjects()` 拉取科目选项作下拉portal-shell 用 text input
- ⚠️ **SectionErrorBoundary** — CICD 用 `SectionErrorBoundary` 包裹portal-shell 用 errorNode
- **技术差距**:较小,主要是视觉/组件差异,功能基本等价
### 3.15 exams - 试卷组卷工作台 `/shell/teacher/exams/[id]/build`
- **路径**`/shell/teacher/exams/[id]/build`
- **CICD 参考实现**`e:\desktop\CICD\src\app\(dashboard)\teacher\exams\[id]\build\page.tsx` + 同目录 `error.tsx` + `loading.tsx`
- **功能描述**试卷组卷工作台CICD 为 Server Component 入口(`export const dynamic = "force-dynamic"`
- `requirePermission(Permissions.EXAM_READ)` 权限校验,拿到 `ctx.dataScope`
- `getExamById(id, ctx.dataScope)` 拉取考试元数据(含 `questions` + `structure`),不存在则 `notFound()`
- `Promise.all` 并行拉取题库前 20 条(`getQuestions({ pageSize: 20 })`+ 已选题目详情(`getQuestions({ ids: selectedQuestionIds })`
- `questionOptionsById` Map 去重合并 bank + selected 题目为 `questionOptions`
- `normalizeStructure(exam.structure)``exam.structure` 规范化为 `ExamNode[]` 树(支持嵌套分组节点)
- structure 空但 `initialSelected` 非空时回退为扁平节点列表(用 `@paralleldrive/cuid2` `createId()` 生成节点 ID
- `createCoreAiClientService()` 创建 AI 服务,`<AiClientProvider>` 注入 AI 上下文
- 渲染 `<ExamAssembly>` 富组件(位于 `modules/exams/components/exam-assembly`),透传 examId/title/subject/grade/difficulty/totalScore/durationMin + initialSelected + initialStructure + questionOptions
- 配套 `error.tsx``useErrorReport` 错误上报 + `EmptyState` + retry 按钮)+ `loading.tsx`3 栏 Skeleton`lg:grid-cols-3` 2+1 布局)
- **技术栈**Next.js App Router Server Component`force-dynamic`+ next-intl `getTranslations("examHomework.exam.build")` + `requirePermission` + `Permissions.EXAM_READ` + `ctx.dataScope` 数据范围过滤 + Drizzle data-access`getExamById` / `getQuestions`+ `normalizeStructure` 转换层 + `@paralleldrive/cuid2` + AI 集成(`AiClientProvider` + `createCoreAiClientService`+ `ExamAssembly` 客户端组件 + 专用 error/loading 边界
- **ARCHITECTURE.md 契约**B2— portal-shell `page.tsx` 注释明确 `@contract-pending``examBuild(examId)` / `questionsLibrary(filter)` / `saveExamBuild(input)` 三个根字段均不存在,全 MSW 兜底
- **portal-shell 现状**
- `page.tsx``<Suspense fallback={<WorkbenchPageSkeleton />}>` 包裹 `ExamBuildClient`**无服务端预加载、无权限守卫、无 notFound**
- `ExamBuildClient` 纯客户端,使用 `useExamBuild` / `useQuestionsLibrary` / `useSaveExamBuild` 三个 Apollo hook全 MSW 兜底)
- `WorkbenchPageShell` 三栏布局:左 `QuestionsLibraryPanel` / 中 `SelectedQuestionsPanel` / 右 `PreviewPanel`
- 左栏q 关键词 + type 下拉 + difficulty 下拉筛选 + 题目列表 + 添加按钮(`Plus` 图标)+ 总数显示
- 中栏:已选题目列表,支持上移/下移(`↑`/`↓`/编辑分值(`Input type="number"`/移除(`Trash2`
- 右栏:总分(含 baseline 差值 ± 提示amber/destructive 配色)+ 及格分 + 题型分布(`countByType`
- 本地 `useState<ExamBuildNode[] | null>` 管理 selected`useEffect` 在 data 首次就绪时初始化(`sortBySortOrder`
- 保存 mutation `useSaveExamBuild` + `notify.success/error` 反馈
- 三态合并到 `errorNode`error + empty 共用降级节点)
- **无专用 error.tsx / loading.tsx 文件**
- **缺失功能**
-**Server Component 数据预加载** — CICD 在服务端并行 `Promise.all` 拉取 exam + bank questions + selected questionsportal-shell 完全依赖客户端 MSW
-**DataScope 权限过滤** — CICD 用 `ctx.dataScope` 过滤考试可见性portal-shell 无
-**`requirePermission(Permissions.EXAM_READ)` 权限守卫** — portal-shell 无
-**`notFound()` 404 处理** — CICD 考试不存在时调 `notFound()`portal-shell 显示空态节点
-**AI 集成** — CICD 包 `<AiClientProvider service={createCoreAiClientService()}>` 支持 AI 辅助组卷portal-shell 无 AI 接入(与 §3.9 教案编辑同类型缺失,见 §六 共性技术债 6
-**`normalizeStructure` 转换层** — CICD 把 `exam.structure` 规范化为 `ExamNode[]`支持嵌套分组节点portal-shell 用扁平 `ExamBuildNode[]`,无结构化分组能力
-**structure 空时回退逻辑** — CICD 在 structure 空但 `initialSelected` 非空时回退为扁平节点列表cuid2 生成 IDportal-shell 无此兼容
-**`ExamAssembly` 富组件** — CICD 用专门的 `ExamAssembly` 组件(`modules/exams/components/exam-assembly`portal-shell 是手写 3 个 Panel 函数
-**questionOptions 去重合并** — CICD 把 bank + selected 题目通过 Map 去重合并为 `questionOptions` 传给组件portal-shell 左右栏分别查询、无合并
-**专用 error.tsx** — CICD 有 `error.tsx``useErrorReport` 上报 + `EmptyState` + retry 按钮portal-shell 用 `WorkbenchPageShell.errorNode` 整页降级,无错误上报
-**专用 loading.tsx** — CICD 有 3 栏 Skeleton`lg:grid-cols-3` 2+1 布局portal-shell 用通用 `WorkbenchPageSkeleton`
-**`dynamic = "force-dynamic"`** — CICD 强制动态渲染权限相关数据不能静态化portal-shell 默认
- ⚠️ **i18n 命名空间差异** — CICD 用 `examHomework.exam.build`portal-shell 用 `exams`,需对齐
- ⚠️ **exam 元数据透传** — CICD 把 subject/grade/difficulty/durationMin 传给 `ExamAssembly` 展示portal-shell 不展示这些上下文
- **建议**
1. **短期(契约未就绪)**:保留 MSW 兜底;补 `error.tsx``useErrorReport` + EmptyState + retry+ `loading.tsx`3 栏 Skeletoni18n 命名空间与 CICD 对齐(或保留 `exams` 但与 ARCH §11 一致)
2. **中期(契约就绪后)**
- 改造为 Server Component并行预加载 exam + questionsbank + selected
- 引入 `requirePermission` + `ctx.dataScope` 过滤
- 实现 `normalizeStructure` 转换层,支持嵌套 `ExamNode` 树(与 CICD 对齐)
- 引入 `AiClientProvider` + `createCoreAiClientService`,接入 AI 辅助组卷
- 抽取 `ExamAssembly` 富组件,统一 3 栏 UI 与 CICD 对齐
- questionOptions 去重合并,减少客户端重复查询
3. **长期**:与 §3.4exams/[id]/edit 富文本)+ §3.9lesson-plans edit统一引入 Tiptap + AI 集成方案(见 §六 共性技术债 1/2/6
---
## 四、按模块汇总
| 模块 | ARCH 规划 | portal-shell 已实现 | ✅ 完整 | 🟡 不完整 | ❌ 缺失 | 备注 |
| ---------------- | --------- | ------------------- | -------------- | --------------------- | --------------- | ----------------------------------------------------------------------------------- |
| dashboard | 1 | 1 | 0 | 1§3.13 | 0 | i18n 硬编码 + 缺流式 + 缺富视图 |
| exams | 7 | 6 | 1analytics | 4§3.1/3.2/3.3/3.4 | 1proctoring | build 列入🟡但功能基本完整,缺 AI |
| homework | 7 | 7 | 5 | 2§3.7/3.8 | 0 | 详情缺分析卡片,新建缺考试关联 |
| grades | 5 | 5 | 4 | 1§3.10 | 0 | entry 缺批量录入 |
| lesson-plans | 6 | 6 | 5 | 1§3.9 | 0 | edit 缺 Tiptap + AI + 教材章节 |
| questions | 1 | 1 | 1 | 0 | 0 | — |
| textbooks | 2 | 2 | 2 | 0 | 0 | — |
| attendance | 4 | 4 | 3 | 1§3.11 | 0 | sheet 缺班级下拉 + 学生预加载 |
| classes | 3 | 3 | 1schedule | 2§3.5/3.14 | 0 | [id] 缺 5 个 widgetlist 轻量差异 |
| students | 1 | 1 | 0 | 1§3.6 | 0 | 缺下拉 + 科目成绩 |
| course-plans | 2 | 2 | 2 | 0 | 0 | — |
| elective | 3 | 3 | 3 | 0 | 0 | — |
| error-book | 1 | 1 | 1 | 0 | 0 | — |
| diagnostic | 2 | 2 | 1list | 1§3.12 | 0 | class/[classId] 缺富视图 + 服务上下文 |
| analytics | 2 | 2 | 2 | 0 | 0 | ARCH 新建MSW 兜底 |
| ai | 3 | 3 | 3 | 0 | 0 | ARCH 新建 B2末全 MSW |
| knowledge-graph | 1 | 1 | 1 | 0 | 0 | ARCH 新建 B2末 |
| practice | 1 | 1 | 1 | 0 | 0 | — |
| schedule-changes | 1 | 1 | 1 | 0 | 0 | — |
| leave | 1 | 1 | 1 | 0 | 0 | — |
| notifications | 1共享 | 0 | 0 | 0 | 1§2.3 | B1 共享schema ✅ |
| settings | 1共享 | 0 | 0 | 0 | 1§2.4 | B1 共享 |
| **合计** | **56** | **53** | **33** | **14** | **4** | 另CICD 历史功能 `diagnostic/student/[studentId]` 未在 ARCH 规划建议补做§2.2 |
---
## 五、优先级建议
### P0B1 共享必须补schema 已就绪)
1. `/shell/notifications` — B1 共享,`notifications(userId)`
2. `/shell/settings` — B1 共享
### P1B2末 规划页,必须补)
3. `/shell/teacher/exams/[id]/proctoring` — B2末WS 二期,需先定 WS 契约
### P2CICD 历史功能,建议补,需同步更新 ARCH §9.1
4. `/shell/teacher/diagnostic/student/[studentId]` — 学生诊断雷达图CICD 已有完整实现
### P3功能不完整页按业务优先级补
**高优先级(核心教学场景,差距大)**5. `classes/[id]` 班级详情 — 缺 5 个 widget概览/趋势/课表/作业/学生科目成绩班级是教师核心工作台6. `homework/[id]` 作业详情 — 缺分析卡片 + 内容卡片,作业是高频场景 7. `grades/entry` 成绩录入 — 缺批量录入,单生录入效率太低 8. `lesson-plans/[planId]/edit` 教案编辑 — 缺 Tiptap + AIcontentEditable deprecated 不可长期维护
**中优先级(交互不完整,影响体验)**9. `students` 学生列表 — 缺下拉 + 科目成绩 10. `homework/new` 布置作业 — 缺考试关联 + 班级下拉 11. `attendance/sheet` 考勤点名 — 缺班级下拉 + 学生预加载 12. `diagnostic/class/[classId]` 班级诊断 — 缺富视图 + 服务上下文 13. `exams/[id]/edit` 富文本编辑 — 缺 Tiptap + 题目结构(与 §3.9 教案编辑同类型问题,建议统一升级 Tiptap14. `exams` 列表 — 缺筛选/计数/分页/DataTable
**低优先级(功能基本可用,细节差距)**15. `exams/[id]` 详情 — 编辑按钮未接路由小修16. `exams/new` 新建考试 — 是否补富文本取决于产品决策 17. `classes` 列表 — 视觉差异,功能等价 18. `dashboard` 仪表盘 — i18n 化 + 流式渲染i18n 应立即修,违反 §3.10
---
## 六、共性技术债
1. **Tiptap 缺失**`exams/[id]/edit``lesson-plans/[planId]/edit` 均用 `contentEditable` + `document.execCommand`deprecatedCICD 用 Tiptap。建议统一引入 Tiptap或 Lexical编写 structure→EditorDoc 转换层。
2. **dangerouslySetInnerHTML 违规**:上述两个富文本页直接 `dangerouslySetInnerHTML`,违反 §4 安全规范,需 DOMPurify 清洗。
3. **下拉选择器缺失**`students`/`homework/new`/`grades/entry`/`attendance/sheet` 等多处用 `<input type="text">` 替代 `<select>`,需补 data-access 查询 + select 组件。
4. **DataScope 校验缺失**portal-shell 普遍无 `ctx.dataScope` 权限过滤CICD 在 Server Component 内做 scope 过滤),需在后端契约就绪后补。
5. **Server Component 预加载缺失**CICD 多个详情页在 Server Component 内并行预加载多个数据源portal-shell 纯客户端 MSW等契约就绪后需改 Server Component 预加载 + Suspense 流式。
6. **AI 集成缺失**`exams/[id]/build``lesson-plans/[planId]/edit` 在 CICD 有 `AiClientProvider` + `createCoreAiClientService`portal-shell 无 AI 接入。
7. **i18n 硬编码**`dashboard` 用硬编码中文,应全面 `useTranslations`
8. **SectionErrorBoundary / WidgetBoundary 缺失**CICD 多处用 `SectionErrorBoundary`/`WidgetBoundary` 做局部降级portal-shell 用 errorNode 整页降级,粒度较粗。
---
## 七、参考文件索引
### CICD 参考实现
- `e:\desktop\CICD\src\app\(dashboard)\teacher\` — 教师域 53 页源
- `e:\desktop\CICD\src\modules\exams\components\exam-rich-form.tsx` — 富文本试卷表单
- `e:\desktop\CICD\src\modules\exams\components\exam-assembly.tsx` — 组卷工作台
- `e:\desktop\CICD\src\modules\classes\components\class-detail\` — 班级详情 5 个 widget
- `e:\desktop\CICD\src\modules\classes\components\my-classes-grid.tsx` — 班级网格
- `e:\desktop\CICD\src\modules\classes\components\students-table.tsx` — 学生表
- `e:\desktop\CICD\src\modules\homework\components\homework-assignment-question-error-overview-card.tsx` — 作业错误概览
- `e:\desktop\CICD\src\modules\homework\components\homework-assignment-exam-content-card.tsx` — 作业内容卡片
- `e:\desktop\CICD\src\modules\grades\components\batch-grade-entry.tsx` — 批量录入
- `e:\desktop\CICD\src\modules\lesson-preparation\components\lesson-plan-editor.tsx` — 教案编辑器
- `e:\desktop\CICD\src\modules\diagnostic\components\class-diagnostic-view.tsx` — 班级诊断视图
- `e:\desktop\CICD\src\modules\diagnostic\components\student-diagnostic-view.tsx` — 学生诊断视图
- `e:\desktop\CICD\src\modules\proctoring\components\proctoring-dashboard.tsx` — 监考面板
- `e:\desktop\CICD\src\modules\dashboard\components\teacher-dashboard\teacher-dashboard-view.tsx` — 仪表盘视图
### portal-shell 当前实现
- `e:\Desktop\Edu\apps\portal-shell\src\app\shell\teacher\` — 教师域 53 页
- `e:\Desktop\Edu\apps\portal-shell\src\features\teacher\` — 51 个 `*-client.tsx` + 辅助组件
- `e:\Desktop\Edu\apps\portal-shell\src\lib\api\` — Apollo hooks含 MSW 兜底)
- `e:\Desktop\Edu\apps\portal-shell\src\shared\components\page-templates\` — ListPageShell/FormPageShell/DetailPageShell/WorkbenchPageShell
- `e:\Desktop\Edu\apps\portal-shell\ARCHITECTURE.md` §9.1 — 教师域 56 页规划
### 契约工单
- `docs/architecture/issues/contracts/core-edu_contract.md` — exams/homework/grades/questions mutation 工单
- `docs/architecture/issues/contracts/classes_contract.md` — classes/students/attendance 工单
- `docs/architecture/issues/contracts/data-ana_contract.md` — diagnostic/analytics 工单
---
**分析完成。下一步建议按 §五 优先级逐项补做,每补一页同步更新 ARCH §9.1 状态 + 004 + arch.db。**