Files
HaHafeng bbf98c4d5c fix(backend): Resolve PgBoss infinite loop issue and cleanup unused files
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
2026-01-27 18:16:22 +08:00

31 KiB
Raw Permalink Blame History

AI智能文献模块 - API设计规范

文档版本: v3.0
创建日期: 2025-10-29
维护者: AI智能文献开发团队
最后更新: 2025-11-23
更新说明: 新增全文复筛API5个核心接口


📋 文档说明

本文档描述AI智能文献模块的API设计规范包括接口定义、请求响应格式、错误处理等。

API基础信息:

  • Base URL: http://localhost:3001 (开发环境)
  • API前缀: /api/v1/asl
  • 协议: HTTP/HTTPS
  • 数据格式: JSON
  • 认证方式: JWT Token (测试阶段支持默认用户)

🔌 API设计原则

  1. RESTful设计: 遵循RESTful API设计规范
  2. 统一响应格式: { success: boolean, data?: any, error?: string }
  3. 分页支持: 列表接口支持分页参数
  4. 版本控制: API版本化管理 (/api/v1/...)
  5. 错误处理: 统一的HTTP状态码和错误消息
  6. 模块化路由: /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": "任务创建成功,正在后台处理"
  }
}

业务规则:

  1. 验证所有文献是否属于该项目
  2. 检查文献是否有可用的PDFpdfStatus === 'ready'
  3. 任务创建后立即返回,后台异步处理
  4. 如果部分文献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

生产环境(待实现)

认证流程:

  1. 用户登录获取JWT Token
  2. 请求头携带Token: Authorization: Bearer {token}
  3. 中间件验证Token并提取userId
  4. 控制器使用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集合

导入说明:

  1. 创建新的Collection: ASL API
  2. 设置环境变量:
    • base_url: http://localhost:3001
    • api_prefix: /api/v1/asl
  3. 导入下方接口

示例请求 (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)

  • 新增全文复筛管理API5个接口
    • 创建任务、获取进度、获取结果、人工审核、导出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个并行查询
  • 性能:<500ms199篇文献
  • 减少网络传输从MB级降到KB级

测试命令:

curl http://localhost:3001/api/v1/asl/projects/55941145-bba0-4b15-bda4-f0a398d78208/statistics
```---**文档版本:** v3.0  
**最后更新:** 2025-11-23Day 5: 全文复筛API  
**维护者:** AI智能文献开发团队**本次更新**
- ✅ 新增全文复筛管理API5个核心接口
- ✅ 详细的12字段评估文档
- ✅ 双模型对比和冲突检测说明
- ✅ Excel导出格式规范
- ✅ 完整的请求/响应示例---## 📚 相关文档- [数据库设计文档](./01-数据库设计.md)
- [API测试报告](../../../backend/ASL-API-测试报告.md)
- [Week 1完成报告](../05-开发记录/2025-11-18-Week1完成报告.md)