# shared/api-contract Specification ## Purpose 定义服务机构端 C0 的统一响应契约与业务错误码,作为前后端接口交互的唯一约定。 ## Requirements ### Requirement: 统一响应结构 所有接口 MUST 返回统一响应结构 `{code, message, data, hint}`;`code=0` 成功,非 0 失败;硬锁拒绝时 `hint` MUST 提供用户可读的「怎么解」提示。 #### Scenario: 硬锁拒绝带 hint - **WHEN** 接口因硬锁拒绝(如无有效待遇) - **THEN** 返回非 0 code 与可读 message,且 `hint` 说明「先做什么才能做」 ### Requirement: 业务错误码 业务错误码 MUST 落地为 5 位码 [域码2][序3],并覆盖:1001 无有效待遇、1002 无有效计划、1003 无有效工单、1004 留痕不完整、1005 未质控、1006 资质不匹配(提示级)、2001 时间冲突(硬拒)、2002 项数不满足(提示)、3001 必拍未拍(硬拒)、3002 定位失败(非错误)、3003 扑空登记、3004 垫付不计费、4001 越权或自审自放行。 #### Scenario: 资质不匹配提示级 - **WHEN** 派单时护理员资质不匹配 - **THEN** 返回 1006,前端仅提示、允许继续(本期不拦截,二期改硬拒) ### Requirement: 老人档案接口 `GET /elder`、`POST /elder`、`GET /elder/:id`、`POST /elder/:id/status`、`GET /elder/:id/status/log`、`POST /elder/assess-evidence` MUST 存在,遵循统一响应 `{code,message,data,hint}`。 #### Scenario: 状态变更必填原因 - **WHEN** 调用 `/elder/:id/status` 且缺 change_reason - **THEN** 返回校验错误,拒绝变更 ### Requirement: 身份证服务端掩码 `/elder/list` MUST 返回掩码后的身份证(如 `5301**********1234`);明文仅在 `/elder/detail` 且 admin/qc 授权时返回,并 MUST 落审计。 #### Scenario: 列表掩码 - **WHEN** 调用 `/elder/list` - **THEN** id_card_no 返回掩码值,非明文 ### Requirement: 计划与工单接口 `POST /plan`、`POST /plan/change`、`GET /plan/:id`、`POST /plan/:id/confirm`、`GET /plan/by-elder/:elderId`、`POST /order/generate`、`POST /order/assign`、`POST /order/:id/reassign`、`GET /order/batch-recommend`、`GET /order/today`、`POST /order/:id/cancel`、`GET /order/:id`、`GET /elder-svc/:elderId`、`PUT /elder-svc/:elderId` MUST 存在,遵循统一响应。 #### Scenario: 时间冲突硬拒 - **WHEN** 派单时同护理员时间重叠 - **THEN** 返回 2001,拒绝保存 ### Requirement: 属地项数校验 制定计划时,昆明按 care_mode×care_level 校验项数(一级≥18/二级≥15/三级≥13,附加≤5),不满足返回 2002(提示级);州市只提示不拦。 #### Scenario: 昆明项数不满足 - **WHEN** 昆明一级护理计划项数 < 18 - **THEN** 返回 2002 提示,不硬拦 ### Requirement: 履约留痕接口 `POST /record/checkin`、`POST /record/item/save`、`POST /record/photo/upload`、`POST /record/checkout`、`POST /record/offline/sync`、`GET /record/:id`、`GET /record`、`GET /record/prepaid-list`、`POST /record/prepaid/carryover` MUST 存在,遵循统一响应。 #### Scenario: 签退必拍未拍硬拒 - **WHEN** 必拍项未拍照且未走拒拍出路时签退 - **THEN** 返回 3001,拒绝签退 #### Scenario: 签到服务器取时 - **WHEN** 签到 - **THEN** checkin_time 由服务端生成,客户端传入被忽略 ### Requirement: 异常接口 `POST /abnormal`、`GET /abnormal` MUST 存在,遵循统一响应。 #### Scenario: 扑空 - **WHEN** 护理员登记未遇(扑空) - **THEN** 工单转 not_met、到访时间/定位/原因必留、不产生 record ### Requirement: 垫付结转接口 `GET /record/prepaid-list` MUST 返回老人垫付台账(is_prepaid=1);`POST /record/prepaid/carryover` MUST 勾选垫付记录生成正式记录,原记录保留只读。 #### Scenario: 结转不改原始时间戳 - **WHEN** 结转垫付记录 - **THEN** 新记录签到时间/定位/照片仍为原始值,仅标记来源=垫付台账 ### Requirement: 质控接口 `GET /qc/pending/list`、`GET /qc/detail`、`POST /qc/pass`、`POST /qc/return`、`POST /qc/exception/link`、`POST /qc/correct`、`POST /qc/batch-pass` MUST 存在,遵循统一响应。 #### Scenario: 放行前自检 - **WHEN** 放行一条留痕 - **THEN** 按序校验四要素(1004)/必拍(3001)/幂等/非自审(4001),任一不过拒绝 #### Scenario: 退回必填原因 - **WHEN** 退回留痕缺 qc_note - **THEN** 拒绝 ### Requirement: 五类主动推送 `GET /qc/pending/list` MUST 聚合五类待办:异常待处理、逾期未做(>24h)、住院仍有派单、计划未制定(5 工作日)、留痕待放行,每类带消除条件。 #### Scenario: 消除条件 - **WHEN** 某类待办已处理 - **THEN** 该类从待办列表消除