# 系统架构
> 文档版本：v1.0
> 最后更新：2026-04-02 08:28:05


## 1. 目标

当前 backend 不是一个“给地图页喂数据的简单服务”，而是一个业务壳后端。

它负责：

- 用户与登录
- 多租户与多入口
- 首页与业务入口聚合
- Event 业务对象
- 配置发布解析
- 启动一局游戏
- session 生命周期
- 结果沉淀

它不负责：

- 解释游戏玩法细节
- 运行时解析复杂地图规则
- 直接下发数据库编辑态对象给客户端

补充约束：

- 这套 backend 必须服务未来 APP，不是“小程序专用后端”
- 登录方式可以按终端区分，但业务对象和业务接口不能按端分裂成两套

## 2. 分层

### 2.1 平台层

平台层统一处理：

- `tenant`
- `entry_channel`
- `user`
- `login_identity`
- `auth_refresh_token`

这层是整个平台共用能力。

它必须同时支撑：

- APP
- 微信小程序
- 后续公众号 / H5 / 其他渠道

### 2.2 业务层

业务层统一处理：

- `card`
- `event`
- `event_play`
- `entry_home`
- `profile`

它面向页面和运营入口，但不直接承载游戏规则。

### 2.3 配置发布层

配置发布层统一处理：

- `event_release`
- `manifest_url`
- `manifest_checksum_sha256`
- `route_code`

这层是“客户端真正进入游戏时要消费的运行配置入口”。

这里的发布结构应保持终端中立：

- 不写死为小程序专用结构
- 不直接依赖某个端的页面实现
- 允许 APP 和小程序共用同一份 release / manifest

### 2.4 运行层

运行层统一处理：

- `game_session`
- `session_token`
- `session_results`

这层不关心编辑态，只关心“一局游戏”。

## 3. 最重要的对象关系

### 3.1 `event`

`event` 是业务对象。

它负责：

- 活动身份
- 展示名称
- 业务状态
- 当前指向的发布版本

它不是客户端实际运行的配置文件本体。

### 3.2 `event_release`

`event_release` 是配置发布对象。

它负责：

- 这次发布的 `manifest_url`
- 配置标签 `config_label`
- 可选校验值
- 可选 `route_code`

进入游戏时，客户端真正需要的是这里。

### 3.3 `game_session`

`game_session` 是运行对象。

它必须固化：

- 当前用户
- 当前 event
- 当前实际使用的 `event_release`
- 当前 `session_token`

这样后续哪怕 event 切到新 release，旧 session 也不会漂移。

## 4. 配置驱动原则

这套系统必须坚持下面这条原则：

> 业务层先解析出一份可启动的 release，客户端再基于这份 release 的 manifest 进入游戏。

不能走成：

> 客户端拿到 event 后自己再去推断该加载哪份配置

所以当前接口都在往这个方向收口：

- `GET /events/{id}/play` 会返回 `resolvedRelease`
- `POST /events/{id}/launch` 会返回 `resolvedRelease`
- `GET /sessions/{id}` 会返回 `resolvedRelease`
- `GET /sessions/{id}/result` 能追溯到当时的 release

补充约束：

- release / manifest 只描述运行配置，不承载某个端的页面状态
- 玩家设置、设备能力差异、运行时 UI 编译由客户端自行处理
- 后端负责“发布可运行配置”，不是“替某个端生成最终运行时 profile”

## 5. 代码分层

### 5.1 入口层

- [main.go](D:/dev/cmr-mini/backend/cmd/api/main.go)
- [app.go](D:/dev/cmr-mini/backend/internal/app/app.go)
- [config.go](D:/dev/cmr-mini/backend/internal/app/config.go)

### 5.2 HTTP 层

- [router.go](D:/dev/cmr-mini/backend/internal/httpapi/router.go)
- [handlers](D:/dev/cmr-mini/backend/internal/httpapi/handlers)
- [middleware](D:/dev/cmr-mini/backend/internal/httpapi/middleware)

### 5.3 用例层

- [service](D:/dev/cmr-mini/backend/internal/service)

当前主要服务：

- `AuthService`
- `EntryService`
- `HomeService`
- `EntryHomeService`
- `EventService`
- `EventPlayService`
- `SessionService`
- `ResultService`
- `ProfileService`
- `DevService`

### 5.4 数据层

- [store/postgres](D:/dev/cmr-mini/backend/internal/store/postgres)

特点：

- 手写 SQL
- `pgx` 连接池
- 不依赖 ORM

### 5.5 平台适配层

- [jwtx](D:/dev/cmr-mini/backend/internal/platform/jwtx)
- [security](D:/dev/cmr-mini/backend/internal/platform/security)
- [wechatmini](D:/dev/cmr-mini/backend/internal/platform/wechatmini)

## 6. 当前边界

### 6.1 backend 管什么

- 业务身份
- 配置发布解析
- 启动编排
- 一局的生命周期和结果

### 6.2 游戏客户端管什么

- 下载 `manifest_url`
- 解析运行配置
- 驱动地图和玩法
- 产生过程数据和结束摘要

适用范围：

- 微信小程序客户端
- 未来 APP 客户端

也就是说：

- 后端按统一业务模型输出
- 终端差异放在客户端运行时适配层，不放在后端业务接口层

### 6.3 后续网关该怎么接

后面如果接实时网关，建议仍然走：

- backend 负责登录与 launch
- launch 或 session 负责产出短期实时票据
- 网关只认 backend 签发的运行态票据

不要把微信身份或业务 token 直接暴露给实时网关。


