218 lines
7.2 KiB
Markdown
218 lines
7.2 KiB
Markdown
# 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 纵向研究提供了更精确的质控能力。
|