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
6.7 KiB
业务端 GCP 质控报表开发计划专家审查报告
审查对象:《GCP Business Reports 开发计划》 (5aeb159b.plan)
审查定位:针对 D1、D2、D3/D4、D6 报表开发的逻辑闭环、性能瓶颈及 LLM 协同性进行深度排雷。
审查结论:总体架构极佳,完美贯彻了“硬计算归系统,软推理归 LLM”的原则。但在 D2 缺失数据写入、D6 字段解析及前端加载性能上存在 4 个隐藏坑点,需在编码前修正。
一、 值得高度肯定的亮点(What's Good)
- 极其敏锐的 P0 漏洞捕捉:
发现 SkillRunner 未将 category 传播给 QcExecutor,导致 D1 变 D3。这个 Bug 如果在测试期才发现,会导致所有报表数据串位。修复方案非常精准。 - 对 LLM 极其友好的底层设计:
你没有选择“把几十万条数据直接扔给 LLM 让它画表格”,而是老老实实写了 4 个结构化的 API。这是最顶级的 LLM 友好型架构!
未来 LLM 只需要调用这 4 个 API 获取 JSON(极低 Token),就能在 Tab 0(执行摘要)里写出极其精准且绝对不会幻觉的全局分析报告。 - 前端 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 时:
-
前端并行请求 D1, D2, D3, D6 的 4 个 API 的 summary 部分(不包含 entries 明细)。
-
将这 4 个 JSON summary 拼成一个 Context 对象:
const llmContext = { D1: d1.summary, D2: d2.summary, D3: d3.summary, D6: d6.summary }; -
把这个极简的 Context 喂给系统的 LLM 接口:
Prompt: "你是一个资深项目经理,请根据以下当前项目的多维 GCP 质控摘要,写一段 200 字以内的项目质量执行总结,并指出当前最需要介入的风险点。" -
将 LLM 生成的这段话展示在 Tab 0 的最顶端。
这就是真正的 AI 原生 SaaS:不仅能提供冷冰冰的报表,还能直接基于结构化报表进行像人一样的洞察和汇报。
四、 审查最终结论
这个开发计划的粒度非常合适,属于“刚刚好能落地且能商用”的级别。它没有去强求一次性做完所有的 AI 关联,而是优先把 GCP 需要的“表单底子”搭了出来。
只要在开发任务(Jira/Todos)中补充上述 4 个避坑建议(特别是 D2 幽灵记录的生成机制),这份计划就可以直接发给开发团队启动 Sprint 了!