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:
2026-03-01 22:49:49 +08:00
parent 0b29fe88b5
commit 2030ebe28f
50 changed files with 8687 additions and 1492 deletions

View File

@@ -1,10 +1,11 @@
# AIclinicalresearch 系统当前状态与开发指南
> **文档版本:** v6.5
> **文档版本:** v6.6
> **创建日期:** 2025-11-28
> **维护者:** 开发团队
> **最后更新:** 2026-02-27
> **最后更新:** 2026-03-01
> **🎉 重大里程碑:**
> - **🆕 2026-03-01IIT 业务端 GCP 报表 + AI 时间线增强 + 多项 Bug 修复!** 4 张 GCP 标准报表(筛选入选/完整性/质疑跟踪/方案偏离)+ AI 工作流水详情展开 + 一键全量质控 + dimension_code/时区/通过率/D1 数据源修复
> - **🆕 2026-02-27旧版系统集成完成** Token 注入自动登录 + Wrapper Bridge 架构 + Storage Access API + iframe 嵌入(研究管理 + 统计分析工具 126 个) + CSS 注入样式定制 + 本地 E2E 验证通过
> - **🆕 2026-02-27数据库文档体系 + 部署文档体系 + Prisma Schema 对齐完成!** 6 篇数据库核心文档 + 部署文档归档整理 + 统一操作手册 + 数据库开发规范 v3.0 + Cursor Rule 自动提醒 + Schema 类型漂移修正
> - **🆕 2026-02-26ASL 工具 4 SR 图表生成器 + 工具 5 Meta 分析引擎开发完成!** PRISMA 流程图(中英切换)+ 基线特征表 + Meta 分析HR/二分类/连续型)+ 森林图/漏斗图 + R Docker meta 包 + E2E 36/36 通过
@@ -33,6 +34,7 @@
> - **2026-01-22OSS 存储集成完成!** 阿里云 OSS 正式接入平台基础层
>
> **🆕 最新进展(旧版系统集成 + 数据库文档体系 2026-02-27**
> - ✅ **🆕 IIT 业务端 GCP 报表 + Bug 修复** — 4 张 GCP 标准报表D1/D2/D3D4/D6+ AI Timeline 详情展开 + 一键全量质控 + 6 项关键 Bug 修复
> - ✅ **🆕 旧版系统集成** — Token 注入自动登录 + Wrapper BridgeCookie 设置 + CSS 注入)+ Storage Access API + 本地 E2E 全部通过
> - ✅ **🆕 数据库文档体系建立** — 6 篇核心文档(架构总览/迁移历史/环境对照/技术债务/种子数据/PG扩展位于 `docs/01-平台基础层/07-数据库/`
> - ✅ **🆕 Prisma Schema 类型漂移修正** — IIT/SSA 模型 @db.* 注解对齐 + 手动迁移 + Tech Debt 注释
@@ -81,7 +83,7 @@
| **PKB** | 个人知识库 | RAG问答、私人文献库 | ⭐⭐⭐ | 🎉 **Dify已替换自研RAG上线95%** | P1 |
| **ASL** | AI智能文献 | 文献筛选、Deep Research、全文智能提取、SR图表、Meta分析 | ⭐⭐⭐⭐⭐ | 🎉 **V2.0 核心完成90%+ 🆕工具4+5完成** - SSE流式+瀑布流UI+HITL+Word导出+散装派发+PRISMA流程图+Meta分析引擎(R Docker) | **P0** |
| **DC** | 数据清洗整理 | ETL + 医学NER百万行级数据 | ⭐⭐⭐⭐⭐ | ✅ **Tool B完成 + Tool C 99%(异步架构+性能优化-99%+多指标转换+7大功能** | **P0** |
| **IIT** | IIT Manager Agent | CRA Agent - LLM Tool Use + 自驱动质控 + 统一驾驶舱 | ⭐⭐⭐⭐⭐ | 🎉 **V3.0 P0+P1完成** ChatOrchestrator + 4工具 + E2E 54/54 | **P1-2** |
| **IIT** | IIT Manager Agent | CRA Agent - LLM Tool Use + 自驱动质控 + 统一驾驶舱 | ⭐⭐⭐⭐⭐ | 🎉 **V3.1完成 + GCP报表 + Bug修复** 质控引擎升级 + 4张GCP业务报表 + AI时间线增强 + 一键全量质控 | **P1-2** |
| **SSA** | 智能统计分析 | **QPER架构** + 四层七工具 + 对话层LLM + 意图路由器 | ⭐⭐⭐⭐⭐ | 🎉 **Phase I-IV 开发完成** — QPER闭环 + Session黑板 + 意图路由 + 对话LLM + 方法咨询 + 对话驱动分析E2E 107/107 | **P1** |
| **ST** | 统计分析工具 | 126 个轻量化统计工具(旧系统 iframe 嵌入) | ⭐⭐⭐⭐ | ✅ **旧系统集成完成** — Token 注入 + Wrapper Bridge + E2E 验证通过 | P2 |
| **RVW** | 稿件审查系统 | 方法学评估 + 🆕数据侦探L1/L2/L2.5验证)+ Skills架构 + Word导出 | ⭐⭐⭐⭐ | 🚀 **V2.0 Week3完成85%** - 统计验证扩展+负号归一化+文件格式提示+用户体验优化 | P1 |
@@ -168,7 +170,7 @@
---
## 🚀 当前开发状态2026-02-26
## 🚀 当前开发状态2026-03-01
### 🎉 最新进展ASL 工具 4 + 工具 5 开发完成2026-02-26
@@ -972,9 +974,14 @@ data: [DONE]\n\n
- 🎯 **统一驾驶舱** - 去角色化设计,健康分 + 风险热力图 + AI Timeline
- 🎯 **企业微信实时通知** - 质控预警秒级推送,移动端查看
**V3.0 当前状态**:✅ **P0+P1 完成E2E 54/54 通过**
-P0自驱动质控流水线变量清单 + 规则配置 + 定时质控 + eQuery 闭环 + 驾驶舱
-P1对话层 Tool Use 改造ChatOrchestrator + Function Calling + 4 工具
**当前状态**:✅ **V3.1 质控引擎完成 + GCP 业务报表完成 + 多项 Bug 修复**
-V3.1:质控引擎五级数据结构 + D1-D7 多维报告 + 三级聚合 + HealthScore + 前端驾驶舱
-B4定时质控灵活配置项目级 cronExpression + pg-boss dispatcher
- ✅ GCP 报表4 张标准报表(筛选入选/完整性/质疑跟踪/方案偏离)后端 + 前端
- ✅ AI 时间线增强:真实规则数 + 中文事件名 + 可展开问题详情 + severity 映射
- ✅ 业务端一键全量质控 + 报告缓存自动刷新
- ✅ Bug 修复dimension_code/D1 数据源/时区 UTC→北京/通过率计算
- ✅ P0+P1自驱动质控 + ChatOrchestrator + Function Calling + E2E 54/54
- 📋 P1-2对话体验优化待开发
- 📋 P2可选功能不排期
@@ -1293,6 +1300,7 @@ AIclinicalresearch/
| **2026-01-22** | **🆕 OSS存储集成** | ✅ 阿里云OSS接入PKB文档存储云端化建立存储开发规范 |
| **2026-02-22** | **SSA Phase I-IV 完成** 🎉 | ✅ Session黑板+意图路由+对话LLM+方法咨询+QPER集成E2E 107/107 |
| **2026-02-26** | **ASL 工具 4+5 完成** 🎉 | ✅ SR图表生成器+Meta分析引擎+R Docker meta包+E2E 36/36 |
| **2026-03-01** | **IIT GCP报表+Bug修复** 🎉 | ✅ 4张GCP标准报表+AI时间线增强+一键全量质控+6项Bug修复 |
| **2026-02-27** | **DB文档+部署体系** 📚 | ✅ 6篇数据库文档+部署归档+统一操作手册+开发规范v3.0+Schema对齐 |
| **当前** | **PKB模块生产可用** | ✅ 核心功能全部实现95%自研RAG+OSS存储上线 |
| **2026-01-07 晚** | **RVW模块开发完成** 🎉 | ✅ Phase 1-3完成后端迁移+数据库扩展+前端重构) |
@@ -1481,7 +1489,7 @@ npm run dev # http://localhost:3000
### 模块完成度
-**已完成**AIA V2.085%核心功能完成、平台基础层100%、RVW95%、通用能力层升级100%)、**PKB95%Dify已替换** 🎉
- 🚧 **开发中****ASL90%,🎉 工具3 M1+M2 + 工具4 + 工具5 完成PRISMA图+Meta分析+R Docker**、DCTool C 98%Tool B后端100%Tool B前端0%、IIT60%Phase 1.5完成)、**SSAQPER主线100% + Phase I-IV 全部完成E2E 107/107Phase VI 待启动)** 🎉
- 🚧 **开发中****ASL90%,🎉 工具3 M1+M2 + 工具4 + 工具5 完成PRISMA图+Meta分析+R Docker**、DCTool C 98%Tool B后端100%Tool B前端0%)、**IIT80%V3.1引擎+GCP报表+AI时间线+Bug修复全部完成** 🎉、**SSAQPER主线100% + Phase I-IV 全部完成E2E 107/107Phase VI 待启动)** 🎉
- 📋 **未开始**ST
### 部署完成度
@@ -1631,9 +1639,9 @@ if (items.length >= 50) {
---
**文档版本**v6.4
**最后更新**2026-02-27
**本次更新**数据库文档体系建立6 篇核心文档)+ 部署文档整理归档 + Prisma Schema 类型漂移修正 + 数据库开发规范 v3.0 + Cursor Rule 自动提醒 + 部署状态更新为全部运行中
**文档版本**v6.6
**最后更新**2026-03-01
**本次更新**IIT 业务端 GCP 标准报表 4 张完成D1 筛选入选/D2 完整性/D3D4 质疑跟踪/D6 方案偏离)+ AI 工作流水时间线增强(真实规则数/中文事件名/可展开详情)+ 业务端一键全量质控 + 6 项关键 Bug 修复dimension_code/D1 数据源/时区/通过率/severity 映射/报告缓存刷新)
---

View File

@@ -0,0 +1,923 @@
# Protocol Agent 2.0 开发计划 — 工作流驱动的智能对话 Agent
> **版本:** v2.0
> **日期:** 2026-03-01
> **核心定位:** 将 6 个验证过的子 Agent 聚合为一个工作流驱动的研究方案制定智能体
> **架构模式:** 智能拼图板(工作流编排层 + 对话智能层 双层融合)
> **前置文档:**
> - `00-模块当前状态与开发指南.md`AIA 模块全貌)
> - `04-Protocol_Agent开发计划/`V1.0 MVP 设计)
> - `06-开发记录/2026-01-24-Protocol_Agent_MVP开发完成.md`
> - `06-开发记录/2026-01-25-Protocol_Agent_MVP完整交付.md`
---
## 1. 为什么需要 2.0
### 1.1 V1.0 MVP 的测试反馈11 个问题)
| # | 问题 | 根因 |
|---|------|------|
| 0 | 段落序号全为 "1." | Markdown 渲染 Bug |
| 1 | 说了队列研究,同步时还是显示 RCT | 上下文未注入已确认数据 |
| 2 | 未确认参数就可以同步,内容是 AI 编造的 | 同步按钮触发逻辑依赖关键词匹配 |
| 3 | 已确认的信息被重复讨论 | 历史消息注入方式低效 |
| 4 | 观察指标阶段 AI 又绕回样本量 | 阶段控制完全依赖 Prompt 约束 |
| 5 | 不联系对话上下文PICO 阶段说过的数据收集时间点在研究设计又问) | 阶段间上下文未传递 |
| 6 | 发送参数后又要求重复提供 | `take: 20` 历史消息截断关键信息 |
| 7 | 完成样本量计算后仍然说"正式进入样本量计算阶段" | LLM 无视 system prompt 的阶段指令 |
| 8 | 纠正后能回到正确方向,下一条消息又回退 | LLM 无法可靠维持阶段状态 |
| 9 | 正在进行观察指标设计,又回到样本量计算 | 同上Prompt 约束不可靠 |
| 10 | 同步到右侧的内容与对话讨论内容不一致 | `condenseStageData` 二次 LLM 调用改变了数据 |
### 1.2 V1.0 架构的 5 个根本缺陷
1. **编排器被绕过**`ProtocolAgentController.sendMessage` 直接调用 LLM未经过 `BaseAgentOrchestrator`Agent 框架形同虚设
2. **阶段管理 100% 靠 Prompt**`buildSystemPrompt` 用"禁止事项"约束 LLMLLM 经常违反
3. **`<extracted_data>` 机制脆弱**:依赖 LLM 在对话中输出 XML 标签,前端解析后触发同步
4. **历史消息注入低效**`take: 20` 原始消息不分阶段全部注入,浪费 Token 且丢失关键上下文
5. **未复用已验证的子 Agent 提示词**:用一个通用 `buildSystemPrompt` 取代了 6 个经过专家验证的提示词
### 1.3 核心设计理念
> **一句话定义:** Protocol Agent 2.0 = **工作流驱动的智能对话 Agent**
>
> - **工作流层**(智能拼图板)定义 6 块必须完成的"拼图",但**不强制填充顺序**,用户可以从任意话题切入
> - **对话智能层**保证用户交互的自然性和灵活性(来自 SSA 模式的核心思想:用户驱动对话流,系统智能填补空白)
> - **验证过的提示词**保证每个阶段的专业深度(复用已有 6 个子 Agent
> - **双层依赖模型**保证方法学严谨性(软依赖允许开始聊,硬依赖守卫最终同步)
>
> **核心隐喻**6 块拼图可以任意顺序完成,但每块拼图内部由经过专家验证的 AI 专家坐诊。
---
## 2. 架构设计
### 2.1 智能拼图板架构
```
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 1: 工作流编排层 — 智能拼图板 (WorkflowOrchestrator) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ ① 科学问题│ │ ② PICO │ │ ③ 选题评价│ 第一阶:定问题 │
│ │ ██░░ 40% │ │ ████ 85%│ │ ░░░░ 0% │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ ④ 研究设计│ │ ⑤ 观察指标│ │ ⑥ 样本量 │ 第二阶:做设计 │
│ │ ██░░ 50% │ │ ░░░░ 0% │ │ ░░░░ 0% │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ SmartFocus: 当前聚焦 → ② PICO建议非强制
│ 用户可随时切换到任意阶段讨论 │
│ │
│ 依赖关系(软约束): │
│ 科学问题 ─soft→ PICO ─soft→ 选题评价 │
│ │ │
│ └─soft→ 研究设计 ─soft→ 观察指标 ─soft→ 样本量 │
│ │
│ 同步守卫(硬约束): │
│ 同步样本量 ←hard─ 研究设计已确认 + 主要指标已确认 │
└──────────────────────┬──────────────────────────────────────────────┘
│ 每次对话
┌─────────────────────────────────────────────────────────────────────┐
│ Layer 2: 对话智能层 (ConversationIntelligence) │
│ │
│ ┌────────────┐ ┌───────────────────┐ ┌──────────────────┐ │
│ │ Opening │ │ Intent │ │ Prompt │ │
│ │ Analyzer │→ │ Router │→ │ Selector │ │
│ │ (首条消息) │ │ (7 种意图) │ │ (依赖感知选择) │ │
│ └────────────┘ └───────────────────┘ └────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────┐ ┌────────────────────────────────────┐ │
│ │ Conversation │ │ Post-Process Pipeline │ │
│ │ Service │→ │ GlobalExtract → CheckProgress │ │
│ │ (验证提示词 + │ │ → SmartFocus → SyncGuard? │ │
│ │ 黑板上下文注入) │ └────────────────────────────────────┘ │
│ └───────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ ProtocolBlackboard (Session 黑板 — 单一真相源) │ │
│ │ 科学问题 ██░░ 40% PICO ████ 85% 🔄 选题评价 ░░░░ 0% │ │
│ │ 研究设计 ██░░ 50% 观察指标 ░░░░ 0% 样本量 ░░░░ 0% │ │
│ └──────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
```
### 2.2 核心组件职责
| 组件 | 层级 | 职责 | 复用来源 |
|------|------|------|---------|
| **WorkflowOrchestrator** | 工作流层 | 管理 6 阶段拼图板、依赖关系(软/硬、SmartFocus 推荐 | 新建 |
| **StageRegistry** | 工作流层 | 注册 6 个阶段的提示词、输出 Schema、完成标准、软硬依赖 | 新建(消费已有 Prompt |
| **OpeningAnalyzer** | 对话智能层 | 首条消息分析,判定开场模式(新手/有经验/跳阶段),初始化黑板 | 新建 |
| **IntentRouter** | 对话智能层 | 轻量级意图分类7 种意图) | 参考 SSA IntentRouterService |
| **PromptSelector** | 对话智能层 | 根据 focusStage + 前提条件选择 Prompt 策略(完整模式/依赖感知模式) | 新建 |
| **ConversationService** | 对话智能层 | 组装 system prompt + 黑板上下文 + 对话历史 → LLM 流式生成 | 参考 SSA ConversationService |
| **ProtocolBlackboard** | 对话智能层 | 统一存储所有阶段的结构化数据(单一真相源) | 参考 SSA SessionBlackboard |
| **GlobalExtractTool** | 对话智能层 | 每次 AI 回复后全域提取(可同时更新多个阶段黑板) | 新建 |
| **CheckProgressTool** | 对话智能层 | 评估各阶段完整度 + 硬依赖守卫 | 新建 |
| **SyncElementTool** | 对话智能层 | 用户确认后同步数据到方案(含硬依赖校验) | 重构现有 sync |
### 2.3 阶段定义与验证提示词映射
| # | 阶段 | Prompt Code | 输出 Schema | 完成标准 |
|---|------|-------------|-------------|---------|
| 1 | 科学问题梳理 | `AIA_SCIENTIFIC_QUESTION` | `{ content: string }` | content 非空且 ≥30 字 |
| 2 | PICO 梳理 | `AIA_PICO_ANALYSIS` | `{ population, intervention, comparison, outcome }` | 4 字段均非空 |
| 3 | 选题评价 | `AIA_TOPIC_EVALUATION` | `{ feasibility, novelty, significance, summary }` | summary 非空 |
| 4 | 研究设计 | 新建 `PA_STUDY_DESIGN`(基于验证提示词适配) | `{ studyType, designFeatures[], details }` | studyType 非空 |
| 5 | 观察指标设计 | `AIA_OUTCOME_DESIGN` | `{ outcomes: { primary[], secondary[], safety[] }, confounders[] }` | primary 至少 1 项 |
| 6 | 样本量计算 | `AIA_SAMPLE_SIZE` | `{ sampleSize, calculation: { alpha, power, effectSize }, rationale }` | sampleSize > 0 |
> **关键原则**:验证过的提示词从 `capability_schema.prompt_templates` 数据库加载(通过 `PromptService`),不硬编码在 TypeScript 中。进入方式变了(拼图板而非流水线),但阶段内部仍加载对应的验证提示词。
### 2.4 意图分类7 种)
| 意图 | 触发示例 | 处理方式 |
|------|---------|---------|
| `chat` | "队列研究和 RCT 有什么区别" | focusStage 提示词 + 黑板上下文 → LLM 直接回答 |
| `provide_info` | "研究人群是 45-75 岁冠心病患者" | LLM 回复 + 全域提取 → 更新黑板 |
| `multi_stage_input` | "做老年冠心病队列研究,看出血事件发生率" | LLM 回复 + 全域提取(多阶段同时更新)→ SmartFocus 推荐聚焦 |
| `ask_guidance` | "下一步该讨论什么" / "还缺什么" | check_progress → LLM 引导回复 |
| `confirm_sync` | "确认" / 点击同步按钮 | sync_element含硬依赖守卫→ SmartFocus 切换 |
| `generate` | "帮我生成完整方案" | 校验全局完整度 → 生成全文 |
| `revise` | "PICO 的人群描述要改一下" | 定位目标阶段和要素 → 更新黑板 → LLM 确认 |
意图识别采用**规则优先 + LLM 兜底**策略(与 SSA 一致),规则配置放在 `intent_rules.json`
`multi_stage_input``provide_info` 的区别:前者的用户消息涉及多个阶段的信息(通过规则或 LLM 判断消息中包含多个阶段关键词),全域提取会扫描所有阶段 Schema后者只涉及当前 focusStage。
### 2.5 核心对话流程(全域提取 + 智能聚焦)
```
用户发送消息
┌─────────────────────────────────────────────────────────────┐
│ 1. IntentRouter.classify(message, blackboard) │
│ → chat / provide_info / multi_stage_input / │
│ ask_guidance / confirm_sync / generate / revise │
│ │
│ 如果是会话首条消息 → 先经过 OpeningAnalyzer见 2.8 节) │
└──────────┬──────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. PromptSelector.select(focusStage, blackboard) │
│ │
│ 检查 focusStage 的软依赖是否满足: │
│ │
│ 情况 A — 前提充足(软依赖满足): │
│ mode = 'full_stage' │
│ → 直接加载 focusStage 的验证提示词 │
│ → 如 AIA_SAMPLE_SIZE │
│ │
│ 情况 B — 前提不足(软依赖缺失): │
│ mode = 'dependency_aware' │
│ → 加载 focusStage 的验证提示词作为专业知识参考 │
│ → 额外注入依赖感知指令: │
│ "用户希望讨论样本量计算。以下前提信息尚未收集: │
│ - 研究设计类型 - 主要观察指标 │
│ 围绕用户目标,自然地引导收集上述信息。" │
│ │
│ 随着对话推进、黑板填充,情况 B 自然过渡到情况 A用户无感知
└──────────┬──────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. ConversationService.buildMessages() │
│ │
│ system = PromptSelector 选择的提示词组合 │
│ + 全黑板状态摘要(每个阶段一两句话,自然语言) │
│ + focusStage 阶段内已收集的数据 │
│ │
│ history = focusStage 阶段内的对话历史 │
│ (滑动窗口 ≤15 轮,不含其他阶段的对话) │
│ │
│ user = 用户消息 │
└──────────┬──────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. LLM 流式生成回复createStreamingService
│ 使用通用 StreamingServiceOpenAI Compatible
└──────────┬──────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. 后处理管线(流式完成后执行) │
│ │
│ a. GlobalExtractTool.extract( │
│ recentMessages, │
│ allStageSchemas ← 全域扫描,非仅 focusStage │
│ ) │
│ → 独立 LLM 调用temperature=0.1, Zod 校验) │
│ → 一次提取,多阶段黑板同时更新 │
│ → 例:用户说"做队列研究看出血事件" │
│ → study_design.data.studyType = "队列研究" │
│ → endpoints.data.primary = ["出血事件发生率"] │
│ │
│ b. CheckProgressTool.check(blackboard) │
│ → 纯规则计算(确定性逻辑,无 LLM
│ → 返回:每个阶段的 completeness%, readyToSync │
│ → readyToSync 需同时满足: │
│ ✅ 本阶段完整度达标completionRules
│ ✅ 硬依赖的前序阶段已 confirmed │
│ │
│ c. SmartFocus.recommend(blackboard, userMessage) │
│ → 计算下一步建议聚焦的阶段(见 2.6 节) │
│ │
│ d. 如果某阶段 readyToSync == true │
│ → 前端显示该阶段的同步按钮(含预览数据,可编辑) │
│ │
│ e. 保存 AI 回复到 messages 表metadata 含 stageCode
│ f. 更新 conversation.updatedAt │
└─────────────────────────────────────────────────────────────┘
```
### 2.6 SmartFocus 智能聚焦机制
SmartFocus 替代了 V1.0 的固定 `advanceStage`,它**建议**聚焦阶段但**不强制**。
```
SmartFocus.recommend(blackboard, userMessage)
┌─────────────────────────────────────────────────────────────┐
│ 优先级规则(从高到低): │
│ │
│ P0: 用户明确要求的阶段 │
│ "我们聊聊样本量" → focusStage = sample_size │
│ "PICO 的人群描述要改" → focusStage = pico │
│ │
│ P1: 用户刚同步完的阶段的下一个推荐阶段 │
│ 刚同步完 PICO → 推荐 topic_evaluation 或 study_design │
│ │
│ P2: 完整度最低的、且软依赖已满足的阶段 │
│ 科学问题 40% + PICO 85% → 推荐先补完科学问题 │
│ │
│ P3: 完整度已高但未确认的阶段(建议确认同步) │
│ PICO 85% 且未 confirmed → "PICO 信息已较完整, │
│ 建议确认后同步到方案" │
│ │
│ → 输出: suggestedFocusStage + reason │
│ → 以系统提示的方式告知用户(非强制切换) │
│ → 用户下一条消息可以接受建议,也可以继续聊其他话题 │
└─────────────────────────────────────────────────────────────┘
```
**focusStage 切换时机**
| 场景 | 切换行为 |
|------|---------|
| 用户对话内容明确指向某阶段 | 自动切换IntentRouter 识别) |
| 用户点击同步按钮 | 同步完成后SmartFocus 推荐下一个 |
| 用户说"继续"/"下一步" | SmartFocus 自动推荐 |
| 用户持续在当前阶段对话 | 不切换 |
### 2.7 阶段同步与回溯机制
```
用户点击"同步到方案"
┌─────────────────────────────────────────────────────────────┐
│ SyncElementTool.sync(stageCode, confirmedData) │
│ │
│ 1. 硬依赖守卫 canSync(): │
│ 检查该阶段的硬依赖是否全部满足 │
│ │
│ ❌ 不满足 → 返回友好提示 + 快捷操作: │
│ "样本量计算结果同步前,需先确认研究设计和主要观察指标。 │
│ [快速确认研究设计] [快速确认观察指标]" │
│ │
│ ✅ 满足 → 继续: │
│ 2. 将数据写入 ProtocolBlackboard标记 confirmed
│ 3. 写入 protocol_contexts 表持久化 │
│ 4. SmartFocus.recommend() → 推荐下一个聚焦阶段 │
│ 5. 前端更新 StatePanel 进度 │
└─────────────────────────────────────────────────────────────┘
```
**回溯机制**(与原方案一致):
```
用户修改已确认的阶段数据(通过 StatePanel 编辑按钮或对话中 revise 意图)
┌─────────────────────────────────────────────────────────────┐
│ WorkflowOrchestrator.handleRevision(targetStage) │
│ │
│ 策略 A小修改不影响后续阶段: │
│ → 直接更新黑板对应字段 │
│ → 不切换 focusStage │
│ → LLM 回复确认修改 │
│ │
│ 策略 B大修改影响后续阶段的依赖: │
│ → 更新黑板 │
│ → 将受影响的后续阶段标记为 needs_review │
│ → 提示用户: "人群范围的变化可能影响研究设计, │
│ 建议重新确认研究设计。" │
│ → 不强制回溯,由用户决定 │
└─────────────────────────────────────────────────────────────┘
```
### 2.8 开场模式自适应OpeningAnalyzer
用户的第一条消息由 OpeningAnalyzer 分析,自适应三种开场模式:
```
用户首条消息
┌─────────────────────────────────────────────────────────────┐
│ OpeningAnalyzer.analyze(firstMessage) │
│ │
│ 模式 A: 新手 / 空白开场 │
│ 触发: "我想做一个研究" / "你好" / 消息 < 20 字且无专业术语 │
│ 处理: │
│ → focusStage = scientific_question │
│ → 引导式对话: "请先告诉我你想研究什么问题?" │
│ │
│ 模式 B: 有经验 / 信息丰富开场 │
│ 触发: "做老年冠心病患者队列研究,看出血事件发生率" │
│ 消息含多个阶段的关键信息 │
│ 处理: │
│ → GlobalExtract 全域提取 → 多阶段黑板同时填充 │
│ → focusStage = 最需要补充的阶段 │
│ → "我已记录到您的研究主题和设计方向。 │
│ 目前 PICO 中的对照组还未明确,我们来确认一下?" │
│ │
│ 模式 C: 明确跳阶段 │
│ 触发: "科学问题和 PICO 已确定,直接做研究设计" │
│ 明确表示跳过某些阶段 │
│ 处理: │
│ → 在 StatePanel 显示待确认项(快速录入界面) │
│ → focusStage = 用户指定的阶段 │
│ → 对于已跳过的阶段,提示"可在 StatePanel 中补充" │
└─────────────────────────────────────────────────────────────┘
```
### 2.9 双层依赖模型
**核心洞察**:方法学上的依赖关系有两种强度,不能一刀切。
#### 软依赖Soft Dependency— 可以开始聊
| 阶段 | 软依赖 | 含义 |
|------|--------|------|
| 科学问题 | 无 | 任何时候都可以聊 |
| PICO | 有大致研究方向 | 知道"大概要研究什么"就能开始 |
| 选题评价 | 有科学问题 | 需要评价的对象 |
| 研究设计 | 有大致 P 和 O | 知道"人群和结局"就能聊设计 |
| 观察指标 | 有研究设计方向 | 知道"什么研究类型"就能聊指标 |
| 样本量 | 有研究类型和指标方向 | 知道"做什么研究、看什么"就能开始聊 |
**软依赖不满足时**:不阻止用户,而是进入"依赖感知对话模式"(见 2.5 节 PromptSelector 情况 B通过对话自然收集缺失的前提信息。
> **类比**:研究者说"老师我想算样本量",方法学专家不会说"请先写好 PICO 再来",而是说"好的,你打算做什么类型的研究?主要看什么指标?"——在讨论样本量的过程中自然收集前提。
#### 硬依赖Hard Dependency— 不能最终同步
| 阶段 | 硬依赖(同步守卫) | 含义 |
|------|-------------------|------|
| 科学问题 | 无 | 随时可同步 |
| PICO | 无 | 随时可同步 |
| 选题评价 | PICO 已 confirmed | 评价必须基于确认的 PICO |
| 研究设计 | PICO 已 confirmed | 设计必须基于确认的人群和结局 |
| 观察指标 | 研究设计已 confirmed | 指标必须匹配确认的设计 |
| 样本量 | 研究设计 + 主要指标已 confirmed | 计算必须基于确认的设计和指标 |
**硬依赖不满足时**:同步按钮不出现,或点击后返回友好提示 + 快捷操作按钮(如"快速确认研究设计")。
#### Prompt 选择策略伪代码
```typescript
function selectPromptStrategy(
focusStage: ProtocolStageCode,
blackboard: ProtocolBlackboard
): PromptStrategy {
const softDeps = stageRegistry[focusStage].softDependencies;
const missingDeps = softDeps.filter(
dep => !hasSufficientData(blackboard.stages[dep.stage], dep.minimumFields)
);
if (missingDeps.length === 0) {
// 前提充足 → 直接用该阶段的验证提示词深度对话
return {
mode: 'full_stage',
promptCode: stageRegistry[focusStage].promptCode,
context: buildBlackboardSummary(blackboard),
};
} else {
// 前提不足 → 依赖感知模式(目标导向收集前提)
return {
mode: 'dependency_aware',
primaryPromptCode: stageRegistry[focusStage].promptCode,
missingPrerequisites: missingDeps.map(formatMissing),
guidanceInstruction: '围绕用户目标,自然地引导收集上述前提信息',
context: buildBlackboardSummary(blackboard),
};
}
}
```
**关键点**:随着对话推进、全域提取不断填充黑板,`missingDeps` 逐渐清零,系统从"依赖感知模式"**自然过渡**到"完整验证提示词模式",用户完全无感知。
### 2.10 ProtocolBlackboard 数据结构
```typescript
interface ProtocolBlackboard {
sessionId: string;
userId: string;
conversationId: string;
// 当前工作流状态
focusStage: ProtocolStageCode; // 建议聚焦的阶段(非强制锁定)
stageHistory: Array<{ stage: string; enteredAt: Date; completedAt?: Date }>;
// 6 个阶段的数据(每个阶段独立管理)
stages: {
scientific_question: StageData<{
content: string;
}>;
pico: StageData<{
population: string;
intervention: string;
comparison: string;
outcome: string;
}>;
topic_evaluation: StageData<{
feasibility: string;
novelty: string;
significance: string;
summary: string;
}>;
study_design: StageData<{
studyType: string;
designFeatures: string[];
details: string;
}>;
endpoints: StageData<{
outcomes: {
primary: string[];
secondary: string[];
safety: string[];
};
confounders: string[];
followUp: string;
}>;
sample_size: StageData<{
sampleSize: number;
calculation: {
alpha: number;
power: number;
effectSize: string;
};
rationale: string;
dropoutRate: string;
}>;
};
// 每个阶段的对话历史 ID用于加载阶段内历史
stageConversationRanges: Record<string, { startMessageId: string; endMessageId?: string }>;
}
interface StageData<T> {
status: 'pending' | 'in_progress' | 'completed' | 'needs_review';
data: Partial<T>; // 已收集的数据(可能不完整)
confirmedData?: T; // 用户确认后的完整数据
completeness: number; // 0-100
confirmedAt?: Date;
lastExtractedAt?: Date;
}
```
**持久化策略**ProtocolBlackboard 写入 `protocol_contexts` 表(已存在),使用 JSONB 字段存储。每次 `GlobalExtract``sync_element` 后更新。
---
## 3. 与 V1.0 的关键差异
| 维度 | V1.0 MVP | V2.0 |
|------|---------|------|
| **架构模型** | 顺序流水线(必须按 1→2→3→4→5 走) | **智能拼图板**6 块拼图任意顺序SmartFocus 引导) |
| **提示词** | 1 个通用 `buildSystemPrompt`(手写,未验证) | **6 个验证过的提示词**(从 PromptService 加载) |
| **阶段控制** | Prompt 中写"禁止讨论其他阶段" | **代码控制**WorkflowOrchestrator + SmartFocus |
| **依赖关系** | 隐含在顺序中(硬编码) | **双层依赖模型**(软依赖可聊,硬依赖守卫同步) |
| **上下文管理** | `take: 20` 原始消息 + JSON.stringify 注入 | **ProtocolBlackboard** + 阶段内对话隔离 + 自然语言摘要注入 |
| **数据提取** | LLM 在对话中输出 `<extracted_data>` 标签 | **GlobalExtractTool**(独立 LLM全域扫描多阶段Zod 校验) |
| **同步按钮** | 关键词匹配 / 前端解析 XML 标签 | **CheckProgressTool 规则计算** + **硬依赖守卫**(双重校验) |
| **编排器** | `BaseAgentOrchestrator` 被绕过 | **WorkflowOrchestrator 统一入口** |
| **意图识别** | 无 | **IntentRouter**7 种意图,规则 + LLM 兜底) |
| **开场方式** | 强制从科学问题开始 | **OpeningAnalyzer** 三模式自适应(新手/有经验/跳阶段) |
| **跨阶段修改** | 不支持 | **回溯机制**(小修改直接更新,大修改提示用户) |
---
## 4. 工具定义5 个)
### 4.1 Tool 1: `global_extract`(自动触发)
```typescript
{
name: "global_extract",
trigger: "auto_after_response",
description: "从最近对话中全域提取结构化数据,可同时更新多个阶段黑板",
input: {
recentMessages: "最近 3 轮对话",
allStageSchemas: "所有 6 个阶段的 Zod Schema",
currentBlackboard: "黑板当前状态"
},
output: {
updates: "Record<StageCode, { updatedFields, confidence }>",
rationale: "提取依据"
},
implementation: "独立 LLM 调用非对话层temperature=0.1Zod 校验jsonrepair 容错"
}
```
**与 V1.0 的区别**
- V1.0 要求对话 LLM 在回复中输出 `<extracted_data>` 标签(不可靠)
- V2.0 用独立的 LLM 调用专门做提取(可靠),且是**全域扫描**而非仅 focusStage
**全域提取示例**
```
用户: "做老年冠心病患者的队列研究,主要看 6 个月后的出血事件发生率"
GlobalExtract 输出:
scientific_question → { content: "老年冠心病患者...出血事件..." }
pico → { population: "老年冠心病患者", outcome: "出血事件发生率" }
study_design → { studyType: "前瞻性队列研究" }
endpoints → { primary: ["出血事件发生率"], followUp: "6个月" }
```
### 4.2 Tool 2: `check_progress`(自动触发 + 按需)
```typescript
{
name: "check_progress",
trigger: "auto_after_extract | on_demand",
description: "评估各阶段完整度 + 硬依赖校验",
input: {},
output: {
stageProgress: "Record<StageCode, { completeness, missingFields, readyToSync }>",
globalCompleteness: "number 0-100",
suggestion: "string下一步建议"
},
implementation: "纯规则计算,无 LLM 调用"
}
```
**完成标准规则示例**
```typescript
const COMPLETION_RULES: Record<ProtocolStageCode, (data: any) => CompletionResult> = {
pico: (data) => {
const fields = ['population', 'intervention', 'comparison', 'outcome'];
const filled = fields.filter(f => data[f] && data[f].length >= 5);
return {
completeness: Math.round((filled.length / fields.length) * 100),
missingFields: fields.filter(f => !filled.includes(f)),
};
},
// ...其他阶段
};
```
**readyToSync 判定(含硬依赖守卫)**
```typescript
function isReadyToSync(stageCode: ProtocolStageCode, blackboard: ProtocolBlackboard): boolean {
const completion = COMPLETION_RULES[stageCode](blackboard.stages[stageCode].data);
if (!completion.readyToSync) return false;
const hardDeps = stageRegistry[stageCode].hardDependencies;
return hardDeps.every(
dep => blackboard.stages[dep.stage].status === 'completed'
);
}
```
### 4.3 Tool 3: `search_methodology`(按需)
```typescript
{
name: "search_methodology",
trigger: "on_demand",
description: "在方法学知识库中检索",
input: { question: "string", topic: "string" },
output: { chunks: "RetrievalResult[]", summary: "string" },
implementation: "复用平台 RAG 引擎pgvector"
}
```
> **Phase 1 不实现**预留接口。Phase 2 接入知识库后启用。
### 4.4 Tool 4: `compute_sample_size`(按需)
```typescript
{
name: "compute_sample_size",
trigger: "on_demand样本量阶段参数就绪后",
description: "调用统计引擎计算样本量",
input: { design, outcomeType, alpha, power, effectSize, dropoutRate },
output: { sampleSize, formula, sensitivityTable },
implementation: "复用 SSA 的 RClientService 或内置公式"
}
```
> **Phase 1 不实现**预留接口。Phase 2 接入 R 统计引擎后启用。
### 4.5 Tool 5: `sync_element`(用户确认触发)
```typescript
{
name: "sync_element",
trigger: "user_explicit_action",
description: "将确认的数据同步到方案(含硬依赖守卫)",
input: { stageCode, data, source: "extracted | edited" },
output: { success, updatedBlackboard, nextSuggestion },
guards: {
canSync: "硬依赖校验,不满足时返回友好提示 + 快捷操作按钮"
},
implementation: "硬依赖校验 → 写入 protocol_contexts → 更新黑板 → SmartFocus 推荐"
}
```
**硬依赖守卫伪代码**
```typescript
function canSync(stageCode: ProtocolStageCode, blackboard: ProtocolBlackboard): SyncGuardResult {
const hardDeps = stageRegistry[stageCode].hardDependencies;
const unmet = hardDeps.filter(
dep => blackboard.stages[dep.stage].status !== 'completed'
);
if (unmet.length > 0) {
return {
allowed: false,
reason: `同步前需先确认: ${unmet.map(d => d.label).join('、')}`,
quickActions: unmet.map(d => ({
label: `确认${d.label}`,
action: `sync_stage:${d.stage}`,
})),
};
}
return { allowed: true };
}
```
---
## 5. 开发计划
### 5.1 Phase 概览
```
Phase 0: 基础设施搭建3 天)
→ ProtocolBlackboard + WorkflowOrchestrator + StageRegistry含双层依赖配置
Phase 1: 对话智能层核心5 天)
→ OpeningAnalyzer + IntentRouter + PromptSelector + ConversationService 改造
→ GlobalExtractTool + CheckProgressTool + SyncElementTool
Phase 2: 前端重构3 天)
→ ChatArea 改造 + StatePanel 改造 + 同步按钮重构
Phase 3: 联调测试 + 迁移2 天)
→ 端到端测试 + V1.0 数据兼容
合计:~13 天
```
### 5.2 Phase 0基础设施搭建3 天)
| # | 任务 | 工时 | 产出 |
|---|------|------|------|
| 0-1 | **ProtocolBlackboard 设计与实现** | 4h | `ProtocolBlackboardService`CRUD + 增量 patch + 完整度计算。使用 `protocol_contexts` 表 JSONB 字段持久化 |
| 0-2 | **StageRegistry 阶段注册表** | 4h | 6 个阶段的配置promptCode、outputSchemaZod、completionRules、softDependencies、hardDependencies。JSON 配置 + Zod 校验 |
| 0-3 | **WorkflowOrchestrator 实现** | 5h | 拼图板状态机:`SmartFocus.recommend()` / `handleRevision()` / `canSync()`。双层依赖校验 |
| 0-4 | **阶段配置 JSON + Seed** | 3h | `protocol_stages.json`6 阶段定义(含软硬依赖配置)。`seed-protocol-stages.ts`:写入数据库或加载到内存 |
| 0-5 | **类型定义** | 2h | `ProtocolBlackboard``StageData``CompletionResult``StageConfig``SoftDependency``HardDependency` 等接口 |
**验收标准**
- `ProtocolBlackboardService` 可以 get/patch/reset
- `SmartFocus.recommend()` 可以根据黑板状态推荐聚焦阶段
- `canSync()` 正确拒绝硬依赖不满足的同步请求
- 每个阶段能加载对应的 Prompt Code
### 5.3 Phase 1对话智能层核心5 天)
| # | 任务 | 工时 | 产出 |
|---|------|------|------|
| 1-1 | **IntentRouter 实现** | 4h | 规则引擎(关键词 + 上下文守卫)+ LLM 兜底。7 种意图(含 `multi_stage_input`)。`intent_rules.json` 配置 |
| 1-2 | **OpeningAnalyzer 实现** | 3h | 首条消息分析,三模式判定(新手/有经验/跳阶段),初始化 focusStage |
| 1-3 | **PromptSelector 实现** | 4h | 根据 focusStage + 软依赖状态选择 Prompt 策略full_stage / dependency_aware。依赖感知 Prompt 模板设计 |
| 1-4 | **ConversationService 改造** | 5h | 核心改造:① 从 PromptService 加载验证提示词;② PromptSelector 策略组装;③ 注入全黑板摘要(自然语言);④ 阶段内对话历史隔离 |
| 1-5 | **GlobalExtractTool 实现** | 6h | 独立 LLM 调用 + 全域扫描所有阶段 Schema + Zod 校验 + jsonrepair + 增量 patch 黑板。每个阶段有专属提取 Prompt |
| 1-6 | **CheckProgressTool 实现** | 3h | 纯规则计算 + 硬依赖守卫。返回每个阶段的 completeness + missingFields + readyToSync |
| 1-7 | **SyncElementTool 重构** | 3h | 替代现有 `handleProtocolSync`。canSync 硬依赖守卫 → 写入黑板confirmed→ SmartFocus 推荐 |
| 1-8 | **ProtocolAgentController 重写** | 5h | `sendMessage` 走新架构OpeningAnalyzer(首条) → IntentRouter → PromptSelector → ConversationService → 流式生成 → 后处理管线 |
| 1-9 | **提取 Prompt 设计 + Seed** | 3h | 全域提取 Prompt 模板 + 6 个阶段的字段映射。写入 `prompt_templates` 表 |
**验收标准**
- 新手开场:"你好" → 引导到科学问题
- 信息丰富开场:"做队列研究看出血事件" → 全域提取填充多个阶段,推荐最需要补充的阶段
- 跳阶段:"直接聊样本量" → 进入依赖感知模式,自然引导收集前提
- `check_progress` 在 PICO 四字段填满后返回 `readyToSync: true`
- 同步样本量时,如果研究设计未确认 → canSync 返回拒绝 + 快捷操作
### 5.4 Phase 2前端重构3 天)
| # | 任务 | 工时 | 产出 |
|---|------|------|------|
| 2-1 | **ChatArea 改造** | 5h | ① 移除 `parseExtractedData` XML 解析逻辑;② 同步按钮改为由后端 `readyToSync` 控制显示;③ 同步前显示数据预览(可编辑);④ 硬依赖不满足时显示快捷操作按钮 |
| 2-2 | **StatePanel 增强** | 3h | ① 显示 6 阶段拼图板(非线性展示);② 每个阶段显示完整度百分比;③ 已确认阶段支持查看和编辑;④ focusStage 高亮;⑤ 点击任意阶段可切换 focusStage |
| 2-3 | **阶段过渡 UI** | 3h | ① SmartFocus 推荐提示(系统消息,用户可接受或忽略);② 进度条更新;③ 依赖关系可视化提示 |
| 2-4 | **回溯编辑 UI** | 2h | ① StatePanel 已确认阶段的编辑按钮;② 编辑弹窗;③ 编辑后触发 `handleRevision` |
| 2-5 | **Markdown 渲染修复** | 1h | 修复段落序号全为 "1." 的问题Issue #0 |
**验收标准**
- 同步按钮只在 `readyToSync`(含硬依赖满足)时出现
- 硬依赖不满足时显示友好提示和快捷操作
- 同步前可以预览和编辑提取的数据
- StatePanel 点击阶段可切换聚焦
- 已确认阶段可以查看详情和编辑
### 5.5 Phase 3联调测试 + 迁移2 天)
| # | 任务 | 工时 | 产出 |
|---|------|------|------|
| 3-1 | **端到端测试脚本** | 4h | 覆盖 11 个 V1.0 反馈问题的回归测试 + 3 种开场模式测试 |
| 3-2 | **V1.0 数据兼容** | 2h | 已有的 protocol_contexts 数据迁移到新的 blackboard 格式 |
| 3-3 | **Prompt 调优** | 3h | 根据测试结果微调阶段内指令、提取 Prompt、依赖感知指令 |
| 3-4 | **文档更新** | 2h | 更新模块状态文档 + API 文档 |
---
## 6. 数据库变更
### 6.1 无需新建表
V2.0 复用现有表:
| 表 | Schema | 用途 | 变更 |
|---|--------|------|------|
| `protocol_contexts` | `protocol_schema` | ProtocolBlackboard 持久化 | 扩展 JSONB 字段结构 |
| `conversations` | `aia_schema` | 对话管理 | 无变更 |
| `messages` | `aia_schema` | 消息存储 | 新增 `metadata.stageCode` 字段JSONB 内) |
| `prompt_templates` | `capability_schema` | 提示词管理 | 新增 6 个提取 Prompt + 依赖感知 Prompt 模板 |
| `agent_sessions` | `agent_schema` | Agent 会话 | 无变更 |
### 6.2 protocol_contexts 字段扩展
现有的 `protocol_contexts` 表已包含 `scientific_question``pico``study_design``sample_size``endpoints` 等 JSONB 字段。V2.0 在这些字段内增加 `status``completeness``confirmedAt` 等元数据,向后兼容。
---
## 7. 配置文件清单
| 文件 | 位置 | 用途 | 维护者 |
|------|------|------|--------|
| `protocol_stages.json` | `backend/src/modules/agent/protocol/config/` | 6 阶段定义promptCode、schema、completionRules、softDependencies、hardDependencies | 方法学团队 |
| `intent_rules.json` | `backend/src/modules/agent/protocol/config/` | 意图识别规则7 种意图,关键词 + 上下文守卫) | IT 团队 |
| `extraction_prompts/` | PromptService 数据库 | 6 个阶段的数据提取 Prompt + 全域提取模板 | 方法学团队 |
---
## 8. 保留什么(不动的部分)
| 组件 | 理由 |
|------|------|
| `ProtocolContextService`(大部分) | CRUD 逻辑复用,增加 blackboard 适配层 |
| `ProtocolExportService` | Word 导出,不变 |
| `protocolGenerationPrompts.ts` | 全文生成 Prompt不变 |
| 前端 `DocumentPanel` | 方案预览和 A4 展示,不变 |
| 前端 `useProtocolGeneration` | 一键生成逻辑,不变 |
| 前端 `useProtocolConversations` | 对话管理,不变 |
| 6 个验证过的 Prompt数据库中 | 核心资产,阶段进入方式变了但阶段内仍加载验证提示词 |
## 9. 废弃什么
| 组件 | 替代 |
|------|------|
| `ProtocolAgentController.buildSystemPrompt()` | → PromptSelector + ConversationService从 PromptService 加载) |
| `ProtocolAgentController.buildMessagesWithContext()` | → ConversationService黑板上下文 + 阶段内历史) |
| `ProtocolAgentController.getStageOutputFormat()` | → StageRegistryZod Schema 定义) |
| `ProtocolAgentController.getStageInstructions()` | → StageRegistry阶段内指令 |
| `ProtocolOrchestrator.buildSyncButton()`(关键词匹配) | → CheckProgressTool规则计算 + 硬依赖守卫) |
| `ProtocolOrchestrator.extractDataFromResponse()`XML 解析) | → GlobalExtractTool独立 LLM全域扫描 |
| 前端 `parseExtractedData()`XML 解析) | → 后端推送 `readyToSync` 信号 |
| 固定 `advanceStage()` 顺序推进 | → SmartFocus 智能推荐 |
---
## 10. V1.0 问题解决映射
| # | 问题 | V2.0 解决机制 |
|---|------|-------------|
| 0 | 段落序号全为 "1." | Phase 2 Markdown 渲染修复 |
| 1 | 不结合上下文(说了队列还显示 RCT | **ProtocolBlackboard** + 全黑板摘要注入 + **GlobalExtract** 全域提取 |
| 2 | 未确认就可同步 AI 编造内容 | **CheckProgressTool** completionRules + **硬依赖守卫** canSync |
| 3 | 重复讨论已确认信息 | **阶段内对话历史隔离** + 已确认数据以摘要形式注入 |
| 4 | 观察指标阶段又讨论样本量 | **SmartFocus** 代码控制聚焦 + 每阶段专属验证提示词 |
| 5 | 不联系对话过程中的上下文 | **ProtocolBlackboard** 统一存储 + **GlobalExtract** 跨阶段收集 |
| 6 | 发送参数后不联系上下文 | **阶段内对话历史不截断**(窗口 ≤15 轮,非全局 20 条) |
| 7 | 阶段未正确推进 | **SmartFocus.recommend()** 智能推荐 + 同步后自动切换 |
| 8 | 纠正后又回退 | **ProtocolBlackboard** 为单一真相源,不受 LLM 遗忘影响 |
| 9 | 反复回到已完成话题 | **SmartFocus** + 每阶段专属验证提示词 + 阶段内历史隔离 |
| 10 | 同步内容与讨论不一致 | **GlobalExtractTool** 独立提取 + 同步前预览可编辑 |
---
## 11. 风险管理
| 风险 | 概率 | 影响 | 应对 |
|------|------|------|------|
| GlobalExtractTool 全域提取准确率不足 | 中 | 高 | Zod 校验 + 置信度阈值(<0.5 不更新黑板)+ 同步前人工确认 |
| 全域提取误将信息归入错误阶段 | 中 | 中 | 阶段 Schema 设计有区分度 + 同步前预览可编辑 |
| 验证提示词不适配对话场景 | 中 | 中 | 原提示词设计为一问一答,需增加阶段内指令适配多轮对话 |
| 依赖感知模式 Prompt 收集效果不好 | 中 | 中 | 依赖感知指令模板迭代优化 + 前提收集完成后自然切换到完整模式 |
| 后处理管线增加延迟 | 中 | 低 | GlobalExtract 异步执行,不阻塞 UI先显示 AI 回复,提取结果后续更新 |
| 拼图板自由度导致用户迷失 | 低 | 中 | SmartFocus 始终给出建议 + StatePanel 可视化进度 |
| V1.0 数据迁移 | 低 | 低 | Blackboard 结构向后兼容,旧数据可平滑映射 |
### 回退策略
| 层级 | 正常路径 | 降级路径 | 触发条件 |
|------|---------|---------|---------|
| 验证提示词加载 | PromptService 从数据库加载 | 内置兜底 Prompt | 数据库不可用 |
| OpeningAnalyzer | 三模式分析 | 默认新手模式(最安全) | 分析异常 |
| IntentRouter | 规则引擎 + LLM 兜底 | 默认为 `provide_info`(最安全) | LLM 不可用 |
| PromptSelector | full_stage / dependency_aware 切换 | 始终 full_stage降级为只用当前阶段提示词 | 依赖分析异常 |
| GlobalExtractTool | 全域扫描 + Zod 校验 | 仅提取 focusStage降级为单阶段提取 | LLM 不可用或全域提取超时 |
| CheckProgressTool | 规则计算 + 硬依赖守卫 | 不显示同步按钮,等待人工确认 | 规则异常 |
---
## 12. 工时与里程碑
| Phase | 名称 | 工时 | 日历天 | 里程碑 |
|-------|------|------|--------|--------|
| **0** | 基础设施搭建 | 18h | 3 天 | Blackboard + Orchestrator + StageRegistry含双层依赖可用 |
| **1** | 对话智能层核心 | 36h | 5 天 | 三种开场模式、全域提取、依赖感知对话、硬依赖守卫全部可用 |
| **2** | 前端重构 | 14h | 3 天 | 完整用户体验(拼图板 StatePanel + 同步守卫 UI |
| **3** | 联调测试 + 迁移 | 11h | 2 天 | 11 个问题 + 3 种开场模式全部验证通过 |
| **合计** | | **79h** | **~13 天** | **Protocol Agent 2.0 上线** |
### 里程碑时间线
```
Week 1 ──────────────────────────────────
Day 1-3: Phase 0基础设施 + 双层依赖配置)
Day 4-5: Phase 1 前半OpeningAnalyzer + IntentRouter + PromptSelector
Week 2 ──────────────────────────────────
Day 6-8: Phase 1 后半GlobalExtract + CheckProgress + SyncElement + Controller 重写)
Day 9-11: Phase 2前端重构
Week 3 ──────────────────────────────────
Day 12-13: Phase 3联调测试 + 迁移)
✅ Protocol Agent 2.0 上线
```
---
## 13. 未来扩展Phase 2+
| 功能 | 说明 | 何时做 |
|------|------|--------|
| RAG 知识库接入 | `search_methodology` 工具接入方法学知识库 | V2.0 上线 + 知识库就绪后 |
| 样本量计算器 | `compute_sample_size` 工具接入 R 统计引擎 | V2.0 上线 + R 引擎就绪后 |
| 方法学评审 | 第 7 个阶段,方案生成后自动评审 | V2.1 |
| 多会话支持 | 跨天/跨设备继续协作 | V2.1 |
| 协作功能 | 多人协同编辑方案 | V3.0 |
---
## 14. 关键决策记录
| 决策 | 选择 | 理由 |
|------|------|------|
| 架构模型 | **智能拼图板**(非顺序流水线) | 真正融合 SSA 模式的核心思想:用户驱动对话流,系统智能填补空白 |
| 依赖关系 | **双层模型**(软依赖 + 硬依赖) | 软依赖保证灵活性(可以聊),硬依赖保证严谨性(不能乱同步) |
| 阶段聚焦 | **SmartFocus 建议,非强制锁定** | 用户可以从任意话题切入,系统推荐但不阻止 |
| 开场方式 | **OpeningAnalyzer 三模式自适应** | 新手得到引导,有经验的用户不被束缚 |
| 前提信息收集 | **依赖感知对话模式**(自然引导) | 像真正的方法学专家一样,在讨论目标话题时自然收集前提 |
| 提示词来源 | 复用 6 个验证过的子 Agent 提示词 | 不重复造轮子,验证过的是核心资产。进入方式变了,阶段内提示词不变 |
| 数据提取 | **GlobalExtract 全域提取**(非仅当前阶段) | 一次对话可能涉及多个阶段信息,全域扫描不遗漏 |
| 同步判断 | 代码规则计算 + **硬依赖守卫** | 确定性逻辑 > 概率性判断,方法学约束代码化 |
| 阶段内对话 | 自由对话 + 验证提示词引导 | 用户体验自然,专业深度有保证 |
| 历史消息 | 阶段内隔离 + 全黑板摘要注入 | 避免跨阶段干扰,保留跨阶段上下文 |
| Session 黑板 | protocol_contexts 表 JSONB | 复用现有表,无需新建 |
| IntentRouter | 规则优先 + LLM 兜底7 种意图) | 与 SSA 模式一致,已验证有效。新增 multi_stage_input 处理跨阶段输入 |
---
> **一句话总结**Protocol Agent 2.0 = 智能拼图板6 块拼图任意顺序完成)+ 验证过的 AI 专家(每块拼图由专家坐诊)+ 双层依赖守卫(聊天自由,同步严谨),让用户像和方法学专家自由聊天一样完成研究方案制定。

View File

@@ -3,8 +3,14 @@
> **文档版本:** v3.1
> **创建日期:** 2026-01-01
> **维护者:** IIT Manager开发团队
> **最后更新:** 2026-03-01 **质控引擎 V3.1 架构升级计划定稿(五级数据结构 + 多维报告)**
> **最后更新:** 2026-03-01 **GCP 业务报表 + AI 工作流水增强 + 多项 Bug 修复完成!**
> **重大里程碑:**
> - **2026-03-01GCP 业务端报表全量完成!** 4 张 GCP 标准报表D1 筛选入选/D2 完整性/D3D4 质疑跟踪/D6 方案偏离)后端 API + 前端组件 + ReportsPage 五 Tab 重构
> - **2026-03-01AI 工作流水时间线增强!** 实际规则数显示33 条而非 1 条)+ 中文事件名 + 可展开问题详情表格 + severity 映射修复
> - **2026-03-01业务端一键全量质控** DashboardPage 新增按钮 + 自动刷新报告缓存 + 事件级通过率修复
> - **2026-03-01多项关键 Bug 修复!** dimension_code→rule_category / D1 仅显示 1 人→14 人 / 时区 UTC→北京时间 / 通过率 271%→正确值
> - **2026-03-01B4 定时质控灵活配置完成!** 项目级 cron → pg-boss dispatcher 每分钟匹配 → QcExecutor.executeBatch → DailyQcOrchestrator
> - **2026-03-01V3.1 质控引擎全量完成!** 17 项任务全部实现QcExecutor 统一入口 → D1-D7 全维度 → 三级聚合 → HealthScore → 前端驾驶舱 → 端到端测试
> - **2026-03-01质控引擎 V3.1 架构设计完成!** 五级数据结构CDISC ODM+ D1-D7 多维报告 + 三批次落地计划
> - **2026-03-01架构团队评审完成** 采纳 InstanceID/规则分类/状态冒泡/LLM 三不原则,暂缓 SDV/自动映射/GCP 全量报表
> - **2026-02-26前端架构调整完成** 运营管理端恢复 IIT 项目管理 + 业务端精简为日常使用 + Web AI 对话页面上线
@@ -55,7 +61,26 @@ CRA Agent 是一个**替代 CRA 岗位的自主 AI Agent**,而非辅助 CRA
- AI能力DeepSeek/Qwen + 自研 RAGpgvector+ LLM Tool Use
### 当前状态
- **开发阶段****V3.0 P0 + P1 已完成 → 正在规划 V3.1 质控引擎架构升级**
- **开发阶段****V3.1 质控引擎 + GCP 业务报表 + AI 时间线增强 + Bug 修复 → 待部署验证**
- **GCP 业务报表 + Bug 修复已完成**2026-03-01
- 4 张 GCP 标准报表后端 APIiitQcCockpitServicegetEligibilityReport/getCompletenessReport/getEqueryReport/getDeviationReport
- 4 个前端报表组件EligibilityTable/CompletenessTable/EqueryLogTable/DeviationLogTable
- ReportsPage 五 Tab 重构(执行摘要 + 4 张报表)
- AI 工作流水时间线增强SkillRunner 真实规则数 + iitQcCockpitController severity 映射 + AiStreamPage 可展开详情表格)
- 业务端一键全量质控按钮DashboardPage + 报告缓存自动刷新)
- Bug 修复dimension_code→rule_category / D1 数据源→record_summary 全量 + qc_field_status 叠加 / 时区 UTC→Asia/Shanghai / 通过率 passed/totalEvents
- **B4 已完成**2026-03-01
- 项目级 cronExpression 持久化(后端 UpdateProjectInput + Prisma update
- 全局 dispatcher 调度器pg-boss 每分钟轮询 → 匹配 cronExpression → 派发 iit_scheduled_qc
- iit_scheduled_qc Worker V3.1 升级QcExecutor.executeBatch + DailyQcOrchestrator
- 前端管理端 cron 配置 UI 增强6 个预设 + 自定义输入 + cronEnabled/cronExpression 类型修复)
- 动态生效:保存项目配置后 refreshProjectCronSchedule() 即时反映
- **V3.1 已完成**2026-03-01
- P1: 后端集成QcExecutor 统一入口 + D2/D6 维度引擎 + HealthScore 聚合)
- P2: 报告升级QcReportService 数据源切换 + dimension_summary/event_overview XML
- P3: API + 服务(新增 3 端点 + CockpitService 升级 + ToolsService 升级)
- P4: 前端DashboardPage 健康度+维度条 + 热力图 record×event + ReportsPage 维度/事件 Tab
- P5: 端到端测试脚本 + 部署清单
- **V3.0 已完成**
- P0 自驱动质控流水线 + P1 对话层 Tool Use 改造 + E2E 54/54 通过
- QC 系统深度修复null tolerance + baseline merge + record-level pass rate + LLM 报告修正)
@@ -82,10 +107,31 @@ CRA Agent 是一个**替代 CRA 岗位的自主 AI Agent**,而非辅助 CRA
-**端到端测试通过**REDCap → Node.js → 企业微信)
-~~AI对话集成完成ChatService + SessionMemory~~ → 已替换为 ChatOrchestrator
#### ✅ 已完成功能GCP 业务报表 + AI 时间线 + Bug 修复 - 2026-03-01
-**GCP 标准报表(阶段 A 4 张)**
- D1 筛选入选表getEligibilityReportrecord_summary 全量 + qc_field_status D1 叠加)
- D2 数据录入率与缺失率getCompletenessReportrecord_summary 聚合统计)
- D3/D4 数据质疑跟踪表getEqueryReportqc_field_status severity 分布)
- D6 方案偏离表getDeviationReportqc_field_status D6 维度)
-**前端 4 个报表组件**EligibilityTable / CompletenessTable / EqueryLogTable / DeviationLogTable
-**ReportsPage 五 Tab 重构**(执行摘要 LLM + 4 张报表独立 Tab
-**AI 工作流水时间线增强**
- SkillRunner 输出 totalRules33 条真实规则数替代 1 条 skill 数)
- iitQcCockpitController severity 映射修复critical→red / warning→yellow
- AiStreamPage 可展开 Collapse 详情表格(规则名/字段/描述/严重性/实际值)
- 中文事件名显示eventLabel+ 状态标签中文化(通过/严重/警告)
-**业务端一键全量质控**DashboardPage SyncOutlined 按钮 + batchQualityCheck API 调用)
-**报告缓存自动刷新**iitBatchController 批量 QC 后调用 QcReportService.refreshReport
-**Bug 修复**
- dimension_code→rule_categoryiitQcCockpitService 4 处 SQL
- D1 筛选入选仅 1 人→14 人(数据源从 qc_field_status 改为 record_summary 全量)
- 时区 UTC→北京时间QcReportService toBeijingTime + buildLlmXmlReport Asia/Shanghai
- 通过率 271%→正确值iitBatchController passed/totalEvents 替代 passed/totalRecords
#### ✅ 已完成功能P0 自驱动质控流水线 - 2026-02-26
-**变量清单导入**REDCap Data Dictionary → iit_field_metadata
-**规则配置增强**4 类规则 + AI 辅助建议 + 变量关联)
-**定时质控调度**pg-boss cron + DailyQcOrchestrator
-**定时质控调度**pg-boss cron dispatcher + 项目级 cronExpression + DailyQcOrchestrator
-**eQuery 闭环**open → responded → ai_reviewing → resolved/reopened
-**重大事件归档**SAE + 方案偏离自动归档 iit_critical_events
-**统一驾驶舱**(健康分 + 趋势图 + 风险热力图 + 核心指标卡片)
@@ -908,8 +954,8 @@ npx ts-node src/modules/iit-manager/test-wechat-push.ts
---
> **提示**本文档反映IIT Manager Agent模块的最新真实状态每个里程碑完成后必须更新
> **最后更新**2026-02-25
> **当前进度**V3.0 开发计划已定稿 | 下一步P0-1 ChatOrchestrator + ToolsService 重构
> **最后更新**2026-03-01
> **当前进度**V3.1 QC Engine 完成 | GCP 业务报表 4 张全量完成 | AI Timeline 增强 | 一键全量质控 | 多项 Bug 修复 | Phase 2: LLM 执行摘要待开发
> **核心文档**
> - [CRA Agent V3.0 开发计划](./04-开发计划/V3.0全新开发计划/V3.0全新开发计划.md) ⭐⭐⭐⭐⭐
> - [统一数字 CRA 质控平台 PRD](./04-开发计划/V3.0全新开发计划/统一数字%20CRA%20质控平台产品需求文档(PRD).md) ⭐⭐⭐⭐⭐

View 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**
### **💣 坑点 1D2 (数据完整性) 的“幽灵记录”取数陷阱**
**🔍 计划漏洞**
计划中 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 的开发任务中。*
### **💣 坑点 2D6 (方案偏离) 脆断的文本解析**
**🔍 计划漏洞**
计划中写道:对于 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。
### **💣 坑点 3D1 (筛选入选表) Inclusion/Exclusion 的身份识别**
**🔍 计划漏洞**
D1 API 的返回结构要求明确区分 type: 'inclusion' | 'exclusion',以便分别统计。但在我们现有的 qc\_field\_status 五层表中,并没有字段标识一条规则到底是纳入还是排除。
**🛠️ 修正建议 (后端映射)**
在执行 P0 Bugfix 时,连同将规则的子分类也传递下去。或者在项目的 IitSkill 配置中,规定 D1 规则的命名必须带有前缀例如INC-年龄校验EXC-妊娠状态。D1 的 API 通过解析 ruleName 的前缀来区分 inclusion 和 exclusion从而正确归类到前端表格中。
### **💣 坑点 4D2 前端表格的三级展开 (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 了!

View File

@@ -17,18 +17,64 @@
|---|---------|---------|--------|------|
| DB-1 | ssa_workflows 类型精度对齐 + 清理重复 FK | `20260227_align_schema_with_db_types` | 低 | 幂等 SQLRDS 上执行无副作用 |
| DB-2 | Phase 2: user_mappings 加 user_id FK + projects 加 tenant_id FK + UserRole 加 IIT_OPERATOR | `20260228_add_iit_phase2_user_project_rbac` | 高 | nullable 列,不破坏现有数据 |
| DB-3 | IIT projects 加 is_demo 标记 | `20260228_add_iit_project_is_demo` | 低 | nullable boolean DEFAULT false无破坏 |
| DB-4 | V3.1 QC 引擎架构升级:新建 qc_field_status 五级坐标表 + qc_logs/equery 加 instance_id + field_mapping 加 semantic_label/form_name/rule_category | `20260301_add_v31_qc_field_status_and_instance_columns` | 高 | 全部 ADD COLUMN / CREATE TABLE向后兼容零停机 |
| DB-5 | V3.1 Batch B新建 qc_event_status 事件级聚合表 + record_summary 加 events/fields/d1-d7 聚合列 + top_issues | `20260301_add_v31_qc_event_status_and_record_summary_aggregation` | 高 | 全部 ADD COLUMN / CREATE TABLEIF NOT EXISTS零停机 |
| DB-6 | V3.1 Batch Cqc_project_stats 加 d1-d7 pass_rate + health_score + health_grade + dimension_detail | `20260301_add_v31_project_stats_health_score` | 中 | 全部 ADD COLUMNDEFAULT 值,零停机 |
### 后端变更 (Node.js)
| # | 变更内容 | 涉及文件 | 需要操作 | 备注 |
|---|---------|---------|---------|------|
| — | *暂无* | | | |
| BE-1 | V3.1 RedcapAdapter: normalizeInstances() + exportRecordsNormalized() 五级坐标标准化 | `adapters/RedcapAdapter.ts` | 重新构建镜像 | 新增公共方法,不破坏现有调用 |
| BE-2 | V3.1 QC 分类体系升级D1-D7 七维分类 + toDimensionCode() 转换函数 | `engines/HardRuleEngine.ts`, `engines/SoftRuleEngine.ts` | 重新构建镜像 | 扩展联合类型,旧值 → D-code 自动映射 |
| BE-3 | V3.1 QcExecutor 统一质控执行入口executeSingle/executeBatch + qc_field_status upsert | `engines/QcExecutor.ts` (新文件) | 重新构建镜像 | 包装 SkillRunner新增字段级状态写入 |
| BE-4 | V3.1 SyncManager: syncSemanticLabels() 语义标签自动同步 | `services/SyncManager.ts` | 重新构建镜像 | 从 REDCap 元数据填充 field_mapping.semantic_label |
| BE-5 | 种子规则 D-code 迁移inclusion→D1, exclusion→D1, lab_values→D3 | `prisma/seed-iit-qc-rules.ts` | 重新执行种子脚本 | 下次重新初始化项目时生效 |
| BE-6 | V3.1 QcAggregator: aggregateDeferred() + aggregateForRecord() 异步防抖聚合 | `engines/QcAggregator.ts` (新文件) | 重新构建镜像 | 纯 SQL INSERT...ON CONFLICT 聚合field→event→record 三级冒泡 |
| BE-7 | V3.1 QcExecutor 集成聚合 + State Transition HookFAIL→PASS 自动关闭 eQuery | `engines/QcExecutor.ts` | 重新构建镜像 | executeSingle 推 pg-boss 防抖executeBatch 直接聚合PASS-flip 覆盖旧 FAIL |
| BE-8 | V3.1 pg-boss Worker: iit_qc_aggregate 受试者粒度防抖聚合 | `modules/iit-manager/index.ts` | 重新构建镜像 | singletonKey 防抖 10s多 CRC 并发录入互不干扰 |
| BE-9 | V3.1 D2 CompletenessEngine: 绝对必填字段缺失率 + 双重过滤(字段+时序) | `engines/CompletenessEngine.ts` (新文件) | 重新构建镜像 | 排除 branching_logic/calc/descriptive 字段 + 排除未来访视 |
| BE-10 | V3.1 D6 ProtocolDeviationEngine: 访视超窗检测 | `engines/ProtocolDeviationEngine.ts` (新文件) | 重新构建镜像 | 基于项目 cachedRules.visitWindows 配置,支持早到/迟到检测 |
| BE-11 | V3.1 C4 HealthScoreEngine: D1-D7 加权综合健康度评分 | `engines/HealthScoreEngine.ts` (新文件) | 重新构建镜像 | 0-100 评分 + A-F 等级,持久化到 qc_project_stats |
| BE-12 | V3.1 Webhook Worker 接入 QcExecutor.executeSingle() | `modules/iit-manager/index.ts` | 重新构建镜像 | 替换 HardRuleEngine 旧路径 |
| BE-13 | V3.1 batchQualityCheck 接入 QcExecutor.executeBatch() | `admin/iitBatchController.ts` | 重新构建镜像 | 替换 SkillRunner 直接调用 |
| BE-14 | V3.1 QcExecutor 集成 D2/D6 维度引擎 | `engines/QcExecutor.ts` | 重新构建镜像 | 自动运行 CompletenessEngine + ProtocolDeviationEngine |
| BE-15 | V3.1 QcAggregator 集成 HealthScoreEngine | `engines/QcAggregator.ts` | 重新构建镜像 | aggregateDeferred 末尾自动刷新健康度 |
| BE-16 | V3.1 QcReportService 数据源升级 | `services/QcReportService.ts` | 重新构建镜像 | qc_field_status + event_overview + dimension_summary |
| BE-17 | V3.1 iitQcCockpitService 升级 | `admin/iitQcCockpitService.ts` | 重新构建镜像 | 热力图 record×event + healthScore/维度 |
| BE-18 | V3.1 新增 API: dimensions / completeness / field-status | `admin/iitQcCockpitRoutes.ts` + Controller | 重新构建镜像 | 3 个新 GET 端点 |
| BE-19 | V3.1 ToolsService check_quality → QcExecutor | `services/ToolsService.ts` | 重新构建镜像 | + read_report dimension_summary/event_overview |
| BE-20 | B4: 项目级 cronExpression 持久化 + 调度器重构 | `iitProjectService.ts`, `iit-manager/index.ts` | 重新构建镜像 | 旧全局 cron → dispatcher 每分钟轮询 + per-project 匹配 |
| BE-21 | B4: iit_scheduled_qc Worker V3.1 升级 | `iit-manager/index.ts` | 重新构建镜像 | 替换 HardRuleEngine → QcExecutor.executeBatch |
| BE-22 | P0-A: SkillRunner evidence 传播 category + subType | `engines/SkillRunner.ts` | 重新构建镜像 | D1 规则不再被错误存为 D3需重跑全量 QC |
| BE-23 | P0-A: QcExecutor dimCode 回退逻辑增强 | `engines/QcExecutor.ts` | 重新构建镜像 | 优先取 evidence.category |
| BE-24 | P0-B: ProtocolDeviationEngine 输出结构化 JSON actual_value | `engines/ProtocolDeviationEngine.ts` | 重新构建镜像 | D6 API 零正则零脆断 |
| BE-25 | GCP D1 筛选入选表 API + D2 完整性总览/字段懒加载 API | `iitQcCockpitService/Controller/Routes` | 重新构建镜像 | 5 层数据 + L4/L5 按需加载 |
| BE-26 | GCP D3/D4 eQuery 全生命周期跟踪 API | `iitQcCockpitService/Controller/Routes` | 重新构建镜像 | 统计+分组+全量明细+时间线 |
| BE-27 | GCP D6 方案偏离报表增强 API | `iitQcCockpitService/Controller/Routes` | 重新构建镜像 | JSON.parse(actual_value) 结构化超窗数据 |
### 前端变更
| # | 变更内容 | 涉及文件 | 需要操作 | 备注 |
|---|---------|---------|---------|------|
| — | *暂无* | | | |
| FE-1 | V3.1 DashboardPage: 后端 healthScore + D1-D7 维度条 | `DashboardPage.tsx` | 重新构建前端 | 替换客户端健康度计算 |
| FE-2 | V3.1 热力图 record×event 矩阵 | `DashboardPage.tsx` | 重新构建前端 | cells 用 eventId |
| FE-3 | V3.1 ReportsPage: 维度分析 + 事件概览 tab | `ReportsPage.tsx` | 重新构建前端 | 2 新 Tab + 五级坐标列 |
| FE-4 | V3.1 API 客户端 + 类型定义 | `iitProjectApi.ts`, `qcCockpit.ts` | 重新构建前端 | 3 个新 API + V3.1 类型 |
| FE-5 | B4: 管理端项目配置页 cron UI 增强 | `IitProjectDetailPage.tsx`, `iitProject.ts` | 重新构建前端 | 更多预设选项 + 自定义 cron 输入框 |
| FE-6 | V3.1 管理端类型 V3.1 升级 | `qcCockpit.ts` | 重新构建前端 | HeatmapCell.eventId + DimensionBreakdown + DeviationItem + RecordDetail 五级坐标 |
| FE-7 | V3.1 管理端 API 客户端升级 | `iitProjectApi.ts` | 重新构建前端 | getQcRecordDetail(eventId) + getDeviations + getDimensions + getCompleteness + getFieldStatus |
| FE-8 | V3.1 QcDetailDrawer 事件级详情 + 维度标签 | `QcDetailDrawer.tsx` | 重新构建前端 | eventId 传参 + 语义标签 + D-code Tag |
| FE-9 | V3.1 RiskHeatmap 列头中文化 | `RiskHeatmap.tsx` | 重新构建前端 | 使用后端 columnLabels 映射 + Tooltip 显示原始 eventId |
| FE-10 | V3.1 IitQcCockpitPage 方案偏离弹窗升级 | `IitQcCockpitPage.tsx` | 重新构建前端 | 调用 D6 deviations API + 五级坐标定位表格 |
| FE-11 | V3.1 QcReportDrawer 维度分析 + 事件概览 Tab | `QcReportDrawer.tsx` | 重新构建前端 | 新增维度分析(D1-D7)和事件概览(按受试者缺失率)Tab |
| FE-12 | GCP 业务端 API 类型定义 | `iit/api/iitProjectApi.ts` | 重新构建前端 | 5 个报表接口 + 完整 TS 类型 |
| FE-13 | GCP ReportsPage 重构为 5 Tab | `iit/pages/ReportsPage.tsx` | 重新构建前端 | 执行摘要 + D1/D2/D3D4/D6 四张 GCP 报表 |
| FE-14 | GCP D1 EligibilityTable 组件 | `iit/components/reports/EligibilityTable.tsx` | 重新构建前端 | 纳入/排除逐条判定 + 受试者展开 |
| FE-15 | GCP D2 CompletenessTable 组件 | `iit/components/reports/CompletenessTable.tsx` | 重新构建前端 | L2/L3 统计 + L4/L5 懒加载展开 |
| FE-16 | GCP D3/D4 EqueryLogTable 组件 | `iit/components/reports/EqueryLogTable.tsx` | 重新构建前端 | eQuery 生命周期时间线 + 筛选 |
| FE-17 | GCP D6 DeviationLogTable 组件 | `iit/components/reports/DeviationLogTable.tsx` | 重新构建前端 | 结构化超窗数据 + 影响评估/CAPA 预留 |
### Python 微服务变更