5.7 KiB
5.7 KiB
立项配置接口说明(Excel 导入导出版)
1. 概览
- 基础路径:
/api/v1/studies/{study_id}/setup-config - 数据作用域: 单项目唯一配置(
study_setup_configs.study_id唯一约束) - 存储格式: JSONB(字段结构与前端
SetupConfigDraft对齐) - 并发控制: 乐观锁(
expected_version) - 发布机制: 草稿/已发布(
publish_status) - 前端视图语义:
草稿视图: 当前草稿可编辑发布预览: 当前草稿只读预览(不直接读取published_data)published_data: 用于发布快照、差异比较与版本能力published_project_snapshot: 发布时的项目基础信息快照(用于“项目信息差异”判定)
2. 权限矩阵
GET /setup-config- 允许: 项目成员、管理员
PUT /setup-config- 允许: PM、ADMIN
- 限制: 项目锁定时返回
403
POST /setup-config/publish- 允许: PM、ADMIN
- 限制: 项目锁定时返回
403
GET /setup-config/export-excel- 允许: 项目成员、管理员
POST /setup-config/import-excel- 允许: PM、ADMIN
- 限制: 项目锁定时返回
403
3. 数据结构
3.1 请求体(保存)
{
"expected_version": 3,
"data": {
"projectMilestones": [
{
"id": "m1",
"name": "首例入组",
"planDate": "2026-03-01",
"owner": "项目经理",
"remark": "",
"status": "未开始"
}
],
"enrollmentPlan": {
"totalTarget": 100,
"startDate": "2026-02-01",
"endDate": "2026-12-31",
"monthlyGoalNote": "按月拆解",
"stageBreakdown": "阶段1/2/3"
},
"siteMilestones": [],
"siteEnrollmentPlans": [],
"monitoringStrategies": [],
"centerConfirm": []
}
}
3.2 响应体(GET/PUT/PUBLISH/IMPORT-EXCEL)
{
"id": "f0ac2fca-5fd3-470e-8e7e-2ded2b8f0f77",
"study_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"version": 6,
"publish_status": "PUBLISHED",
"data": {
"projectMilestones": [],
"enrollmentPlan": {
"totalTarget": 120,
"startDate": "2026-02-01",
"endDate": "2026-12-31",
"monthlyGoalNote": "",
"stageBreakdown": ""
},
"siteMilestones": [],
"siteEnrollmentPlans": [],
"monitoringStrategies": [],
"centerConfirm": []
},
"published_data": null,
"published_project_snapshot": {
"code": "DEMO-CTMS",
"name": "演示项目",
"project_full_name": "演示项目全称",
"sponsor": "",
"protocol_no": "",
"lead_unit": "",
"principal_investigator": "",
"main_pm": "",
"research_analysis": "",
"research_product": "",
"control_product": "",
"indication": "",
"research_population": "",
"research_design": "",
"plan_start_date": "2026-02-01",
"plan_end_date": "2026-12-31",
"planned_site_count": 12,
"planned_enrollment_count": 120,
"summary_note": "",
"objective_note": "",
"status": "DRAFT",
"visit_interval_days": null,
"visit_total": null,
"visit_window_start_offset": null,
"visit_window_end_offset": null
},
"saved_by": "11111111-1111-1111-1111-111111111111",
"saved_by_name": "System Admin",
"published_by": null,
"published_by_name": null,
"published_at": null,
"created_at": "2026-02-09T01:30:00.000000Z",
"updated_at": "2026-02-09T02:11:13.000000Z"
}
4. 接口定义
4.1 GET 获取配置
GET /api/v1/studies/{study_id}/setup-config
Authorization: Bearer <token>
4.2 PUT 保存配置(草稿)
PUT /api/v1/studies/{study_id}/setup-config
Authorization: Bearer <token>
Content-Type: application/json
4.3 POST 发布配置
POST /api/v1/studies/{study_id}/setup-config/publish
Authorization: Bearer <token>
Content-Type: application/json
4.4 GET 导出 Excel
GET /api/v1/studies/{study_id}/setup-config/export-excel
Authorization: Bearer <token>
说明:
- 返回
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet - 文件可直接作为导入模板继续回灌
4.5 POST 导入 Excel
POST /api/v1/studies/{study_id}/setup-config/import-excel
Authorization: Bearer <token>
Content-Type: multipart/form-data
表单字段:
file:.xlsx文件(必填)expected_version: 当前配置版本(可选,建议携带)
说明:
- 导入会覆盖当前草稿并自增版本。
- 写入审计事件:
IMPORT_SETUP_CONFIG_EXCEL。
5. 错误码与典型场景
400 BAD REQUEST- 上传文件非
.xlsx - Excel 解析失败
- 上传文件非
403 FORBIDDEN- 非 PM/ADMIN 导入/保存/发布
- 项目已锁定
404 NOT FOUND- study 不存在
409 CONFLICTexpected_version与服务端不一致
422 UNPROCESSABLE ENTITY- Excel 数据通过解析后,业务字段校验失败
6. 联调脚本(curl)
- 脚本路径:
docs/setup-config-curl-smoke.sh - 使用方式:
chmod +x docs/setup-config-curl-smoke.sh
BASE_URL=http://localhost \
EMAIL=admin@example.com \
PASSWORD=admin123 \
STUDY_ID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa \
bash docs/setup-config-curl-smoke.sh
7. Postman 联调集合
- Collection:
docs/postman/setup-config.postman_collection.json - Environment:
docs/postman/local.postman_environment.json
8. 后端烟雾测试(非 pytest)
docker compose up -d db backend
docker compose exec -T backend python scripts/smoke_setup_config.py
9. 监控埋点(4xx/5xx)
- 中间件统计以下接口:
GET /api/v1/studies/{study_id}/setup-configPUT /api/v1/studies/{study_id}/setup-configPOST /api/v1/studies/{study_id}/setup-config/publishGET /api/v1/studies/{study_id}/setup-config/export-excelPOST /api/v1/studies/{study_id}/setup-config/import-excel