370 lines
8.8 KiB
Markdown
370 lines
8.8 KiB
Markdown
# 前后端联调清单
|
||
|
||
## 1. 目的
|
||
|
||
这份清单只回答三件事:
|
||
|
||
1. 小程序当前已经具备哪些接后端的前置能力
|
||
2. backend 当前已经提供了哪些可联调接口
|
||
3. 哪些链路已经能接,哪些链路还缺适配
|
||
|
||
本文不讨论未来大而全后台方案,只服务当前联调落地。
|
||
|
||
## 2. 当前结论
|
||
|
||
当前状态可以概括成一句话:
|
||
|
||
> backend 业务主链已经可联调;小程序地图运行内核也已经成型;两边之间还缺一层业务接入和会话上报适配。
|
||
|
||
也就是说:
|
||
|
||
- 登录、活动详情、launch、session、result 这一条后端链已经可用
|
||
- 小程序地图页已经支持携带 `configUrl / releaseId / sessionId / sessionToken`
|
||
- 但小程序当前仍主要走本地 demo / 直连 OSS manifest
|
||
- 真正的“后端 launch -> 地图页 -> session start/finish/result”还没有正式接上
|
||
|
||
## 3. 小程序当前已具备的联调基础
|
||
|
||
## 3.1 启动信封已经成型
|
||
|
||
地图页不是只吃一个 `configUrl`,而是吃一份启动信封:
|
||
|
||
- [gameLaunch.ts](D:/dev/cmr-mini/miniprogram/utils/gameLaunch.ts)
|
||
|
||
当前结构:
|
||
|
||
- `config.configUrl`
|
||
- `config.configLabel`
|
||
- `config.configChecksumSha256`
|
||
- `config.releaseId`
|
||
- `config.routeCode`
|
||
- `business.source`
|
||
- `business.competitionId`
|
||
- `business.eventId`
|
||
- `business.launchRequestId`
|
||
- `business.participantId`
|
||
- `business.sessionId`
|
||
- `business.sessionToken`
|
||
- `business.sessionTokenExpiresAt`
|
||
- `business.realtimeEndpoint`
|
||
- `business.realtimeToken`
|
||
|
||
这意味着:
|
||
|
||
- backend `launch` 返回的数据结构已经能自然装进小程序地图启动链
|
||
- 地图页并不需要重构启动模型,只需要把业务页接到 `GameLaunchEnvelope`
|
||
|
||
## 3.2 地图页已经支持远端 manifest 启动
|
||
|
||
- [map.ts](D:/dev/cmr-mini/miniprogram/pages/map/map.ts)
|
||
|
||
当前地图页会:
|
||
|
||
1. 解析 `GameLaunchEnvelope`
|
||
2. 调 `loadRemoteMapConfig(configUrl)`
|
||
3. 编译 runtime profile
|
||
4. 启动 `MapEngine`
|
||
|
||
所以只要后端能给出:
|
||
|
||
- `manifestUrl`
|
||
- `releaseId`
|
||
- `configChecksumSha256`
|
||
|
||
地图页就可以直接跑。
|
||
|
||
## 3.3 会话态字段已经进入地图页
|
||
|
||
地图页当前已经能接收并持有:
|
||
|
||
- `sessionId`
|
||
- `sessionToken`
|
||
- `sessionTokenExpiresAt`
|
||
|
||
这说明后面接:
|
||
|
||
- `POST /sessions/{id}/start`
|
||
- `POST /sessions/{id}/finish`
|
||
|
||
不需要再改地图启动协议。
|
||
|
||
## 3.4 故障恢复也已经具备会话上下文承载
|
||
|
||
故障恢复快照当前会保留:
|
||
|
||
- `launchEnvelope`
|
||
- 运行态快照
|
||
|
||
这意味着一旦接入后端 session 后,恢复链也可以继续沿用同一份 `launchEnvelope`。
|
||
|
||
## 4. backend 当前已具备的联调基础
|
||
|
||
## 4.1 路由主链已落地
|
||
|
||
- [router.go](D:/dev/cmr-mini/backend/internal/httpapi/router.go)
|
||
|
||
当前已实现:
|
||
|
||
- `POST /auth/login/wechat-mini`
|
||
- `GET /me/entry-home`
|
||
- `GET /events/{eventPublicID}/play`
|
||
- `POST /events/{eventPublicID}/launch`
|
||
- `POST /sessions/{sessionPublicID}/start`
|
||
- `POST /sessions/{sessionPublicID}/finish`
|
||
- `GET /sessions/{sessionPublicID}/result`
|
||
- `GET /me/results`
|
||
|
||
## 4.2 launch 返回结构已贴近客户端
|
||
|
||
- [核心流程.md](D:/dev/cmr-mini/backend/docs/核心流程.md)
|
||
- [接口清单.md](D:/dev/cmr-mini/backend/docs/接口清单.md)
|
||
|
||
当前 `launch` 返回重点:
|
||
|
||
- `launch.resolvedRelease.releaseId`
|
||
- `launch.resolvedRelease.manifestUrl`
|
||
- `launch.resolvedRelease.manifestChecksumSha256`
|
||
- `launch.business.sessionId`
|
||
- `launch.business.sessionToken`
|
||
|
||
这和小程序 `GameLaunchEnvelope` 基本是同一语义。
|
||
|
||
## 4.3 session 运行态和结果态已分离
|
||
|
||
- [session_service.go](D:/dev/cmr-mini/backend/internal/service/session_service.go)
|
||
|
||
当前已经区分:
|
||
|
||
- 业务登录态:`access_token`
|
||
- 局内运行态:`sessionToken`
|
||
|
||
这对地图页是对的,因为地图页真正需要的是:
|
||
|
||
- 进入前有业务 token
|
||
- 进入后局内动作用 sessionToken
|
||
|
||
## 4.4 开发 workbench 已可用于联调
|
||
|
||
- [dev_handler.go](D:/dev/cmr-mini/backend/internal/httpapi/handlers/dev_handler.go)
|
||
|
||
当前 workbench 已能串:
|
||
|
||
- bootstrap
|
||
- auth
|
||
- entry/home
|
||
- event play / launch
|
||
- session start / finish / detail
|
||
- result 查询
|
||
|
||
这对前后端联调非常有价值,说明后端已经不是“只看文档”阶段。
|
||
|
||
## 5. 当前已经能接的链路
|
||
|
||
## 5.1 P0:登录与业务页前置链
|
||
|
||
可接:
|
||
|
||
1. 小程序 `wx.login`
|
||
2. `POST /auth/login/wechat-mini`
|
||
3. 拿到 `accessToken`
|
||
4. 调 `GET /me/entry-home`
|
||
5. 调 `GET /events/{eventPublicID}/play`
|
||
|
||
当前缺口:
|
||
|
||
- 小程序还没有正式业务页 API 适配层
|
||
- 还没有统一 token 持久化与请求封装
|
||
|
||
## 5.2 P0:launch 进入地图
|
||
|
||
可接:
|
||
|
||
1. 前置业务页拿到 event play
|
||
2. 调 `POST /events/{eventPublicID}/launch`
|
||
3. 把返回结果映射成 `GameLaunchEnvelope`
|
||
4. `navigateTo('/pages/map/map?...')`
|
||
|
||
当前缺口:
|
||
|
||
- 还没有一层 `backend launch -> GameLaunchEnvelope` 的适配函数
|
||
- 当前 `gameLaunch.ts` 仍偏 demo/static config 驱动
|
||
|
||
## 5.3 P0:finish 回传结果
|
||
|
||
可接:
|
||
|
||
1. 地图页结束一局
|
||
2. 提取结果摘要
|
||
3. 用 `sessionId + sessionToken` 调 `POST /sessions/{id}/finish`
|
||
4. 业务页或结果页再查 `GET /sessions/{id}/result`
|
||
|
||
当前缺口:
|
||
|
||
- 小程序本地结果页已经有摘要,但还没有正式调用 backend finish
|
||
- finish payload 和本地 `resultSummary` 之间还需要一层映射
|
||
|
||
## 6. 当前还不能说已经接通的链路
|
||
|
||
## 6.1 配置后台 source/build/release
|
||
|
||
backend 当前已经有:
|
||
|
||
- 表结构
|
||
- 文档模型
|
||
|
||
但还没有真正开放:
|
||
|
||
- `config source`
|
||
- `build`
|
||
- `release assets`
|
||
- `preview launch`
|
||
|
||
也就是说:
|
||
|
||
**配置后台链还不能联调,只能联业务主链。**
|
||
|
||
## 6.2 body profile / 遥测个体化
|
||
|
||
小程序已经有:
|
||
|
||
- 身体数据入口
|
||
- 遥测 runtime profile
|
||
|
||
backend 文档里也规划了:
|
||
|
||
- 用户身体资料
|
||
|
||
但当前接口清单里还没有明确的 body profile 读接口落到小程序链上,所以这条还不能算当前联调主线。
|
||
|
||
## 7. 当前最大的接口适配缺口
|
||
|
||
我认为目前最大缺口只有 4 个:
|
||
|
||
### 7.1 业务 API 客户端缺失
|
||
|
||
小程序当前缺:
|
||
|
||
- 统一 `request` 封装
|
||
- token 持久化
|
||
- access token 刷新
|
||
- backend DTO -> 小程序 view model 适配
|
||
|
||
### 7.2 launch 适配层缺失
|
||
|
||
需要一层明确的转换:
|
||
|
||
`LaunchResponse -> GameLaunchEnvelope`
|
||
|
||
这里最适合单独做成一个小模块,而不是散落在页面里。
|
||
|
||
### 7.3 session finish 映射缺失
|
||
|
||
地图页当前本地已经有:
|
||
|
||
- 用时
|
||
- 分数
|
||
- 完成点数
|
||
- 里程
|
||
- 速度
|
||
- 最大心率
|
||
|
||
但还没有一个稳定函数把它映射为 backend finish payload。
|
||
|
||
### 7.4 业务结果页与地图结果页还未打通
|
||
|
||
现在地图页已经有自己的结果页。
|
||
|
||
后面要决定:
|
||
|
||
- 地图页结果页先本地展示,再异步回传
|
||
- 还是 finish 成功后跳业务结果页
|
||
|
||
这件事需要前后端统一策略。
|
||
|
||
## 8. 推荐联调顺序
|
||
|
||
建议按下面顺序推进,不要跳步:
|
||
|
||
### 第一步:接微信小程序登录
|
||
|
||
目标:
|
||
|
||
- 小程序拿到 `accessToken`
|
||
- 能请求鉴权接口
|
||
|
||
### 第二步:接 event play
|
||
|
||
目标:
|
||
|
||
- 小程序业务页能拿到:
|
||
- `event`
|
||
- `resolvedRelease`
|
||
- `play.canLaunch`
|
||
- `play.ongoingSession`
|
||
|
||
### 第三步:接 launch -> map
|
||
|
||
目标:
|
||
|
||
- 从后端 launch 返回直接进入地图
|
||
- 不再靠 demo preset 手工切配置
|
||
|
||
### 第四步:接 start / finish / result
|
||
|
||
目标:
|
||
|
||
- 开赛后能回传 start
|
||
- 结束后能回传 finish
|
||
- 结果页能查 backend result
|
||
|
||
### 第五步:再考虑 ongoing session 恢复
|
||
|
||
目标:
|
||
|
||
- backend ongoing session
|
||
- 本地故障恢复
|
||
|
||
两条链统一口径
|
||
|
||
## 9. 当前已落地的小程序联调适配
|
||
|
||
小程序侧当前已经补了第一批适配层:
|
||
|
||
- [backendAuth.ts](D:/dev/cmr-mini/miniprogram/utils/backendAuth.ts)
|
||
- [backendApi.ts](D:/dev/cmr-mini/miniprogram/utils/backendApi.ts)
|
||
- [backendLaunchAdapter.ts](D:/dev/cmr-mini/miniprogram/utils/backendLaunchAdapter.ts)
|
||
- [index.ts](D:/dev/cmr-mini/miniprogram/pages/index/index.ts)
|
||
|
||
当前已具备:
|
||
|
||
- 后端 base URL 本地持久化
|
||
- access / refresh token 本地持久化
|
||
- 微信小程序登录请求封装
|
||
- `event play` 请求封装
|
||
- `launch -> GameLaunchEnvelope` 适配
|
||
- 从首页直接 `launch` 进入地图
|
||
- 地图页 `session start / finish` 上报接入
|
||
|
||
因此当前主链已从“可分析”进入“可实测”。
|
||
|
||
## 10. 我建议的最近行动项
|
||
|
||
如果开始联调,我建议先做这 3 件事:
|
||
|
||
1. 新增小程序 `backendApi` 请求层
|
||
先只包 auth / event play / launch / session finish
|
||
|
||
2. 新增 `launchAdapter`
|
||
把 backend launch 响应稳定转成 `GameLaunchEnvelope`
|
||
|
||
3. 新增 `finishAdapter`
|
||
把地图页结果摘要稳定转成 backend finish payload
|
||
|
||
这三件做完,前后端主链就能真正接起来。
|
||
|
||
## 11. 一句话结论
|
||
|
||
当前最真实的进度判断是:
|
||
|
||
> backend 业务后端主链已经进入可联调阶段;小程序地图运行内核也已经具备承接能力;下一步最值钱的是补小程序业务 API 层和 launch/finish 两个适配器。
|