Align client surgery API with documented contract and support consumable codes.

Unify result 503 to RESULT_NOT_READY, restore resolve ASR failures as HTTP 422, accept label_id-only candidate_consumables, and document the changelog for integrators.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Kevin
2026-05-25 09:36:09 +08:00
parent aae0340a1b
commit 0917109d6a
10 changed files with 157 additions and 83 deletions

View File

@@ -1,5 +1,26 @@
# 手术室监控服务:客户端手术通信接口说明
## Changelog
对接方请按部署版本核对本节;**已发布路径与字段语义以正文为准**,本节仅记录相对上一版的客户端需改动点。
### 2026-05-25
**行为对齐(实现已与正文一致)**
| 接口 | 变更 | 客户端需改动 |
| ---- | ---- | ------------ |
| `GET /client/surgeries/{surgery_id}/result` | 无明细时的 `503` **统一**返回 `detail.code = RESULT_NOT_READY``detail.message` 仍为人可读原因) | 勿再依赖已废弃的 `SURGERY_NOT_STARTED``SURGERY_STARTING``SURGERY_IN_PROGRESS_NO_DETAILS``SURGERY_ENDED_NO_CONSUMPTION` 等细分码;判断 `503` 时用 `RESULT_NOT_READY` |
| `POST .../pending-confirmation/{confirmation_id}/resolve` | ASR/解析可重试失败(如 `VOICE_ASR_FAILED`)改回 **HTTP 422**,不再返回 `200` + `status: "failed"` | 删除对 `200`/`status=failed`/`error_code` 的处理;可重试失败按 `422` + `detail.code` 重录上传 |
| `POST /client/surgeries/start``candidate_consumables` | 新增:可仅传**产品编码**`label_id`,与 `consumable_classifier_labels.yaml` 一致) | 可传 `["14764-2-4"]``[{"消耗品编号":"14764-2-4"}]`;服务端解析为类名后参与推理,响应与其它字段不变 |
**未变更**
- 路由路径、HTTP 方法、`surgery_id` 约束、成功体字段名与 §5 各节描述一致。
- 可新增 `/internal/demo/...` 等内部接口,不影响本文档契约。
---
## 能力概览
| **能力** | **说明** |
@@ -165,8 +186,8 @@ flowchart LR
- 服务端会为 `camera_ids` 中的每个摄像头建立拉流与推理任务,只有在确认开录成功(如首帧就绪)后才返回 HTTP `200`
- `candidate_consumables` 为空时,服务端会展开为目录中的全部耗材名。
- `candidate_consumables` 为空时,服务端会展开为目录中的全部耗材名。
- 非空时,每项可为**耗材名称**或**产品编码**`label_id`);编码通过 `consumable_classifier_labels.yaml` 解析为类名。亦支持医院导出对象(见下表)。
**请求体JSON**
@@ -174,7 +195,16 @@ flowchart LR
| ----------------------- | ---------- | ------ | ----------------------------------- |
| `surgery_id` | `string` | 是 | 6 位数字 |
| `camera_ids` | `string[]` | 是 | 至少 1 个;必须与运维配置的摄像头 ID 完全一致,见第 2 节 |
| `candidate_consumables` | `string[]` | 否 | 非空时仅这些名称参与自动记账与待确认;缺省或 `[]` 时使用全部候选 |
| `candidate_consumables` | `string[]` 或对象数组 | 否 | 非空时仅这些名称/编码参与自动记账与待确认;缺省或 `[]` 时使用全部候选。字符串可为类名或 `label_id`;对象见下 |
**`candidate_consumables` 数组元素**
| **形式** | **示例** | **说明** |
| -------- | -------- | -------- |
| 名称字符串 | `"纱布"` | 与 yaml / 模型类名一致 |
| 编码字符串 | `"14764-2-4"` | 与 yaml 中 `label_id` 一致,服务端解析为类名 |
| 导出对象(名称) | `{"消耗品编号":"14764-2-4","名称":"一次性使用手术单"}` | 以 `名称`(或 `name`)为准 |
| 导出对象(仅编号) | `{"消耗品编号":"14764-2-4"}` | 按编号解析为类名 |
**响应体200**
@@ -202,6 +232,16 @@ flowchart LR
}
```
仅传产品编码时:
```
{
"surgery_id": "123456",
"camera_ids": ["or-cam-01"],
"candidate_consumables": ["14764-2-4", "8036-5-22"]
}
```
**响应示例200**
```
@@ -265,11 +305,11 @@ flowchart LR
**业务说明**
- 仅当存在至少一条消耗明细时返回 `200`
- 仅当存在至少一条消耗明细时返回 `200`
- 无明细(包括已归档但零消耗)、手术未开始、未成功开录或当前尚不可查时,返回 `503`
- 无明细(包括已归档但零消耗)、手术未开始、未成功开录或当前尚不可查时,返回 `503`
- 上述 `503` 场景的常见错误码为 `RESULT_NOT_READY`
- 上述 `503``detail.code`**`RESULT_NOT_READY`**`detail.message` 说明具体原因(如未开始、进行中尚无明细、已结束无消耗等)
**响应体200**
@@ -306,7 +346,7 @@ flowchart LR
| -------- | ------------------------------ |
| `200` | 至少有一条明细 |
| `422` | `surgery_id` 路径不符合约束 |
| `503` | `RESULT_NOT_READY`,当前无可用明细或不可查 |
| `503` | `detail.code``RESULT_NOT_READY``message` 为具体原因 |
**响应示例200**
@@ -433,7 +473,7 @@ flowchart LR
| `200` | 已受理并完成解析 |
| `404` | 确认项不存在或手术未活跃;例如 `CONFIRMATION_NOT_FOUND` |
| `409` | 当前确认项已处理过;例如 `CONFIRMATION_ALREADY_RESOLVED` |
| `422` | 空文件、非 `.wav``VOICE_AUDIO_INVALID`、ASR/解析失败等,具体错误码见响应 |
| `422` | 空文件、非 `.wav``VOICE_AUDIO_INVALID`**ASR/解析可重试失败**(如 `VOICE_ASR_FAILED``VOICE_TEXT_EMPTY``VOICE_PARSE_FAILED`)等,具体错误码见 `detail.code` |
| `503` | MinIO、百度等依赖不可用例如 `MINIO_NOT_CONFIGURED``MINIO_UPLOAD_FAILED``BAIDU_NOT_CONFIGURED` |
**cURL 示例**