swagger: "2.0"
info:
  title: HY Gateway Service API
  version: "1.0.0"
  description: |
    gateway-service 对外暴露 HTTP + JSON API。
    `/api/v1/**` 业务接口统一返回 `code/message/request_id/data` 外壳；`request_id` 和响应 `X-Request-ID` 均由服务端生成，并透传到内部 gRPC RequestMeta。
    `/healthz/**` 是健康检查接口，不使用业务响应外壳。
host: localhost:13000
basePath: /
schemes:
  - http
consumes:
  - application/json
produces:
  - application/json
tags:
  - name: health
    description: Gateway 进程和依赖探测。
  - name: auth
    description: 登录、刷新、登出和密码初始化。
  - name: tencent-im
    description: 腾讯云 IM 登录票据和服务端回调入口。
  - name: tencent-rtc
    description: 腾讯 RTC 语音进房票据入口。
  - name: files
    description: App 文件和头像上传入口。
  - name: users
    description: 当前展示短号查询和变更。
  - name: countries
    description: App 注册页国家选择公开读接口。
  - name: app-config
    description: App 运行时配置公开读接口。
  - name: devices
    description: App 设备推送 token 绑定和失效。
  - name: rooms
    description: 房间命令入口，最终由 room-service 执行。
  - name: wallet
    description: App 钱包余额、币商转账和充值口径入口。
  - name: resources
    description: App 资源库、资源组、礼物配置和我的资源入口。
  - name: manager-center
    description: H5 经理中心入口；服务端校验业务身份，客户端不能自报经理权限。
  - name: business
    description: 带业务场景权限裁剪的通用能力入口。
  - name: messages
    description: App 消息 tab，后端只负责 system/activity inbox，用户私聊来自腾讯云 IM SDK。
securityDefinitions:
  BearerAuth:
    type: apiKey
    name: Authorization
    in: header
    description: 使用 `Bearer <JWT>`；JWT 使用 HS256，claims 中的 `user_id` 是数值型用户 ID 的字符串，避免 64 位 ID 精度丢失。
parameters:
  DisplayUserIDPath:
    name: display_user_id
    in: path
    required: true
    type: string
    description: 当前有效展示短号。
  ResourceGroupIDPath:
    name: group_id
    in: path
    required: true
    type: integer
    format: int64
    description: 资源组 ID。
  ResourceIDPath:
    name: resource_id
    in: path
    required: true
    type: integer
    format: int64
    description: 资源 ID。
  TencentIMSDKAppID:
    name: SdkAppid
    in: query
    required: true
    type: integer
    format: int64
    description: 腾讯云 IM 回调携带的 SDKAppID；当前入口接受 `SdkAppid` 查询名。
  TencentIMCallbackCommand:
    name: CallbackCommand
    in: query
    required: false
    type: string
    enum:
      - Group.CallbackBeforeApplyJoinGroup
      - Group.CallbackBeforeSendMsg
    description: 腾讯云 IM 回调命令；如果 query 和 body 同时存在，二者必须一致。
  TencentIMCallbackAuthToken:
    name: CallbackAuthToken
    in: query
    required: false
    type: string
    description: 腾讯云 IM 回调鉴权 token；也可通过 `X-Tencent-IM-Callback-Token` header 传入。
  TencentIMCallbackTokenHeader:
    name: X-Tencent-IM-Callback-Token
    in: header
    required: false
    type: string
    description: 腾讯云 IM 回调鉴权 token header。
  TencentRTCSDKAppIDHeader:
    name: SdkAppId
    in: header
    required: true
    type: integer
    format: int64
    description: 腾讯 RTC 事件回调 header 中的 SDKAppID。
  TencentRTCSignHeader:
    name: Sign
    in: header
    required: true
    type: string
    description: 腾讯 RTC 事件回调签名，计算方式为 `base64(hmacsha256(callback_sign_key, raw_body))`。
responses:
  BadRequest:
    description: 请求体不是合法 JSON，或下游返回非法参数；常见 `code` 为 `INVALID_JSON`、`INVALID_ARGUMENT`、`DISPLAY_USER_ID_INVALID`。
    schema:
      $ref: "#/definitions/ErrorEnvelope"
  Unauthorized:
    description: 未通过 access token 校验，或下游返回认证失败。
    schema:
      $ref: "#/definitions/ErrorEnvelope"
  Forbidden:
    description: 已认证但被禁用、封禁或无权限。
    schema:
      $ref: "#/definitions/ErrorEnvelope"
  NotFound:
    description: 下游实体不存在。
    schema:
      $ref: "#/definitions/ErrorEnvelope"
  Conflict:
    description: 下游唯一键、状态、租约或冷却期冲突。
    schema:
      $ref: "#/definitions/ErrorEnvelope"
  Internal:
    description: gateway 或下游返回不可细分的内部错误。
    schema:
      $ref: "#/definitions/ErrorEnvelope"
  UpstreamError:
    description: gateway 调内部服务失败，或内部服务返回不可映射错误。
    schema:
      $ref: "#/definitions/ErrorEnvelope"
paths:
  /healthz/live:
    get:
      tags:
        - health
      summary: 进程存活探测
      operationId: gatewayLive
      responses:
        "200":
          description: Gateway HTTP runtime 正在服务。
          schema:
            $ref: "#/definitions/HealthResponse"
        "500":
          description: Gateway HTTP runtime 不可用。
          schema:
            $ref: "#/definitions/HealthResponse"
  /healthz/ready:
    get:
      tags:
        - health
      summary: 接流量就绪探测
      operationId: gatewayReady
      responses:
        "200":
          description: Gateway 可接新请求。
          schema:
            $ref: "#/definitions/HealthResponse"
        "503":
          description: Gateway 不应接新请求，失败详情在 `checks`。
          schema:
            $ref: "#/definitions/HealthResponse"
  /api/v1/auth/account/login:
    post:
      tags:
        - auth
      summary: 账号密码登录
      description: 账号就是用户当前有效短号。
      operationId: loginAccountPassword
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/LoginPasswordRequest"
      responses:
        "200":
          description: 登录成功，`data` 返回 token 集合。
          schema:
            $ref: "#/definitions/AuthTokenEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/auth/third-party/login:
    post:
      tags:
        - auth
      summary: 三方登录或注册
      operationId: loginThirdParty
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/LoginThirdPartyRequest"
      responses:
        "200":
          description: 登录或注册成功，`data` 返回 token 集合和 `is_new_user`。
          schema:
            $ref: "#/definitions/AuthTokenEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/auth/password/set:
    post:
      tags:
        - auth
      summary: 已登录用户首次设置密码
      operationId: setPassword
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/SetPasswordRequest"
      responses:
        "200":
          description: 密码设置成功。
          schema:
            $ref: "#/definitions/PasswordSetEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/auth/token/refresh:
    post:
      tags:
        - auth
      summary: 刷新 token
      operationId: refreshToken
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/RefreshTokenRequest"
      responses:
        "200":
          description: 刷新成功，`data` 返回新的 token 集合。
          schema:
            $ref: "#/definitions/AuthTokenEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/auth/logout:
    post:
      tags:
        - auth
      summary: 登出并失效 refresh session
      operationId: logout
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/LogoutRequest"
      responses:
        "200":
          description: 登出处理完成。
          schema:
            $ref: "#/definitions/LogoutEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/countries:
    get:
      tags:
        - countries
      summary: 获取 App 注册页可选国家
      operationId: listRegistrationCountries
      description: 公开读接口，只返回 user-service 判定的 `enabled=true` 国家，并按 `sort_order,country_code` 排序。
      parameters:
      responses:
        "200":
          description: 查询成功，`data.countries` 返回当前开放国家。
          schema:
            $ref: "#/definitions/CountryListEnvelope"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/app/bootstrap:
    get:
      tags:
        - app-config
      summary: 获取 App 启动配置摘要
      operationId: getAppBootstrap
      description: 公开读接口，只返回版本、维护、feature flags、底部 tab 和配置版本号，不返回 banner、礼物或资源大列表。
      parameters:
      responses:
        "200":
          description: 查询成功，`data` 返回 App 启动状态机需要的轻量配置摘要。
          schema:
            $ref: "#/definitions/AppBootstrapEnvelope"
  /api/v1/app/version:
    get:
      tags:
        - app-config
      summary: 获取 App 最新版本信息
      operationId: getAppVersion
      description: 公开读接口，gateway 根据 App 平台返回后台 APP配置/版本管理 中最高 `build_number` 版本，并按客户端当前 `build_number` 计算是否需要提示更新。
      parameters:
        - name: platform
          in: query
          required: false
          type: string
          enum: [android, ios]
          description: 可选平台覆盖值；不传时读取 `X-App-Platform` / `X-Platform`。
        - name: build_number
          in: query
          required: false
          type: integer
          format: int64
          description: 当前客户端编译版本号；不传时读取 `X-App-Build-Number` / `X-Build-Number`。
        - name: X-App-Platform
          in: header
          required: false
          type: string
          enum: [android, ios]
        - name: X-App-Build-Number
          in: header
          required: false
          type: integer
          format: int64
      responses:
        "200":
          description: 查询成功，`data` 返回最新版本和更新判定。
          schema:
            $ref: "#/definitions/AppVersionEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/app/h5-links:
    get:
      tags:
        - app-config
      summary: 获取 App H5 入口地址
      operationId: listAppH5Links
      description: 公开读接口，返回后台管理系统 APP配置/H5配置 维护的 H5 地址。未配置 URL 的入口仍按固定 key 返回空字符串。
      parameters:
      responses:
        "200":
          description: 查询成功，`data.items` 返回固定 H5 入口集合。
          schema:
            $ref: "#/definitions/H5LinkListEnvelope"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/app/splash-screens:
    get:
      tags:
        - app-config
      summary: 获取 App 开屏配置
      operationId: listSplashScreens
      description: 公开读接口，返回后台 APP配置/开屏配置 中当前有效的开屏列表，客户端按列表顺序取最高优先级配置展示。
      parameters:
        - name: platform
          in: query
          required: false
          type: string
          enum: [android, ios]
          description: 可选平台覆盖值；不传时读取 `X-App-Platform` / `X-Platform`。
        - name: region_id
          in: query
          required: false
          type: integer
          format: int64
          description: 当前用户区域 ID；0 或不传只命中全区域配置。
        - name: country
          in: query
          required: false
          type: string
          description: 当前用户国家码；不传时读取 `X-Country-Code` / `X-App-Country`。
        - name: X-App-Platform
          in: header
          required: false
          type: string
          enum: [android, ios]
        - name: X-Country-Code
          in: header
          required: false
          type: string
      responses:
        "200":
          description: 查询成功，`data.items` 返回当前可展示的开屏配置。
          schema:
            $ref: "#/definitions/SplashScreenListEnvelope"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/app/popups:
    get:
      tags:
        - app-config
      summary: 获取 App 弹窗配置
      operationId: listAppPopups
      description: 公开读接口，返回后台 APP配置/弹窗配置 中当前有效的弹窗列表。客户端按列表顺序选择弹窗，并按 display_period_days 做本地展示频控。
      parameters:
      responses:
        "200":
          description: 查询成功，`data.items` 返回当前可展示的弹窗配置。
          schema:
            $ref: "#/definitions/PopupListEnvelope"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/im/usersig:
    get:
      tags:
        - tencent-im
      summary: 获取腾讯云 IM UserSig
      operationId: issueTencentIMUserSig
      security:
        - BearerAuth: []
      parameters:
      responses:
        "200":
          description: 签发成功，`data.user_id` 使用内部长 `user_id` 的十进制字符串。
          schema:
            $ref: "#/definitions/TencentIMUserSigEnvelope"
        "401":
          $ref: "#/responses/Unauthorized"
        "500":
          description: 腾讯云 IM SDKAppID、SecretKey 或 TTL 配置缺失，fail-closed。
          schema:
            $ref: "#/definitions/ErrorEnvelope"
  /api/v1/rtc/token:
    post:
      tags:
        - tencent-rtc
      summary: 获取腾讯 RTC 进房 UserSig
      operationId: issueTencentRTCToken
      description: |
        gateway 使用 access token 中的内部 `user_id` 签发腾讯 RTC UserSig，并在签发前调用 room-service `VerifyRoomPresence`。
        当前只支持 TRTC 字符串房间 `strRoomId`，客户端不能把 `room_id` 转成数字 `roomId`。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/TencentRTCTokenRequest"
      responses:
        "200":
          description: 签发成功，`data.user_id` 和 `data.rtc_user_id` 都是内部长 `user_id` 的十进制字符串。
          schema:
            $ref: "#/definitions/TencentRTCTokenEnvelope"
        "400":
          description: "`room_id` 为空或不满足 `^[A-Za-z0-9_-]{1,48}$`。"
          schema:
            $ref: "#/definitions/ErrorEnvelope"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          description: 用户不在房间、已被踢出或被封禁，gateway 不返回 UserSig。
          schema:
            $ref: "#/definitions/ErrorEnvelope"
        "404":
          description: room-service guard 返回 `room_not_found`。
          schema:
            $ref: "#/definitions/ErrorEnvelope"
        "500":
          description: 腾讯 RTC 未启用、SDKAppID、SecretKey、TTL 或固定策略配置缺失，fail-closed。
          schema:
            $ref: "#/definitions/ErrorEnvelope"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/tencent-rtc/callback:
    post:
      tags:
        - tencent-rtc
      summary: 腾讯 RTC 服务端事件回调
      operationId: handleTencentRTCCallback
      description: |
        腾讯 RTC 控制台配置的房间/媒体事件回调入口。gateway 校验 `SdkAppId` 与 `Sign` 后，只消费房间退出 `104`、开始推送音频 `203`、停止推送音频 `204`。
        该接口不使用业务 envelope；成功或可忽略业务错误返回 `{"code":0}`。
      parameters:
        - $ref: "#/parameters/TencentRTCSDKAppIDHeader"
        - $ref: "#/parameters/TencentRTCSignHeader"
        - name: app_code
          in: query
          required: false
          type: string
          description: 多 App 部署时建议把腾讯控制台回调 URL 配置为携带 `app_code`，用于 room-service 租户路由。
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/TencentRTCCallbackRequest"
      responses:
        "200":
          description: 回调已接受，未知事件或不可恢复业务错误也按成功 ACK，避免无意义重试。
          schema:
            $ref: "#/definitions/TencentRTCCallbackResponse"
        "400":
          description: 回调 body 非法。
          schema:
            $ref: "#/definitions/TencentRTCCallbackResponse"
        "403":
          description: SDKAppID 不匹配或签名校验失败。
          schema:
            $ref: "#/definitions/TencentRTCCallbackResponse"
        "500":
          description: room-service 暂时不可用，返回非 200 让腾讯 RTC 按平台策略重试。
          schema:
            $ref: "#/definitions/TencentRTCCallbackResponse"
  /api/v1/files/upload:
    post:
      tags:
        - files
      summary: 上传 App 通用文件
      operationId: uploadFile
      description: 上传到腾讯云 COS，返回可直接写入业务资料的公开访问 URL；该接口只要求已登录，不要求注册资料已完成。
      consumes:
        - multipart/form-data
      security:
        - BearerAuth: []
      parameters:
        - name: file
          in: formData
          required: true
          type: file
          description: 文件字段；单文件最大 20 MiB。
      responses:
        "200":
          description: 上传成功，`data.url` 为 `tencent-cos.access-url` 下的对象访问地址。
          schema:
            $ref: "#/definitions/UploadFileEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/files/avatar/upload:
    post:
      tags:
        - files
      summary: 上传用户头像
      operationId: uploadAvatar
      description: 上传头像到腾讯云 COS；服务端按文件头嗅探，只接受 JPEG、PNG、WebP，单文件最大 5 MiB。
      consumes:
        - multipart/form-data
      security:
        - BearerAuth: []
      parameters:
        - name: file
          in: formData
          required: true
          type: file
          description: 头像文件字段，也兼容字段名 `avatar`。
      responses:
        "200":
          description: 上传成功，`data.url` 可作为注册资料或用户资料里的 `avatar`。
          schema:
            $ref: "#/definitions/UploadFileEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/devices/push-token:
    post:
      tags:
        - devices
      summary: 绑定设备推送 token
      operationId: bindPushToken
      description: 资料完成后由客户端上报系统推送 token；gateway 只使用 access token 中的用户身份，user-service 负责落库。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/BindPushTokenRequest"
      responses:
        "200":
          description: 绑定成功。
          schema:
            $ref: "#/definitions/BindPushTokenEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
    delete:
      tags:
        - devices
      summary: 删除设备推送 token
      operationId: deletePushToken
      description: 登出、关闭通知或 token 失效时调用；`push_token` 可为空，为空时按当前用户和 `device_id` 失效。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/DeletePushTokenRequest"
      responses:
        "200":
          description: 删除或失效处理完成。
          schema:
            $ref: "#/definitions/DeletePushTokenEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/tencent-im/callback:
    post:
      tags:
        - tencent-im
      summary: 腾讯云 IM 服务端回调
      operationId: handleTencentIMCallback
      description: |
        该接口不使用项目业务 envelope，直接返回腾讯云 IM 要求的 `ActionStatus/ErrorCode/ErrorInfo`。
        当前支持入群前守卫 `Group.CallbackBeforeApplyJoinGroup` 和发言前守卫 `Group.CallbackBeforeSendMsg`。
        白名单外回调在通过来源校验和 SDKAppID 校验后返回允许，避免阻断腾讯云新增回调。
      parameters:
        - $ref: "#/parameters/TencentIMSDKAppID"
        - $ref: "#/parameters/TencentIMCallbackCommand"
        - $ref: "#/parameters/TencentIMCallbackAuthToken"
        - $ref: "#/parameters/TencentIMCallbackTokenHeader"
        - name: body
          in: body
          required: false
          schema:
            $ref: "#/definitions/TencentIMCallbackRequest"
      responses:
        "200":
          description: 腾讯云 IM 回调处理结果；业务拒绝也返回 HTTP 200，通过 `ErrorCode=1` 表示拒绝。
          schema:
            $ref: "#/definitions/TencentIMCallbackResponse"
        "405":
          description: 非 POST 请求会返回腾讯云原生结构，`ErrorCode=1`。
          schema:
            $ref: "#/definitions/TencentIMCallbackResponse"
  /api/v1/users/by-display-user-id/{display_user_id}:
    get:
      tags:
        - users
      summary: 通过当前展示短号解析用户
      operationId: resolveDisplayUserID
      parameters:
        - $ref: "#/parameters/DisplayUserIDPath"
      responses:
        "200":
          description: 解析成功，`data` 返回短号归属。
          schema:
            $ref: "#/definitions/UserIdentityEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "404":
          $ref: "#/responses/NotFound"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/profiles:batch:
    get:
      tags:
        - users
      summary: 批量查询会话展示资料
      operationId: batchUserProfiles
      description: 用于腾讯云 IM 会话列表补头像、昵称和短号；只返回展示字段，不返回登录、实名或后台身份信息。
      security:
        - BearerAuth: []
      parameters:
        - name: user_ids
          in: query
          required: true
          type: string
          description: 逗号分隔或重复传入的用户 ID，最多 100 个。
      responses:
        "200":
          description: 查询成功。
          schema:
            $ref: "#/definitions/UserProfilesBatchEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/me/identity:
    get:
      tags:
        - users
      summary: 查询当前用户展示短号状态
      operationId: getMyIdentity
      security:
        - BearerAuth: []
      parameters:
      responses:
        "200":
          description: 查询成功，`data` 返回当前用户短号状态。
          schema:
            $ref: "#/definitions/UserIdentityEnvelope"
        "401":
          $ref: "#/responses/Unauthorized"
        "404":
          $ref: "#/responses/NotFound"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/me/host-identity:
    get:
      tags:
        - users
      summary: 查询当前用户 Host/Agency/BD 身份
      operationId: getMyHostIdentity
      description: App 用于判断是否展示 H5 入口；不存在的身份返回 false，不按 404 处理。
      security:
        - BearerAuth: []
      parameters:
      responses:
        "200":
          description: 查询成功，`data` 返回当前用户身份开关。
          schema:
            $ref: "#/definitions/UserHostIdentityEnvelope"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/me/overview:
    get:
      tags:
        - users
      summary: 我的页首屏聚合摘要
      operationId: getMyOverview
      description: 聚合当前用户资料、顶部计数、金币钱包卡片、VIP、Host/Agency/BD/币商身份和入口显隐。该接口不查消息红点、邀请码、钻石、美元余额、流水、成员或工资；钱包、VIP、计数和角色上游失败时按字段 `unavailable=true` 局部降级。
      security:
        - BearerAuth: []
      parameters:
      responses:
        "200":
          description: 查询成功，`data` 返回我的页首屏渲染摘要。
          schema:
            $ref: "#/definitions/MyOverviewEnvelope"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/me/invite-overview:
    get:
      tags:
        - users
      summary: 查询当前用户邀请概览
      operationId: getMyInviteOverview
      description: 返回当前登录用户自己的邀请码和邀请计数；该接口只服务私有 H5 分享页，不并入我的页首屏聚合摘要。
      security:
        - BearerAuth: []
      parameters:
      responses:
        "200":
          description: 查询成功，`data` 返回当前用户邀请概览。
          schema:
            $ref: "#/definitions/MyInviteOverviewEnvelope"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/me/onboarding/complete:
    post:
      tags:
        - users
      summary: 完成注册页必填资料
      operationId: completeMyOnboarding
      description: 三方登录即注册后唯一资料提交入口；`username/avatar/gender/country` 在 user-service 同事务校验并写入。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/CompleteOnboardingRequest"
      responses:
        "200":
          description: 注册资料完成，`data.profile_completed=true`，`data.token.access_token` 是替换旧 JWT 的新 access token。
          schema:
            $ref: "#/definitions/CompleteOnboardingEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "404":
          $ref: "#/responses/NotFound"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/me/profile/update:
    post:
      tags:
        - users
      summary: 修改当前用户基础资料
      operationId: updateMyProfile
      description: 只修改 `username`、`avatar`、`birth`；国家修改必须走独立国家接口。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/UpdateUserProfileRequest"
      responses:
        "200":
          description: 修改成功，`data` 返回最新用户资料。
          schema:
            $ref: "#/definitions/UserProfileEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "404":
          $ref: "#/responses/NotFound"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/me/country/change:
    post:
      tags:
        - users
      summary: 修改当前用户国家
      operationId: changeMyCountry
      description: 国家修改单独写变更日志；同一用户按滚动 30 天冷却窗口只能成功修改一次。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/ChangeUserCountryRequest"
      responses:
        "200":
          description: 修改成功，`data.next_country_change_allowed_at_ms` 返回下一次可修改时间。
          schema:
            $ref: "#/definitions/UserProfileEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/me/display-id/change:
    post:
      tags:
        - users
      summary: 修改当前用户默认短号
      operationId: changeMyDisplayUserID
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/ChangeDisplayUserIDRequest"
      responses:
        "200":
          description: 修改成功，`data` 返回最新短号状态。
          schema:
            $ref: "#/definitions/UserIdentityEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/me/display-id/pretty/apply:
    post:
      tags:
        - users
      summary: 申请临时靓号
      operationId: applyMyPrettyDisplayUserID
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/ApplyPrettyDisplayUserIDRequest"
      responses:
        "200":
          description: 申请成功，`data` 返回最新短号状态和租约 ID。
          schema:
            $ref: "#/definitions/UserIdentityEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms:
    get:
      tags:
        - rooms
      summary: 房间发现列表
      operationId: listRooms
      description: 按当前登录用户的服务端 region_id 查询房间发现列表；响应卡片显式返回 `im_group_id`，当前值等于 `room_id`，但客户端不能硬编码该映射。
      security:
        - BearerAuth: []
      parameters:
        - name: tab
          in: query
          required: false
          type: string
          enum:
            - hot
            - new
        - name: cursor
          in: query
          required: false
          type: string
        - name: limit
          in: query
          required: false
          type: integer
          format: int32
        - name: q
          in: query
          required: false
          type: string
          description: 房间标题或用户 ID 搜索词；`query` 是兼容别名。
        - name: query
          in: query
          required: false
          type: string
      responses:
        "200":
          description: 查询成功，`data.rooms[*].im_group_id` 是 JoinRoom 成功后客户端加入的腾讯 IM 房间群 ID。
          schema:
            $ref: "#/definitions/RoomListEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/feeds:
    get:
      tags:
        - rooms
      summary: Mine 房间关系流
      operationId: listRoomFeeds
      description: 查询 Mine 页下方 Visited/Friend/Following/Followed 房间流；`visited` 读取 JoinRoom 写入的房间访问索引，`friend/following` 由 gateway 先读取 user-service 关系事实，`followed` 读取 room-service 房间关注关系，再让 room-service 返回 active 房间卡片和 `im_group_id`，不作为公共房间发现列表。
      security:
        - BearerAuth: []
      parameters:
        - name: tab
          in: query
          required: true
          type: string
          enum:
            - visited
            - friend
            - following
            - followed
        - name: cursor
          in: query
          required: false
          type: string
        - name: limit
          in: query
          required: false
          type: integer
          format: int32
      responses:
        "200":
          description: 查询成功；`visited` 由 JoinRoom 成功写入，`friend/following` 同步使用 user-service 好友/关注关系，`followed` 同步使用 room-service 房间关注关系，不依赖 Redis 缓存命中。
          schema:
            $ref: "#/definitions/RoomListEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/me:
    get:
      tags:
        - rooms
      summary: 查询我的房间卡片
      operationId: getMyRoom
      description: Mine 顶部“我的房间”权威查询；gateway 使用 access token user_id，room-service 直接读取 rooms 元数据并用 Room Cell 快照补齐卡片字段，不依赖发现页 `room_list_entries` 投影命中。
      security:
        - BearerAuth: []
      parameters:
      responses:
        "200":
          description: 查询成功，`data.has_room=false` 表示当前用户尚未创建房间；有房间时 `data.room.im_group_id` 显式返回腾讯 IM 房间群 ID。
          schema:
            $ref: "#/definitions/MyRoomEnvelope"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/current:
    get:
      tags:
        - rooms
      summary: 查询当前可恢复房间
      operationId: getCurrentRoom
      description: App 启动、回前台或网络恢复时调用；gateway 使用 access token user_id，room-service 用 presence 读模型和 Room Cell 快照二次校验，不会隐式 JoinRoom。
      security:
        - BearerAuth: []
      parameters:
      responses:
        "200":
          description: 查询成功，`data.has_current_room=false` 表示无需恢复。
          schema:
            $ref: "#/definitions/CurrentRoomEnvelope"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/snapshot:
    get:
      tags:
        - rooms
      summary: 查询房间完整快照
      operationId: getRoomSnapshot
      description: 房间页主动同步当前 Room Cell 快照；只读，不刷新 heartbeat，不隐式 JoinRoom。gateway 使用 access token user_id 作为 viewer，room-service 要求 viewer 仍在该房间。
      security:
        - BearerAuth: []
      parameters:
        - name: room_id
          in: query
          required: true
          type: string
          pattern: "^[A-Za-z0-9_-]{1,48}$"
          maxLength: 48
      responses:
        "200":
          description: 查询成功，`data.room` 返回完整房间快照。
          schema:
            $ref: "#/definitions/RoomSnapshotEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/{room_id}/banned-users:
    get:
      tags:
        - rooms
      summary: 查询房间黑名单列表
      operationId: listRoomBannedUsers
      description: 房主或房管分页查看当前仍有效的房间踢人列表；已过期和已解封用户不返回。
      security:
        - BearerAuth: []
      parameters:
        - name: room_id
          in: path
          required: true
          type: string
          pattern: "^[A-Za-z0-9_-]{1,48}$"
          maxLength: 48
        - name: page
          in: query
          required: false
          type: integer
          format: int32
          default: 1
        - name: page_size
          in: query
          required: false
          type: integer
          format: int32
          default: 20
      responses:
        "200":
          description: 返回房间当前仍有效的黑名单用户及展示资料。
          schema:
            $ref: "#/definitions/RoomBannedUsersEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/{room_id}/follow:
    post:
      tags:
        - rooms
      summary: 关注房间
      operationId: followRoom
      description: 使用 access token user_id 建立当前用户对房间的关注关系；重复关注幂等，`followed_at_ms` 不因重复点击刷新。
      security:
        - BearerAuth: []
      parameters:
        - name: room_id
          in: path
          required: true
          type: string
          pattern: "^[A-Za-z0-9_-]{1,48}$"
          maxLength: 48
      responses:
        "200":
          description: 关注成功，`data.is_followed=true`。
          schema:
            $ref: "#/definitions/RoomFollowEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "502":
          $ref: "#/responses/UpstreamError"
    delete:
      tags:
        - rooms
      summary: 取消关注房间
      operationId: unfollowRoom
      description: 使用 access token user_id 取消当前用户对房间的关注关系；未关注时按幂等成功返回 `is_followed=false`。
      security:
        - BearerAuth: []
      parameters:
        - name: room_id
          in: path
          required: true
          type: string
          pattern: "^[A-Za-z0-9_-]{1,48}$"
          maxLength: 48
      responses:
        "200":
          description: 取消成功，`data.is_followed=false`。
          schema:
            $ref: "#/definitions/RoomFollowEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/create:
    post:
      tags:
        - rooms
      summary: 创建房间
      operationId: createRoom
      description: |
        gateway 从 access token 取当前 `user_id` 写入 room-service `RequestMeta.actor_user_id`，room-service 由该 actor 确定 owner。
        请求体不接收 `room_id` 或 `owner_user_id`；`command_id` 由客户端按创建动作生成，gateway 生成内部 room_id。
        room-service 会在返回前同步确保腾讯 IM 房间群存在；创建成功后 `data.room.im_group_id` 可直接用于 JoinRoom 成功后的腾讯 IM SDK joinGroup。
        同一个登录用户只能作为 owner 创建一个房间；已有房间时返回 409 Conflict。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/CreateRoomRequest"
      responses:
        "200":
          description: 创建成功，`data` 返回房间首屏基础数据和已存在的腾讯 IM 群 ID。
          schema:
            $ref: "#/definitions/CreateRoomEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/profile/update:
    post:
      tags:
        - rooms
      summary: 修改房间资料和座位数
      operationId: updateRoomProfile
      description: |
        App 房主在房间内修改房间名、头像、简介和座位数。所有状态变更经过 room-service Room Cell；缩小座位数时，被删除的高编号麦位必须全部空闲且未锁。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/UpdateRoomProfileRequest"
      responses:
        "200":
          description: 修改成功，`data` 返回最新房间信息和麦位列表。
          schema:
            $ref: "#/definitions/UpdateRoomProfileEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "409":
          $ref: "#/responses/Conflict"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/join:
    post:
      tags:
        - rooms
      summary: 加入房间
      operationId: joinRoom
      description: JoinRoom 是业务 presence、IM 入群和 RTC 进房的权限分界点。成功后响应返回首屏房间数据、`im.group_id` 和内嵌 `rtc.token`；RTC 签发失败时仍返回房间数据，并设置 `rtc.available=false`。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/JoinRoomRequest"
      responses:
        "200":
          description: 加入成功，`data` 返回首屏初始化数据和可选 RTC token。
          schema:
            $ref: "#/definitions/JoinRoomEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/heartbeat:
    post:
      tags:
        - rooms
      summary: 刷新房间业务 presence
      operationId: roomHeartbeat
      description: 心跳只刷新已经存在的房间 presence；用户不在房间时返回 404，不会隐式 JoinRoom。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/RoomHeartbeatRequest"
      responses:
        "200":
          description: 心跳成功，`data` 返回刷新后的用户房间态和房间快照。
          schema:
            $ref: "#/definitions/RoomHeartbeatEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/leave:
    post:
      tags:
        - rooms
      summary: 离开房间
      operationId: leaveRoom
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/LeaveRoomRequest"
      responses:
        "200":
          description: 离房成功，`data` 返回最新房间快照。
          schema:
            $ref: "#/definitions/LeaveRoomEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/mic/up:
    post:
      tags:
        - rooms
      summary: 上麦
      operationId: micUp
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/MicUpRequest"
      responses:
        "200":
          description: 上麦成功，`data` 返回目标麦位和最新房间快照。
          schema:
            $ref: "#/definitions/MicUpEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/mic/down:
    post:
      tags:
        - rooms
      summary: 下麦
      operationId: micDown
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/MicDownRequest"
      responses:
        "200":
          description: 下麦成功，`data` 返回目标麦位和最新房间快照。
          schema:
            $ref: "#/definitions/MicDownEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/mic/change:
    post:
      tags:
        - rooms
      summary: 调整麦位
      operationId: changeMicSeat
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/ChangeMicSeatRequest"
      responses:
        "200":
          description: 调整成功，`data` 返回最新房间快照。
          schema:
            $ref: "#/definitions/ChangeMicSeatEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/mic/publishing/confirm:
    post:
      tags:
        - rooms
      summary: 确认 RTC 音频发布成功
      operationId: confirmMicPublishing
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/ConfirmMicPublishingRequest"
      responses:
        "200":
          description: 确认成功或旧事件被安全忽略，`data` 返回最新房间快照。
          schema:
            $ref: "#/definitions/ConfirmMicPublishingEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/mic/lock:
    post:
      tags:
        - rooms
      summary: 锁定或解锁麦位
      operationId: setMicSeatLock
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/SetMicSeatLockRequest"
      responses:
        "200":
          description: 锁麦状态修改成功，`data` 返回最新房间快照。
          schema:
            $ref: "#/definitions/SetMicSeatLockEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/chat/enabled:
    post:
      tags:
        - rooms
      summary: 开启或关闭房间公屏
      operationId: setChatEnabled
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/SetChatEnabledRequest"
      responses:
        "200":
          description: 公屏开关修改成功，`data` 返回最新房间快照。
          schema:
            $ref: "#/definitions/SetChatEnabledEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/password:
    post:
      tags:
        - rooms
      summary: 设置或清空房间密码
      operationId: setRoomPassword
      description: 仅房主可调用。`locked=true` 时 `password` 必须非空；`locked=false` 清空密码并解除锁房。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/SetRoomPasswordRequest"
      responses:
        "200":
          description: 密码状态修改成功，`data.room.locked` 返回最新锁房标识。
          schema:
            $ref: "#/definitions/SetRoomPasswordEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/admin/set:
    post:
      tags:
        - rooms
      summary: 添加或移除房间管理员
      operationId: setRoomAdmin
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/SetRoomAdminRequest"
      responses:
        "200":
          description: 管理员集合修改成功，`data` 返回最新房间快照。
          schema:
            $ref: "#/definitions/SetRoomAdminEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/user/mute:
    post:
      tags:
        - rooms
      summary: 设置房间内禁言
      operationId: muteUser
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/MuteUserRequest"
      responses:
        "200":
          description: 禁言状态修改成功，`data` 返回最新房间快照。
          schema:
            $ref: "#/definitions/MuteUserEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/user/kick:
    post:
      tags:
        - rooms
      summary: 踢出房间用户
      operationId: kickUser
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/KickUserRequest"
      responses:
        "200":
          description: 踢人成功，`data` 返回最新房间快照。
          schema:
            $ref: "#/definitions/KickUserEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/user/unban:
    post:
      tags:
        - rooms
      summary: 解除房间 ban
      operationId: unbanUser
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/UnbanUserRequest"
      responses:
        "200":
          description: 解封成功，`data` 返回最新房间快照，不自动恢复 presence、麦位或管理员身份。
          schema:
            $ref: "#/definitions/UnbanUserEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/rooms/gift/send:
    post:
      tags:
        - rooms
      summary: 发送礼物
      operationId: sendGift
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/SendGiftRequest"
      responses:
        "200":
          description: 送礼成功，`data` 返回账单凭证、热度、本地礼物榜和房间快照。
          schema:
            $ref: "#/definitions/SendGiftEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/resources:
    get:
      tags:
        - resources
      summary: App 资源列表
      operationId: listResources
      parameters:
        - name: resource_type
          in: query
          required: false
          type: string
          enum: [avatar_frame, profile_card, coin, vehicle, chat_bubble, badge, floating_screen, gift, mic_seat_icon, mic_seat_animation, emoji_pack]
        - name: keyword
          in: query
          required: false
          type: string
        - name: page
          in: query
          required: false
          type: integer
          format: int32
        - name: page_size
          in: query
          required: false
          type: integer
          format: int32
        - name: region_id
          in: query
          required: false
          type: integer
          format: int64
          description: 区域 ID；传入后返回该区域和 GLOBAL 兜底礼物，不传时只返回 GLOBAL 兜底礼物。
      responses:
        "200":
          description: 返回当前 App active 资源列表。
          schema:
            $ref: "#/definitions/ResourceListEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/manager-center/resource-grants/resources:
    get:
      tags:
        - manager-center
      summary: 经理中心可赠送资源列表
      operationId: listManagerGrantResources
      description: gateway 先校验当前用户拥有 `manager_resource_grant` capability，再从 wallet-service 查询 `status=active AND grantable=TRUE AND manager_grant_enabled=TRUE` 的资源。
      security:
        - BearerAuth: []
      parameters:
        - name: resource_type
          in: query
          required: false
          type: string
          enum: [avatar_frame, profile_card, coin, vehicle, chat_bubble, badge, floating_screen, gift, mic_seat_icon, mic_seat_animation, emoji_pack]
        - name: page
          in: query
          required: false
          type: integer
          format: int32
        - name: page_size
          in: query
          required: false
          type: integer
          format: int32
          maximum: 20
      responses:
        "200":
          description: 返回 H5 展示和提交所需的最小资源字段。
          schema:
            $ref: "#/definitions/ManagerGrantResourceListEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/manager-center/resource-grants:
    post:
      tags:
        - manager-center
      summary: 经理中心赠送单个资源
      operationId: grantManagerResource
      description: 客户端提交命令 ID、目标用户、资源 ID 和可选有效期；数量固定为 1，有效期只能是 7/30/90 天，未传默认 7 天，`grant_source` 固定为 `manager_center`。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/ManagerResourceGrantRequest"
      responses:
        "200":
          description: 赠送成功，返回资源赠送事实。
          schema:
            $ref: "#/definitions/ManagerResourceGrantEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/business/users/lookup:
    get:
      tags:
        - business
      summary: 业务场景用户查询
      operationId: lookupBusinessUsers
      description: 首版只支持 `scene=manager_resource_grant`。user-service 会按 scene 校验 actor 能力，并只返回同 app_code 的 active 用户最小资料。
      security:
        - BearerAuth: []
      parameters:
        - name: scene
          in: query
          required: true
          type: string
          enum: [manager_resource_grant]
        - name: keyword
          in: query
          required: true
          type: string
          description: 展示短号、用户 ID 或至少 2 个字符的昵称片段。
        - name: page_size
          in: query
          required: false
          type: integer
          format: int32
          maximum: 20
      responses:
        "200":
          description: 查询成功。
          schema:
            $ref: "#/definitions/BusinessUserLookupEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/resource-groups/{group_id}:
    get:
      tags:
        - resources
      summary: App 资源组详情
      operationId: getResourceGroup
      parameters:
        - $ref: "#/parameters/ResourceGroupIDPath"
      responses:
        "200":
          description: 返回 active 资源组及组内资源。
          schema:
            $ref: "#/definitions/ResourceGroupEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "404":
          $ref: "#/responses/NotFound"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/gifts:
    get:
      tags:
        - resources
      summary: App 礼物列表
      operationId: listGifts
      parameters:
        - name: keyword
          in: query
          required: false
          type: string
        - name: page
          in: query
          required: false
          type: integer
          format: int32
        - name: page_size
          in: query
          required: false
          type: integer
          format: int32
        - name: region_id
          in: query
          required: false
          type: integer
          format: int64
          description: 区域 ID；返回该区域和 GLOBAL 兜底礼物。
      responses:
        "200":
          description: 返回当前 active、区域可用且在有效期内的礼物配置；礼物资源必须来自 `resource_type=gift`。
          schema:
            $ref: "#/definitions/GiftListEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/gift-tabs:
    get:
      tags:
        - resources
      summary: App 礼物 Tab 配置列表
      operationId: listGiftTabs
      parameters:
        - name: region_id
          in: query
          required: false
          type: integer
          format: int64
          description: 不传时预加载全部 active 礼物；传入时只返回 GLOBAL 和该区域可用礼物。
      responses:
        "200":
          description: 返回后台启用的礼物 Tab 配置和当前 active 礼物；不按礼物数量过滤 Tab，即使 Tab 下当前没有礼物也返回 gifts 空数组。
          schema:
            $ref: "#/definitions/GiftTabListEnvelope"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/me/resources:
    get:
      tags:
        - resources
      summary: 我的资源权益
      operationId: listMyResources
      security:
        - BearerAuth: []
      parameters:
        - name: resource_type
          in: query
          required: false
          type: string
          enum: [avatar_frame, profile_card, coin, vehicle, chat_bubble, badge, floating_screen, gift, mic_seat_icon, mic_seat_animation, emoji_pack]
      responses:
        "200":
          description: 返回当前用户有效资源权益。
          schema:
            $ref: "#/definitions/UserResourceListEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/users/me/resources/{resource_id}/equip:
    post:
      tags:
        - resources
      summary: 佩戴我的资源
      operationId: equipMyResource
      security:
        - BearerAuth: []
      parameters:
        - $ref: "#/parameters/ResourceIDPath"
        - name: body
          in: body
          required: false
          schema:
            $ref: "#/definitions/EquipUserResourceRequest"
      responses:
        "200":
          description: 返回被佩戴的有效资源权益。
          schema:
            $ref: "#/definitions/UserResourceEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/messages/tabs:
    get:
      tags:
        - messages
      summary: 消息 tab 分区摘要
      operationId: listMessageTabs
      description: 返回 user/system/activity 三个分区；user 分区只声明来源为腾讯云 IM SDK，不返回私聊内容。
      security:
        - BearerAuth: []
      parameters:
      responses:
        "200":
          description: 查询成功。
          schema:
            $ref: "#/definitions/MessageTabsEnvelope"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/messages:
    get:
      tags:
        - messages
      summary: system/activity 消息列表
      operationId: listInboxMessages
      description: 只读取当前 app_code 和当前用户下 visible、未删除、未过期的 system/activity 消息，按 sent_at_ms 倒序游标分页。
      security:
        - BearerAuth: []
      parameters:
        - name: section
          in: query
          required: true
          type: string
          enum: [system, activity]
        - name: page_size
          in: query
          required: false
          type: integer
          format: int32
        - name: page_token
          in: query
          required: false
          type: string
      responses:
        "200":
          description: 查询成功。
          schema:
            $ref: "#/definitions/MessageListEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/messages/read-all:
    post:
      tags:
        - messages
      summary: 标记分区全部已读
      operationId: markInboxSectionRead
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/MessageReadAllRequest"
      responses:
        "200":
          description: 已读成功；重复请求成功且 read_count 可为 0。
          schema:
            $ref: "#/definitions/MessageReadAllEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/messages/{message_id}/read:
    post:
      tags:
        - messages
      summary: 标记单条消息已读
      operationId: markInboxMessageRead
      security:
        - BearerAuth: []
      parameters:
        - name: message_id
          in: path
          required: true
          type: string
      responses:
        "200":
          description: 已读成功；重复请求不覆盖首次 read_at_ms。
          schema:
            $ref: "#/definitions/MessageReadEnvelope"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/messages/{message_id}:
    delete:
      tags:
        - messages
      summary: 删除单条消息
      operationId: deleteInboxMessage
      description: 删除是当前用户侧隐藏，不物理删除 inbox 事实；不存在、已删除或不属于当前用户均返回 NOT_FOUND。
      security:
        - BearerAuth: []
      parameters:
        - name: message_id
          in: path
          required: true
          type: string
      responses:
        "200":
          description: 删除成功。
          schema:
            $ref: "#/definitions/MessageDeleteEnvelope"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/wallet/recharge/products:
    get:
      tags:
        - wallet
      summary: 获取充值商品列表
      operationId: listRechargeProducts
      description: gateway 根据当前登录用户资料中的 `region_id` 和 App 平台筛选已上架内购商品；平台可通过 `platform` query 覆盖，默认读取 `X-App-Platform` / `X-Platform` 请求头。
      security:
        - BearerAuth: []
      parameters:
        - name: platform
          in: query
          required: false
          type: string
          enum: [android, ios]
          description: 可选平台覆盖值；不传时读取 App 平台请求头。
        - name: X-App-Platform
          in: header
          required: false
          type: string
          enum: [android, ios]
          description: App 平台请求头。
        - name: X-Platform
          in: header
          required: false
          type: string
          enum: [android, ios]
          description: 兼容平台请求头。
      responses:
        "200":
          description: 返回当前用户区域和平台可购买的上架商品。
          schema:
            $ref: "#/definitions/RechargeProductListEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/wallet/payments/google/confirm:
    post:
      tags:
        - wallet
      summary: 确认 Google Play 充值支付
      operationId: confirmGooglePayment
      description: App 支付成功后提交 Google purchase token；后端调用 Google Play Developer API 校验，成功后写入钱包账本、充值记录、payment_orders 审计并尝试 consume。接口支持按 purchase token 幂等重试。
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/GooglePaymentConfirmRequest"
      responses:
        "200":
          description: 校验成功并已入账；`consume_state=consume_pending` 也表示已入账成功，只是 Google consume 待后续重试。
          schema:
            $ref: "#/definitions/GooglePaymentConfirmEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
  /api/v1/wallet/coin-seller/transfer:
    post:
      tags:
        - wallet
      summary: 币商给玩家转金币
      operationId: transferCoinFromSeller
      security:
        - BearerAuth: []
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/CoinSellerTransferRequest"
      responses:
        "200":
          description: 转账成功，`data` 返回账务交易、双方账后余额和充值金额口径。
          schema:
            $ref: "#/definitions/CoinSellerTransferEnvelope"
        "400":
          $ref: "#/responses/BadRequest"
        "401":
          $ref: "#/responses/Unauthorized"
        "403":
          $ref: "#/responses/Forbidden"
        "404":
          $ref: "#/responses/NotFound"
        "409":
          $ref: "#/responses/Conflict"
        "500":
          $ref: "#/responses/Internal"
        "502":
          $ref: "#/responses/UpstreamError"
definitions:
  GatewayOKEnvelopeBase:
    type: object
    required:
      - code
      - message
      - request_id
    properties:
      code:
        type: string
        enum:
          - OK
      message:
        type: string
        enum:
          - ok
      request_id:
        type: string
    description: gateway 业务 API 成功响应外壳。
  ErrorEnvelope:
    type: object
    required:
      - code
      - message
      - request_id
    properties:
      code:
        type: string
        enum:
          - INVALID_JSON
          - UNAUTHORIZED
          - UPSTREAM_ERROR
          - INTERNAL_ERROR
          - INVALID_ARGUMENT
          - RATE_LIMITED
          - AUTH_FAILED
          - SESSION_EXPIRED
          - SESSION_REVOKED
          - PASSWORD_ALREADY_SET
          - DISPLAY_USER_ID_INVALID
          - DISPLAY_USER_ID_EXISTS
          - DISPLAY_USER_ID_COOLDOWN
          - COUNTRY_CHANGE_COOLDOWN
          - DISPLAY_USER_ID_NOT_FOUND
          - DISPLAY_USER_ID_PRETTY_NOT_AVAILABLE
          - DISPLAY_USER_ID_PRETTY_ACTIVE
          - DISPLAY_USER_ID_LEASE_EXPIRED
          - DISPLAY_USER_ID_PAYMENT_REQUIRED
          - USER_DISABLED
          - PERMISSION_DENIED
          - NOT_FOUND
          - CONFLICT
          - INSUFFICIENT_BALANCE
      message:
        type: string
        enum:
          - invalid request body
          - unauthorized
          - upstream service error
          - internal error
          - invalid argument
          - rate limited
          - authentication failed
          - conflict
          - insufficient balance
          - permission denied
          - not found
      request_id:
        type: string
    description: gateway 业务 API 失败响应外壳；失败响应不返回 `data`。
  HealthResponse:
    type: object
    properties:
      status:
        type: string
        enum:
          - ok
          - fail
      service:
        type: string
        example: gateway-service
      node_id:
        type: string
      time_unix_ms:
        type: integer
        format: int64
      checks:
        type: array
        items:
          $ref: "#/definitions/HealthCheck"
  HealthCheck:
    type: object
    properties:
      name:
        type: string
        example: room_grpc
      status:
        type: string
        enum:
          - ok
          - fail
      message:
        type: string
  LoginPasswordRequest:
    type: object
    required:
      - account
      - password
      - device_id
    description: 账号就是用户当前有效短号。
    properties:
      account:
        type: string
        example: "123456"
      password:
        type: string
        example: "1234567"
      device_id:
        type: string
  LoginThirdPartyRequest:
    type: object
    description: 三方登录即注册；首次注册时资料字段写入 user-service users 主记录。`ip`、`user_agent` 和 `country_by_ip` 由 gateway/服务端上下文生成，不接受客户端 JSON。
    required:
      - provider
      - credential
      - device_id
      - platform
    properties:
      provider:
        type: string
        example: firebase
      credential:
        type: string
        description: Firebase Auth ID token；不能提交 Google account id、email 或 access token。
      username:
        type: string
        maxLength: 64
      gender:
        type: string
        maxLength: 32
      country:
        type: string
        maxLength: 3
        pattern: "^[A-Za-z]{2,3}$"
        description: 国家主数据 country_code，支持 2 到 3 位英文，服务端会转大写并要求 active。
      invite_code:
        type: string
        maxLength: 64
        description: 可选邀请码。
      device_id:
        type: string
        maxLength: 128
      device:
        type: string
        maxLength: 128
      os_version:
        type: string
        maxLength: 64
      avatar:
        type: string
        maxLength: 512
        description: 绝对 http/https URL。
      birth:
        type: string
        description: yyyy-mm-dd。
      app_version:
        type: string
        maxLength: 64
      build_number:
        type: string
        maxLength: 64
      source:
        type: string
        maxLength: 64
      install_channel:
        type: string
        maxLength: 64
      campaign:
        type: string
        maxLength: 128
      platform:
        type: string
        maxLength: 16
        enum:
          - android
          - ios
      language:
        type: string
        maxLength: 32
        description: BCP 47 language tag subset，例如 en-US。
      timezone:
        type: string
        maxLength: 64
        description: IANA timezone name，例如 America/Los_Angeles。
  SetPasswordRequest:
    type: object
    properties:
      password:
        type: string
  RefreshTokenRequest:
    type: object
    properties:
      refresh_token:
        type: string
        description: 登录和 refresh 响应返回；CompleteOnboarding 不轮换 refresh token，可能为空或缺失。
      device_id:
        type: string
  LogoutRequest:
    type: object
    properties:
      refresh_token:
        type: string
      session_id:
        type: string
  AuthTokenData:
    type: object
    properties:
      user_id:
        type: string
        description: 数值型用户 ID 的字符串形式。
      display_user_id:
        type: string
      default_display_user_id:
        type: string
      display_user_id_kind:
        type: string
      display_user_id_expires_at_ms:
        type: integer
        format: int64
      session_id:
        type: string
      access_token:
        type: string
      refresh_token:
        type: string
      expires_in_sec:
        type: integer
        format: int64
      token_type:
        type: string
        example: Bearer
      is_new_user:
        type: boolean
      profile_completed:
        type: boolean
      onboarding_status:
        type: string
        enum:
          - profile_required
          - completed
  PasswordSetData:
    type: object
    properties:
      password_set:
        type: boolean
  LogoutData:
    type: object
    properties:
      revoked:
        type: boolean
  TencentIMUserSigData:
    type: object
    properties:
      sdk_app_id:
        type: integer
        format: int64
      user_id:
        type: string
        description: 腾讯云 IM identifier；当前固定使用内部长 `user_id` 的十进制字符串。
      user_sig:
        type: string
      expire_at_ms:
        type: integer
        format: int64
    description: 客户端登录腾讯云 IM SDK 所需票据。
  TencentRTCTokenRequest:
    type: object
    required:
      - room_id
    properties:
      room_id:
        type: string
        pattern: "^[A-Za-z0-9_-]{1,48}$"
        maxLength: 48
        description: 内部房间 ID，同时作为腾讯 RTC `strRoomId` 使用。
  TencentRTCTokenData:
    type: object
    properties:
      sdk_app_id:
        type: integer
        format: int64
      user_id:
        type: string
        description: 腾讯 RTC UserID；当前固定使用内部长 `user_id` 的十进制字符串。
      rtc_user_id:
        type: string
        description: 与 `user_id` 相同，帮助客户端显式区分业务身份和 RTC SDK 身份。
      user_sig:
        type: string
        description: 腾讯 RTC UserSig，客户端用它进入腾讯 RTC；不是 SecretKey。
      expire_at_ms:
        type: integer
        format: int64
      room_id:
        type: string
        description: 内部房间 ID。
      rtc_room_id:
        type: string
        description: 腾讯 RTC 字符串房间 ID，值等于 `room_id`。
      rtc_room_id_type:
        type: string
        enum:
          - string
      str_room_id:
        type: string
        description: 客户端调用 TRTC enterRoom 时使用的 `strRoomId`。
      app_scene:
        type: string
        enum:
          - voice_chat_room
      role:
        type: string
        enum:
          - audience
        description: 首版固定返回 audience；上麦成功后客户端再切换发布角色。
    description: 客户端进入腾讯 RTC 语音房所需票据和字符串房间映射。
  UploadFileData:
    type: object
    properties:
      url:
        type: string
        description: 公开访问 URL，可写入用户头像、房间头像或其他业务资料字段。
      object_key:
        type: string
        description: COS object key，便于后续服务端删除或审计。
      content_type:
        type: string
        description: 服务端确认后的文件 MIME 类型。
      size_bytes:
        type: integer
        format: int64
        description: 上传文件字节数。
  BindPushTokenRequest:
    type: object
    required:
      - device_id
      - push_token
      - platform
    properties:
      device_id:
        type: string
        maxLength: 128
        description: App 安装级稳定 ID。
      push_token:
        type: string
        maxLength: 512
        description: APNS/FCM 等系统推送 token。
      provider:
        type: string
        maxLength: 32
        description: 可选；为空时 android 默认 fcm，ios 默认 apns。
      platform:
        type: string
        enum:
          - android
          - ios
      app_version:
        type: string
        maxLength: 64
      language:
        type: string
        maxLength: 32
      timezone:
        type: string
        maxLength: 64
  DeletePushTokenRequest:
    type: object
    required:
      - device_id
    properties:
      device_id:
        type: string
        maxLength: 128
      push_token:
        type: string
        maxLength: 512
        description: 可选；为空时按当前用户和 device_id 失效 active token。
  BindPushTokenData:
    type: object
    required:
      - bound
      - updated_at_ms
    properties:
      bound:
        type: boolean
      updated_at_ms:
        type: integer
        format: int64
      gifts:
        type: array
        description: 当前 Tab 下的 active 礼物列表；没有礼物时返回空数组。
        items:
          $ref: "#/definitions/GiftConfigData"
  DeletePushTokenData:
    type: object
    required:
      - deleted
      - updated_at_ms
    properties:
      deleted:
        type: boolean
      updated_at_ms:
        type: integer
        format: int64
  TencentIMCallbackRequest:
    type: object
    properties:
      CallbackCommand:
        type: string
        enum:
          - Group.CallbackBeforeApplyJoinGroup
          - Group.CallbackBeforeSendMsg
      GroupId:
        type: string
        description: 映射为内部 `room_id`。
      Requestor_Account:
        type: string
        description: 入群申请用户；必须是内部长 `user_id` 的十进制字符串。
      From_Account:
        type: string
        description: 发言用户；必须是内部长 `user_id` 的十进制字符串。
      Operator_Account:
        type: string
        description: 腾讯云 IM 回调操作者账号字段。
  TencentIMCallbackResponse:
    type: object
    properties:
      ActionStatus:
        type: string
        enum:
          - OK
      ErrorInfo:
        type: string
      ErrorCode:
        type: integer
        format: int32
        enum:
          - 0
          - 1
    description: 腾讯云 IM 原生回调响应；`ErrorCode=0` 允许，`ErrorCode=1` 拒绝本次入群或发言。
  TencentRTCCallbackRequest:
    type: object
    properties:
      EventGroupId:
        type: integer
        format: int32
        enum:
          - 1
          - 2
        description: 1 为房间事件组，2 为媒体事件组。
      EventType:
        type: integer
        format: int32
        enum:
          - 104
          - 203
          - 204
        description: 当前只消费退出房间、开始推送音频、停止推送音频。
      CallbackTs:
        type: integer
        format: int64
      EventInfo:
        type: object
        properties:
          RoomId:
            description: 腾讯 RTC 房间 ID；本系统要求等于内部字符串 `room_id`。
          UserId:
            type: string
            description: 腾讯 RTC UserID；必须是内部长 `user_id` 的十进制字符串。
          EventTs:
            type: integer
            format: int64
          EventMsTs:
            type: integer
            format: int64
          Reason:
            type: integer
            format: int32
    description: 腾讯 RTC 原生回调请求；签名必须基于原始 body，不要重新序列化后计算。
  TencentRTCCallbackResponse:
    type: object
    properties:
      code:
        type: integer
        format: int32
        enum:
          - 0
          - 1
      message:
        type: string
    description: 腾讯 RTC 回调响应；`code=0` 表示 gateway 已接受或安全忽略该事件。
  UserIdentityData:
    type: object
    properties:
      user_id:
        type: string
        description: 数值型用户 ID 的字符串形式。
      display_user_id:
        type: string
      status:
        type: string
      default_display_user_id:
        type: string
      display_user_id_kind:
        type: string
      display_user_id_expires_at_ms:
        type: integer
        format: int64
      lease_id:
        type: string
  UserHostIdentityData:
    type: object
    properties:
      is_host:
        type: boolean
        description: 用户是否拥有 active host profile。
      is_agent:
        type: boolean
        description: 用户是否拥有 Agency 入口身份；active Agency owner 或 Agency 来源主播都可能为 true。
      is_manager:
        type: boolean
        description: 用户是否拥有经理中心身份；首版等价于 active Agency owner。
      is_bd:
        type: boolean
        description: 用户是否拥有 active BD 或 BD Leader 身份。
      is_bd_leader:
        type: boolean
        description: 用户是否拥有 active BD Leader 身份。
      is_coin_seller:
        type: boolean
        description: 用户是否拥有 active 币商身份。
  MyOverviewRolesData:
    type: object
    required:
      - is_host
      - is_agency
      - is_manager
      - is_bd
      - is_bd_leader
      - is_coin_seller
      - pending_role_invitations
    properties:
      is_host:
        type: boolean
      is_agency:
        type: boolean
      is_manager:
        type: boolean
      is_bd:
        type: boolean
      is_bd_leader:
        type: boolean
      is_coin_seller:
        type: boolean
      host_status:
        type: string
      agency_id:
        type: integer
        format: int64
      bd_id:
        type: integer
        format: int64
      bd_status:
        type: string
      coin_seller_status:
        type: string
      pending_role_invitations:
        type: integer
        format: int64
      unavailable:
        type: boolean
        description: 角色上游不可用时为 true；此时所有特权身份按 false 返回。
  MyOverviewProfileStatsData:
    type: object
    required:
      - visitors_count
      - following_count
      - friends_count
      - updated_at_ms
    properties:
      visitors_count:
        type: integer
        format: int64
      following_count:
        type: integer
        format: int64
      friends_count:
        type: integer
        format: int64
      updated_at_ms:
        type: integer
        format: int64
      unavailable:
        type: boolean
        description: 计数 read model 上游不可用时为 true；客户端可按 0 展示。
  MyOverviewWalletData:
    type: object
    required:
      - coin_amount
      - updated_at_ms
    properties:
      coin_amount:
        type: integer
        format: int64
        description: 我的页首屏只展示金币余额。
      updated_at_ms:
        type: integer
        format: int64
      unavailable:
        type: boolean
        description: 钱包上游不可用时为 true。
  MyOverviewVIPData:
    type: object
    properties:
      level:
        type: integer
        format: int32
      name:
        type: string
      active:
        type: boolean
      started_at_ms:
        type: integer
        format: int64
      expires_at_ms:
        type: integer
        format: int64
      unavailable:
        type: boolean
        description: VIP 上游不可用时为 true。
  MyOverviewEntryData:
    type: object
    required:
      - key
      - visible
      - enabled
      - route
      - icon_key
      - badge_count
      - order
    properties:
      key:
        type: string
        enum:
          - store
          - bag
          - level
          - task
          - apply_host
          - host_center
          - agency_center
          - bd_center
          - bd_leader_center
          - coin_seller_center
          - settings
          - language
      visible:
        type: boolean
      enabled:
        type: boolean
      route:
        type: string
      icon_key:
        type: string
      badge_count:
        type: integer
        format: int64
      order:
        type: integer
        format: int32
  MyOverviewData:
    type: object
    required:
      - profile
      - profile_stats
      - wallet
      - vip
      - roles
      - entries
      - server_time_ms
    properties:
      profile:
        $ref: "#/definitions/UserProfileData"
      profile_stats:
        $ref: "#/definitions/MyOverviewProfileStatsData"
      wallet:
        $ref: "#/definitions/MyOverviewWalletData"
      vip:
        $ref: "#/definitions/MyOverviewVIPData"
      roles:
        $ref: "#/definitions/MyOverviewRolesData"
      entries:
        type: array
        items:
          $ref: "#/definitions/MyOverviewEntryData"
      server_time_ms:
        type: integer
        format: int64
  MyInviteOverviewData:
    type: object
    required:
      - my_invite_code
      - invite_enabled
      - invite_count
      - valid_invite_count
      - valid_invite_threshold_coin
    properties:
      my_invite_code:
        type: string
      invite_enabled:
        type: boolean
      invite_count:
        type: integer
        format: int64
      valid_invite_count:
        type: integer
        format: int64
      valid_invite_threshold_coin:
        type: integer
        format: int64
  UserProfileData:
    type: object
    properties:
      user_id:
        type: string
        description: 数值型用户 ID 的字符串形式。
      display_user_id:
        type: string
      default_display_user_id:
        type: string
      display_user_id_kind:
        type: string
      display_user_id_expires_at_ms:
        type: integer
        format: int64
      username:
        type: string
      gender:
        type: string
      country:
        type: string
        maxLength: 3
        description: 用户选择的国家主数据 country_code。
      country_id:
        type: integer
        format: int64
        description: 国家主数据内部 ID；0 表示未命中国家表。
      country_name:
        type: string
      country_display_name:
        type: string
      iso_numeric:
        type: string
        description: ISO numeric / UNSD M49 三位字符串，客户端不能按数字解析。
      phone_country_code:
        type: string
        description: E.164 国家呼叫码，例如 `+86`；可能为空或多个国家共享。
      country_enabled:
        type: boolean
        description: 当前国家是否仍对 App 注册和改国家开放。
      region_id:
        type: integer
        format: int64
        description: 国家映射出的区域 ID；0 表示无区域归属。
      region_code:
        type: string
      region_name:
        type: string
      avatar:
        type: string
      birth:
        type: string
        description: yyyy-mm-dd。
      language:
        type: string
      profile_completed:
        type: boolean
      profile_completed_at_ms:
        type: integer
        format: int64
      onboarding_status:
        type: string
        enum:
          - profile_required
          - completed
      updated_at_ms:
        type: integer
        format: int64
      next_country_change_allowed_at_ms:
        type: integer
        format: int64
  UserProfileBatchData:
    type: object
    required:
      - user_id
      - display_user_id
      - username
      - app_code
    properties:
      user_id:
        type: string
        description: 数值型用户 ID 的字符串形式，避免客户端 JS 精度丢失。
      display_user_id:
        type: string
      username:
        type: string
      avatar:
        type: string
      gender:
        type: string
      country:
        type: string
      region_id:
        type: integer
        format: int64
      app_code:
        type: string
    description: 腾讯云 IM 会话列表展示资料；不包含手机号、登录凭证、实名或后台身份字段。
  UserProfilesBatchData:
    type: object
    required:
      - profiles
    properties:
      profiles:
        type: array
        items:
          $ref: "#/definitions/UserProfileBatchData"
  MessageTabSectionData:
    type: object
    required:
      - section
      - title
      - unread_count
      - source
    properties:
      section:
        type: string
        enum:
          - user
          - system
          - activity
      title:
        type: string
      unread_count:
        type: integer
        format: int64
      source:
        type: string
        enum:
          - tencent_im_sdk
          - backend
  MessageTabsData:
    type: object
    required:
      - sections
    properties:
      sections:
        type: array
        items:
          $ref: "#/definitions/MessageTabSectionData"
  InboxMessageData:
    type: object
    required:
      - message_id
      - title
      - summary
      - read
      - sent_at_ms
    properties:
      message_id:
        type: string
      title:
        type: string
      summary:
        type: string
      body:
        type: string
      icon_url:
        type: string
      image_url:
        type: string
      action_type:
        type: string
        description: 服务端白名单动作，例如 wallet_withdraw_detail、activity_detail、room_detail。
      action_param:
        type: string
      read:
        type: boolean
      sent_at_ms:
        type: integer
        format: int64
  MessageListData:
    type: object
    required:
      - section
      - items
      - next_page_token
    properties:
      section:
        type: string
        enum:
          - system
          - activity
      items:
        type: array
        items:
          $ref: "#/definitions/InboxMessageData"
      next_page_token:
        type: string
  MessageReadAllRequest:
    type: object
    required:
      - section
    properties:
      section:
        type: string
        enum:
          - system
          - activity
  MessageReadData:
    type: object
    required:
      - message_id
      - read
      - read_at_ms
    properties:
      message_id:
        type: string
      read:
        type: boolean
      read_at_ms:
        type: integer
        format: int64
  MessageReadAllData:
    type: object
    required:
      - section
      - read_count
    properties:
      section:
        type: string
        enum:
          - system
          - activity
      read_count:
        type: integer
        format: int64
  MessageDeleteData:
    type: object
    required:
      - message_id
      - deleted
    properties:
      message_id:
        type: string
      deleted:
        type: boolean
  CountryData:
    type: object
    properties:
      country_id:
        type: integer
        format: int64
      country_name:
        type: string
      country_code:
        type: string
        maxLength: 3
      iso_alpha3:
        type: string
        maxLength: 3
      iso_numeric:
        type: string
        description: 三位 numeric 字符串。
      country_display_name:
        type: string
      phone_country_code:
        type: string
      enabled:
        type: boolean
      flag:
        type: string
      sort_order:
        type: integer
        format: int32
  CountryListData:
    type: object
    properties:
      countries:
        type: array
        items:
          $ref: "#/definitions/CountryData"
  H5LinkData:
    type: object
    properties:
      key:
        type: string
        description: 后台 H5 配置 key，App 只对已接入的 key 做入口展示，例如 rank、explore_game_rank、game_rock、game_dice、vip、level、task。
      label:
        type: string
      url:
        type: string
        description: 后台配置的 H5 URL；未配置时为空字符串。
      updated_at_ms:
        type: integer
        format: int64
        description: 该入口最近更新时间；未配置时为 0。
  H5LinkListData:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: "#/definitions/H5LinkData"
      total:
        type: integer
        format: int32
  SplashScreenData:
    type: object
    properties:
      id:
        type: integer
        format: uint64
      cover_url:
        type: string
        description: 开屏图片 URL。
      type:
        type: string
        enum: [h5, app]
        description: h5 表示 param 是 H5 链接；app 表示 param 由客户端解释。
      param:
        type: string
      platform:
        type: string
        enum: [android, ios]
      sort_order:
        type: integer
        format: int32
      region_id:
        type: integer
        format: int64
      country_code:
        type: string
      description:
        type: string
      starts_at_ms:
        type: integer
        format: int64
      ends_at_ms:
        type: integer
        format: int64
      updated_at_ms:
        type: integer
        format: int64
  SplashScreenListData:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: "#/definitions/SplashScreenData"
      total:
        type: integer
        format: int32
  PopupData:
    type: object
    properties:
      id:
        type: integer
        format: uint64
      code:
        type: string
        description: 弹窗编码，同一个 App 下唯一，用于客户端本地频控和埋点识别。
      name:
        type: string
        description: 弹窗名字。
      image_url:
        type: string
        description: 弹窗图片 URL；为空表示无图片。
      jump_type:
        type: string
        enum: [h5, app]
        description: h5 表示 jump_url 是 H5 链接；app 表示 jump_url 由客户端解释。
      jump_url:
        type: string
      display_period_days:
        type: integer
        format: int32
        description: 展示周期天数；0 表示每次打开都展示。
      sort_order:
        type: integer
        format: int32
      starts_at_ms:
        type: integer
        format: int64
      ends_at_ms:
        type: integer
        format: int64
      updated_at_ms:
        type: integer
        format: int64
  PopupListData:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: "#/definitions/PopupData"
      total:
        type: integer
        format: int32
  AppBootstrapTab:
    type: object
    properties:
      key:
        type: string
        enum:
          - rooms
          - messages
          - me
      title:
        type: string
      enabled:
        type: boolean
  AppBootstrapData:
    type: object
    properties:
      app_code:
        type: string
      server_time_ms:
        type: integer
        format: int64
      force_upgrade:
        type: boolean
      maintenance:
        type: boolean
      minimum_version:
        type: string
      latest_version:
        type: string
      feature_flags:
        type: object
        additionalProperties:
          type: boolean
      bottom_tabs:
        type: array
        items:
          $ref: "#/definitions/AppBootstrapTab"
      config_versions:
        type: object
        additionalProperties:
          type: string
  AppVersionData:
    type: object
    properties:
      app_code:
        type: string
      platform:
        type: string
        enum: [android, ios]
      version:
        type: string
        description: 最新版本号，例如 1.2.0。
      build_number:
        type: integer
        format: int64
        description: 最新编译版本号，App 使用它和本地 build number 比较。
      force_update:
        type: boolean
        description: 当前客户端落后且后台最新版本要求强更时为 true。
      download_url:
        type: string
      description:
        type: string
      has_update:
        type: boolean
      current_build_number:
        type: integer
        format: int64
      updated_at_ms:
        type: integer
        format: int64
      server_time_ms:
        type: integer
        format: int64
  CompleteOnboardingRequest:
    type: object
    required:
      - username
      - avatar
      - gender
      - country
    properties:
      username:
        type: string
      avatar:
        type: string
        description: HTTP/HTTPS 头像 URL。
      gender:
        type: string
        maxLength: 32
      country:
        type: string
        maxLength: 3
        pattern: "^[A-Za-z]{2,3}$"
        description: 注册页从 `/api/v1/countries` 取得的 country_code。
      invite_code:
        type: string
        maxLength: 64
        description: 可选邀请码；非空时必须解析到有效邀请人。
  CompleteOnboardingData:
    allOf:
      - $ref: "#/definitions/UserProfileData"
      - type: object
        properties:
          invite:
            type: object
            properties:
              bound:
                type: boolean
              invite_code:
                type: string
              inviter_user_id:
                type: string
                description: 64 位用户 ID 使用字符串返回，未绑定时为空。
          token:
            $ref: "#/definitions/AuthTokenData"
            description: 注册完成后替换旧 access token；refresh_token 为空或不返回。
  UpdateUserProfileRequest:
    type: object
    properties:
      username:
        type: string
      avatar:
        type: string
      birth:
        type: string
        description: yyyy-mm-dd；传空字符串表示清空生日。
  ChangeUserCountryRequest:
    type: object
    properties:
      country:
        type: string
        maxLength: 3
        pattern: "^[A-Za-z]{2,3}$"
        description: 国家主数据 country_code，服务端会转大写并要求 `enabled=true`。
  ChangeDisplayUserIDRequest:
    type: object
    properties:
      new_display_user_id:
        type: string
      reason:
        type: string
  ApplyPrettyDisplayUserIDRequest:
    type: object
    properties:
      pretty_display_user_id:
        type: string
      lease_duration_ms:
        type: integer
        format: int64
      payment_receipt_id:
        type: string
  ResourceData:
    type: object
    properties:
      resource_id:
        type: integer
        format: int64
      resource_code:
        type: string
      resource_type:
        type: string
        enum: [avatar_frame, profile_card, coin, vehicle, chat_bubble, badge, floating_screen, gift, mic_seat_icon, mic_seat_animation, emoji_pack]
      name:
        type: string
      status:
        type: string
      grantable:
        type: boolean
      grant_strategy:
        type: string
      wallet_asset_type:
        type: string
      wallet_asset_amount:
        type: integer
        format: int64
      usage_scopes:
        type: array
        items:
          type: string
      asset_url:
        type: string
      preview_url:
        type: string
      animation_url:
        type: string
      metadata_json:
        type: string
      sort_order:
        type: integer
        format: int32
  ResourceListData:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: "#/definitions/ResourceData"
      total:
        type: integer
        format: int64
      page:
        type: integer
        format: int32
      page_size:
        type: integer
        format: int32
  ManagerGrantResourceData:
    type: object
    properties:
      resource_id:
        type: string
        description: 资源 ID；按字符串返回避免 64 位整数在客户端丢精度。
      resource_type:
        type: string
        enum: [avatar_frame, profile_card, coin, vehicle, chat_bubble, badge, floating_screen, gift, mic_seat_icon, mic_seat_animation, emoji_pack]
      name:
        type: string
      asset_url:
        type: string
      preview_url:
        type: string
      wallet_asset_type:
        type: string
      wallet_asset_amount:
        type: integer
        format: int64
      sort_order:
        type: integer
        format: int32
  ManagerGrantResourceListData:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: "#/definitions/ManagerGrantResourceData"
      total:
        type: integer
        format: int64
      page:
        type: integer
        format: int32
      page_size:
        type: integer
        format: int32
  BusinessUserLookupItem:
    type: object
    properties:
      user_id:
        type: string
        description: 用户 ID；按字符串返回避免 64 位整数在客户端丢精度。
      display_user_id:
        type: string
      username:
        type: string
      avatar:
        type: string
      status:
        type: string
        enum: [active, disabled, banned, unspecified]
      region_id:
        type: integer
        format: int64
      region_code:
        type: string
      region_name:
        type: string
  BusinessUserLookupData:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: "#/definitions/BusinessUserLookupItem"
      total:
        type: integer
        format: int32
      page_size:
        type: integer
        format: int32
  ManagerResourceGrantRequest:
    type: object
    required:
      - command_id
      - target_user_id
      - resource_id
    properties:
      command_id:
        type: string
        description: 客户端按用户动作生成的幂等命令 ID；同一动作重试必须复用。
      target_user_id:
        type: string
        description: 目标用户 ID；gateway 会校验用户存在且 active。
      resource_id:
        type: string
        description: 资源 ID；wallet-service 会在事务内复验 `manager_grant_enabled`。
      duration_ms:
        type: integer
        format: int64
        enum: [604800000, 2592000000, 7776000000]
        default: 604800000
        description: 资源有效期，仅允许 7/30/90 天；未传时 gateway 默认 7 天。
      reason:
        type: string
        default: manager_center
    description: 不接受 `quantity`、`wallet_asset_amount` 等客户端计算字段。
  ManagerResourceGrantData:
    type: object
    properties:
      grant_id:
        type: string
      command_id:
        type: string
      target_user_id:
        type: string
      resource_id:
        type: string
      status:
        type: string
      grant_source:
        type: string
        enum: [manager_center]
      operator_user_id:
        type: string
      created_at_ms:
        type: integer
        format: int64
  ResourceGroupItemData:
    type: object
    properties:
      group_item_id:
        type: integer
        format: int64
      item_type:
        type: string
        enum: [resource, wallet_asset]
      resource_id:
        type: integer
        format: int64
      resource:
        $ref: "#/definitions/ResourceData"
      wallet_asset_type:
        type: string
        enum: [COIN, DIAMOND]
      wallet_asset_amount:
        type: integer
        format: int64
      quantity:
        type: integer
        format: int64
      duration_ms:
        type: integer
        format: int64
      sort_order:
        type: integer
        format: int32
  ResourceGroupData:
    type: object
    properties:
      group_id:
        type: integer
        format: int64
      group_code:
        type: string
      name:
        type: string
      status:
        type: string
      description:
        type: string
      sort_order:
        type: integer
        format: int32
      items:
        type: array
        items:
          $ref: "#/definitions/ResourceGroupItemData"
  GiftConfigData:
    type: object
    properties:
      gift_id:
        type: string
      resource_id:
        type: integer
        format: int64
      resource:
        $ref: "#/definitions/ResourceData"
      status:
        type: string
      name:
        type: string
      presentation_json:
        type: string
      price_version:
        type: string
      gift_type_code:
        type: string
        enum:
          - normal
          - cp
          - lucky
          - super_lucky
          - exclusive
          - noble
          - flag
          - activity
          - magic
          - custom
      charge_asset_type:
        type: string
        enum:
          - COIN
          - DIAMOND
      coin_price:
        type: integer
        format: int64
      gift_point_amount:
        type: integer
        format: int64
      heat_value:
        type: integer
        format: int64
      effective_from_ms:
        type: integer
        format: int64
        description: 0 表示不限制开始时间。
      effective_to_ms:
        type: integer
        format: int64
        description: 0 表示不限制结束时间。
      effect_types:
        type: array
        items:
          type: string
          enum:
            - animation
            - music
            - global_broadcast
      region_ids:
        type: array
        items:
          type: integer
          format: int64
  GiftListData:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: "#/definitions/GiftConfigData"
      total:
        type: integer
        format: int64
      page:
        type: integer
        format: int32
      page_size:
        type: integer
        format: int32
  GiftTabData:
    type: object
    properties:
      key:
        type: string
        description: Tab 稳定 key，等同于礼物类型编码。
      gift_type_code:
        type: string
        description: 礼物类型编码，用于和 gifts[].gift_type_code 对齐。
      name:
        type: string
        description: 后台配置的中文显示名。
      label:
        type: string
        description: App Tab 展示名，来源于后台 tab_key。
      tab_key:
        type: string
        description: 后台配置的 Tab Name。
      status:
        type: string
      order:
        type: integer
        format: int32
        description: App 排序值，等同于 sort_order。
      sort_order:
        type: integer
        format: int32
      created_at_ms:
        type: integer
        format: int64
      updated_at_ms:
        type: integer
        format: int64
  GiftTabListData:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: "#/definitions/GiftTabData"
      total:
        type: integer
        format: int32
  UserResourceData:
    type: object
    properties:
      entitlement_id:
        type: string
      resource_id:
        type: integer
        format: int64
      resource:
        $ref: "#/definitions/ResourceData"
      status:
        type: string
      quantity:
        type: integer
        format: int64
      remaining_quantity:
        type: integer
        format: int64
      effective_at_ms:
        type: integer
        format: int64
      expires_at_ms:
        type: integer
        format: int64
      source_grant_id:
        type: string
      equipped:
        type: boolean
        description: 当前权益是否是该资源类型的已佩戴项。
  UserResourceListData:
    type: object
    properties:
      items:
        type: array
        items:
          $ref: "#/definitions/UserResourceData"
      total:
        type: integer
        format: int32
  EquipUserResourceRequest:
    type: object
    properties:
      entitlement_id:
        type: string
        description: 可选；不传时服务端自动选择当前用户该资源最新有效权益。
  RechargeProductData:
    type: object
    properties:
      product_id:
        type: integer
        format: int64
      product_code:
        type: string
      product_name:
        type: string
      description:
        type: string
      platform:
        type: string
        enum: [android, ios]
      channel:
        type: string
        enum: [google, apple]
      currency_code:
        type: string
        example: USDT
      coin_amount:
        type: integer
        format: int64
      amount_minor:
        type: integer
        format: int64
      amount_micro:
        type: integer
        format: int64
        description: USDT 微单位金额，1 USDT = 1000000。
      policy_version:
        type: string
      region_ids:
        type: array
        items:
          type: integer
          format: int64
      resource_asset_type:
        type: string
        example: COIN
      status:
        type: string
        enum: [active, disabled]
      enabled:
        type: boolean
      sort_order:
        type: integer
        format: int32
  RechargeProductListData:
    type: object
    properties:
      channels:
        type: array
        description: 当前结果涉及的充值渠道，例如 google、apple。
        items:
          type: string
      products:
        type: array
        items:
          $ref: "#/definitions/RechargeProductData"
  GooglePaymentConfirmRequest:
    type: object
    required:
      - command_id
      - product_id
      - package_name
      - purchase_token
    properties:
      command_id:
        type: string
        description: 客户端确认支付幂等键；同一 purchase token 重试建议复用。
      product_id:
        type: integer
        format: int64
        description: 后端充值商品 ID。
      product_code:
        type: string
        description: 后端返回的 Google productId，必须与 Play Console 商品 ID 一致。
      package_name:
        type: string
        description: Android 包名。
      purchase_token:
        type: string
        description: Google Play Billing 返回的 serverVerificationData，服务端只保存 SHA256。
      order_id:
        type: string
        description: Google orderId；客户端拿不到时可不传。
      purchase_time_ms:
        type: integer
        format: int64
        description: 客户端购买时间，UTC epoch ms，仅用于排障。
  GooglePaymentConfirmData:
    type: object
    properties:
      payment_order_id:
        type: string
      transaction_id:
        type: string
      status:
        type: string
        enum: [credited]
      product_id:
        type: integer
        format: int64
      product_code:
        type: string
      coin_amount:
        type: integer
        format: int64
      balance:
        type: object
        properties:
          asset_type:
            type: string
            example: COIN
          available_amount:
            type: integer
            format: int64
          frozen_amount:
            type: integer
            format: int64
          version:
            type: integer
            format: int64
      idempotent_replay:
        type: boolean
      consume_state:
        type: string
        enum: [consume_pending, consumed]
  CoinSellerTransferRequest:
    type: object
    required:
      - command_id
      - amount
      - reason
    description: "`target_user_id` 和 `target_display_user_id` 至少传一个；两者都是玩家短 ID/展示号，不是 user-service 内部长 ID。"
    properties:
      command_id:
        type: string
        description: 钱包命令幂等键；客户端按用户转账动作生成，同一动作重试必须复用。
      target_user_id:
        type: integer
        format: int64
        description: 目标玩家短 ID/展示号；gateway 会先解析成内部 user_id 再调用 wallet-service。
      target_display_user_id:
        type: string
        description: 目标玩家短 ID/展示号；推荐新客户端使用该字段。
      amount:
        type: integer
        format: int64
        minimum: 1
        description: 转给玩家的普通金币数量。
      reason:
        type: string
        description: 转账原因或线下凭证摘要。
  CoinSellerTransferResponse:
    type: object
    properties:
      transaction_id:
        type: string
      seller_balance_after:
        type: integer
        format: int64
        description: 币商 `COIN_SELLER_COIN` 账后余额。
      target_balance_after:
        type: integer
        format: int64
        description: 目标玩家 `COIN` 账后余额。
      amount:
        type: integer
        format: int64
      recharge_usd_minor:
        type: integer
        format: int64
        description: 本次转账按区域充值政策折算的美元最小单位金额；100 表示 1 美元。
      recharge_currency_code:
        type: string
        example: USD
      recharge_policy_id:
        type: integer
        format: int64
      recharge_policy_version:
        type: string
      recharge_policy_coin_amount:
        type: integer
        format: int64
        description: 政策快照里的金币数量，例如 80000。
      recharge_policy_usd_minor_amount:
        type: integer
        format: int64
        description: 政策快照里的美元最小单位数量，例如 100。
  CreateRoomRequest:
    type: object
    required:
      - command_id
      - mode
      - room_name
    properties:
      command_id:
        type: string
        description: 房间创建命令幂等键；客户端按创建房间动作生成，同一动作的 HTTP 重试必须复用。
      seat_count:
        type: integer
        format: int32
        minimum: 0
        description: 麦位数量，可省略；不传或传 0 时使用后台房间配置默认值，正数必须命中后台启用座位数。
      mode:
        type: string
        minLength: 1
        description: 房间模式，不能为空；当前服务只保存并透出该值，不在 gateway 做枚举分发。
      room_name:
        type: string
        minLength: 1
        maxLength: 128
        description: 房间展示名称，必填；room-service 写入 `room_ext.title` 并投影到房间列表。
      room_avatar:
        type: string
        maxLength: 512
        description: 房间头像，可选；为空时 room-service 写入默认系统头像 `hyapp://room/default-avatar`。
      room_description:
        type: string
        maxLength: 512
        description: 房间简介，可选；只写入 `room_ext.description`，不进入房间高频核心字段。
  UpdateRoomProfileRequest:
    type: object
    required:
      - room_id
      - command_id
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      room_name:
        type: string
        minLength: 1
        maxLength: 128
        description: 可选；传入时更新房间标题。
      room_avatar:
        type: string
        maxLength: 512
        description: 可选；传空字符串时 room-service 恢复系统默认头像。
      room_description:
        type: string
        maxLength: 512
        description: 可选；允许传空字符串清空简介。
      seat_count:
        type: integer
        format: int32
        enum:
          - 10
          - 15
          - 20
          - 25
          - 30
        description: 可选；必须是后台已启用座位数。缩容时高编号麦位必须空闲且未锁。
  JoinRoomRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      role:
        type: string
        enum:
          - audience
        description: 首版固定 audience；上麦成功后客户端再切换发布角色。
      password:
        type: string
        maxLength: 64
        description: 锁房时必填；只用于本次 JoinRoom 校验，服务端不保存明文。
  RoomHeartbeatRequest:
    type: object
    required:
      - room_id
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 心跳命令幂等键；客户端按单次心跳动作生成，HTTP 重试同一次心跳必须复用。
  LeaveRoomRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
  MicUpRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      seat_no:
        type: integer
        format: int32
  MicDownRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      target_user_id:
        type: integer
        format: int64
      reason:
        type: string
        description: 主动下麦可为空；系统自动下麦会使用 publish_timeout 等稳定原因。
  ChangeMicSeatRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      target_user_id:
        type: integer
        format: int64
      seat_no:
        type: integer
        format: int32
  ConfirmMicPublishingRequest:
    type: object
    required:
      - room_id
      - mic_session_id
      - room_version
      - event_time_ms
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按单次确认事件生成，HTTP 重试同一确认事件必须复用。
      target_user_id:
        type: integer
        format: int64
        description: 为空时默认确认当前登录用户；RTC webhook 编排可显式传目标用户。
      mic_session_id:
        type: string
      room_version:
        type: integer
        format: int64
      event_time_ms:
        type: integer
        format: int64
      source:
        type: string
        description: 例如 client 或 rtc_webhook。
  SetMicSeatLockRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      seat_no:
        type: integer
        format: int32
      locked:
        type: boolean
  SetChatEnabledRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      enabled:
        type: boolean
  SetRoomPasswordRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      locked:
        type: boolean
      password:
        type: string
        description: "`locked=true` 时必填；`locked=false` 时忽略。"
  SetRoomAdminRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      target_user_id:
        type: integer
        format: int64
      enabled:
        type: boolean
  MuteUserRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      target_user_id:
        type: integer
        format: int64
      muted:
        type: boolean
  KickUserRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      target_user_id:
        type: integer
        format: int64
      duration_ms:
        type: integer
        format: int64
        description: 0 表示永久禁止进房；大于 0 表示从服务端当前 UTC 时间起禁止进房的毫秒时长。
  UnbanUserRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      target_user_id:
        type: integer
        format: int64
  SendGiftRequest:
    type: object
    properties:
      room_id:
        type: string
      command_id:
        type: string
        description: 房间命令幂等键；客户端按用户动作生成，同一动作的 HTTP 重试必须复用。
      target_user_id:
        type: integer
        format: int64
      gift_id:
        type: string
      gift_count:
        type: integer
        format: int32
  CommandResult:
    type: object
    properties:
      applied:
        type: boolean
      room_version:
        type: integer
        format: int64
      server_time_ms:
        type: integer
        format: int64
  RoomUser:
    type: object
    properties:
      user_id:
        type: integer
        format: int64
      role:
        type: string
      joined_at_ms:
        type: integer
        format: int64
      last_seen_at_ms:
        type: integer
        format: int64
  SeatState:
    type: object
    properties:
      seat_no:
        type: integer
        format: int32
      user_id:
        type: integer
        format: int64
      locked:
        type: boolean
      publish_state:
        type: string
        enum:
          - pending_publish
          - publishing
          - idle
        description: pending_publish 表示业务占麦成功但 RTC 尚未确认发流；publishing 表示已确认发布音频。
      mic_session_id:
        type: string
      publish_deadline_ms:
        type: integer
        format: int64
      mic_session_room_version:
        type: integer
        format: int64
      last_publish_event_time_ms:
        type: integer
        format: int64
  RankItem:
    type: object
    properties:
      user_id:
        type: integer
        format: int64
      score:
        type: integer
        format: int64
      gift_value:
        type: integer
        format: int64
      updated_at_ms:
        type: integer
        format: int64
  RoomSnapshot:
    type: object
    properties:
      room_id:
        type: string
        description: App 作用域房间长 ID，格式为 `<app_code>_<uuid>`。
      room_short_id:
        type: string
        description: 房间短 ID，首版等于创建者当前 `display_user_id`。
      owner_user_id:
        type: integer
        format: int64
      mode:
        type: string
      status:
        type: string
      chat_enabled:
        type: boolean
      locked:
        type: boolean
      mic_seats:
        type: array
        items:
          $ref: "#/definitions/SeatState"
      online_users:
        type: array
        items:
          $ref: "#/definitions/RoomUser"
      admin_user_ids:
        type: array
        items:
          type: integer
          format: int64
      ban_user_ids:
        type: array
        items:
          type: integer
          format: int64
      ban_states:
        type: array
        description: 房间 ban 的时间边界；expires_at_ms 为 0 表示永久。
        items:
          $ref: "#/definitions/RoomBanState"
      mute_user_ids:
        type: array
        items:
          type: integer
          format: int64
      gift_rank:
        type: array
        items:
          $ref: "#/definitions/RankItem"
      room_ext:
        type: object
        description: 扩展字段集合；创建房间展示资料固定使用 `title`、`cover_url`、`description`。
        additionalProperties:
          type: string
      heat:
        type: integer
        format: int64
      version:
        type: integer
        format: int64
  RoomBanState:
    type: object
    properties:
      user_id:
        type: integer
        format: int64
      actor_user_id:
        type: integer
        format: int64
      created_at_ms:
        type: integer
        format: int64
      expires_at_ms:
        type: integer
        format: int64
        description: 0 表示永久；非 0 表示该 UTC 毫秒后可重新进房。
  RoomBannedUserData:
    type: object
    properties:
      user_id:
        type: string
      display_user_id:
        type: string
      username:
        type: string
      avatar:
        type: string
      country:
        type: string
      country_name:
        type: string
      country_display_name:
        type: string
      country_flag:
        type: string
      actor_user_id:
        type: string
      created_at_ms:
        type: integer
        format: int64
      unban_at_ms:
        type: integer
        format: int64
        description: 0 表示永久，需要手动解除；非 0 表示自动解封 UTC 毫秒。
      remaining_ms:
        type: integer
        format: int64
      permanent:
        type: boolean
  RoomBannedUsersData:
    type: object
    properties:
      room_id:
        type: string
      items:
        type: array
        items:
          $ref: "#/definitions/RoomBannedUserData"
      total:
        type: integer
        format: int64
      page:
        type: integer
        format: int32
      page_size:
        type: integer
        format: int32
      server_time_ms:
        type: integer
        format: int64
  RoomListItemData:
    type: object
    required:
      - room_id
      - im_group_id
    properties:
      room_id:
        type: string
      im_group_id:
        type: string
        description: 腾讯 IM 房间群 ID。当前等于 `room_id`，只代表目标群，不代表入群授权。
      owner_user_id:
        type: string
      title:
        type: string
      cover_url:
        type: string
      mode:
        type: string
      status:
        type: string
      locked:
        type: boolean
        description: true 表示该房间需要入房密码；列表和搜索只返回标识，不返回密码。
      heat:
        type: integer
        format: int64
      online_count:
        type: integer
        format: int32
      seat_count:
        type: integer
        format: int32
      occupied_seat_count:
        type: integer
        format: int32
      visible_region_id:
        type: integer
        format: int64
      app_code:
        type: string
      room_short_id:
        type: string
  RoomListData:
    type: object
    properties:
      rooms:
        type: array
        items:
          $ref: "#/definitions/RoomListItemData"
      next_cursor:
        type: string
  MyRoomData:
    type: object
    required:
      - has_room
      - server_time_ms
    properties:
      has_room:
        type: boolean
      room:
        $ref: "#/definitions/RoomListItemData"
      server_time_ms:
        type: integer
        format: int64
  RoomInitialData:
    type: object
    required:
      - room_id
      - im_group_id
      - chat_enabled
      - online_count
      - seat_count
      - version
    properties:
      room_id:
        type: string
      im_group_id:
        type: string
      room_short_id:
        type: string
      title:
        type: string
      cover_url:
        type: string
      description:
        type: string
      owner_user_id:
        type: string
      mode:
        type: string
      status:
        type: string
      chat_enabled:
        type: boolean
      locked:
        type: boolean
        description: true 表示该房间需要入房密码。
      heat:
        type: integer
        format: int64
      online_count:
        type: integer
        format: int32
      seat_count:
        type: integer
        format: int32
      occupied_seat_count:
        type: integer
        format: int32
      version:
        type: integer
        format: int64
  RoomViewerData:
    type: object
    properties:
      user_id:
        type: string
      role:
        type: string
      joined_at_ms:
        type: integer
        format: int64
      last_seen_at_ms:
        type: integer
        format: int64
  RoomSeatData:
    type: object
    properties:
      seat_no:
        type: integer
        format: int32
      user_id:
        type: string
      locked:
        type: boolean
      publish_state:
        type: string
      mic_session_id:
        type: string
      publish_deadline_ms:
        type: integer
        format: int64
  RoomRankItemData:
    type: object
    properties:
      user_id:
        type: string
      score:
        type: integer
        format: int64
      gift_value:
        type: integer
        format: int64
      updated_at_ms:
        type: integer
        format: int64
  RoomUserProfileData:
    type: object
    properties:
      user_id:
        type: string
      display_user_id:
        type: string
      username:
        type: string
      avatar:
        type: string
  RoomIMData:
    type: object
    properties:
      group_id:
        type: string
      need_join_group:
        type: boolean
  RoomRTCData:
    type: object
    required:
      - need_token
      - available
    properties:
      need_token:
        type: boolean
      available:
        type: boolean
      token:
        $ref: "#/definitions/TencentRTCTokenData"
      reason:
        type: string
        enum:
          - rtc_token_unavailable
  CurrentRoomData:
    type: object
    required:
      - has_current_room
      - room_id
      - room_version
      - role
      - mic_session_id
      - publish_state
      - need_join_im_group
      - need_rtc_token
      - server_time_ms
    properties:
      has_current_room:
        type: boolean
      room_id:
        type: string
      room_version:
        type: integer
        format: int64
      role:
        type: string
        enum:
          - owner
          - host
          - admin
          - audience
      mic_session_id:
        type: string
      publish_state:
        type: string
        enum:
          - ""
          - pending_publish
          - publishing
      need_join_im_group:
        type: boolean
      need_rtc_token:
        type: boolean
      server_time_ms:
        type: integer
        format: int64
  RoomSnapshotData:
    type: object
    required:
      - room
      - server_time_ms
    properties:
      room:
        $ref: "#/definitions/RoomSnapshot"
      is_followed:
        type: boolean
        description: 当前 token 用户是否已关注该房间；来自 room-service 房间关注关系，不属于 Room Cell 核心状态。
      server_time_ms:
        type: integer
        format: int64
  RoomFollowData:
    type: object
    required:
      - room_id
      - is_followed
      - server_time_ms
    properties:
      room_id:
        type: string
      is_followed:
        type: boolean
      followed_at_ms:
        type: integer
        format: int64
        description: POST 关注成功时返回；DELETE 取消关注时省略。
      server_time_ms:
        type: integer
        format: int64
  CreateRoomResponse:
    type: object
    required:
      - result
      - room
      - seats
      - im
      - server_time_ms
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      room:
        $ref: "#/definitions/RoomInitialData"
      seats:
        type: array
        items:
          $ref: "#/definitions/RoomSeatData"
      im:
        $ref: "#/definitions/RoomIMData"
      server_time_ms:
        type: integer
        format: int64
  JoinRoomResponse:
    type: object
    required:
      - result
      - room
      - viewer
      - seats
      - contribution_rank
      - profiles
      - im
      - rtc
      - server_time_ms
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      room:
        $ref: "#/definitions/RoomInitialData"
      viewer:
        $ref: "#/definitions/RoomViewerData"
      seats:
        type: array
        items:
          $ref: "#/definitions/RoomSeatData"
      contribution_rank:
        type: array
        description: 首屏贡献榜，当前最多返回前 10 名；完整榜单后续走分页接口。
        items:
          $ref: "#/definitions/RoomRankItemData"
      profiles:
        type: array
        description: 只包含房主、当前用户、麦位用户和首屏贡献榜用户的展示资料。
        items:
          $ref: "#/definitions/RoomUserProfileData"
      im:
        $ref: "#/definitions/RoomIMData"
      rtc:
        $ref: "#/definitions/RoomRTCData"
      server_time_ms:
        type: integer
        format: int64
  UpdateRoomProfileResponse:
    type: object
    required:
      - result
      - room
      - seats
      - server_time_ms
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      room:
        $ref: "#/definitions/RoomInitialData"
      seats:
        type: array
        items:
          $ref: "#/definitions/RoomSeatData"
      server_time_ms:
        type: integer
        format: int64
  RoomHeartbeatResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      user:
        $ref: "#/definitions/RoomUser"
      room:
        $ref: "#/definitions/RoomSnapshot"
  LeaveRoomResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      room:
        $ref: "#/definitions/RoomSnapshot"
  MicUpResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      seat_no:
        type: integer
        format: int32
      room:
        $ref: "#/definitions/RoomSnapshot"
      mic_session_id:
        type: string
      publish_deadline_ms:
        type: integer
        format: int64
  MicDownResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      seat_no:
        type: integer
        format: int32
      room:
        $ref: "#/definitions/RoomSnapshot"
  ChangeMicSeatResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      room:
        $ref: "#/definitions/RoomSnapshot"
  ConfirmMicPublishingResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      seat_no:
        type: integer
        format: int32
      room:
        $ref: "#/definitions/RoomSnapshot"
  SetMicSeatLockResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      room:
        $ref: "#/definitions/RoomSnapshot"
  SetChatEnabledResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      room:
        $ref: "#/definitions/RoomSnapshot"
  SetRoomAdminResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      room:
        $ref: "#/definitions/RoomSnapshot"
  MuteUserResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      room:
        $ref: "#/definitions/RoomSnapshot"
  KickUserResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      room:
        $ref: "#/definitions/RoomSnapshot"
      rtc_kicked:
        type: boolean
        description: room-service 是否已通过 TRTC 服务端接口移除目标用户；失败不回滚踢人事实。
      rtc_kick_error:
        type: string
        description: TRTC 服务端踢人失败原因，仅用于排障和告警。
  UnbanUserResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      room:
        $ref: "#/definitions/RoomSnapshot"
  SendGiftResponse:
    type: object
    properties:
      result:
        $ref: "#/definitions/CommandResult"
      billing_receipt_id:
        type: string
      room_heat:
        type: integer
        format: int64
      gift_rank:
        type: array
        items:
          $ref: "#/definitions/RankItem"
      room:
        $ref: "#/definitions/RoomSnapshot"
  AuthTokenEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/AuthTokenData"
  PasswordSetEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/PasswordSetData"
  LogoutEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/LogoutData"
  TencentIMUserSigEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/TencentIMUserSigData"
  TencentRTCTokenEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/TencentRTCTokenData"
  UploadFileEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/UploadFileData"
  BindPushTokenEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/BindPushTokenData"
  DeletePushTokenEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/DeletePushTokenData"
  UserIdentityEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/UserIdentityData"
  UserHostIdentityEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/UserHostIdentityData"
  MyOverviewEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/MyOverviewData"
  MyInviteOverviewEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/MyInviteOverviewData"
  UserProfileEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/UserProfileData"
  UserProfilesBatchEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/UserProfilesBatchData"
  MessageTabsEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/MessageTabsData"
  MessageListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/MessageListData"
  MessageReadEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/MessageReadData"
  MessageReadAllEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/MessageReadAllData"
  MessageDeleteEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/MessageDeleteData"
  CompleteOnboardingEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/CompleteOnboardingData"
  CountryListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/CountryListData"
  AppBootstrapEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/AppBootstrapData"
  AppVersionEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/AppVersionData"
  H5LinkListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/H5LinkListData"
  SplashScreenListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/SplashScreenListData"
  PopupListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/PopupListData"
  ResourceListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/ResourceListData"
  ManagerGrantResourceListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/ManagerGrantResourceListData"
  BusinessUserLookupEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/BusinessUserLookupData"
  ManagerResourceGrantEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/ManagerResourceGrantData"
  ResourceGroupEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/ResourceGroupData"
  GiftListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/GiftListData"
  GiftTabListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/GiftTabListData"
  UserResourceListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/UserResourceListData"
  UserResourceEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/UserResourceData"
  CreateRoomEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/CreateRoomResponse"
  UpdateRoomProfileEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/UpdateRoomProfileResponse"
  RoomListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/RoomListData"
  MyRoomEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/MyRoomData"
  CurrentRoomEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/CurrentRoomData"
  RoomSnapshotEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/RoomSnapshotData"
  RoomFollowEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/RoomFollowData"
  JoinRoomEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/JoinRoomResponse"
  RoomHeartbeatEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/RoomHeartbeatResponse"
  LeaveRoomEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/LeaveRoomResponse"
  MicUpEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/MicUpResponse"
  MicDownEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/MicDownResponse"
  ChangeMicSeatEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/ChangeMicSeatResponse"
  ConfirmMicPublishingEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/ConfirmMicPublishingResponse"
  SetMicSeatLockEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/SetMicSeatLockResponse"
  SetChatEnabledEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/SetChatEnabledResponse"
  SetRoomPasswordEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/UpdateRoomProfileResponse"
  SetRoomAdminEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/SetRoomAdminResponse"
  MuteUserEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/MuteUserResponse"
  KickUserEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/KickUserResponse"
  UnbanUserEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/UnbanUserResponse"
  RoomBannedUsersEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/RoomBannedUsersData"
  SendGiftEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/SendGiftResponse"
  RechargeProductListEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/RechargeProductListData"
  GooglePaymentConfirmEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/GooglePaymentConfirmData"
  CoinSellerTransferEnvelope:
    allOf:
      - $ref: "#/definitions/GatewayOKEnvelopeBase"
      - type: object
        properties:
          data:
            $ref: "#/definitions/CoinSellerTransferResponse"
