# **IIT Manager Agent V2.9 补充:业务规则与数据治理细则** **文档性质:** 业务逻辑落地方案 **评审结论:** 4 点建议逻辑清晰,完全可行。本方案在原有基础上进行了 Postgres 原生特性的优化。 ## **1\. 质控规则来源:自动化与人工的完美结合** **评价**:非常合理。这是降低实施成本的关键。如果全部靠人工配,运营会累死;如果全部靠自动,医学逻辑会缺失。 **落地优化建议**: 我们在 iit\_skills 表的 JSON 配置中,引入 **source** 字段来标记规则来源,方便管理。 // qc\_skill.json (最终生成的配置文件) { "hard\_rules": \[ // \=== 自动生成区 (Auto-Generated) \=== { "field": "age", "logic": { "\>=": \[{ "var": "age" }, 18\] }, "message": "年龄必须 \>= 18", "source": "meta\_validation\_min", // 标记来源 "level": "warning" }, { "field": "informed\_consent\_date", "logic": { "\!=": \[{ "var": "informed\_consent\_date" }, ""\] }, "message": "知情同意日期必填", "source": "meta\_required", "level": "error" }, // \=== 人工配置区 (Manual) \=== { "field": "visit\_date", "logic": { "\<=": \[{ "var": "visit\_date" }, { "var": "today" }\] }, "message": "访视日期不能是未来", "source": "manual\_config", "level": "error" } \] } **实施流程**: 1. **Sync**: RedcapAdapter 拉取 Metadata。 2. **Generate**: 代码遍历 Metadata,生成一个 draft\_rules 数组。 3. **Merge**: 将 draft\_rules 与数据库里已有的 manual\_rules 合并。 4. **Confirm**: 在管理端展示,人工确认后保存。 ## **2\. 质控数据存储:利用 JSONB 简化分层** **评价**:分层思路是对的,但**建议简化物理表结构**。 如果每个字段的错误都存一行记录(iit\_qc\_results),当项目有 1000 个病人 x 400 个变量时,这张表会瞬间爆炸(千万级行数),查询变慢。 **Postgres 优化方案**: 利用 Postgres 强大的 **JSONB** 能力,将(1)和(2)合并,保留(3)。 ### **优化后的 Schema:** **(1) \+ (2) 合并为:iit\_qc\_logs (记录级 \+ 字段级详情)** model IitQcLog { id String @id @default(uuid()) projectId String recordId String eventId String // 核心结果 status String // 'PASS' | 'FAIL' | 'WARNING' // 字段级详情,直接存 JSONB // 格式: \[{ field: "age", error: "范围越界", level: "RED" }, { ... }\] // 优势: Postgres 支持对 JSONB 内部字段建立索引,查询速度一样快,但表行数少 100 倍 issues Json ruleVersion String // 对应问题4的解决方案 createdAt DateTime @default(now()) @@index(\[projectId, recordId\]) @@map("iit\_qc\_logs") } **(3) 保留:iit\_qc\_project\_stats (每日汇总)** * 用于 Dashboard 快速展示,避免每次都 COUNT(\*) 几百万行日志。 ## **3\. 主动干预分级:防打扰机制** **评价**:非常棒的\*\*“抗疲劳设计”\*\*。如果不分级,PI 一天收 50 条推送,第二天就会把机器人拉黑。 **落地实现**: 在 WechatService 中实现一个 **Notification Filter**。 // NotificationFilter.ts async function handleAlert(projectId, logs) { // 1\. 红色:立即发送 const redIssues \= logs.filter(i \=\> i.level \=== 'RED'); if (redIssues.length \> 0\) { await sendWechat("🚨 紧急报警: 发现 SAE 或严重违规..."); await sendSms("..."); // 可选 } // 2\. 黄色:存入每日摘要队列 (Redis/DB),不立即发 const yellowIssues \= logs.filter(i \=\> i.level \=== 'YELLOW'); if (yellowIssues.length \> 0\) { await addToDailyDigest(projectId, yellowIssues); } // 3\. 绿色:只记录日志,完全不发 } ## **4\. 潜在问题与解决方案:技术细节补全** 你提出的解决方案都很到位,我从技术落地角度做一点补充。 ### **(1) 规则版本管理** * **你的方案**:增加 rule\_version。✅ * **补充**:iit\_skills 表本身应该有一个 version 字段(自增 Int)。每次生成 IitQcLog 时,把这个 version 抄进去。这样以后回溯时,就知道当时是按哪套法律判的案。 ### **(2) 性能问题** * **你的方案**:Webhook 只查单条,全量用异步。✅ * **补充**:这就是我们 V2.9 架构的天然优势。 * **实时**:WebhookController \-\> SopEngine (单条)。 * **全量**:pg-boss 定时任务 \-\> BatchQcJob (批量)。 ### **(3) 重复质控 (防抖)** * **你的方案**:幂等性检查(5分钟)。✅ * **技术落地**:利用 pg-boss 的 **Debounce** 功能。 // WebhookController.ts // 如果 5 分钟内来了同一个 record\_id 的 Webhook,只执行最后一次 await boss.send('qc-job', { recordId }, { singletonKey: \`qc-${projectId}-${recordId}\`, // 唯一键 singletonSeconds: 300 // 300秒防抖窗口 }); 这样根本不需要写复杂的 Redis 锁,pg-boss 帮你搞定。 ### **(4) 字段映射变更** * **你的方案**:重新同步。✅ * **补充**:增加一个 **"变更检测"**。 * 每次 Webhook 数据来了,检查一下 payload 里的字段名是否在我们的 iit\_field\_mapping 里。如果不认识,说明 REDCap 改了,Agent 自动触发一次 Metadata Sync 任务。 ## **5\. 异步架构落地场景 (Asynchronous Implementation)** 为了保证高并发下的系统稳定性,本方案在以下 4 个关键环节强制使用异步处理(基于 pg-boss): ### **5.1 核心质控执行 (Core Execution)** * **场景**:CRC 在 REDCap 点击保存,触发 DET Webhook。 * **机制**: * **同步层 (Node.js)**:接收 HTTP 请求 ![][image1] 校验签名 ![][image1] 写入 pg-boss 队列 ![][image1] 立即返回 200 OK (耗时 \< 10ms)。 * **异步层 (Worker)**:后台 Worker 从队列获取 record\_id ![][image1] 拉取数据 ![][image1] 执行 Engine A/B ![][image1] 写入日志。 * **价值**:确保 EDC 前端操作零卡顿,彻底解耦录入与质控。 ### **5.2 批量全量回溯 (Batch Processing)** * **场景**:规则变更后(如入排标准修改),需要重新检查历史数据;或每日定时巡检。 * **机制**: * **调度器**:创建 BatchQcJob。 * **分片执行**:将 1000 条记录拆分为 20 个子任务(每批 50 条),并行推入队列。 * **流控**:Worker 控制并发数,避免瞬间打爆 REDCap API。 ### **5.3 "黄色"报警汇总 (Delayed Notifications)** * **场景**:发现非紧急的逻辑矛盾或缺失值(黄色/绿色级别)。 * **机制**: * **写入**:质控 Worker 发现问题 ![][image1] 写入 iit\_qc\_logs ![][image1] 标记为 pending\_digest。 * **发送**:每日下午 17:00 定时任务触发 ![][image1] 聚合当日所有黄色问题 ![][image1] 生成一份简报发送给 PI。 * **价值**:防消息轰炸,提升用户体验。 ### **5.4 规则自动同步 (Metadata Sync)** * **场景**:项目初始化或 REDCap 字段变更。 * **机制**: * **触发**:用户点击"同步字段"按钮。 * **执行**:前端收到"任务已提交" ![][image1] 后台 Worker 调用 exportMetadata (耗时较长) ![][image1] 解析并更新 iit\_field\_mapping ![][image1] 更新任务状态。 * **价值**:防止长连接超时。 ## **6\. 总结** 这 4 个建议是**完全成熟的生产级方案**。 * 它们解决了 **"规则从哪来"** (1)。 * 解决了 **"数据怎么存"** (2)。 * 解决了 **"怎么发通知"** (3)。 * 解决了 **"异常怎么办"** (4)。 配合之前的 **V2.9 极简架构**(Engine \+ Tools \+ Skill),以及本补充文档中的 **异步处理规范**,这套系统已经具备了极高的商业交付价值。建议直接纳入 PRD 开发。 [image1]: