feat(aia): Complete AIA V2.0 with universal streaming capabilities
Major Changes: - Add StreamingService with OpenAI Compatible format - Upgrade Chat component V2 with Ant Design X integration - Implement AIA module with 12 intelligent agents - Update API routes to unified /api/v1 prefix - Update system documentation Backend (~1300 lines): - common/streaming: OpenAI Compatible adapter - modules/aia: 12 agents, conversation service, streaming integration - Update route versions (RVW, PKB to v1) Frontend (~3500 lines): - modules/aia: AgentHub + ChatWorkspace (100% prototype restoration) - shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook - Update API endpoints to v1 Documentation: - AIA module status guide - Universal capabilities catalog - System overview updates - All module documentation sync Tested: Stream response verified, authentication working Status: AIA V2.0 core completed (85%)
This commit is contained in:
@@ -1,76 +1,57 @@
|
||||
# IIT Manager Agent - Day 2 寮€鍙戝畬鎴愭€荤粨
|
||||
|
||||
**鏃ユ湡**: 2026-01-02
|
||||
**开发者**: AI Assistant
|
||||
**状态**: ✅ 全部完成
|
||||
**寮€鍙戣€?*: AI Assistant
|
||||
**鐘舵€?*: 鉁?鍏ㄩ儴瀹屾垚
|
||||
|
||||
---
|
||||
|
||||
## 馃搵 浠诲姟瀹屾垚娓呭崟
|
||||
|
||||
- [x] 鐜<><E9909C>鍑嗗<E98D91>锛欴ET閰嶇疆 + API Token鑾峰彇
|
||||
- [x] 开发 RedcapAdapter(API适配器)
|
||||
- [x] 开发 WebhookController(Webhook接收器)
|
||||
- [x] 开发 SyncManager(轮询管理)
|
||||
- [x] 寮€鍙?RedcapAdapter锛圓PI閫傞厤鍣<EFBFBD>級
|
||||
- [x] 寮€鍙?WebhookController锛圵ebhook鎺ユ敹鍣<EFBFBD>級
|
||||
- [x] 寮€鍙?SyncManager锛堣疆璇㈢<EFBFBD>鐞嗭級
|
||||
- [x] 閰嶇疆璺<E79686>敱鍜學orker娉ㄥ唽
|
||||
- [x] 编写测试脚本(API + Webhook + 集成)
|
||||
- [x] 端到端验证测试准备
|
||||
|
||||
- [x] 缂栧啓娴嬭瘯鑴氭湰锛圓PI + Webhook + 闆嗘垚锛?- [x] 绔<>埌绔<E59F8C>獙璇佹祴璇曞噯澶?
|
||||
---
|
||||
|
||||
## 馃幆 鏍稿績鎴愭灉
|
||||
|
||||
### 1. RedcapAdapter - API适配器
|
||||
|
||||
### 1. RedcapAdapter - API閫傞厤鍣?
|
||||
**鏂囦欢**: `backend/src/modules/iit-manager/adapters/RedcapAdapter.ts`
|
||||
|
||||
**鍔熻兘**:
|
||||
- ✅ `exportRecords()` - 支持增量同步(dateRangeBegin)
|
||||
- ✅ `exportMetadata()` - 获取字段定义
|
||||
- ✅ `importRecords()` - 回写数据(Phase 2预留)
|
||||
- ✅ `testConnection()` - 连接测试
|
||||
- ✅ 完整的错误处理和日志记录
|
||||
- ✅ 性能监控(请求耗时)
|
||||
|
||||
**技术亮点**:
|
||||
- 使用 `form-data` 构造 multipart/form-data 请求
|
||||
- 智能日期格式化(REDCap格式:YYYY-MM-DD HH:MM:SS)
|
||||
- Axios 实例化,支持超时配置
|
||||
- 友好的错误信息(连接失败、权限不足、端点不存在)
|
||||
|
||||
- 鉁?`exportRecords()` - 鏀<EFBFBD>寔澧為噺鍚屾<EFBFBD>锛坉ateRangeBegin锛?- 鉁?`exportMetadata()` - 鑾峰彇瀛楁<E7809B>瀹氫箟
|
||||
- 鉁?`importRecords()` - 鍥炲啓鏁版嵁锛圥hase 2棰勭暀锛?- 鉁?`testConnection()` - 杩炴帴娴嬭瘯
|
||||
- 鉁?瀹屾暣鐨勯敊璇<E6958A><E79287>鐞嗗拰鏃ュ織璁板綍
|
||||
- 鉁?鎬ц兘鐩戞帶锛堣<E9949B>姹傝€楁椂锛?
|
||||
**鎶€鏈<E282AC>寒鐐?*:
|
||||
- 浣跨敤 `form-data` 鏋勯€?multipart/form-data 璇锋眰
|
||||
- 鏅鸿兘鏃ユ湡鏍煎紡鍖栵紙REDCap鏍煎紡锛歒YYY-MM-DD HH:MM:SS锛?- Axios 瀹炰緥鍖栵紝鏀<E7B49D>寔瓒呮椂閰嶇疆
|
||||
- 鍙嬪ソ鐨勯敊璇<E6958A>俊鎭<E4BF8A>紙杩炴帴澶辫触銆佹潈闄愪笉瓒炽€佺<E282AC>鐐逛笉瀛樺湪锛?
|
||||
---
|
||||
|
||||
### 2. WebhookController - Webhook接收器
|
||||
|
||||
### 2. WebhookController - Webhook鎺ユ敹鍣?
|
||||
**鏂囦欢**: `backend/src/modules/iit-manager/controllers/WebhookController.ts`
|
||||
|
||||
**鍔熻兘**:
|
||||
- ✅ 接收 REDCap DET Webhook
|
||||
- ✅ **极速响应**:<100ms 返回 200 OK
|
||||
- ✅ 异步处理(`setImmediate`)
|
||||
- ✅ **幂等性检查**:5分钟内防重复
|
||||
- ✅ 拉取完整记录数据
|
||||
- ✅ 推送到质控队列(pg-boss)
|
||||
- ✅ 完整的审计日志
|
||||
|
||||
- 鉁?鎺ユ敹 REDCap DET Webhook
|
||||
- 鉁?**鏋侀€熷搷搴?*锛?100ms 杩斿洖 200 OK
|
||||
- 鉁?寮傛<E5AFAE>澶勭悊锛坄setImmediate`锛?- 鉁?**骞傜瓑鎬ф<E98EAC>鏌?*锛?鍒嗛挓鍐呴槻閲嶅<E996B2>
|
||||
- 鉁?鎷夊彇瀹屾暣璁板綍鏁版嵁
|
||||
- 鉁?鎺ㄩ€佸埌璐ㄦ帶闃熷垪锛坧g-boss锛?- 鉁?瀹屾暣鐨勫<E990A8>璁℃棩蹇?
|
||||
**鎬ц兘鐩<E58598>爣**:
|
||||
- 同步响应:<100ms ✅
|
||||
- 数据拉取:<2s
|
||||
- 端到端通知:<5s
|
||||
- 鍚屾<EFBFBD>鍝嶅簲锛?100ms 鉁?- 鏁版嵁鎷夊彇锛?2s
|
||||
- 绔<EFBFBD>埌绔<EFBFBD>€氱煡锛?5s
|
||||
|
||||
**鏋舵瀯璁捐<E79281>**:
|
||||
```
|
||||
REDCap DET → Webhook接收器 → 立即返回200 OK
|
||||
↓ (异步)
|
||||
REDCap DET 鈫?Webhook鎺ユ敹鍣?鈫?绔嬪嵆杩斿洖200 OK
|
||||
鈫?(寮傛<E5AFAE>)
|
||||
鏌ユ壘椤圭洰閰嶇疆
|
||||
↓
|
||||
幂等性检查
|
||||
↓
|
||||
拉取完整数据
|
||||
↓
|
||||
推送质控队列
|
||||
↓
|
||||
记录审计日志
|
||||
鈫? 骞傜瓑鎬ф<E98EAC>鏌? 鈫? 鎷夊彇瀹屾暣鏁版嵁
|
||||
鈫? 鎺ㄩ€佽川鎺ч槦鍒? 鈫? 璁板綍瀹¤<E780B9>鏃ュ織
|
||||
```
|
||||
|
||||
---
|
||||
@@ -80,21 +61,17 @@ REDCap DET → Webhook接收器 → 立即返回200 OK
|
||||
**鏂囦欢**: `backend/src/modules/iit-manager/services/SyncManager.ts`
|
||||
|
||||
**鍔熻兘**:
|
||||
- ✅ 定时轮询(每5分钟)
|
||||
- ✅ **增量同步**:使用 `lastSyncAt`
|
||||
- ✅ **并发处理多项目**
|
||||
- ✅ 手动同步接口(`manualSync`)
|
||||
- ✅ 全量同步接口(`fullSync`)
|
||||
- ✅ 完整的错误处理和恢复机制
|
||||
- 鉁?瀹氭椂杞<E6A482><E69D9E>锛堟瘡5鍒嗛挓锛?- 鉁?**澧為噺鍚屾<E98D9A>**锛氫娇鐢?`lastSyncAt`
|
||||
- 鉁?**骞跺彂澶勭悊澶氶」鐩?*
|
||||
- 鉁?鎵嬪姩鍚屾<E98D9A>鎺ュ彛锛坄manualSync`锛?- 鉁?鍏ㄩ噺鍚屾<E98D9A>鎺ュ彛锛坄fullSync`锛?- 鉁?瀹屾暣鐨勯敊璇<E6958A><E79287>鐞嗗拰鎭㈠<E98EAD>鏈哄埗
|
||||
|
||||
**浣跨敤鍦烘櫙**:
|
||||
- 鍐呯綉鐜<E7B689><E9909C>鏃犳硶鎺ユ敹Webhook
|
||||
- Webhook涓㈠け鏃剁殑鍏滃簳鏂规<E98F82>
|
||||
- 瀹氭湡鍏ㄩ噺鎵<E599BA>弿
|
||||
|
||||
**技术亮点**:
|
||||
- pg-boss 定时任务(Cron: */5 * * * *)
|
||||
- 按记录ID去重
|
||||
**鎶€鏈<EFBFBD>寒鐐?*:
|
||||
- pg-boss 瀹氭椂浠诲姟锛圕ron: */5 * * * *锛?- 鎸夎<E98EB8>褰旾D鍘婚噸
|
||||
- 澶辫触鑷<E8A7A6>姩閲嶈瘯
|
||||
- 瀹¤<E780B9>鏃ュ織璁板綍
|
||||
|
||||
@@ -106,13 +83,13 @@ REDCap DET → Webhook接收器 → 立即返回200 OK
|
||||
|
||||
**璺<>敱鍒楄〃**:
|
||||
|
||||
| 方法 | 路径 | 功能 | 状态 |
|
||||
| 鏂规硶 | 璺<>緞 | 鍔熻兘 | 鐘舵€?|
|
||||
|-----|------|------|------|
|
||||
| GET | `/api/v1/iit/health` | 健康检查 | ✅ |
|
||||
| POST | `/api/v1/iit/webhooks/redcap` | DET Webhook接收器 | ✅ |
|
||||
| POST | `/api/v1/iit/projects/:id/sync` | 手动触发同步 | ✅ |
|
||||
| POST | `/api/v1/iit/projects/:id/full-sync` | 全量同步 | ✅ |
|
||||
| GET | `/api/v1/iit/webhooks/health` | Webhook健康检查 | ✅ |
|
||||
| GET | `/api/v1/iit/health` | 鍋ュ悍妫€鏌?| 鉁?|
|
||||
| POST | `/api/v1/iit/webhooks/redcap` | DET Webhook鎺ユ敹鍣?| 鉁?|
|
||||
| POST | `/api/v1/iit/projects/:id/sync` | 鎵嬪姩瑙﹀彂鍚屾<EFBFBD> | 鉁?|
|
||||
| POST | `/api/v1/iit/projects/:id/full-sync` | 鍏ㄩ噺鍚屾<EFBFBD> | 鉁?|
|
||||
| GET | `/api/v1/iit/webhooks/health` | Webhook鍋ュ悍妫€鏌?| 鉁?|
|
||||
|
||||
---
|
||||
|
||||
@@ -121,9 +98,7 @@ REDCap DET → Webhook接收器 → 立即返回200 OK
|
||||
**鏂囦欢**: `backend/src/modules/iit-manager/index.ts`
|
||||
|
||||
**Worker鍒楄〃**:
|
||||
- ✅ `iit:redcap:poll` - 定时轮询任务(每5分钟)
|
||||
- 🔜 `iit:quality-check` - 质控任务(Phase 1.5)
|
||||
|
||||
- 鉁?`iit:redcap:poll` - 瀹氭椂杞<EFBFBD><EFBFBD>浠诲姟锛堟瘡5鍒嗛挓锛?- 馃敎 `iit:quality-check` - 璐ㄦ帶浠诲姟锛圥hase 1.5锛?
|
||||
---
|
||||
|
||||
### 6. 娴嬭瘯鑴氭湰
|
||||
@@ -133,13 +108,10 @@ REDCap DET → Webhook接收器 → 立即返回200 OK
|
||||
**鏂囦欢**: `backend/src/modules/iit-manager/test-redcap-api.ts`
|
||||
|
||||
**娴嬭瘯鍐呭<E98D90>**:
|
||||
- ✅ 创建 Adapter 实例
|
||||
- ✅ 测试API连接
|
||||
- ✅ 导出元数据
|
||||
- ✅ 导出所有记录
|
||||
- ✅ 导出指定记录
|
||||
- ✅ 增量同步测试(最近1小时)
|
||||
|
||||
- 鉁?鍒涘缓 Adapter 瀹炰緥
|
||||
- 鉁?娴嬭瘯API杩炴帴
|
||||
- 鉁?瀵煎嚭鍏冩暟鎹?- 鉁?瀵煎嚭鎵€鏈夎<E98F88>褰?- 鉁?瀵煎嚭鎸囧畾璁板綍
|
||||
- 鉁?澧為噺鍚屾<E98D9A>娴嬭瘯锛堟渶杩?灏忔椂锛?
|
||||
**杩愯<E69DA9>鏂瑰紡**:
|
||||
```bash
|
||||
cd backend
|
||||
@@ -151,14 +123,8 @@ npm run tsx src/modules/iit-manager/test-redcap-api.ts
|
||||
**鏂囦欢**: `backend/src/modules/iit-manager/test-redcap-webhook.ts`
|
||||
|
||||
**娴嬭瘯鍐呭<E98D90>**:
|
||||
- ✅ Webhook健康检查
|
||||
- ✅ 检查项目配置
|
||||
- ✅ 发送测试Webhook
|
||||
- ✅ 验证响应时间(<100ms)
|
||||
- ✅ 检查审计日志
|
||||
- ✅ 测试幂等性
|
||||
- ✅ 测试无效Webhook(400错误)
|
||||
|
||||
- 鉁?Webhook鍋ュ悍妫€鏌?- 鉁?妫€鏌ラ」鐩<E3808D>厤缃?- 鉁?鍙戦€佹祴璇昗ebhook
|
||||
- 鉁?楠岃瘉鍝嶅簲鏃堕棿锛?100ms锛?- 鉁?妫€鏌ュ<E98F8C>璁℃棩蹇?- 鉁?娴嬭瘯骞傜瓑鎬?- 鉁?娴嬭瘯鏃犳晥Webhook锛?00閿欒<E996BF>锛?
|
||||
**杩愯<E69DA9>鏂瑰紡**:
|
||||
```bash
|
||||
cd backend
|
||||
@@ -170,19 +136,12 @@ npm run tsx src/modules/iit-manager/test-redcap-webhook.ts
|
||||
**鏂囦欢**: `backend/src/modules/iit-manager/test-redcap-integration.ts`
|
||||
|
||||
**娴嬭瘯鍐呭<E98D90>**:
|
||||
- ✅ 后端服务检查
|
||||
- ✅ 数据库配置检查
|
||||
- ✅ REDCap API连接
|
||||
- ✅ 元数据获取
|
||||
- ✅ 记录获取
|
||||
- ✅ Webhook接收器测试
|
||||
- ✅ 异步处理验证
|
||||
- ✅ 审计日志检查
|
||||
- ✅ 增量同步测试
|
||||
- ✅ 手动同步接口测试
|
||||
- ✅ Webhook健康检查
|
||||
- ✅ 幂等性测试
|
||||
|
||||
- 鉁?鍚庣<E98D9A>鏈嶅姟妫€鏌?- 鉁?鏁版嵁搴撻厤缃<E58EA4><E7BC83>鏌?- 鉁?REDCap API杩炴帴
|
||||
- 鉁?鍏冩暟鎹<E69A9F>幏鍙?- 鉁?璁板綍鑾峰彇
|
||||
- 鉁?Webhook鎺ユ敹鍣ㄦ祴璇?- 鉁?寮傛<E5AFAE>澶勭悊楠岃瘉
|
||||
- 鉁?瀹¤<E780B9>鏃ュ織妫€鏌?- 鉁?澧為噺鍚屾<E98D9A>娴嬭瘯
|
||||
- 鉁?鎵嬪姩鍚屾<E98D9A>鎺ュ彛娴嬭瘯
|
||||
- 鉁?Webhook鍋ュ悍妫€鏌?- 鉁?骞傜瓑鎬ф祴璇?
|
||||
**杩愯<E69DA9>鏂瑰紡**:
|
||||
```bash
|
||||
cd backend
|
||||
@@ -193,8 +152,7 @@ npm run tsx src/modules/iit-manager/test-redcap-integration.ts
|
||||
|
||||
## 馃敡 鐜<><E9909C>閰嶇疆
|
||||
|
||||
### REDCap 配置(已完成)
|
||||
|
||||
### REDCap 閰嶇疆锛堝凡瀹屾垚锛?
|
||||
**椤圭洰淇℃伅**:
|
||||
- 椤圭洰鍚嶇О: test0102
|
||||
- 椤圭洰ID (PID): 16
|
||||
@@ -242,48 +200,38 @@ INSERT INTO iit_schema.projects (
|
||||
|
||||
## 馃搳 涓庢枃妗g殑瀵规瘮
|
||||
|
||||
### ✅ 完全符合的地方
|
||||
|
||||
1. **技术方案**: DET + REST API(不使用External Modules)
|
||||
2. **混合模式**: Webhook实时触发 + 轮询兜底
|
||||
3. **核心逻辑**: 幂等性、异步处理、增量同步
|
||||
4. **代码结构**: Adapter、Controller、Service分层清晰
|
||||
5. **性能目标**: <100ms响应、5s端到端
|
||||
|
||||
### 🚀 超越文档的地方
|
||||
|
||||
1. **更强大的错误处理**: 连接测试、友好错误信息
|
||||
2. **更完善的日志**: 性能监控、详细上下文
|
||||
### 鉁?瀹屽叏绗﹀悎鐨勫湴鏂?
|
||||
1. **鎶€鏈<E282AC>柟妗?*: DET + REST API锛堜笉浣跨敤External Modules锛?2. **娣峰悎妯″紡**: Webhook瀹炴椂瑙﹀彂 + 杞<><E69D9E>鍏滃簳
|
||||
3. **鏍稿績閫昏緫**: 骞傜瓑鎬с€佸紓姝ュ<EFBFBD>鐞嗐€佸<EFBFBD>閲忓悓姝?4. **浠g爜缁撴瀯**: Adapter銆丆ontroller銆丼ervice鍒嗗眰娓呮櫚
|
||||
5. **鎬ц兘鐩<EFBFBD>爣**: <100ms鍝嶅簲銆?s绔<73>埌绔?
|
||||
### 馃殌 瓒呰秺鏂囨。鐨勫湴鏂?
|
||||
1. **鏇村己澶х殑閿欒<EFBFBD>澶勭悊**: 杩炴帴娴嬭瘯銆佸弸濂介敊璇<E6958A>俊鎭?2. **鏇村畬鍠勭殑鏃ュ織**: 鎬ц兘鐩戞帶銆佽<E98A86>缁嗕笂涓嬫枃
|
||||
3. **鏇寸伒娲荤殑鍚屾<E98D9A>**: 鎵嬪姩鍚屾<E98D9A>銆佸叏閲忓悓姝ャ€佸苟鍙戝<E98D99>鐞嗗<E9909E>椤圭洰
|
||||
4. **鏇村畬鍠勭殑娴嬭瘯**: API娴嬭瘯銆乄ebhook娴嬭瘯銆侀泦鎴愭祴璇曪紙12椤规祴璇曪級
|
||||
5. **更好的代码质量**: 详细注释、类型定义、Schema验证
|
||||
5. **鏇村ソ鐨勪唬鐮佽川閲?*: 璇︾粏娉ㄩ噴銆佺被鍨嬪畾涔夈€丼chema楠岃瘉
|
||||
|
||||
### ⚠️ 修正的地方
|
||||
### 鈿狅笍 淇<><E6B787>鐨勫湴鏂?
|
||||
1. **鏁版嵁搴撳瓧娈靛悕**: 鏂囨。鐢?`snake_case`锛屽疄闄匰chema鐢?`camelCase`
|
||||
- `redcap_api_token` 鈫?`redcapApiToken`
|
||||
- `redcap_api_base_url` 鈫?`redcapUrl`
|
||||
- `sync_enabled` 鈫?锛堟殏鏈<E6AE8F>湪Schema涓<61>畾涔夛級
|
||||
|
||||
1. **数据库字段名**: 文档用 `snake_case`,实际Schema用 `camelCase`
|
||||
- `redcap_api_token` → `redcapApiToken`
|
||||
- `redcap_api_base_url` → `redcapUrl`
|
||||
- `sync_enabled` → (暂未在Schema中定义)
|
||||
2. **琛ㄥ悕**: 鏂囨。鐢?`projects`锛屽疄闄呯敤 `IitProject`
|
||||
|
||||
2. **表名**: 文档用 `projects`,实际用 `IitProject`
|
||||
|
||||
3. **审计日志字段**: 文档用 `operation_type`,实际用 `actionType`
|
||||
3. **瀹¤<EFBFBD>鏃ュ織瀛楁<EFBFBD>**: 鏂囨。鐢?`operation_type`锛屽疄闄呯敤 `actionType`
|
||||
|
||||
---
|
||||
|
||||
## 馃攳 Linter 閿欒<E996BF>淇<EFBFBD><E6B787>
|
||||
|
||||
修复了以下类型的错误:
|
||||
|
||||
1. ✅ **模块导入路径**: 移除 `.js` 扩展名(TypeScript导入规范)
|
||||
2. ✅ **数据库字段名**: 统一为 camelCase
|
||||
3. ✅ **类型错误**: 添加显式类型注解
|
||||
4. ✅ **JSON类型**: 使用 `JSON.parse(JSON.stringify())` 转换
|
||||
淇<EFBFBD><EFBFBD>浜嗕互涓嬬被鍨嬬殑閿欒<EFBFBD>锛?
|
||||
1. 鉁?**妯″潡瀵煎叆璺<E58F86>緞**: 绉婚櫎 `.js` 鎵╁睍鍚嶏紙TypeScript瀵煎叆瑙勮寖锛?2. 鉁?**鏁版嵁搴撳瓧娈靛悕**: 缁熶竴涓?camelCase
|
||||
3. 鉁?**绫诲瀷閿欒<E996BF>**: 娣诲姞鏄惧紡绫诲瀷娉ㄨВ
|
||||
4. 鉁?**JSON绫诲瀷**: 浣跨敤 `JSON.parse(JSON.stringify())` 杞<>崲
|
||||
|
||||
---
|
||||
|
||||
## 📝 下一步工作(Day 3)
|
||||
|
||||
## 馃摑 涓嬩竴姝ュ伐浣滐紙Day 3锛?
|
||||
### Phase 1.5: 鏁版嵁璐ㄦ帶Agent
|
||||
|
||||
1. **璐ㄦ帶Worker娉ㄥ唽**:
|
||||
@@ -292,45 +240,37 @@ INSERT INTO iit_schema.projects (
|
||||
|
||||
2. **Dify RAG闆嗘垚**:
|
||||
- 闆嗘垚 Dify Client
|
||||
- 查询研究方案知识库
|
||||
|
||||
- 鏌ヨ<EFBFBD>鐮旂┒鏂规<EFBFBD>鐭ヨ瘑搴?
|
||||
3. **璐ㄦ帶瑙勫垯寮曟搸**:
|
||||
- 瀹炵幇鍩虹<E98DA9>璐ㄦ帶瑙勫垯
|
||||
- 鐢熸垚璐ㄦ帶鎰忚<E98EB0>
|
||||
|
||||
4. **浼佷笟寰<E7AC9F>俊閫氱煡**:
|
||||
- 发送质控卡片
|
||||
- 包含:记录信息、质控问题、建议操作
|
||||
|
||||
5. **影子状态管理**:
|
||||
- 鍙戦€佽川鎺у崱鐗? - 鍖呭惈锛氳<E9949B>褰曚俊鎭<E4BF8A>€佽川鎺ч棶棰樸€佸缓璁<E7BC93>搷浣?
|
||||
5. **褰卞瓙鐘舵€佺<E282AC>鐞?*:
|
||||
- 鍒涘缓 PendingAction
|
||||
- 状态:PROPOSED → APPROVED → EXECUTED
|
||||
- 鐘舵€侊細PROPOSED 鈫?APPROVED 鈫?EXECUTED
|
||||
|
||||
---
|
||||
|
||||
## 馃帀 鎬荤粨
|
||||
|
||||
Day 2 的开发任务**全部完成**!我们成功实现了:
|
||||
|
||||
✅ **完整的REDCap对接能力**
|
||||
✅ **混合同步模式(Webhook + 轮询)**
|
||||
✅ **极速响应的Webhook接收器(<100ms)**
|
||||
✅ **完善的测试脚本**
|
||||
✅ **符合且超越技术文档的实现**
|
||||
Day 2 鐨勫紑鍙戜换鍔?*鍏ㄩ儴瀹屾垚**锛佹垜浠<E59E9C>垚鍔熷疄鐜颁簡锛?
|
||||
鉁?**瀹屾暣鐨凴EDCap瀵规帴鑳藉姏**
|
||||
鉁?**娣峰悎鍚屾<E98D9A>妯″紡锛圵ebhook + 杞<><E69D9E>锛?*
|
||||
鉁?**鏋侀€熷搷搴旂殑Webhook鎺ユ敹鍣<E695B9>紙<100ms锛?*
|
||||
鉁?**瀹屽杽鐨勬祴璇曡剼鏈?*
|
||||
鉁?**绗﹀悎涓旇秴瓒婃妧鏈<E5A6A7>枃妗g殑瀹炵幇**
|
||||
|
||||
**浠g爜璐ㄩ噺**:
|
||||
- 璇︾粏鐨勬敞閲婂拰鏂囨。
|
||||
- 完整的错误处理
|
||||
- 性能监控和日志
|
||||
- 类型安全
|
||||
- 可测试性
|
||||
|
||||
**下一步**: 准备测试环境,运行测试脚本,验证端到端功能!
|
||||
- 瀹屾暣鐨勯敊璇<EFBFBD><EFBFBD>鐞?- 鎬ц兘鐩戞帶鍜屾棩蹇?- 绫诲瀷瀹夊叏
|
||||
- 鍙<EFBFBD>祴璇曟€?
|
||||
**涓嬩竴姝?*: 鍑嗗<E98D91>娴嬭瘯鐜<E798AF><E9909C>锛岃繍琛屾祴璇曡剼鏈<E589BC>紝楠岃瘉绔<E79889>埌绔<E59F8C>姛鑳斤紒
|
||||
|
||||
---
|
||||
|
||||
**开发时间**: ~2小时
|
||||
**代码行数**: ~1,500行
|
||||
**测试覆盖**: 12项集成测试
|
||||
**文档质量**: ⭐⭐⭐⭐⭐
|
||||
|
||||
**寮€鍙戞椂闂?*: ~2灏忔椂
|
||||
**浠g爜琛屾暟**: ~1,500琛?
|
||||
**娴嬭瘯瑕嗙洊**: 12椤归泦鎴愭祴璇?
|
||||
**鏂囨。璐ㄩ噺**: 猸愨瓙猸愨瓙猸?
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,69 +1,69 @@
|
||||
# REDCap蟇ケ謗・謚譛ッ譁ケ譯井ク主ョ樊命謖<E591BD>漉
|
||||
|
||||
**版本:** V1.0
|
||||
**创建日期:** 2026-01-02
|
||||
**适用阶段:** IIT Manager Agent MVP - Day 2
|
||||
**文档性质:** 核心技术基石
|
||||
**重要程度:** ⭐⭐⭐⭐⭐
|
||||
**迚域悽<EFBFBD>?* V1.0
|
||||
**蛻帛サコ譌・譛滂シ?* 2026-01-02
|
||||
**騾ら畑髦カ谿オ<EFBFBD>?* IIT Manager Agent MVP - Day 2
|
||||
**譁<EFBFBD>。」諤ァ雍ィ<EFBFBD>?* 譬ク蠢<EFBDB8>橿譛ッ蝓コ遏?
|
||||
**驥崎ヲ∫ィ句コヲ<EFBFBD>?* 箝絶ュ絶ュ絶ュ絶ュ?
|
||||
|
||||
---
|
||||
|
||||
## <20>搭 譁<>。」逶ョ譬<EFBDAE>
|
||||
|
||||
本文档是IIT Manager Agent与REDCap集成的**权威技术指南**,明确:
|
||||
1. ✅ REDCap对接方式的技术选型
|
||||
2. ✅ Data Entry Trigger (DET) 的验证与配置
|
||||
3. ✅ REST API的使用方法
|
||||
4. ✅ 实时质控的完整架构
|
||||
5. ✅ Day 2的开发实施步骤
|
||||
譛ャ譁<EFBFBD>。」譏ッIIT Manager Agent荳山EDCap髮<EFBFBD><EFBFBD>逧?*譚<>ィ∵橿譛ッ謖<EFBDAF><E8AC96>?*<2A>梧<EFBFBD>遑ョ<E98191><EFBDAE>
|
||||
1. 笨?REDCap蟇ケ謗・譁ケ蠑冗噪謚譛ッ騾牙梛
|
||||
2. 笨?Data Entry Trigger (DET) 逧<EFBFBD>ェ瑚ッ∽ク朱<EFBFBD>鄂ョ
|
||||
3. 笨?REST API逧<EFBFBD>スソ逕ィ譁ケ豕?
|
||||
4. 笨?螳樊慮雍ィ謗ァ逧<EFBDA7>ョ梧紛譫カ譫?
|
||||
5. 笨?Day 2逧<EFBFBD>シ蜿大ョ樊命豁・鬪?
|
||||
|
||||
---
|
||||
|
||||
## 🎯 核心结论(Executive Summary)
|
||||
## <EFBFBD>識 譬ク蠢<EFBDB8>サ楢ョコ<EFBDAE><EFBDBA>xecutive Summary<EFBFBD>?
|
||||
|
||||
### ✅ **技术选型:DET(实时触发) + REST API(数据读写)**
|
||||
### 笨?**謚譛ッ騾牙梛<E78999>咼ET<45>亥ョ樊慮隗ヲ蜿托シ<E68998> + REST API<50>域焚謐ョ隸サ蜀呻シ<E591BB>**
|
||||
|
||||
**荳埼㊦逕ィ<E98095><EFBDA8>** External Module (EM)
|
||||
**原因:** EM需要PHP开发、侵入REDCap源码、维护成本高、不适合外部系统集成
|
||||
**蜴溷屏<EFBFBD>?* EM髴隕 ̄HP蠑蜿代∽セオ蜈・REDCap貅千<E8B285>√∫サエ謚、謌先悽鬮倥∽ク埼ょ粋螟夜Κ邉サ扈滄寔謌<E5AF94>
|
||||
|
||||
**采用方案:**
|
||||
**驥<EFBFBD>畑譁ケ譯茨シ?*
|
||||
|
||||
| 组件 | 技术 | 用途 | 实时性 |
|
||||
| 扈<EFBFBD>サカ | 謚譛?| 逕ィ騾?| 螳樊慮諤?|
|
||||
|------|-----|------|--------|
|
||||
| **Data Entry Trigger** | REDCap原生功能 | 数据保存时实时通知 | 0秒延迟 |
|
||||
| **Data Entry Trigger** | REDCap蜴溽函蜉溯<EFBFBD> | 謨ー謐ョ菫晏ュ俶慮螳樊慮騾夂衍 | 0遘貞サカ霑?|
|
||||
| **REST API (Export)** | HTTP + JSON | 諡牙叙謨ー謐ョ縲∝<E7B8B2>謨ー謐ョ | 謖蛾怙隹<E68099>畑 |
|
||||
| **REST API (Import)** | HTTP + JSON | 回写质控意见(Phase 2) | 按需调用 |
|
||||
| **REST API (Import)** | HTTP + JSON | 蝗槫<EFBFBD>雍ィ謗ァ諢剰ァ<EFBFBD>シ<EFBFBD>hase 2<>?| 謖蛾怙隹<E68099>畑 |
|
||||
| **霓ョ隸「譛コ蛻カ** | pg-boss螳壽慮莉サ蜉。 | 陦・蜈<EFBDA5>ET驕玲シ乗焚謐ョ | 30蛻<30>帖 |
|
||||
|
||||
---
|
||||
|
||||
## 🔍 技术调研结果
|
||||
## <EFBFBD>剥 謚譛ッ隹<EFBDAF><E99AB9>皮サ捺<EFBDBB>?
|
||||
|
||||
### 调研1:REDCap提供的对接方式
|
||||
### 隹<EFBFBD><EFBFBD><EFBFBD>1<EFBFBD>啌EDCap謠蝉セ帷噪蟇ケ謗・譁ケ蠑?
|
||||
|
||||
**调研来源:**
|
||||
**隹<EFBFBD><EFBFBD>疲擂貅撰シ?*
|
||||
- REDCap 15.8.0貅千<EFBFBD><EFBFBD>
|
||||
- External Module Framework螳俶婿譁<E5A9BF>。」
|
||||
- REDCap二次开发深度指南
|
||||
- REDCap莠梧ャ。蠑蜿第キア蠎ヲ謖<EFBFBD><EFBFBD>?
|
||||
|
||||
**蜿醍鴫逧<E9B4AB>ッケ謗・譁ケ蠑擾シ<E693BE>**
|
||||
|
||||
| 譁ケ蠑<EFBDB9> | 謚譛ッ譬<EFBDAF> | 騾ら畑蝨コ譎ッ | 謌台サャ譏ッ蜷ヲ騾ら畑 |
|
||||
|------|--------|---------|-------------|
|
||||
| **External Module** | PHP + Hook | REDCap内部功能扩展、UI定制 | ❌ 不适用 |
|
||||
| **REST API** | HTTP + JSON | 外部系统集成、数据同步 | ✅ **适用** |
|
||||
| **Data Entry Trigger** | Webhook | 实时通知外部系统 | ✅ **适用** |
|
||||
| **External Module** | PHP + Hook | REDCap蜀<EFBFBD>Κ蜉溯<EFBFBD>謇ゥ螻輔ゞI螳壼宛 | 笶?荳埼ら畑 |
|
||||
| **REST API** | HTTP + JSON | 螟夜Κ邉サ扈滄寔謌舌∵焚謐ョ蜷梧ュ?| 笨?**騾ら畑** |
|
||||
| **Data Entry Trigger** | Webhook | 螳樊慮騾夂衍螟夜Κ邉サ扈<EFBFBD> | 笨?**騾ら畑** |
|
||||
|
||||
### 隹<><E99AB9><EFBFBD>2<EFBFBD>咼ata Entry Trigger (DET) 鬪瑚ッ<E7919A>
|
||||
|
||||
**源码位置:**
|
||||
**貅千<EFBFBD>∽ス咲スョ<EFBFBD>?*
|
||||
```
|
||||
/var/www/html/redcap/redcap_v15.8.0/Classes/DataEntry.php
|
||||
/var/www/html/redcap/redcap_v15.8.0/ProjectSetup/index.php
|
||||
/var/www/html/redcap/redcap_v15.8.0/ControlCenter/modules_settings.php
|
||||
```
|
||||
|
||||
**关键代码:**
|
||||
**蜈ウ髞ョ莉」遐<EFBFBD>シ?*
|
||||
```php
|
||||
// DataEntry.php 譬ク蠢<EFBDB8>ョ樒鴫
|
||||
global $data_entry_trigger_url, $data_entry_trigger_enabled;
|
||||
@@ -74,88 +74,88 @@ if (!$data_entry_trigger_enabled || $data_entry_trigger_url == '') {
|
||||
$full_url = $pre_url . $data_entry_trigger_url;
|
||||
```
|
||||
|
||||
**验证结论:** ✅ DET是REDCap原生功能,真实存在且广泛使用
|
||||
**鬪瑚ッ∫サ楢ョコ<EFBFBD>?* 笨?DET譏ッREDCap蜴溽函蜉溯<EFBFBD><EFBFBD>檎悄螳槫ュ伜惠荳泌ケソ豕帑スソ逕ィ
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 完整架构设计
|
||||
## <EFBFBD>女<EFBFBD>?螳梧紛譫カ譫<EFBDB6>ョセ隶。
|
||||
|
||||
### 架构图
|
||||
### 譫カ譫<EFBFBD><EFBFBD>?
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 1. CRC 在 REDCap 中保存记录 │
|
||||
│ - 录入患者数据 │
|
||||
│ - 点击"Save"按钮 │
|
||||
└──────────────────┬──────────────────────────────────┘
|
||||
↓ 立即触发(REDCap DET,0秒延迟)
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 2. REDCap Data Entry Trigger (DET) │
|
||||
│ POST → https://iit.xunzhengyixue.com/ │
|
||||
│ api/v1/iit/webhooks/redcap │
|
||||
│ Payload: │
|
||||
│ - project_id: 16 │
|
||||
│ - record: 101 │
|
||||
│ - instrument: demographics │
|
||||
│ - redcap_event_name: baseline_arm_1 │
|
||||
└──────────────────┬──────────────────────────────────┘
|
||||
↓ 1秒内
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 3. Node.js Webhook接收器 │
|
||||
│ - 验证请求来源(可选) │
|
||||
│ - 立即返回200 OK(<100ms,不阻塞REDCap) │
|
||||
│ - 异步调用质控流程(setImmediate) │
|
||||
└──────────────────┬──────────────────────────────────┘
|
||||
↓ 异步处理
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 4. REDCap REST API - exportRecords │
|
||||
│ - 使用API Token认证 │
|
||||
│ - 拉取指定record_id的完整数据 │
|
||||
│ - 包含所有字段值、元数据 │
|
||||
└──────────────────┬──────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 5. 推送到质控队列 │
|
||||
│ - jobQueue.send('iit:quality-check', record) │
|
||||
│ - 异步处理,不影响实时响应 │
|
||||
└──────────────────┬──────────────────────────────────┘
|
||||
↓ 由QualityCheckAgent处理(Day 6)
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 6. AI质控分析 │
|
||||
│ - 规则引擎验证 │
|
||||
│ - AI推理检测异常 │
|
||||
│ - 生成质控报告 │
|
||||
└──────────────────┬──────────────────────────────────┘
|
||||
↓ 3-5秒内
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 7. 多渠道反馈 │
|
||||
│ A. 企业微信推送给CRC(实时通知) │
|
||||
│ B. REDCap API importQueries(写回质疑) │
|
||||
│ C. IIT Manager前端显示(待办事项) │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
笏娯楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
笏? 1. CRC 蝨?REDCap 荳ュ菫晏ュ倩ョー蠖? 笏?
|
||||
笏? - 蠖募<EFBFBD>謔」閠<EFBFBD>焚謐? 笏?
|
||||
笏? - 轤ケ蜃サ"Save"謖蛾聴 笏?
|
||||
笏披楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏ャ笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
竊?遶句叉隗ヲ蜿托シ<E68998>EDCap DET<45>?遘貞サカ霑滂シ<E6BB82>
|
||||
笏娯楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
笏? 2. REDCap Data Entry Trigger (DET) 笏?
|
||||
笏? POST 竊?https://iit.xunzhengyixue.com/ 笏?
|
||||
笏? api/v1/iit/webhooks/redcap 笏?
|
||||
笏? Payload: 笏?
|
||||
笏? - project_id: 16 笏?
|
||||
笏? - record: 101 笏?
|
||||
笏? - instrument: demographics 笏?
|
||||
笏? - redcap_event_name: baseline_arm_1 笏?
|
||||
笏披楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏ャ笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
竊?1遘貞<E98198>
|
||||
笏娯楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
笏? 3. Node.js Webhook謗・謾カ蝎? 笏?
|
||||
笏? - 鬪瑚ッ∬ッキ豎よ擂貅撰シ亥庄騾会シ<EFBFBD> 笏?
|
||||
笏? - 遶句叉霑泌屓200 OK<EFBFBD>?100ms<EFBFBD>御ク埼仆蝪朿EDCap<EFBFBD>? 笏?
|
||||
笏? - 蠑よュ・隹<EFBFBD>畑雍ィ謗ァ豬∫ィ具シ<EFBFBD>etImmediate<EFBFBD>? 笏?
|
||||
笏披楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏ャ笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
竊?蠑よュ・螟<EFBDA5>炊
|
||||
笏娯楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
笏? 4. REDCap REST API - exportRecords 笏?
|
||||
笏? - 菴ソ逕ィAPI Token隶、隸<EFBFBD> 笏?
|
||||
笏? - 諡牙叙謖<EFBFBD>ョ嗷ecord_id逧<EFBFBD>ョ梧紛謨ー謐? 笏?
|
||||
笏? - 蛹<EFBFBD>性謇譛牙ュ玲ョオ蛟シ縲∝<EFBFBD>謨ー謐ョ 笏?
|
||||
笏披楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏ャ笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
竊?
|
||||
笏娯楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
笏? 5. 謗ィ騾∝芦雍ィ謗ァ髦溷<EFBFBD> 笏?
|
||||
笏? - jobQueue.send('iit:quality-check', record) 笏?
|
||||
笏? - 蠑よュ・螟<EFBFBD>炊<EFBFBD>御ク榊スア蜩榊ョ樊慮蜩榊コ<EFBFBD> 笏?
|
||||
笏披楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏ャ笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
竊?逕アQualityCheckAgent螟<EFBFBD>炊<EFBFBD><EFBFBD>ay 6<EFBFBD>?
|
||||
笏娯楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
笏? 6. AI雍ィ謗ァ蛻<EFBFBD>梵 笏?
|
||||
笏? - 隗<EFBFBD><EFBFBD>蠑墓梼鬪瑚ッ<EFBFBD> 笏?
|
||||
笏? - AI謗ィ逅<EFBFBD>」豬句シょク? 笏?
|
||||
笏? - 逕滓<EFBFBD>雍ィ謗ァ謚・蜻<EFBFBD> 笏?
|
||||
笏披楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏ャ笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
竊?3-5遘貞<EFBFBD>
|
||||
笏娯楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
笏? 7. 螟壽ク<EFBFBD>驕灘渚鬥? 笏?
|
||||
笏? A. 莨∽ク壼セョ菫。謗ィ騾∫サ僂RC<EFBFBD>亥ョ樊慮騾夂衍<EFBFBD>? 笏?
|
||||
笏? B. REDCap API importQueries<EFBFBD>亥<EFBFBD>蝗櫁エィ逍托シ<EFBFBD> 笏?
|
||||
笏? C. IIT Manager蜑咲ォッ譏セ遉コ<EFBFBD>亥セ<EFBFBD>萱莠矩。ケ<EFBFBD><EFBFBD> 笏?
|
||||
笏披楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 补充:定时轮询机制(每30分钟) │
|
||||
│ - 防止DET遗漏数据 │
|
||||
│ - 使用dateRangeBegin增量拉取 │
|
||||
│ - 推送到相同的质控队列 │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
笏娯楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
笏? 陦・蜈<EFBDA5>シ壼ョ壽慮霓ョ隸「譛コ蛻カ<E89BBB>域ッ?0蛻<30>帖<EFBFBD>? 笏?
|
||||
笏? - 髦イ豁「DET驕玲シ乗焚謐ョ 笏?
|
||||
笏? - 菴ソ逕ィdateRangeBegin蠅樣㍼諡牙叙 笏?
|
||||
笏? - 謗ィ騾∝芦逶ク蜷檎噪雍ィ謗ァ髦溷<EFBFBD>? 笏?
|
||||
笏披楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
```
|
||||
|
||||
### 实时性对比
|
||||
### 螳樊慮諤ァ蟇ケ豈?
|
||||
|
||||
| 譁ケ譯<EFBDB9> | 蟒カ霑滓慮髣エ | 謌台サャ逧<EFBDAC>画叫 |
|
||||
|------|---------|-----------|
|
||||
| **纯轮询(每5分钟)** | 最高5分钟 | ❌ 不满足实时性要求 |
|
||||
| **纯轮询(每1分钟)** | 最高1分钟 | ⚠️ 资源浪费、延迟仍高 |
|
||||
| **DET + API** | 0秒触发 + 3-5秒处理 | ✅ **最优方案** |
|
||||
| **DET + 轮询补充** | 实时 + 可靠 | ✅ **最终架构** |
|
||||
| **郤ッ霓ョ隸「<EFBFBD>域ッ?蛻<>帖<EFBFBD>?* | 譛鬮?蛻<>帖 | 笶?荳肴サ。雜ウ螳樊慮諤ァ隕∵ア?|
|
||||
| **郤ッ霓ョ隸「<EFBFBD>域ッ?蛻<>帖<EFBFBD>?* | 譛鬮?蛻<>帖 | 笞<><E7AC9E><EFBFBD> 襍<>コ先オェ雍ケ縲∝サカ霑滉サ埼ォ?|
|
||||
| **DET + API** | 0遘定ァヲ蜿?+ 3-5遘貞、<E8B29E><EFBDA4>?| 笨?**譛莨俶婿譯?* |
|
||||
| **DET + 霓ョ隸「陦・蜈<EFBFBD>** | 螳樊慮 + 蜿ッ髱<EFBDAF> | 笨?**譛扈域楔譫?* |
|
||||
|
||||
**结论:** CRC点击"保存" → 5秒内收到企业微信通知 ✅
|
||||
**扈楢ョコ<EFBFBD>?* CRC轤ケ蜃サ"菫晏ュ<E6998F>" 竊?5遘貞<E98198>謾カ蛻ー莨∽ク壼セョ菫。騾夂衍 笨?
|
||||
|
||||
---
|
||||
|
||||
## 📦 技术实现详解
|
||||
## <EFBFBD>逃 謚譛ッ螳樒鴫隸ヲ隗?
|
||||
|
||||
### 1. Data Entry Trigger (DET) 驟咲スョ
|
||||
|
||||
@@ -163,9 +163,9 @@ $full_url = $pre_url . $data_entry_trigger_url;
|
||||
|
||||
```
|
||||
1. 逋サ蠖紐EDCap<61>喇ttp://localhost:8080/
|
||||
2. 使用管理员账户(Admin / Admin123!)
|
||||
3. 进入:Control Center → "Additional Customizations"
|
||||
4. 找到:"Data Entry Trigger" 选项
|
||||
2. 菴ソ逕ィ邂。逅<EFBFBD>遭雍ヲ謌キ<EFBFBD><EFBFBD>dmin / Admin123!<EFBFBD>?
|
||||
3. 霑帛<EFBFBD><EFBFBD>咾ontrol Center 竊?"Additional Customizations"
|
||||
4. 謇セ蛻ー<EFBFBD>?Data Entry Trigger" 騾蛾。ケ
|
||||
5. 隶セ鄂ョ荳コ<E88DB3><EFBDBA>"Enabled"
|
||||
6. 菫晏ュ倬<EFBDAD>鄂ョ
|
||||
```
|
||||
@@ -176,10 +176,10 @@ $full_url = $pre_url . $data_entry_trigger_url;
|
||||
|
||||
```
|
||||
1. 霑帛<E99C91>豬玖ッ暮。ケ逶ョ<E980B6>嗾est0102 (PID 16)
|
||||
2. 左侧菜单 → Project Setup
|
||||
3. 找到:"Additional Customizations"
|
||||
4. 展开:"Data Entry Trigger URL"
|
||||
5. 填入Webhook URL:
|
||||
2. 蟾ヲ萓ァ闖懷黒 竊?Project Setup
|
||||
3. 謇セ蛻ー<EFBFBD>?Additional Customizations"
|
||||
4. 螻募シ<EFBFBD>?Data Entry Trigger URL"
|
||||
5. 蝪ォ蜈・Webhook URL<EFBFBD>?
|
||||
- 蠑蜿醍識蠅<E8AD98>シ喇ttp://localhost:3001/api/v1/iit/webhooks/redcap
|
||||
- 豬玖ッ慕識蠅<E8AD98>シ喇ttps://backend-dev.xunzhengyixue.com/api/v1/iit/webhooks/redcap
|
||||
- 逕滉コァ邇ッ蠅<EFBDAF>シ喇ttps://iit.xunzhengyixue.com/api/v1/iit/webhooks/redcap
|
||||
@@ -190,22 +190,22 @@ $full_url = $pre_url . $data_entry_trigger_url;
|
||||
|
||||
#### 豁・鬪、3<EFBDA4>夐ェ瑚ッ.ET驟咲スョ
|
||||
|
||||
**使用RequestBin/ngrok验证:**
|
||||
**菴ソ逕ィRequestBin/ngrok鬪瑚ッ<EFBFBD>シ?*
|
||||
|
||||
```bash
|
||||
# 使用ngrok创建临时公网URL(开发测试用)
|
||||
# 菴ソ逕ィngrok蛻帛サコ荳エ譌カ蜈ャ鄂繕RL<EFBFBD>亥シ蜿第オ玖ッ慕畑<EFBFBD>?
|
||||
ngrok http 3001
|
||||
|
||||
# 蟆<>grok URL驟咲スョ蛻ーREDCap DET
|
||||
# 萓句ヲゑシ喇ttps://1234-abc-def.ngrok.io/api/v1/iit/webhooks/redcap
|
||||
|
||||
# 在REDCap中保存一条记录
|
||||
# 蝨ィREDCap荳ュ菫晏ュ倅ク譚。隶ー蠖?
|
||||
# 譽譟・ngrok謗ァ蛻カ蜿ー譏ッ蜷ヲ謾カ蛻ーPOST隸キ豎<EFBDB7>
|
||||
```
|
||||
|
||||
#### DET逧ПOST Payload譬シ蠑<EFBDBC>
|
||||
|
||||
**REDCap发送的请求:**
|
||||
**REDCap蜿鷹∫噪隸キ豎ゑシ?*
|
||||
|
||||
```http
|
||||
POST /api/v1/iit/webhooks/redcap HTTP/1.1
|
||||
@@ -221,7 +221,7 @@ project_id=16
|
||||
&redcap_url=http://localhost:8080/
|
||||
```
|
||||
|
||||
**字段说明:**
|
||||
**蟄玲ョオ隸エ譏趣シ?*
|
||||
|
||||
| 蟄玲ョオ | 邀サ蝙<EFBDBB> | 隸エ譏<EFBDB4> | 遉コ萓<EFBDBA> |
|
||||
|------|-----|------|------|
|
||||
@@ -229,7 +229,7 @@ project_id=16
|
||||
| `record` | string | 隶ー蠖肘D | "101" |
|
||||
| `instrument` | string | 陦ィ蜊募錐遘ー | "demographics" |
|
||||
| `redcap_event_name` | string | 莠倶サカ蜷咲ァー<EFBDA7>育コオ蜷醍<E89CB7>皮ゥカ<EFBDA9><EFBDB6> | "baseline_arm_1" |
|
||||
| `[instrument]_complete` | string | 表单完成状态(0/1/2) | "2" |
|
||||
| `[instrument]_complete` | string | 陦ィ蜊募ョ梧<EFBFBD>迥カ諤<EFBFBD>シ<EFBFBD>0/1/2<EFBFBD>?| "2" |
|
||||
| `redcap_url` | string | REDCap螳樔セ偽RL | "http://localhost:8080/" |
|
||||
|
||||
---
|
||||
@@ -244,23 +244,23 @@ http://localhost:8080/api/
|
||||
|
||||
#### API隶、隸<EFBDA4>シ啜oken
|
||||
|
||||
**生成步骤:**
|
||||
**逕滓<EFBFBD>豁・鬪、<EFBFBD>?*
|
||||
```
|
||||
1. 逋サ蠖紐EDCap
|
||||
2. 霑帛<E99C91>鬘ケ逶ョ<E980B6>嗾est0102 (PID 16)
|
||||
3. 左侧菜单 → "API"
|
||||
3. 蟾ヲ萓ァ闖懷黒 竊?"API"
|
||||
4. 轤ケ蜃サ "Generate API Token"
|
||||
5. 复制Token(32位字符串)
|
||||
5. 螟榊宛Token<EFBFBD>?2菴榊ュ礼ャヲ荳イ<E88DB3>?
|
||||
6. 菫晏ュ伜芦邇ッ蠅<EFBDAF>序驥擾シ<E693BE>
|
||||
REDCAP_API_TOKEN_TEST=YOUR_TOKEN_HERE
|
||||
```
|
||||
|
||||
**Token存储:**
|
||||
- ✅ 环境变量(推荐)
|
||||
- ✅ 数据库加密字段(IitProject.redcapApiToken)
|
||||
- ❌ 不要提交到Git
|
||||
**Token蟄伜お<EFBFBD>?*
|
||||
- 笨?邇ッ蠅<EFBDAF>序驥擾シ域耳闕撰シ<E692B0>
|
||||
- 笨?謨ー謐ョ蠎灘刈蟇<E58888>ュ玲ョオ<EFBDAE><EFBDB5>itProject.redcapApiToken<EFBFBD>?
|
||||
- 笶?荳崎ヲ∵署莠、蛻ーGit
|
||||
|
||||
#### API方法1:导出记录 (exportRecords)
|
||||
#### API譁ケ豕<EFBFBD>1<EFBFBD>壼ッシ蜃コ隶ー蠖?(exportRecords)
|
||||
|
||||
**逕ィ騾費シ<E8B2BB>** 諡牙叙謨ー謐ョ<E8AC90>域髪謖∝「樣㍼蜷梧ュ・<EFBDAD><EFBDA5>
|
||||
|
||||
@@ -277,28 +277,28 @@ curl -X POST http://localhost:8080/api/ \
|
||||
-F "dateRangeBegin=2026-01-01 00:00:00"
|
||||
```
|
||||
|
||||
**参数说明:**
|
||||
**蜿よ焚隸エ譏趣シ?*
|
||||
|
||||
| 蜿よ焚 | 蠢<>。ォ | 隸エ譏<EFBDB4> | 遉コ萓<EFBDBA> |
|
||||
|------|-----|------|------|
|
||||
| `token` | ✅ | API Token | "ABC123..." |
|
||||
| `content` | ✅ | 固定值 | "record" |
|
||||
| `format` | ✅ | 返回格式 | "json" |
|
||||
| `type` | ✅ | 数据结构 | "flat" |
|
||||
| `records` | ❌ | 指定记录ID | ["101", "102"] |
|
||||
| `fields` | ❌ | 指定字段 | ["age", "gender"] |
|
||||
| `dateRangeBegin` | ❌ | 时间过滤(增量同步关键) | "2026-01-01 00:00:00" |
|
||||
| `dateRangeEnd` | ❌ | 结束时间 | "2026-01-31 23:59:59" |
|
||||
| `token` | 笨?| API Token | "ABC123..." |
|
||||
| `content` | 笨?| 蝗コ螳壼?| "record" |
|
||||
| `format` | 笨?| 霑泌屓譬シ蠑<EFBDBC> | "json" |
|
||||
| `type` | 笨?| 謨ー謐ョ扈捺桷 | "flat" |
|
||||
| `records` | 笶?| 謖<>ョ夊ョー蠖肘D | ["101", "102"] |
|
||||
| `fields` | 笶?| 謖<>ョ壼ュ玲ョオ | ["age", "gender"] |
|
||||
| `dateRangeBegin` | 笶?| 譌カ髣エ霑<EFBDB4>サ、<EFBDBB>亥「樣㍼蜷梧ュ・蜈ウ髞ョ<E9AB9E><EFBDAE> | "2026-01-01 00:00:00" |
|
||||
| `dateRangeEnd` | 笶?| 扈捺據譌カ髣エ | "2026-01-31 23:59:59" |
|
||||
|
||||
**响应示例:**
|
||||
**蜩榊コ皮、コ萓具シ?*
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"record_id": "101",
|
||||
"redcap_event_name": "baseline_arm_1",
|
||||
"first_name": "张",
|
||||
"last_name": "三",
|
||||
"first_name": "蠑?,
|
||||
"last_name": "荳?,
|
||||
"age": "30",
|
||||
"gender": "1",
|
||||
"demographics_complete": "2"
|
||||
@@ -308,9 +308,9 @@ curl -X POST http://localhost:8080/api/ \
|
||||
|
||||
#### API譁ケ豕<EFBDB9>2<EFBFBD>壼ッシ蜃コ蜈<EFBDBA>焚謐ョ (exportMetadata)
|
||||
|
||||
**用途:** 获取字段定义、表单结构
|
||||
**逕ィ騾費シ<EFBFBD>** 闔キ蜿門ュ玲ョオ螳壻ケ峨∬。ィ蜊慕サ捺<EFBDBB>?
|
||||
|
||||
**请求示例:**
|
||||
**隸キ豎ら、コ萓具シ?*
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/ \
|
||||
@@ -319,7 +319,7 @@ curl -X POST http://localhost:8080/api/ \
|
||||
-F "format=json"
|
||||
```
|
||||
|
||||
**响应示例:**
|
||||
**蜩榊コ皮、コ萓具シ?*
|
||||
|
||||
```json
|
||||
[
|
||||
@@ -346,11 +346,11 @@ curl -X POST http://localhost:8080/api/ \
|
||||
]
|
||||
```
|
||||
|
||||
#### API方法3:导入记录 (importRecords) - Phase 2
|
||||
#### API譁ケ豕<EFBFBD>3<EFBFBD>壼ッシ蜈・隶ー蠖?(importRecords) - Phase 2
|
||||
|
||||
**用途:** 回写数据(如质控意见、AI建议)
|
||||
**逕ィ騾費シ<EFBFBD>** 蝗槫<E89D97>謨ー謐ョ<E8AC90>亥ヲりエィ謗ァ諢剰ァ√、I蟒コ隶ョ<E99AB6>?
|
||||
|
||||
**请求示例:**
|
||||
**隸キ豎ら、コ萓具シ?*
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/ \
|
||||
@@ -368,7 +368,7 @@ curl -X POST http://localhost:8080/api/ \
|
||||
|
||||
#### 3.1 RedcapAdapter<65><72>PI騾る<E9A8BE>蝎ィ<E89D8E><EFBDA8>
|
||||
|
||||
**文件:** `backend/src/modules/iit-manager/adapters/RedcapAdapter.ts`
|
||||
**譁<EFBFBD>サカ<EFBFBD>?* `backend/src/modules/iit-manager/adapters/RedcapAdapter.ts`
|
||||
|
||||
```typescript
|
||||
import axios from 'axios';
|
||||
@@ -452,7 +452,7 @@ export class RedcapAdapter {
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出元数据(字段定义)
|
||||
* 蟇シ蜃コ蜈<EFBFBD>焚謐ョ<EFBFBD>亥ュ玲ョオ螳壻ケ会シ?
|
||||
*/
|
||||
async exportMetadata(): Promise<any[]> {
|
||||
const formData = new FormData();
|
||||
@@ -523,7 +523,7 @@ export class RedcapAdapter {
|
||||
|
||||
#### 3.2 WebhookController<65><72>ebhook謗・謾カ蝎ィ<E89D8E><EFBDA8>
|
||||
|
||||
**文件:** `backend/src/modules/iit-manager/controllers/webhookController.ts`
|
||||
**譁<EFBFBD>サカ<EFBFBD>?* `backend/src/modules/iit-manager/controllers/webhookController.ts`
|
||||
|
||||
```typescript
|
||||
import { FastifyRequest, FastifyReply } from 'fastify';
|
||||
@@ -536,7 +536,7 @@ export class WebhookController {
|
||||
/**
|
||||
* 謗・謾カREDCap Data Entry Trigger Webhook
|
||||
*
|
||||
* 性能要求:响应时间 < 100ms(不阻塞REDCap)
|
||||
* 諤ァ閭ス隕∵アゑシ壼桃蠎疲慮髣?< 100ms<6D>井ク埼仆蝪朿EDCap<EFBFBD>?
|
||||
*/
|
||||
async handleRedcapWebhook(
|
||||
request: FastifyRequest,
|
||||
@@ -569,7 +569,7 @@ export class WebhookController {
|
||||
event: redcap_event_name
|
||||
});
|
||||
|
||||
// 立即返回200(不阻塞REDCap)
|
||||
// 遶句叉霑泌屓200<EFBFBD>井ク埼仆蝪朿EDCap<EFBFBD>?
|
||||
const responseTime = Date.now() - startTime;
|
||||
reply.code(200).send({
|
||||
status: 'received',
|
||||
@@ -577,7 +577,7 @@ export class WebhookController {
|
||||
response_time_ms: responseTime
|
||||
});
|
||||
|
||||
// 异步处理(不阻塞HTTP响应)
|
||||
// 蠑よュ・螟<EFBFBD>炊<EFBFBD>井ク埼仆蝪曰TTP蜩榊コ費シ?
|
||||
setImmediate(async () => {
|
||||
try {
|
||||
await this.processWebhook({
|
||||
@@ -589,7 +589,7 @@ export class WebhookController {
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Webhook processing failed:', error);
|
||||
// 不抛出错误,因为已经返回200了
|
||||
// 荳肴鴨蜃コ髞呵ッッ<EFBFBD>悟屏荳コ蟾イ扈剰ソ泌屓200莠?
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -616,7 +616,7 @@ export class WebhookController {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 幂等性检查(防止重复处理)
|
||||
// 2. 蟷らュ画ァ譽譟・<EFBFBD>磯亟豁「驥榊、榊、<EFBFBD>炊<EFBFBD>?
|
||||
const isDuplicate = await this.checkDuplicate(
|
||||
project.id,
|
||||
record,
|
||||
@@ -635,7 +635,7 @@ export class WebhookController {
|
||||
);
|
||||
|
||||
const records = await adapter.exportRecords({
|
||||
records: [record] // 只拉取这一条记录
|
||||
records: [record] // 蜿ェ諡牙叙霑吩ク譚。隶ー蠖?
|
||||
});
|
||||
|
||||
if (records.length === 0) {
|
||||
@@ -699,7 +699,7 @@ export class WebhookController {
|
||||
|
||||
#### 3.3 SyncManager<65>郁スョ隸「陦・蜈<EFBDA5>シ<EFBFBD>
|
||||
|
||||
**文件:** `backend/src/modules/iit-manager/services/SyncManager.ts`
|
||||
**譁<EFBFBD>サカ<EFBFBD>?* `backend/src/modules/iit-manager/services/SyncManager.ts`
|
||||
|
||||
```typescript
|
||||
import { prisma } from '@/config/database';
|
||||
@@ -709,10 +709,10 @@ import { RedcapAdapter } from '../adapters/RedcapAdapter';
|
||||
|
||||
export class SyncManager {
|
||||
/**
|
||||
* 初始化同步(注册定时任务)
|
||||
* 蛻晏ァ句喧蜷梧ュ・<EFBFBD>域ウィ蜀悟ョ壽慮莉サ蜉。<EFBFBD>?
|
||||
*/
|
||||
async initializeSync(projectId: string, interval: string = '*/30 * * * *'): Promise<void> {
|
||||
// 注册定时任务(每30分钟)
|
||||
// 豕ィ蜀悟ョ壽慮莉サ蜉。<EFBFBD>域ッ<EFBFBD>30蛻<EFBFBD>帖<EFBFBD>?
|
||||
await jobQueue.schedule(
|
||||
'iit:redcap:poll',
|
||||
interval,
|
||||
@@ -783,7 +783,7 @@ export class SyncManager {
|
||||
* 蛛懈ュ「蜷梧ュ・<EFBDAD>亥叙豸亥ョ壽慮莉サ蜉。<E89C89><EFBDA1>
|
||||
*/
|
||||
async stopSync(projectId: string): Promise<void> {
|
||||
// pg-boss不支持直接取消schedule,需要在Worker中检查项目状态
|
||||
// pg-boss荳肴髪謖∫峩謗・蜿匁カ<EFBFBD>chedule<EFBFBD>碁怙隕∝惠Worker荳ュ譽譟・鬘ケ逶ョ迥カ諤?
|
||||
logger.info(`Sync stopped for project ${projectId}`);
|
||||
}
|
||||
}
|
||||
@@ -791,7 +791,7 @@ export class SyncManager {
|
||||
|
||||
#### 3.4 霍ッ逕ア驟咲スョ
|
||||
|
||||
**文件:** `backend/src/modules/iit-manager/routes/index.ts`
|
||||
**譁<EFBFBD>サカ<EFBFBD>?* `backend/src/modules/iit-manager/routes/index.ts`
|
||||
|
||||
```typescript
|
||||
import { FastifyInstance } from 'fastify';
|
||||
@@ -802,12 +802,12 @@ export async function iitManagerRoutes(fastify: FastifyInstance) {
|
||||
const webhookController = new WebhookController();
|
||||
const syncManager = new SyncManager();
|
||||
|
||||
// Webhook端点(接收REDCap DET)
|
||||
// Webhook遶ッ轤ケ<EFBFBD>域磁謾カREDCap DET<EFBFBD>?
|
||||
fastify.post('/webhooks/redcap', async (request, reply) => {
|
||||
return webhookController.handleRedcapWebhook(request, reply);
|
||||
});
|
||||
|
||||
// 手动触发同步(测试用)
|
||||
// 謇句勘隗ヲ蜿大酔豁・<EFBFBD>域オ玖ッ慕畑<EFBFBD>?
|
||||
fastify.post('/projects/:id/sync', async (request, reply) => {
|
||||
const { id } = request.params as { id: string };
|
||||
await syncManager.handlePoll(id);
|
||||
@@ -818,7 +818,7 @@ export async function iitManagerRoutes(fastify: FastifyInstance) {
|
||||
|
||||
#### 3.5 Worker豕ィ蜀<EFBDA8>
|
||||
|
||||
**文件:** `backend/src/modules/iit-manager/index.ts`
|
||||
**譁<EFBFBD>サカ<EFBFBD>?* `backend/src/modules/iit-manager/index.ts`
|
||||
|
||||
```typescript
|
||||
import { jobQueue } from '@/common/jobs';
|
||||
@@ -844,19 +844,19 @@ export async function initializeIITManager() {
|
||||
|
||||
### 豬玖ッ<E78E96>1<EFBFBD>夐ェ瑚ッ.ET驟咲スョ
|
||||
|
||||
**步骤:**
|
||||
**豁・鬪、<EFBFBD>?*
|
||||
1. 驟咲スョngrok<6F>啻ngrok http 3001`
|
||||
2. 蟆<>grok URL驟咲スョ蛻ーREDCap DET
|
||||
3. 在REDCap中保存一条记录
|
||||
3. 蝨ィREDCap荳ュ菫晏ュ倅ク譚。隶ー蠖?
|
||||
4. 譽譟・ngrok謗ァ蛻カ蜿ー譏ッ蜷ヲ謾カ蛻ーPOST隸キ豎<EFBDB7>
|
||||
|
||||
**预期结果:**
|
||||
- ✅ ngrok收到POST请求
|
||||
- ✅ Payload包含project_id、record等字段
|
||||
**鬚<EFBFBD>悄扈捺棡<EFBFBD>?*
|
||||
- 笨?ngrok謾カ蛻ーPOST隸キ豎<EFBFBD>
|
||||
- 笨?Payload蛹<EFBFBD>性project_id縲〉ecord遲牙ュ玲ョ?
|
||||
|
||||
### 豬玖ッ<E78E96>2<EFBFBD>夐ェ瑚ッ、PI Token
|
||||
|
||||
**测试脚本:** `test-redcap-api.ts`
|
||||
**豬玖ッ戊<EFBFBD>譛ャ<EFBFBD>?* `test-redcap-api.ts`
|
||||
|
||||
```typescript
|
||||
import { RedcapAdapter } from './adapters/RedcapAdapter';
|
||||
@@ -871,11 +871,11 @@ async function testRedcapAPI() {
|
||||
const records = await adapter.exportRecords();
|
||||
console.log('Records:', records);
|
||||
|
||||
// 测试导出元数据
|
||||
// 豬玖ッ募ッシ蜃コ蜈<EFBFBD>焚謐?
|
||||
const metadata = await adapter.exportMetadata();
|
||||
console.log('Metadata fields:', metadata.length);
|
||||
|
||||
console.log('✅ REDCap API test passed!');
|
||||
console.log('笨?REDCap API test passed!');
|
||||
}
|
||||
|
||||
testRedcapAPI();
|
||||
@@ -883,7 +883,7 @@ testRedcapAPI();
|
||||
|
||||
### 豬玖ッ<E78E96>3<EFBFBD>夂ォッ蛻ー遶ッ髮<EFBDAF><E9ABAE>豬玖ッ<E78E96>
|
||||
|
||||
**测试脚本:** `test-redcap-integration.ts`
|
||||
**豬玖ッ戊<EFBFBD>譛ャ<EFBFBD>?* `test-redcap-integration.ts`
|
||||
|
||||
```typescript
|
||||
async function testIntegration() {
|
||||
@@ -898,11 +898,11 @@ async function testIntegration() {
|
||||
}
|
||||
});
|
||||
|
||||
// 2. 初始化同步
|
||||
// 2. 蛻晏ァ句喧蜷梧ュ?
|
||||
const syncManager = new SyncManager();
|
||||
await syncManager.initializeSync(project.id);
|
||||
|
||||
// 3. 手动触发一次轮询
|
||||
// 3. 謇句勘隗ヲ蜿台ク谺。霓ョ隸?
|
||||
await syncManager.handlePoll(project.id);
|
||||
|
||||
// 4. 讓。諡欷ebhook
|
||||
@@ -918,7 +918,7 @@ async function testIntegration() {
|
||||
{} as any
|
||||
);
|
||||
|
||||
console.log('✅ Integration test passed!');
|
||||
console.log('笨?Integration test passed!');
|
||||
}
|
||||
```
|
||||
|
||||
@@ -926,18 +926,18 @@ async function testIntegration() {
|
||||
|
||||
## <20>搭 Day 2螳樊命貂<E591BD>黒
|
||||
|
||||
### 阶段1:环境准备(30分钟)
|
||||
### 髦カ谿オ1<EFBFBD>夂識蠅<EFBFBD>㊥螟<EFBFBD>シ<EFBFBD>30蛻<EFBFBD>帖<EFBFBD>?
|
||||
|
||||
- [ ] 蝨ィREDCap Control Center蜷ッ逕ィDET蜉溯<E89C89>
|
||||
- [ ] 蝨ィtest0102鬘ケ逶ョ逕滓<E98095>API Token
|
||||
- [ ] 配置环境变量:
|
||||
- [ ] 驟咲スョ邇ッ蠅<EFBFBD>序驥擾シ?
|
||||
```env
|
||||
REDCAP_BASE_URL=http://localhost:8080
|
||||
REDCAP_API_TOKEN_TEST=YOUR_TOKEN_HERE
|
||||
```
|
||||
- [ ] 菴ソ逕ィcurl豬玖ッ柊PI譏ッ蜷ヲ蜿ッ逕ィ
|
||||
|
||||
### 阶段2:开发RedcapAdapter(1.5小时)
|
||||
### 髦カ谿オ2<EFBFBD>壼シ蜿然edcapAdapter<EFBFBD>?.5蟆乗慮<EFBFBD>?
|
||||
|
||||
- [ ] 蛻帛サコ譁<EFBDBA>サカ<EFBDBB>啻adapters/RedcapAdapter.ts`
|
||||
- [ ] 螳樒鴫 `exportRecords()` 譁ケ豕<EFBDB9>
|
||||
@@ -945,15 +945,15 @@ async function testIntegration() {
|
||||
- [ ] 螳樒鴫 `formatRedcapDate()` 蟾・蜈キ譁ケ豕<EFBDB9>
|
||||
- [ ] 郛門<E9839B>蜊募<E89C8A>豬玖ッ包シ啻RedcapAdapter.test.ts`
|
||||
|
||||
### 阶段3:开发WebhookController(2小时)
|
||||
### 髦カ谿オ3<EFBFBD>壼シ蜿糎ebhookController<EFBFBD>?蟆乗慮<E4B997>?
|
||||
|
||||
- [ ] 蛻帛サコ譁<EFBDBA>サカ<EFBDBB>啻controllers/webhookController.ts`
|
||||
- [ ] 螳樒鴫 `handleRedcapWebhook()` 譁ケ豕<EFBDB9>
|
||||
- [ ] 螳樒鴫 `processWebhook()` 遘∵怏譁ケ豕<EFBDB9>
|
||||
- [ ] 实现 `checkDuplicate()` 幂等性检查
|
||||
- [ ] 螳樒鴫 `checkDuplicate()` 蟷らュ画ァ譽譟?
|
||||
- [ ] 驟咲スョ霍ッ逕ア<E98095>啻POST /api/v1/iit/webhooks/redcap`
|
||||
|
||||
### 阶段4:开发SyncManager(1.5小时)
|
||||
### 髦カ谿オ4<EFBFBD>壼シ蜿全yncManager<EFBFBD>?.5蟆乗慮<EFBFBD>?
|
||||
|
||||
- [ ] 蛻帛サコ譁<EFBDBA>サカ<EFBDBB>啻services/SyncManager.ts`
|
||||
- [ ] 螳樒鴫 `initializeSync()` 譁ケ豕<EFBDB9>
|
||||
@@ -961,19 +961,19 @@ async function testIntegration() {
|
||||
- [ ] 螳樒鴫 `stopSync()` 譁ケ豕<EFBDB9>
|
||||
- [ ] 豕ィ蜀係orker<65>啻iit:redcap:poll`
|
||||
|
||||
### 阶段5:集成测试(1小时)
|
||||
### 髦カ谿オ5<EFBFBD>夐寔謌先オ玖ッ包シ<EFBFBD>1蟆乗慮<EFBFBD>?
|
||||
|
||||
- [ ] 驟咲スョngrok/RequestBin豬玖ッ疋ET
|
||||
- [ ] 霑占。<E58DA0> `test-redcap-api.ts`
|
||||
- [ ] 霑占。<E58DA0> `test-redcap-integration.ts`
|
||||
- [ ] 验证端到端流程
|
||||
- [ ] 鬪瑚ッ∫ォッ蛻ー遶ッ豬∫ィ?
|
||||
- [ ] 隶ー蠖墓オ玖ッ慕サ捺棡
|
||||
|
||||
### 阶段6:文档更新(30分钟)
|
||||
### 髦カ谿オ6<EFBFBD>壽枚譯」譖エ譁ー<EFBFBD><EFBFBD>30蛻<EFBFBD>帖<EFBFBD>?
|
||||
|
||||
- [ ] 更新MVP开发任务清单(Day 2完成)
|
||||
- [ ] 记录API Token和配置信息
|
||||
- [ ] 更新架构图
|
||||
- [ ] 譖エ譁ーMVP蠑蜿台ササ蜉。貂<EFBDA1>黒<EFBFBD><E9BB92>ay 2螳梧<E89EB3><E6A2A7>?
|
||||
- [ ] 隶ー蠖柊PI Token蜥碁<EFBFBD>鄂ョ菫。諱?
|
||||
- [ ] 譖エ譁ー譫カ譫<EFBDB6><E8ADAB>?
|
||||
- [ ] 謠蝉コ、Git
|
||||
|
||||
---
|
||||
@@ -982,48 +982,48 @@ async function testIntegration() {
|
||||
|
||||
### 1. DET驟咲スョ隕∫せ
|
||||
|
||||
**常见错误:**
|
||||
- ❌ 忘记在Control Center启用DET全局开关
|
||||
- ❌ Webhook URL填写错误(多了斜杠、少了路径)
|
||||
- ❌ 本地开发环境无法接收外网Webhook
|
||||
**蟶ク隗<EFBFBD>漠隸ッ<EFBFBD>?*
|
||||
- 笶?蠢倩ョー蝨ィControl Center蜷ッ逕ィDET蜈ィ螻蠑蜈?
|
||||
- 笶?Webhook URL蝪ォ蜀咎漠隸ッ<EFBFBD>亥、壻コ<EFBFBD>万譚<EFBFBD>縲∝ー台コ<EFBFBD>キッ蠕<EFBFBD>シ<EFBFBD>
|
||||
- 笶?譛ャ蝨ー蠑蜿醍識蠅<E8AD98>裏豕墓磁謾カ螟也ス糎ebhook
|
||||
|
||||
**解决方案:**
|
||||
- ✅ 使用ngrok创建临时公网URL测试
|
||||
- ✅ 开发环境可先用RequestBin验证Payload格式
|
||||
- ✅ 生产环境确保URL可访问(防火墙、HTTPS)
|
||||
**隗」蜀ウ譁ケ譯茨シ?*
|
||||
- 笨?菴ソ逕ィngrok蛻帛サコ荳エ譌カ蜈ャ鄂繕RL豬玖ッ<E78E96>
|
||||
- 笨?蠑蜿醍識蠅<E8AD98>庄蜈育畑RequestBin鬪瑚ッ ̄ayload譬シ蠑<EFBFBD>
|
||||
- 笨?逕滉コァ邇ッ蠅<EFBDAF>。ョ菫拔RL蜿ッ隶ソ髣ョ<E9ABA3>磯亟轣ォ蠅吶?TTPS<EFBFBD>?
|
||||
|
||||
### 2. API Token螳牙<E89EB3>
|
||||
|
||||
**安全实践:**
|
||||
- ✅ 存储在环境变量或数据库加密字段
|
||||
- ✅ 定期轮换Token
|
||||
- ✅ 最小权限原则(只开启需要的权限)
|
||||
- ❌ 不要提交到Git
|
||||
- ❌ 不要在日志中打印完整Token
|
||||
**螳牙<EFBFBD>螳櫁キオ<EFBFBD>?*
|
||||
- 笨?蟄伜お蝨ィ邇ッ蠅<EFBDAF>序驥乗<E9A9A5>謨ー謐ョ蠎灘刈蟇<E58888>ュ玲ョ?
|
||||
- 笨?螳壽悄霓ョ謐「Token
|
||||
- 笨?譛蟆乗揀髯仙次蛻呻シ亥宵蠑蜷ッ髴隕∫噪譚<E599AA>剞<EFBFBD>?
|
||||
- 笶?荳崎ヲ∵署莠、蛻ーGit
|
||||
- 笶?荳崎ヲ∝惠譌・蠢嶺クュ謇灘魂螳梧紛Token
|
||||
|
||||
### 3. 諤ァ閭ス莨伜喧
|
||||
|
||||
**Webhook响应时间:**
|
||||
- ✅ 必须 < 100ms(立即返回200)
|
||||
- ✅ 使用 `setImmediate()` 异步处理
|
||||
- ❌ 不要在Webhook中执行耗时操作
|
||||
**Webhook蜩榊コ疲慮髣エ<EFBFBD>?*
|
||||
- 笨?蠢<>。サ < 100ms<6D>育ォ句叉霑泌<E99C91>?00<30>?
|
||||
- 笨?菴ソ逕ィ `setImmediate()` 蠑よュ・螟<EFBDA5>炊
|
||||
- 笶?荳崎ヲ∝惠Webhook荳ュ謇ァ陦瑚玲慮謫堺ス<E5A0BA>
|
||||
|
||||
**API调用频率:**
|
||||
- ✅ 增量拉取(使用dateRangeBegin)
|
||||
- ✅ 指定字段(减少数据量)
|
||||
- ✅ 合理设置timeout(30秒)
|
||||
**API隹<EFBFBD>畑鬚醍紫<EFBFBD>?*
|
||||
- 笨?蠅樣㍼諡牙叙<E78999>井スソ逕ィdateRangeBegin<EFBFBD>?
|
||||
- 笨?謖<>ョ壼ュ玲ョオ<EFBDAE>亥㍼蟆第焚謐ョ驥擾シ?
|
||||
- 笨?蜷育炊隶セ鄂ョtimeout<75>?0遘抵シ<E68AB5>
|
||||
|
||||
### 4. 髞呵ッッ螟<EFBDAF>炊
|
||||
|
||||
**DET Webhook失败:**
|
||||
- REDCap会重试3次(间隔1分钟)
|
||||
**DET Webhook螟ア雍・<EFBFBD>?*
|
||||
- REDCap莨夐㍾隸?谺。<E8B0BA>磯龍髫<E9BE8D>1蛻<31>帖<EFBFBD>?
|
||||
- 螯よ棡莉榊、ア雍・<E99B8D>軍EDCap莨夊ョー蠖募芦譌・蠢<EFBDA5>
|
||||
- 謌台サャ逧<EFBDAC>スョ隸「譛コ蛻カ蜿ッ莉・陦・蜈<EFBDA5>@貍冗噪謨ー謐ョ
|
||||
|
||||
**API调用失败:**
|
||||
- 实现重试机制(3次,指数退避)
|
||||
**API隹<EFBFBD>畑螟ア雍・<EFBFBD>?*
|
||||
- 螳樒鴫驥崎ッ墓惻蛻カ<E89BBB>?谺。<E8B0BA>梧欠謨ー騾驕ソ<E9A995><EFBDBF>
|
||||
- 隶ー蠖募、ア雍・譌・蠢<EFBDA5>
|
||||
- 告警通知管理员
|
||||
- 蜻願ュヲ騾夂衍邂。逅<EFBDA1><E98085>?
|
||||
|
||||
---
|
||||
|
||||
@@ -1031,41 +1031,42 @@ async function testIntegration() {
|
||||
|
||||
### Day 2螳梧<E89EB3>譬<EFBFBD>㊥
|
||||
|
||||
- [ ] ✅ REDCap API Token已生成并验证
|
||||
- [ ] ✅ RedcapAdapter可以拉取测试数据
|
||||
- [ ] ✅ DET已配置并成功接收Webhook
|
||||
- [ ] ✅ Webhook可以触发API拉取
|
||||
- [ ] ✅ 轮询机制可以定时运行
|
||||
- [ ] ✅ 数据推送到质控队列
|
||||
- [ ] ✅ 单元测试全部通过
|
||||
- [ ] ✅ 端到端集成测试通过
|
||||
- [ ] 笨?REDCap API Token蟾イ逕滓<EFBFBD>蟷カ鬪瑚ッ<EFBFBD>
|
||||
- [ ] 笨?RedcapAdapter蜿ッ莉・諡牙叙豬玖ッ墓焚謐ョ
|
||||
- [ ] 笨?DET蟾イ驟咲スョ蟷カ謌仙粥謗・謾カWebhook
|
||||
- [ ] 笨?Webhook蜿ッ莉・隗ヲ蜿羨PI諡牙叙
|
||||
- [ ] 笨?霓ョ隸「譛コ蛻カ蜿ッ莉・螳壽慮霑占。<E58DA0>
|
||||
- [ ] 笨?謨ー謐ョ謗ィ騾∝芦雍ィ謗ァ髦溷<E9ABA6>
|
||||
- [ ] 笨?蜊募<E89C8A>豬玖ッ募<EFBDAF>驛ィ騾夊ソ<E5A48A>
|
||||
- [ ] 笨?遶ッ蛻ー遶ッ髮<EFBDAF><E9ABAE>豬玖ッ暮夊ソ<E5A48A>
|
||||
|
||||
### 諤ァ閭ス謖<EFBDBD><E8AC96><EFBFBD>
|
||||
|
||||
- [ ] Webhook蜩榊コ疲慮髣エ < 100ms
|
||||
- [ ] API调用成功率 > 99%
|
||||
- [ ] 端到端延迟 < 5秒(DET触发 → 企微通知)
|
||||
- [ ] API隹<EFBFBD>畑謌仙粥邇?> 99%
|
||||
- [ ] 遶ッ蛻ー遶ッ蟒カ霑?< 5遘抵シ<E68AB5>ET隗ヲ蜿<EFBDA6> 竊?莨∝セョ騾夂衍<E5A482>?
|
||||
|
||||
---
|
||||
|
||||
## <20>迫 逶ク蜈ウ譁<EFBDB3>。」
|
||||
|
||||
- **MVP开发任务清单:** `MVP开发任务清单.md`
|
||||
- **完整技术方案:** `IIT Manager Agent 完整技术开发方案 (V1.1).md`
|
||||
- **REDCap二次开发指南:** `../../Redcap/03-API对接与开发/33-REDCap二次开发深度指南.md`
|
||||
- **REDCap部署手册:** `../../Redcap/01-部署与配置/10-REDCap_Docker部署操作手册.md`
|
||||
- **MVP蠑蜿台ササ蜉。貂<EFBFBD>黒<EFBFBD><EFBFBD>** `MVP蠑蜿台ササ蜉。貂<EFBFBD><EFBFBD>?md`
|
||||
- **螳梧紛謚譛ッ譁ケ譯茨シ<E88CA8>** `IIT Manager Agent 螳梧紛謚譛ッ蠑蜿第婿譯?(V1.1).md`
|
||||
- **REDCap莠梧ャ。蠑蜿第欠蜊暦シ<EFBFBD>** `../../Redcap/03-API蟇ケ謗・荳主シ蜿?33-REDCap莠梧ャ。蠑蜿第キア蠎ヲ謖<EFBDA6><E8AC96>?md`
|
||||
- **REDCap驛ィ鄂イ謇句<EFBFBD><EFBFBD>?* `../../Redcap/01-驛ィ鄂イ荳朱<EFBFBD>鄂?10-REDCap_Docker驛ィ鄂イ謫堺ス懈焔蜀<EFBFBD>.md`
|
||||
|
||||
---
|
||||
|
||||
## <20>統 譖エ譁ー譌・蠢<EFBDA5>
|
||||
|
||||
| 日期 | 版本 | 更新内容 | 更新人 |
|
||||
| 譌・譛<EFBFBD> | 迚域悽 | 譖エ譁ー蜀<EFBDB0>ョケ | 譖エ譁ー莠?|
|
||||
|------|------|---------|--------|
|
||||
| 2026-01-02 | V1.0 | 蛻晏ァ狗沿譛ャ<E8AD9B>悟ョ梧<EFBDAE>謚譛ッ隹<EFBDAF><E99AB9>泌柱譁ケ譯郁ョセ隶。 | AI Assistant |
|
||||
|
||||
---
|
||||
|
||||
**这是IIT Manager Agent的技术基石文档,请妥善保管!** ⭐⭐⭐⭐⭐
|
||||
**霑呎弍IIT Manager Agent逧<EFBFBD>橿譛ッ蝓コ遏ウ譁<EFBFBD>。」<EFBFBD>瑚ッキ螯・蝟<EFBFBD>ソ晉ョ。<EFBFBD><EFBFBD>** 箝絶ュ絶ュ絶ュ絶ュ?
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# 企业微信注册与配置指南
|
||||
# 隡<EFBFBD><EFBFBD>敺桐縑瘜典<EFBFBD>銝𡡞<EFBFBD>蝵格<EFBFBD><EFBFBD>?
|
||||
|
||||
> **目标**:获取企业微信API凭证,用于IIT Manager Agent发送质控预警卡片
|
||||
> **预计时间**:20分钟
|
||||
> **<EFBFBD>格<EFBFBD>**嚗朞繮<E69C9E>碶<EFBFBD>銝𡁜凝靽,PI<50>剛<EFBFBD>嚗𣬚鍂鈭穉IT Manager Agent<EFBFBD>煾<EFBFBD><EFBFBD>捶<EFBFBD>折<EFBFBD>霅血㨃<EFBFBD>?
|
||||
> **憸<EFBFBD>恣<EFBFBD>園𡢿**嚗?0<><30><EFBFBD>
|
||||
|
||||
---
|
||||
|
||||
## 📋 步骤1:注册企业微信账号
|
||||
## <EFBFBD><EFBFBD> 甇仿炊1嚗𡁏釣<F0A1818F>䔶<EFBFBD>銝𡁜凝靽∟揭<E2889F>?
|
||||
|
||||
### 1.1 霈輸䔮隡<E494AE><E99AA1>敺桐縑摰条<E691B0>
|
||||
|
||||
@@ -15,28 +15,28 @@
|
||||
|
||||
1. <20>孵稬"**蝡见朖瘜典<E7989C>**"
|
||||
2. <20>㗇𥋘"**隡<><E99AA1>**"蝐餃<E89D90>
|
||||
3. 填写企业信息:
|
||||
- 企业名称:`测试医院`(或您的实际机构名称)
|
||||
3. 憛怠<EFBFBD>隡<EFBFBD><EFBFBD>靽⊥<EFBFBD>嚗?
|
||||
- 隡<EFBFBD><EFBFBD><EFBFBD>滨妍嚗䫤瘚贝<EFBFBD><EFBFBD>駁堺`嚗<><E59A97><EFBFBD>函<EFBFBD>摰鮋<E691B0><E9AE8B>箸<EFBFBD><E7AEB8>滨妍嚗?
|
||||
- 銵䔶<E98AB5>蝐餃<E89D90>嚗䫤<E59A97>餌<EFBFBD><E9A48C>亙熒`
|
||||
- 隡<><E99AA1>鈭箸㺭嚗䫤100鈭箔誑銝㞗
|
||||
- 蝞∠<E89D9E><E288A0>睃<EFBFBD><E79D83>㵪<EFBFBD><E3B5AA>函<EFBFBD>憪枏<E686AA>
|
||||
- 蝞∠<E89D9E><E288A0>䀹<EFBFBD><E480B9>綽<EFBFBD><E7B6BD>函<EFBFBD><E587BD>𧢲㦤<F0A7A2B2>瘀<EFBFBD><E79880>交𤣰撉諹<E69289><E8ABB9><EFBFBD><EFBFBD>
|
||||
4. 完成验证,注册成功
|
||||
4. 摰峕<EFBFBD>撉諹<EFBFBD>嚗峕釣<EFBFBD>峕<EFBFBD><EFBFBD>?
|
||||
|
||||
---
|
||||
|
||||
## 📋 步骤2:创建自建应用
|
||||
## <EFBFBD><EFBFBD> 甇仿炊2嚗𡁜<E59A97>撱箄䌊撱箏<E692B1><E7AE8F>?
|
||||
|
||||
### 2.1 <20>餃<EFBFBD>蝞∠<E89D9E><E288A0>𤾸蝱
|
||||
|
||||
1. 霈輸䔮嚗冴ttps://work.weixin.qq.com/wework_admin/loginpage_wx
|
||||
2. 使用企业微信APP扫码登录(需先在手机上下载企业微信APP)
|
||||
2. 雿輻鍂隡<EFBFBD><EFBFBD>敺桐縑APP<EFBFBD>怎<EFBFBD><EFBFBD>餃<EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>銁<EFBFBD>𧢲㦤銝𠹺<EFBFBD>頧賭<EFBFBD>銝𡁜凝靽,PP嚗?
|
||||
|
||||
### 2.2 <20>𥕦遣摨𠉛鍂
|
||||
|
||||
1. 进入**【应用管理】** → **【自建】** → **【创建应用】**
|
||||
1. 餈𥕦<EFBFBD>**<2A>𣂼<EFBFBD><F0A382BC>函恣<E587BD><E681A3><EFBFBD>?* <20>?**<2A>鞱䌊撱箝<E692B1>?* <20>?**<2A>𣂼<EFBFBD>撱箏<E692B1><E7AE8F>具<EFBFBD>?*
|
||||
|
||||
2. 填写应用信息:
|
||||
2. 憛怠<EFBFBD>摨𠉛鍂靽⊥<EFBFBD>嚗?
|
||||
- **摨𠉛鍂<F0A0899B>滨妍**嚗䫤IIT Manager Agent嚗<74><E59A97>霂𤏪<E99C82>`
|
||||
- **摨𠉛鍂Logo**嚗帋<E59A97>隡牐<E99AA1>銝芸㦛<E88AB8><E3A69B><EFBFBD><EFBFBD>舀<EFBFBD><E88880>嗡蝙<E597A1>券<EFBFBD>霈歹<E99C88>
|
||||
- **摨𠉛鍂隞讠<E99A9E>**嚗䫤IIT<49>𠉛弦<F0A0899B>箄<EFBFBD>韐冽綉<E586BD>拇<EFBFBD> - <20>唳旿韐券<E99F90>摰墧𧒄<E5A2A7>烐綉`
|
||||
@@ -44,19 +44,19 @@
|
||||
|
||||
3. <20>孵稬"**<2A>𥕦遣摨𠉛鍂**"
|
||||
|
||||
### 2.3 获取API凭证(重要!)
|
||||
### 2.3 <EFBFBD>瑕<EFBFBD>API<EFBFBD>剛<EFBFBD>嚗<EFBFBD><EFBFBD>閬<EFBFBD><EFBFBD>嚗?
|
||||
|
||||
创建成功后,在应用详情页可以看到:
|
||||
<EFBFBD>𥕦遣<EFBFBD>𣂼<EFBFBD><EFBFBD>𠬍<EFBFBD><EFBFBD>典<EFBFBD><EFBFBD>刻祕<EFBFBD><EFBFBD>△<EFBFBD>臭誑<EFBFBD>见<EFBFBD>嚗?
|
||||
|
||||
```
|
||||
隡<EFBFBD><EFBFBD>ID嚗㇃orpID嚗㚁<EFBFBD> ww1234567890abcdef
|
||||
AgentID: 1000002
|
||||
Secret: 点击"查看"按钮查看
|
||||
AgentID嚗? 1000002
|
||||
Secret嚗? <EFBFBD>孵稬"<22>亦<EFBFBD>"<22>厰僼<E58EB0>亦<EFBFBD>
|
||||
```
|
||||
|
||||
**⚠️ 重要提示**:
|
||||
**<EFBFBD>𩤃<EFBFBD> <20>滩<EFBFBD><E6BBA9>鞟內**嚗?
|
||||
- **Secret** <20>芣遬蝷箔<E89DB7>甈∴<E79488>霂瑞<E99C82><E7919E>喳<EFBFBD><E596B3>嗡<EFBFBD>摮矋<E691AE>
|
||||
- 如果忘记Secret,需要重置(会导致旧Secret失效)
|
||||
- 憒<EFBFBD><EFBFBD>敹䁅扇Secret嚗屸<EFBFBD>閬<EFBFBD><EFBFBD>蝵殷<EFBFBD>隡𡁜紡<EFBFBD>湔唂Secret憭望<EFBFBD>嚗?
|
||||
|
||||
---
|
||||
|
||||
@@ -64,10 +64,10 @@ Secret: 点击"查看"按钮查看
|
||||
|
||||
### 3.1 霈曄蔭蝵煾△<E785BE><E296B3><EFBFBD><EFBFBD>蹆S-SDK
|
||||
|
||||
1. 在应用详情页,找到"**网页授权及JS-SDK**"
|
||||
2. 设置**可信域名**:
|
||||
1. <EFBFBD>典<EFBFBD><EFBFBD>刻祕<EFBFBD><EFBFBD>△嚗峕𪄳<EFBFBD>?**蝵煾△<E785BE><E296B3><EFBFBD><EFBFBD>蹆S-SDK**"
|
||||
2. 霈曄蔭**<2A>臭縑<E887AD>笔<EFBFBD>**嚗?
|
||||
- 撘<><E69298>𤑳㴓憓<E3B493><E68693>`localhost`嚗<EFBFBD><EFBFBD><EFBFBD>𨀣𣈲<EFBFBD><EFBFBD><EFBFBD>
|
||||
- 生产环境:您的实际域名(如 `iit.example.com`)
|
||||
- <EFBFBD>煺漣<EFBFBD>臬<EFBFBD>嚗𡁏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㵪<EFBFBD>憒?`iit.example.com`嚗?
|
||||
|
||||
### 3.2 霈曄蔭<E69B84>交𤣰瘨<F0A4A3B0><E798A8>
|
||||
|
||||
@@ -77,13 +77,13 @@ Secret: 点击"查看"按钮查看
|
||||
### 3.3 霈曄蔭<E69B84><E894AD><EFBFBD><EFBFBD><EFBFBD>凒
|
||||
|
||||
蝖桐<EFBFBD>摨𠉛鍂<EFBFBD>劐誑銝𧢲<EFBFBD><EFBFBD>琜<EFBFBD>
|
||||
- ✅ **发送消息到微信** - 核心功能
|
||||
- ✅ **成员信息读取** - 用于获取用户OpenID
|
||||
- ✅ **通讯录管理** - 用于用户映射
|
||||
- <EFBFBD>?**<2A>煾<EFBFBD><E785BE><EFBFBD><EFBFBD>臬<EFBFBD>敺桐縑** - <EFBFBD>詨<EFBFBD><EFBFBD>蠘<EFBFBD>
|
||||
- <EFBFBD>?**<2A>𣂼<EFBFBD>靽⊥<E99DBD>霂餃<E99C82>** - <EFBFBD>其<EFBFBD><EFBFBD>瑕<EFBFBD><EFBFBD>冽<EFBFBD>OpenID
|
||||
- <EFBFBD>?**<2A>朞悖敶閧恣<E996A7>?* - <20>其<EFBFBD><E585B6>冽<EFBFBD><E586BD>惩<EFBFBD>
|
||||
|
||||
---
|
||||
|
||||
## 📋 步骤4:配置到项目中
|
||||
## <EFBFBD><EFBFBD> 甇仿炊4嚗𡁻<E59A97>蝵桀<E89DB5>憿寧𤌍銝?
|
||||
|
||||
### 4.1 憭滚<E686AD><E6BB9A>剛<EFBFBD>
|
||||
|
||||
@@ -95,7 +95,7 @@ AgentID: 1000002
|
||||
Secret: abc123xyz789_your_secret_here
|
||||
```
|
||||
|
||||
### 4.2 添加到 .env 文件
|
||||
### 4.2 瘛餃<EFBFBD><EFBFBD>?.env <EFBFBD><EFBFBD>辣
|
||||
|
||||
蝻𤥁<EFBFBD> `AIclinicalresearch/backend/.env`嚗峕溶<EFBFBD>𩤃<EFBFBD>
|
||||
|
||||
@@ -106,9 +106,9 @@ WECHAT_CORP_SECRET=abc123xyz789_your_secret_here
|
||||
WECHAT_AGENT_ID=1000002
|
||||
```
|
||||
|
||||
**⚠️ 注意**:
|
||||
- 不要提交 `.env` 文件到Git(已在 `.gitignore` 中)
|
||||
- 生产环境使用独立的企业微信应用
|
||||
**<EFBFBD>𩤃<EFBFBD> 瘜冽<E7989C>**嚗?
|
||||
- 銝滩<EFBFBD><EFBFBD>𣂷漱 `.env` <EFBFBD><EFBFBD>辣<EFBFBD>蚣it嚗<EFBFBD>歇<EFBFBD>?`.gitignore` 銝哨<EFBFBD>
|
||||
- <EFBFBD>煺漣<EFBFBD>臬<EFBFBD>雿輻鍂<EFBFBD>祉<EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝𡁜凝靽∪<EFBFBD><EFBFBD>?
|
||||
|
||||
---
|
||||
|
||||
@@ -116,18 +116,18 @@ WECHAT_AGENT_ID=1000002
|
||||
|
||||
### 5.1 <20>滚鍳<E6BB9A>𡒊垢<F0A1928A>滚𦛚
|
||||
|
||||
保存 `.env` 后,重启后端:
|
||||
靽嘥<EFBFBD> `.env` <EFBFBD>𠬍<EFBFBD><EFBFBD>滚鍳<EFBFBD>𡒊垢嚗?
|
||||
|
||||
```bash
|
||||
# 停止当前服务(Ctrl+C)
|
||||
# <EFBFBD>𨀣迫敶枏<EFBFBD><EFBFBD>滚𦛚嚗㇃trl+C嚗?
|
||||
# <20>齿鰵<E9BDBF>臬𢆡
|
||||
cd D:\MyCursor\AIclinicalresearch\backend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### 5.2 手动测试(使用Postman或curl)
|
||||
### 5.2 <EFBFBD>见𢆡瘚贝<EFBFBD>嚗<EFBFBD>蝙<EFBFBD>沌ostman<EFBFBD>鈪url嚗?
|
||||
|
||||
**测试端点**(后续Day 5会创建):
|
||||
**瘚贝<EFBFBD>蝡舐<EFBFBD>**嚗<><E59A97>蝏胖ay 5隡𡁜<E99AA1>撱綽<E692B1>嚗?
|
||||
|
||||
```bash
|
||||
POST http://localhost:3001/api/v1/iit/test/wechat-push
|
||||
@@ -136,73 +136,73 @@ Content-Type: application/json
|
||||
{
|
||||
"toUser": "YourUserID",
|
||||
"title": "瘚贝<E7989A><E8B49D>𡁶䰻",
|
||||
"description": "这是一条来自IIT Manager的测试消息",
|
||||
"description": "餈蹱糓銝<EFBFBD><EFBFBD>⊥䔉<EFBFBD>杷IT Manager<EFBFBD><EFBFBD><EFBFBD>霂閙<EFBFBD><EFBFBD>?,
|
||||
"url": "http://localhost:5173"
|
||||
}
|
||||
```
|
||||
|
||||
**预期结果**:
|
||||
- ✅ 返回200状态码
|
||||
- ✅ 企业微信APP收到卡片消息
|
||||
**憸<EFBFBD><EFBFBD>蝏𤘪<EFBFBD>**嚗?
|
||||
- <EFBFBD>?餈𥪜<E9A488>200<30>嗆<EFBFBD><E59786><EFBFBD>
|
||||
- <EFBFBD>?隡<><E99AA1>敺桐縑APP<50>嗅<EFBFBD><E59785>∠<EFBFBD>瘨<EFBFBD><E798A8>
|
||||
|
||||
---
|
||||
|
||||
## 📋 常见问题(FAQ)
|
||||
## <EFBFBD><EFBFBD> 撣貉<E692A3><E8B289>桅<EFBFBD>嚗㇅AQ嚗?
|
||||
|
||||
### Q1:我没有企业,可以注册吗?
|
||||
### Q1嚗𡁏<EFBFBD>瘝⊥<EFBFBD>隡<EFBFBD><EFBFBD>嚗<EFBFBD>虾隞交釣<EFBFBD><EFBFBD><EFBFBD>嚗?
|
||||
|
||||
**A**:可以!选择"**个人**"或"**个体工商户**"类型注册,功能完全相同。
|
||||
**A**嚗𡁜虾隞伐<E99A9E><E4BC90>㗇𥋘"**銝芯犖**"<22>?**銝芯<E98A9D>撌亙<E6928C><E4BA99>?*"蝐餃<E89D90>瘜典<E7989C>嚗<EFBFBD><E59A97><EFBFBD>賢<EFBFBD><E8B3A2>函㮾<E587BD>䎚<EFBFBD>?
|
||||
|
||||
### Q2嚗锭ecret敹䁅扇鈭<E68987><E988AD>𦒘<EFBFBD><F0A69298>痹<EFBFBD>
|
||||
|
||||
**A**:在应用详情页点击"**重置Secret**",但会导致旧Secret失效。
|
||||
**A**嚗𡁜銁摨𠉛鍂霂行<E99C82>憿萇<E686BF><E89087>?**<EFBFBD>滨蔭Secret**"嚗䔶<E59A97>隡𡁜紡<F0A1819C>湔唂Secret憭望<EFBFBD><EFBFBD>?
|
||||
|
||||
### Q3:测试环境需要实名认证吗?
|
||||
### Q3嚗𡁏<EFBFBD>霂閧㴓憓<EFBFBD><EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>滩恕霂<EFBFBD><EFBFBD>嚗?
|
||||
|
||||
**A**:不需要。未认证企业也可以使用自建应用的全部功能,只是人数有限制(100人)。
|
||||
**A**嚗帋<E59A97><E5B88B><EFBFBD>閬<EFBFBD><E996AC><EFBFBD>𧊋霈方<E99C88>隡<EFBFBD><E99AA1>銋笔虾隞乩蝙<E4B9A9>刻䌊撱箏<E692B1><E7AE8F>函<EFBFBD><E587BD>券<EFBFBD><E588B8>蠘<EFBFBD>嚗<EFBFBD>蘨<EFBFBD>臭犖<E887AD>唳<EFBFBD><E594B3>𣂼<EFBFBD>嚗?00鈭綽<E988AD><E7B6BD>?
|
||||
|
||||
### Q4:如何找到用户的 UserID?
|
||||
### Q4嚗𡁜<EFBFBD>雿閙𪄳<EFBFBD>啁鍂<EFBFBD>瑞<EFBFBD> UserID嚗?
|
||||
|
||||
**A**:
|
||||
1. 方法1:登录管理后台 → 通讯录 → 点击成员 → 查看"账号"
|
||||
**A**嚗?
|
||||
1. <EFBFBD>寞<EFBFBD>1嚗𡁶蒈敶閧恣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?<3F>朞悖敶?<3F>?<3F>孵稬<E5ADB5>𣂼<EFBFBD> <20>?<3F>亦<EFBFBD>"韐血噡"
|
||||
2. <20>寞<EFBFBD>2嚗朞<E59A97><E69C9E>其<EFBFBD>銝𡁜凝靽,PI<50>瑕<EFBFBD>嚗䫤GET /cgi-bin/user/getuserinfo`
|
||||
|
||||
### Q5:消息发送失败,返回40014错误?
|
||||
### Q5嚗𡁏<EFBFBD><EFBFBD>臬<EFBFBD><EFBFBD><EFBFBD>仃韐伐<EFBFBD>餈𥪜<EFBFBD>40014<EFBFBD>躰秤嚗?
|
||||
|
||||
**A**嚗䫤invalid access_token`嚗<>虾<EFBFBD>賢<EFBFBD><E8B3A2>𩤃<EFBFBD>
|
||||
- Secret<65>滨蔭<E6BBA8>躰秤
|
||||
- Access Token过期(需重新获取)
|
||||
- Access Token餈<EFBFBD><EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD>齿鰵<EFBFBD>瑕<EFBFBD>嚗?
|
||||
- CorpID<49>䨝gentID<49>滨蔭<E6BBA8>躰秤
|
||||
|
||||
---
|
||||
|
||||
## ✅ 验收标准
|
||||
## <EFBFBD>?撉峕𤣰<E5B395><F0A4A3B0><EFBFBD>
|
||||
|
||||
完成以下任务后,Day 1就完美收官了:
|
||||
摰峕<EFBFBD>隞乩<EFBFBD>隞餃𦛚<EFBFBD>𠬍<EFBFBD>Day 1撠勗<E692A0>蝢擧𤣰摰䀝<E691B0>嚗?
|
||||
|
||||
- [ ] 隡<><E99AA1>敺桐縑韐血噡瘜典<E7989C><E585B8>𣂼<EFBFBD>
|
||||
- [ ] <20>芸遣摨𠉛鍂<F0A0899B>𥕦遣<F0A595A6>𣂼<EFBFBD>
|
||||
- [ ] <20>瑕<EFBFBD><E79195>蚓orpID<49><44>gentID<49><44>ecret
|
||||
- [ ] 配置到 `.env` 文件
|
||||
- [ ] <20>滨蔭<E6BBA8>?`.env` <20><>辣
|
||||
- [ ] <20>𡒊垢<F0A1928A>滚𦛚<E6BB9A>賣迤撣詨鍳<E8A9A8>剁<EFBFBD><E58981>䭾𥁒<E4ADBE>辷<EFBFBD>
|
||||
|
||||
---
|
||||
|
||||
## 🎯 下一步
|
||||
## <EFBFBD>㴓 銝衤<E98A9D>甇?
|
||||
|
||||
摰峕<EFBFBD>隡<EFBFBD><EFBFBD>敺桐縑<EFBFBD>滨蔭<EFBFBD>𠬍<EFBFBD>Day 2<>睲賑撠<E8B391><E692A0>憪页<E686AA>
|
||||
|
||||
1. **REDCap API Adapter开发**(核心功能)
|
||||
2. **SyncManager开发**(混合同步模式)
|
||||
3. 实现REDCap数据拉取和轮询
|
||||
1. **REDCap API Adapter撘<EFBFBD><EFBFBD>?*嚗<>瓲敹<E793B2><E695B9><EFBFBD>踝<EFBFBD>
|
||||
2. **SyncManager撘<EFBFBD><EFBFBD>?*嚗<>毽<EFBFBD><E6AFBD><EFBFBD>甇交芋撘𧶏<E69298>
|
||||
3. 摰䂿緵REDCap<EFBFBD>唳旿<EFBFBD>匧<EFBFBD><EFBFBD>諹蔭霂?
|
||||
|
||||
预计完成时间:8小时
|
||||
憸<EFBFBD>恣摰峕<EFBFBD><EFBFBD>園𡢿嚗?撠𤩺𧒄
|
||||
|
||||
---
|
||||
|
||||
**创建日期**:2025-12-31
|
||||
**维护者**:开发团队
|
||||
**参考文档**:
|
||||
**<EFBFBD>𥕦遣<EFBFBD>交<EFBFBD>**嚗?025-12-31
|
||||
**蝏湔擪<EFBFBD>?*嚗𡁜<E59A97><F0A1819C>穃𣪧<E7A983>?
|
||||
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>獢?*嚗?
|
||||
- 隡<><E99AA1>敺桐縑摰䀹䲮<E480B9><E4B2AE>﹝嚗冴ttps://developer.work.weixin.qq.com/document/
|
||||
- <20>煾<EFBFBD><E785BE><EFBFBD><EFBFBD>冽<EFBFBD><E586BD>荔<EFBFBD>https://developer.work.weixin.qq.com/document/path/90236
|
||||
|
||||
@@ -225,5 +225,6 @@ Content-Type: application/json
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user