Files
gongxue-base/docs/refactor/content-import-contract.md

159 lines
4.0 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.

# 内容导入契约
更新时间2026-06-21
## 结论
内容导入的最终规范化、校验、租户隔离、幂等和审计必须由后端负责。
前端只负责:
- 上传或粘贴 JSON/Excel/CSV。
- 做轻量格式预检查,减少明显错误。
- 展示后端 preview 返回的 `job/items/issues`
- 让运营人员修正数据后再确认导入。
迁移脚本只负责:
- 从 PocketBase 导出或旧 JSON 中抽取数据。
- 转换成新架构推荐格式。
- 调用后端 preview/import API。
不建议迁移脚本直接绕过后端写业务表,除非是一次性内控迁移,并且必须额外跑导入后校验。
## 已实现导入 API
```text
POST /api/tenant-content/imports/preview/questions
POST /api/tenant-content/imports/questions
POST /api/tenant-content/imports/preview/vocabulary
POST /api/tenant-content/imports/vocabulary
POST /api/tenant-content/imports/preview/handbook
POST /api/tenant-content/imports/handbook
GET /api/tenant-content/imports
GET /api/tenant-content/imports/issues
```
所有导入都会写入:
- `content_import_jobs`
- `content_import_items`
- `content_import_issues`
- `audit_logs`
## 单词导入
推荐新格式:
```json
{
"regionId": "uuid",
"entryId": "uuid",
"contentNodeId": "uuid",
"units": [
{
"legacyId": "unit-1",
"name": "Unit 1 - 高频核心词",
"description": "专升本考试高频词汇",
"order": 1,
"words": [
{
"legacyId": "word-abandon",
"word": "abandon",
"phonetic": "/əˈbændən/",
"meaning": "v. 放弃,抛弃",
"example": "He had to abandon his car in the snow.",
"exampleTranslation": "他不得不把车丢弃在雪地里。",
"difficulty": 3,
"tags": ["高频词"],
"order": 1
}
]
}
]
}
```
兼容旧模板:
- `vocabulary_units_示例数据`
- `vocabulary_示例数据`
后端会把旧模板归一化为 `vocabulary_units/vocabulary_words`,并可自动挂到 `content_entries/content_nodes`
## 知识手册导入
推荐新格式:
```json
{
"regionId": "uuid",
"entryId": "uuid",
"contentNodeId": "uuid",
"subjects": [
{
"legacyId": "handbook-chinese",
"name": "大学语文",
"type": "guide",
"chapters": [
{
"legacyId": "chapter-outline",
"name": "一、语文考纲",
"sections": [
{
"legacyId": "section-outline",
"name": "考纲解读",
"entries": [
{
"legacyId": "entry-outline",
"title": "2024年天津专升本语文考试大纲",
"summary": "全面解读语文考试要求",
"content": "Markdown 内容",
"tags": ["考纲"]
}
]
}
]
}
]
}
]
}
```
映射规则:
- 手册入口:`content_entries.entry_type = handbook`
- 书籍/科目:`handbook_subjects`,并生成或绑定一个 `content_nodes`
- 章节:`handbook_chapters`,并生成章节节点
- 小节:默认进入 `content_nodes`,作为知识点的目录节点
- 知识点:`handbook_entries`,通过 `content_node_id` 归属到小节或章节
## 题目导入
题目继续兼容旧题库 JSON 数组格式,并支持 Markdown、KaTeX、图片、表格、阅读理解子题等字段。导入时可以传
- `subjectId`
- `categoryId`
- `entryId`
- `contentNodeId`
- `collectionId`
这样题目会同时落到旧兼容表和新内容导航/题目集合。
## 幂等规则
- 优先使用 `legacyId` 作为跨迁移稳定标识。
- 没有 `legacyId` 时,后端按导入 job 和行号生成内部标识。
- 相同 `legacyId` 再导入会更新。
- 内容 hash 未变化时标记为 `skipped`
## 下一步
- 增加 Excel/CSV 解析入口,但解析后仍进入同一套 preview/import 管线。
- 增加分数线、视频导入。
- 增加异步 worker处理大批量导入、重试和导入后校验。