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

218 lines
7.2 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.
# 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` 接口新增 `applicableEvents``applicableForms` 字段 |
| `SoftRuleEngine.ts` | `SoftRuleCheck` 接口同样新增事件/表单适用性字段 |
| `SkillRunner.ts` | 重构 `runByTrigger()` 按 record+event 独立执行质控 |
| `SkillRunner.ts` | 新增 `filterApplicableRules()` 方法,按事件/表单动态过滤规则 |
| `SkillRunner.ts` | `SkillRunResult` 新增 `eventName``eventLabel``forms` 字段 |
| `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 修复后正常 |
---
## 📝 配置说明
### 规则适用性配置示例
```typescript
// 在 Skill 配置中设置规则的适用表单
{
"id": "inc_001",
"name": "年龄范围检查",
"applicableForms": ["basic_demography_form"], // 只在人口学表单执行
"applicableEvents": [] // 空数组 = 适用所有事件
}
```
### 执行配置更新脚本
```bash
cd backend
npx tsx update-skill-applicable-forms.ts
```
---
## 🔄 后续优化建议
1. **规则配置 UI**:在管理端添加规则 → 表单映射的可视化配置界面
2. **事件标签显示**:在报告中显示事件的中文标签(如"筛选期")而非唯一标识
3. **增量质控**:只对有变化的事件执行质控,避免全量重算
4. **质控历史**:保留历史质控结果,支持趋势分析
---
## 📚 相关文档
- [模块状态文档](../00-模块当前状态与开发指南.md)
- [实时质控系统开发记录](./2026-02-07-实时质控系统开发记录.md)
- [质控系统 UI 与 LLM 格式优化计划](../04-开发计划/07-质控系统UI与LLM格式优化计划.md)
---
> **总结:** 本次开发完成了 IIT 质控系统从"记录级"到"事件级"的架构升级解决了数据合并覆盖、报告重复、AI 无法回答等多个问题,为 REDCap 纵向研究提供了更精确的质控能力。