feat: align surgery API with schemas and extend client tooling
- Refactor app API and schemas; adjust surgery pipeline, repository, and session manager. - Improve consumption TSV logging and consumable vision integration; trim voice resolution. - Add Baidu Face 1:N search script, .env.example entries, and client API integration doc. - Update demo client, staging checklist, surgery interface doc, and related tests; add sample face image. Made-with: Cursor
This commit is contained in:
213
docs/client-api-integration.md
Normal file
213
docs/client-api-integration.md
Normal file
@@ -0,0 +1,213 @@
|
||||
# 手术室监控服务 — 客户端 HTTP API 对接说明
|
||||
|
||||
本文档面向**集成我方 FastAPI 后端的客户系统**(HIS、手麻、护理工作站、自研终端等),说明如何通过 HTTP 调用完成「手术开始 / 结束」「耗材结果查询」「低置信度耗材语音确认」等能力。
|
||||
|
||||
> **说明**:仓库内 `scripts/demo_client/` 等演示页面仅用于**内部联调与测试**,不代表生产对接规范;生产环境请按本文档与 OpenAPI 契约自行实现客户端。
|
||||
|
||||
---
|
||||
|
||||
## 1. 服务与发现
|
||||
|
||||
|
||||
| 项目 | 说明 |
|
||||
| ------- | ------------------------------------------------------------- |
|
||||
| 默认监听 | 应用默认 `0.0.0.0:38080`(以实际部署为准,可能经反向代理改写路径或端口) |
|
||||
| 基础路径 | 路由**无全局前缀**;下文路径均为相对服务根路径 |
|
||||
| OpenAPI | 服务启动后可访问 `**/docs`(Swagger UI)**、`**/redoc`** 获取实时 Schema 与试调 |
|
||||
| 健康检查 | `GET /health`:探活与数据库连通性(降级时可能返回 503) |
|
||||
| 跨域 CORS | 仅当服务端开启演示用 CORS 配置时对浏览器页面生效;**服务端对接通常不受 CORS 限制** |
|
||||
|
||||
|
||||
认证方式以部署约定为准;当前公开路由未在文档层强制 API Key,若贵方环境增加了网关鉴权,请在请求头中按网关要求携带。
|
||||
|
||||
---
|
||||
|
||||
## 2. 客户端 API 一览(`/client/...`)
|
||||
|
||||
所有「客户集成」接口均位于 `**/client`** 命名空间下。
|
||||
|
||||
|
||||
| 方法 | 路径 | 摘要 |
|
||||
| ------ | ------------------------------------------------------------------------------- | ------------------------- |
|
||||
| `POST` | `/client/surgeries/start` | 开始手术:确认摄像头开录成功后返回 |
|
||||
| `POST` | `/client/surgeries/end` | 结束手术:确认停录成功后返回 |
|
||||
| `GET` | `/client/surgeries/{surgery_id}/result` | 查询该台手术的耗材明细与汇总 |
|
||||
| `GET` | `/client/surgeries/{surgery_id}/pending-confirmation` | 拉取一条待确认项(含 TTS 音频 Base64) |
|
||||
| `POST` | `/client/surgeries/{surgery_id}/pending-confirmation/{confirmation_id}/resolve` | 上传医生语音 WAV,完成确认或否认 |
|
||||
|
||||
|
||||
路径参数 `**surgery_id`**:固定 **6 位数字**(正则 `^\d{6}$`)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 端到端业务流程(推荐时序)
|
||||
|
||||
以下为客户系统与手术室监控服务之间的**推荐调用顺序**与并行关系。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as 客户系统
|
||||
participant API as 监控服务 API
|
||||
|
||||
Client->>API: POST /client/surgeries/start
|
||||
Note over Client,API: body: surgery_id, camera_ids, candidate_consumables
|
||||
API-->>Client: 200 accepted(开录已确认)
|
||||
|
||||
par 术中轮询
|
||||
loop 按需轮询
|
||||
Client->>API: GET .../result
|
||||
API-->>Client: 200 明细+汇总 或 503 RESULT_NOT_READY
|
||||
end
|
||||
loop 语音确认闭环(若启用)
|
||||
Client->>API: GET .../pending-confirmation
|
||||
API-->>Client: 200 待确认+MP3 或 404 无待确认
|
||||
opt 有待确认
|
||||
Client->>Client: 播放 prompt_audio_mp3_base64
|
||||
Client->>API: POST .../resolve(multipart audio)
|
||||
API-->>Client: 200 accepted
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Client->>API: POST /client/surgeries/end
|
||||
API-->>Client: 200 accepted(停录已确认)
|
||||
|
||||
Client->>API: GET .../result
|
||||
API-->>Client: 200 归档后持久化结果(若可查)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 3.1 手术生命周期(状态视角)
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[未开始] -->|POST start 成功| B[录制中 / 推理中]
|
||||
B -->|GET result 可 200| C[可查消耗]
|
||||
B -->|GET pending 可 200| D[有待确认]
|
||||
D -->|POST resolve| B
|
||||
B -->|POST end 成功| E[已结束]
|
||||
E -->|GET result| C
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 4. 接口说明与请求/响应要点
|
||||
|
||||
### 4.1 `POST /client/surgeries/start`
|
||||
|
||||
**Content-Type**:`application/json`
|
||||
|
||||
**请求体(摘要)**
|
||||
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| ----------------------- | -------- | ------------------------------------------------------------- |
|
||||
| `surgery_id` | string | 6 位数字手术号 |
|
||||
| `camera_ids` | string[] | 至少 1 个;需与贵方 RTSP/SDK 映射中的 **摄像头 ID** 一致 |
|
||||
| `candidate_consumables` | string[] | 可选;**本台手术可能用到的耗材名称清单**。服务端仅对该清单内耗材做自动记账与待确认追问;为空则只做拉流推理、不写入消耗 |
|
||||
|
||||
|
||||
**成功(200)**:`SurgeryApiResponse` — `status` 一般为 `accepted`,表示**服务端已确认开录完成**。
|
||||
|
||||
**失败**:常见 `**503 Service Unavailable`**,`detail` 内含业务 `code`(如录制子系统未就绪、开录未确认等)。开录/停录类错误会按服务端配置**自动重试**;仍失败则返回最后一次错误信息。
|
||||
|
||||
### 4.2 `POST /client/surgeries/end`
|
||||
|
||||
**Content-Type**:`application/json`
|
||||
|
||||
**请求体**:`{ "surgery_id": "123456" }`
|
||||
|
||||
**成功(200)**:停录已确认。
|
||||
|
||||
**失败**:`503` 同 start,表示未能在确认摄像头全部停录后完成请求。
|
||||
|
||||
### 4.3 `GET /client/surgeries/{surgery_id}/result`
|
||||
|
||||
**幂等只读**。术中返回当前内存已记账结果;结束后返回数据库持久化结果(以服务端实现为准)。
|
||||
|
||||
**成功(200)**:`SurgeryResultResponse`
|
||||
|
||||
- `details`:多行消耗明细,字段顺序为 `**item_id` → `item_name` → `qty` → `doctor_id` → `timestamp`**
|
||||
- `summary`:按 `item_id` 汇总的 `total_quantity`
|
||||
|
||||
`**503`**:`detail.code === "RESULT_NOT_READY"` — 尚无该手术可查询结果(未开始、未成功开录或暂无可返回数据)。
|
||||
|
||||
### 4.4 `GET /client/surgeries/{surgery_id}/pending-confirmation`
|
||||
|
||||
用于**低置信度识别**的人工确认闭环(需服务端启用语音确认及相关配置)。
|
||||
|
||||
**成功(200)**:包含 `confirmation_id`、`prompt_text`、候选项 `options`、`prompt_audio_mp3_base64`(与话术一致的 **MP3 标准 Base64**,无换行)、模型 Top1 等。
|
||||
|
||||
`**404`**:当前无待确认或手术未在进行(`NO_PENDING_CONFIRMATION`)。
|
||||
|
||||
`**422` / `503`**:话术为空、音频无效、ASR/TTS/MinIO/百度语音等异常时返回,详见响应 `detail.code`。
|
||||
|
||||
### 4.5 `POST /client/surgeries/{surgery_id}/pending-confirmation/{confirmation_id}/resolve`
|
||||
|
||||
**Content-Type**:`multipart/form-data`
|
||||
|
||||
**表单字段**
|
||||
|
||||
|
||||
| 字段 | 说明 |
|
||||
| ------- | -------------------------------------------------------- |
|
||||
| `audio` | 单个 `**.wav`** 文件;建议 16 kHz 单声道 PCM;其他格式服务端可能尝试 ffmpeg 转码 |
|
||||
|
||||
|
||||
**成功(200)**:`SurgeryPendingConfirmationResolveResponse` — 含 `resolved_label`、`rejected`、`asr_text`、`audio_object_key` 等。
|
||||
|
||||
**常见 HTTP 状态**:`404`(确认项不存在或已失效)、`409`(已处理)、`422`(音频/解析问题)、`503`(外部依赖故障)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 错误约定
|
||||
|
||||
FastAPI 对 `HTTPException` 的 JSON 外形一般为:
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": {
|
||||
"code": "业务错误码",
|
||||
"message": "人类可读说明",
|
||||
"surgery_id": "123456"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
部分错误可能在 `detail` 中附带额外字段(如重试剩余次数),请以实际响应与 OpenAPI 为准。
|
||||
|
||||
**校验错误(422)**:请求体或路径不符合 Pydantic 校验时,FastAPI 可能返回标准 `422` 验证错误结构(与上表「对象型 detail」不同),请客户端分别解析。
|
||||
|
||||
---
|
||||
|
||||
## 6. 与内部演示能力的关系(非客户必选)
|
||||
|
||||
以下路由用于**内部一键联调**,客户生产系统**无需依赖**:
|
||||
|
||||
|
||||
| 路径 | 说明 |
|
||||
| ------------------------------------------- | -------------------------------------------------- |
|
||||
| `GET /internal/demo/orchestrator-status` | 探测演示编排是否开启、RTSP 配置文件是否设置等 |
|
||||
| `POST /internal/demo/orchestrate-and-start` | 仅在服务端开启 `DEMO_ORCHESTRATOR_ENABLED` 时注册;用于演示环境串联开录 |
|
||||
|
||||
|
||||
客户正式对接应直接调用 `**/client/...`**,并在贵方环境中配置真实的 `camera_ids` 与视频后端映射。
|
||||
|
||||
---
|
||||
|
||||
## 7. 联调建议
|
||||
|
||||
1. 先调用 `**GET /health`** 确认服务与数据库可用。
|
||||
2. 用 `**POST /client/surgeries/start`** 验证 `camera_ids` 与现场 RTSP/SDK 配置一致,避免 503。
|
||||
3. `**candidate_consumables**` 与实际手术耗材名称尽量与院内目录或模型标签对齐,减少待确认次数。
|
||||
4. 结果查询 `**503**` 时建议**退避重试**(术中数据尚未就绪属正常现象)。
|
||||
5. 以 `**/docs`** 导出或对照契约测试,与贵方 CI 中的契约测试对齐。
|
||||
|
||||
---
|
||||
|
||||
## 8. 文档修订
|
||||
|
||||
接口行为以部署实例的 **OpenAPI(`/docs`)** 与代码为准;字段含义补充见仓库内 `app/schemas.py` 中各模型的 `description`。
|
||||
Reference in New Issue
Block a user