Completed features: - Created Dify dataset (Dify_test0102) with 2 processed documents - Linked test0102 project with Dify dataset ID - Extended intent detection to recognize query_protocol intent - Implemented queryDifyKnowledge method (semantic search Top 5) - Integrated hybrid retrieval (REDCap data + Dify documents) - Fixed AI hallucination bugs (intent detection + API field path) - Developed debugging scripts - Completed end-to-end testing (5 scenarios passed) - Generated comprehensive documentation (600+ lines) - Updated development plans and module status Technical highlights: - Single project single knowledge base architecture - Smart routing based on user intent - Prevent AI hallucination by injecting real data/documents - Session memory for multi-turn conversations - Reused LLMFactory for DeepSeek-V3 integration Bug fixes: - Fixed intent detection missing keywords - Fixed Dify API response field path error Testing: All scenarios verified in WeChat production environment Status: Fully tested and deployed
15 KiB
Day 2 - REDCap 实时集成开发完成记录
开发日期: 2026-01-02
开发者: AI Assistant + 用户
文档版本: v1.0
开发阶段: Day 2 - REDCap对接与实时同步
📋 开发概述
Day 2的核心目标是实现 IIT Manager Agent 与 REDCap 的实时数据集成,采用 REDCap 原生的 Data Entry Trigger (DET) + REST API 技术方案,实现零延迟的数据同步和双向通信。
核心价值
- ✅ 实时性: Webhook响应时间<10ms,数据录入后立即触发
- ✅ 可靠性: DET + 定时轮询双保险机制
- ✅ 云原生: 完全基于Postgres-Only架构,使用pg-boss队列
- ✅ 标准化: 符合团队开发规范(队列名称、Worker注册等)
🎯 完成的功能模块
1. RedcapAdapter (API适配器)
文件: backend/src/modules/iit-manager/adapters/RedcapAdapter.ts
核心功能:
- ✅
testConnection()- 连接测试 - ✅
exportMetadata()- 导出字段定义(17个字段) - ✅
exportRecords()- 导出记录(支持全量/增量/指定记录) - ✅
importRecords()- 导入记录(Phase 2预留)
关键参数:
baseUrl:http://localhost:8080apiToken:FCB30F9CBD12EE9E8E9B3E3A0106701Btimeout: 30秒
实际性能:
- exportMetadata: 260-560ms
- exportRecords (全量): 450-1,400ms
- exportRecords (增量): 300-800ms
2. WebhookController (Webhook接收器)
文件: backend/src/modules/iit-manager/controllers/WebhookController.ts
核心逻辑:
1. 立即返回200 OK(<10ms)
2. 验证project_id是否在配置中
3. 幂等性检查(防止重复处理)
4. 记录审计日志(WEBHOOK_RECEIVED)
5. 推送到质控队列(iit_quality_check)
REDCap DET格式支持:
- ✅ 添加了
application/x-www-form-urlencoded解析器 - ✅ 支持REDCap原生POST格式
Webhook字段:
{
"project_id": "16",
"record": "6",
"instrument": "demographics",
"redcap_event_name": "",
"redcap_version": "15.8.0",
"redcap_url": "http://localhost:8080"
}
3. SyncManager (轮询管理器)
文件: backend/src/modules/iit-manager/services/SyncManager.ts
核心功能:
- ✅
initScheduledJob()- 初始化定时任务(每5分钟) - ✅
handlePoll()- 轮询所有active项目 - ✅
manualSync()- 手动同步指定项目 - ✅
fullSync()- 全量同步
增量同步策略:
// 基于lastSyncAt时间戳
dateRangeBegin: lastSyncAt || createdAt - 24h
审计日志:
SCHEDULED_SYNC: 定时轮询完成MANUAL_SYNC: 手动同步完成FULL_SYNC: 全量同步完成
4. Worker注册 (异步任务处理)
文件: backend/src/modules/iit-manager/index.ts
注册的Worker:
-
iit_redcap_poll (定时轮询)
- 队列名称:
iit_redcap_poll - 触发频率: 每5分钟(Cron:
*/5 * * * *) - 并发数: 1
- 功能: 轮询所有active项目的增量数据
- 队列名称:
-
iit_quality_check (质控任务)
- 队列名称:
iit_quality_check - 触发方式: Webhook/SyncManager推送
- 功能: 质控逻辑(Phase 1.5实现)
- 队列名称:
关键修复:
- ❌ 初始:
await jobQueue.work('iit:redcap:poll', ...) - ✅ 修复:
jobQueue.process('iit_redcap_poll', ...) - ❌ 初始: 队列名称使用冒号
iit:quality-check - ✅ 修复: 使用下划线
iit_quality_check
5. 路由配置
文件: backend/src/modules/iit-manager/routes/index.ts
注册的API端点:
| 端点 | 方法 | 功能 | 状态 |
|---|---|---|---|
/api/v1/iit/health |
GET | 健康检查 | ✅ |
/api/v1/iit/webhooks/redcap |
POST | DET回调接收 | ✅ |
/api/v1/iit/webhooks/health |
GET | Webhook健康检查 | ✅ |
/api/v1/iit/projects/:id/sync |
POST | 手动同步 | ✅ |
/api/v1/iit/projects/:id/full-sync |
POST | 全量同步 | ✅ |
🐛 遇到的问题与解决方案
问题1: 模块路径解析错误
错误信息:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@/common'
原因: 项目使用相对路径,而不是路径别名 @/common
解决方案:
// 错误
import { logger } from '@/common/logging';
import { jobQueue } from '@/common/jobs';
// 正确
import { logger } from '../../../common/logging/index.js';
import { jobQueue } from '../../../common/jobs/index.js';
修改文件: 所有IIT Manager模块的import语句
问题2: 数据库字段名称不一致
错误信息:
ERROR: column "redcapProjectId" does not exist
原因: Prisma使用camelCase,但PostgreSQL实际使用snake_case
数据库真实情况:
-- 表名: iit_schema.projects (not IitProject)
-- 字段名: redcap_project_id (not redcapProjectId)
解决方案:
- ✅ TypeScript代码中继续使用Prisma的camelCase(自动映射)
- ✅ 原始SQL语句改为snake_case
- ✅ JSON字段使用
'{}'::jsonb类型转换
修改文件:
- 测试脚本中的SQL语句
- 文档中的SQL示例
问题3: pg-boss任务名称格式错误
错误信息:
Name can only contain alphanumeric characters, underscores, hyphens, or periods
原因: 初始使用连字符 -,但实际测试发现不稳定
团队标准:
❌ 'iit:quality-check' // 冒号
❌ 'iit-quality-check' // 连字符(不稳定)
✅ 'iit_quality_check' // 下划线(推荐)
修改:
iit:quality-check→iit_quality_checkiit:redcap:poll→iit_redcap_poll
依据文档: AIclinicalresearch\docs\02-通用能力层\Postgres-Only异步任务处理指南.md
问题4: Worker注册方法错误
错误: 使用了 await jobQueue.work()
正确方法: 使用 jobQueue.process()
对比:
// ❌ 错误
await jobQueue.work(
'iit_redcap_poll',
{ teamSize: 1, teamConcurrency: 1 },
async (job) => { ... }
);
// ✅ 正确
jobQueue.process('iit_redcap_poll', async (job) => {
// ...
return { success: true };
});
问题5: REDCap DET格式不兼容
错误信息:
Unsupported Media Type: application/x-www-form-urlencoded
原因: REDCap DET发送的是表单格式,而不是JSON
解决方案: 添加Content-Type解析器
fastify.addContentTypeParser(
'application/x-www-form-urlencoded',
{ parseAs: 'string' },
(req, body, done) => {
try {
const params = new URLSearchParams(body as string);
const parsed: any = {};
params.forEach((value, key) => {
parsed[key] = value;
});
done(null, parsed);
} catch (err: any) {
done(err);
}
}
);
问题6: Docker网络访问问题
问题: REDCap容器无法通过 localhost 访问宿主机服务
DET URL配置:
❌ http://localhost:3001/api/v1/iit/webhooks/redcap
✅ http://host.docker.internal:3001/api/v1/iit/webhooks/redcap
验证方法:
docker exec redcap-apache curl http://host.docker.internal:3001/api/v1/iit/health
# ✅ 成功返回
✅ 测试验证
1. API连接测试
测试脚本: test-redcap-api.ts
结果:
✅ 连接成功
✅ 元数据导出: 17个字段
✅ 记录导出: 6条记录 (ID: 1,2,3,4,5,6)
✅ 增量同步: 成功获取最近1小时数据
✅ 指定记录: 成功导出单条记录
2. Webhook接收测试
测试脚本: test-redcap-webhook.ts
结果:
✅ 健康检查: ok
✅ Webhook发送成功: 200
✅ 响应时间: <10ms (优秀)
✅ 幂等性检查: 通过
✅ 无效请求拦截: 400错误
3. 集成测试
测试脚本: test-redcap-integration.ts
结果: 12/12 通过 ✅
✅ 1. 后端服务运行正常
✅ 2. 项目配置存在
✅ 3. REDCap API连接成功
✅ 4. 元数据获取成功
✅ 5. 记录获取成功
✅ 6. Webhook响应速度<100ms
✅ 7. 异步处理等待完成
✅ 8. 审计日志记录完整
✅ 9. 增量同步成功
✅ 10. 手动同步成功 ⭐
✅ 11. Webhook健康检查
✅ 12. 幂等性测试通过
4. 真实场景测试
操作:
- 在REDCap中新增记录ID 5
- 在REDCap中编辑记录ID 1
- 在REDCap中新增记录ID 6
- 在REDCap中编辑记录ID 4
Webhook接收日志:
action_type | entity_id | details
------------------+-----------+--------------------------------------------------
WEBHOOK_RECEIVED | 4 | instrument: ddcd, project_id: 16
WEBHOOK_RECEIVED | 6 | instrument: demographics, project_id: 16
验证结果: ✅ 数据完全一致
📊 性能指标
API响应时间
| 操作 | 耗时 | 数据量 |
|---|---|---|
| exportMetadata | 260-560ms | 17个字段 |
| exportRecords (全量) | 450-1,400ms | 6条记录 |
| exportRecords (增量) | 300-800ms | 变化记录 |
| Webhook响应 | <10ms | 立即返回 |
实时性验证
| 指标 | 目标 | 实际 | 状态 |
|---|---|---|---|
| Webhook响应时间 | <100ms | 7ms | ✅ 优秀 |
| DET触发延迟 | 0秒 | 0秒 | ✅ 完美 |
| 数据同步准确性 | 100% | 100% | ✅ 完美 |
🗄️ 数据库配置
REDCap项目配置
数据库表: iit_schema.projects
INSERT INTO iit_schema.projects (
id,
name,
redcap_project_id,
redcap_api_token,
redcap_base_url,
status,
settings,
created_at,
updated_at
) VALUES (
'40062738-2eb5-472f-8a36-e098f5c2f9b9',
'test0102',
'16',
'FCB30F9CBD12EE9E8E9B3E3A0106701B',
'http://localhost:8080',
'active',
'{}'::jsonb,
NOW(),
NOW()
);
REDCap项目信息
| 字段 | 值 |
|---|---|
| 项目名称 | test0102 |
| Project ID | 16 (int) |
| REDCap URL | http://localhost:8080/redcap_v15.8.0 |
| API Token | FCB30F9CBD12EE9E8E9B3E3A0106701B |
| DET URL | http://host.docker.internal:3001/api/v1/iit/webhooks/redcap |
表单结构
1. demographics (基本信息)
- record_id, first_name, last_name, address
- telephone, email, dob, age
- ethnicity, race, sex
- height, weight, bmi
- comments, demographics_complete
2. ddcd (自定义表单)
- zhiliaoshi (治疗室)
- shifou (是否)
- ddcd_complete
📝 审计日志示例
Webhook接收日志
{
"action_type": "WEBHOOK_RECEIVED",
"entity_id": "6",
"details": {
"record": "6",
"source": "redcap_det",
"instrument": "demographics",
"project_id": "16"
},
"created_at": "2026-01-02 09:50:32"
}
同步完成日志
{
"action_type": "SCHEDULED_SYNC",
"entity_id": "40062738-2eb5-472f-8a36-e098f5c2f9b9",
"details": {
"source": "sync_manager",
"duration": 447,
"recordCount": 3,
"uniqueRecordCount": 3
},
"created_at": "2026-01-02 09:20:17"
}
🎓 经验总结
1. 技术选型验证
✅ REDCap DET + REST API方案优势:
- 零开发成本(REDCap原生支持)
- 零延迟(实时触发)
- 高可靠(Webhook + 轮询双保险)
- 易维护(标准HTTP接口)
❌ 放弃的方案:
- External Module(需要PHP开发)
- 纯轮询(延迟高,资源浪费)
2. 开发规范遵循
✅ 符合团队标准:
- 队列名称: 使用下划线(
iit_quality_check) - Worker注册: 使用
jobQueue.process() - 审计日志: 记录所有关键操作
- 错误处理: 统一异常捕获和日志记录
参考文档:
Postgres-Only异步任务处理指南.mdREDCap对接技术方案与实施指南.md
3. 调试技巧
Docker容器调试:
# 测试网络连通性
docker exec redcap-apache curl http://host.docker.internal:3001/api/v1/iit/health
# 查询审计日志
docker exec ai-clinical-postgres psql -U postgres -d ai_clinical_research \
-c "SELECT * FROM iit_schema.audit_logs ORDER BY created_at DESC LIMIT 5;"
# 查询项目配置
docker exec ai-clinical-postgres psql -U postgres -d ai_clinical_research \
-c "SELECT name, redcap_project_id, status FROM iit_schema.projects;"
REDCap数据库查询:
docker exec redcap-mysql mysql -u redcap_user -predcap_pass_dev_456 redcap \
-e "SELECT project_id, app_title FROM redcap_projects WHERE project_id = 16;"
📚 相关文档
| 文档名称 | 路径 | 说明 |
|---|---|---|
| REDCap对接技术方案 | 04-开发计划/REDCap对接技术方案与实施指南.md |
Day 2技术方案 |
| MVP开发任务清单 | 04-开发计划/MVP开发任务清单.md |
整体开发计划 |
| Postgres-Only异步任务处理指南 | docs/02-通用能力层/Postgres-Only异步任务处理指南.md |
队列开发规范 |
| 模块当前状态 | 00-模块当前状态与开发指南.md |
模块整体状态 |
🚀 下一步计划
Phase 1.5 - 质控逻辑实现
目标: 实现AI驱动的数据质控
核心功能:
- 实现
iit_quality_checkWorker的质控逻辑 - 调用Dify工作流进行数据验证
- 生成质控建议(shadow state)
- 返回结果给研究者
预估工作量: 1-2天
Phase 2 - 双向同步
目标: 实现AI建议回写到REDCap
核心功能:
- 完善
importRecords()API - 实现shadow state审批流程
- 经研究者确认后同步到REDCap
- 处理冲突和版本控制
预估工作量: 2-3天
✅ 验收清单
- RedcapAdapter API适配器完成
- WebhookController Webhook接收器完成
- SyncManager 轮询管理器完成
- Worker注册和队列配置完成
- 路由配置和Content-Type解析完成
- 单元测试脚本通过(test-redcap-api.ts)
- Webhook测试通过(test-redcap-webhook.ts)
- 集成测试通过(test-redcap-integration.ts,12/12)
- 真实场景测试通过(新增+编辑记录)
- 审计日志记录完整
- 性能指标达标(Webhook<10ms)
- 符合团队开发规范
- 文档更新完成
📌 附录
A. 环境信息
开发环境:
- OS: Windows 11
- Node.js: v22.18.0
- PostgreSQL: 16.1 (Docker)
- REDCap: 15.8.0 (Docker)
- Backend: Fastify + Prisma
- 队列: pg-boss
Docker容器:
- redcap-apache: REDCap应用
- redcap-mysql: REDCap数据库
- ai-clinical-postgres: IIT数据库
B. 关键代码文件清单
backend/src/modules/iit-manager/
├── adapters/
│ └── RedcapAdapter.ts (271行)
├── controllers/
│ └── WebhookController.ts (327行)
├── services/
│ └── SyncManager.ts (398行)
├── routes/
│ └── index.ts (203行)
├── index.ts (91行)
├── test-redcap-api.ts (189行)
├── test-redcap-webhook.ts (274行)
└── test-redcap-integration.ts (449行)
总代码量: ~2,200行
文档维护者: 开发团队
最后更新: 2026-01-02
状态: ✅ Day 2 开发完成