hyapp-server/docs/voice-room-feature-inventory.md
2026-04-30 02:30:32 +08:00

269 lines
20 KiB
Markdown
Raw 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.

# 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_idsJoinRoom 有 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` | 后台价格、上下架、表现资源、版本管理未做 |
| 背包/道具 | `TODO` | 当前只有金币扣费 | 背包扣减、免费礼物、道具有效期未做 |
| 礼物消息补偿 | `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/readyroom gRPC healthdocs 存在 | 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 写 banuser-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` | 礼物配置返回表现资源,客户端按版本缓存 |
### 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 权限矩阵、锁麦、关房、聊天开关、解封。
- 礼物配置和服务端定价,禁止客户端自报价格。
- 房间列表、推荐、搜索和区域化。
- activity-service 真实消费 room outbox幸运礼物完整实现。
- 管理后台、审计查询、风控、指标告警。
- 客户端断线重连、系统消息去重、IM 历史补拉、RTC re-enter。