Files
AIclinicalresearch/docs/_templates/API设计-模板.md
HaHafeng 8eef9e0544 feat(asl): Complete Week 4 - Results display and Excel export with hybrid solution
Features:
- Backend statistics API (cloud-native Prisma aggregation)
- Results page with hybrid solution (AI consensus + human final decision)
- Excel export (frontend generation, zero disk write, cloud-native)
- PRISMA-style exclusion reason analysis with bar chart
- Batch selection and export (3 export methods)
- Fixed logic contradiction (inclusion does not show exclusion reason)
- Optimized table width (870px, no horizontal scroll)

Components:
- Backend: screeningController.ts - add getProjectStatistics API
- Frontend: ScreeningResults.tsx - complete results page (hybrid solution)
- Frontend: excelExport.ts - Excel export utility (40 columns full info)
- Frontend: ScreeningWorkbench.tsx - add navigation button
- Utils: get-test-projects.mjs - quick test tool

Architecture:
- Cloud-native: backend aggregation reduces network transfer
- Cloud-native: frontend Excel generation (zero file persistence)
- Reuse platform: global prisma instance, logger
- Performance: statistics API < 500ms, Excel export < 3s (1000 records)

Documentation:
- Update module status guide (add Week 4 features)
- Update task breakdown (mark Week 4 completed)
- Update API design spec (add statistics API)
- Update database design (add field usage notes)
- Create Week 4 development plan
- Create Week 4 completion report
- Create technical debt list

Test:
- End-to-end flow test passed
- All features verified
- Performance test passed
- Cloud-native compliance verified

Ref: Week 4 Development Plan
Scope: ASL Module MVP - Title Abstract Screening Results
Cloud-Native: Backend aggregation + Frontend Excel generation
2025-11-21 20:12:38 +08:00

8.5 KiB
Raw Blame History

[模块名称] - API设计

基础路径: /api/v1/模块名
端点数量: X个
认证要求: JWT Token
最后更新: YYYY-MM-DD


📋 API概览

端点 方法 说明 认证
/api/v1/xxx/resources GET 获取资源列表
/api/v1/xxx/resources/:id GET 获取资源详情
/api/v1/xxx/resources POST 创建资源
/api/v1/xxx/resources/:id PUT 更新资源
/api/v1/xxx/resources/:id DELETE 删除资源

📚 API详细设计

1. 获取资源列表

端点: GET /api/v1/xxx/resources

用途: 获取当前用户的资源列表(分页)

请求参数:

Query参数

{
  page?: number;        // 页码默认1
  pageSize?: number;    // 每页数量默认10最大100
  status?: string;      // 筛选状态active/inactive
  keyword?: string;     // 搜索关键词
  sortBy?: string;      // 排序字段createdAt/updatedAt
  sortOrder?: 'asc' | 'desc';  // 排序方向默认desc
}

请求示例:

GET /api/v1/xxx/resources?page=1&pageSize=10&status=active
Authorization: Bearer <token>

成功响应: 200 OK

{
  "success": true,
  "data": {
    "items": [
      {
        "id": 1,
        "userId": 123,
        "fieldName": "示例",
        "description": "描述",
        "status": "active",
        "createdAt": "2025-11-06T10:00:00.000Z",
        "updatedAt": "2025-11-06T10:00:00.000Z"
      }
    ],
    "pagination": {
      "page": 1,
      "pageSize": 10,
      "total": 100,
      "totalPages": 10
    }
  },
  "message": "获取成功"
}

错误响应:

// 401 Unauthorized
{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "未授权,请先登录"
  }
}

// 400 Bad Request
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "参数错误",
    "details": [
      { "field": "pageSize", "message": "最大不能超过100" }
    ]
  }
}

2. 获取资源详情

端点: GET /api/v1/xxx/resources/:id

用途: 获取指定资源的详细信息

路径参数:

  • id (必填): 资源ID

请求示例:

GET /api/v1/xxx/resources/123
Authorization: Bearer <token>

成功响应: 200 OK

{
  "success": true,
  "data": {
    "id": 123,
    "userId": 456,
    "fieldName": "示例",
    "description": "详细描述",
    "status": "active",
    "createdAt": "2025-11-06T10:00:00.000Z",
    "updatedAt": "2025-11-06T10:00:00.000Z",
    // 额外的关联数据
    "user": {
      "id": 456,
      "name": "用户名"
    }
  },
  "message": "获取成功"
}

错误响应:

// 404 Not Found
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "资源不存在"
  }
}

// 403 Forbidden
{
  "success": false,
  "error": {
    "code": "FORBIDDEN",
    "message": "无权访问此资源"
  }
}

3. 创建资源

端点: POST /api/v1/xxx/resources

用途: 创建新资源

请求体:

{
  "fieldName": "资源名称",      // 必填长度2-200
  "description": "描述",        // 可选最大5000字
  "status": "active"            // 可选默认active
}

验证规则:

  • fieldName: 必填2-200字符不能包含特殊字符
  • description: 可选最大5000字符
  • status: 可选有效值active, inactive

请求示例:

POST /api/v1/xxx/resources
Authorization: Bearer <token>
Content-Type: application/json

{
  "fieldName": "新资源",
  "description": "这是一个新资源"
}

成功响应: 201 Created

{
  "success": true,
  "data": {
    "id": 124,
    "userId": 456,
    "fieldName": "新资源",
    "description": "这是一个新资源",
    "status": "active",
    "createdAt": "2025-11-06T10:00:00.000Z",
    "updatedAt": "2025-11-06T10:00:00.000Z"
  },
  "message": "创建成功"
}

错误响应:

// 422 Unprocessable Entity
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "参数验证失败",
    "details": [
      { "field": "fieldName", "message": "字段名称不能为空" },
      { "field": "fieldName", "message": "字段名称长度必须在2-200之间" }
    ]
  }
}

// 409 Conflict
{
  "success": false,
  "error": {
    "code": "ALREADY_EXISTS",
    "message": "该资源已存在"
  }
}

4. 更新资源

端点: PUT /api/v1/xxx/resources/:id

用途: 更新指定资源(完整更新)

路径参数:

  • id (必填): 资源ID

请求体:

{
  "fieldName": "更新后的名称",
  "description": "更新后的描述",
  "status": "inactive"
}

请求示例:

PUT /api/v1/xxx/resources/123
Authorization: Bearer <token>
Content-Type: application/json

{
  "fieldName": "更新后的名称",
  "description": "更新后的描述"
}

成功响应: 200 OK

{
  "success": true,
  "data": {
    "id": 123,
    "fieldName": "更新后的名称",
    "description": "更新后的描述",
    "updatedAt": "2025-11-06T11:00:00.000Z"
  },
  "message": "更新成功"
}

错误响应:

// 404 Not Found
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "资源不存在"
  }
}

// 403 Forbidden
{
  "success": false,
  "error": {
    "code": "FORBIDDEN",
    "message": "无权修改此资源"
  }
}

5. 删除资源

端点: DELETE /api/v1/xxx/resources/:id

用途: 删除指定资源(软删除)

路径参数:

  • id (必填): 资源ID

请求示例:

DELETE /api/v1/xxx/resources/123
Authorization: Bearer <token>

成功响应: 200 OK

{
  "success": true,
  "data": null,
  "message": "删除成功"
}

错误响应:

// 404 Not Found
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "资源不存在"
  }
}

// 403 Forbidden
{
  "success": false,
  "error": {
    "code": "FORBIDDEN",
    "message": "无权删除此资源"
  }
}

// 409 Conflict
{
  "success": false,
  "error": {
    "code": "CANNOT_DELETE",
    "message": "该资源有关联数据,无法删除"
  }
}

🔐 认证与权限

认证方式

所有API都需要JWT Token认证

Authorization: Bearer <token>

权限检查

  • 用户只能访问自己的资源
  • ADMIN角色可以访问所有资源

📊 错误码汇总

错误码 HTTP状态 说明
UNAUTHORIZED 401 未授权
FORBIDDEN 403 无权限
NOT_FOUND 404 资源不存在
VALIDATION_ERROR 422 参数验证失败
ALREADY_EXISTS 409 资源已存在
INTERNAL_ERROR 500 服务器错误

🚀 使用示例

JavaScript/TypeScript

// 获取资源列表
const response = await fetch('/api/v1/xxx/resources?page=1&pageSize=10', {
  headers: {
    'Authorization': `Bearer ${token}`,
  },
});
const data = await response.json();

// 创建资源
const response = await fetch('/api/v1/xxx/resources', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    fieldName: '新资源',
    description: '描述',
  }),
});

cURL

# 获取列表
curl -X GET "http://localhost:3001/api/v1/xxx/resources?page=1&pageSize=10" \
  -H "Authorization: Bearer <token>"

# 创建资源
curl -X POST "http://localhost:3001/api/v1/xxx/resources" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"fieldName":"新资源","description":"描述"}'

⚠️ 注意事项

性能优化:

  • 列表接口必须支持分页默认pageSize=10最大100
  • 避免返回过多关联数据,按需加载
  • 大量数据导出使用异步任务

安全性:

  • 所有接口必须验证JWT Token
  • 必须检查资源归属(用户只能操作自己的资源)
  • 敏感字段不要返回(如密码)

向后兼容:

  • API变更使用版本号/api/v2
  • 不要删除已有字段只能标记为deprecated
  • 新增字段必须有默认值

🔗 相关文档

规范:

数据库:


最后更新: YYYY-MM-DD
维护人: 技术架构师