Files
AIclinicalresearch/docs/03-业务模块/IIT Manager Agent/06-开发记录/2026-02-08-事件级质控与报告优化开发记录.md

7.2 KiB
Raw Permalink Blame History

2026-02-08 事件级质控与报告优化开发记录

开发日期: 2026-02-08
开发人员: AI Assistant
版本: V3.1
状态: 基本测试成功


📋 开发概述

本次开发主要完成了 IIT Manager Agent 质控系统的重大架构升级,从"记录级合并质控"改为"事件级独立质控",同时优化了质控报告生成逻辑和 AI 对话能力。


🎯 核心改动

1. 事件级质控架构V3.1

问题背景:

  • REDCap 纵向研究中,一个 record_id 可能有多个事件如筛选期、随访1、随访2等
  • 之前的质控将所有事件的数据合并到一条记录,导致数据覆盖问题
  • 不同事件的表单应该独立质控

解决方案:

改动文件 改动内容
RedcapAdapter.ts 新增 getAllRecordsByEvent() 方法,按 record+event 返回独立数据单元
RedcapAdapter.ts 新增 getFormEventMapping()getEvents() 获取事件配置
RedcapAdapter.ts 新增 getFormCompletionStatusByEvent() 按事件获取表单完成状态
HardRuleEngine.ts QCRule 接口新增 applicableEventsapplicableForms 字段
SoftRuleEngine.ts SoftRuleCheck 接口同样新增事件/表单适用性字段
SkillRunner.ts 重构 runByTrigger() 按 record+event 独立执行质控
SkillRunner.ts 新增 filterApplicableRules() 方法,按事件/表单动态过滤规则
SkillRunner.ts SkillRunResult 新增 eventNameeventLabelforms 字段
SkillRunner.ts saveQcLog() 现在保存 eventId 到数据库

架构变化:

之前(记录级合并):
Record 1 = Event A 数据 + Event B 数据 + ... (合并可能覆盖)

之后(事件级独立):
Record 1 + Event A = 独立质控单元 1
Record 1 + Event B = 独立质控单元 2
...

2. 质控报告优化

问题背景:

  • 报告从多个事件收集问题,导致同一规则重复出现
  • 报告使用缓存,不是最新数据
  • 显示限制导致部分问题被隐藏

解决方案:

改动文件 改动内容
QcReportService.ts SQL 查询改用 DISTINCT ON (record_id, event_id)
QcReportService.ts 新增 deduplicateIssues() 按 recordId+ruleId 去重
QcReportService.ts 统计计数也按 recordId+ruleId 去重(使用 Set
QcReportService.ts 移除所有 slice 显示限制,显示所有问题
QcReportService.ts 兼容新旧两种 issues 格式(数组 vs { items: [...] }

3. 批量操作 API 更新

改动文件 改动内容
iitBatchController.ts batchQualityCheck 改用 SkillRunner.runByTrigger()
ToolsService.ts batch_quality_check 工具同样改用事件级质控

4. 前端优化

改动文件 改动内容
QcReportDrawer.tsx 导出 XML 前自动刷新报告(确保获取最新数据)
QcReportDrawer.tsx 文件名添加时分HHMM格式便于区分
IitQcCockpitPage.tsx 删除重复的"全量质控"按钮(保留配置页的)

5. AI 对话增强

改动文件 改动内容
ChatService.ts 增强意图识别,支持更多质控查询表达方式
PromptBuilder.ts 修复 this 上下文丢失导致的 500 错误

🐛 修复的 Bug

Bug 1: formatPatientData undefined 错误

现象: 点击记录详情时返回 500 错误

原因: buildClinicalSlice 函数导出时丢失了 this 上下文

修复:this.formatPatientData 改为 PromptBuilder.formatPatientData

Bug 2: 质控报告重复问题

现象: Record 1 显示 14 条违规,实际应该是 5 条

原因: 同一规则在多个事件中执行,结果都被收集到报告中

修复:recordId + ruleId 去重,只保留最新结果

Bug 3: 报告记录数不正确

现象: 显示 13 条记录,实际有 14 条

原因:iitRecordSummary 获取记录数,该表可能缺少记录

修复: 从质控日志获取独立 record_id 数量

Bug 4: AI 无法回答质控问题

现象: 问"严重违规有几项"AI 说"没有相关信息"

原因: 意图识别规则不够全面

修复: 增加更多匹配模式质控问题、严重违规、record问题等


📁 涉及文件清单

后端核心文件

backend/src/modules/iit-manager/
├── adapters/
│   └── RedcapAdapter.ts              ✅ 新增 3 个方法
├── engines/
│   ├── HardRuleEngine.ts             ✅ QCRule 接口扩展
│   ├── SoftRuleEngine.ts             ✅ SoftRuleCheck 接口扩展
│   └── SkillRunner.ts                ✅ 事件级质控核心重构
├── services/
│   ├── QcReportService.ts            ✅ 去重 + 移除限制
│   ├── ChatService.ts                ✅ 意图识别增强
│   ├── PromptBuilder.ts              ✅ 修复 this 上下文
│   └── ToolsService.ts               ✅ batch_quality_check 更新

backend/src/modules/admin/iit-projects/
└── iitBatchController.ts             ✅ 使用 SkillRunner

前端文件

frontend-v2/src/modules/admin/
├── components/qc-cockpit/
│   └── QcReportDrawer.tsx            ✅ 自动刷新 + 文件名优化
└── pages/
    └── IitQcCockpitPage.tsx          ✅ 删除重复按钮

🧪 测试验证

测试结果

测试项 结果 备注
事件级质控执行 14 条记录 × 5 个事件 = 70 个质控单元
规则动态过滤 配置 applicableForms 后规则只在相关事件执行
报告去重 168 条问题去重后变为 69 条
XML 导出 自动刷新 + 显示所有问题
AI 质控查询 能正确回答"严重违规有几项"
详情页 500 错误 formatPatientData 修复后正常

📝 配置说明

规则适用性配置示例

// 在 Skill 配置中设置规则的适用表单
{
  "id": "inc_001",
  "name": "年龄范围检查",
  "applicableForms": ["basic_demography_form"],  // 只在人口学表单执行
  "applicableEvents": []  // 空数组 = 适用所有事件
}

执行配置更新脚本

cd backend
npx tsx update-skill-applicable-forms.ts

🔄 后续优化建议

  1. 规则配置 UI:在管理端添加规则 → 表单映射的可视化配置界面
  2. 事件标签显示:在报告中显示事件的中文标签(如"筛选期")而非唯一标识
  3. 增量质控:只对有变化的事件执行质控,避免全量重算
  4. 质控历史:保留历史质控结果,支持趋势分析

📚 相关文档


总结: 本次开发完成了 IIT 质控系统从"记录级"到"事件级"的架构升级解决了数据合并覆盖、报告重复、AI 无法回答等多个问题,为 REDCap 纵向研究提供了更精确的质控能力。