# Voice Room Feature Inventory

本文档按当前仓库代码和已有技术文档梳理语音房完整功能清单，并标记当前完成度。状态只表达本仓库服务端能力，不代表客户端、腾讯云控制台和真实环境已经完成联调。

状态定义：

| Status | Meaning |
| --- | --- |
| `DONE` | 代码、配置或测试已存在，服务端能力基本闭环 |
| `PARTIAL` | 主链路或骨架存在，但缺少权限、管理、真实联调、客户端或补偿细节 |
| `TODO` | 仅有规划或尚未实现 |

## Current Architecture Boundary

| Boundary | Current Rule | Status |
| --- | --- | --- |
| HTTP 入口 | `gateway-service` 只做鉴权、协议转换、腾讯 IM/RTC token 签发和内部 gRPC 编排 | `DONE` |
| 房间状态 owner | `room-service` 持有 Room Cell、presence、麦位、禁言、踢人、快照、command log、outbox、Redis lease | `DONE` |
| 长连接和房间消息 | 腾讯云 IM 负责客户端长连接、群消息、公屏、离线/漫游和全球接入 | `DONE` |
| 真实语音 | 腾讯云 RTC 负责音频频道和音频流 | `PARTIAL` |
| 账务 | `wallet-service` 负责扣费语义，`room-service.SendGift` 扣费成功后才落房间表现 | `DONE` |
| 活动 | `activity-service` 只通过 room outbox 异步接收房间事件，不侵入 Room Cell 主链路 | `PARTIAL` |
| 用户资料 | `user-service` 负责用户主数据、短号、头像、国家等资料 | `DONE` |

## Foundation And Identity

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| 三方登录即注册 | `DONE` | gateway `/api/v1/auth/third-party/login`，user-service 事务创建用户、短号、三方身份、session，并接入 Firebase Auth verifier | 真实 Firebase project id、Google sign_in_provider 和客户端 ID token 联调；直接 provider 后续再逐个接入 |
| 密码登录和设置密码 | `DONE` | gateway/user-service 已有 password login/set | 生产密码策略和风控可继续增强 |
| access token 解析 `user_id` | `DONE` | gateway 从 JWT context 获取 `user_id`，房间命令 actor 来自 token | 多端设备策略仍需产品确认 |
| 默认短号和当前展示号 | `DONE` | user-service 生成默认短号，支持 display id 查询和修改 | 房间内资料缓存和 IM 展示资料同步仍需做 |
| 靓号租约 | `DONE` | pretty display id lease 表和接口存在 | 购买/支付入口未形成完整商业闭环 |
| 用户资料更新 | `DONE` | 支持 username/avatar/birth，国家独立接口 | 房间内资料变更实时刷新未做 |
| 国家修改和审计 | `DONE` | `ChangeUserCountry`、`user_country_change_logs`、冷却期 | 新增“区域”能力尚未实现 |
| 区域功能 | `TODO` | 已有需求文档 `docs/用户区域与国家开发.md` | regions/region_countries 表、管理端、注册归属、历史回填 |

## Gateway HTTP Surface

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| `/api/v1` envelope | `DONE` | gateway 业务响应使用 `{code,message,request_id,data}` | healthcheck 不套 envelope，保持现状 |
| 房间命令 HTTP 路由 | `DONE` | create/join/leave/close-as-leave/mic/mute/kick/sendGift 路由存在 | OpenAPI 需持续同步最新字段 |
| 房间详情页聚合接口 | `DONE` | `/rooms/{room_id}/detail` 返回 room/viewer/seats/rank_top/online_count/permissions/im/rtc | 头像框、座驾、VIP、等级等展示 read model 仍需接入 |
| 房间在线用户分页 | `DONE` | `/rooms/{room_id}/online-users` 读取 `room_user_presence` 分页投影 | 大页码仍是 offset 分页，超大房间可升级 cursor |
| 房间礼物面板 | `DONE` | `/rooms/{room_id}/gift-panel` 聚合 COIN 余额、收礼人、礼物 tabs、礼物配置和数量预设 | all_mic/all_room/couple 账务拆单策略未开放 |
| 房间命令 `command_id` | `DONE` | 写命令使用前端按用户动作生成的 `command_id` 做服务端幂等 | 同一次用户动作的 HTTP 重试必须复用 command_id |
| `request_id` 追踪 | `DONE` | gateway 生成 request_id 并透传 RequestMeta，不作为幂等键 | 日志和链路追踪系统可继续完善 |
| IM UserSig 签发 | `DONE` | `/api/v1/im/usersig` 使用 access token `user_id` 签发 | 真实腾讯云应用联调和告警 |
| RTC token 签发 | `DONE` | `JoinRoom` 响应内嵌首屏 RTC token；`/api/v1/rtc/token` 保留为过期刷新和补偿入口 | 客户端 TRTC SDK 实际进房联调 |
| 腾讯 IM 回调入口 | `DONE` | `/api/v1/tencent-im/callback` 支持入群前和发言前守卫 | 腾讯云控制台回调 URL 和鉴权参数真实配置 |
| 管理端 HTTP API | `TODO` | 当前没有完整 admin auth/API | 房间管理、区域管理、礼物配置、活动配置、封禁等后台接口 |

## Room Lifecycle

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| 创建房间 | `DONE` | `CreateRoom` 校验 room_id、actor、mode；`seat_count=0` 使用后台默认值，正数必须命中后台启用配置；同步确保腾讯 IM 房间群存在后再写 meta/command/outbox/snapshot 并返回 `im_group_id` | 腾讯云真实错误码覆盖和已存在群语义验证 |
| 修改房间资料和座位数 | `DONE` | `UpdateRoomProfile` 由房间内 owner 执行；资料和座位数变更经过 Room Cell，缩容要求被删除麦位空闲且未锁 | App 编辑页和真实 IM `room_profile_updated` 展示联调 |
| owner/host 收敛 | `DONE` | room-service 从 `actor_user_id` 默认 owner/host，拒绝外部冒用 | 后续转主持需独立命令 |
| 进房 presence | `DONE` | `JoinRoom` 写 `OnlineUsers`，gateway 返回首屏房间 DTO、`im_group_id` 和 RTC token | 客户端断线重连自动化测试 |
| 显式心跳刷新 | `DONE` | `/api/v1/rooms/heartbeat` 和 `RoomHeartbeat` 只刷新已有 `last_seen_at_ms` | 客户端按 stale timeout 配置周期调用 |
| 重复 JoinRoom 刷新 | `DONE` | 重复进房刷新 `last_seen_at_ms`，不重复发进房事件 | 新客户端优先使用 RoomHeartbeat |
| 离房 | `DONE` | `LeaveRoom` 幂等，移除 presence，释放麦位，写 outbox | 客户端收到离房/被踢后退出 IM/RTC 需联调 |
| stale presence 清理 | `DONE` | `RunPresenceStaleWorker` 和 `SweepStalePresence` 存在 | 多实例下只扫描本节点已装载 Cell，需压测确认 |
| 房间恢复 | `DONE` | snapshot + command log + Redis lease 接管恢复测试存在 | 大房间 command log 回放性能和快照策略压测 |
| 房间关闭 | `PARTIAL` | room-service 有 CloseRoom 命令；App 设计稿右上角电源按钮当前走 `/rooms/close` 退出自己，不关闭房间 | 真正关闭房间入口只应给房主/后台，需单独确认产品入口 |
| 房间列表/发现 | `TODO` | 当前无 list/search/recommend API | 需要房间索引、热度排序、状态过滤 |
| 房间基础配置更新 | `TODO` | 当前无修改标题、公告、封面、模式等命令 | 需要定义哪些字段属于 Room Cell，哪些属于房间资料表 |

## Persistence And Routing

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| MySQL 持久化 | `DONE` | `rooms`、`room_snapshots`、`room_command_log`、`room_outbox` | 线上迁移脚本和容量评估 |
| Redis room lease | `DONE` | Redis directory 做 room owner lease，保持单房间单活 | lease 续约/释放策略需要真实故障演练 |
| command log 幂等 | `DONE` | `HasCommand` 检查 command_id，命令重复返回当前快照 | 客户端必须按用户动作生成并在重试时复用 command_id |
| snapshot 频率 | `DONE` | `snapshot_every_n` 配置，本地/生产默认 `10`，命令日志保证恢复 | 高并发房间可按恢复成本调到 20 并压测 |
| outbox 持久化 | `DONE` | 房间事件写 `room_outbox` | 事件消费侧 schema 演进策略需补 |
| outbox worker 生命周期 | `DONE` | app 生命周期启动/停止 room outbox worker | 外部消费者不止腾讯 IM 时需要 fanout 策略 |
| outbox 重试配置 | `DONE` | poll interval、batch size、publish timeout、指数退避、最大重试和死信 | 后台死信查看、人工重放和告警规则需补 |

## Tencent IM Integration

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| 客户端 IM UserSig | `DONE` | gateway 签发，identifier 使用内部 `user_id` 十进制字符串 | 线上密钥管理和过期刷新体验 |
| room-service 建群 | `DONE` | `CreateRoom` 主链路同步调用腾讯 REST `create_group`；`RoomCreated` outbox 仍可幂等补偿 EnsureGroup | 腾讯云真实错误码覆盖和已存在群语义验证 |
| 房间系统消息 | `DONE` | `PublishRoomEvent` 发送 TIMCustomElem，事件包含 room_version | 客户端消息解析和版本去重 |
| 房间系统消息不阻塞命令 | `DONE` | 除 CreateRoom 同步建群外，房间系统消息在命令提交 command log/outbox 后由 outbox worker 异步投递 | 需要监控 pending/retryable/failed 积压 |
| outbox 投递 IM | `DONE` | outbox worker publish 成功后标记 `delivered`，失败指数退避，超限进 `failed` | 多消费者场景需要更细粒度 sink 状态 |
| 入群前守卫 | `DONE` | `Group.CallbackBeforeApplyJoinGroup` -> `VerifyRoomPresence` | 腾讯云控制台配置和公网回调验收 |
| 发言前守卫 | `DONE` | `Group.CallbackBeforeSendMsg` -> `CheckSpeakPermission` | 公屏消息内容审核、频控未做 |
| 群历史补拉 | `PARTIAL` | 设计上依赖腾讯云 IM 群历史 | 客户端补拉窗口、服务端兜底 API 未实现 |
| 单聊 | `TODO` | roadmap 有 peer_message 目标，代码未实现 | 可直接使用腾讯 IM 单聊，但本仓库未做入口和 ACK 设计 |
| ACK | `TODO` | roadmap 有 peer/system ACK 目标，代码未实现 | 需要客户端协议和消息状态存储 |

## Tencent RTC Integration

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| RTC UserSig 签发 | `DONE` | `pkg/tencentrtc`、JoinRoom 内嵌签发和 `/api/v1/rtc/token` 补偿入口已存在 | 真实 TRTC SDK enterRoom 联调 |
| RTC user_id 映射 | `DONE` | 内部 `user_id` -> RTC `UserID` 十进制字符串 | 多端同房策略未做 |
| RTC room_id 映射 | `DONE` | 统一使用 TRTC `strRoomId`，校验 room_id 子集 | 当前入口 fail-closed，非法 room_id 不创建房间 |
| 进频道权限 | `DONE` | JoinRoom 成功即证明业务 presence；独立 `/rtc/token` 仍调用 `VerifyRoomPresence` | 客户端必须按 JoinRoom 成功后再进 RTC |
| RTC 角色 | `PARTIAL` | token 返回默认 `audience` | 上麦后切 `anchor` 或 SDK role 切换未闭环 |
| RTC 事件回调 | `DONE` | `/api/v1/tencent-rtc/callback` 验签后消费 203/204/104 并调用 `ApplyRTCEvent` | 腾讯控制台公网回调配置和真实 TRTC 联调 |
| 离频道 | `PARTIAL` | 服务端 LeaveRoom 和 RTC 104 回调都会移除业务 presence | 客户端退出 TRTC 房间、异常重进策略未联调 |
| RTC 断线恢复 | `PARTIAL` | 文档定义 RTC 断线不等于业务离房 | 客户端 SDK 回调、重新取 token、重新 enterRoom 未验收 |
| 音频权限/上麦联动 | `PARTIAL` | MicUp 创建 pending_publish，客户端确认或 RTC 203 回调推进 publishing，RTC 204 回调释放麦位 | MicUp 后切 anchor、MicDown 后停止推流的端侧策略未联调 |
| 音频审核/录制 | `TODO` | 当前无设计和代码 | 后续接腾讯云审核/录制能力 |

## Mic And Room Management

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| 上麦 | `DONE` | `MicUp` 校验 presence、麦位存在、未锁、未占用 | 缺少角色权限和 RTC 推流联动 |
| 下麦 | `DONE` | `MicDown` 支持目标用户下麦 | 权限策略未区分本人、host、admin |
| 换麦 | `DONE` | `ChangeMicSeat` 原子清空源麦位并占用目标麦位 | 权限策略未完成 |
| 麦位锁定字段 | `PARTIAL` | `SeatState.locked` 存在，MicUp 会拒绝 locked seat | 没有 LockMic/UnlockMic 命令和 HTTP API |
| 禁言 | `DONE` | `MuteUser` 修改 mute 集合，CheckSpeakPermission 生效 | 权限策略和禁言时长未做 |
| 踢人/ban | `DONE` | `KickUser` 移除 presence、释放麦位、写 ban 集合 | 解封/解除 ban 未做 |
| 房主/主持/管理员角色 | `PARTIAL` | snapshot 有 owner/host/admin_user_ids，JoinRoom 有 role | 管理员增删、权限矩阵、owner 转让未做 |
| 聊天开关 | `PARTIAL` | `chat_enabled` 在 snapshot 和 guard 中存在 | 没有命令修改 chat_enabled |
| 房间黑名单 | `PARTIAL` | ban 集合由 KickUser 写入 | 独立黑名单管理、过期时间、后台查询未做 |

## Gifts, Wallet And Ranking

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| wallet-service 账务表 | `DONE` | `wallet_accounts`、`wallet_transactions`、`wallet_entries`、`wallet_outbox`、`wallet_gift_prices` | 充值、退款、管理员调账未做 |
| 礼物扣费幂等 | `DONE` | `DebitGift` 使用 `wallet_transactions.command_id` 幂等，测试覆盖 | 冲突请求告警 |
| SendGift 房间命令 | `DONE` | room-service 先扣费，再更新 heat、gift_rank、outbox；HTTP 支持 `target_type + target_user_ids`，兼容旧 `target_user_id` | 当前只开放 `target_type=user`，all_mic/all_room/couple 账务拆单和表现策略未做 |
| 房间热度 | `DONE` | `RoomSnapshot.heat` 和 `RoomHeatChanged` 事件 | 热度衰减/排行榜周期未做 |
| 本地礼物榜 | `DONE` | `LocalRank` 和 `gift_rank` 快照 | 全局榜、跨房榜、榜单重置未做 |
| 礼物配置 | `PARTIAL` | `wallet_gift_prices` 提供服务端价格和 `COIN`/`DIAMOND` 收费资产，`gift_configs` 提供礼物类型、有效期和特效；SendGift 请求只传 `gift_id/gift_count`；礼物配置已绑定 `resource_type=gift` 资源 | 客户端礼物表现联调、资源版本缓存刷新未做 |
| 背包/道具 | `PARTIAL` | `user_resource_entitlements`、`user_resource_equipment` 支持资源发放、我的资源和可佩戴资源装备 | 背包扣减、免费礼物、道具过期扫描未做 |
| 礼物消息补偿 | `DONE` | GiftSent/Heat/Rank 事件进入 outbox，由 worker direct 投 IM/activity，或发布到 RocketMQ 后由各 consumer group 消费 | 客户端去重和展示策略未验收 |
| 语音房火箭 | `DONE` | `room_rocket_configs`、`GetRoomRocket`、`RoomRocketFuelChanged/Ignited/Launched/RewardGranted`，发射支持本地扫描和 RocketMQ 延迟唤醒 | App UI、后台配置运营验收和真实 MQ 联调 |

## Activity And Lucky Gift

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| activity-service 底座 | `PARTIAL` | gRPC Ping/GetActivityStatus、MySQL activity/outbox 表存在 | 具体活动规则和奖励结算未实现 |
| room outbox 消费边界 | `DONE` | 本地 direct 投递 activity-service；线上可发布 `hyapp_room_outbox`，activity 使用 `hyapp-activity-room-outbox` 独立消费位点 | 后台排障页和消费积压告警需补 |
| 幸运礼物实现文档 | `DONE` | `docs/幸运礼物实现文档.md` | 后续幸运礼物变更同步该唯一文档 |
| 活动配置 | `TODO` | 只有 activity status projection | 活动规则、时间、奖池、风控配置未实现 |
| LuckyGift Check | `DONE` | `CheckLuckyGift` RPC、gateway 检查接口和 room-service 扣费前检查已实现 | App 礼物面板按 `pool_id` 联调 |
| LuckyGift Draw | `DONE` | `ExecuteLuckyGiftDraw`、三层奖池、RTP 窗口、风控计数、批量抽奖和幂等已实现 | 运营配置和长压测继续补 |
| 奖励入账 | `DONE` | 幸运礼物中奖后优先同步调 wallet `CreditLuckyGiftReward` 入账并把余额返回给 App；activity outbox worker 只做钱包补偿、IM 和区域播报 | 同步发奖成功率、补偿 pending age 和播报积压告警需补 |
| 幸运礼物审计 | `DONE` | `lucky_draw_records`、后台 draws 和 draw-summary 查询已实现 | 后台可视化维度继续补 |

## Messaging Product Surface

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| 公屏消息 | `PARTIAL` | 腾讯 IM 发言前回调会问 `CheckSpeakPermission` | 消息发送本身由客户端直连腾讯 IM；内容审核、刷屏频控未做 |
| 系统消息 | `DONE` | 创建、进房、离房、上下麦、禁言、踢人、送礼事件可投腾讯 IM | 客户端解析和展示顺序未验收 |
| 最近消息历史 | `PARTIAL` | 设计依赖腾讯 IM ChatRoom 历史 | 服务端不保存自研历史，客户端补拉方案未写验收 |
| 单聊 | `TODO` | roadmap 有目标，服务端未实现 | 可由腾讯 IM 单聊承载，但需要产品协议 |
| ACK | `TODO` | roadmap 有目标，服务端未实现 | 需要定义 ACK 对象、存储、重试和客户端状态 |
| 消息内容审核 | `TODO` | 当前只做是否可发言 | 接腾讯 IM/内容安全回调、敏感词和风控 |
| 消息频控 | `TODO` | gateway auth 有 public rate limit，房间消息无频控 | 房间维度、用户维度刷屏限制 |

## Discovery, Recommendation And Search

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| 房间列表 | `TODO` | 当前没有 list rooms API | 需要房间索引、分页、状态、热度排序 |
| 推荐流 | `TODO` | roadmap 明确当前不优先 | 依赖热度、活跃、标签、区域、风控 |
| 房间搜索 | `TODO` | 当前无标题/标签/房间号搜索 | 需要房间资料和索引 |
| 分类/标签 | `TODO` | 当前 RoomSnapshot 只有 mode/ext | 需要标签模型和后台配置 |
| 区域化分发 | `TODO` | 区域需求文档刚写 | 用户区域、房间区域、推荐策略未实现 |

## Operations, Admin And Risk Control

| Feature | Status | Current Evidence | Remaining Work |
| --- | --- | --- | --- |
| healthcheck | `DONE` | gateway HTTP live/ready，room gRPC health，docs 存在 | compose/线上健康检查需持续验证 |
| graceful shutdown | `PARTIAL` | docs 和部分 app worker 停止逻辑存在 | Room Cell snapshot flush 和全服务演练需补 |
| 登录审计 | `DONE` | user-service `login_audit` | 管理端查询未做 |
| 房间审计 | `PARTIAL` | room outbox 事件可作为审计来源 | audit consumer、查询表和后台未做 |
| 账务审计 | `DONE` | wallet ledger 存在 | 管理端查询和对账导出未做 |
| 基础封禁 | `PARTIAL` | room 内 Kick 写 ban，user-service 有用户状态 | 全局封禁、设备/IP 黑名单、后台操作未做 |
| 刷屏风控 | `TODO` | 当前只有 IM 发言权限守卫 | 需要消息频控、敏感词、内容安全 |
| 房间后台 | `TODO` | 当前无 admin API | 查房、关房、踢人、禁言、封禁、改配置 |
| 指标和告警 | `PARTIAL` | health、结构化日志和 `room_command_timing` 已存在 | outbox 积压、IM/RTC 错误率、wallet 失败率告警未完整实现 |

## Client Required Work

| Feature | Status | Server Dependency | Remaining Work |
| --- | --- | --- | --- |
| 登录/注册 | `PARTIAL` | gateway/user-service 已有接口 | 客户端提交 Firebase ID token；服务端接 Firebase verifier 后形成生产登录闭环 |
| CreateRoom/JoinRoom/LeaveRoom | `PARTIAL` | gateway/room-service 已有接口 | command_id、重试和状态覆盖联调 |
| 腾讯 IM 登录和进群 | `PARTIAL` | `/api/v1/im/usersig` 和回调守卫已存在 | SDK login、joinGroup、回调配置、历史补拉 |
| 腾讯 RTC 进房 | `PARTIAL` | `/api/v1/rtc/token` 已存在 | TRTC enterRoom、角色切换、断线重连 |
| 麦位 UI | `PARTIAL` | mic commands 已存在 | 上麦后推流、下麦停止推流、锁麦状态展示 |
| 系统消息展示 | `PARTIAL` | room system event 已投 IM | 客户端解析 TIMCustomElem 和 room_version 去重 |
| 礼物 UI | `PARTIAL` | SendGift/heat/rank 已存在 | 礼物配置、余额展示、动画和失败回滚提示 |
| 重连恢复 | `PARTIAL` | JoinRoom 刷新和 snapshot 恢复已存在 | 客户端 token refresh、IM relogin、RTC re-enter、快照覆盖 |

## Immediate Development Plan

### P0 Stabilize Current End-To-End Voice Room

| Task | Status | Acceptance |
| --- | --- | --- |
| 本地 docker compose 全服务启动 | `TODO` | gateway、user、room、wallet、activity、MySQL、Redis 都 healthy |
| 真实腾讯 IM 建群和回调联调 | `TODO` | CreateRoom 建群，JoinRoom 后 IM joinGroup 通过，Leave/Kick 后回调拒绝 |
| 真实 TRTC token 和进房联调 | `TODO` | JoinRoom 后取 RTC token，客户端用 strRoomId 进语音房 |
| 钱包余额种子和 SendGift smoke test | `TODO` | 余额扣减、房间 heat/rank 变化、IM 礼物系统消息到达 |
| 断线重连 smoke test | `TODO` | token refresh、JoinRoom 刷新、IM 重新进群、RTC 重新进房 |

### P1 Close Room Management Gaps

| Task | Status | Acceptance |
| --- | --- | --- |
| 权限矩阵 | `TODO` | owner/host/admin/audience 对 mic/mute/kick/sendGift 行为明确 |
| LockMic/UnlockMic | `TODO` | 锁麦位普通用户不能上，管理员可锁/解锁 |
| ChatEnable/Disable | `TODO` | 关闭公屏后 CheckSpeakPermission 返回 `chat_disabled` |
| Unban/解除踢人限制 | `TODO` | 被踢用户可由管理员恢复进房资格 |
| CloseRoom | `TODO` | 房间关闭后 Join/IM/RTC token 全部拒绝，客户端收到系统事件退出 |

### P2 Productize Gifts

| Task | Status | Acceptance |
| --- | --- | --- |
| 礼物配置表 | `TODO` | 客户端只能按服务端配置 gift_id 送礼 |
| 礼物价格版本 | `TODO` | SendGift 使用服务端价格，客户端不能自报单价 |
| 余额查询和充值入口 | `TODO` | 送礼前能展示余额，余额不足有稳定错误 |
| 礼物动画资源 | `TODO` | 礼物必须从 `resource_type=gift` 资源选择，客户端按资源版本缓存 |
| 资源和资源组赠送 | `TODO` | 后台可以给用户赠送单个资源或资源组，资源组原子展开 |

### P3 Activity And Lucky Gift

| Task | Status | Acceptance |
| --- | --- | --- |
| LuckyGift event handler | `TODO` | activity-service 在现有 RoomGiftSent 消费入口上增加幸运礼物 Check/Draw |
| LuckyGift proto 和 service | `TODO` | CheckLuckyGift/ExecuteLuckyGiftDraw 可用 |
| 三层奖池和风控 | `TODO` | 平台、房间、礼物奖池不会透支 |
| 奖励入账 | `TODO` | wallet 支持 CreditLuckyReward，失败进入 activity outbox |

### P4 Discovery And Admin

| Task | Status | Acceptance |
| --- | --- | --- |
| 房间列表 | `TODO` | 可分页拉取 active 房间并按热度排序 |
| 管理后台 API | `TODO` | 可以查房、关房、踢人、禁言、配置礼物和区域 |
| 区域功能 | `TODO` | 用户按国家归属区域，区域可管理，历史用户可回填 |
| 审计查询 | `TODO` | 登录、房间、账务、活动都可按用户/房间/时间查询 |

## Done Summary

当前服务端已经完成或基本完成：

- 用户注册登录、短号、资料和国家修改底座。
- gateway `/api/v1` envelope、服务端 `request_id` 生成、房间命令 HTTP 路由和写命令 `command_id` 透传。
- room-service Room Cell、Create/Join/Leave、麦位上下/换位、禁言、踢人、SendGift。
- MySQL command log/snapshot/outbox、Redis lease、恢复和 stale presence 清理。
- 腾讯 IM UserSig、建群、系统消息、入群/发言回调守卫。
- room outbox worker 异步投递腾讯 IM/activity，支持指数退避和死信。
- wallet-service DebitGift 幂等扣费。
- gateway RTC token 签发和 `user_id/room_id` 映射。

## Todo Summary

最关键待办不是再堆接口，而是把当前已存在能力做成可运营闭环：

- 真实腾讯 IM + TRTC 客户端联调。
- room 权限矩阵、锁麦、关房、聊天开关、解封。
- 礼物配置和服务端定价，礼物从 `resource_type=gift` 资源选择，禁止客户端自报价格或资源 URL。
- 房间列表、推荐、搜索和区域化。
- activity-service 真实消费 room outbox，幸运礼物完整实现。
- 管理后台、审计查询、风控、指标告警。
- 客户端断线重连、系统消息去重、IM 历史补拉、RTC re-enter。
