Files
AIclinicalresearch/backend/src/modules/iit-manager/test-iit-database.ts
HaHafeng 440f75255e feat(rvw): Complete Phase 4-5 - Bug fixes and Word export
Summary:
- Fix methodology score display issue in task list (show score instead of 'warn')
- Add methodology_score field to database schema
- Fix report display when only methodology agent is selected
- Implement Word document export using docx library
- Update documentation to v3.0/v3.1

Backend changes:
- Add methodologyScore to Prisma schema and TaskSummary type
- Update reviewWorker to save methodologyScore
- Update getTaskList to return methodologyScore

Frontend changes:
- Install docx and file-saver libraries
- Implement handleExportReport with Word generation
- Fix activeTab auto-selection based on available data
- Add proper imports for docx components

Documentation:
- Update RVW module status to 90% (Phase 1-5 complete)
- Update system status document to v3.0

Tested: All review workflows verified, Word export functional
2026-01-10 22:52:15 +08:00

168 lines
5.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* IIT Manager 数据库测试脚本
* 验证Schema和CRUD操作
*/
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function testIitDatabase() {
console.log('🔍 Testing IIT Manager Database...\n');
try {
// ==================== 测试1创建项目 ====================
console.log('✅ Test 1: 创建IIT项目');
const testProject = await prisma.iitProject.create({
data: {
name: 'Test IIT Project',
description: '这是一个测试项目',
fieldMappings: {
age: 'patient_age',
gender: 'sex',
enrollmentDate: 'consent_date'
},
redcapProjectId: '123',
redcapApiToken: 'test_token_12345',
redcapUrl: 'https://redcap.example.com',
status: 'active'
}
});
console.log(` ✓ 项目ID: ${testProject.id}`);
console.log(` ✓ 项目名称: ${testProject.name}\n`);
// ==================== 测试2创建影子状态记录 ====================
console.log('✅ Test 2: 创建影子状态记录');
const testAction = await prisma.iitPendingAction.create({
data: {
projectId: testProject.id,
recordId: 'RECORD_001',
fieldName: 'age',
currentValue: 65,
suggestedValue: null,
status: 'PROPOSED',
agentType: 'DATA_QUALITY',
reasoning: 'AI detected: 年龄65岁超出入排标准18-60岁',
evidence: {
protocolPage: 12,
protocolSection: '入排标准',
confidence: 0.95,
ruleType: 'inclusion'
}
}
});
console.log(` ✓ 影子状态ID: ${testAction.id}`);
console.log(` ✓ 状态: ${testAction.status}\n`);
// ==================== 测试3创建任务记录 ====================
console.log('✅ Test 3: 创建任务运行记录');
const testTaskRun = await prisma.iitTaskRun.create({
data: {
projectId: testProject.id,
taskType: 'bulk-scan',
status: 'pending',
totalItems: 100,
processedItems: 0,
successItems: 0,
failedItems: 0
}
});
console.log(` ✓ 任务ID: ${testTaskRun.id}`);
console.log(` ✓ 任务类型: ${testTaskRun.taskType}\n`);
// ==================== 测试4创建用户映射 ====================
console.log('✅ Test 4: 创建用户映射');
const testUserMapping = await prisma.iitUserMapping.create({
data: {
projectId: testProject.id,
systemUserId: 'user_123',
redcapUsername: 'test_crc',
wecomUserId: 'wecom_123',
role: 'CRC'
}
});
console.log(` ✓ 用户映射ID: ${testUserMapping.id}`);
console.log(` ✓ 角色: ${testUserMapping.role}\n`);
// ==================== 测试5创建审计日志 ====================
console.log('✅ Test 5: 创建审计日志');
const testAuditLog = await prisma.iitAuditLog.create({
data: {
projectId: testProject.id,
userId: 'user_123',
actionType: 'APPROVE_ACTION',
entityType: 'PENDING_ACTION',
entityId: testAction.id,
details: {
before: { status: 'PROPOSED' },
after: { status: 'APPROVED' }
},
traceId: 'trace_' + Date.now()
}
});
console.log(` ✓ 审计日志ID: ${testAuditLog.id}`);
console.log(` ✓ 操作类型: ${testAuditLog.actionType}\n`);
// ==================== 测试6查询和关联 ====================
console.log('✅ Test 6: 查询项目及关联数据');
const projectWithRelations = await prisma.iitProject.findUnique({
where: { id: testProject.id },
include: {
pendingActions: true,
taskRuns: true,
userMappings: true,
auditLogs: true
}
});
console.log(` ✓ 项目名称: ${projectWithRelations?.name}`);
console.log(` ✓ 影子状态记录数: ${projectWithRelations?.pendingActions.length}`);
console.log(` ✓ 任务记录数: ${projectWithRelations?.taskRuns.length}`);
console.log(` ✓ 用户映射数: ${projectWithRelations?.userMappings.length}`);
console.log(` ✓ 审计日志数: ${projectWithRelations?.auditLogs.length}\n`);
// ==================== 清理测试数据 ====================
console.log('🧹 清理测试数据...');
await prisma.iitAuditLog.delete({ where: { id: testAuditLog.id } });
await prisma.iitUserMapping.delete({ where: { id: testUserMapping.id } });
await prisma.iitTaskRun.delete({ where: { id: testTaskRun.id } });
await prisma.iitPendingAction.delete({ where: { id: testAction.id } });
await prisma.iitProject.delete({ where: { id: testProject.id } });
console.log(' ✓ 测试数据已清理\n');
console.log('🎉 所有测试通过IIT Schema工作正常\n');
} catch (error) {
console.error('❌ 测试失败:', error);
throw error;
} finally {
await prisma.$disconnect();
}
}
// 运行测试
testIitDatabase()
.then(() => {
console.log('✅ 数据库验证完成');
process.exit(0);
})
.catch((error) => {
console.error('❌ 数据库验证失败:', error);
process.exit(1);
});