Files
DEMO-AGENT/docs/4.数据库设计/2.NMPA注册资料法规核查与整改闭环.md

486 lines
20 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.
# NMPA 注册资料法规核查与整改闭环工作流数据库设计
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 需求分析文档 | docs/1.需求分析/2.NMPA注册资料法规核查与整改闭环.md |
| 功能设计文档 | docs/2.功能设计/2.NMPA注册资料法规核查与整改闭环.md |
| 数据库类型 | SQLite / Django ORM |
| 表名前缀 | ra_ |
| 设计日期 | 2026-06-06 |
| 设计版本 | V1.0 |
---
## 一、设计原则
| 原则 | 说明 |
| --- | --- |
| 复用汇总批次 | 法规核查不重复保存文件清单,必须关联既有 `ra_file_summary_batch` |
| 独立核查批次 | 同一个文件汇总批次可以产生多次法规核查批次,适用条件变更时创建新批次 |
| 规则版本入库 | 结构化规则版本进入数据库便于追溯规则文件、RAG 索引和启用状态 |
| RAG 不单独建表 | RAG 索引信息挂在规则版本和核查批次字段中,不新增索引表 |
| 枚举存值 | 数据库存英文枚举 value前端或服务层映射为中文展示 |
| 关键字段独立 | 常用查询字段独立存储,其余过程上下文进入 JSON 或文件产物 |
| 大文本不入库 | 过程产物只在数据库保存路径、摘要和 hash大文本内容写入文件 |
| 软删除优先 | 法规核查相关数据采用软删除/归档策略,便于审计和恢复 |
| 过程产物留底 | 条件确认、核查矩阵、风险清单、RAG 结果、通知记录、复核记录均需留底 |
---
## 二、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_REGULATORY_REVIEW_BATCH : reviews
AUTH_USER ||--o{ RA_REGULATORY_REVIEW_BATCH : runs
AUTH_USER ||--o{ RA_REGULATORY_ISSUE : owns
RA_REGULATORY_RULE_VERSION ||--o{ RA_REGULATORY_REVIEW_BATCH : used_by
RA_REGULATORY_REVIEW_BATCH ||--o{ RA_REGULATORY_ISSUE : produces
RA_REGULATORY_REVIEW_BATCH ||--o{ RA_REGULATORY_ARTIFACT : keeps
RA_REGULATORY_REVIEW_BATCH ||--o{ RA_REGULATORY_NOTIFICATION_RECORD : sends
RA_REGULATORY_REVIEW_BATCH ||--o{ RA_EXPORTED_SUMMARY_FILE : exports
RA_REGULATORY_REVIEW_BATCH ||--o{ RA_WORKFLOW_NODE_RUN : tracks
RA_REGULATORY_REVIEW_BATCH ||--o{ RA_WORKFLOW_EVENT : emits
```
说明:`ra_workflow_node_run``ra_workflow_event` 在第一阶段设计中属于文件汇总批次节点记录表。法规核查工作流复用同一套事件机制,采用 `workflow_type``workflow_batch_id` 兼容多工作流;原 `batch_id` 保留用于兼容文件汇总旧逻辑。
---
## 三、表结构设计
### 3.1 ra_regulatory_rule_version
法规结构化规则版本表。规则文件仍以 YAML/JSON 文件形式维护,数据库记录版本元数据、文件 hash、RAG 索引版本和启用状态。
| 字段名 | Django 类型 | SQLite 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| id | BigAutoField | integer | 是 | 主键 |
| version | CharField(80) | varchar(80) | 是 | 规则版本,如 nmpa_ivd_2021_v1 |
| source_url | URLField(500) | varchar(500) | 是 | 法规来源 URL |
| source_path | CharField(500) | varchar(500) | 是 | 本地法规资料路径 |
| effective_date | DateField | date | 否 | 规则生效日期或公告日期 |
| rule_file_path | CharField(500) | varchar(500) | 是 | 结构化规则文件路径 |
| rule_file_hash | CharField(128) | varchar(128) | 是 | 规则文件 hash |
| rag_index_version | CharField(80) | varchar(80) | 否 | RAG 索引版本 |
| rag_index_path | CharField(500) | varchar(500) | 否 | RAG 索引存储路径 |
| is_active | BooleanField | bool | 是 | 是否当前启用版本 |
| created_by_id | ForeignKey(User) | bigint | 否 | 创建人 |
| activated_at | DateTimeField | datetime | 否 | 启用时间 |
| description | TextField | text | 否 | 版本说明 |
| created_at | DateTimeField | datetime | 是 | 创建时间 |
| updated_at | DateTimeField | datetime | 是 | 更新时间 |
| is_deleted | BooleanField | bool | 是 | 软删除标记 |
唯一约束:
| 约束名 | 字段 |
| --- | --- |
| uq_ra_reg_rule_version | version |
索引:
| 索引名 | 字段 | 说明 |
| --- | --- | --- |
| idx_ra_reg_rule_active | is_active, is_deleted | 查询当前启用规则 |
| idx_ra_reg_rule_effective | effective_date | 按生效日期追溯 |
| idx_ra_reg_rule_created | created_at | 查看规则版本历史 |
---
### 3.2 ra_regulatory_review_batch
法规核查批次表。一次法规核查工作流对应一条记录。同一个 `ra_file_summary_batch` 可关联多个法规核查批次,用于适用条件变更或重新核查。
| 字段名 | Django 类型 | SQLite 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| id | BigAutoField | integer | 是 | 主键 |
| conversation_id | ForeignKey | bigint | 是 | 绑定对话 |
| user_id | ForeignKey | bigint | 是 | 发起用户 |
| file_summary_batch_id | ForeignKey | bigint | 是 | 关联文件汇总批次 |
| rule_version_id | ForeignKey | bigint | 否 | 使用的规则版本 |
| batch_no | CharField(64) | varchar(64) | 是 | 法规核查批次编号,唯一 |
| status | CharField(30) | varchar(30) | 是 | pending、running、waiting_user、success、failed、reference_only、partial_success、cancelled |
| product_category | CharField(80) | varchar(80) | 否 | 产品类别 |
| registration_type | CharField(80) | varchar(80) | 否 | 注册类型 |
| clinical_evaluation_path | CharField(120) | varchar(120) | 否 | 临床评价路径 |
| product_name | CharField(200) | varchar(200) | 否 | 产品名称 |
| model_specification | CharField(200) | varchar(200) | 否 | 型号规格 |
| intended_use | TextField | text | 否 | 预期用途 |
| condition_json | JSONField | text/json | 否 | 其他适用条件、用户确认记录和抽取置信度 |
| rule_version_value | CharField(80) | varchar(80) | 否 | 冗余记录规则版本值,便于历史追溯 |
| rule_source_url | URLField(500) | varchar(500) | 否 | 冗余记录法规来源 URL |
| rule_source_path | CharField(500) | varchar(500) | 否 | 冗余记录本地法规资料路径 |
| rag_index_version | CharField(80) | varchar(80) | 否 | 本次使用的 RAG 索引版本 |
| risk_summary_json | JSONField | text/json | 否 | 风险数量摘要 |
| artifact_root | 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_reg_batch_no | batch_no |
索引:
| 索引名 | 字段 | 说明 |
| --- | --- | --- |
| idx_ra_reg_batch_conv_status | conversation_id, status | 查询对话下法规核查批次状态 |
| idx_ra_reg_batch_summary | file_summary_batch_id | 根据文件汇总批次查询法规核查历史 |
| idx_ra_reg_batch_created | created_at | 按创建时间查询 |
| idx_ra_reg_batch_rule | rule_version_value | 规则版本追溯 |
| idx_ra_reg_batch_user_created | user_id, created_at | 查询用户发起记录 |
---
### 3.3 ra_regulatory_issue
法规核查问题表,记录完整性、章节结构、一致性、通知、复核等业务问题及整改状态。
| 字段名 | Django 类型 | SQLite 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| id | BigAutoField | integer | 是 | 主键 |
| batch_id | ForeignKey | bigint | 是 | 所属法规核查批次 |
| owner_id | ForeignKey(User) | bigint | 否 | 责任人,默认上传人 |
| issue_code | CharField(100) | varchar(100) | 是 | 问题编码 |
| issue_type | CharField(40) | varchar(40) | 是 | completeness、structure、consistency、notification、review |
| risk_level | CharField(20) | varchar(20) | 是 | blocking、high、medium、low、info |
| status | CharField(30) | varchar(30) | 是 | pending_confirm、pending_fix、fixed、review_passed、review_failed、closed |
| title | CharField(255) | varchar(255) | 是 | 问题标题 |
| description | TextField | text | 否 | 问题描述 |
| rule_id | CharField(120) | varchar(120) | 否 | 命中的规则 ID |
| regulation_basis | TextField | text | 否 | 法规依据或规则依据 |
| file_item_id | ForeignKey(FileSummaryItem) | bigint | 否 | 关联文件明细,可为空 |
| file_path | CharField(500) | varchar(500) | 否 | 常用证据文件路径 |
| page_no | PositiveIntegerField | integer | 否 | 常用证据页码 |
| field_name | CharField(120) | varchar(120) | 否 | 一致性或字段问题名称 |
| evidence_json | JSONField | text/json | 否 | 证据详情如文本片段、多个来源值、RAG 引用等 |
| suggestion | TextField | text | 否 | 整改建议 |
| source_node | CharField(60) | varchar(60) | 否 | 产生问题的工作流节点 |
| confirmed_by_id | ForeignKey(User) | bigint | 否 | 确认人 |
| confirmed_at | DateTimeField | datetime | 否 | 确认时间 |
| closed_by_id | ForeignKey(User) | bigint | 否 | 关闭人 |
| closed_at | DateTimeField | datetime | 否 | 关闭时间 |
| created_at | DateTimeField | datetime | 是 | 创建时间 |
| updated_at | DateTimeField | datetime | 是 | 更新时间 |
| is_deleted | BooleanField | bool | 是 | 软删除标记 |
唯一约束:
| 约束名 | 字段 |
| --- | --- |
| uq_ra_reg_issue_batch_code | batch_id, issue_code |
索引:
| 索引名 | 字段 | 说明 |
| --- | --- | --- |
| idx_ra_reg_issue_batch | batch_id, created_at | 查询批次问题 |
| idx_ra_reg_issue_risk_status | risk_level, status | 风险列表和整改状态筛选 |
| idx_ra_reg_issue_owner_status | owner_id, status | 责任人待办 |
| idx_ra_reg_issue_rule | rule_id | 规则问题追溯 |
| idx_ra_reg_issue_file | file_item_id | 关联文件问题 |
| idx_ra_reg_issue_field | field_name | 字段一致性问题查询 |
---
### 3.4 ra_regulatory_artifact
法规核查过程产物表。只保存文件元数据,不保存大文本全文。文件内容写入受控存储目录,`file_hash` 必填。
| 字段名 | Django 类型 | SQLite 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| id | BigAutoField | integer | 是 | 主键 |
| batch_id | ForeignKey | bigint | 是 | 所属法规核查批次 |
| artifact_type | CharField(60) | varchar(60) | 是 | condition_record、rule_matrix、risk_list、text_extract_json、rag_result_json、notification_record、review_record |
| file_format | CharField(20) | varchar(20) | 是 | markdown、excel、json |
| file_name | CharField(255) | varchar(255) | 是 | 文件名 |
| storage_path | CharField(500) | varchar(500) | 是 | 存储路径 |
| file_size | BigIntegerField | bigint | 是 | 文件大小 |
| file_hash | CharField(128) | varchar(128) | 是 | 文件 hash用于校验留底文件未被篡改 |
| summary | TextField | text | 否 | 产物摘要 |
| created_by_node | CharField(60) | varchar(60) | 否 | 产生该产物的工作流节点 |
| created_at | DateTimeField | datetime | 是 | 创建时间 |
| is_deleted | BooleanField | bool | 是 | 软删除标记 |
索引:
| 索引名 | 字段 | 说明 |
| --- | --- | --- |
| idx_ra_reg_artifact_batch_type | batch_id, artifact_type | 查询批次过程产物 |
| idx_ra_reg_artifact_format | file_format | 按格式查询 |
| idx_ra_reg_artifact_created | created_at | 按时间追溯 |
---
### 3.5 ra_regulatory_notification_record
法规核查通知记录表,记录飞书 CLI 发送结果。飞书失败不阻断工作流,但需要留痕。
| 字段名 | Django 类型 | SQLite 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| id | BigAutoField | integer | 是 | 主键 |
| batch_id | ForeignKey | bigint | 是 | 所属法规核查批次 |
| recipient_id | ForeignKey(User) | bigint | 是 | 通知对象 |
| channel | CharField(30) | varchar(30) | 是 | feishu_cli、feishu_api、mock |
| risk_levels | JSONField | text/json | 是 | 本次通知包含的风险等级 |
| issue_ids | JSONField | text/json | 是 | 本次通知关联的问题 ID 列表 |
| message_summary | TextField | text | 是 | 通知内容摘要 |
| send_status | CharField(20) | varchar(20) | 是 | pending、success、failed |
| retry_count | PositiveIntegerField | integer | 是 | 已重试次数,最多 3 次 |
| 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_reg_notify_batch | batch_id, created_at | 查询批次通知记录 |
| idx_ra_reg_notify_recipient | recipient_id, send_status | 查询用户通知状态 |
| idx_ra_reg_notify_status | send_status, retry_count | 查询待重试通知 |
---
## 四、枚举设计
### 4.1 RegulatoryReviewBatch.status
| value | 中文展示 | 说明 |
| --- | --- | --- |
| pending | 待执行 | 已创建,等待执行 |
| running | 执行中 | 工作流正在执行 |
| waiting_user | 等待用户 | 等待用户确认适用条件或关闭复核 |
| success | 已完成 | 核查完成且无关键失败 |
| failed | 失败 | 关键节点失败,无法输出有效结果 |
| reference_only | 仅供参考 | 规则文件加载失败,降级为 RAG 辅助核查 |
| partial_success | 部分完成 | 部分节点或通知失败,但已输出主要结果 |
| cancelled | 已取消 | 用户或系统取消执行 |
### 4.2 RegulatoryIssue.status
| value | 中文展示 | 说明 |
| --- | --- | --- |
| pending_confirm | 待确认 | 条件性问题或低置信度问题等待人工确认 |
| pending_fix | 待处理 | 已确认需要补充或整改 |
| fixed | 已补充 | 用户已上传补充资料或声明已处理 |
| review_passed | 复核通过 | 系统复核通过,关闭前仍需人工确认 |
| review_failed | 复核不通过 | 系统复核后问题仍存在 |
| closed | 已关闭 | 用户确认问题解决并关闭 |
### 4.3 RegulatoryIssue.risk_level
| value | 中文展示 | 说明 |
| --- | --- | --- |
| blocking | 阻断项 | 直接影响资料能否进入有效申报或审核 |
| high | 高风险 | 可能导致注册审评补正或重大整改 |
| medium | 中风险 | 需要补充说明或修改 |
| low | 低风险 | 建议修正但影响较小 |
| info | 提示项 | 系统无法充分判断或建议人工关注 |
### 4.4 其他枚举
| 字段 | value |
| --- | --- |
| issue_type | completeness、structure、consistency、notification、review |
| artifact_type | condition_record、rule_matrix、risk_list、text_extract_json、rag_result_json、notification_record、review_record |
| file_format | markdown、excel、json |
| send_status | pending、success、failed |
| channel | feishu_cli、feishu_api、mock |
---
## 五、软删除与归档策略
| 对象 | 策略 |
| --- | --- |
| RegulatoryRuleVersion | 使用 `is_deleted` 软删除;已被批次引用的版本不允许物理删除 |
| RegulatoryReviewBatch | 使用 `is_deleted``archived_at` 归档;归档后默认不在对话主列表展示 |
| RegulatoryIssue | 使用 `is_deleted` 软删除;删除时保留批次摘要和过程产物 |
| RegulatoryArtifact | 使用 `is_deleted` 软删除;正式环境可配合对象存储生命周期归档 |
| RegulatoryNotificationRecord | 使用 `is_deleted` 软删除;保留通知失败原因和重试次数 |
删除 Conversation 时,本期不建议物理级联法规核查数据。应先标记相关批次归档或删除,再由后台清理任务处理文件和产物。
---
## 六、过程产物存储设计
### 6.1 存储目录
法规核查过程产物使用独立目录,按用户、对话、法规核查批次隔离:
```text
media/regulatory_review/{user_id}/{conversation_id}/{batch_id}/
```
示例:
```text
media/regulatory_review/12/1001/2001/
condition_record.md
condition_record.json
rule_matrix.xlsx
risk_list.md
risk_list.json
text_extract.json
rag_result.json
notification_record.md
review_record.json
```
### 6.2 文件 hash
`ra_regulatory_artifact.file_hash` 必填。建议使用 SHA-256。
| 场景 | 处理 |
| --- | --- |
| 文件生成成功 | 计算 hash 后写入记录 |
| hash 计算失败 | 产物生成视为失败,节点进入 partial_success 或 failed |
| 下载文件 | 可选重新计算 hash 校验 |
---
## 七、JSON 字段结构建议
### 7.1 condition_json
```json
{
"extracted": {
"product_category": {"value": "in_vitro_diagnostic", "confidence": 0.92},
"registration_type": {"value": "initial_registration", "confidence": 0.76}
},
"confirmed": {
"confirmed_by": 1,
"confirmed_at": "2026-06-06T00:00:00+08:00",
"source": "dialog_choice"
},
"raw_user_input": "按体外诊断试剂首次注册处理"
}
```
### 7.2 risk_summary_json
```json
{
"blocking": 2,
"high": 1,
"medium": 3,
"low": 4,
"info": 2,
"notified": {
"feishu": 6
}
}
```
### 7.3 evidence_json
```json
{
"matched_rule": {
"rule_id": "ivd_registration_test_report",
"rule_title": "注册检验报告"
},
"matched_files": [
{
"file_item_id": 33,
"relative_path": "注册检验/检验报告.pdf",
"matched_by": "directory_keyword"
}
],
"rag_citations": [
{
"source_file": "体外诊断试剂注册申报资料要求及说明.doc",
"section_title": "注册申报资料要求",
"snippet": "..."
}
]
}
```
---
## 八、与现有表的改造建议
### 8.1 ra_workflow_node_run
第一阶段设计中该表通过 `batch_id` 直接关联文件汇总批次。法规核查复用同一套工作流状态机制,采用通用工作流引用:
| 字段 | 说明 |
| --- | --- |
| workflow_type | 新增,用于区分 file_summary 和 regulatory_review |
| workflow_batch_id | 新增,记录对应工作流批次 ID |
| batch_id | 保留,兼容文件汇总旧逻辑 |
### 8.2 ra_workflow_event
同样增加 `workflow_type``workflow_batch_id`,使 SSE 能同时服务文件汇总和法规核查卡片。
### 8.3 ra_exported_summary_file
最终法规核查报告复用导出文件表。现有 `batch_id` 关联文件汇总批次,需要通用化:
| 字段 | 说明 |
| --- | --- |
| workflow_type | 新增,用于区分 file_summary 和 regulatory_review |
| workflow_batch_id | 新增,记录对应工作流批次 ID |
| batch_id | 保留,兼容文件汇总旧逻辑 |
| export_category | 新增,用于区分 summary_report、risk_report、excel_list、json_package |
最终法规核查报告进入 `ExportedSummaryFile`,过程产物进入 `RegulatoryArtifact`
---
## 九、Django Model 命名建议
| 表名 | Model 名称 |
| --- | --- |
| ra_regulatory_rule_version | RegulatoryRuleVersion |
| ra_regulatory_review_batch | RegulatoryReviewBatch |
| ra_regulatory_issue | RegulatoryIssue |
| ra_regulatory_artifact | RegulatoryArtifact |
| ra_regulatory_notification_record | RegulatoryNotificationRecord |
---
## 十、验收检查点
| 序号 | 检查项 | 验收标准 |
| --- | --- | --- |
| 1 | 规则版本可追溯 | 每个法规核查批次能查到 rule_version、source_path、rule_file_hash 和 rag_index_version |
| 2 | 批次可多次核查 | 同一个 FileSummaryBatch 可创建多个 RegulatoryReviewBatch |
| 3 | 软删除可用 | 归档或删除法规核查批次后,默认列表不展示但历史可追溯 |
| 4 | 问题可筛选 | 可按 risk_level、status、owner 查询待处理问题 |
| 5 | 证据可追溯 | Issue 可查到 file_path、page_no、field_name 和 evidence_json |
| 6 | 产物可校验 | 每个 RegulatoryArtifact 都有 file_hash |
| 7 | 飞书可重试 | NotificationRecord 可记录 retry_count、send_status 和失败原因 |
| 8 | 权限可追溯 | 所有法规核查数据可通过 batch -> conversation -> user 校验访问权限 |
---
## 十一、后续实现注意事项
| 序号 | 问题 | 当前建议 |
| --- | --- | --- |
| 1 | WorkflowNodeRun/Event 通用化 | 已确定新增 workflow_type 和 workflow_batch_id保留 batch_id 兼容文件汇总 |
| 2 | ExportedSummaryFile 通用化 | 已确定新增 workflow_type、workflow_batch_id 和 export_category |
| 3 | RegulatoryArtifact 下载接口 | 按 batch -> conversation -> user 校验权限 |
| 4 | 飞书用户映射 | 暂通过 User 扩展字段或配置表映射飞书 CLI 可识别账号 |
| 5 | 规则文件 hash 计算时机 | 规则导入或激活时计算并写入 RegulatoryRuleVersion |