diff --git a/b2f.md b/b2f.md
index f71dcf9..4bb3881 100644
--- a/b2f.md
+++ b/b2f.md
@@ -1,6 +1,6 @@
# b2f
-> 文档版本:v1.0
-> 最后更新:2026-04-02 09:01:17
+> 文档版本:v1.3
+> 最后更新:2026-04-02 15:25:40
说明:
@@ -54,6 +54,51 @@
- frontend 是否确认正式流程只消费上述字段,不再自行推断 release URL
- 是否已解决:否
+### B2F-015
+
+- 时间:2026-04-02
+- 谁提的:backend
+- 当前事实:
+ - backend 已阅读前端多赛道文档:
+ - [多赛道 Variant 五层设计草案](D:/dev/cmr-mini/doc/gameplay/多赛道Variant五层设计草案.md)
+ - [多赛道 Variant 前后端最小契约](D:/dev/cmr-mini/doc/gameplay/多赛道Variant前后端最小契约.md)
+ - backend 认可第一阶段先做“最小契约”,不先做完整后台模型
+ - backend 当前建议的第一阶段正式口径为:
+ - `play.assignmentMode`
+ - `play.courseVariants[]`
+ - `id`
+ - `name`
+ - `description`
+ - `routeCode`
+ - `selectable`
+ - `launch.variant.id`
+ - `launch.variant.name`
+ - `launch.variant.routeCode`
+ - `launch.variant.assignmentMode`
+ - `session / ongoing / recent / result` 摘要中补:
+ - `variantId`
+ - `variantName`
+ - `routeCode`
+ - backend 第一阶段实现目标仍然保持保守:
+ - 一个 session 只绑定一个最终 `variantId`
+ - `launch` 返回最终绑定结果
+ - 恢复链不重新分配 variant
+ - 当前兼容性约束:
+ - 如果 `assignmentMode=manual` 且前端暂时未传 `variantId`
+ - backend 当前会先回退到首个可选 variant,避免旧主链直接被打断
+ - backend 当前已完成第一阶段最小实现:
+ - `GET /events/{eventPublicID}/play`
+ - `POST /events/{eventPublicID}/launch`
+ - `GET /me/entry-home`
+ - `GET /sessions/{sessionPublicID}`
+ - `GET /sessions/{sessionPublicID}/result`
+ - `GET /me/results`
+ - `GET /me/sessions`
+ - 上述链路已能携带第一阶段 variant 摘要字段
+- 需要对方确认什么:
+ - frontend 可按这组字段开始第一阶段联调
+- 是否已解决:是
+
---
## 已确认
@@ -121,6 +166,49 @@
- frontend 继续按当前补报 / 重试逻辑联调
- 是否已解决:是
+### B2F-016
+
+- 时间:2026-04-02
+- 谁提的:backend
+- 当前事实:
+ - backend 已确认 `launch` 当前关键字段为前端正式联调契约:
+ - `resolvedRelease.manifestUrl`
+ - `resolvedRelease.releaseId`
+ - `business.sessionId`
+ - `business.sessionToken`
+ - `business.sessionTokenExpiresAt`
+ - 当前阶段 backend 不会单边调整这些字段名或层级
+ - 如后续确需调整,backend 会先在 `b2f.md` 明确通知,再安排联调变更
+- 需要对方确认什么:
+ - frontend 继续按当前字段接入,不做额外推断
+- 是否已解决:是
+
+### B2F-017
+
+- 时间:2026-04-02
+- 谁提的:backend
+- 当前事实:
+ - backend 已完成对 ongoing 口径的代码回归确认
+ - 当前实现中:
+ - 只有 `launched` 和 `running` 会被识别为 ongoing
+ - `cancelled`、`failed`、`finished` 都不会再进入 ongoing
+ - `/me/entry-home` 与 `/events/{eventPublicID}/play` 当前都复用同一 ongoing 判定逻辑
+ - `/me/results` 当前只返回终态 session:
+ - `finished`
+ - `failed`
+ - `cancelled`
+ - 当前首页摘要、play 摘要、result 详情都会复用同一组 session 基础摘要字段:
+ - `id`
+ - `status`
+ - `eventId`
+ - `eventName`
+ - `releaseId`
+ - `configLabel`
+ - `routeCode`
+- 需要对方确认什么:
+ - frontend 可以按这套 ongoing / result 口径继续回归
+- 是否已解决:是
+
---
## 阻塞
@@ -226,6 +314,52 @@
- 无
- 是否已解决:是
+### B2F-018
+
+- 时间:2026-04-02
+- 谁提的:backend
+- 当前事实:
+ - backend 已补一条可联调的 `manual` 多赛道 demo 活动:
+ - `eventPublicID = evt_demo_variant_manual_001`
+ - `releaseId = rel_demo_variant_manual_001`
+ - `channelCode = mini-demo`
+ - `channelType = wechat_mini`
+ - 当前 demo 配置为:
+ - `assignmentMode = manual`
+ - `courseVariants = [variant_a, variant_b]`
+ - 当前两条可选赛道:
+ - `variant_a`
+ - `name = A 线`
+ - `routeCode = route-variant-a`
+ - `variant_b`
+ - `name = B 线`
+ - `routeCode = route-variant-b`
+ - 该活动已由 `POST /dev/bootstrap-demo` 自动准备
+- 需要对方确认什么:
+ - 无
+- 是否已解决:是
+
+### B2F-019
+
+- 时间:2026-04-02
+- 谁提的:backend
+- 当前事实:
+ - backend 已完成 `variant_b` 的 service 层回归验证
+ - 已确认从 `launch` 选定的 `variantId` 会稳定回流到:
+ - `GET /me/entry-home`
+ - `GET /sessions/{sessionPublicID}/result`
+ - `GET /me/results`
+ - 实测链路为:
+ - `play.assignmentMode=manual`
+ - `play.courseVariants=2`
+ - `launch.variant.id=variant_b`
+ - `entry-home recent.variantId=variant_b`
+ - `result.session.variantId=variant_b`
+ - `results[0].session.variantId=variant_b`
+- 需要对方确认什么:
+ - 无
+- 是否已解决:是
+
---
## 下一步
@@ -244,6 +378,7 @@
- frontend 当前优先配合:
- 用当前 demo release 回归 `play -> launch -> map load`
- 回归“继续恢复 / 放弃恢复”两条路径
+ - 如确认进入多赛道第一阶段联调,请先回复 `B2F-015`
- 如发现状态口径不一致,直接在 `f2b.md` 标具体接口和返回值
- 是否已解决:否
diff --git a/backend/README.md b/backend/README.md
index e4d4900..5a2a133 100644
--- a/backend/README.md
+++ b/backend/README.md
@@ -1,6 +1,6 @@
# Backend
-> 文档版本:v1.0
-> 最后更新:2026-04-02 08:28:05
+> 文档版本:v1.1
+> 最后更新:2026-04-02 09:35:44
这套后端现在已经能支撑一条完整主链:
@@ -46,5 +46,8 @@ go run .\cmd\api
- 局生命周期:`start / finish / detail`
- 局后结果:`/sessions/{id}/result`、`/me/results`
- 开发工作台:`/dev/workbench`
+ - 用户主链调试
+ - 资源对象与 Event 组装调试
+ - Build / Publish / Rollback 调试
diff --git a/backend/docs/todolist.md b/backend/docs/todolist.md
index 4703462..c56b56d 100644
--- a/backend/docs/todolist.md
+++ b/backend/docs/todolist.md
@@ -1,6 +1,6 @@
# Backend TodoList
-> 文档版本:v1.0
-> 最后更新:2026-04-02 08:28:05
+> 文档版本:v1.2
+> 最后更新:2026-04-02 11:03:02
## 1. 目标
@@ -37,6 +37,8 @@
- `evt_demo_001` 的 release manifest 现已可正常加载
- 小程序已能进入地图
+- `launch` 关键字段在当前阶段不再单边漂移
+- `cancelled / failed / finished` 已从 ongoing 口径里收稳
- 模拟定位 / 调试日志问题已回到小程序与模拟器侧,不再属于 backend 当前阻塞
前端当前需要配合的事项:
@@ -160,27 +162,36 @@ backend 现在需要做的是:
## 4. P1 应尽快做
-## 4.1 给首页 / play / result 的 ongoing 语义再做一次回归确认
+## 4.1 多赛道 Variant 第一阶段最小契约
-当前前端已经开始走:
+当前前端已给出:
-- 首页聚合
-- `event play`
-- `launch`
-- `session start / finish`
-- 本地故障恢复
+- [多赛道 Variant 五层设计草案](D:/dev/cmr-mini/doc/gameplay/多赛道Variant五层设计草案.md)
+- [多赛道 Variant 前后端最小契约](D:/dev/cmr-mini/doc/gameplay/多赛道Variant前后端最小契约.md)
-backend 建议再回归确认这几个接口对“进行中 session”的口径一致:
+backend 当前建议第一阶段只做最小闭环:
-- `/me/entry-home`
-- `/events/{eventPublicID}/play`
-- `/sessions/{sessionPublicID}/result`
+- `play.assignmentMode`
+- `play.courseVariants[]`
+- `launch.variant.*`
+- `session / result / ongoing / recent` 补 `variantId / variantName / routeCode`
-重点确认:
+当前目标:
-1. `cancelled` 后不再继续出现在 ongoing 入口
-2. `failed` 后不再继续出现在 ongoing 入口
-3. `finished` 后结果页与首页摘要字段一致
+1. 一个 session 最终只绑定一个 `variantId`
+2. `launch` 返回最终绑定结果
+3. 恢复链不重新分配 variant
+4. 结果页、ongoing、历史结果都能追溯 variant
+
+备注:
+
+- 当前只先定最小契约,不先做完整后台 variant 编排模型
+- 当前第一阶段最小后端链路已补入:
+ - `play.assignmentMode`
+ - `play.courseVariants[]`
+ - `launch.variant.*`
+ - `session / result / ongoing / recent` 的 `variantId / variantName / routeCode`
+- 下一步应由前端按该契约联调,不再继续扩后台 variant 模型
## 4.2 增加用户身体资料读取接口
@@ -318,18 +329,18 @@ backend 后面如果要接业务结果页,最好提前定:
## 7. 我建议的最近动作
-backend 现在最值得先做的,不是扩接口,而是先确认下面 3 条:
+backend 现在最值得先做的,不是继续铺更多页面接口,而是先推进下面 3 条:
-1. `finished / failed / cancelled` 三态语义
-2. 放弃恢复是否写 `cancelled`
-3. `start / finish` 是否按幂等处理
+1. 与前端确认多赛道第一阶段最小契约
+2. 已按最小契约扩完 `play -> launch -> session/result`
+3. 再补用户身体资料接口和 workbench 恢复场景按钮
-这 3 条一旦确定,前后端联调会顺很多。
+这样不会打断当前主链,同时能把下一阶段多赛道联调接上。
## 8. 一句话结论
当前 backend 最重要的任务不是“再加更多接口”,而是:
-> 先把 session 运行态语义、放弃恢复语义和 ongoing session 口径定稳,再继续扩后台配置系统。
+> 在不破坏当前稳定主链的前提下,先把多赛道 Variant 第一阶段最小契约定稳,再继续向配置与后台模型延伸。
diff --git a/backend/docs/开发说明.md b/backend/docs/开发说明.md
index 571d590..65f7352 100644
--- a/backend/docs/开发说明.md
+++ b/backend/docs/开发说明.md
@@ -1,6 +1,6 @@
# 开发说明
-> 文档版本:v1.0
-> 最后更新:2026-04-02 08:28:05
+> 文档版本:v1.1
+> 最后更新:2026-04-02 09:35:44
## 1. 环境变量
@@ -51,6 +51,11 @@ cd D:\dev\cmr-mini\backend
- [http://127.0.0.1:18090/dev/workbench](http://127.0.0.1:18090/dev/workbench)
+当前 workbench 已覆盖两类调试链:
+
+- 用户主链:`bootstrap -> auth -> entry/home -> event play/launch -> session -> result`
+- 后台运营链:`maps/playfields/resource-packs -> admin event source -> build -> publish -> rollback`
+
## 3. 当前开发约定
### 3.1 开发阶段先不用 Redis
diff --git a/backend/docs/接口清单.md b/backend/docs/接口清单.md
index 5615cf3..2af383f 100644
--- a/backend/docs/接口清单.md
+++ b/backend/docs/接口清单.md
@@ -1,6 +1,6 @@
# API 清单
-> 文档版本:v1.0
-> 最后更新:2026-04-02 09:01:17
+> 文档版本:v1.1
+> 最后更新:2026-04-02 11:05:32
本文档只记录当前 backend 已实现接口,不写未来规划接口。
@@ -121,6 +121,12 @@
- `ongoingSession`
- `recentSession`
+`ongoingSession / recentSession` 当前会额外带:
+
+- `variantId`
+- `variantName`
+- `routeCode`
+
## 4. Event
### `GET /events/{eventPublicID}`
@@ -150,6 +156,8 @@
- `event`
- `release`
- `resolvedRelease`
+- `play.assignmentMode`
+- `play.courseVariants`
- `play.canLaunch`
- `play.primaryAction`
- `play.launchSource`
@@ -169,13 +177,21 @@
请求体重点:
- `releaseId`
+- `variantId`
- `clientType`
- `deviceKey`
+补充说明:
+
+- 如果当前 release 声明了 `play.courseVariants[]`
+- `launch` 会返回最终绑定的 `launch.variant`
+- 当前为兼容旧调用方,`assignmentMode=manual` 且未传 `variantId` 时,backend 会先回退到首个可选 variant
+
返回重点:
- `launch.source`
- `launch.resolvedRelease`
+- `launch.variant`
- `launch.config`
- `launch.business.sessionId`
- `launch.business.sessionToken`
@@ -228,6 +244,13 @@
- `event`
- `resolvedRelease`
+`session` 当前会额外带:
+
+- `assignmentMode`
+- `variantId`
+- `variantName`
+- `routeCode`
+
### `POST /sessions/{sessionPublicID}/start`
鉴权:
@@ -312,6 +335,9 @@
- `releaseId`
- `configLabel`
+- `variantId`
+- `variantName`
+- `routeCode`
### `GET /me/results`
diff --git a/backend/docs/核心流程.md b/backend/docs/核心流程.md
index c90fdfc..77f5383 100644
--- a/backend/docs/核心流程.md
+++ b/backend/docs/核心流程.md
@@ -1,6 +1,6 @@
# 核心流程
-> 文档版本:v1.0
-> 最后更新:2026-04-02 08:28:05
+> 文档版本:v1.1
+> 最后更新:2026-04-02 11:03:02
## 1. 总流程
@@ -100,6 +100,7 @@ APP 当前主链是手机号验证码:
- 当前是否可启动
- 当前会落到哪份 `release`
+- 当前是否存在多赛道 `variant` 编排
- 是否有 ongoing session
- 当前推荐动作是什么
@@ -112,12 +113,27 @@ APP 当前主链是手机号验证码:
- `event`
- `release`
- `resolvedRelease`
+- `play.assignmentMode`
+- `play.courseVariants[]`
- `play.canLaunch`
- `play.primaryAction`
- `play.launchSource`
- `play.ongoingSession`
- `play.recentSession`
+当前多赛道第一阶段约束:
+
+- `play.assignmentMode` 只先支持最小口径:
+ - `manual`
+ - `random`
+ - `server-assigned`
+- `play.courseVariants[]` 只先返回准备页必需字段:
+ - `id`
+ - `name`
+ - `description`
+ - `routeCode`
+ - `selectable`
+
## 6. Launch 流程
### 6.1 当前原则
@@ -135,6 +151,7 @@ APP 当前主链是手机号验证码:
当前请求体支持:
- `releaseId`
+- `variantId`
- `clientType`
- `deviceKey`
@@ -142,6 +159,7 @@ APP 当前主链是手机号验证码:
- `launch.source`
- `launch.resolvedRelease`
+- `launch.variant`
- `launch.config`
- `launch.business.sessionId`
- `launch.business.sessionToken`
@@ -158,6 +176,14 @@ APP 当前主链是手机号验证码:
- `launch.resolvedRelease.releaseId`
- `launch.resolvedRelease.manifestUrl`
- `launch.resolvedRelease.manifestChecksumSha256`
+- `launch.variant.id`
+- `launch.variant.assignmentMode`
+
+补充说明:
+
+- 如果活动声明了多赛道 variant,`launch` 会返回本局最终绑定的 `variant`
+- 前端可以发起选择,但最终绑定以后端 `launch` 返回为准
+- 故障恢复不重新分配 variant
而不是再拿 `event` 自己去猜。
@@ -195,6 +221,11 @@ APP 当前主链是手机号验证码:
- `cancelled` 和 `failed` 都不再作为 ongoing session 返回
- “放弃恢复”当前正式收口为 `finish(cancelled)`
- 同一局旧 `sessionToken` 在 `finish(cancelled)` 场景允许继续使用
+- 第一阶段若活动声明了多赛道,session 会固化:
+ - `assignmentMode`
+ - `variantId`
+ - `variantName`
+ - `routeCode`
### 7.4 幂等要求
@@ -232,6 +263,7 @@ APP 当前主链是手机号验证码:
- 一个 event 未来可能发布新版本
- 历史结果必须追溯到当时真实跑过的那份 release
+- 如果一场活动存在多个 variant,结果与历史摘要也必须能追溯本局 `variantId`
## 9. 当前最应该坚持的流程约束
diff --git a/backend/internal/httpapi/handlers/dev_handler.go b/backend/internal/httpapi/handlers/dev_handler.go
index 0a9a52d..d82666c 100644
--- a/backend/internal/httpapi/handlers/dev_handler.go
+++ b/backend/internal/httpapi/handlers/dev_handler.go
@@ -92,6 +92,101 @@ const devWorkbenchHTML = `
color: var(--muted);
line-height: 1.6;
}
+ .layout {
+ display: grid;
+ grid-template-columns: 260px minmax(0, 1fr);
+ gap: 20px;
+ align-items: start;
+ }
+ .sidebar {
+ position: sticky;
+ top: 18px;
+ display: grid;
+ gap: 16px;
+ }
+ .workspace {
+ display: grid;
+ gap: 0;
+ min-width: 0;
+ }
+ .side-card {
+ background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)), var(--panel);
+ border: 1px solid var(--line);
+ border-radius: 18px;
+ padding: 16px;
+ display: grid;
+ gap: 12px;
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.18);
+ }
+ .side-card h2 {
+ margin: 0;
+ font-size: 16px;
+ }
+ .side-card p {
+ margin: 0;
+ color: var(--muted);
+ font-size: 12px;
+ line-height: 1.6;
+ }
+ .mode-list,
+ .side-links {
+ display: grid;
+ gap: 8px;
+ }
+ .mode-btn,
+ .side-link {
+ display: inline-flex;
+ align-items: center;
+ justify-content: flex-start;
+ min-height: 40px;
+ padding: 0 14px;
+ border-radius: 12px;
+ border: 1px solid var(--line);
+ background: rgba(255,255,255,0.04);
+ color: var(--text);
+ font-size: 13px;
+ font-weight: 600;
+ text-decoration: none;
+ cursor: pointer;
+ }
+ .mode-btn.active {
+ background: rgba(79, 209, 165, 0.16);
+ border-color: rgba(79, 209, 165, 0.55);
+ color: var(--accent);
+ }
+ .guide-list {
+ display: grid;
+ gap: 8px;
+ margin: 0;
+ padding-left: 18px;
+ color: var(--muted);
+ font-size: 13px;
+ line-height: 1.6;
+ }
+ .category-head {
+ display: grid;
+ gap: 6px;
+ margin: 28px 0 14px;
+ }
+ .category-kicker {
+ color: var(--accent);
+ font-size: 12px;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+ }
+ .category-head h2 {
+ margin: 0;
+ font-size: 24px;
+ line-height: 1.2;
+ }
+ .category-head p {
+ margin: 0;
+ color: var(--muted);
+ line-height: 1.6;
+ font-size: 13px;
+ max-width: 960px;
+ }
.grid {
display: grid;
gap: 16px;
@@ -244,6 +339,24 @@ const devWorkbenchHTML = `
display: grid;
gap: 12px;
}
+ .api-summary {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin: 4px 0 2px;
+ }
+ .api-chip {
+ display: inline-flex;
+ align-items: center;
+ min-height: 30px;
+ padding: 0 10px;
+ border-radius: 999px;
+ border: 1px solid var(--line);
+ background: rgba(255,255,255,0.04);
+ color: var(--muted);
+ font-size: 12px;
+ font-weight: 600;
+ }
.api-item {
display: grid;
gap: 8px;
@@ -255,6 +368,9 @@ const devWorkbenchHTML = `
.api-item.hidden {
display: none;
}
+ .mode-hidden {
+ display: none !important;
+ }
.api-head {
display: flex;
flex-wrap: wrap;
@@ -299,6 +415,8 @@ const devWorkbenchHTML = `
color: var(--danger);
}
@media (max-width: 900px) {
+ .layout { grid-template-columns: 1fr; }
+ .sidebar { position: static; }
.row.two { grid-template-columns: 1fr; }
.shell { padding: 20px 16px 32px; }
}
@@ -312,20 +430,64 @@ const devWorkbenchHTML = `
把入口、登录、首页、活动详情、launch、session、profile 串成一条完整调试链。这个页面只在非 production 环境开放,适合后续继续扩展成你想要的 API 测试面板。
+
+
+
+
+
+
+
Main Flow
+
联调主区
+
前台联调和配置发布最常用的入口都在这里。先跑通用户主链,再处理配置与发布。
+
-
- 1. Bootstrap
+
+ 准备 Demo 数据
初始化 demo tenant / channel / event / card。
+
默认入口 tenant_demo / mini-demo / evt_demo_001
+
多赛道入口 tenant_demo / mini-demo / evt_demo_variant_manual_001
-
- 2. Config Pipeline
+
+ 本地配置导入与发布
从本地 event 目录导入 source config,生成 preview build,并可直接发布成当前 release。
-
- 3. Session State
+
+ 当前上下文
当前调试上下文,所有按钮共享这一组状态。
Access Token -
@@ -370,8 +532,8 @@ const devWorkbenchHTML = `
-
- 4. SMS Auth
+
+ 短信登录 / 绑定
-
- 5. WeChat Mini
+
+ 微信小程序登录
开发环境可直接使用 dev-xxx code。
-
- 6. Entry / Home
+
-
- 7. Event
+
+ 活动与启动
@@ -465,8 +629,8 @@ const devWorkbenchHTML = `
-
- 8. Session
+
-
- 9. Results
+
+ 结果查询
-
- 10. Profile
+
+ 当前用户
@@ -540,9 +704,14 @@ const devWorkbenchHTML = `
-
-
- 11. Quick Flows
+
+
Fast Path
+
快捷操作
+
当你只是想验证“能不能跑通”,优先使用这一组。
+
+
+
+ 一键流程
把常用接口串成一键工作流,减少重复点击。
@@ -553,8 +722,8 @@ const devWorkbenchHTML = `
这些流程会复用当前表单里的手机号、设备、event、channel 等输入。
-
- 12. Request Export
+
+ 请求导出
最后一次请求会生成一条可复制的 curl,后面做问题复现会方便很多。
@@ -567,9 +736,262 @@ const devWorkbenchHTML = `
+
+
Advanced
+
后台运营与发布
+
这一组给资源对象、Event 组装、Build / Publish / Rollback 使用。默认隐藏,只有需要管理配置和资源时再打开。
+
+
+
+
-
- 13. Scenarios
+
+
+
+ 场景模板
保存当前表单状态为可复用场景,也支持导入导出 JSON,适合后续切换不同俱乐部、入口和 event。
-
- 14. Response Log
+
+ 响应日志
最后一次请求的结果会记录在这里,便于后续做请求回放和用例保存。
ready
@@ -603,21 +1025,27 @@ const devWorkbenchHTML = `
-
- 15. Request History
+
+ 请求历史
最近 12 次请求会保留在浏览器本地,刷新页面不会丢。
-
-
- 16. API 列表
+
+
Reference
+
API 目录 (0)
+
需要查路径、参数、鉴权方式时再展开这一块,不影响主链调试。
+
+
+
+ API 目录
把当前已实现接口按分组放进 workbench,直接看中文说明、鉴权要求和关键参数,不用来回翻文档。
+
GET/healthz
@@ -709,18 +1137,18 @@ const devWorkbenchHTML = `
-
+
GET/events/{eventPublicID}/play
-
活动详情页 / 开始前准备页聚合接口,判断是否可启动、继续还是查看上次结果。
+
活动详情页 / 开始前准备页聚合接口,判断是否可启动、继续还是查看上次结果;第一阶段也会返回多赛道 assignmentMode 和 courseVariants。
-
+
POST/events/{eventPublicID}/launch
-
基于当前 event 的已发布 release 创建一局 session,并返回 config URL、releaseId、sessionToken。
+
基于当前 event 的已发布 release 创建一局 session,并返回 config URL、releaseId、sessionToken;多赛道第一阶段支持可选 variantId,并返回最终绑定的 launch.variant。
@@ -834,15 +1262,180 @@ const devWorkbenchHTML = `
关键参数:buildId
+
+
+
GET/admin/maps
+
后台地图对象列表接口。
+
+
+
+
+
POST/admin/maps
+
创建地图对象,后续再为它追加版本。
+
+
+
+
+
GET/admin/maps/{mapPublicID}
+
查看单个地图对象和它的版本列表。
+
+
+
+
+
POST/admin/maps/{mapPublicID}/versions
+
为地图对象创建一个版本,挂接 mapmeta 和 tiles 根路径。
+
+
+
+
+
GET/admin/playfields
+
后台赛场对象列表接口。
+
+
+
+
+
POST/admin/playfields
+
创建赛场对象,适合管理 KML / GeoJSON 这类可复用场地资源。
+
+
+
+
+
GET/admin/playfields/{playfieldPublicID}
+
查看单个赛场对象和它的版本列表。
+
+
+
+
+
POST/admin/playfields/{playfieldPublicID}/versions
+
为赛场对象创建一个版本,挂接 KML 等源文件地址和控制点摘要。
+
+
+
+
+
GET/admin/resource-packs
+
后台资源包对象列表接口。
+
+
+
+
+
POST/admin/resource-packs
+
创建资源包对象,用来管理内容页、音频和主题资源。
+
+
+
+
+
GET/admin/resource-packs/{resourcePackPublicID}
+
查看单个资源包对象和它的版本列表。
+
+
+
+
+
POST/admin/resource-packs/{resourcePackPublicID}/versions
+
为资源包对象创建版本,配置内容入口、音频根路径和主题代码。
+
+
+
+
+
GET/admin/events
+
后台 event 列表接口。
+
+
+
+
+
POST/admin/events
+
创建 event 基础信息。
+
+
+
+
+
GET/admin/events/{eventPublicID}
+
查看 event 明细、最新 source 和当前 source 摘要。
+
+
+
+
+
PUT/admin/events/{eventPublicID}
+
更新 event 基础信息。
+
+
+
+
+
POST/admin/events/{eventPublicID}/source
+
把 map/playfield/resource pack 版本和 gameModeCode 组装成 source config。
+
+
+
+
+
GET/admin/events/{eventPublicID}/pipeline
+
查看 event 下的 source、build、release 流水线概览。
+
+
+
+
+
POST/admin/sources/{sourceID}/build
+
基于 source 生成一条 build 记录和 preview manifest。
+
+
+
+
+
GET/admin/builds/{buildID}
+
查看后台 build 明细。
+
+
+
+
+
POST/admin/builds/{buildID}/publish
+
把后台 build 发布为正式 release,并切换为 event 当前发布版本。
+
+
+
+
+
POST/admin/events/{eventPublicID}/rollback
+
将 event 当前发布版本回滚到指定 releaseId。
+
+
+
+