diff --git a/app_prd/文档转换.md b/app_prd/文档转换UDC-M.md similarity index 100% rename from app_prd/文档转换.md rename to app_prd/文档转换UDC-M.md diff --git a/app_prd/知识增强服务.md b/app_prd/知识增强服务KES.md similarity index 90% rename from app_prd/知识增强服务.md rename to app_prd/知识增强服务KES.md index a4a5505..4a51eea 100644 --- a/app_prd/知识增强服务.md +++ b/app_prd/知识增强服务KES.md @@ -86,23 +86,17 @@ ## 4. 数据库设计 (PostgreSQL) 沿用模块二的 `questions` 表,本模块主要负责 **UPDATE** 操作。 +### **4.1 Table: questions (字段更新)** -### 4.1 Table: `questions` (字段补充) +本模块负责该表的 **更新 (UPDATE)** 操作。 -| 字段名 | 类型 | 说明 | -| :--- | :--- | :--- | -| ... | ... | (模块二已有的基础字段) | -| `problem_summary` | TEXT | 题目一句话摘要 (AI生成) | -| `knowledges` | JSONB | AI提取: `["k1", "k2"]` | -| `methods` | JSONB | AI提取: `["m1"]` | -| `updated_knowledges`| JSONB | **人工审核版** (应用层展示以此为准) | -| `updated_methods` | JSONB | **人工审核版** | -| `enrich_status` | VARCHAR | `pending` (待处理), `processing`, `done`, `failed` | -| `enrich_error` | TEXT | 调用外部API失败的错误日志 | -| `is_reviewed` | BOOLEAN | 是否经过人工确认 (默认 False) | -| `reviewer_id` | INT | 审核人ID | -| `reviewed_at` | TIMESTAMP | 审核时间 | +- **读取条件**: WHERE enrich_status = 'pending' + +- **更新字段 (AI)**: knowledges, methods, problem_summary, enrich_status。 + +- **更新字段 (人工)**: updated_knowledges, updated_methods, is_reviewed。 +- (完整表结构定义请参考“统一数据库设计规范”文档) --- ## 5. API 接口定义 (RESTful) diff --git a/app_prd/统一数据库架构设计文档SQL.md b/app_prd/统一数据库架构设计文档SQL.md new file mode 100644 index 0000000..8f2e89f --- /dev/null +++ b/app_prd/统一数据库架构设计文档SQL.md @@ -0,0 +1,216 @@ + +# 统一数据库架构设计文档 (Unified Database Schema) + +| 文档版本 | V1.0 | +| :--- | :--- | +| **最后更新** | 2025-12-09 | +| **适用范围** | UDC-M (模块一), QPES (模块二), KES (模块三) | +| **技术选型** | PostgreSQL 14+, SQLModel (ORM) | + +--- + +## 1. 设计概述 + +本数据库旨在支撑“文档解析 -> 题目提取 -> 知识增强”的全链路数据流转。 + +### 1.1 核心实体关系 (ERD 简述) +* **Documents (1) : (N) Conversion Tasks** + * 一个文档可以被多次转换(如转 MD, 转 PDF)。 +* **Documents (1) : (N) Questions** + * 一个文档包含多道题目。 +* **Documents (1) : (N) Extraction Tasks** + * 一个文档可以被多次提取(如调整 Prompt 后重试)。 + +### 1.2 关键数据类型 +* **UUID**: 所有核心业务主键使用 UUID,方便分布式生成和迁移。 +* **JSONB**: 充分利用 PostgreSQL 的 JSONB 能力存储非结构化数据(选项、知识点数组、图片链接),支持索引查询。 + +--- + +## 2. 详细表结构定义 + +### 2.1 基础资产层 (Module 1: UDC-M) + +#### Table: `documents` (文档资产表) +这是系统的根表,记录所有上传的原始文件。 + +```sql +CREATE TABLE documents ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + + -- 文件元数据 + filename VARCHAR(255) NOT NULL, -- 原始文件名 + file_hash VARCHAR(64) NOT NULL UNIQUE, -- SHA256,用于秒传去重 + file_size BIGINT, -- 文件大小 (Bytes) + file_type VARCHAR(16), -- 扩展名: pdf, docx, xlsx + storage_path VARCHAR(512) NOT NULL, -- MinIO 永久存储路径 (udc-raw/...) + + -- 业务元数据 + tags JSONB, -- 标签: {"subject": "math", "year": 2024} + uploader_id BIGINT, -- 上传用户ID + + -- 转换状态缓存 (指向最新的 Markdown 结果) + latest_parse_status VARCHAR(32) DEFAULT 'none', -- none, processing, success, failed + latest_result_url VARCHAR(512), -- 解析后的 Markdown MinIO 地址 + + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +CREATE INDEX idx_docs_hash ON documents(file_hash); +CREATE INDEX idx_docs_created ON documents(created_at); +``` + +#### Table: `conversion_tasks` (转换流水记录) +记录 UDC 服务的每次转换操作。 + +```sql +CREATE TABLE conversion_tasks ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + document_id UUID REFERENCES documents(id) ON DELETE CASCADE, + + target_format VARCHAR(16) NOT NULL, -- markdown, pdf, docx + output_mode VARCHAR(16) DEFAULT 'url', -- url, archive + + status VARCHAR(32) NOT NULL, -- queued, processing, success, failed + result_url VARCHAR(512), -- 结果文件下载地址 + error_msg TEXT, -- 错误日志 + + -- 性能指标 + worker_node VARCHAR(64), -- 处理该任务的 Worker 节点名 + process_duration_ms INT, -- 处理耗时 + + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + completed_at TIMESTAMP +); +``` + +--- + +### 2.2 题目数据层 (Module 2 & 3: QPES & KES) + +#### Table: `questions` (核心题库表) +这张表是 Module 2 (Insert) 和 Module 3 (Update) 的协作点。 + +```sql +CREATE TABLE questions ( + id BIGSERIAL PRIMARY KEY, -- 题目自增ID (用于对外展示更短) + uid UUID DEFAULT gen_random_uuid(), -- 内部唯一标识 + + -- 关联 + document_id UUID REFERENCES documents(id) ON DELETE CASCADE, + extraction_task_id UUID, -- 关联是哪次任务提取出来的 + question_seq INT, -- 题目在原卷中的顺序 + + -- ========================================== + -- Module 2 写入 (内容提取) + -- ========================================== + question_type VARCHAR(32), -- choice, fill, essay, unknown + + content_md TEXT NOT NULL, -- 题干 (Markdown + LaTeX + MinIO URL) + options_json JSONB, -- 选项 (仅选择题): [{"label":"A", "text":"..."}, ...] + answer_md TEXT, -- 参考答案 + analysis_md TEXT, -- 解析 + + image_urls JSONB, -- 冗余字段: ["http://minio.../1.jpg"] 方便索引包含图片的题 + content_hash VARCHAR(64), -- MD5(content_md),用于文档内或跨文档去重 + + -- ========================================== + -- Module 3 写入 (知识增强) + -- ========================================== + -- 机器自动提取部分 + problem_summary TEXT, -- 摘要 + knowledges JSONB, -- ["知识点1", "知识点2"] + methods JSONB, -- ["方法1", "方法2"] + + -- 人工审核部分 (应用层展示以此为准) + updated_knowledges JSONB, + updated_methods JSONB, + + -- 状态流转 + enrich_status VARCHAR(32) DEFAULT 'pending', -- pending -> processing -> done / failed + enrich_error TEXT, + + is_reviewed BOOLEAN DEFAULT FALSE, -- 是否人工审核过 + reviewer_id BIGINT, + reviewed_at TIMESTAMP, + + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- 索引 +CREATE INDEX idx_q_doc ON questions(document_id); +CREATE INDEX idx_q_enrich_status ON questions(enrich_status) WHERE enrich_status = 'pending'; -- 任务队列轮询优化 +CREATE INDEX idx_q_knowledges ON questions USING GIN (knowledges); -- 支持 JSON 数组搜索 +CREATE INDEX idx_q_hash ON questions(content_hash); +``` + +#### Table: `extraction_tasks` (提取任务记录) +记录 LLM 提取的消耗。 + +```sql +CREATE TABLE extraction_tasks ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + document_id UUID REFERENCES documents(id), + + model_name VARCHAR(64), -- e.g., deepseek-v3 + chunk_strategy VARCHAR(64), -- e.g., sliding-window-3000 + + total_tokens INT, -- 消耗 Token 数 + questions_count INT, -- 提取出的题目数量 + + status VARCHAR(32), -- processing, success, failed + error_log TEXT, + + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +--- + +### 2.3 辅助字典层 (Module 3 Optional) + +#### Table: `knowledge_tree` (知识点树 - 选做) +用于规范化 Module 3 的打标结果,避免 AI 生成“勾股定理”和“毕达哥拉斯定理”这种同义词导致检索分裂。 + +```sql +CREATE TABLE knowledge_tree ( + id SERIAL PRIMARY KEY, + name VARCHAR(128) NOT NULL, + parent_id INT REFERENCES knowledge_tree(id), + subject VARCHAR(32), -- math, physics + level VARCHAR(32), -- primary, middle, high + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +--- + +## 3. 数据流转状态机 (State Machine) + +### 3.1 `documents.latest_parse_status` +* `none`: 刚上传,未处理。 +* `processing`: UDC 正在转换中。 +* `success`: 转换完成,`latest_result_url` 有值(Markdown可用)。 +* `failed`: 转换失败。 + +### 3.2 `questions.enrich_status` +* `pending`: 题目刚被 Module 2 插入,等待打标。 +* `processing`: Module 3 正在调用 API。 +* `done`: 机器打标成功。 +* `failed`: 外部 API 调用失败(需重试)。 + +--- + +## 4. 开发注意事项 + +1. **JSONB 兼容性**: 在 Python 中使用 SQLModel 定义 JSONB 字段时,需要使用 `sa_column=Column(JSON)`。 +2. **事务控制**: + * Module 2 在写入 `questions` 时,建议开启事务:如果一道题写入失败,整个 Batch 回滚,或者记录错误日志但不中断其他题目。 +3. **并发锁**: + * Module 3 在领取任务时(`SELECT * FROM questions WHERE enrich_status='pending' LIMIT 10`),建议使用 `FOR UPDATE SKIP LOCKED`,防止多个 Worker 抢同一个题目造成重复调用 API 浪费钱。 + +--- + +现在,你的三个 PRD 只需要专注于**业务逻辑**和**接口定义**,数据库部分直接指向这份文档即可。这样不仅结构清晰,而且保证了技术实现的一致性。 \ No newline at end of file diff --git a/app_prd/题目解析.md b/app_prd/题目解析QPES.md similarity index 84% rename from app_prd/题目解析.md rename to app_prd/题目解析QPES.md index 71c5171..aceb375 100644 --- a/app_prd/题目解析.md +++ b/app_prd/题目解析QPES.md @@ -71,25 +71,11 @@ ## 4. 数据库设计 (PostgreSQL) -基于 SQLModel 设计,与 UDC-M 的 `documents` 表关联。 - -### 4.1 Table: `questions` (题库核心表) - -| 字段名 | 类型 | 说明 | -| :-------------- | :---------- | :---------------------------------------------- | -| `id` | BIGINT (PK) | 题目唯一主键 | -| `document_id` | UUID (FK) | **关联 UDC-M 的 documents 表** | -| `batch_id` | UUID | 关联本次提取任务 ID | -| `question_seq` | INT | 在原文档中的顺序号 (1, 2, 3...) | -| `question_type` | VARCHAR | `choice` (选择), `fill` (填空), `essay` (解答) | -| `content_md` | TEXT | **题干内容** (含 Markdown 图片和 Latex) | -| `options_json` | JSONB | 选择题选项 `[{"label":"A","text":"..."}, ...]` | -| `answer_md` | TEXT | 参考答案 | -| `analysis_md` | TEXT | 解析 (如果有) | -| `image_urls` | JSONB | 提取出的图片链接列表 `["http...", "http..."]` (冗余字段,方便索引) | -| `content_hash` | VARCHAR(64) | 用于去重 | -| `enrich_status` | VARCHAR | `pending` (待打标), `done` (已打标) | -| `created_at` | TIMESTAMP | | +### **4.1 Table: `questions` (题库核心表)** + 本模块负责该表的 **初始化 (INSERT)** 操作。 + * **写入字段**: `id`, `document_id`, `question_seq`, `content_md`, `options_json`, `answer_md`, `analysis_md`, `content_hash`。 +* **默认字段**: `enrich_status` 默认为 `'pending'`,`knowledges`/`methods` 等字段保持为 `NULL`。 +* *(完整表结构定义请参考“统一数据库设计规范”文档)* ### 4.2 Table: `extraction_tasks` (提取任务记录) 用于记录每次 LLM 调用的消耗和状态。