Files
cmr-mini/doc/config/线上业务接入边界方案.md

7.9 KiB
Raw Blame History

线上业务接入边界方案

文档版本v1.0 最后更新2026-04-02

1. 目的

本文档定义小程序接入线上业务 API 时的架构边界,确保以下原则始终成立:

  • 游戏玩法仍然完全由配置驱动
  • 线上 API 只负责业务编排,不负责定义或污染玩法
  • 地图引擎和规则运行时可以继续独立于业务系统运行
  • 本地 demo、离线配置、线上赛事三种入口可以共存

本文档适用于以下接入范围:

  • 用户管理
  • 登录与鉴权
  • 首页卡片
  • 赛事详情
  • 地图详情
  • Event 详情
  • 报名
  • launch 启动
  • 后续 session 上报与查询

2. 核心结论

线上接入后,系统仍保持两层结构:

  • 业务层:决定“用户是谁、能进什么、当前启动什么”
  • 游戏层:决定“地图怎么画、规则怎么跑、控制点怎么判定、体验怎么表现”

两层之间只允许通过一个明确的启动模型通信,不允许业务 API 对游戏规则对象做直接写入。

一句话定义:

API 负责发放启动上下文,配置负责定义游戏本身。

3. 分层原则

3.1 业务层职责

业务层负责:

  • 登录与 token 管理
  • 用户资料与身体数据
  • 卡片、赛事、地图、Event 列表与详情
  • 报名资格校验
  • launch 启动资格与 session 凭证发放
  • 后续成绩、轨迹、历史记录上传与查询

业务层可以决定:

  • 是否允许用户启动
  • 当前应启动哪个 Event
  • 当前应加载哪份配置或 manifest
  • 当前启动绑定的 session_idsession_token

业务层不可以决定:

  • 控制点布局
  • 游戏规则
  • 打卡判定
  • 跳点规则
  • 引导、音效、表现策略
  • 游戏内内容卡的结构和行为定义

3.2 游戏层职责

游戏层负责:

  • 地图资源加载
  • KML / course / 配置解析
  • GameDefinition 构建
  • 规则插件运行
  • 传感器接入
  • HUD、反馈、结果页、本地统计
  • 游戏内 session 生命周期

游戏层只认配置和本地运行态,不认业务 API 对象。

游戏层不应该直接出现以下业务字段:

  • competition_id
  • registration_status
  • access_token
  • refresh_token
  • Authorization
  • user_id

业务字段可以存在于页面壳层或业务服务层,但不进入规则层。

4. 唯一允许的层间模型

业务层和游戏层之间,统一通过 GameLaunchEnvelope 通信。

建议结构如下:

interface GameLaunchEnvelope {
  config: {
    configUrl: string
    configLabel: string
    configChecksumSha256?: string | null
    releaseId?: string | null
    routeCode?: string | null
  }
  business: {
    source: 'demo' | 'competition' | 'direct-event' | 'custom'
    competitionId?: string | null
    eventId?: string | null
    launchRequestId?: string | null
    participantId?: string | null
    sessionId?: string | null
    sessionToken?: string | null
    sessionTokenExpiresAt?: string | null
    realtimeEndpoint?: string | null
    realtimeToken?: string | null
  } | null
}

解释:

  • config 是游戏层真正消费的输入
  • business 是业务壳保留的上下文
  • 地图页可以同时拿到两者,但地图引擎只读取 config

5. 推荐启动链路

5.1 Demo 启动

适用于本地调试、离线测试、玩法验证。

流程:

  1. 页面构建 demo GameLaunchEnvelope
  2. config.configUrl 指向 demo 配置
  3. business.source = 'demo'
  4. 跳转地图页
  5. 地图页加载配置并启动引擎

特点:

  • 不依赖业务 API
  • 不依赖登录
  • 不依赖 session

5.2 线上赛事启动

适用于正式业务入口。

流程:

  1. 业务页请求赛事 / Event 详情
  2. 用户在业务页完成登录、资格校验、报名确认
  3. 用户点击开始,业务页调用 launch
  4. 后端返回 session_idsession_tokenrelease_idmanifest_urlroute_code
  5. 业务层把上述信息转换为 GameLaunchEnvelope
  6. 地图页只根据 config 载入配置
  7. 业务壳层保存 business 上下文供后续上报使用

注意:

  • launch 是业务启动,不等于规则层 startSession
  • 规则层本地开始游戏,仍由引擎按配置驱动

5.3 线上直入地图启动

适用于地图详情或 Event 直入。

流程与赛事入口基本一致,区别仅在于:

  • 入口页不同
  • 资格校验更轻
  • business.source = 'direct-event'

6. manifest 的角色

后端提供的 manifest_url 不应直接变成规则层对象。

推荐做法:

  • 业务层或适配层下载 manifest
  • 将 manifest 解析并映射到当前配置体系
  • 输出为当前引擎已支持的配置入口

manifest 是“线上发布描述”,不是“规则运行对象”。

建议把 manifest 适配理解为一个编译过程:

  • 输入:后端发布描述
  • 输出:当前配置驱动引擎可识别的配置资源

7. 目录建议

建议按三层组织代码:

miniprogram/
  services/
    http.ts
    client-api.ts
    auth.ts
  business/
    launch/
      launchBuilder.ts
      launchStore.ts
      manifestAdapter.ts
  utils/
    gameLaunch.ts
  pages/
    login/
    home/
    competition-detail/
    event-detail/
    map/

说明:

  • services 只处理 API 通信
  • business/launch 只做业务到配置的适配
  • utils/gameLaunch.ts 定义启动模型和页面跳转协议
  • pages/map 只做配置加载和游戏承载

8. 代码边界约束

8.1 允许进入地图页的内容

允许进入地图页:

  • GameLaunchEnvelope
  • configUrl
  • configLabel
  • releaseId
  • routeCode
  • sessionToken

但地图页内部还要继续区分:

  • 引擎可读:config
  • 业务壳可读:business

8.2 不允许进入引擎的内容

以下内容禁止进入 MapEngineGameRuntimeGameDefinition

  • 用户信息
  • 登录态 token
  • 报名状态
  • 业务接口返回原始对象
  • 赛事详情原始 JSON
  • Event 详情原始 JSON

8.3 上报也走旁路

后续若接 punchesfinishsession-uploads,建议流程如下:

  1. 游戏层产生本地事件
  2. 页面壳层或业务 service 订阅这些事件
  3. 由业务层决定是否调用 API

不要在规则层里直接 wx.request

9. 当前项目的落地点

当前项目已具备以下基础:

  • 地图页是配置驱动入口
  • remoteMapConfig.ts 负责远程配置加载
  • MapEngine 负责本地规则与表现运行
  • 已新增 utils/gameLaunch.ts 作为启动边界模型

当前建议继续保持:

  • MapEngine 只接 RemoteMapConfig
  • 地图页只从 GameLaunchEnvelope.config 获取配置入口
  • 业务上下文保留在地图页外层或页面壳层

10. 分阶段落地建议

阶段一:边界固化

目标:

  • 地图页彻底改为只接 GameLaunchEnvelope
  • demo 启动与线上启动走同一套入口协议

验收标准:

  • 不再依赖页面内硬编码 URL 作为唯一启动方式
  • 业务字段不进入引擎

阶段二:业务壳接入

目标:

  • 接入登录、首页卡片、赛事详情、Event 详情、报名、launch

验收标准:

  • 能从业务页成功进入地图页
  • 地图仍由配置驱动启动

阶段三manifest 适配

目标:

  • 将后端 manifest_url 适配为当前配置体系可消费的输入

验收标准:

  • 同一个 Event 的线上发布内容可稳定映射为游戏配置入口

阶段四session 下游联通

目标:

  • 补充上报、完成、结果、历史查询

验收标准:

  • 业务链路打通
  • 规则层仍不直接依赖业务 API

11. 必须长期坚持的规则

  • 业务 API 不定义玩法
  • 配置文件不承载用户态
  • 引擎不依赖登录状态
  • 引擎不依赖报名状态
  • 业务页不直接修改 GameDefinition
  • 规则层不直接请求业务 API

如果后续出现需求需要绕过这几条规则,应视为架构变更,不应当作普通功能迭代处理。

12. 一句话总结

线上系统负责“把用户送进正确的一局游戏”,配置系统负责“定义这局游戏是什么”。