# 房间座位数配置

本文定义房间创建和 App 修改房间资料时的座位数规则，以及后台“房间配置”的边界。

## 当前规则

- 固定候选座位数为 `10/15/20/25/30`。
- 后台只配置启用项和默认值，不允许新增候选数字。
- 默认配置为：启用 `10/15/20/25/30`，默认 `15`。
- 不使用 Redis 缓存。创建房间和修改房间资料是低频路径，`room-service` 每次直接读取 MySQL `room_seat_configs`，后台保存后立即生效。

## 数据表

`room_seat_configs` 是 App 级低频配置表：

| 字段 | 说明 |
| --- | --- |
| `app_code` | App 隔离键，当前默认 `lalu` |
| `allowed_seat_counts` | JSON 数组字符串，例如 `[10,15,20,25,30]` |
| `default_seat_count` | 创建房间不传 `seat_count` 或传 `0` 时使用 |
| `created_at_ms` / `updated_at_ms` | UTC epoch milliseconds |

`rooms.seat_count` 和 `room_list_entries.seat_count` 保存房间当前座位数；Room Cell 快照里的 `mic_seats` 是房间内麦位权威状态。

## 创建房间

`POST /api/v1/rooms/create` 的 `seat_count` 可省略：

- 不传或传 `0`：使用后台默认座位数，当前为 `15`。
- 传正数：必须命中后台启用座位数。
- 传负数或未启用数字：返回 `invalid_argument`。

创建成功会初始化对应数量的空麦位，并写入 `rooms`、snapshot、command log、outbox 和 `room_list_entries`。

## 修改房间资料

App 修改房间资料走：

```http
POST /api/v1/rooms/profile/update
```

请求：

```json
{
  "room_id": "lalu_xxx",
  "command_id": "cmd_profile_xxx",
  "room_name": "房间标题",
  "room_avatar": "https://cdn.example.com/room.png",
  "room_description": "简介",
  "seat_count": 20
}
```

规则：

- 只有当前在房间内的房主可以执行。
- `room_name`、`room_avatar`、`room_description`、`seat_count` 都是可选字段；只提交需要修改的字段。
- `seat_count` 必须是已启用正数，不能用 `0` 表示默认。
- 扩大座位数时追加连续空麦位。
- 缩小座位数时，高编号将被删除的麦位必须全部空闲、未锁、无发流会话；否则返回 `conflict`。
- 成功后返回 `result`、`room`、`seats`、`server_time_ms`，客户端可立即刷新房间信息和麦位列表。
- 成功命令写 `RoomProfileUpdated` outbox，并向 IM 发布 `room_profile_updated` 房间系统事件。

## 后台配置

后台“房间管理 / 房间配置”使用：

```http
GET /api/v1/admin/rooms/config
PUT /api/v1/admin/rooms/config
```

响应 DTO：

```json
{
  "candidateSeatCounts": [10, 15, 20, 25, 30],
  "allowedSeatCounts": [10, 15, 20, 25, 30],
  "defaultSeatCount": 15,
  "updatedAtMs": 1778000000000
}
```

权限：

| 权限码 | 说明 |
| --- | --- |
| `room-config:view` | 查看房间配置页面和接口 |
| `room-config:update` | 保存房间配置 |
