Files
DEMO-AGENT/docs/3.数据库设计/3.产品关键信息提取与申报文件自动填表.md

434 lines
16 KiB
Markdown
Raw Permalink 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.
# 产品关键信息提取与申报文件自动填表数据库设计
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 需求分析文档 | docs/1.需求分析/3.产品关键信息提取与申报文件自动填表.md |
| 功能设计文档 | docs/2.功能设计/3.产品关键信息提取与申报文件自动填表.md |
| 数据库类型 | SQLite / Django ORM |
| 表名前缀 | ra_ |
| 设计日期 | 2026-06-07 |
| 设计版本 | V1.0 |
---
## 一、设计原则
| 原则 | 说明 |
| --- | --- |
| 独立填表批次 | 自动填表作为独立工作流,使用独立批次表,不强绑法规核查批次 |
| 复用文件来源 | 填表批次必须关联一个成功的 `FileSummaryBatch`,不重复保存文件清单 |
| 可选复用法规条件 | 如当前对话已有已确认法规核查批次,可通过可空外键复用注册类型等条件 |
| 导出记录复用 | Word、Excel、JSON、PDF 等下载文件继续进入 `ExportedSummaryFile` |
| 过程产物独立 | 自动填表过程产物单独建表,避免和法规核查 `RegulatoryArtifact` 混用 |
| 通知记录独立 | 自动填表飞书通知单独建表,字段风格与法规通知记录保持一致 |
| 大文本不入库 | 字段抽取 JSON、追溯清单和模板副本保存为文件数据库仅保存路径、hash 和摘要 |
| 字段明细暂不入库 | 本期不新增字段级明细表;字段结果保存在 JSON/Excel 产物与批次摘要中 |
| SQLite 兼容 | 字段类型、索引和约束优先保证当前 SQLite + Django ORM 可运行 |
---
## 二、ER 图
```mermaid
erDiagram
AUTH_USER ||--o{ CONVERSATION : owns
CONVERSATION ||--o{ RA_FILE_SUMMARY_BATCH : has
RA_FILE_SUMMARY_BATCH ||--o{ RA_FILE_SUMMARY_ITEM : produces
RA_FILE_SUMMARY_BATCH ||--o{ RA_APPLICATION_FORM_FILL_BATCH : feeds
RA_REGULATORY_REVIEW_BATCH ||--o{ RA_APPLICATION_FORM_FILL_BATCH : optionally_confirms
AUTH_USER ||--o{ RA_APPLICATION_FORM_FILL_BATCH : runs
CONVERSATION ||--o{ RA_APPLICATION_FORM_FILL_BATCH : has
MESSAGE ||--o{ RA_APPLICATION_FORM_FILL_BATCH : triggers
RA_APPLICATION_FORM_FILL_BATCH ||--o{ RA_APPLICATION_FORM_FILL_ARTIFACT : keeps
RA_APPLICATION_FORM_FILL_BATCH ||--o{ RA_APPLICATION_FORM_FILL_NOTIFICATION_RECORD : sends
RA_APPLICATION_FORM_FILL_BATCH ||--o{ RA_EXPORTED_SUMMARY_FILE : exports
RA_APPLICATION_FORM_FILL_BATCH ||--o{ RA_WORKFLOW_NODE_RUN : tracks
RA_APPLICATION_FORM_FILL_BATCH ||--o{ RA_WORKFLOW_EVENT : emits
```
说明:`ra_workflow_node_run``ra_workflow_event``ra_exported_summary_file` 已在第二批中被通用化,通过 `workflow_type``workflow_batch_id` 支持多工作流。本功能使用 `workflow_type=application_form_fill`
---
## 三、表结构设计
### 3.1 ra_application_form_fill_batch
一次自动填表工作流批次。该表记录本次触发来源、选择模板、输出类型、注册类型、产品名称、冲突摘要、工作目录和状态。
| 字段名 | Django 类型 | SQLite 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| id | BigAutoField | integer | 是 | 主键 |
| conversation_id | ForeignKey | bigint | 是 | 绑定对话 |
| user_id | ForeignKey | bigint | 是 | 发起用户 |
| trigger_message_id | ForeignKey | bigint | 否 | 触发填表工作流的用户消息 |
| source_summary_batch_id | ForeignKey | bigint | 是 | 文件来源汇总批次 |
| source_regulatory_batch_id | ForeignKey | bigint | 否 | 可选,复用已确认法规核查批次条件 |
| batch_no | CharField(64) | varchar(64) | 是 | 填表批次编号,唯一 |
| status | CharField(30) | varchar(30) | 是 | pending、running、waiting_user、success、partial_success、failed、cancelled |
| requested_templates | JSONField | text/json | 是 | 用户指定模板编码列表;未指定为空数组 |
| selected_templates | JSONField | text/json | 是 | 系统实际选择模板编码列表 |
| output_types | JSONField | text/json | 是 | 请求输出类型,如 word、excel、json、pdf |
| registration_type | CharField(80) | varchar(80) | 否 | 识别出的注册类型 |
| registration_type_source | CharField(40) | varchar(40) | 否 | user_message、regulatory_batch、file_extract、unknown |
| product_name | CharField(200) | varchar(200) | 否 | 产品名称 |
| conflict_summary | JSONField | text/json | 是 | 冲突字段摘要 |
| risk_notes | JSONField | text/json | 是 | 不适用模板、低置信度、PDF 待生成等提示 |
| template_config_version | CharField(80) | varchar(80) | 否 | 模板配置版本 |
| template_config_hash | CharField(128) | varchar(128) | 否 | 模板配置文件 hash |
| work_dir | CharField(500) | varchar(500) | 否 | 批次工作目录 |
| error_message | TextField | text | 否 | 批次异常说明 |
| created_at | DateTimeField | datetime | 是 | 创建时间 |
| started_at | DateTimeField | datetime | 否 | 开始时间 |
| finished_at | DateTimeField | datetime | 否 | 完成时间 |
| archived_at | DateTimeField | datetime | 否 | 归档时间 |
| is_deleted | BooleanField | bool | 是 | 软删除标记 |
唯一约束:
| 约束名 | 字段 |
| --- | --- |
| uq_ra_aff_batch_no | batch_no |
索引:
| 索引名 | 字段 | 说明 |
| --- | --- | --- |
| idx_ra_aff_batch_conv_status | conversation_id, status | 查询对话下填表批次状态 |
| idx_ra_aff_batch_summary | source_summary_batch_id | 根据文件汇总批次查询填表历史 |
| idx_ra_aff_batch_regulatory | source_regulatory_batch_id | 根据法规核查批次查询关联填表历史 |
| idx_ra_aff_batch_user_created | user_id, created_at | 查询用户发起记录 |
| idx_ra_aff_batch_created | created_at | 按创建时间查询 |
---
### 3.2 ra_application_form_fill_artifact
自动填表过程产物表。仅保存文件元数据,不保存字段抽取大 JSON 的全文。
| 字段名 | Django 类型 | SQLite 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| id | BigAutoField | integer | 是 | 主键 |
| batch_id | ForeignKey | bigint | 是 | 所属自动填表批次 |
| artifact_type | CharField(60) | varchar(60) | 是 | template_copy、field_extract_result、merged_fields、traceability、filled_template、notification_record |
| file_format | CharField(20) | varchar(20) | 是 | json、excel、docx、pdf、markdown |
| name | CharField(160) | varchar(160) | 是 | 产物名称 |
| file_name | CharField(255) | varchar(255) | 是 | 文件名 |
| storage_path | CharField(500) | varchar(500) | 是 | 存储路径 |
| file_size | BigIntegerField | bigint | 是 | 文件大小 |
| content_hash | CharField(128) | varchar(128) | 是 | 文件 SHA-256 hash |
| metadata | JSONField | text/json | 是 | 模板编码、输出类型、生成状态、错误摘要等 |
| created_by_node | CharField(60) | varchar(60) | 否 | 产生该产物的节点 |
| created_at | DateTimeField | datetime | 是 | 创建时间 |
| is_deleted | BooleanField | bool | 是 | 软删除标记 |
索引:
| 索引名 | 字段 | 说明 |
| --- | --- | --- |
| idx_ra_aff_artifact_batch_type | batch_id, artifact_type | 查询批次过程产物 |
| idx_ra_aff_artifact_format | file_format | 按文件格式查询 |
| idx_ra_aff_artifact_created | created_at | 按时间追溯 |
---
### 3.3 ra_application_form_fill_notification_record
自动填表飞书通知记录表。通知失败不阻断文件下载,但需要留痕和支持后续重试。
| 字段名 | Django 类型 | SQLite 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| id | BigAutoField | integer | 是 | 主键 |
| batch_id | ForeignKey | bigint | 是 | 所属自动填表批次 |
| recipient_id | ForeignKey(User) | bigint | 是 | 通知对象,默认上传人/发起人 |
| channel | CharField(30) | varchar(30) | 是 | feishu_cli、feishu_api、mock |
| template_codes | JSONField | text/json | 是 | 本次通知涉及模板 |
| export_ids | JSONField | text/json | 是 | 本次通知关联导出文件 ID |
| message_summary | TextField | text | 是 | 通知摘要 |
| send_status | CharField(20) | varchar(20) | 是 | pending、success、failed |
| retry_count | PositiveIntegerField | integer | 是 | 已重试次数 |
| external_message_id | CharField(120) | varchar(120) | 否 | 飞书外部消息 ID |
| error_message | TextField | text | 否 | 失败原因 |
| sent_at | DateTimeField | datetime | 否 | 发送成功时间 |
| created_at | DateTimeField | datetime | 是 | 创建时间 |
| updated_at | DateTimeField | datetime | 是 | 更新时间 |
| is_deleted | BooleanField | bool | 是 | 软删除标记 |
索引:
| 索引名 | 字段 | 说明 |
| --- | --- | --- |
| idx_ra_aff_notify_batch | batch_id, created_at | 查询批次通知记录 |
| idx_ra_aff_notify_recipient | recipient_id, send_status | 查询用户通知状态 |
| idx_ra_aff_notify_status | send_status, retry_count | 查询待重试通知 |
---
## 四、既有表扩展
### 4.1 ra_exported_summary_file
继续复用导出文件表,需扩展导出类型。
| 字段/枚举 | 处理 |
| --- | --- |
| export_type | 增加 `word``pdf` |
| workflow_type | 使用 `application_form_fill` |
| workflow_batch_id | 记录 `ApplicationFormFillBatch.id` |
| export_category | 使用 `filled_template``traceability``extract_result` |
导出类型枚举:
| value | 中文展示 | 说明 |
| --- | --- | --- |
| markdown | Markdown | 既有报告 |
| excel | Excel | 追溯清单 |
| json | JSON | 字段抽取结果包 |
| word | Word | 填好的 Word 模板 |
| pdf | PDF | Word 转换后的 PDFP1 预留 |
### 4.2 ra_workflow_node_run
本功能使用通用工作流字段:
| 字段 | 值 |
| --- | --- |
| workflow_type | application_form_fill |
| workflow_batch_id | ApplicationFormFillBatch.id |
| node_group | form_fill |
| batch_id | 可为空或兼容性填充 source_summary_batch_id |
### 4.3 ra_workflow_event
本功能事件写入:
| 字段 | 值 |
| --- | --- |
| workflow_type | application_form_fill |
| workflow_batch_id | ApplicationFormFillBatch.id |
| conversation_id | 当前对话 ID |
| payload | 节点状态、模板列表、冲突数量、导出文件等 |
---
## 五、枚举设计
### 5.1 ApplicationFormFillBatch.status
| value | 中文展示 | 说明 |
| --- | --- | --- |
| pending | 待执行 | 批次已创建,等待执行 |
| running | 执行中 | 工作流正在执行 |
| waiting_user | 等待用户 | 缺少文件汇总批次或关键条件 |
| success | 成功 | Word 和必要追溯产物生成成功 |
| partial_success | 部分成功 | 部分模板、PDF、追溯清单或通知失败 |
| failed | 失败 | 所有目标 Word 模板均生成失败 |
| cancelled | 已取消 | 用户或系统取消执行 |
### 5.2 artifact_type
| value | 说明 |
| --- | --- |
| template_copy | 模板副本 |
| field_extract_result | 规则/正则与 LLM 抽取原始结果 |
| merged_fields | 合并后的最终字段和冲突 |
| traceability | 字段来源追溯清单 |
| filled_template | 已填写模板 |
| notification_record | 通知记录产物 |
### 5.3 registration_type_source
| value | 说明 |
| --- | --- |
| user_message | 用户话语明确指定 |
| regulatory_batch | 复用已确认法规核查条件 |
| file_extract | 从文件内容抽取 |
| unknown | 未识别 |
### 5.4 通知枚举
| 字段 | value |
| --- | --- |
| channel | feishu_cli、feishu_api、mock |
| send_status | pending、success、failed |
---
## 六、JSON 字段结构建议
### 6.1 requested_templates / selected_templates
```json
["registration_certificate", "essential_principles"]
```
### 6.2 output_types
```json
["word", "excel", "json"]
```
PDF 作为 P1 预留,可在后续加入:
```json
["word", "pdf", "excel", "json"]
```
### 6.3 conflict_summary
```json
[
{
"field_key": "storage_condition",
"field_label": "产品储存条件及有效期",
"selected_value": "2-8℃保存有效期12个月",
"selected_source": "说明书.docx",
"conflict_values": [
{
"value": "-20℃保存",
"source_file": "产品技术要求.docx",
"evidence": "储存条件:-20℃保存"
}
],
"handling": "说明书优先,模板内黄底红字高亮"
}
]
```
### 6.4 risk_notes
```json
[
{
"type": "template_registration_mismatch",
"message": "用户指定变更注册(备案)文件,但系统识别注册类型为首次注册,需人工确认。"
},
{
"type": "pdf_pending",
"message": "PDF 转换为后续增强项,本次优先生成 Word。"
}
]
```
### 6.5 artifact.metadata
```json
{
"template_code": "registration_certificate",
"output_type": "word",
"node_code": "word_fill",
"status": "success",
"conflict_count": 2
}
```
---
## 七、存储路径设计
自动填表工作目录按用户、对话和批次隔离:
```text
media/application_form_fill/{user_id}/{conversation_id}/{batch_no}/
```
目录结构:
```text
media/application_form_fill/12/1001/AFF-20260607153000-a1b2c3/
templates/
registration_certificate.source.docx
essential_principles.source.docx
filled/
AFF-20260607153000-a1b2c3-甲胎蛋白检测试剂盒-注册证格式.docx
exports/
AFF-20260607153000-a1b2c3-甲胎蛋白检测试剂盒-字段来源追溯清单.xlsx
field_extract_result.json
merged_fields.json
notifications/
notification_record.json
```
所有产物写入 `ApplicationFormFillArtifact` 时必须记录 SHA-256 hash。
---
## 八、权限与查询规则
### 8.1 批次访问权限
```text
ApplicationFormFillBatch -> conversation -> user
必须等于当前 request.user
```
### 8.2 导出下载权限
```text
ExportedSummaryFile.workflow_type == application_form_fill
-> workflow_batch_id
-> ApplicationFormFillBatch.conversation.user
```
`workflow_type=file_summary``regulatory_review`,仍按既有逻辑校验。
### 8.3 文件读取权限
自动填表只能读取 `source_summary_batch.items` 对应的文件,不允许从其他对话或其他批次随意读取文件。
---
## 九、字段级数据库表暂缓说明
本期不新增 `ApplicationFormFillField` 字段级明细表。原因:
| 原因 | 说明 |
| --- | --- |
| Demo 主链路更轻 | 字段结果以 JSON 和 Excel 追溯清单即可满足下载复核 |
| 避免过早建模 | 字段结构依赖模板配置和后续人工修改交互,暂不固化表结构 |
| 查询需求有限 | 本期主要按批次下载文件,不做字段级统计和在线编辑 |
后续如需要在线确认、人工修改、字段级审计或批量统计,再新增字段级表。该事项写入 `docs/6.待办计划/第二阶段暂缓事项.md`
---
## 十、Django Model 命名建议
| 表名 | Model 名称 |
| --- | --- |
| ra_application_form_fill_batch | ApplicationFormFillBatch |
| ra_application_form_fill_artifact | ApplicationFormFillArtifact |
| ra_application_form_fill_notification_record | ApplicationFormFillNotificationRecord |
建议模型仍集中放在 `review_agent/models.py`,与前两批现有模型保持一致;业务逻辑放在 `review_agent/application_form_fill/`
---
## 十一、验收检查点
| 序号 | 检查项 | 验收标准 |
| --- | --- | --- |
| 1 | 独立批次 | 触发填表后生成 `ApplicationFormFillBatch` |
| 2 | 文件来源 | 每个填表批次都关联一个成功的 `FileSummaryBatch` |
| 3 | 可选法规条件 | 如有关联法规核查批次,可记录 `source_regulatory_batch` |
| 4 | 过程产物 | 字段抽取 JSON、合并结果、追溯清单、模板副本均可留底 |
| 5 | 导出复用 | 填好的 Word 和追溯清单进入 `ExportedSummaryFile` |
| 6 | 导出类型 | `ExportedSummaryFile.ExportType` 支持 `word``pdf` |
| 7 | 通知记录 | 飞书通知记录能保存状态、重试次数、失败原因 |
| 8 | 权限隔离 | A 对话的填表批次和导出文件不能被 B 对话访问 |
| 9 | 字段表暂缓 | 字段级结果不入库,但能从 JSON/Excel 追溯产物复核 |
---
## 十二、开发顺序建议
1. 扩展 `ExportedSummaryFile.ExportType`,增加 `word``pdf`
2. 新增 `ApplicationFormFillBatch``ApplicationFormFillArtifact``ApplicationFormFillNotificationRecord`
3. 为新增状态字段定义 Django `TextChoices`
4. 配置表名、索引和唯一约束。
5. 执行 `python manage.py makemigrations review_agent``python manage.py migrate`
6. 编写模型测试,覆盖批次创建、产物 hash、通知重试字段、导出权限查询。
7. 将字段级数据库表和 PDF 转换能力写入待办计划。