# 设备模块说明（`src/devices`）

## 1. 目标

- 提供“全局植入物目录”管理，供患者手术表单选择。
- 维护患者手术下的植入实例记录。
- 支持区分“阀门 / 管子”，并仅为阀门配置挡位列表。
- 支持管理员按医院、患者、状态和关键词分页查询患者植入实例。

## 2. 设备实例

`Device` 现在表示“患者某次手术下的植入设备实例”，不是独立库存主数据。

核心字段：

- `patientId`：归属患者
- `surgeryId`：归属手术，可为空
- `implantCatalogId`：型号字典 ID，可为空
- `implantModel` / `implantManufacturer` / `implantName`：历史快照
- `isValve`：是否为阀门
- `isPressureAdjustable`：是否可调压
- `isAbandoned`：是否弃用
- `currentPressure`：当前压力挡位标签
- `status`：设备状态

补充：

- `currentPressure` 不允许在创建/编辑设备实例时手工指定。
- 新植入设备默认以 `initialPressure`（或系统默认值 `0`）作为当前压力起点，后续只允许在调压任务完成时更新。
- 发布调压任务时不会立刻修改 `currentPressure`，只有任务完成后才会把目标挡位回写到设备。

## 3. 植入物目录

新增 `ImplantCatalog`：

- `modelCode`：型号编码，唯一
- `manufacturer`：厂商
- `name`：名称
- `isValve`：是否为阀门；关闭时表示管子或附件
- `pressureLevels`：可调压器械的挡位字符串标签列表
- `isPressureAdjustable`：后端按 `isValve` 自动派生
- `notes`：目录备注

可见性：

- 全部已登录 B 端角色都可读取，用于患者手术录入
- 仅 `SYSTEM_ADMIN` 可做目录 CRUD
- 目录是全局共享的，不按医院隔离

说明：

- 非阀门目录项不会保存压力挡位，前端也不会显示压力录入区域。
- 阀门目录项至少需要配置一个挡位。
- 挡位列表按字符串标签保存，例如 `["0.5", "1", "1.5"]` 或 `["10", "20", "30"]`。
- 保存前会自动标准化并去重排序，例如 `["01.0", "1.50", "1"]` 最终会整理为 `["1", "1.5"]`。

## 4. 接口

设备实例：

- `GET /b/devices`：分页查询设备列表
- `GET /b/devices/:id`：查询设备详情
- `POST /b/devices`：创建设备
- `PATCH /b/devices/:id`：更新设备
- `DELETE /b/devices/:id`：删除设备

型号字典：

- `GET /b/devices/catalogs`：查询植入物型号字典
- `POST /b/devices/catalogs`：新增植入物目录
- `PATCH /b/devices/catalogs/:id`：更新植入物目录
- `DELETE /b/devices/catalogs/:id`：删除植入物目录

## 5. 约束

- 设备必须绑定到一个患者。
- 删除已被任务明细引用的设备会返回 `409`。
- 删除已被患者手术引用的植入物目录会返回 `409`。
- 可调压植入物若配置了 `pressureLevels`，患者手术录入和任务调压时的压力值必须命中该挡位列表。
- 调压任务仅允许针对 `ACTIVE + isPressureAdjustable=true + isAbandoned=false` 的设备发布。
- `Device.currentPressure` 只允许由调压任务完成时更新，患者手术录入和设备实例编辑都不开放手工写入。
