Features - User Management (Phase 4.1): - Database: Add user_modules table for fine-grained module permissions - Database: Add 4 user permissions (view/create/edit/delete) to role_permissions - Backend: UserService (780 lines) - CRUD with tenant isolation - Backend: UserController + UserRoutes (648 lines) - 13 API endpoints - Backend: Batch import users from Excel - Frontend: UserListPage (412 lines) - list/filter/search/pagination - Frontend: UserFormPage (341 lines) - create/edit with module config - Frontend: UserDetailPage (393 lines) - details/tenant/module management - Frontend: 3 modal components (592 lines) - import/assign/configure - API: GET/POST/PUT/DELETE /api/admin/users/* endpoints Architecture Upgrade - Module Permission System: - Backend: Add getUserModules() method in auth.service - Backend: Login API returns modules array in user object - Frontend: AuthContext adds hasModule() method - Frontend: Navigation filters modules based on user.modules - Frontend: RouteGuard checks requiredModule instead of requiredVersion - Frontend: Remove deprecated version-based permission system - UX: Only show accessible modules in navigation (clean UI) - UX: Smart redirect after login (avoid 403 for regular users) Fixes: - Fix UTF-8 encoding corruption in ~100 docs files - Fix pageSize type conversion in userService (String to Number) - Fix authUser undefined error in TopNavigation - Fix login redirect logic with role-based access check - Update Git commit guidelines v1.2 with UTF-8 safety rules Database Changes: - CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled) - ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code) - INSERT 4 permissions + role assignments - UPDATE PUBLIC tenant with 8 module subscriptions Technical: - Backend: 5 new files (~2400 lines) - Frontend: 10 new files (~2500 lines) - Docs: 1 development record + 2 status updates + 1 guideline update - Total: ~4900 lines of code Status: User management 100% complete, module permission system operational
40 KiB
40 KiB
REDCap与AIclinicalresearch平台对接总体方案
文档版本: v1.0
创建日期: 2025-12-30
最后更新: 2025-12-30
文档状态: 规划中
作者: 技术架构师
📋 文档说明
本文档定义REDCap(15.8.0)与壹证循AI科研平台的完整对接方案,包括:
- 对接架构设计
- External Module开发方案
- API集成方案
- 数据流设计
- 开发计划与实施步骤
前置条件:
- ✅ 已获得REDCap官方授权
- ✅ 拥有REDCap 15.8.0源代码
- ✅ 拥有External Module Framework文档
相关文档:
🎯 对接目标与价值
核心目标
将REDCap的强大EDC能力与AI科研平台的AI增值功能深度融合
REDCap (数据采集) + AIclinicalresearch (AI能力)
↓ ↓
临床数据录入 AI智能处理、分析、洞察
↓ ↓
完整的AI驱动临床研究闭环
业务价值
| 功能模块 | REDCap基础能力 | AI平台增值能力 | 协同价值 |
|---|---|---|---|
| 数据采集 | ✅ 表单设计、数据录入、验证 | 🎁 AI辅助录入、智能质控 | 提升录入效率50% |
| 数据清洗 | ⚠️ 手动查询、导出Excel | 🎁 DC模块自动清洗、NER提取 | 减少数据处理时间80% |
| 统计分析 | ⚠️ 需导出到R/SPSS | 🎁 SSA模块一键分析、可视化 | 降低统计门槛,分析速度提升10倍 |
| 文献支持 | ❌ 无 | 🎁 ASL模块智能文献筛选 | 系统评价效率提升5倍 |
| AI问答 | ❌ 无 | 🎁 AIA模块10+智能体辅助 | 全流程AI辅助 |
| 知识库 | ❌ 无 | 🎁 PKB模块RAG问答 | 项目知识沉淀 |
🏗️ 对接架构设计
整体架构
┌─────────────────────────────────────────────────────────────────┐
│ 用户层(研究人员/医生) │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 前端展示层 │
│ ┌────────────────┐ ┌─────────────────────────┐ │
│ │ REDCap Web UI │ │ AIclinicalresearch │ │
│ │ (原生界面) │◄────────────►│ Frontend (React) │ │
│ └────────────────┘ └─────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 集成层(核心) │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ REDCap External Module: "AI Research Assistant" │ │
│ │ ───────────────────────────────────────────────────── │ │
│ │ ├── 数据同步服务 (Data Sync Service) │ │
│ │ ├── AI功能菜单 (AI Menu Links) │ │
│ │ ├── Hooks处理器 (Hook Handlers) │ │
│ │ └── API代理层 (API Proxy) │ │
│ └────────────────────────────────────────────────────────┘ │
│ ↕ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ AIclinicalresearch Backend RESTful API │ │
│ │ /api/v1/redcap/* │ │
│ └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 业务处理层(AI能力) │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ DC │ │ SSA │ │ ASL │ │ AIA │ │ PKB │ ... │
│ │数据 │ │统计 │ │文献 │ │问答 │ │知识库│ │
│ │清洗 │ │分析 │ │筛选 │ │ │ │ │ │
│ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 数据存储层 │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ REDCap MySQL │ │ AI Platform │ │
│ │ (临床数据) │◄───────►│ PostgreSQL │ │
│ │ - 患者数据 │ 同步 │ (分析结果) │ │
│ │ - 表单元数据 │ │ - 清洗后数据 │ │
│ └──────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
核心对接模式
我们采用双向对接策略:
模式A:REDCap → AI平台(数据推送)
用户在REDCap录入数据
↓
redcap_save_record Hook触发
↓
External Module推送数据到AI平台API
↓
AI平台处理(清洗/分析/AI处理)
↓
结果返回REDCap存储
模式B:AI平台 → REDCap(数据拉取)
用户在AI平台发起分析
↓
AI平台调用REDCap API获取数据
↓
AI平台执行分析(DC/SSA/AIA等)
↓
结果展示在AI平台前端
↓
(可选)结果回写REDCap
🔧 技术方案详解
方案1:REDCap External Module开发
模块命名与结构
模块名称: ai_research_assistant
版本: v1.0.0
完整目录: <redcap-root>/modules/ai_research_assistant_v1.0.0/
目录结构:
ai_research_assistant_v1.0.0/
├── config.json # 模块配置
├── AiResearchAssistantModule.php # 主逻辑类
├── README.md # 说明文档
├── LICENSE # MIT许可
├── pages/ # 自定义页面
│ ├── dashboard.php # AI功能仪表盘
│ ├── data_sync.php # 数据同步管理
│ ├── analysis_center.php # 分析中心
│ └── settings.php # 模块设置
├── js/ # JavaScript文件
│ ├── dashboard.js
│ └── data_sync.js
├── css/ # 样式文件
│ └── style.css
└── services/ # 服务类
├── ApiClient.php # AI平台API客户端
├── DataMapper.php # 数据映射转换
└── SyncService.php # 同步服务
config.json核心配置
{
"name": "AI Research Assistant",
"description": "壹证循AI科研平台集成模块 - 提供数据智能清洗、统计分析、文献支持等AI增值功能",
"authors": [
{
"name": "壹证循科技",
"email": "support@yizx.ai",
"institution": "壹证循科技"
}
],
"framework-version": 16,
"permissions": [],
"links": {
"project": [
{
"name": "🤖 AI功能中心",
"icon": "fas fa-brain",
"url": "pages/dashboard.php",
"show-header-and-footer": true
},
{
"name": "🔄 数据同步",
"icon": "fas fa-sync-alt",
"url": "pages/data_sync.php",
"show-header-and-footer": true
},
{
"name": "📊 AI分析中心",
"icon": "fas fa-chart-line",
"url": "pages/analysis_center.php",
"show-header-and-footer": true
}
],
"control-center": [
{
"name": "AI平台配置",
"icon": "fas fa-cog",
"url": "pages/settings.php"
}
]
},
"system-settings": [
{
"key": "ai_platform_url",
"name": "AI平台地址",
"type": "text",
"required": true,
"default": "https://ai.yizx.com"
},
{
"key": "ai_platform_api_key",
"name": "API密钥",
"type": "password",
"required": true
},
{
"key": "enable_auto_sync",
"name": "启用自动同步",
"type": "checkbox",
"default": true
}
],
"project-settings": [
{
"key": "sync_mode",
"name": "同步模式",
"type": "dropdown",
"choices": [
{"value": "manual", "name": "手动同步"},
{"value": "realtime", "name": "实时同步"},
{"value": "scheduled", "name": "定时同步"}
],
"default": "realtime"
},
{
"key": "enable_dc_module",
"name": "启用数据清洗模块",
"type": "checkbox",
"default": true
},
{
"key": "enable_ssa_module",
"name": "启用统计分析模块",
"type": "checkbox",
"default": true
},
{
"key": "enable_asl_module",
"name": "启用智能文献模块",
"type": "checkbox",
"default": false
}
],
"crons": [
{
"cron_name": "data_sync_cron",
"cron_description": "定时同步数据到AI平台",
"method": "syncDataToAIPlatform",
"cron_frequency": "3600",
"cron_max_run_time": "600"
}
]
}
主逻辑类(AiResearchAssistantModule.php)
<?php
namespace YiZhengXun\AiResearchAssistant;
use ExternalModules\AbstractExternalModule;
use REDCap;
class AiResearchAssistantModule extends AbstractExternalModule {
// API客户端实例
private $apiClient;
/**
* 构造函数 - 初始化API客户端
*/
public function __construct() {
parent::__construct();
require_once __DIR__ . '/services/ApiClient.php';
$this->apiClient = new ApiClient(
$this->getSystemSetting('ai_platform_url'),
$this->getSystemSetting('ai_platform_api_key')
);
}
/**
* Hook: 数据保存时触发
* 核心功能:实时推送数据到AI平台
*/
public function redcap_save_record(
$project_id,
$record,
$instrument,
$event_id,
$group_id,
$survey_hash,
$response_id,
$repeat_instance
) {
// 检查是否启用实时同步
$syncMode = $this->getProjectSetting('sync_mode');
if ($syncMode !== 'realtime') {
return;
}
// 防止无限循环
static $is_syncing = false;
if ($is_syncing) return;
$is_syncing = true;
try {
// 获取记录数据
$data = REDCap::getData($project_id, 'array', $record);
// 转换数据格式
require_once __DIR__ . '/services/DataMapper.php';
$mapper = new DataMapper();
$mappedData = $mapper->redcapToAIPlatform($data, $project_id, $record);
// 推送到AI平台
$result = $this->apiClient->post('/api/v1/redcap/records', $mappedData);
// 记录日志
$this->log("数据同步成功", [
'project_id' => $project_id,
'record' => $record,
'instrument' => $instrument,
'ai_platform_response' => $result
]);
// 如果启用了AI数据清洗,触发清洗任务
if ($this->getProjectSetting('enable_dc_module')) {
$this->triggerDataCleaning($project_id, $record);
}
} catch (\Exception $e) {
// 错误处理
$this->log("数据同步失败", [
'project_id' => $project_id,
'record' => $record,
'error' => $e->getMessage()
]);
}
$is_syncing = false;
}
/**
* Hook: 每个页面顶部
* 功能:注入AI辅助录入的JavaScript
*/
public function redcap_every_page_top($project_id) {
// 仅在数据录入页面生效
if (strpos(PAGE, 'DataEntry/index.php') !== false) {
$this->injectAIAssistant();
}
}
/**
* Hook: 数据导出前
* 功能:可以添加AI分析结果字段到导出
*/
public function redcap_custom_verify_username($username) {
// 验证逻辑
}
/**
* Cron任务: 定时同步数据
*/
public function syncDataToAIPlatform($cron_info) {
$projects = $this->getEnabledProjects();
foreach ($projects as $project_id) {
try {
// 获取项目所有数据
$data = REDCap::getData($project_id, 'array');
// 批量推送
$result = $this->apiClient->post('/api/v1/redcap/batch-sync', [
'project_id' => $project_id,
'data' => $data,
'timestamp' => time()
]);
$this->log("定时同步完成", [
'project_id' => $project_id,
'records_count' => count($data)
]);
} catch (\Exception $e) {
$this->log("定时同步失败", [
'project_id' => $project_id,
'error' => $e->getMessage()
]);
}
}
return "同步完成";
}
/**
* 触发AI数据清洗
*/
private function triggerDataCleaning($project_id, $record) {
$result = $this->apiClient->post('/api/v1/redcap/dc/clean', [
'project_id' => $project_id,
'record' => $record,
'auto_mode' => true
]);
return $result;
}
/**
* 注入AI辅助录入JavaScript
*/
private function injectAIAssistant() {
?>
<script src="<?= $this->getUrl('js/ai_assistant.js') ?>"></script>
<script>
const aiConfig = {
apiUrl: '<?= $this->getSystemSetting('ai_platform_url') ?>',
projectId: <?= PROJECT_ID ?>,
enableAutoComplete: true,
enableSmartValidation: true
};
AiAssistant.init(aiConfig);
</script>
<?php
}
/**
* 获取启用模块的项目列表
*/
private function getEnabledProjects() {
$sql = "SELECT project_id FROM redcap_external_modules
WHERE external_module_id = ?
AND directory_prefix = ?";
$result = $this->query($sql, [
$this->getModuleId(),
$this->PREFIX
]);
$projects = [];
while ($row = $result->fetch_assoc()) {
$projects[] = $row['project_id'];
}
return $projects;
}
}
方案2:AI平台Backend API开发
新增REDCap专用模块
// backend/src/modules/redcap/ 目录结构
backend/src/modules/redcap/
├── controllers/
│ ├── RedcapController.ts // 主控制器
│ ├── SyncController.ts // 数据同步控制器
│ └── WebhookController.ts // Webhook控制器
├── services/
│ ├── RedcapApiClient.ts // REDCap API客户端
│ ├── DataTransformService.ts // 数据转换服务
│ ├── SyncService.ts // 同步服务
│ └── ProjectMappingService.ts // 项目映射服务
├── models/
│ └── redcap.prisma // Prisma Schema
├── routes/
│ └── redcap.routes.ts // 路由定义
└── types/
└── redcap.types.ts // TypeScript类型定义
Prisma Schema设计
// backend/prisma/schema.prisma
// REDCap Schema
datasource redcap_schema {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["redcap_schema"]
}
// REDCap项目映射表
model RedcapProject {
id String @id @default(cuid())
redcapProjectId Int @unique // REDCap项目ID
redcapUrl String // REDCap服务器地址
redcapApiToken String @db.VarChar(64) // API Token (加密存储)
// 映射关系
dcProjectId String? // 关联的DC项目ID
ssaProjectId String? // 关联的SSA项目ID
aslProjectId String? // 关联的ASL项目ID
// 同步配置
syncEnabled Boolean @default(true)
syncMode String @default("realtime") // realtime, scheduled, manual
lastSyncAt DateTime?
// 元数据
projectName String
projectDescription String? @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// 关联关系
syncRecords RedcapSyncRecord[]
fieldMappings RedcapFieldMapping[]
@@map("redcap_projects")
@@schema("redcap_schema")
}
// REDCap同步记录表
model RedcapSyncRecord {
id String @id @default(cuid())
projectId String
project RedcapProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
recordId String // REDCap记录ID
eventId String? // REDCap事件ID
instrument String? // 表单名称
// 同步状态
status String // pending, syncing, success, failed
direction String // redcap_to_ai, ai_to_redcap
// 数据快照
redcapData Json // REDCap原始数据
aiPlatformData Json? // AI平台处理后数据
// 错误信息
errorMessage String? @db.Text
retryCount Int @default(0)
syncedAt DateTime @default(now())
@@map("redcap_sync_records")
@@schema("redcap_schema")
@@index([projectId, recordId])
@@index([status])
}
// REDCap字段映射表
model RedcapFieldMapping {
id String @id @default(cuid())
projectId String
project RedcapProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
// REDCap字段信息
redcapFieldName String
redcapFieldLabel String?
redcapFieldType String // text, radio, checkbox, dropdown, etc.
// AI平台字段映射
aiPlatformField String? // 映射到AI平台的字段名
transformRule Json? // 转换规则(JSON)
// 映射配置
isRequired Boolean @default(false)
isIdentifier Boolean @default(false) // 是否为主键字段
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("redcap_field_mappings")
@@schema("redcap_schema")
@@unique([projectId, redcapFieldName])
}
REDCap API路由定义
// backend/src/modules/redcap/routes/redcap.routes.ts
import { FastifyInstance } from 'fastify';
import { RedcapController } from '../controllers/RedcapController';
import { SyncController } from '../controllers/SyncController';
import { WebhookController } from '../controllers/WebhookController';
export async function redcapRoutes(fastify: FastifyInstance) {
const redcapController = new RedcapController();
const syncController = new SyncController();
const webhookController = new WebhookController();
// ========== 项目管理 ==========
// 创建REDCap项目映射
fastify.post('/api/v1/redcap/projects',
redcapController.createProject
);
// 获取项目列表
fastify.get('/api/v1/redcap/projects',
redcapController.listProjects
);
// 获取项目详情
fastify.get('/api/v1/redcap/projects/:id',
redcapController.getProject
);
// 更新项目配置
fastify.put('/api/v1/redcap/projects/:id',
redcapController.updateProject
);
// 删除项目映射
fastify.delete('/api/v1/redcap/projects/:id',
redcapController.deleteProject
);
// ========== 数据同步 ==========
// 手动触发同步(REDCap → AI平台)
fastify.post('/api/v1/redcap/sync/import/:projectId',
syncController.importFromRedcap
);
// 推送数据到REDCap(AI平台 → REDCap)
fastify.post('/api/v1/redcap/sync/export/:projectId',
syncController.exportToRedcap
);
// 查询同步状态
fastify.get('/api/v1/redcap/sync/status/:projectId',
syncController.getSyncStatus
);
// 查询同步历史
fastify.get('/api/v1/redcap/sync/history/:projectId',
syncController.getSyncHistory
);
// ========== Webhook接收 ==========
// REDCap External Module推送数据(实时同步)
fastify.post('/api/v1/redcap/webhook/records',
webhookController.receiveRecordUpdate
);
// 批量同步(定时任务)
fastify.post('/api/v1/redcap/webhook/batch-sync',
webhookController.receiveBatchSync
);
// ========== 字段映射管理 ==========
// 获取REDCap项目元数据(字段列表)
fastify.get('/api/v1/redcap/projects/:id/metadata',
redcapController.getProjectMetadata
);
// 创建/更新字段映射
fastify.post('/api/v1/redcap/projects/:id/field-mappings',
redcapController.upsertFieldMappings
);
// 获取字段映射
fastify.get('/api/v1/redcap/projects/:id/field-mappings',
redcapController.getFieldMappings
);
// ========== AI功能集成 ==========
// 触发数据清洗(DC模块)
fastify.post('/api/v1/redcap/dc/clean',
redcapController.triggerDataCleaning
);
// 触发统计分析(SSA模块)
fastify.post('/api/v1/redcap/ssa/analyze',
redcapController.triggerStatisticalAnalysis
);
// 获取AI分析结果
fastify.get('/api/v1/redcap/analysis/:recordId',
redcapController.getAnalysisResults
);
}
核心Controller实现
// backend/src/modules/redcap/controllers/SyncController.ts
import { FastifyRequest, FastifyReply } from 'fastify';
import { prisma } from '@/config/database';
import { logger } from '@/common/logging';
import { RedcapApiClient } from '../services/RedcapApiClient';
import { DataTransformService } from '../services/DataTransformService';
export class SyncController {
/**
* 从REDCap导入数据到AI平台
*/
async importFromRedcap(
req: FastifyRequest<{ Params: { projectId: string } }>,
res: FastifyReply
) {
const { projectId } = req.params;
try {
// 1. 获取项目配置
const project = await prisma.redcapProject.findUnique({
where: { id: projectId },
include: { fieldMappings: true }
});
if (!project) {
return res.status(404).send({
success: false,
error: '项目不存在'
});
}
// 2. 调用REDCap API获取数据
const redcapClient = new RedcapApiClient(
project.redcapUrl,
project.redcapApiToken
);
const redcapData = await redcapClient.exportRecords({
format: 'json',
type: 'flat'
});
logger.info('从REDCap获取数据成功', {
projectId,
recordCount: redcapData.length
});
// 3. 数据转换
const transformer = new DataTransformService();
const transformedData = await transformer.redcapToAIPlatform(
redcapData,
project.fieldMappings
);
// 4. 存储到AI平台数据库
// 根据项目配置,推送到DC/SSA/ASL等模块
if (project.dcProjectId) {
await this.importToDCModule(project.dcProjectId, transformedData);
}
if (project.ssaProjectId) {
await this.importToSSAModule(project.ssaProjectId, transformedData);
}
// 5. 记录同步历史
await prisma.redcapSyncRecord.create({
data: {
projectId,
recordId: 'batch_import',
status: 'success',
direction: 'redcap_to_ai',
redcapData: redcapData as any,
aiPlatformData: transformedData as any
}
});
// 6. 更新同步时间
await prisma.redcapProject.update({
where: { id: projectId },
data: { lastSyncAt: new Date() }
});
return res.send({
success: true,
message: '数据导入成功',
data: {
recordCount: redcapData.length,
transformedCount: transformedData.length
}
});
} catch (error) {
logger.error('REDCap数据导入失败', {
projectId,
error: error.message
});
return res.status(500).send({
success: false,
error: '数据导入失败',
details: error.message
});
}
}
/**
* 导入到DC模块
*/
private async importToDCModule(dcProjectId: string, data: any[]) {
// 调用DC模块的导入API
// TODO: 实现DC模块集成逻辑
}
/**
* 导入到SSA模块
*/
private async importToSSAModule(ssaProjectId: string, data: any[]) {
// 调用SSA模块的导入API
// TODO: 实现SSA模块集成逻辑
}
}
📊 数据流设计
数据流1:REDCap → AI平台(实时同步)
┌─────────────────────────────────────────────────────────┐
│ Step 1: 用户在REDCap录入数据 │
│ ───────────────────────────────────────────────────── │
│ 研究人员在REDCap表单中录入患者数据 │
│ 例如:患者ID、年龄、性别、诊断、检验结果等 │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Step 2: REDCap触发redcap_save_record Hook │
│ ───────────────────────────────────────────────────── │
│ External Module捕获保存事件 │
│ 获取:project_id, record, instrument, event_id │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Step 3: 数据获取与映射 │
│ ───────────────────────────────────────────────────── │
│ 1. 调用REDCap::getData()获取完整记录 │
│ 2. DataMapper转换REDCap EAV格式→AI平台标准格式 │
│ 3. 应用字段映射规则(redcap_field_mappings表) │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Step 4: HTTP POST推送到AI平台API │
│ ───────────────────────────────────────────────────── │
│ URL: https://ai.yizx.com/api/v1/redcap/webhook/records │
│ Payload: { │
│ project_id: 123, │
│ record_id: "PAT001", │
│ data: {...}, │
│ timestamp: 1735542000 │
│ } │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Step 5: AI平台接收并处理 │
│ ───────────────────────────────────────────────────── │
│ 1. WebhookController验证请求签名 │
│ 2. 存储原始数据到redcap_sync_records表 │
│ 3. 异步触发AI处理任务(DC/SSA模块) │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Step 6: AI处理与结果返回 │
│ ───────────────────────────────────────────────────── │
│ 1. DC模块:数据清洗、NER提取、缺失值处理 │
│ 2. SSA模块:自动统计分析、生成可视化图表 │
│ 3. 结果存储到AI平台数据库 │
│ 4. (可选)回写结果到REDCap(通过API) │
└─────────────────────────────────────────────────────────┘
数据流2:AI平台 → REDCap(分析结果回写)
AI平台完成分析
↓
生成分析结果(JSON)
↓
调用REDCap API: importRecords
↓
REDCap存储结果到特定字段
↓
研究人员在REDCap中查看AI分析结果
🚀 开发计划与实施步骤
Phase 1: 基础对接(Week 1-2)✅ 优先级P0
目标:建立REDCap与AI平台的基本连接
Week 1: External Module骨架
任务清单:
- 创建External Module目录结构
- 编写config.json配置文件
- 实现AiResearchAssistantModule.php基础类
- 实现redcap_save_record Hook(基础版)
- 开发ApiClient.php(HTTP客户端)
- 测试:REDCap保存数据→打印日志
交付物:
ai_research_assistant_v1.0.0/完整目录- 可在REDCap中启用的External Module
- 基础日志记录功能
Week 2: AI平台API端点
任务清单:
- 创建redcap_schema数据库Schema
- 实现Prisma模型(RedcapProject等3个表)
- 开发WebhookController接收数据
- 实现数据转换服务DataTransformService
- 开发项目管理API(CRUD)
- 测试:REDCap推送→AI平台接收→存储
交付物:
/api/v1/redcap/*API端点- PostgreSQL redcap_schema创建
- Postman测试集合
Phase 2: 数据同步与映射(Week 3-4)⭐ 优先级P1
目标:实现双向数据同步和字段智能映射
Week 3: 字段映射系统
任务清单:
- 开发字段映射管理UI(前端React)
- 实现REDCap元数据获取API
- 开发字段映射配置界面
- 实现映射规则引擎(DataMapper)
- 支持复杂转换(如:单位转换、编码映射)
- 测试:映射配置→数据转换验证
交付物:
- 字段映射UI页面
- 映射规则引擎
- 配置文档
Week 4: 双向同步
任务清单:
- 实现批量数据导入(REDCap → AI)
- 实现分析结果回写(AI → REDCap)
- 开发Cron定时同步任务
- 实现同步状态监控界面
- 错误处理与重试机制
- 测试:完整同步流程
交付物:
- 双向同步功能
- 同步监控Dashboard
- 错误处理机制
Phase 3: AI功能集成(Week 5-6)🎁 优先级P1
目标:集成DC、SSA、AIA等AI模块
Week 5: DC模块集成
任务清单:
- REDCap数据→DC模块自动清洗
- 清洗结果→REDCap回写
- 在REDCap中展示清洗报告
- 支持手动触发清洗
- 测试:录入→清洗→查看结果
交付物:
- DC集成API
- REDCap清洗报告页面
Week 6: SSA模块集成
任务清单:
- REDCap数据→SSA模块自动分析
- 支持三大分析路径(队列/预测/RCT)
- 在REDCap中嵌入统计报告
- 可视化图表展示
- 测试:数据录入→自动分析→报告生成
交付物:
- SSA集成API
- 统计报告嵌入页面
Phase 4: 高级功能(Week 7-8)🌟 优先级P2
目标:AI辅助录入、智能质控等增值功能
Week 7: AI辅助录入
任务清单:
- 开发智能自动完成(基于历史数据)
- 异常值预警(实时AI判断)
- 字段关联推荐(AI预测)
- 录入效率提升统计
- 测试:录入体验优化验证
交付物:
- AI辅助录入JS插件
- 智能质控规则引擎
Week 8: 综合测试与优化
任务清单:
- 性能测试(100万条记录同步)
- 安全测试(API认证、数据加密)
- 用户验收测试(UAT)
- 文档编写(用户手册+开发文档)
- 部署到生产环境
交付物:
- 性能测试报告
- 完整文档
- 生产环境部署
🔒 安全性设计
API认证机制
// 使用HMAC-SHA256签名验证
// REDCap External Module发送请求时
const timestamp = Date.now();
const signature = crypto
.createHmac('sha256', apiSecret)
.update(`${timestamp}${JSON.stringify(payload)}`)
.digest('hex');
// Headers:
{
'X-API-Key': apiKey,
'X-Timestamp': timestamp,
'X-Signature': signature
}
// AI平台验证
function verifySignature(req) {
const { timestamp, signature } = req.headers;
const expectedSignature = crypto
.createHmac('sha256', apiSecret)
.update(`${timestamp}${JSON.stringify(req.body)}`)
.digest('hex');
return signature === expectedSignature;
}
数据加密
- REDCap API Token:使用AES-256加密存储
- 传输加密:强制HTTPS
- 敏感字段:支持字段级加密(PHI数据)
权限控制
// REDCap用户权限同步到AI平台
interface UserPermission {
userId: string;
redcapRights: {
data_entry: boolean;
data_export: boolean;
data_analysis: boolean;
};
aiPlatformRights: {
dc_access: boolean;
ssa_access: boolean;
asl_access: boolean;
};
}
📚 技术栈总结
| 层级 | REDCap侧 | AI平台侧 |
|---|---|---|
| 编程语言 | PHP 7.4+ | TypeScript/Node.js 22 |
| 框架 | REDCap EM Framework v16 | Fastify v4 |
| 数据库 | MySQL 5.7+ | PostgreSQL 15 |
| 数据模型 | EAV模型 | 关系型+JSONB |
| 前端 | jQuery + Bootstrap 5 | React 19 + Ant Design 6 |
| API | REDCap RESTful API | Fastify RESTful API |
| 认证 | API Token | HMAC-SHA256签名 |
| 日志 | REDCap日志表 | Winston + SLS |
| 任务队列 | REDCap Cron | pg-boss (Postgres-Only) |
📝 下一步行动
立即行动(本周)
-
确认需求:
- 确认优先级(DC优先?还是SSA优先?)
- 确认部署形态(云端SaaS?还是私有化部署?)
- 确认REDCap服务器信息(URL、版本、访问权限)
-
环境准备:
- 搭建REDCap测试环境(使用Docker)
- 创建测试项目和测试数据
- 配置AI平台测试API
-
启动开发:
- 创建External Module目录
- 初始化Git仓库
- 编写config.json
技术预研
- REDCap API深入测试
- External Module Hook机制验证
- 大数据量同步性能测试
- 移动端(REDCap Mobile App)集成可行性
🎯 成功标准
MVP版本(Phase 1-2完成):
- ✅ REDCap数据能推送到AI平台
- ✅ AI平台能接收并存储数据
- ✅ 字段映射配置功能可用
- ✅ 基础同步监控可用
标准版本(Phase 3完成):
- ✅ DC模块集成完成(自动清洗)
- ✅ SSA模块集成完成(自动分析)
- ✅ 分析结果可在REDCap中查看
- ✅ 用户体验流畅
企业版本(Phase 4完成):
- ✅ AI辅助录入提升效率50%+
- ✅ 智能质控减少错误率80%+
- ✅ 支持100万+记录同步
- ✅ 安全合规(符合FDA 21 CFR Part 11)
文档版本:v1.0
最后更新:2025-12-30
下次更新:Phase 1启动后更新开发进度
🚀 准备好开始了吗?让我们开启REDCap与AI的融合之旅!