# P1 数据模型对拍报告

| 项目 | 内容 |
|---|---|
| 日期 | 2026-08-22 |
| 对拍物 | 《v0.2样例JSON.md》（P0 交付；字段以该文件为准） |
| 结构要点 | 《设计说明书-v0.2.md》§4.2 / §6.3 |
| Schema | `prisma/schema.prisma` + 迁移 `20260822014730_v02_models` |
| JSON 存储 | Prisma 5.22 SQLite 连接器**不支持** `Json` 类型；一律用 `String` 存 JSON 文本（schema 文件头与字段注释写明结构） |

**结论：与样例 JSON 字段名全部一致（95/95 静态对拍通过；17/17 入库回读通过）。**

---

## 1. 存储约定（对拍前先冻结）

教案 / PPT / 材料不拆成三张子表，写入 `lesson_plans.draft_content` 与 `lesson_plans.confirmed_content`（草稿与定稿分存），JSON 形状为：

```json
{ "plan": { /* 样例一 */ }, "ppt": { /* 样例二 */ }, "materials": { /* 样例三 */ } }
```

问卷题目写入 `questionnaires.questions`（数组）。学号**不是**题目，见第 5 节。

---

## 2. 教案 `lesson_plan`（样例一 → `draft_content.plan` / `confirmed_content.plan`）

| 样例字段 | 落点 | 结果 |
|---|---|---|
| `lesson_title` | JSON 键 | 一致 |
| `lesson_type` | JSON 键 | 一致 |
| `class_profile_summary` | JSON 键 | 一致 |
| `objectives[]` | JSON 数组 | 一致 |
| `objectives[].id` | JSON 键 | 一致 |
| `objectives[].text` | JSON 键 | 一致 |
| `objectives[].bloom` | JSON 键 | 一致 |
| `objectives[].literacy_dim` | JSON 键 | 一致 |
| `objectives[].success_criteria` | JSON 键 | 一致 |
| `objectives[].course_outcome_ids` | JSON 键（引用 `course_outcomes.code`，如 `"O1-2"`） | 一致 |
| `core_plan.{core,scaffold,extension}` | JSON 对象 | 一致（以样例 `core_plan` 为准，不用 `core_plus_extension` 作键名） |
| `lesson_events[]` | JSON 数组 | 一致 |
| `lesson_events[].phase` | `pre \| in \| post` | 一致 |
| `lesson_events[].duration` | JSON 键 | 一致 |
| `lesson_events[].teacher_move` | JSON 键 | 一致 |
| `lesson_events[].student_task` | JSON 键 | 一致 |
| `lesson_events[].interaction` | JSON 键 | 一致 |
| `lesson_events[].prompt_questions` | JSON 键 | 一致 |
| `hook` | JSON 键 | 一致 |
| `relevance_to_major` | JSON 键 | 一致 |
| `formative_checks` | JSON 键 | 一致 |
| `sizheng_integration[]` | JSON 数组（非单对象） | 一致 |
| `sizheng_integration[].element / role / organic_link / student_dilemma / position / avoid_preaching` | JSON 键；`role` 与库表 `knowledge_point_sizheng.role` 同为 `content \| infusion` | 一致 |
| `case_plan.{case_id,usage,discussion_ladder}` | JSON 对象 | 一致 |
| `timeline_check.{total_minutes,lesson_minutes,overload}` | JSON 对象 | 一致 |
| `citations[]` | JSON 数组 | 一致 |
| `citations[].source_type` | 闭集：`case \| knowledge_point \| hotspot \| teacher_url \| textbook_section` | 一致 |
| `citations[].source_id` | JSON 键 | 一致 |
| `citations[].claim_unverified` | JSON 键 | 一致 |
| `difficulty_notes` | JSON 键 | 一致 |
| `adaptation_log[{evidence,decision}]` | 教案 JSON 内保留同名字段；表另有列 `lesson_plans.adaptation_log`（确认页只读） | 一致 |

课时知识库目标 `lessons.objectives` 使用同一套键（`id/text/bloom/literacy_dim/success_criteria/course_outcome_ids`），另含 `type`（知识/能力/价值-伦理），与 A1/M4.1 章—课时目标结构对齐。

---

## 3. PPT `slides`（样例二 → `draft_content.ppt` / `confirmed_content.ppt`）

| 样例字段 | 落点 | 结果 |
|---|---|---|
| `theme` | JSON 键 | 一致 |
| `lesson_type` | JSON 键（样例为 `case_discussion`；§6.3 顶层误写 `slide_type`，**以样例为准**） | 一致 |
| `slides[]` | JSON 数组 | 一致 |
| `slides[].slide_type` | `cover \| agenda \| concept \| diagram \| case \| compare \| quiz \| sizheng \| summary \| activity` | 一致 |
| `slides[].title` | JSON 键 | 一致 |
| `slides[].bullets` | JSON 键 | 一致 |
| `slides[].visual` | JSON 键 | 一致 |
| `slides[].speaker_notes` | JSON 键 | 一致 |
| `slides[].diagram_spec` | 可选对象 | 一致 |
| `diagram_spec.kind` | `flow \| compare \| pros_cons` | 一致（样例含 `flow`、`compare`） |
| `diagram_spec.nodes` | `flow` 型 | 一致 |
| `diagram_spec.left` / `right` | `compare` 型 | 一致 |

schema 注释超集（§6.3 有、样例未出现，不构成字段名冲突）：`highlight`、`takeaway`。

---

## 4. 材料 `materials`（样例三 → `draft_content.materials` / `confirmed_content.materials`）

| 样例字段 | 落点 | 结果 |
|---|---|---|
| `cases[]` | JSON 数组 | 一致 |
| `cases[].case_id / title / summary / discussion_questions / sizheng_angle / citations` | JSON 键 | 一致 |
| `exercises[]` | JSON 数组 | 一致 |
| `exercises[].task_type` | 样例：`recall \| explain \| case_ruling \| authentic_task` | 一致 |
| `exercises[].question` | JSON 键 | 一致 |
| `exercises[].options` | 可选（再认题） | 一致 |
| `exercises[].answer` | JSON 键 | 一致 |
| `exercises[].rubric[{criterion,level}]` | 裁决/真实性任务 | 一致 |
| `exercises[].tier` | 样例：`required \| extension` | 一致 |
| `exercises[].objective_ids` | 挂接教案目标 id（如 `"o1"`） | 一致 |
| `exercises[].difficulty` | `easy \| medium \| hard` | 一致 |
| `exercises[].knowledge_point` | JSON 键 | 一致 |

schema 注释超集（§6.3 / M4.12，样例未出现）：`task_type=classroom_speech`、`tier=optional`、`evidence_type`、`attachments[]`。

案例库表 `cases` 另有结构化列：`case_type / dilemma / stakeholders / teaching_note / time_needed / literacy_focus / source_case_id`；知识点与模板改为关联表 `case_knowledge_points`、`case_templates`（不再用 JSON 承担参照完整性）。

---

## 5. 学情问卷（样例四 → `questionnaires.questions`）

| 样例字段 | 落点 | 结果 |
|---|---|---|
| `title` / `description` | 表列 `questionnaires.title` / `description`；蓝图 JSON 亦可含同名字段 | 一致 |
| `module_ids` | 蓝图顶层；必测 A–F | 一致 |
| `questions[].id` | JSON 键 | 一致 |
| `questions[].module_id` | ∈ `{A,B,C,D,E,F}` | 一致 |
| `questions[].profile_field` | 如 `misconception_agency` | 一致 |
| `questions[].blueprint_locked` | 布尔；A–F 锁定不可删 | 一致 |
| `questions[].type` | `single \| multi \| scale \| text` | 一致 |
| `questions[].question` | JSON 键 | 一致 |
| `questions[].options` | 可选 | 一致 |
| `questions[].required` | JSON 键 | 一致 |
| 学号 | **`questionnaire_responses.student_no` 可空独立列**，不在 `questions[]` | 一致 |

样例全部 9 题的 `profile_field` 均不是 `student_no`。表另有 `status / token / expires_at / max_submissions`（及 v0.1 保留的 `deadline`）。

---

## 6. `course_outcomes`（literacy_dim / is_core）

| 样例/设计字段 | 落点 | 结果 |
|---|---|---|
| 目标编码（如 `O1-2`） | 列 `course_outcomes.code`；教案 `course_outcome_ids` 引用编码 | 一致 |
| `literacy_dim` | **列** `literacy_dim`（素养五维之一） | 一致 |
| `is_core` | **列** `is_core`（BOOLEAN；core 不可删） | 一致 |
| `text` | 列 `text` | 一致 |

三级目标：课程级走 `course_outcomes` 表；章级走 `chapters.objectives` JSON；课时级走 `lessons.objectives` JSON（禁止纯自由文本作为唯一目标）。

---

## 7. 入库回读（用样例 JSON 实写 SQLite 再读出）

写入 `lesson_plans.draft_content`、`questionnaires.questions`、`course_outcomes`、`questionnaire_responses.student_no=NULL` 后读回：

| 检查 | 结果 |
|---|---|
| `draft.plan.objectives[].course_outcome_ids` | 通过 |
| `draft.plan.lesson_events[0].phase === "pre"` | 通过 |
| `draft.plan.sizheng_integration[0].role === "infusion"` | 通过 |
| `draft.plan.citations[0].source_type === "case"` | 通过 |
| `draft.ppt.slides[0].slide_type === "cover"` | 通过 |
| `draft.ppt` 含 `diagram_spec.kind === "flow"` | 通过 |
| `draft.materials.exercises[0].task_type === "recall"` | 通过 |
| `rubric` / `tier=required` / `objective_ids=["o1"]` | 通过 |
| `questions[0].module_id === "A"` | 通过 |
| `questions[0].profile_field === "misconception_agency"` | 通过 |
| `questions[0].blueprint_locked === true` | 通过 |
| `course_outcomes.literacy_dim === "概念理解"` | 通过 |
| `course_outcomes.is_core === true` | 通过 |
| `student_no` 可空（`NULL`） | 通过 |
| `users.admin` 仍在 | 通过 |

临时对拍数据已删除，库中无残留。

---

## 8. 设计书 §4.2 关键列（非样例 JSON、但 P1 范围要求）

| 项 | Schema | 结果 |
|---|---|---|
| 知识点 `content_depth` / `bloom_range` / `misconceptions` | `knowledge_points` 列 | 有 |
| `knowledge_prereq(from_kp_id, to_kp_id)` | 表 + 唯一约束 | 有 |
| 思政 `theme` / `natural_example` / `forbidden_example` | `sizheng_elements` | 有 |
| `knowledge_point_sizheng.role` = `content \| infusion` | 列 + 唯一(kp, element, role) | 有 |
| `major_templates.default_content_depth` / `default_ppt_theme` | 列（原 `default_depth` 改名） | 有 |
| `template_rules` PCK：`literacy_focus` / `omit_items` / `permitted_tools` / `expected_student_performance` / `preferred_lesson_type` / `media_strategy` | 列 | 有 |
| `classes.profile` 版本化 + `profile_revision_log` | String JSON | 有 |
| `chaoxing_course_id` / `chaoxing_class_id` | 可空列 | 有 |
| `lesson_plans` 七态 | `not_started → plan_draft → plan_confirmed → ppt_draft → ppt_confirmed → materials_draft → completed` | 有 |
| `draft_content` / `confirmed_content` 分存 | 两列 | 有 |
| `teacher_edits_summary` / `why_changed` / `adaptation_log` / `generation_meta` | 列 | 有 |
| `course_outlines.version` / `confirmed_at` / `assessment_plan` | 列 | 有 |
| `feedbacks` 最小四字段 + `effect_rating` | `goal_achievement` / `difficulty` / `case_sparked_discussion` / `next_lesson_suggestion` | 有 |
| `generation_tasks.type` 扩充 | 含 `questionnaire` / `profile_report` / `knowledge_extract` / `hotspot_analyze` | 有 |
| `hotspots.analysis` 合规键 + `raw_text` 短摘录 | 注释含 `sizheng_confidence` / `suggest_patch` / `compliance_check` | 有 |
| `knowledge_patches` / `sys_config` / `user_export_prefs` / `rss_sources` | 表 | 有 |

---

## 9. 超集与非冲突说明（不算不一致）

1. **§6.3 相对样例的额外键**（`highlight` / `takeaway` / `classroom_speech` / `optional` / `evidence_type` / `attachments`）写入 schema 注释，样例未强制出现。
2. **`exports` 表**：v0.2 ER「LessonPlan 1──N Export」与 v0.1 §4.2 均有，v0.2 未删除，一并建表（任务清单未点名，但是完整模型）。
3. **`generation_tasks.created_by`**：可选 FK，便于按教师隔离任务；原 v0.1 表无此列。
4. **`feedbacks.notes` / `chaoxing_metrics`**：四字段之外的补充与预留粘贴列。
5. **`questionnaires.deadline`**：v0.1 字段保留，与 v0.2 `expires_at` 并存（截止展示 vs token 过期）。

以上均不改变样例 JSON 的字段名。

**对拍结论：全部一致。**
