# 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/user-region-country-development.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/mic/mute/kick/sendGift 路由存在 | OpenAPI 需持续同步最新字段 | | 房间命令 `command_id` | `DONE` | HTTP body 支持 `command_id`,gateway 未传时生成但不保证重试幂等 | 客户端必须稳定复用 command_id | | `request_id` 追踪 | `DONE` | request_id 透传 RequestMeta,不作为幂等键 | 日志和链路追踪系统可继续完善 | | IM UserSig 签发 | `DONE` | `/api/v1/im/usersig` 使用 access token `user_id` 签发 | 真实腾讯云应用联调和告警 | | RTC token 签发 | `DONE` | `/api/v1/rtc/token` 存在,先查 `VerifyRoomPresence` 再签 UserSig | 客户端 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、seat_count、mode;写 meta/command/outbox/snapshot | 真实 IM 建群失败注入和线上重试策略联调 | | owner/host 收敛 | `DONE` | room-service 从 `actor_user_id` 默认 owner/host,拒绝外部冒用 | 后续转主持需独立命令 | | 进房 presence | `DONE` | `JoinRoom` 写 `OnlineUsers`,返回 user 和 snapshot | 客户端心跳或定期 Join 刷新策略需定稿 | | 重复 JoinRoom 刷新 | `DONE` | 重复进房刷新 `last_seen_at_ms`,不重复发进房事件 | 客户端断线重连自动化测试 | | 离房 | `DONE` | `LeaveRoom` 幂等,移除 presence,释放麦位,写 outbox | 客户端收到离房/被踢后退出 IM/RTC 需联调 | | stale presence 清理 | `DONE` | `RunPresenceStaleWorker` 和 `SweepStalePresence` 存在 | 多实例下只扫描本节点已装载 Cell,需压测确认 | | 房间恢复 | `DONE` | snapshot + command log + Redis lease 接管恢复测试存在 | 大房间 command log 回放性能和快照策略压测 | | 房间关闭 | `TODO` | 当前无 CloseRoom 命令 | 需要状态变更、IM/RTC 退出通知、恢复语义 | | 房间列表/发现 | `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` 配置,默认每次保存 | 高并发房间可能要调大并验证恢复成本 | | outbox 持久化 | `DONE` | 房间事件写 `room_outbox` | 事件消费侧 schema 演进策略需补 | | outbox worker 生命周期 | `DONE` | app 生命周期启动/停止 room outbox worker | 外部消费者不止腾讯 IM 时需要 fanout 策略 | | outbox 重试配置 | `DONE` | poll interval、batch size、publish timeout、fixed_interval | 指数退避、死信和告警未做 | ## Tencent IM Integration | Feature | Status | Current Evidence | Remaining Work | | --- | --- | --- | --- | | 客户端 IM UserSig | `DONE` | gateway 签发,identifier 使用内部 `user_id` 十进制字符串 | 线上密钥管理和过期刷新体验 | | room-service 建群 | `DONE` | `EnsureRoomGroup` 调腾讯 REST create_group | 腾讯云真实错误码覆盖和已存在群语义验证 | | 房间系统消息 | `DONE` | `PublishRoomEvent` 发送 TIMCustomElem,事件包含 room_version | 客户端消息解析和版本去重 | | 同步推失败不回滚 | `DONE` | 命令提交后同步 publish 失败保持 outbox pending | 需要监控 pending 积压 | | outbox 补投 IM | `DONE` | outbox worker 后续 publish 并标记 published | 多消费者场景需要事件状态拆分 | | 入群前守卫 | `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` 和 `/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` | 签 RTC token 前调用 `VerifyRoomPresence` | 客户端必须按 JoinRoom 后再取 token | | RTC 角色 | `PARTIAL` | token 返回默认 `audience` | 上麦后切 `anchor` 或 SDK role 切换未闭环 | | 离频道 | `PARTIAL` | 服务端 LeaveRoom 会移除业务 presence | 客户端退出 TRTC 房间、异常重进策略未联调 | | RTC 断线恢复 | `PARTIAL` | 文档定义 RTC 断线不等于业务离房 | 客户端 SDK 回调、重新取 token、重新 enterRoom 未验收 | | 音频权限/上麦联动 | `TODO` | MicUp 只改 Room Cell 麦位 | MicUp 后允许推流、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 | 礼物目标、礼物表现和客户端动画联调 | | 房间热度 | `DONE` | `RoomSnapshot.heat` 和 `RoomHeatChanged` 事件 | 热度衰减/排行榜周期未做 | | 本地礼物榜 | `DONE` | `LocalRank` 和 `gift_rank` 快照 | 全局榜、跨房榜、榜单重置未做 | | 礼物配置 | `PARTIAL` | `wallet_gift_prices` 提供服务端价格,SendGift 请求只传 `gift_id/gift_count`;礼物配置已绑定 `resource_type=gift` 资源 | 客户端礼物表现联调、资源版本缓存刷新未做 | | 背包/道具 | `PARTIAL` | `user_resource_entitlements`、`user_resource_equipment` 支持资源发放、我的资源和可佩戴资源装备 | 背包扣减、免费礼物、道具过期扫描未做 | | 礼物消息补偿 | `DONE` | GiftSent/Heat/Rank 事件进入 outbox,主事件同步 IM | 客户端去重和展示策略未验收 | ## Activity And Lucky Gift | Feature | Status | Current Evidence | Remaining Work | | --- | --- | --- | --- | | activity-service 底座 | `PARTIAL` | gRPC Ping/GetActivityStatus、MySQL activity/outbox 表存在 | 尚未消费 room outbox | | room outbox 消费边界 | `PARTIAL` | `consumer/room` 有接口骨架 | 真实 polling/MQ/offset/idempotency 未实现 | | 幸运礼物开发文档 | `DONE` | `docs/lucky-gift-activity-service-development.md` | 按文档实现 proto、pool、risk、draw | | 活动配置 | `TODO` | 只有 activity status projection | 活动规则、时间、奖池、风控配置未实现 | | LuckyGift Check | `TODO` | 文档有设计,proto/code 未实现 | `CheckLuckyGift` RPC 和规则校验 | | LuckyGift Draw | `TODO` | 文档有设计,proto/code 未实现 | 三层奖池、一层风控、幂等 draw | | 奖励入账 | `TODO` | wallet 只有 DebitGift,无 CreditLuckyReward | wallet credit RPC、activity outbox、重试 | | 幸运礼物审计 | `TODO` | 文档有 draw/pool/risk 审计设计 | 表结构和查询入口未实现 | ## 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 和日志存在,文档提到指标 | 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 | | --- | --- | --- | | room outbox -> activity consumer | `TODO` | activity-service 幂等消费 RoomGiftSent | | 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、房间命令 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 补偿投递。 - 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。