docs(architecture): update impact map, data, audit report, troubleshooting
Some checks failed
CI / scheduled-backup (push) Has been skipped
CI / backup-verify (push) Has been skipped
CI / weekly-dr-drill (push) Failing after 0s
CI / build-deploy (push) Has been cancelled
CI / security-scan (push) Has been cancelled

- Update 004_architecture_impact_map.md

- Update 005_architecture_data.json

- Add lesson-preparation-audit-report-v5.md

- Add troubleshooting docs
This commit is contained in:
SpecialX
2026-07-04 10:24:08 +08:00
parent cbc6e259fa
commit 872d5fb085
4 changed files with 1176 additions and 12 deletions

View File

@@ -894,7 +894,7 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
| `actions.ts` | 502 | 14 个 Server Action写操作含 Zod 校验 + 资源归属校验 + 知识图谱查询/前置依赖管理 + class-mastery 视图) |
| `data-access.ts` | 593 | 教材/章节/知识点 CRUD + 跨模块查询接口 + 资源归属校验 + 数据范围过滤 + 前置依赖 CRUDv3 P2硬编码异常改为 NotFoundError |
| `data-access-graph.ts` | 188 | 知识图谱只读查询(✅ Task 5 新增:知识点关联聚合、学生/班级掌握度、前置后置知识点,标记 `server-only`v2 修复:前置依赖双向 IN 过滤防跨教材污染) |
| `types.ts` | 94 | 类型定义含知识图谱类型GraphViewMode/MasteryInfo/KpWithRelations/GraphNodeData/GraphEdgeData/KnowledgeGraphData/MasteryLevel |
| `types.ts` | 94 | 类型定义含知识图谱类型GraphViewMode/GraphLayoutMode/MasteryInfo/KpWithRelations/GraphNodeData/GraphEdgeData/KnowledgeGraphData/MasteryLevel |
| `schema.ts` | 56 | Zod 校验(含 CreatePrerequisiteSchema/DeletePrerequisiteSchemav2 修复refine 消息改为英文v3 修复:移除死代码 ReorderChaptersSchema |
| `constants.ts` | 91 | 学科/年级常量与颜色映射(✅ 新增v1 测试修复:新增 Chinese/Grade 1/Grade 2 |
| `utils.ts` | 226 | 章节树构建/排序/查找等纯函数 + 循环检测(✅ 新增,含单测) |
@@ -908,10 +908,11 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
| `hooks/use-kp-update.ts` | 36 | 知识点更新 Hookv3 P2 新增:从 use-kp-crud 拆分) |
| `hooks/use-text-selection.ts` | 49 | 文本选区捕获 Hook |
| `hooks/use-graph-data.ts` | 65 | 知识图谱数据加载 Hook✅ Task 11 新增:派生值模式避免 effect 中 setStatev2 修复:区分 isLoading/isRefreshing 避免 UI 闪烁) |
| `components/knowledge-graph.tsx` | 356 | React Flow 知识图谱主组件(✅ Task 10/15 重写:全书视图 + 搜索高亮 + 关联节点高亮 + 章节着色v2 新增:添加/删除前置依赖 Dialog |
| `components/knowledge-graph.tsx` | 408 | 知识图谱主组件(✅ Task 10/15 重写:全书视图 + 搜索高亮 + 关联节点高亮 + 章节着色v2 新增:添加/删除前置依赖 Dialogv4 新增hierarchical/force 布局模式切换,根据布局模式渲染分层 ReactFlow 或 Obsidian 风格力导向图,状态/详情面板/依赖增删对话框共享 |
| `components/graph-kp-node.tsx` | 92 | React Flow 自定义节点(✅ Task 9 新增:知识点名称+题目数徽章+掌握度进度条v2 修复:节点宽度常量化 NODE_WIDTHv3 修复:类型守卫替代 as 断言) |
| `components/graph-prerequisite-edge.tsx` | 43 | React Flow 自定义边(✅ Task 9 新增:虚线+箭头表示前置依赖v2 修复GraphEdgeData 类型安全转换) |
| `components/graph-toolbar.tsx` | 84 | 图谱工具栏(✅ Task 9 新增:视图模式切换 + 搜索 + 重置视图v2 新增isRefreshing 轻量指示器) |
| `components/graph-toolbar.tsx` | 121 | 图谱工具栏(✅ Task 9 新增:视图模式切换 + 搜索 + 重置视图v2 新增isRefreshing 轻量指示器v4 新增hierarchical/force 布局模式切换 Select |
| `components/force-graph.tsx` | 451 | Obsidian 风格力导向图谱组件v4 新增:基于 react-force-graph-2d + d3-forcev5 视觉对齐 Obsidian Graph View小圆点节点+极细半透明边线+标签右侧带背景+hover/选中邻居高亮+紫色外圈焦点环;通过 next/dynamic ssr:false + import type 加载避免 SSR canvas/window 报错) |
| `components/graph-node-detail-panel.tsx` | 171 | 节点详情侧边面板(✅ Task 13 新增:描述/掌握度/关联题目/前置后置列表v2 修复:移除未使用 textbookId propv3 修复aria-label |
| `components/chapter-sidebar-list.tsx` | 325 | 章节侧边栏列表v2 修复canEdit 默认 false + orderUpdateFailed i18n keyv3 修复:键盘导航) |
| `components/section-error-boundary.tsx` | 53 | 章节内容错误边界v2 修复:默认值改为空字符串 + 条件渲染v3 修复componentDidCatch + a11y |
@@ -919,7 +920,7 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
| `components/textbook-content-panel.tsx` | 199 | 章节内容面板v3 P217 props 按 chapter/editing/selection/highlight 四组重构) |
| `components/textbook-form-dialog.tsx` | 68 | 教材创建对话框v3 P2复用 TextbookFormFields |
| `components/textbook-settings-dialog.tsx` | 136 | 教材设置对话框v3 P2复用 TextbookFormFields |
| `components/textbook-reader.tsx` | 412 | 教材阅读器主组件v3 P2移除命令式 classList高亮改为状态驱动 |
| `components/textbook-reader.tsx` | 458 | 教材阅读器主组件v3 P2移除命令式 classList高亮改为状态驱动v5 桌面端改用 ResizablePanel 可拖拽分栏,图谱 tab 时图谱初始占 60%,切换 tab 用 key 重置比例 |
| `components/*` | 17 文件 | 教材编辑/知识图谱组件(新增 `textbook-form-fields.tsx`、5 个 graph-* 组件、3 个 use-kp-* 子 Hook`teacher-textbook-reader.tsx` 已移至 app 层) |
---
@@ -2758,6 +2759,34 @@ src/auth.ts ──▶ import { ... } from "@/shared/lib/permissions"
> - **权限扩展**:新增 STANDARD_READ/MANAGE/LINK + LESSON_PLAN_SUBMIT/REVIEW/ANALYTICS_READ/SUBSTITUTE_MANAGE
> - **i18n 扩展**zh-CN 新增 9 个命名空间status 扩展为 6 状态
> - **数据库表**:新增 6 张表lessonPlanComments/lessonPlanReviewRecords/lessonPlanFormativeItems/lessonPlanAttachments/lessonPlanAiEvaluations/lessonPlanSubstituteAssignments
>
> 架构变更2026-07-03V5 场景缺口修复第一阶段):
> - **V5-1 自动保存失败 UI 兜底**version-slice.ts 新增 saveError/isOnline 状态lesson-plan-editor.tsx 监听 online/offline 事件 + toast 提示 + 重试按钮
> - **V5-2 撤销/重做**:新增 hooks/history-slice.tspast/future 栈50 步上限editor-slice.ts 所有 mutation 包装 pushHistory编辑器顶部 Undo/Redo 按钮 + Ctrl/Cmd+Z/Shift+Z 快捷键
> - **V5-3 发布前作业单预览**publish-homework-dialog.tsx 改为 3 步流程(选班级 → 预览题目+总分+学生数 → 确认发布exercise-block.tsx 传入 items
> - **V5-4 导出/打印**:新增 lib/export.ts文档扁平化详细版/简洁版)+ components/print-view.tsx打印视图编辑器顶部新增"导出"按钮
> - **V5-5 多媒体嵌入 + 素材库**types.ts RichTextBlockData 新增 attachments 字段rich-text-block.tsx 集成 @tiptap/extension-image新增 components/attachment-picker.tsx复用 use-file-upload + M6 附件表 data-accessLessonPlanDataService 接口新增 getLessonPlanAttachments/createLessonPlanAttachment/deleteLessonPlanAttachment 三个方法;新增依赖 @tiptap/extension-imageFileTargetType 新增 "lesson_plan"
> - **i18n 扩展**zh-CN/en 同步新增 action.undo/redo、status.retrySave/saveFailed/recovered/offline、publish.step1-3/preview*/confirm*、questionBank.type 多题型、export.*、attachment.*、editor.textbookContent
> - **审计报告**:新增 docs/architecture/audit/lesson-preparation-audit-report-v5.md场景缺口维度对照 v4 架构合规维度)
>
> 架构变更2026-07-03V5 场景缺口修复第二阶段 V5-6~V5-21
> - **V5-6 W1 题库组卷预览**exercise-block.tsx 增加组卷预览模式(题目列表 + 总分统计)
> - **V5-7 W3/W4 课案绑定课时**:新增 data-access-schedules.ts + actions-schedules.ts + components/schedule-dialog.tsx编辑器新增「安排课时」按钮数据库新增 lesson_plan_schedules 表
> - **V5-8 U2 画布自动布局**:新增 lib/auto-layout.ts@dagrejs/dagre DAG 自动布局项目已安装依赖无需新增editor-slice.ts 新增 autoLayout action
> - **V5-9 F5 教材模糊搜索 + 最近使用**template-picker.tsx 增加客户端模糊搜索(标题/学科/年级/出版社)+ localStorage 最近使用 5 个教材
> - **V5-10 P1 画布性能优化**node-editor.tsx ReactFlow 新增 onlyRenderVisibleElements 虚拟化 + minZoom={0.2}/maxZoom={2.5}/elevateNodesOnSelect={false}
> - **V5-12 R4 校内课案库**:新增 teacher/lesson-plans/library 路由 + loading.tsx + error.tsxactions.ts 新增 duplicateLessonPlanFormActionFormData wrapper 适配 form action
> - **V5-13 P3 移动端只读视图**:新增 components/lesson-plan-mobile-view.tsx按教学阶段分组线性卡片视图lesson-plan-readonly-view.tsx 集成 useMediaQuery("(max-width: 768px)") 小屏切换
> - **V5-14 F4 板书可视化工具**blackboard-block.tsx 增加轻量级可视化预览(不引入新库)——编辑/预览模式切换、structure 层级树、mindmap 中心+分支、text 等宽展示;新增 BlackboardPreview 子组件 + parseContent 纯函数(按缩进识别层级)
> - **V5-15 T1 教学阶段分组**types.ts 新增 TeachingStage 类型 + TEACHING_STAGE_KEYS 常量Block 接口新增 stage? 字段node-edit-panel.tsx 添加教学阶段选择器 UI
> - **V5-16 T2 反思闭环(版本对比)**:新增 lib/version-diff.ts纯函数 diffDocuments 对比两个 LessonPlanDocument 节点级差异added/removed/modified/unchanged + changedFields新增 components/version-diff-view.tsxversion-history-drawer.tsx 集成版本对比currentDoc prop + 对比按钮)
> - **V5-17 A1/A2 AI 反馈闭环**:新增 lib/ai-feedback.tsgenerateLessonPlanFeedback 纯服务端函数4 维度 strengths/improvements/alignment/differentiation含解释性 reason 字段actions-ai.ts 新增 generateLessonPlanFeedbackAction新增 components/ai-feedback-dialog.tsx编辑器工具栏新增「AI 反馈」按钮
> - **V5-18 W6 差异化教学标记**types.ts 新增 DifferentiationLevel 类型 + DIFFERENTIATION_LEVEL_KEYS 常量Block 接口新增 differentiation? 字段node-edit-panel.tsx 添加差异化标记选择器 UI
> - **V5-19 T3 目标-评价一致性校验**:新增 lib/consistency-check.ts纯函数 checkConsistency 输出 ConsistencyResult校验规则缺少 objective/exercise 警告、exercise 无知识点警告、objective 未被评价覆盖警告);新增 components/consistency-check-dialog.tsx编辑器工具栏新增「一致性校验」按钮
> - **V5-20 T4 课标覆盖热力图**:新增 lib/curriculum-coverage.ts纯函数 computeCurriculumCoverage 按 chapterId 分组统计覆盖率,识别 isBlindSpot 教学盲点getHeatLevel 0-4 热力等级);新增 components/curriculum-heatmap.tsx新增 teacher/lesson-plans/heatmap 路由 + loading.tsx + error.tsx
> - **V5-21 A3/A4/A5 AI 差异化模块**:新增 lib/ai-differentiation.ts3 个纯服务端函数generateDifferentiationSuggestions/checkCurriculumAlignment/generateExplainableAssessment复用 ai-feedback.ts 的 createAiChatCompletion + Zod + JSON 提取模式actions-ai.ts 新增 4 个 server actionsgenerateDifferentiationSuggestionsAction/checkCurriculumAlignmentAction/generateExplainableAssessmentAction/getKnowledgePointsForAlignmentAction新增 components/ai-differentiation-dialog.tsx3 Tab 视图:差异化建议/课标核对/可解释评估A4 按教材 ID 按需加载知识点编辑器工具栏新增「AI 差异化」按钮
> - **i18n 扩展**zh-CN/en 同步新增 editor.stage*/editor.differentiation*/editor.consistency*/consistency.*/diff.*/library.*/feedback.*/heatmap.*/aiDifferentiation.*/blackboard.editMode/previewMode/editHint/previewEmpty/untitled
> - **V5-11 R3 协同编辑**需引入新依赖Yjs/Liveblocks或采用轻量协作方案评论+@提醒+版本对比),暂标记为待规划,待用户决策
---
@@ -3893,7 +3922,7 @@ rateLimit(params: RateLimitParams): Promise<RateLimitResult> // audit-P1-6
resetRateLimit(key: string): Promise<void> // audit-P1-6改为 Promise 返回
rateLimitKey(prefix: string, identifier: string): string // 同步纯函数
rateLimitHeaders(result: RateLimitResult): Record<string, string> // 同步纯函数
getRateLimiter(): RateLimiter // audit-P1-6 新增:返回当前进程的限流器实例
getRateLimiter(): Promise<RateLimiter> // audit-P1-6 新增:返回当前进程的限流器实例redis 驱动下动态 import redis-limiter 故为异步
RATE_LIMIT_RULES // 同步常量(含 LOGIN/API/UPLOAD/AI_CHAT/PASSWORD_CHANGE/ONBOARDING_BINDaudit-P1-8 新增 ONBOARDING_BIND: 5次/小时)
// RateLimiter interface (audit-P1-6 新增)
// limit(params: RateLimitParams): Promise<RateLimitResult>

View File

@@ -6443,11 +6443,21 @@
"name": "GraphViewMode",
"type": "type",
"definition": "\"structure\" | \"student-mastery\" | \"class-mastery\"",
"purpose": "Task 7 新增:图谱视图模式",
"purpose": "Task 7 新增:图谱数据视角(结构 / 学生掌握度 / 班级掌握度)",
"usedBy": [
"getKnowledgeGraphDataAction"
]
},
{
"name": "GraphLayoutMode",
"type": "type",
"definition": "\"hierarchical\" | \"force\"",
"purpose": "v4 新增图谱渲染布局hierarchical=分层有向图 ReactFlow+dagreforce=Obsidian 风格力导向图 react-force-graph-2d",
"usedBy": [
"components/knowledge-graph.tsx",
"components/graph-toolbar.tsx"
]
},
{
"name": "MasteryInfo",
"type": "interface",
@@ -6648,7 +6658,17 @@
},
{
"name": "KnowledgeGraph",
"purpose": "知识图谱可视化"
"purpose": "知识图谱可视化v4 新增:支持 hierarchical/force 两种布局模式切换hierarchical=ReactFlow+dagre 分层有向图force=Obsidian 风格力导向图;外层共享状态/详情面板/前置依赖增删对话框)"
},
{
"name": "ForceKnowledgeGraph",
"file": "components/force-graph.tsx",
"purpose": "v4 新增Obsidian 风格力导向图谱组件,基于 react-force-graph-2d + d3-force圆形节点+曲线连接+物理力导向+邻居高亮+拖拽联动;通过 next/dynamic ssr:false 加载避免 SSR canvas/window 报错"
},
{
"name": "GraphToolbar",
"file": "components/graph-toolbar.tsx",
"purpose": "图谱工具栏v4 新增 hierarchical/force 布局模式切换 Select保留视图模式切换/搜索/重置视图)"
},
{
"name": "GraphNodeDetailPanel",
@@ -6693,7 +6713,10 @@
],
"uiDeps": [],
"uiDepsNote": "已通过 render prop 解耦TeacherTextbookReader 已移至 app 层src/app/(dashboard)/teacher/textbooks/[id]/_components/textbooks 模块不再直接 import questions 模块组件",
"npmDeps": ["@xyflow/react", "@dagrejs/dagre", "react-force-graph-2d"],
"npmDepsNote": "v4 新增 react-force-graph-2d基于 d3-force + Canvas实现 Obsidian 风格力导向图谱;通过 next/dynamic ssr:false 加载避免 SSR canvas/window 报错;@xyflow/react + @dagrejs/dagre 用于分层有向图布局",
"knownIssues": [
"v4 新增2026-07-03知识点图谱新增 Obsidian 风格力导向布局force 模式与原分层有向图hierarchical 模式)共存,工具栏可切换;新增组件 force-graph.tsx新增类型 GraphLayoutMode保留全部现有功能掌握度视图/搜索高亮/邻居高亮/前置依赖增删)",
"i18n 覆盖率约 99%v3 新增 notFound/noClassMasteryPermission/close/prerequisiteAddFailed/prerequisiteRemoveFailed 等键data-access 层硬编码英文异常文案已改为 NotFoundError 错误码化)",
"v3 审计修复2026-06-24学生端两个页面添加 requirePermission(Permissions.TEXTBOOK_READ) 显式权限校验",
"v3 审计修复2026-06-24getKnowledgeGraphDataAction 添加学生/家长年级 scope 过滤class-mastery 视图模式限制为 teacher/admin",
@@ -6749,8 +6772,9 @@
"components/graph-kp-node.tsx": 92,
"components/graph-node-detail-panel.tsx": 171,
"components/graph-prerequisite-edge.tsx": 43,
"components/graph-toolbar.tsx": 84,
"components/knowledge-graph.tsx": 356,
"components/graph-toolbar.tsx": 121,
"components/force-graph.tsx": 454,
"components/knowledge-graph.tsx": 408,
"components/knowledge-point-dialogs.tsx": 167,
"components/knowledge-point-list.tsx": 117,
"components/section-error-boundary.tsx": 53,
@@ -20513,6 +20537,76 @@
"name": "suggestKnowledgePoints",
"file": "ai-suggest.ts",
"purpose": "AI 建议知识点(基于课案内容)"
},
{
"name": "autoLayout",
"file": "lib/auto-layout.ts",
"purpose": "V5-8 U2 新增:基于 @dagrejs/dagre 的 DAG 自动布局算法,按 edges 拓扑排序计算 nodes 位置"
},
{
"name": "diffDocuments",
"file": "lib/version-diff.ts",
"purpose": "V5-16 T2 新增:纯函数对比两个 LessonPlanDocument 节点级差异,返回 added/removed/modified/unchanged + changedFields"
},
{
"name": "hasChanges",
"file": "lib/version-diff.ts",
"purpose": "V5-16 T2 新增:判断 VersionDiffResult 是否存在变更"
},
{
"name": "checkConsistency",
"file": "lib/consistency-check.ts",
"purpose": "V5-19 T3 新增:纯函数目标-评价一致性校验,输出 ConsistencyResult缺少 objective/exercise 警告、exercise 无知识点警告、objective 未被评价覆盖警告)"
},
{
"name": "hasConsistencyWarnings",
"file": "lib/consistency-check.ts",
"purpose": "V5-19 T3 新增:判断 ConsistencyResult 是否存在警告"
},
{
"name": "computeCurriculumCoverage",
"file": "lib/curriculum-coverage.ts",
"purpose": "V5-20 T4 新增:纯函数按 chapterId 分组统计教师所有课案对教材知识点的覆盖率,识别 isBlindSpot 教学盲点"
},
{
"name": "getHeatLevel",
"file": "lib/curriculum-coverage.ts",
"purpose": "V5-20 T4 新增根据覆盖率返回热力图颜色等级0-4"
},
{
"name": "generateLessonPlanFeedback",
"file": "lib/ai-feedback.ts",
"purpose": "V5-17 A1/A2 新增AI 反馈闭环纯服务端函数4 维度 strengths/improvements/alignment/differentiation含解释性 reason 字段AI 不可用时返回空结果"
},
{
"name": "generateDifferentiationSuggestions",
"file": "lib/ai-differentiation.ts",
"purpose": "V5-21 A3 新增AI 差异化教学建议生成,按 basic/intermediate/advanced 三层生成建议"
},
{
"name": "checkCurriculumAlignment",
"file": "lib/ai-differentiation.ts",
"purpose": "V5-21 A4 新增AI 课标实时核对,检查课案是否覆盖教材知识点"
},
{
"name": "generateExplainableAssessment",
"file": "lib/ai-differentiation.ts",
"purpose": "V5-21 A5 新增AI 可解释评估,对 exercise 节点给出 conclusion/rationale/suggestion"
},
{
"name": "getLessonPlanSchedules",
"file": "data-access-schedules.ts",
"purpose": "V5-7 W3/W4 新增:查询课案绑定的课时列表"
},
{
"name": "createLessonPlanSchedule",
"file": "data-access-schedules.ts",
"purpose": "V5-7 W3/W4 新增:课案绑定课时"
},
{
"name": "deleteLessonPlanSchedule",
"file": "data-access-schedules.ts",
"purpose": "V5-7 W3/W4 新增:删除课时绑定"
}
],
"actions": [
@@ -20629,6 +20723,60 @@
"permission": "LESSON_PLAN_READ",
"file": "actions.ts",
"purpose": "按 textbookId 获取章节树(供 template-picker 选择章节)"
},
{
"name": "duplicateLessonPlanFormAction",
"permission": "LESSON_PLAN_CREATE",
"file": "actions.ts",
"purpose": "V5-12 R4 新增FormData wrapper 适配 <form action={...}>,内部调用 duplicateLessonPlanAction 后 redirect 到新课案编辑页"
},
{
"name": "getLessonPlanSchedulesAction",
"permission": "LESSON_PLAN_READ",
"file": "actions-schedules.ts",
"purpose": "V5-7 W3/W4 新增:查询课案绑定的课时列表"
},
{
"name": "createLessonPlanScheduleAction",
"permission": "LESSON_PLAN_UPDATE",
"file": "actions-schedules.ts",
"purpose": "V5-7 W3/W4 新增:课案绑定课时"
},
{
"name": "deleteLessonPlanScheduleAction",
"permission": "LESSON_PLAN_UPDATE",
"file": "actions-schedules.ts",
"purpose": "V5-7 W3/W4 新增:删除课时绑定"
},
{
"name": "generateLessonPlanFeedbackAction",
"permission": "LESSON_PLAN_READ + AI_CHAT",
"file": "actions-ai.ts",
"purpose": "V5-17 A1/A2 新增AI 反馈闭环,调用 generateLessonPlanFeedback 生成结构化反馈"
},
{
"name": "generateDifferentiationSuggestionsAction",
"permission": "LESSON_PLAN_READ + AI_CHAT",
"file": "actions-ai.ts",
"purpose": "V5-21 A3 新增AI 差异化教学建议生成"
},
{
"name": "checkCurriculumAlignmentAction",
"permission": "LESSON_PLAN_READ + AI_CHAT",
"file": "actions-ai.ts",
"purpose": "V5-21 A4 新增AI 课标实时核对"
},
{
"name": "generateExplainableAssessmentAction",
"permission": "LESSON_PLAN_READ + AI_CHAT",
"file": "actions-ai.ts",
"purpose": "V5-21 A5 新增AI 可解释评估"
},
{
"name": "getKnowledgePointsForAlignmentAction",
"permission": "LESSON_PLAN_READ",
"file": "actions-ai.ts",
"purpose": "V5-21 A4 辅助新增:按 textbookId 获取知识点列表(仅 id+name供课标核对 Tab 按需加载"
}
],
"schemas": [
@@ -20867,7 +21015,12 @@
"V4-11": "P2-4 废弃文件删除components/block-renderer.tsx@deprecated无源码引用删除",
"V4-12": "P2-5 anchor-injector regex 一致性markdownToPlainText 的 /^>\\s+/gm 改为 /^\\s*>\\s+/gmskipPatterns 5 个 regex 统一添加 g 标志,与 markdownToPlainText 保持一致",
"V4-13": "P2-6 Zustand store 拆 slicehooks/use-lesson-plan-editor.ts 从 303 行单体 store 拆分为 3 个独立 slice——hooks/editor-slice.ts文档结构+文档操作)/hooks/selection-slice.ts选中状态/hooks/version-slice.ts版本与保存状态主文件重写为 25 行薄层,组合 3 个 slice 并导出 EditorState 类型",
"V4-14": "type-guards 导出补全lib/type-guards.ts 的 VALID_QUESTION_TYPES 常量从模块私有改为 export供 inline-question-editor.tsx 复用,消除重复定义)"
"V4-14": "type-guards 导出补全lib/type-guards.ts 的 VALID_QUESTION_TYPES 常量从模块私有改为 export供 inline-question-editor.tsx 复用,消除重复定义)",
"V5-1": "自动保存失败 UI 兜底version-slice.ts 新增 saveError/isOnline 状态 + setSaveError/setOnline 方法lesson-plan-editor.tsx 自动保存失败时 toast 提示 + 设置 saveError断网时不触发保存请求监听 window online/offline 事件 toast 提示saveError 时显示重试按钮,恢复时提示已恢复",
"V5-2": "撤销/重做:新增 hooks/history-slice.tspast/future 栈50 步上限canUndo/canRedo/pushHistory/undo/redo/clearHistory 方法editor-slice.ts 所有 mutation 方法setTitle/addNode/updateNode/removeNode/updateTextbookContent/addAnchor/removeAnchor/updateAnchor/connect/disconnect/setEdges包装 pushHistoryupdateNodePosition 除外(拖拽过程中由调用方在 onDragStart 时推入version-slice hydrate/replaceDoc 调用 clearHistorylesson-plan-editor.tsx 顶部新增 Undo/Redo 按钮 + Ctrl/Cmd+Z 撤销 + Ctrl/Cmd+Shift+Z 或 Ctrl/Cmd+Y 重做快捷键",
"V5-3": "发布前作业单预览publish-homework-dialog.tsx 改为 3 步流程step=select 选班级+时间 → step=preview 预览题目+总分+班级数 → step=confirm 确认发布),第二步显示题目列表(题型/来源/题干预览/分值)+汇总信息(班级数/题目数/总分),第三步显示最终确认信息+警告文案exercise-block.tsx 调用 PublishHomeworkDialog 时传入 items={data.items}",
"V5-4": "导出/打印:新增 lib/export.tsflattenLessonPlanForPrint 函数,将画布式 LessonPlanDocument 扁平化为 PrintableLessonPlan 线性结构,支持 detailed/concise 两种 variantconcise 仅含 objective/new_teaching/exercise/homework+ components/print-view.tsx打印视图组件详细版/简洁版切换 + 调用 window.print() 通过浏览器原生能力保存为 PDF + print: CSS 媒体查询隐藏工具栏 + 页眉含教材/教师/班级/教学时长/最后保存时间 + break-inside-avoid 防止段落跨页lesson-plan-editor.tsx 新增 printablePlan useMemo 构造 + 导出按钮 + PrintView 渲染",
"V5-5": "多媒体嵌入 + 我的素材库types.ts RichTextBlockData 新增 attachments?: RichTextAttachment[] 字段 + RichTextAttachment 类型attachmentId/fileId/displayName/kind: image|audio|video|file/url/mimeType?rich-text-block.tsx 集成 @tiptap/extension-imageImage.configure inline:false allowBase64:false+ 新增附件入口按钮 + 已嵌入附件列表渲染(非图片附件列表 + 图片附件缩略图,含删除按钮)+ 图片附件通过 editor.commands.setImage 直接插入富文本;新增 components/attachment-picker.tsx素材库 picker复用 use-file-upload hook 调用 /api/upload + 调用 service.createLessonPlanAttachment 落库到 M6 lessonPlanAttachments 表 + 列出 service.getLessonPlanAttachments + 删除 service.deleteLessonPlanAttachment + inferAttachmentKind 工具函数LessonPlanDataService 接口新增 getLessonPlanAttachments/createLessonPlanAttachment/deleteLessonPlanAttachment 三个方法 + LessonPlanAttachmentOption 导出类型default-data-service.ts 实现三个方法DB 层 Date 转 ISO string 以匹配接口类型BlockRenderProps 新增 planId? 字段NodeEditPanel 新增 planId prop 透传lesson-plan-editor.tsx NodeEditPanel 调用传入 planId新增依赖 @tiptap/extension-imagefiles/types.ts FileTargetType 新增 'lesson_plan' 类型"
}
},
"error-book": {
@@ -22029,6 +22182,13 @@
"columns": 6,
"indexes": 2,
"foreignKeys": 2
},
"lessonPlanSchedules": {
"owner": "lesson-preparation",
"description": "V5-7 W3/W4 课案绑定课时表(planId+classId+lessonDate 唯一约束2026-07-03 新增)",
"columns": 6,
"indexes": 3,
"foreignKeys": 2
}
}
},
@@ -25438,11 +25598,45 @@
"duplicateLessonPlanAction",
"saveAsTemplateAction",
"suggestKnowledgePointsAction",
"publishLessonPlanHomeworkAction"
"publishLessonPlanHomeworkAction",
"getLessonPlanSchedulesAction",
"createLessonPlanScheduleAction",
"deleteLessonPlanScheduleAction",
"generateLessonPlanFeedbackAction",
"generateDifferentiationSuggestionsAction",
"checkCurriculumAlignmentAction",
"generateExplainableAssessmentAction",
"getKnowledgePointsForAlignmentAction"
],
"permission": "lesson_plan:update",
"permissionRead": "lesson_plan:read",
"description": "编辑课案页面权限requirePermission(LESSON_PLAN_UPDATE);只读访问需 LESSON_PLAN_READ"
"description": "编辑课案页面权限requirePermission(LESSON_PLAN_UPDATE);只读访问需 LESSON_PLAN_READV5-7 新增课时绑定 actionsV5-17/V5-21 新增 AI 反馈/差异化 actions"
},
"/teacher/lesson-plans/library": {
"component": "LibraryPage",
"type": "server",
"module": "lesson-preparation",
"method": "GET",
"dataAccess": [
"lesson-preparation/data-access.getLessonPlans"
],
"actions": [
"duplicateLessonPlanFormAction"
],
"permission": "lesson_plan:read",
"description": "V5-12 R4 新增校内课案库页面展示其他教师发布的课案支持一键复制权限requirePermission(LESSON_PLAN_READ)"
},
"/teacher/lesson-plans/heatmap": {
"component": "HeatmapPage",
"type": "server",
"module": "lesson-preparation",
"method": "GET",
"dataAccess": [
"lesson-preparation/data-access.getLessonPlans",
"textbooks/data-access.getKnowledgePointsByTextbookId"
],
"permission": "lesson_plan:read",
"description": "V5-20 T4 新增课标覆盖热力图页面统计教师所有课案对教材知识点的覆盖情况权限requirePermission(LESSON_PLAN_READ)"
},
"/teacher/error-book": {
"component": "TeacherErrorBookPage + SubjectTabs + ClassFilter + AnalyticsStatsCards + ClassErrorBarChart + KnowledgePointWeaknessChart + ChapterWeaknessChart + GroupedStudentErrorTable + TopWrongQuestions",

View File

@@ -0,0 +1,289 @@
# 备课模块审计报告 v5
> 审计日期2026-07-03
> 审计范围:`src/modules/lesson-preparation/` 场景覆盖度维度(区别于 v4 的架构合规维度)
> 审计依据:用户实际备课工作流反馈 + v4 审计报告 + K12 行业产品对标Planboard / Nearpod / Common Curriculum
> 前序报告:`lesson-preparation-audit-report-v4.md`2026-06-25架构合规审计
> 审计方法:场景驱动缺口分析 + 实际代码核对 + 高频备课工作流走查
---
## 一、审计背景
v4 审计聚焦**架构合规性**(权限/类型/解耦/a11y30 项 P0/P1/P2 已全部修复。M1-M12 中长期计划已**部分实施**M1 课标 / M2 评论 / M3 审核 / M4 课程地图 / M5 形成性 / M6 附件表 / M8 AI 评估 / M9 日历 / M10 分析 / M11 diff / M12 代课)。
但用户反馈显示:**M1-M12 虽建了数据层UI 集成度不够**M6 附件表无 UI、M9 日历不绑课表、M2 评论无协同编辑),且**完全遗漏了 4 项核心能力**(导出/打印、撤销/重做、多媒体嵌入、发布前预览)。
v5 审计聚焦"场景覆盖度"维度,对照教师日常备课工作流识别缺口。
---
## 二、教师备课工作流与模块覆盖度
### 2.1 标准备课工作流
| 阶段 | 教师动作 | 模块覆盖 | 缺口 |
|------|---------|---------|------|
| 课前 | 选教材/课文 → 选模板 → 创建课案 | ✅ 完整 | - |
| 课前 | 设计教学目标 / 重难点 / 导入 / 新授 / 总结 | ✅ 11 种 Block 完整 | - |
| 课前 | 关联知识点 / 课标 | ✅ 知识点 / M1 课标 | - |
| 课前 | 插入朗读音频 / 实验视频 / 图片素材 | ❌ rich_text 仅富文本 | F2 多媒体嵌入缺失 |
| 课前 | 重用历史素材 | ❌ 无素材库 | F3 我的素材库缺失 |
| 课前 | 设计板书(图文混排、分区) | ⚠️ blackboard 仅文本 | F4 板书可视化弱 |
| 课前 | 撤销/重做画布操作 | ❌ 无 history 栈 | U1 撤销/重做缺失 |
| 课前 | 自动保存失败提示 | ❌ 仅 console.error | S1 UI 兜底缺失 |
| 课前 | 题库选题 → 一键发布作业 | ⚠️ 无预览步骤 | W2 发布前预览缺失 |
| 课前 | 导出 PDF / 打印教案 | ❌ 完全缺失 | F1 导出/打印缺失 |
| 课中 | 学生查看发布课案 | ✅ 只读视图 | - |
| 课后 | 教学反思 + 二次备课 | ⚠️ reflection 节点存在,无锁定/diff | T2 反思闭环不完整 |
### 2.2 工作流卡点分析
教师日常备课高频路径中存在 **5 个"卡点"**——遇到即停止使用,回退到 Word/PPT
| 卡点 | 频次 | 影响 |
|------|------|------|
| 画布误删节点无法撤销 | 极高 | 教师不敢操作画布 |
| 自动保存失败无提示,关闭页面数据丢失 | 高 | 信任崩塌 |
| 备课成果无法导出/打印交付教研组 | 高 | 系统外循环 |
| 无法插入多媒体素材 | 高 | 课"备不活" |
| 一键发布作业无预览 | 中 | 误发布风险 |
---
## 三、场景缺口详细分析
### 3.1 S1 - 自动保存失败 UI 兜底(🔴 极紧急)
- **位置**[lesson-plan-editor.tsx](file:///e:/Desktop/CICD/src/modules/lesson-preparation/components/lesson-plan-editor.tsx) L97-116
- **现状**:自动保存失败仅 `console.error("[LessonPlanEditor] auto-save failed", e)`UI 无任何提示
- **后果**
- 教师关闭页面时数据丢失beforeunload 仅检查 isDirty不区分"保存失败"与"未触发保存"
- 断网场景下教师继续编辑,所有改动静默丢失
- **违反需求**:用户 §五"怕丢数据:必须要有强自动保存,以及断网恢复提示"
### 3.2 U1 - 撤销/重做(🔴 极紧急)
- **位置**[editor-slice.ts](file:///e:/Desktop/CICD/src/modules/lesson-preparation/hooks/editor-slice.ts) 全文
- **现状**Zustand store 无 history 栈,所有 mutation 直接 set
- **后果**
- 画布上误删一个节点,只能去版本抽屉回滚到 30 分钟前的状态
- 教师不敢操作画布,回退到列表式备课
- **违反需求**:用户 §三.5"撤销/重做:画布操作没有撤销,简直没法用。必须支持至少 50 步撤销"
### 3.3 W2 - 发布前作业单预览(🔴 极紧急)
- **位置**[publish-homework-dialog.tsx](file:///e:/Desktop/CICD/src/modules/lesson-preparation/components/publish-homework-dialog.tsx) 全文
- **现状**:对话框仅选班级 + 时间,点击"发布"直接调用 service.publishLessonPlanHomework
- **缺失**
- 无题目列表预览(题干/选项/答案/分值)
- 无总分预览
- 无班级学生数提示
- 无"返回修改"步骤
- **后果**:一键发布到学生/家长端,误发布无法收回
- **违反需求**:用户 §五"怕误发布:发布前必须有预览"
### 3.4 F1 - 导出/打印(🔴 极紧急)
- **位置**:全模块无导出/打印相关代码
- **现状**:画布做得再好,备课成果无法走出系统
- **缺失**
- 无 PDF 导出
- 无打印视图
- 无"详细版/简洁版"切换
- **后果**:教研组检查无纸质交付,教师回退到 Word
- **违反需求**:用户 §二.1"没有导出,备课成果无法走出系统"
### 3.5 F2/F3 - 多媒体嵌入 + 我的素材库(🔴 极紧急)
- **位置**
- [rich-text-block.tsx](file:///e:/Desktop/CICD/src/modules/lesson-preparation/components/blocks/rich-text-block.tsx) L29-45 仅用 Tiptap StarterKit + Placeholder
- [data-access-attachments.ts](file:///e:/Desktop/CICD/src/modules/lesson-preparation/data-access-attachments.ts) M6 数据层已建,**无 UI 集成**
- [actions-attachments.ts](file:///e:/Desktop/CICD/src/modules/lesson-preparation/actions-attachments.ts) Server Actions 已建,**无组件调用**
- **现状**rich_text 节点不支持图片/音视频M6 附件表与 UI 完全断链
- **后果**
- 教师无法插入朗读音频 / 实验视频 / PPT 截图
- 每次都得从本地重新上传,无沉淀
- **违反需求**:用户 §二.2"这决定了我能不能把课'备活'"
---
## 四、改进方案与实施
### 4.1 第一阶段实施v5 P0本次完成
| ID | 缺口 | 实施方案 | 验收标准 |
|----|------|---------|---------|
| V5-1 | S1 自动保存失败 UI 兜底 | editor 添加 saveError 状态 + toast 提示 + 在线状态监听 + 重试按钮 | 断网时 toast 显示"保存失败",恢复时 toast 显示"已恢复在线" |
| V5-2 | U1 撤销/重做 | 新增 `hooks/history-slice.ts`past/future 栈50 步上限)+ 编辑器顶部 Undo/Redo 按钮 + Cmd/Ctrl+Z / Cmd+Shift+Z 快捷键 | 误删节点后 Cmd+Z 可恢复 |
| V5-3 | W2 发布前作业单预览 | publish-homework-dialog 改为 3 步流程(选班级 → 预览题目+总分+学生数 → 确认发布) | 发布前可见所有题干、选项、答案、分值、班级学生数 |
| V5-4 | F1 导出/打印 | 新增 `lib/export.ts`(文档扁平化)+ `components/print-view.tsx`(打印视图)+ 编辑器"导出/打印"按钮 + 详细版/简洁版切换 | 浏览器打印对话框可保存为 PDF含教材/教师/班级信息 |
| V5-5 | F2/F3 多媒体嵌入 + 素材库 | rich-text-block 集成 Tiptap Image 扩展 + 新增 `components/attachment-picker.tsx` 附件库 picker + 集成 M6 附件表 | 可在 rich_text 中插入图片,从素材库选择已有附件 |
### 4.2 第二阶段计划v5 P1本次仅记录
| ID | 缺口 | 优先级 |
|----|------|--------|
| V5-6 | W1 题库组卷预览(题干展开) | 🟠 |
| V5-7 | W3/W4 课案绑定课时 | 🟠 |
| V5-8 | U2 画布自动布局 | 🟠 |
| V5-9 | F5 教材模糊搜索 + 最近使用 | 🟠 |
| V5-10 | P1 大课案画布性能压测 | 🟠 |
### 4.3 第三阶段计划v5 P2本次仅记录
| ID | 缺口 | 优先级 |
|----|------|--------|
| V5-11 | R3 协同编辑Yjs/Liveblocks 评估) | 🟡 |
| V5-12 | R4 校内课案库 | 🟡 |
| V5-13 | P3 移动端只读视图 | 🟡 |
| V5-14 | F4 板书可视化工具 | 🟡 |
| V5-15 | T1 教学阶段分组 | 🟡 |
| V5-16 | T2 反思闭环 | 🟡 |
| V5-17 | A1/A2 AI 反馈闭环 + 解释性 | 🟡 |
### 4.4 第四阶段计划v5 P3本次仅记录
| ID | 缺口 | 优先级 |
|----|------|--------|
| V5-18 | W6 差异化教学标记 | 🟢 |
| V5-19 | T3 目标-评价一致性 | 🟢 |
| V5-20 | T4 教师端课标热力图 | 🟢 |
| V5-21 | A3/A4/A5 AI 差异化生成 + 课标实时核对 + 评估可解释 | 🟢 |
---
## 五、架构影响
### 5.1 新增文件
| 文件 | 用途 |
|------|------|
| `hooks/history-slice.ts` | Zustand history slicepast/future 栈50 步上限) |
| `lib/export.ts` | 文档扁平化导出工具(详细版/简洁版) |
| `components/print-view.tsx` | 打印视图组件(含教材/教师/班级信息) |
| `components/attachment-picker.tsx` | 附件库 picker集成 M6 附件表) |
### 5.2 修改文件
| 文件 | 修改内容 |
|------|---------|
| `hooks/use-lesson-plan-editor.ts` | 组合 history slice |
| `hooks/editor-slice.ts` | mutation 方法包装 history 推送 |
| `components/lesson-plan-editor.tsx` | 自动保存失败 UI 兜底 + Undo/Redo 按钮 + 快捷键 + 导出按钮 |
| `components/publish-homework-dialog.tsx` | 3 步发布流程(选班级 → 预览 → 确认) |
| `components/blocks/rich-text-block.tsx` | 集成 Tiptap Image 扩展 + 附件库入口 |
| `shared/i18n/messages/zh-CN/lesson-preparation.json` | 新增 undo/redo/export/print/saveError 等键 |
| `shared/i18n/messages/en/lesson-preparation.json` | 同步英文翻译 |
### 5.3 架构图同步
修改 `docs/architecture/004_architecture_impact_map.md` §2.27 章节末尾追加"V5 场景缺口修复"小节。
修改 `docs/architecture/005_architecture_data.json` modules.lesson_preparation.auditFixes 新增 V5-1 至 V5-5 条目。
---
## 六、验收标准
-`npm run lint` 零错误
-`npx tsc --noEmit` 零错误
- ✅ 单文件行数:组件 ≤ 500hooks ≤ 80工具函数 ≤ 40
- ✅ 无 `any`、无 `as` 断言(除 unknown 收窄)
- ✅ 全量 i18nzh-CN + en
- ✅ 架构文档 004/005 已同步
-`docs/troubleshooting/known-issues.md` 已记录
---
**v5 审计完成。本次实施第一阶段 V5-1 至 V5-5 共 5 项场景缺口修复。**
---
## 七、V5 第二阶段实施结果2026-07-03 续)
### 7.1 已完成清单
| ID | 缺口 | 状态 | 实施摘要 |
|----|------|------|---------|
| V5-6 | W1 题库组卷预览 | ✅ | exercise-block.tsx 增加组卷预览模式 |
| V5-7 | W3/W4 课案绑定课时 | ✅ | 新增 data-access-schedules.ts + actions-schedules.ts + schedule-dialog.tsx + lesson_plan_schedules 表 |
| V5-8 | U2 画布自动布局 | ✅ | 新增 lib/auto-layout.ts@dagrejs/dagre,复用已安装依赖) |
| V5-9 | F5 教材模糊搜索 + 最近使用 | ✅ | template-picker.tsx 增加客户端模糊搜索 + localStorage 最近使用 |
| V5-10 | P1 大画布性能优化 | ✅ | node-editor.tsx ReactFlow onlyRenderVisibleElements + zoom 限制 |
| V5-12 | R4 校内课案库 | ✅ | 新增 teacher/lesson-plans/library 路由 + duplicateLessonPlanFormAction |
| V5-13 | P3 移动端只读视图 | ✅ | 新增 lesson-plan-mobile-view.tsx + useMediaQuery 切换 |
| V5-14 | F4 板书可视化工具 | ✅ | blackboard-block.tsx 增加轻量级可视化预览(不引入新库,纯 CSS + 文本解析) |
| V5-15 | T1 教学阶段分组 | ✅ | types.ts TeachingStage 类型 + node-edit-panel 选择器 |
| V5-16 | T2 反思闭环 | ✅ | 新增 lib/version-diff.ts 纯函数 + version-diff-view 组件 + 抽屉集成 |
| V5-17 | A1/A2 AI 反馈闭环 | ✅ | 新增 lib/ai-feedback.ts 纯服务端函数 + ai-feedback-dialog + 工具栏集成 |
| V5-18 | W6 差异化教学标记 | ✅ | types.ts DifferentiationLevel 类型 + node-edit-panel 选择器 |
| V5-19 | T3 一致性校验 | ✅ | 新增 lib/consistency-check.ts 纯函数 + consistency-check-dialog + 工具栏集成 |
| V5-20 | T4 课标热力图 | ✅ | 新增 lib/curriculum-coverage.ts 纯函数 + curriculum-heatmap + teacher/lesson-plans/heatmap 路由 |
| V5-21 | A3/A4/A5 AI 差异化 | ✅ | 新增 lib/ai-differentiation.ts 3 个纯服务端函数 + ai-differentiation-dialog3 Tab + 4 个 server actions + 工具栏集成 |
### 7.2 待规划
| ID | 缺口 | 状态 | 备注 |
|----|------|------|------|
| V5-11 | R3 协同编辑 | 🟡 长远计划 | 详见 §7.5 Yjs 方案评估2026-07-03 评估,因架构改造复杂度高暂不实施) |
### 7.3 i18n 修复
- 修复 zh-CN/en lesson-preparation.json 重复键问题JSON 后者覆盖前者)
- 新增命名空间:`editor.stage*`/`editor.differentiation*`/`editor.consistency*`/`consistency.*`/`diff.*`/`library.*`/`feedback.*`/`heatmap.*`/`aiDifferentiation.*`/`blackboard.editMode/previewMode/editHint/previewEmpty/untitled`
### 7.4 验证结果
-`npx tsc --noEmit` 零错误
- ✅ 本次修改的 5 个文件ai-differentiation-dialog/blackboard-block/actions-ai/lesson-plan-editor/ai-differentiation lib`npx eslint` 零错误
- ✅ 架构文档 004/005 已同步 V5-6~V5-21
-`docs/troubleshooting/known-issues.md` 新增"V5 第二阶段 V5-6~V5-21 通用规则"小节
**V5 第二阶段完成 15 项V5-6~V5-21 除 V5-11V5-11 作为长远计划记录于 §7.5。**
### 7.5 V5-11 R3 协同编辑长远规划Yjs + y-websocket 方案)
**决策**2026-07-03 评估,因架构改造复杂度高,暂不实施,作为长远计划。
#### 7.5.1 Yjs 工作原理(澄清)
Yjs 是 **CRDT无冲突复制数据类型** 库,**不是邮箱/消息系统**,而是**实时状态同步**机制。当 A 老师在编辑器输入"导入"B 老师的屏幕上**立刻**出现"导入"——这是实时同步,不是发消息。
- **Yjs**CRDT 数据结构库,保证多端最终一致性
- **y-websocket**:传输层,需要独立的 WebSocket 服务器作为中转
- **y-prosemirror**Yjs 与 ProseMirrorTiptap 底层)的绑定,让富文本编辑器支持多人光标
#### 7.5.2 与当前项目的关键冲突
| 冲突点 | 当前项目 | Yjs 要求 |
|--------|---------|---------|
| 服务器类型 | Next.js HTTP | 需独立 WebSocket 服务器进程 |
| 持久化 | Drizzle ORM + MySQL | Yjs document 状态需独立持久化LevelDB 或自定义 adapter |
| 权限校验 | Server Actions + requirePermission | WS 连接时需校验 JWT/session |
| 编辑器状态 | Zustand storeeditor-slice | Yjs document 作为真相源Zustand 降级为视图层 |
| 数据结构 | LessonPlanDocument JSON | Yjs.XmlFragmentTiptap 文档)或 Yjs.Map |
#### 7.5.3 推荐架构(未来实施时)
- **WS 服务器部署**:项目内独立进程(`server/ws-server.ts``npm run ws` 启动,生产环境用 PM2/Docker 管理)
- **协同范围**:仅 RichTextBlockTiptap节点实现多人实时协同其他节点保持单人编辑
- **持久化策略**双写——Yjs document 作为实时层,每隔 N 秒(或用户离开时)将状态序列化为 JSON 写入 `lessonPlans.content`,兼容现有数据结构
- **权限校验**WS 连接握手时校验 JWT按 planId 校验 `LESSON_PLAN_UPDATE` 权限
#### 7.5.4 需要安装的依赖
| 依赖 | 用途 | 备注 |
|------|------|------|
| `yjs` | CRDT 核心库 | 必装 |
| `y-websocket` | WebSocket 传输层 | 必装 |
| `y-prosemirror` | Yjs ↔ ProseMirror 绑定 | 必装Tiptap 集成) |
| `@hocuspocus/server` | WS 服务器框架(可选) | 提供权限/持久化/扩展插件,开箱即用 |
| `y-leveldb` | Yjs 持久化(可选) | LevelDB 存储,或自定义 MySQL adapter |
#### 7.5.5 替代方案
若未来评估认为 Yjs 复杂度过高,可考虑**轻量协作方案**作为替代:
- 不引入实时协同库
- 复用现有 messaging/notifications 模块 + V5-16 版本对比
- 实现「Block 级评论 + @提醒 + 版本对比」
- 无需新依赖,开发快,与项目现有架构契合