Backend fixes: - Fix PgBoss task infinite loop on SAE (root cause: missing queue table constraints) - Add singletonKey to prevent duplicate job enqueueing - Add idempotency check in reviewWorker (skip completed tasks) - Add optimistic locking in reviewService (atomic status update) Frontend fixes: - Add isSubmitting state to prevent duplicate submissions in RVW Dashboard - Fix API baseURL in knowledgeBaseApi (relative path) Cleanup (removed): - Old frontend/ directory (migrated to frontend-v2) - python-microservice/ (unused, replaced by extraction_service) - Root package.json and node_modules (accidentally created) - redcap-docker-dev/ (external dependency) - Various temporary files and outdated docs in root New documentation: - docs/07-运维文档/01-PgBoss队列监控与维护.md - docs/07-运维文档/02-故障预防检查清单.md - docs/07-运维文档/03-数据库迁移注意事项.md Database fix applied to RDS: - Added PRIMARY KEY to platform_schema.queue - Added 3 missing foreign key constraints Tested: Local build passed, RDS constraints verified
31 KiB
AI智能文献模块 - API设计规范
文档版本: v3.0
创建日期: 2025-10-29
维护者: AI智能文献开发团队
最后更新: 2025-11-23
更新说明: 新增全文复筛API(5个核心接口)
📋 文档说明
本文档描述AI智能文献模块的API设计规范,包括接口定义、请求响应格式、错误处理等。
API基础信息:
- Base URL:
http://localhost:3001(开发环境) - API前缀:
/api/v1/asl - 协议: HTTP/HTTPS
- 数据格式: JSON
- 认证方式: JWT Token (测试阶段支持默认用户)
🔌 API设计原则
- RESTful设计: 遵循RESTful API设计规范
- 统一响应格式:
{ success: boolean, data?: any, error?: string } - 分页支持: 列表接口支持分页参数
- 版本控制: API版本化管理 (
/api/v1/...) - 错误处理: 统一的HTTP状态码和错误消息
- 模块化路由:
/api/v1/asl/...独立路由空间
📡 核心API接口
1. 项目管理 (Projects)
1.1 创建筛选项目
接口: POST /api/v1/asl/projects
认证: 需要 (测试阶段默认用户ID)
说明: 创建一个新的文献筛选项目
请求体:
{
"projectName": "SGLT2抑制剂系统综述",
"picoCriteria": {
"P": "2型糖尿病成人患者",
"I": "SGLT2抑制剂(empagliflozin、dapagliflozin等)",
"C": "安慰剂或常规降糖疗法",
"O": "心血管结局(MACE、心衰住院、心血管死亡)",
"S": "随机对照试验 (RCT)"
},
"inclusionCriteria": "英文文献,RCT研究,2010年后发表",
"exclusionCriteria": "病例报告,综述,动物实验",
"screeningConfig": {
"models": ["deepseek-chat", "qwen-max"],
"temperature": 0
}
}
响应示例:
{
"success": true,
"data": {
"id": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
"userId": "asl-test-user-001",
"projectName": "SGLT2抑制剂系统综述",
"picoCriteria": {
"population": "2型糖尿病成人患者",
"intervention": "SGLT2抑制剂",
"comparison": "安慰剂或常规降糖疗法",
"outcome": "心血管结局",
"studyDesign": "随机对照试验 (RCT)"
},
"inclusionCriteria": "英文文献,RCT研究,2010年后发表",
"exclusionCriteria": "病例报告,综述,动物实验",
"status": "draft",
"screeningConfig": {
"models": ["deepseek-chat", "qwen-max"],
"temperature": 0
},
"createdAt": "2025-11-18T07:30:00.000Z",
"updatedAt": "2025-11-18T07:30:00.000Z"
}
}
测试命令:
curl -X POST http://localhost:3001/api/v1/asl/projects \
-H "Content-Type: application/json" \
-d '{
"projectName": "测试项目",
"picoCriteria": {
"population": "成人患者",
"intervention": "药物A",
"comparison": "安慰剂",
"outcome": "主要结局",
"studyDesign": "RCT"
},
"inclusionCriteria": "英文文献",
"exclusionCriteria": "综述"
}'
1.2 获取项目列表
接口: GET /api/v1/asl/projects
认证: 需要
说明: 获取当前用户的所有筛选项目
查询参数: 无
响应示例:
{
"success": true,
"data": [
{
"id": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
"userId": "asl-test-user-001",
"projectName": "SGLT2抑制剂系统综述",
"picoCriteria": {...},
"status": "screening",
"createdAt": "2025-11-18T07:30:00.000Z",
"updatedAt": "2025-11-18T07:35:00.000Z",
"_count": {
"literatures": 3,
"screeningResults": 3
}
}
]
}
测试命令:
curl http://localhost:3001/api/v1/asl/projects
1.3 获取项目详情
接口: GET /api/v1/asl/projects/:projectId
认证: 需要
说明: 获取指定项目的详细信息
路径参数:
projectId: 项目ID (UUID)
响应示例:
{
"success": true,
"data": {
"id": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
"userId": "asl-test-user-001",
"projectName": "SGLT2抑制剂系统综述",
"picoCriteria": {
"population": "2型糖尿病成人患者",
"intervention": "SGLT2抑制剂",
"comparison": "安慰剂或常规降糖疗法",
"outcome": "心血管结局",
"studyDesign": "随机对照试验 (RCT)"
},
"inclusionCriteria": "英文文献,RCT研究,2010年后发表",
"exclusionCriteria": "病例报告,综述,动物实验",
"status": "screening",
"screeningConfig": {
"models": ["deepseek-chat", "qwen-max"],
"temperature": 0
},
"createdAt": "2025-11-18T07:30:00.000Z",
"updatedAt": "2025-11-18T07:35:00.000Z",
"_count": {
"literatures": 3,
"screeningResults": 3,
"screeningTasks": 1
}
}
}
测试命令:
curl http://localhost:3001/api/v1/asl/projects/{projectId}
1.4 更新项目
接口: PUT /api/v1/asl/projects/:projectId
认证: 需要
说明: 更新项目信息
路径参数:
projectId: 项目ID (UUID)
请求体(支持部分更新):
{
"projectName": "更新后的项目名称",
"status": "screening",
"inclusionCriteria": "更新后的纳入标准"
}
响应示例:
{
"success": true,
"data": {
"id": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
"projectName": "更新后的项目名称",
"status": "screening",
...
}
}
测试命令:
curl -X PUT http://localhost:3001/api/v1/asl/projects/{projectId} \
-H "Content-Type: application/json" \
-d '{"status": "screening"}'
1.5 删除项目
接口: DELETE /api/v1/asl/projects/:projectId
认证: 需要
说明: 删除项目及所有关联数据(级联删除)
路径参数:
projectId: 项目ID (UUID)
响应示例:
{
"success": true,
"message": "Project deleted successfully"
}
测试命令:
curl -X DELETE http://localhost:3001/api/v1/asl/projects/{projectId}
2. 文献管理 (Literatures)
2.1 导入文献(JSON格式)
接口: POST /api/v1/asl/literatures/import
认证: 需要
说明: 批量导入文献(JSON格式)
请求体:
{
"projectId": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
"literatures": [
{
"pmid": "12345678",
"title": "Efficacy of SGLT2 inhibitors in type 2 diabetes",
"abstract": "Background: SGLT2 inhibitors are a new class...",
"authors": "Smith J, Jones A, Brown B",
"journal": "New England Journal of Medicine",
"publicationYear": 2020,
"doi": "10.1056/NEJMoa1234567"
},
{
"title": "Another study on SGLT2 inhibitors",
"abstract": "Objective: To evaluate...",
"authors": "Johnson M",
"journal": "The Lancet",
"publicationYear": 2019
}
]
}
响应示例:
{
"success": true,
"data": {
"importedCount": 2
}
}
字段说明:
pmid: PubMed ID (可选)title: 文献标题 (必填)abstract: 摘要 (必填)authors: 作者 (可选)journal: 期刊 (可选)publicationYear: 发表年份 (可选)doi: DOI (可选)
测试命令:
curl -X POST http://localhost:3001/api/v1/asl/literatures/import \
-H "Content-Type: application/json" \
-d '{
"projectId": "{projectId}",
"literatures": [
{
"title": "测试文献",
"abstract": "这是测试摘要"
}
]
}'
2.2 导入文献(Excel文件)
接口: POST /api/v1/asl/literatures/import-excel
认证: 需要
说明: 从Excel文件批量导入文献
请求类型: multipart/form-data
表单字段:
file: Excel文件 (.xlsx)projectId: 项目ID
Excel格式要求:
| 列名(中英文均可) | 必填 | 说明 |
|---|---|---|
| PMID / pmid / PMID编号 | 否 | PubMed ID |
| Title / title / 标题 | 是 | 文献标题 |
| Abstract / abstract / 摘要 | 是 | 摘要 |
| Authors / authors / 作者 | 否 | 作者 |
| Journal / journal / 期刊 | 否 | 期刊名称 |
| Year / year / 年份 | 否 | 发表年份 |
| DOI / doi | 否 | DOI |
响应示例:
{
"success": true,
"data": {
"importedCount": 15,
"totalRows": 15
}
}
测试命令:
curl -X POST http://localhost:3001/api/v1/asl/literatures/import-excel \
-F "file=@literatures.xlsx" \
-F "projectId={projectId}"
2.3 获取文献列表
接口: GET /api/v1/asl/projects/:projectId/literatures
认证: 需要
说明: 获取项目的文献列表(支持分页)
路径参数:
projectId: 项目ID (UUID)
查询参数:
page: 页码(默认: 1)limit: 每页数量(默认: 50,最大: 100)
响应示例:
{
"success": true,
"data": {
"literatures": [
{
"id": "lit-uuid-001",
"projectId": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
"pmid": "12345678",
"title": "Efficacy of SGLT2 inhibitors...",
"abstract": "Background: SGLT2 inhibitors...",
"authors": "Smith J, Jones A",
"journal": "NEJM",
"publicationYear": 2020,
"doi": "10.1056/NEJMoa1234567",
"createdAt": "2025-11-18T07:32:00.000Z",
"screeningResults": [
{
"conflictStatus": "none",
"finalDecision": "include"
}
]
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 3,
"totalPages": 1
}
}
}
测试命令:
curl "http://localhost:3001/api/v1/asl/projects/{projectId}/literatures?page=1&limit=50"
2.4 删除文献
接口: DELETE /api/v1/asl/literatures/:literatureId
认证: 需要
说明: 删除指定文献(级联删除筛选结果)
路径参数:
literatureId: 文献ID (UUID)
响应示例:
{
"success": true,
"message": "Literature deleted successfully"
}
测试命令:
curl -X DELETE http://localhost:3001/api/v1/asl/literatures/{literatureId}
3. 筛选任务管理 (Screening Tasks)
注意: 以下接口为待实现功能(Week 2计划)
3.1 启动筛选任务
接口: POST /api/v1/asl/projects/:projectId/screening/start
认证: 需要
说明: 启动AI筛选任务(异步执行)
请求体:
{
"taskType": "title_abstract",
"models": ["deepseek-chat", "qwen-max"],
"concurrency": 3
}
响应示例:
{
"success": true,
"data": {
"taskId": "task-uuid-001",
"status": "running",
"totalItems": 100,
"startedAt": "2025-11-18T08:00:00.000Z"
}
}
3.2 获取筛选进度
接口: GET /api/v1/asl/tasks/:taskId/progress
认证: 需要
说明: 获取筛选任务进度
响应示例:
{
"success": true,
"data": {
"taskId": "task-uuid-001",
"status": "running",
"totalItems": 100,
"processedItems": 45,
"successItems": 40,
"failedItems": 2,
"conflictItems": 3,
"progress": 45,
"estimatedEndAt": "2025-11-18T08:15:00.000Z"
}
}
3.3 获取筛选结果
接口: GET /api/v1/asl/projects/:projectId/results
认证: 需要
说明: 获取筛选结果列表
查询参数:
page: 页码(默认: 1)limit: 每页数量(默认: 50)conflictOnly: 只显示冲突项(布尔值)finalDecision: 筛选决策(include / exclude / pending)
响应示例:
{
"success": true,
"data": {
"results": [
{
"id": "result-uuid-001",
"literatureId": "lit-uuid-001",
"literature": {
"title": "...",
"abstract": "..."
},
"dsConclusion": "include",
"qwenConclusion": "include",
"conflictStatus": "none",
"finalDecision": "include",
"createdAt": "2025-11-18T08:05:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 100,
"totalPages": 2
}
}
}
3.4 审核冲突文献
接口: POST /api/v1/asl/results/review
认证: 需要
说明: 批量审核冲突文献
请求体:
{
"projectId": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
"reviews": [
{
"resultId": "result-uuid-001",
"finalDecision": "include"
},
{
"resultId": "result-uuid-002",
"finalDecision": "exclude",
"exclusionReason": "不符合PICO标准中的干预措施"
}
]
}
响应示例:
{
"success": true,
"data": {
"reviewedCount": 2
}
}
4. 全文复筛管理 (Fulltext Screening)
状态: ✅ Day 5实现中(2025-11-23)
4.1 创建全文复筛任务
接口: POST /api/v1/asl/fulltext-screening/tasks
认证: 需要
说明: 创建全文复筛任务,对标题初筛通过的文献进行12字段评估
请求体:
{
"projectId": "proj-123",
"literatureIds": ["lit-001", "lit-002", "lit-003"],
"modelA": "deepseek-v3",
"modelB": "qwen-max",
"promptVersion": "v1.0.0"
}
字段说明:
projectId: 项目ID(必填)literatureIds: 待筛选文献ID列表(必填,需要是标题初筛通过的文献)modelA: 模型A名称(可选,默认: deepseek-v3)modelB: 模型B名称(可选,默认: qwen-max)promptVersion: Prompt版本(可选,默认: v1.0.0)
响应示例:
{
"success": true,
"data": {
"taskId": "fst-20251123-001",
"projectId": "proj-123",
"status": "pending",
"totalCount": 3,
"modelA": "deepseek-v3",
"modelB": "qwen-max",
"createdAt": "2025-11-23T10:00:00.000Z",
"message": "任务创建成功,正在后台处理"
}
}
业务规则:
- 验证所有文献是否属于该项目
- 检查文献是否有可用的PDF(
pdfStatus === 'ready') - 任务创建后立即返回,后台异步处理
- 如果部分文献PDF未就绪,仅处理PDF就绪的文献
错误响应:
{
"success": false,
"error": "部分文献PDF未就绪,无法开始全文复筛"
}
测试命令:
curl -X POST http://localhost:3001/api/v1/asl/fulltext-screening/tasks \
-H "Content-Type: application/json" \
-d '{
"projectId": "proj-123",
"literatureIds": ["lit-001", "lit-002"],
"modelA": "deepseek-v3",
"modelB": "qwen-max"
}'
4.2 获取任务进度
接口: GET /api/v1/asl/fulltext-screening/tasks/:taskId
认证: 需要
说明: 获取全文复筛任务的详细进度信息
路径参数:
taskId: 任务ID
响应示例:
{
"success": true,
"data": {
"taskId": "fst-20251123-001",
"projectId": "proj-123",
"status": "processing",
"progress": {
"totalCount": 30,
"processedCount": 15,
"successCount": 13,
"failedCount": 1,
"degradedCount": 1,
"pendingCount": 15,
"progressPercent": 50
},
"statistics": {
"totalTokens": 450000,
"totalCost": 2.25,
"avgTimePerLit": 18500
},
"time": {
"startedAt": "2025-11-23T10:00:00.000Z",
"estimatedEndAt": "2025-11-23T10:12:30.000Z",
"elapsedSeconds": 270
},
"models": {
"modelA": "deepseek-v3",
"modelB": "qwen-max"
},
"updatedAt": "2025-11-23T10:04:30.000Z"
}
}
字段说明:
status: 任务状态pending: 待处理processing: 处理中completed: 已完成failed: 失败cancelled: 已取消
successCount: 双模型都成功的文献数degradedCount: 仅一个模型成功的文献数(降级模式)failedCount: 双模型都失败的文献数totalCost: 累计成本(单位:元)
测试命令:
curl http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001
4.3 获取任务结果
接口: GET /api/v1/asl/fulltext-screening/tasks/:taskId/results
认证: 需要
说明: 获取全文复筛任务的详细结果,支持筛选和分页
路径参数:
taskId: 任务ID
查询参数:
filter: 结果筛选(可选)all: 全部(默认)conflict: 仅冲突项pending: 待审核reviewed: 已审核
page: 页码(默认: 1)pageSize: 每页数量(默认: 20,最大: 100)sortBy: 排序字段(可选:priority,createdAt)sortOrder: 排序方向(asc|desc,默认:desc)
响应示例:
{
"success": true,
"data": {
"taskId": "fst-20251123-001",
"total": 30,
"filtered": 3,
"results": [
{
"resultId": "fsr-001",
"literatureId": "lit-001",
"literature": {
"pmid": "12345678",
"title": "Effect of SGLT2 inhibitors on cardiovascular outcomes",
"authors": "Smith JA, et al.",
"journal": "Lancet",
"year": 2023,
"doi": "10.1016/..."
},
"modelAResult": {
"modelName": "deepseek-v3",
"status": "success",
"fields": {
"field1_source": {
"assessment": "完整",
"evidence": "第一作者Smith JA, Lancet 2023",
"location": "第1页",
"confidence": 0.98
},
"field2_studyType": {
"assessment": "完整",
"evidence": "多中心随机对照试验",
"location": "Methods第2页",
"confidence": 0.95
},
"field5_population": {
"assessment": "完整",
"evidence": "纳入500例2型糖尿病患者,年龄58±12岁",
"location": "Methods第3页",
"confidence": 0.92
},
"field9_outcomes": {
"assessment": "完整",
"evidence": "主要结局eGFR变化:-15.2±3.5 ml/min vs -8.1±2.9 ml/min",
"location": "Results第5页表2",
"confidence": 0.96
}
},
"overall": {
"decision": "include",
"reason": "12字段完整,关键数据可提取",
"dataQuality": "high",
"confidence": 0.94
},
"tokens": 15000,
"cost": 0.015
},
"modelBResult": {
"modelName": "qwen-max",
"status": "success",
"fields": { /* 同上结构 */ },
"overall": {
"decision": "include",
"confidence": 0.92
},
"tokens": 15200,
"cost": 0.061
},
"validation": {
"medicalLogicIssues": [],
"evidenceChainIssues": []
},
"conflict": {
"isConflict": false,
"severity": "none",
"conflictFields": [],
"overallConflict": false
},
"review": {
"finalDecision": null,
"reviewedBy": null,
"reviewedAt": null,
"reviewNotes": null,
"priority": 50
},
"processing": {
"isDegraded": false,
"degradedModel": null,
"processedAt": "2025-11-23T10:02:15.000Z"
}
},
{
"resultId": "fsr-002",
"literatureId": "lit-005",
"literature": { /* ... */ },
"modelAResult": {
"modelName": "deepseek-v3",
"status": "success",
"fields": {
"field9_outcomes": {
"assessment": "缺失",
"evidence": "未报告具体数值,仅有P值",
"location": "Results第4页",
"confidence": 0.88
}
},
"overall": {
"decision": "exclude",
"reason": "关键字段field9数据不完整,无法Meta分析",
"confidence": 0.85
}
},
"modelBResult": {
"overall": {
"decision": "include",
"reason": "虽然主要结局在Discussion报告,但数据完整"
}
},
"conflict": {
"isConflict": true,
"severity": "high",
"conflictFields": ["field9"],
"overallConflict": true,
"details": {
"field9": {
"modelA": "缺失",
"modelB": "完整",
"importance": "critical"
}
}
},
"review": {
"finalDecision": null,
"priority": 95
}
}
],
"pagination": {
"page": 1,
"pageSize": 20,
"totalPages": 2
},
"summary": {
"totalResults": 30,
"conflictCount": 3,
"pendingReview": 3,
"reviewed": 27,
"avgPriority": 62
}
}
}
12字段说明:
field1_source: 文献来源(作者、期刊、年份等)field2_studyType: 研究类型(RCT、队列研究等)field3_studyDesign: 研究设计细节field4_diagnosis: 疾病诊断标准field5_population: 人群特征(样本量、基线等)⭐field6_baseline: 基线数据⭐field7_intervention: 干预措施⭐field8_control: 对照措施field9_outcomes: 结局指标⭐⭐⭐ 最关键field10_statistics: 统计方法field11_quality: 质量评价(随机化、盲法等)⭐⭐field12_other: 其他信息
测试命令:
# 获取所有结果
curl "http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001/results"
# 仅获取冲突项
curl "http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001/results?filter=conflict"
# 分页查询
curl "http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001/results?page=2&pageSize=10"
4.4 人工审核决策
接口: PUT /api/v1/asl/fulltext-screening/results/:resultId/decision
认证: 需要
说明: 对单个全文复筛结果进行人工审核决策
路径参数:
resultId: 结果ID
请求体:
{
"finalDecision": "exclude",
"exclusionReason": "关键字段field9(结局指标)数据不完整",
"reviewNotes": "虽然报告了P<0.05,但缺少均值±SD,无法用于Meta分析"
}
字段说明:
finalDecision: 最终决策(必填)include: 纳入exclude: 排除
exclusionReason: 排除原因(finalDecision === 'exclude'时必填)reviewNotes: 审核备注(可选)
响应示例:
{
"success": true,
"data": {
"resultId": "fsr-002",
"finalDecision": "exclude",
"exclusionReason": "关键字段field9(结局指标)数据不完整",
"reviewedBy": "user-001",
"reviewedAt": "2025-11-23T10:30:00.000Z"
}
}
测试命令:
curl -X PUT http://localhost:3001/api/v1/asl/fulltext-screening/results/fsr-002/decision \
-H "Content-Type: application/json" \
-d '{
"finalDecision": "exclude",
"exclusionReason": "结局指标数据不完整",
"reviewNotes": "缺少均值和标准差"
}'
4.5 导出Excel
接口: GET /api/v1/asl/fulltext-screening/tasks/:taskId/export
认证: 需要
说明: 导出全文复筛结果为Excel文件(3个Sheet)
路径参数:
taskId: 任务ID
响应:
- Content-Type:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet - Content-Disposition:
attachment; filename="fulltext_screening_results_{taskId}.xlsx"
Excel结构:
Sheet 1: 纳入文献列表
| 列名 | 说明 |
|---|---|
| 序号 | 1, 2, 3... |
| PMID | PubMed ID |
| 文献来源 | 第一作者+年份 |
| 标题 | 文献标题 |
| 期刊 | 期刊名称 |
| 年份 | 发表年份 |
| DOI | DOI编号 |
| 最终决策 | 纳入 |
| 数据质量 | 高/中/低 |
| 可提取性 | 可提取/部分可提取/不可提取 |
| 模型一致性 | 一致/不一致 |
| 是否人工审核 | 是/否 |
Sheet 2: 排除文献列表
| 列名 | 说明 |
|---|---|
| 序号 | 1, 2, 3... |
| PMID | PubMed ID |
| 文献来源 | 第一作者+年份 |
| 标题 | 文献标题 |
| 排除原因 | 详细排除原因 |
| 排除字段 | field5, field9等 |
| 是否冲突 | 是/否 |
| 审核人 | 用户ID |
| 审核时间 | 2025-11-23 10:30 |
Sheet 3: PRISMA统计
| 统计项 | 数量 | 百分比 |
|---|---|---|
| 全文复筛总数 | 30 | 100% |
| 最终纳入 | 18 | 60% |
| 最终排除 | 12 | 40% |
| - 结局指标缺失/不完整 | 5 | 16.7% |
| - 人群特征不符 | 3 | 10% |
| - 干预措施不明确 | 2 | 6.7% |
| - 研究质量问题 | 1 | 3.3% |
| - 其他原因 | 1 | 3.3% |
| 模型冲突数 | 3 | 10% |
| 人工审核数 | 3 | 10% |
成本统计(额外Sheet):
| 项目 | 值 |
|---|---|
| 总Token数 | 450,000 |
| 总成本(元) | ¥2.25 |
| 平均成本/篇 | ¥0.075 |
| 模型组合 | DeepSeek-V3 + Qwen-Max |
| 处理时间 | 8分30秒 |
测试命令:
curl -O -J http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001/export
📋 响应格式规范
1. 成功响应
格式:
{
"success": true,
"data": {
// 响应数据
}
}
HTTP状态码:
200- 成功(GET、PUT)201- 创建成功(POST)
2. 错误响应
格式:
{
"success": false,
"error": "错误描述"
}
或(详细错误):
{
"error": "Missing required fields"
}
常见HTTP状态码:
400- 请求参数错误401- 未授权403- 无权限404- 资源不存在500- 服务器内部错误
错误示例:
// 400 - 参数错误
{
"error": "Missing required fields"
}
// 404 - 资源不存在
{
"error": "Project not found"
}
// 500 - 服务器错误
{
"error": "Failed to create project"
}
3. 分页响应
格式:
{
"success": true,
"data": {
"items": [...], // 或 literatures、results 等
"pagination": {
"page": 1,
"limit": 50,
"total": 150,
"totalPages": 3
}
}
}
分页参数:
page: 当前页码(从1开始)limit: 每页数量total: 总记录数totalPages: 总页数
🔐 认证授权
当前状态(测试模式)
测试用户:
- 用户ID:
asl-test-user-001 - 邮箱:
asl-test@example.com - 权限: 完全访问
实现方式:
- 优先从JWT中获取
userId - JWT不存在时使用默认测试用户ID
生产环境(待实现)
认证流程:
- 用户登录获取JWT Token
- 请求头携带Token:
Authorization: Bearer {token} - 中间件验证Token并提取
userId - 控制器使用
userId查询用户数据
中间件示例:
// 待实现
fastify.addHook('preHandler', async (request, reply) => {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) {
return reply.status(401).send({ error: 'Unauthorized' });
}
const userId = await verifyJWT(token);
(request as any).userId = userId;
});
🧪 API测试
快速测试脚本
测试所有API:
cd AIclinicalresearch/backend
npx tsx scripts/test-asl-api.ts
测试结果:
🚀 开始测试 ASL 模块 API...
📍 测试 1/7: 健康检查 ✅
📍 测试 2/7: 创建筛选项目 ✅
📍 测试 3/7: 获取项目列表 ✅
📍 测试 4/7: 获取项目详情 ✅
📍 测试 5/7: 导入文献 ✅
📍 测试 6/7: 获取文献列表 ✅
📍 测试 7/7: 更新项目 ✅
═══════════════════════════════════
🎉 所有测试通过!(7/7 - 100%)
═══════════════════════════════════
Postman集合
导入说明:
- 创建新的Collection:
ASL API - 设置环境变量:
base_url:http://localhost:3001api_prefix:/api/v1/asl
- 导入下方接口
示例请求 (Postman):
POST {{base_url}}{{api_prefix}}/projects
Headers:
Content-Type: application/json
Body (raw JSON):
{
"projectName": "测试项目",
"picoCriteria": {...},
"inclusionCriteria": "英文文献",
"exclusionCriteria": "综述"
}
📊 性能指标
响应时间目标
| 接口类型 | 目标响应时间 | 说明 |
|---|---|---|
| 单个查询 | < 100ms | 项目详情、文献详情 |
| 列表查询 | < 200ms | 项目列表、文献列表 |
| 创建/更新 | < 300ms | 创建项目、更新项目 |
| 批量导入 | < 2s | 导入100篇文献 |
| LLM筛选 | 4-6s/篇 | 双模型并行筛选 |
并发能力
- API服务器: 支持100+并发请求
- LLM筛选: 并发数为3(可配置)
- 数据库连接池: 17个连接
🔄 版本历史
v3.0 (2025-11-23)
- ✅ 新增全文复筛管理API(5个接口)
- 创建任务、获取进度、获取结果、人工审核、导出Excel
- ✅ 支持12字段详细评估
- ✅ 支持双模型对比和冲突检测
- ✅ 完整的Excel导出功能(3 Sheets)
- ✅ 调整文档结构(5大模块)
v2.1 (2025-11-21)
- ✅ 新增统计API接口
- ✅ 更新PICOS格式说明
- ✅ 添加云原生架构标注
v2.0 (2025-11-18)
- ✅ 实现10个核心API端点
- ✅ 完成项目管理功能
- ✅ 完成文献管理功能
- ✅ 添加测试脚本和文档
- ✅ 所有接口测试通过
v1.0 (2025-10-29)
- 初始API设计规范
- 定义接口结构
⏳ 后续规划
Week 2
- 实现筛选任务API (3个接口)
- 实现冲突审核API (2个接口)
- 添加SSE进度推送
- 集成异步任务队列
Week 3-4
- 添加JWT认证中间件
- 实现权限控制
- 添加API限流
- 完善错误处理
5. 统计API (Statistics)
5.1 获取项目统计数据(云原生:后端聚合)
接口: GET /api/v1/asl/projects/:projectId/statistics
认证: 需要
说明: 获取项目的筛选统计数据(总数、纳入率、排除率、排除原因分析等)
路径参数:
projectId: 项目ID
响应示例:
{
"success": true,
"data": {
"total": 199,
"included": 85,
"excluded": 90,
"pending": 24,
"conflict": 24,
"reviewed": 175,
"exclusionReasons": {
"P不匹配(人群)": 40,
"I不匹配(干预)": 25,
"S不匹配(研究设计)": 15,
"其他原因": 10
},
"includedRate": "42.7",
"excludedRate": "45.2",
"pendingRate": "12.1"
}
}
特点:
- ✅ 云原生:后端Prisma聚合查询(6个并行查询)
- ✅ 性能:<500ms(199篇文献)
- ✅ 减少网络传输:从MB级降到KB级
测试命令:
curl http://localhost:3001/api/v1/asl/projects/55941145-bba0-4b15-bda4-f0a398d78208/statistics
```---**文档版本:** v3.0
**最后更新:** 2025-11-23(Day 5: 全文复筛API)
**维护者:** AI智能文献开发团队**本次更新**:
- ✅ 新增全文复筛管理API(5个核心接口)
- ✅ 详细的12字段评估文档
- ✅ 双模型对比和冲突检测说明
- ✅ Excel导出格式规范
- ✅ 完整的请求/响应示例---## 📚 相关文档- [数据库设计文档](./01-数据库设计.md)
- [API测试报告](../../../backend/ASL-API-测试报告.md)
- [Week 1完成报告](../05-开发记录/2025-11-18-Week1完成报告.md)