# 酒店价格日历「设置价格」——把已设库存的日期改回「不限库存」（写侧最终契约·已部署测试服验证）

> 变更类型：⚙️ 后端已就位（写侧补口，最终契约）
> 端类型：管理后台（资源·酒店·房型价格日历「设置价格」弹窗）
> 日期：2026-06-26 ｜ 工单/PR：#4392（#4396 加字段 + #4398 hotfix 真正落库）｜ 服务：hl-resource-service
> 关联：承接 25_ 那条「② 库存可空=不限」里挂起的「待部署测试服验证后单独 changelog 通知最终契约」。**现已部署测试服并 live 实测通过**。

---

## 背景（前端先前反馈的缺口）

「已设库存的日期」想改回「不限库存」时，前端传 `stock=null`，后端原逻辑是**「保留原值不覆盖」**（防误清），所以改不回不限。需要后端提供一个「显式清空库存」的开关。

## 最终契约（已就位）

**端点**：`PUT /admin/hotel/room-type/{roomTypeId}/prices`（`batchSetPrices`，设置/更新某房型某日期区间价格）

**请求体新增字段**：`PriceCalendarSetRequest.unlimitedStock`（`Boolean`，可选）

| 传值 | 后端行为 |
|------|----------|
| `unlimitedStock = true` | **显式把该区间每日 `stock` 清成 `NULL`（= 不限库存）**，不管同时传不传 `stock`、传多少都忽略。新建记录时也直接 `stock=null`。 |
| `unlimitedStock = false` 或**不传** | **维持原逻辑（行为完全不变）**：`stock` 非空才覆盖；`stock=null` 视为「不改」保留原值。老调用零影响。 |

**前端动作**：用户把一个「已设库存」的日期改回「不限」时，提交 `unlimitedStock=true`（`stock` 字段可不传或随意，会被忽略）。其余正常设库存的场景照旧（传 `stock` 数值、不传 `unlimitedStock`）。

**示例**

```jsonc
// 改回不限库存
PUT /admin/hotel/room-type/123/prices
{ "startDate": "2026-06-30", "endDate": "2026-06-30", "protocolPrice": 330.00, "unlimitedStock": true }
// → 该日 stock 变 NULL；GET 回读 stock=null（前端显示「不限制」）

// 正常设有限库存（老逻辑，不变）
PUT /admin/hotel/room-type/123/prices
{ "startDate": "2026-06-30", "endDate": "2026-06-30", "protocolPrice": 330.00, "stock": 15 }
// → 该日 stock=15
```

## 回读

`GET /admin/hotel/room-type/{roomTypeId}/prices?year&month` 的 `PriceCalendarDayVO.stock`：
- `stock = null` → 显示「不限制」（**别显示 0**）。
- `stock = 数值` → 显示该数值（有限库存）。

## 测试服验证（已 live 实测）

实测序列（同一房型同一日期，过网关 9443 + 真 admin token）：
1. `PUT stock=10` → 回读 `stock=10`
2. `PUT {stock:7, unlimitedStock:true}` → 回读 **`stock=null`**（= 不限；同时传的 7 被忽略，证明 `unlimitedStock` 优先且真落库）
3. `PUT stock=15` → 回读 `stock=15`（可从「不限」改回有限）
4. `DELETE` 该日 → 无残留记录

> 实现备注（不影响前端契约）：后端原 `setStock(null)+updateById` 因 MyBatis-Plus 默认跳过 null 字段而清不掉，#4398 改用 Mapper 显式 `set(stock,null)` 才真正落库——此坑由 API 实测发现，单测 mock 掩盖了它。

---

## 说明
- 本条只覆盖 #4392「写侧把库存改回不限」最终契约；读侧（库存 null 展示「不限」、协议价回显、配房扣的是 `stockUsed`/`available` 非总 `stock`）见 25_ 那条。
- 库存硬扣总开关 `hotel.stock.enabled` 已在测试服设为 `true`，扣减/释放已生效。
