Files
AIclinicalresearch/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day2-REDCap实时集成开发完成记录.md
HaHafeng b31255031e feat(iit-manager): Add WeChat Official Account integration for patient notifications
Features:
- PatientWechatCallbackController for URL verification and message handling
- PatientWechatService for template and customer messages
- Support for secure mode (message encryption/decryption)
- Simplified route /wechat/patient/callback for WeChat config
- Event handlers for subscribe/unsubscribe/text messages
- Template message for visit reminders

Technical details:
- Reuse @wecom/crypto for encryption (compatible with Official Account)
- Relaxed Fastify schema validation to prevent early request blocking
- Access token caching (7000s with 5min pre-refresh)
- Comprehensive logging for debugging

Testing: Local URL verification passed, ready for SAE deployment

Status: Code complete, waiting for WeChat platform configuration
2026-01-04 22:53:42 +08:00

15 KiB
Raw Blame History

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 技术方案,实现零延迟的数据同步和双向通信。

核心价值

  1. 实时性: Webhook响应时间<10ms数据录入后立即触发
  2. 可靠性: DET + 定时轮询双保险机制
  3. 云原生: 完全基于Postgres-Only架构使用pg-boss队列
  4. 标准化: 符合团队开发规范队列名称、Worker注册等

🎯 完成的功能模块

1. RedcapAdapter (API适配器)

文件: backend/src/modules/iit-manager/adapters/RedcapAdapter.ts

核心功能:

  • testConnection() - 连接测试
  • exportMetadata() - 导出字段定义17个字段
  • exportRecords() - 导出记录(支持全量/增量/指定记录)
  • importRecords() - 导入记录Phase 2预留

关键参数:

  • baseUrl: http://localhost:8080
  • apiToken: FCB30F9CBD12EE9E8E9B3E3A0106701B
  • timeout: 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:

  1. iit_redcap_poll (定时轮询)

    • 队列名称: iit_redcap_poll
    • 触发频率: 每5分钟Cron: */5 * * * *
    • 并发数: 1
    • 功能: 轮询所有active项目的增量数据
  2. 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)

解决方案:

  1. TypeScript代码中继续使用Prisma的camelCase自动映射
  2. 原始SQL语句改为snake_case
  3. 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-checkiit_quality_check
  • iit:redcap:polliit_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. 真实场景测试

操作:

  1. 在REDCap中新增记录ID 5
  2. 在REDCap中编辑记录ID 1
  3. 在REDCap中新增记录ID 6
  4. 在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异步任务处理指南.md
  • REDCap对接技术方案与实施指南.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驱动的数据质控

核心功能:

  1. 实现 iit_quality_check Worker的质控逻辑
  2. 调用Dify工作流进行数据验证
  3. 生成质控建议shadow state
  4. 返回结果给研究者

预估工作量: 1-2天


Phase 2 - 双向同步

目标: 实现AI建议回写到REDCap

核心功能:

  1. 完善 importRecords() API
  2. 实现shadow state审批流程
  3. 经研究者确认后同步到REDCap
  4. 处理冲突和版本控制

预估工作量: 2-3天


验收清单

  • RedcapAdapter API适配器完成
  • WebhookController Webhook接收器完成
  • SyncManager 轮询管理器完成
  • Worker注册和队列配置完成
  • 路由配置和Content-Type解析完成
  • 单元测试脚本通过test-redcap-api.ts
  • Webhook测试通过test-redcap-webhook.ts
  • 集成测试通过test-redcap-integration.ts12/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 开发完成