/** * REDCap查询测试脚本(从数据库读取配置) * * 目的:测试基础的REDCap查询功能,验证数据格式 * 数据来源:从数据库 iit_schema.projects 表读取项目配置 * * 运行方式: * ```bash * cd backend * npm run tsx src/modules/iit-manager/test-redcap-query-from-db.ts * ``` */ import { RedcapAdapter } from './adapters/RedcapAdapter.js'; import { PrismaClient } from '@prisma/client'; import { logger } from '../../common/logging/index.js'; import dotenv from 'dotenv'; dotenv.config(); const prisma = new PrismaClient(); async function main() { console.log('='.repeat(70)); console.log('🧪 REDCap查询测试(为AI对话准备)'); console.log('='.repeat(70)); console.log(); try { // ============================================= // 1. 从数据库读取test0102项目配置 // ============================================= console.log('📋 从数据库读取项目配置...'); const project = await prisma.iitProject.findFirst({ where: { OR: [ { redcapProjectId: '16' }, { name: { contains: 'test0102' } } ], status: 'active' } }); if (!project) { console.log('❌ 未找到test0102项目(PID: 16)'); console.log(); console.log('💡 可能的原因:'); console.log(' 1. 项目未在数据库中'); console.log(' 2. 项目状态不是active'); console.log(' 3. redcapProjectId不是"16"'); console.log(); console.log('📝 解决方法:'); console.log(' 请检查数据库 iit_schema.projects 表'); console.log(' 或联系管理员添加test0102项目配置'); console.log(); process.exit(1); } console.log('✅ 项目配置读取成功'); console.log(); console.log('📋 项目信息:'); console.log(` 数据库ID: ${project.id}`); console.log(` 项目名称: ${project.name}`); console.log(` REDCap项目ID: ${project.redcapProjectId}`); console.log(` REDCap URL: ${project.redcapUrl}`); console.log(` API Token: ${project.redcapApiToken.substring(0, 8)}***`); console.log(` 状态: ${project.status}`); console.log(); // ============================================= // 2. 创建RedcapAdapter实例 // ============================================= console.log('📦 创建RedcapAdapter实例...'); const redcap = new RedcapAdapter( project.redcapUrl, project.redcapApiToken ); console.log('✅ Adapter创建成功\n'); // ============================================= // 3. 测试连接 // ============================================= console.log('🔌 测试API连接...'); try { const isConnected = await redcap.testConnection(); if (isConnected) { console.log('✅ API连接成功\n'); } else { console.log('❌ API连接失败'); console.log(' 请检查:'); console.log(' 1. REDCap服务是否启动'); console.log(` 2. URL是否正确: ${project.redcapUrl}`); console.log(' 3. API Token是否有效'); console.log(); process.exit(1); } } catch (error: any) { console.error('❌ 连接测试失败:', error.message); process.exit(1); } // ============================================= // 4. 查询所有记录(获取记录ID列表) // ============================================= console.log('📊 测试1: 查询所有记录(获取记录ID列表)'); console.log('-'.repeat(70)); const allRecords = await redcap.exportRecords({ fields: ['record_id'] }); // 提取唯一记录ID const uniqueRecordIds = Array.from( new Set(allRecords.map((r) => r.record_id || r.record)) ); console.log(`✅ 查询成功`); console.log(` 总记录数: ${uniqueRecordIds.length}`); console.log(` 记录ID列表: ${uniqueRecordIds.join(', ')}`); console.log(); if (uniqueRecordIds.length === 0) { console.log('⚠️ 项目中没有记录,请先在REDCap中创建测试数据'); console.log(' 建议:在test0102项目中添加几条测试记录'); console.log(); process.exit(0); } // ============================================= // 5. 查询特定记录的详细信息 // ============================================= const testRecordId = uniqueRecordIds[0]; // 使用第一条记录做测试 console.log(`📋 测试2: 查询特定记录的详细信息 (ID: ${testRecordId})`); console.log('-'.repeat(70)); const specificRecord = await redcap.exportRecords({ records: [testRecordId] }); if (specificRecord.length > 0) { console.log('✅ 查询成功'); console.log(` 记录数: ${specificRecord.length} 条`); console.log(); console.log('📄 第一条记录的数据结构:'); const firstRecord = specificRecord[0]; const fields = Object.keys(firstRecord); console.log(` 共 ${fields.length} 个字段:`); fields.slice(0, 10).forEach((field, index) => { const value = firstRecord[field]; const displayValue = value === '' ? '(空值)' : value; console.log(` ${(index + 1).toString().padStart(2, ' ')}. ${field.padEnd(30)} = ${displayValue}`); }); if (fields.length > 10) { console.log(` ... (还有 ${fields.length - 10} 个字段)`); } console.log(); } else { console.log('❌ 未找到记录'); console.log(); } // ============================================= // 6. 模拟AI对话场景的查询 // ============================================= console.log('🤖 测试3: 模拟AI对话场景'); console.log('-'.repeat(70)); console.log(); // 场景1: 用户问"有多少条记录?" console.log('【场景1】用户问:"我们系统中已经有几条记录了?"'); const countResult = { projectName: project.name, totalRecords: uniqueRecordIds.length, recordIds: uniqueRecordIds }; console.log('💾 AI需要的数据:'); console.log(JSON.stringify(countResult, null, 2)); console.log(); console.log('🤖 AI应该回答:'); console.log(` "您好!根据REDCap系统记录,当前项目${project.name}已有 **${uniqueRecordIds.length}条** 患者数据记录。"`); console.log(); // 场景2: 用户问特定记录的信息 const demoRecordId = uniqueRecordIds.includes('7') ? '7' : uniqueRecordIds[0]; console.log(`【场景2】用户问:"了解Redcap中记录为ID ${demoRecordId}的信息"`); const recordDetailResult = await redcap.exportRecords({ records: [demoRecordId] }); console.log('💾 AI需要的数据:'); console.log(JSON.stringify({ projectName: project.name, recordId: demoRecordId, data: recordDetailResult[0] }, null, 2)); console.log(); // 场景3: 用户问"项目名称" console.log('【场景3】用户问:"咱们当前的项目名称是什么?"'); console.log('💾 AI需要的数据:'); console.log(JSON.stringify({ projectName: project.name, redcapProjectId: project.redcapProjectId, recordCount: uniqueRecordIds.length, lastSync: project.lastSyncAt }, null, 2)); console.log(); console.log('🤖 AI应该回答:'); console.log(` "您好!当前项目名称为 **${project.name}**。如需查看完整方案或项目详情,请登录REDCap系统或查阅项目文档。"`); console.log(); // ============================================= // 测试总结 // ============================================= console.log('='.repeat(70)); console.log('✅ 所有测试完成!REDCap查询功能正常!'); console.log('='.repeat(70)); console.log(); console.log('📝 测试总结:'); console.log(` 1. ✅ 项目配置从数据库读取成功`); console.log(` 2. ✅ API连接正常`); console.log(` 3. ✅ 可以查询所有记录 (${uniqueRecordIds.length} 条)`); console.log(` 4. ✅ 可以查询特定记录`); console.log(` 5. ✅ 数据格式符合AI对话需求`); console.log(); console.log('🚀 下一步:'); console.log(' 将查询功能集成到ChatService,让AI能够基于真实数据回答问题'); console.log(); } catch (error: any) { console.error('❌ 测试失败:', error.message); console.error(' 错误详情:', error); process.exit(1); } finally { await prisma.$disconnect(); } process.exit(0); } // 执行测试 main().catch((error) => { console.error('💥 测试脚本执行失败:', error); process.exit(1); });