Files
AIclinicalresearch/backend/scripts/test-asl-api.ts
HaHafeng 2e8699c217 feat(asl): Week 2 Day 2 - Excel import with template download and intelligent dedup
Features:
- feat: Excel template generation and download (with examples)
- feat: Excel file parsing in memory (cloud-native, no disk write)
- feat: Field validation (title + abstract required)
- feat: Smart deduplication (DOI priority + Title fallback)
- feat: Literature preview table with statistics
- feat: Complete submission flow (create project + import literatures)

Components:
- feat: Create excelUtils.ts with full Excel processing toolkit
- feat: Enhance TitleScreeningSettings page with upload/preview/submit
- feat: Update API interface signatures and export unified aslApi object

Dependencies:
- chore: Add xlsx library for Excel file processing

Ref: Week 2 Frontend Development - Day 2
Scope: ASL Module MVP - Title Abstract Screening
Cloud-Native: Memory parsing, no file persistence
2025-11-19 10:24:47 +08:00

195 lines
7.8 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.
/**
* ASL模块API测试脚本
* 测试所有ASL API端点
*/
const BASE_URL = 'http://localhost:3001';
const API_PREFIX = '/api/v1/asl';
// 测试用的userId (需要先创建用户或使用已有用户)
const TEST_USER_ID = '00000000-0000-0000-0000-000000000001';
async function testAPI() {
console.log('🚀 开始测试 ASL 模块 API...\n');
let projectId = '';
let literatureIds: string[] = [];
try {
// ==================== 测试1: 健康检查 ====================
console.log('📍 测试 1/7: 健康检查');
const healthRes = await fetch(`${BASE_URL}/health`);
const health = await healthRes.json();
console.log('✅ 健康检查成功:', health.status);
console.log('');
// ==================== 测试2: 创建筛选项目 ====================
console.log('📍 测试 2/7: 创建筛选项目');
const createProjectRes = await fetch(`${BASE_URL}${API_PREFIX}/projects`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
projectName: 'SGLT2抑制剂系统综述测试',
picoCriteria: {
population: '2型糖尿病成人患者',
intervention: 'SGLT2抑制剂',
comparison: '安慰剂或常规降糖疗法',
outcome: '心血管结局',
studyDesign: '随机对照试验 (RCT)',
},
inclusionCriteria: '英文文献RCT研究2010年后发表',
exclusionCriteria: '病例报告,综述,动物实验',
screeningConfig: {
models: ['deepseek-chat', 'qwen-max'],
temperature: 0,
},
}),
});
if (!createProjectRes.ok) {
console.log('⚠️ 创建项目失败,状态码:', createProjectRes.status);
const error = await createProjectRes.text();
console.log('错误信息:', error);
console.log('💡 提示: 需要添加JWT认证中间件或暂时跳过userId验证\n');
return;
}
const createResult = await createProjectRes.json();
projectId = createResult.data.id;
console.log('✅ 项目创建成功');
console.log(' 项目ID:', projectId);
console.log(' 项目名称:', createResult.data.projectName);
console.log('');
// ==================== 测试3: 获取项目列表 ====================
console.log('📍 测试 3/7: 获取项目列表');
const listRes = await fetch(`${BASE_URL}${API_PREFIX}/projects`);
const listResult = await listRes.json();
console.log('✅ 获取项目列表成功');
console.log(' 项目数量:', listResult.data.length);
console.log('');
// ==================== 测试4: 获取项目详情 ====================
console.log('📍 测试 4/7: 获取项目详情');
const detailRes = await fetch(`${BASE_URL}${API_PREFIX}/projects/${projectId}`);
const detailResult = await detailRes.json();
console.log('✅ 获取项目详情成功');
console.log(' 项目名称:', detailResult.data.projectName);
console.log(' PICO标准:', JSON.stringify(detailResult.data.picoCriteria, null, 2));
console.log('');
// ==================== 测试5: 导入文献JSON ====================
console.log('📍 测试 5/7: 导入文献JSON');
const importRes = await fetch(`${BASE_URL}${API_PREFIX}/literatures/import`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
projectId: projectId,
literatures: [
{
pmid: '12345678',
title: 'Efficacy of SGLT2 inhibitors in type 2 diabetes: a randomized controlled trial',
abstract: 'Background: SGLT2 inhibitors are a new class of glucose-lowering drugs. Methods: We conducted a randomized, double-blind, placebo-controlled trial. Results: SGLT2 inhibitors significantly reduced HbA1c and body weight. Conclusions: SGLT2 inhibitors are effective for type 2 diabetes.',
authors: 'Smith J, Jones A, Brown B',
journal: 'New England Journal of Medicine',
publicationYear: 2020,
doi: '10.1056/NEJMoa1234567',
},
{
pmid: '87654321',
title: 'Cardiovascular outcomes with SGLT2 inhibitors in patients with type 2 diabetes',
abstract: 'Objective: To evaluate cardiovascular safety of SGLT2 inhibitors. Design: Multicenter randomized controlled trial. Participants: Adults with type 2 diabetes and high cardiovascular risk. Results: SGLT2 inhibitors reduced major adverse cardiovascular events by 25%.',
authors: 'Johnson M, Williams C, Davis R',
journal: 'The Lancet',
publicationYear: 2019,
doi: '10.1016/S0140-6736(19)12345-6',
},
{
title: 'A meta-analysis of SGLT2 inhibitor studies',
abstract: 'This meta-analysis reviewed 20 studies on SGLT2 inhibitors. We found consistent benefits across different populations. However, results were heterogeneous.',
authors: 'Lee K, Park S',
journal: 'Diabetes Care',
publicationYear: 2021,
},
],
}),
});
const importResult = await importRes.json();
console.log('✅ 文献导入成功');
console.log(' 导入数量:', importResult.data.importedCount);
console.log('');
// ==================== 测试6: 获取文献列表 ====================
console.log('📍 测试 6/7: 获取文献列表');
const litListRes = await fetch(`${BASE_URL}${API_PREFIX}/projects/${projectId}/literatures`);
const litListResult = await litListRes.json();
console.log('✅ 获取文献列表成功');
console.log(' 文献数量:', litListResult.data.literatures.length);
console.log(' 分页信息:', litListResult.data.pagination);
if (litListResult.data.literatures.length > 0) {
console.log(' 第一篇文献:');
console.log(' - 标题:', litListResult.data.literatures[0].title.substring(0, 50) + '...');
console.log(' - PMID:', litListResult.data.literatures[0].pmid);
literatureIds = litListResult.data.literatures.map((lit: any) => lit.id);
}
console.log('');
// ==================== 测试7: 更新项目 ====================
console.log('📍 测试 7/7: 更新项目');
const updateRes = await fetch(`${BASE_URL}${API_PREFIX}/projects/${projectId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
status: 'screening',
}),
});
const updateResult = await updateRes.json();
console.log('✅ 项目更新成功');
console.log(' 新状态:', updateResult.data.status);
console.log('');
// ==================== 测试总结 ====================
console.log('═'.repeat(60));
console.log('🎉 所有测试通过!');
console.log('═'.repeat(60));
console.log('📊 测试总结:');
console.log(' ✅ 健康检查');
console.log(' ✅ 创建筛选项目');
console.log(' ✅ 获取项目列表');
console.log(' ✅ 获取项目详情');
console.log(' ✅ 导入文献');
console.log(' ✅ 获取文献列表');
console.log(' ✅ 更新项目状态');
console.log('');
console.log('📝 创建的测试数据:');
console.log(` - 项目ID: ${projectId}`);
console.log(` - 文献数量: ${literatureIds.length}`);
console.log('');
console.log('🧹 清理提示: 如需删除测试数据,请执行:');
console.log(` DELETE http://localhost:3001/api/v1/asl/projects/${projectId}`);
console.log('');
} catch (error) {
console.error('❌ 测试失败:', error);
if (error instanceof Error) {
console.error('错误详情:', error.message);
}
}
}
// 执行测试
testAPI();