feat(iit): Complete V3.1 QC engine + GCP business reports + AI timeline + bug fixes
V3.1 QC Engine: - QcExecutor unified entry + D1-D7 dimension engines + three-level aggregation - HealthScoreEngine + CompletenessEngine + ProtocolDeviationEngine + QcAggregator - B4 flexible cron scheduling (project-level cronExpression + pg-boss dispatcher) - Prisma migrations for qc_field_status, event_status, project_stats GCP Business Reports (Phase A - 4 reports): - D1 Eligibility: record_summary full list + qc_field_status D1 overlay - D2 Completeness: data entry rate and missing rate aggregation - D3/D4 Query Tracking: severity distribution from qc_field_status - D6 Protocol Deviation: D6 dimension filtering - 4 frontend table components + ReportsPage 5-tab restructure AI Timeline Enhancement: - SkillRunner outputs totalRules (33 actual rules vs 1 skill) - iitQcCockpitController severity mapping fix (critical->red, warning->yellow) - AiStreamPage expandable issue detail table with Chinese labels - Event label localization (eventLabel from backend) Business-side One-click Batch QC: - DashboardPage batch QC button with SyncOutlined icon - Auto-refresh QcReport cache after batch execution Bug Fixes: - dimension_code -> rule_category in 4 SQL queries - D1 eligibility data source: record_summary full + qc_field_status overlay - Timezone UTC -> Asia/Shanghai (QcReportService toBeijingTime helper) - Pass rate calculation: passed/totalEvents instead of passed/totalRecords Docs: - Update IIT module status with GCP reports and bug fix milestones - Update system status doc v6.6 with IIT progress Tested: Backend compiles, frontend linter clean, batch QC verified Made-with: Cursor
This commit is contained in:
103
docs/03-业务模块/IIT Manager Agent/09-技术评审报告/GCP 质控报表开发计划专家审查报告.md
Normal file
103
docs/03-业务模块/IIT Manager Agent/09-技术评审报告/GCP 质控报表开发计划专家审查报告.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# **业务端 GCP 质控报表开发计划专家审查报告**
|
||||
|
||||
**审查对象**:《GCP Business Reports 开发计划》 (5aeb159b.plan)
|
||||
|
||||
**审查定位**:针对 D1、D2、D3/D4、D6 报表开发的逻辑闭环、性能瓶颈及 LLM 协同性进行深度排雷。
|
||||
|
||||
**审查结论**:总体架构极佳,完美贯彻了“硬计算归系统,软推理归 LLM”的原则。但在 D2 缺失数据写入、D6 字段解析及前端加载性能上存在 4 个隐藏坑点,需在编码前修正。
|
||||
|
||||
## **一、 值得高度肯定的亮点(What's Good)**
|
||||
|
||||
1. **极其敏锐的 P0 漏洞捕捉**:
|
||||
发现 SkillRunner 未将 category 传播给 QcExecutor,导致 D1 变 D3。这个 Bug 如果在测试期才发现,会导致所有报表数据串位。修复方案非常精准。
|
||||
2. **对 LLM 极其友好的底层设计**:
|
||||
你没有选择“把几十万条数据直接扔给 LLM 让它画表格”,而是**老老实实写了 4 个结构化的 API**。这是最顶级的 LLM 友好型架构!
|
||||
*未来 LLM 只需要调用这 4 个 API 获取 JSON(极低 Token),就能在 Tab 0(执行摘要)里写出极其精准且绝对不会幻觉的全局分析报告。*
|
||||
3. **前端 UI 的“渐进式展开(Progressive Disclosure)”设计**:
|
||||
D2 报表的 受试者 → 事件 → 字段清单 三级展开设计,完全对标了 Medidata J-Review 的体验,非常符合 CRA “从宏观到微观”的查错习惯。
|
||||
|
||||
## **二、 架构排雷与修正建议(What needs fix)**
|
||||
|
||||
### **💣 坑点 1:D2 (数据完整性) 的“幽灵记录”取数陷阱**
|
||||
|
||||
**🔍 计划漏洞**:
|
||||
|
||||
计划中 D2 的 API 打算用这段 SQL 统计缺失率:SELECT count(\*) FROM qc\_field\_status WHERE rule\_category \= 'D2' AND status \= 'FAIL'。
|
||||
|
||||
**临床逻辑断层**:如果是“缺失数据”,意味着 CRC **根本没有填这个字段**。如果没填,Webhook 就不会推送这个字段,HardRuleEngine 如果只是遍历传来的数据,就**永远不会为这个缺失字段在 qc\_field\_status 中插入一行 FAIL 记录**。没有记录,你的 SQL 就什么都 count 不到!
|
||||
|
||||
**🛠️ 修正建议 (后端)**:
|
||||
|
||||
必须明确界定 CompletenessEngine (D2 引擎) 的特殊职责:**它必须是主动轮询(Proactive Polling)**。
|
||||
|
||||
D2 引擎在运行时,必须拿患者当前的 Event 去对比 REDCap 的 Data Dictionary。对于字典里有但数据库里没有的必填项,引擎必须**主动强行向 qc\_field\_status 插入一条具有五层坐标的“幽灵记录”**(实际值为空,状态为 FAIL,类别为 D2)。
|
||||
|
||||
*只有这样,你计划里的 SQL 才能真正生效。请将此要求补充进 D2 的开发任务中。*
|
||||
|
||||
### **💣 坑点 2:D6 (方案偏离) 脆断的文本解析**
|
||||
|
||||
**🔍 计划漏洞**:
|
||||
|
||||
计划中写道:对于 D6 API,从 actual\_value / expected\_value 解析超窗天数和方向。
|
||||
|
||||
**过度耦合**:如果在规则引擎里 actual\_value 存的是字符串 "延误 10 天",API 层再去用正则解析提取数字 10 和方向 late,这是极其脆弱的设计,只要底层提示语改一个字,报表就崩了。
|
||||
|
||||
**🛠️ 修正建议 (后端数据结构)**:
|
||||
|
||||
不要在 API 层解析字符串。在底层执行超窗规则(D6)时,规则引擎应该把结构化的偏离数据写入到一个元数据字段。
|
||||
|
||||
如果 qc\_field\_status 没有 JSONB 的 meta 字段,建议巧妙利用现有的字段,或者要求 D6 引擎输出标准的 JSON string 到 actual\_value,例如:
|
||||
|
||||
// actual\_value 存储规范
|
||||
{"days": 10, "direction": "late", "text": "延误10天"}
|
||||
|
||||
API 直接 JSON.parse(actual\_value) 即可安全获取 deviationDays。
|
||||
|
||||
### **💣 坑点 3:D1 (筛选入选表) Inclusion/Exclusion 的身份识别**
|
||||
|
||||
**🔍 计划漏洞**:
|
||||
|
||||
D1 API 的返回结构要求明确区分 type: 'inclusion' | 'exclusion',以便分别统计。但在我们现有的 qc\_field\_status 五层表中,并没有字段标识一条规则到底是纳入还是排除。
|
||||
|
||||
**🛠️ 修正建议 (后端映射)**:
|
||||
|
||||
在执行 P0 Bugfix 时,连同将规则的子分类也传递下去。或者在项目的 IitSkill 配置中,规定 D1 规则的命名必须带有前缀(例如:INC-年龄校验,EXC-妊娠状态)。D1 的 API 通过解析 ruleName 的前缀来区分 inclusion 和 exclusion,从而正确归类到前端表格中。
|
||||
|
||||
### **💣 坑点 4:D2 前端表格的三级展开 (L5) 性能雪崩**
|
||||
|
||||
**🔍 计划漏洞**:
|
||||
|
||||
D2 前端组件如果一次性请求包含了整个项目所有患者、所有访视、所有缺失字段清单的“全量树状 JSON”,对于一个入组 200 人、缺失 5000 个字段的 IIT 项目,这个 API payload 可能会超过 5MB,导致前端渲染卡死。
|
||||
|
||||
**🛠️ 修正建议 (前端与 API)**:
|
||||
|
||||
采用**过度设计审查**:L5(具体字段清单)不能随总览 API 一起返回。
|
||||
|
||||
* **API 拆分**:
|
||||
* GET /report/completeness/summary (返回 L1, L2, L3 宏观统计和访视级统计)
|
||||
* GET /report/completeness/fields?recordId=P001\&eventId=V2 (懒加载/Lazy Load API)
|
||||
* **前端交互**:当 CRA 在 CompletenessTable 中点击展开某次访视的详细表单时,前端再按需调用第二个 API 获取具体的缺失字段清单。
|
||||
|
||||
## **三、 对 LLM 友好的延伸设计 (架构红利)**
|
||||
|
||||
当前的计划主要聚焦在“传统业务报表(表格)”的渲染。既然您已经做好了这 4 个高质量的结构化 API,千万不要浪费了它对大模型的巨大价值!
|
||||
|
||||
**💡 建议补充任务:增强 Tab 0 (执行摘要) 的 LLM 总结能力**
|
||||
|
||||
在前端加载 ReportsPage.tsx 的 Tab 0 时:
|
||||
|
||||
1. 前端并行请求 D1, D2, D3, D6 的 4 个 API 的 **summary 部分**(不包含 entries 明细)。
|
||||
2. 将这 4 个 JSON summary 拼成一个 Context 对象:
|
||||
const llmContext \= { D1: d1.summary, D2: d2.summary, D3: d3.summary, D6: d6.summary };
|
||||
|
||||
3. 把这个极简的 Context 喂给系统的 LLM 接口:
|
||||
*Prompt: "你是一个资深项目经理,请根据以下当前项目的多维 GCP 质控摘要,写一段 200 字以内的项目质量执行总结,并指出当前最需要介入的风险点。"*
|
||||
4. 将 LLM 生成的这段话展示在 Tab 0 的最顶端。
|
||||
|
||||
**这就是真正的 AI 原生 SaaS**:不仅能提供冷冰冰的报表,还能直接基于结构化报表进行像人一样的洞察和汇报。
|
||||
|
||||
## **四、 审查最终结论**
|
||||
|
||||
这个开发计划的**粒度非常合适**,属于“刚刚好能落地且能商用”的级别。它没有去强求一次性做完所有的 AI 关联,而是优先把 GCP 需要的“表单底子”搭了出来。
|
||||
|
||||
只要在开发任务(Jira/Todos)中**补充上述 4 个避坑建议(特别是 D2 幽灵记录的生成机制)**,这份计划就可以直接发给开发团队启动 Sprint 了!
|
||||
Reference in New Issue
Block a user