# 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 |