hyapp-server/docs/机器人房间技术架构文档.md

230 lines
7.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 机器人房间技术架构文档
## 目标
机器人房间提供后台配置驱动的内部房间编排能力,支持机器人创建房间、进房、虚拟静音上麦、普通礼物展示、幸运礼物展示,并保证与真实钱包、真实幸运礼物、真实奖池、真实榜单和结算隔离。
## 模块边界
### admin-platform
- 提供机器人房间配置页面。
- 调用 admin-server HTTP 接口。
- 不直接访问业务服务。
### admin-server
- 暴露后台 HTTP API。
- 做权限、审计、参数校验和 DTO 转换。
- 通过 gRPC client 调用 room-service 和 robot-service。
- 通过 wallet-service gRPC 获取礼物配置。
- 只读用户库补齐机器人展示资料。
### robot-service
- 只拥有机器人账号池事实。
- 房间机器人池表:`hyapp_robot.robot_room_robots`
- 不处理进房、麦位、送礼和 IM。
### room-service
- 机器人房间配置 owner。
- 创建真实房间状态。
- 管理机器人房间配置表:`hyapp_room.room_robot_rooms`
- 执行机器人进房、虚拟静音上麦、送礼循环。
- 强校验机器人送礼仅限同房间机器人。
- 生成机器人幸运礼物展示事件。
### wallet-service
- 只通过 `ListGiftConfigs` 提供 active、区域可用的礼物展示快照。
- `RobotSendGift` 不调用 `DebitRobotGift`,不创建机器人钱包账户、交易、分录或 wallet outbox。
- 礼物目录在 room-service 按 App/区域短缓存;缓存只保存配置,不保存任何送礼事实。
### activity/statistics
- 消费房间送礼事件时跳过 `is_robot_gift`
- 机器人礼物不进入真实活动、榜单、任务、成长值和统计。
## 核心数据表
### `hyapp_robot.robot_room_robots`
机器人账号池事实表。
关键字段:
- `app_code`
- `room_scene`
- `user_id`
- `status`
- `last_used_at_ms`
- `used_count`
### `hyapp_room.room_robot_rooms`
机器人房间配置和占用事实表。
关键字段:
- `room_id`
- `room_short_id`
- `status`
- `owner_robot_user_id`
- `robot_user_ids_json`
- `gift_ids_json`
- `lucky_gift_ids_json`
- `normal_gift_interval_ms`
- `lucky_combo_min`
- `lucky_combo_max`
- `lucky_pause_min_ms`
- `lucky_pause_max_ms`
## 后台 API
后台 HTTP
- `GET /api/v1/admin/rooms/robot-rooms`
- `GET /api/v1/admin/rooms/robot-rooms/available-robots`
- `POST /api/v1/admin/rooms/robot-rooms`
- `POST /api/v1/admin/rooms/robot-rooms/{room_id}/start`
- `POST /api/v1/admin/rooms/robot-rooms/{room_id}/stop`
room-service gRPC
- `AdminListRobotRooms`
- `AdminFilterAvailableRoomRobots`
- `AdminCreateRobotRoom`
- `AdminSetRobotRoomStatus`
wallet-service gRPC
- `ListGiftConfigs`(只读)
## 创建流程
```mermaid
sequenceDiagram
participant Admin as admin-platform
participant AS as admin-server
participant RS as room-service
participant RB as robot-service
participant DB as MySQL
Admin->>AS: POST /admin/rooms/robot-rooms
AS->>RS: AdminCreateRobotRoom
RS->>DB: 查询 active 机器人房占用
RS->>RS: 从候选机器人随机抽取人数
RS->>RS: CreateRoom(robot_room=true)
RS->>RS: JoinRoom for robots
RS->>RS: RobotVirtualMicUp for robots
RS->>DB: 写 room_robot_rooms
RS->>RS: start runtime loops
RS-->>AS: AdminRobotRoom
AS-->>Admin: 机器人房间详情
```
## 运行时循环
room-service 启动时会扫描所有 active 机器人房间并恢复运行时循环。
每个 active 机器人房间:
- 为每个机器人启动普通礼物 loop。
- 为每个机器人启动幸运礼物 loop。
- stop 后取消对应房间的 context。
普通礼物 loop
1. 等待 `normal_gift_interval_ms`
2.`gift_ids_json` 随机选择礼物。
3. 从同房间其他机器人随机选择 1 个目标。
4. 调用 `RobotSendGift`
幸运礼物 loop
1.`lucky_gift_ids_json` 随机选择礼物。
2. 随机生成 `lucky_combo_min-lucky_combo_max` 连击次数。
3. 当前机器人向同房间其他机器人逐个送礼。
4. 使用 `synthetic_lucky_gift=true`,跳过真实抽奖。
5. 等待 `lucky_pause_min_ms-lucky_pause_max_ms` 后继续。
## 服务端安全校验
room-service 在机器人送礼时强校验:
- 专属机器人房必须带 `robot_room=true`;真人房机器人使用运行时机器人池校验,不把真人加入允许集合。
- sender 必须在该机器人房间 `robot_user_ids_json` 内。
- target 必须在同一机器人房间 `robot_user_ids_json` 内。
- sender 不能给真人送礼。
- 当前机器人礼物只允许单目标调用。
## 纯展示隔离
`RobotSendGift` 不进入通用 `sendGift/mutateRoom`,只执行:
1. 获得或续租 Redis owner lease并只读当前 Room Cell缺失时从 MySQL 只读恢复),校验 sender、target 和机器人池。
2. 从 wallet 礼物目录读取并短缓存名称、图标、动画、类型和展示价值。
3. 在内存构造 `RoomGiftSent`;幸运礼物额外构造 `RoomRobotLuckyGiftDrawn`
4. 经过 2 秒展示采样后best-effort 直发腾讯云 IM。
这条链路不写 `room_gift_operations``room_command_log``room_snapshots``room_outbox`、房间贡献统计、钱包账本或任何 outbox也不调用 RocketMQ producer。内存里的 `outbox.Record` 只复用 protobuf 信封结构,不是持久化 outbox。
## 幸运礼物隔离
机器人幸运礼物不会调用真实幸运抽奖链路。
room-service 只生成展示事件:
- `RoomRobotLuckyGiftDrawn`
- 对 IM 客户端映射为 `lucky_gift_drawn`
- 标记 `synthetic=true`
- 携带机器人房间、送礼人、收礼人、礼物和展示金额字段
真实奖池、真实流水、真实返奖、真实统计完全不写入。
## 排行榜与统计隔离
机器人展示用 `RoomGiftSent` 保留:
- `is_robot_gift`
- `synthetic_lucky_gift`
该事件不会进入 room outbox/MQ所以下游活动、CP、任务、成长和 statistics 根本不会收到机器人送礼事实;`is_robot_gift=true` 只供 IM 展示兼容。
机器人送礼同时不修改房间热度、礼物榜、麦位 `gift_value`、火箭燃料、周贡献或 Redis 跨房贡献榜。真人房机器人也遵守同一边界;历史 `RealRoomHeat` 参数仅用于区分参与者校验范围,不能授权真实贡献。
## 本地接口测试
测试工具:
```bash
go run ./tools/robot-room-api-test
```
默认依赖:
- admin-server: `http://127.0.0.1:13100/api/v1`
- MySQL: `127.0.0.1:23306`
- 管理员账号: `admin / admin123`
工具会:
1. 种 12 个房间机器人账号。
2. 种 2 个礼物配置和价格。
3. 登录 admin-server。
4. 调用可用机器人列表接口。
5. 创建机器人房间。
6. 查询 active 列表。
7. 停止、启动、再次停止机器人房间。
8. 校验 robot 展示前后 `room_gift_operations`、command log、snapshot、room outbox、房间统计行数不变`DebitRobotGift` 调用次数为 0。
## 运维注意事项
- 多实例 room-service 下,机器人房间 runtime 是进程内循环;重启会从 MySQL active 配置恢复。
- 机器人房间配置以 MySQL 为准。
- 同一机器人账号不能被多个 active 机器人房间占用。
- 停止机器人房间只停止 runtime不删除房间。
- 如果需要彻底释放机器人账号,应增加删除/归档能力后再开放。
- 腾讯云 IM 是唯一实时展示通道,失败不补写数据库或 MQ也不重试成业务事实丢失的动画/公屏不恢复,房间快照只保证真实热度、榜单和麦位值不被机器人展示污染。