# B2B 交接文档
> 文档版本：v1.0
> 最后更新：2026-04-07 18:47:09

## 1. 文档用途

这份文档给“新线程 / 新接手人”直接使用，目标是：

1. 快速理解当前 backend 主线已经做到哪里。
2. 明确哪些架构约束已经定死，不能再随意回退。
3. 明确当前运维后台、调试后台、前后端联调各自的边界。
4. 给出下一步应该从哪里继续，而不是重新摸索一遍。

---

## 2. 先说结论

当前 backend 已经形成三条比较稳定的主线：

1. `玩家链`
   - `entry -> auth -> home/cards -> event detail/play -> launch -> session -> result`

2. `游客链`
   - `public experience maps -> public event detail/play -> public launch`

3. `运维链`
   - `资源录入 -> 地图/地点管理 -> 路线资源管理 -> 活动管理/编排 -> 发布中心`

同时，调试与运维已经明确分离：

- 调试后台：`/dev/workbench`
- 运维后台：`/admin/ops-workbench`

当前接口总数：

- `116`

---

## 3. 当前最重要的架构边界

### 3.1 活动运行模型

当前已经明确，第一阶段活动模型按最小运行单元收口：

- `单地图`
- `单路线组`
- `单玩法`

不要在第一阶段把单个活动扩成：

- 多地图
- 多路线组
- 多玩法

复杂需求后续通过两种方式承接：

1. `活动实例化`
   - 一个复杂主题拆成多个明确活动实例。

2. `组合入口 / 组合卡片`
   - 前台组合多个活动实例形成复杂入口。

这条原则已经同步给总控，后续不要回退。

### 3.2 玩家进入游戏的依据

玩家进入游戏必须基于：

- `已发布 release`

而不是：

- event 草稿
- event 默认绑定
- 未发布的 presentation / content bundle

当前 `play.canLaunch` 已按这条规则收紧：

必须同时具备：

- event 是 `active`
- 当前已发布 release 存在
- release 有 `manifest`
- release 绑定了 `runtime`
- release 绑定了 `presentation`
- release 绑定了 `content bundle`

否则：

- `play.canLaunch = false`

### 3.3 调试后台与运维后台分离

不要再把所有能力塞回一个页面。

当前原则：

- `/dev/workbench`
  - 只做联调、一键回归、日志、摘要、问题排查

- `/admin/ops-workbench`
  - 只做资源录入、地图/路线/活动管理、发布中心

---

## 4. 用户明确表达过的产品/交互偏好

这些是用户多次强调过的，后续要严格遵守。

### 4.1 不要把所有功能平铺在一个长页面里

用户明确反感“所有功能平铺一个页面”的方式。

正确方向：

- 列表就是列表
- 点某一项进详情
- 新增/编辑用：
  - 新页面
  - 弹出页
  - 分步流程

不要继续堆按钮。

### 4.2 运维后台要符合人的使用习惯

例如在地图管理里，用户明确要求的是：

1. 先进入地图列表
2. 右上角有：
   - `添加地图`
   - `添加地点`
3. 点一张地图再进入详情
4. 地图上传能力要放在地图管理里

### 4.3 运维后台 UI 必须尽量利用宽屏

用户明确要求：

- 不要再固定窄宽度
- 主区要做最大宽度适配
- 不要浪费屏幕空间

### 4.4 开发环境尽量免登录

用户明确要求：

- 开发环境不要每次都要求登录

当前已实现：

- `APP_ENV != production` 时，`/ops/admin/*` 默认可免登录使用
- 即使浏览器残留旧玩家 token / 过期 token / 非 ops token，也会自动 fallback 到 dev ops 上下文

---

## 5. 当前已完成的关键能力

## 5.1 调试后台

入口：

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

地址：

- `/dev/workbench`

已完成：

- demo bootstrap
- 一键发布链
- 一键标准回归
- 前端调试日志上报与查看
- 当前玩法关键状态卡
- Launch 实际配置摘要
- 准备页地图预览状态
- API 目录按业务链分类展示

调试链已经能稳定支撑：

- 选玩法
- 回归
- 看日志
- 看 launch / manifest / preview 摘要

## 5.2 游客模式

公开接口：

- `GET /public/experience-maps`
- `GET /public/experience-maps/{mapAssetPublicID}`
- `GET /public/events/{eventPublicID}`
- `GET /public/events/{eventPublicID}/play`
- `POST /public/events/{eventPublicID}/launch`

语义：

- 只允许默认体验活动
- 只允许基于已发布 release
- `launch.business.isGuest = true`
- `launch.source = public-default-experience`

游客 launch 曾经被 `guest` identity DB 约束卡死，已通过 migration 修复。

## 5.3 地图列表下的默认体验活动

接口：

- `GET /experience-maps`
- `GET /experience-maps/{mapAssetPublicID}`

当前用于前端地图列表下的“默认体验活动”展示。

## 5.4 运维后台

入口：

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

地址：

- `/admin/ops-workbench`

当前导航结构已收成：

- `资源总览`
- `地图 / 地点管理`
- `路线资源管理`
- `活动管理`
- `活动编排`
- `发布中心`
- `资源录入`

注意：

- 这只是第一版结构
- 还没有完全做成成熟的列表页/详情页后台
- 但已经明确不再走“全平铺”老路

## 5.5 资源录入第二期基础能力

已新增统一资源模型接口：

- `GET /ops/admin/assets`
- `POST /ops/admin/assets/register-link`
- `POST /ops/admin/assets/upload`
- `GET /ops/admin/assets/{assetPublicID}`

目的：

- 运维无需操心资源到底来自上传文件还是外链
- 最终都纳管成统一资源对象

---

## 6. 当前地图/地点管理做到哪里了

这是接下来最可能继续做的主线。

当前已经做了这些：

1. 地图/地点管理已不再是平铺对象区
2. 地图列表成为主入口
3. 右上角只有：
   - `添加地图`
   - `添加地点`
4. 地图详情改成弹层
5. 地点编辑改成弹层
6. 地点支持：
   - 省份
   - 城市
   - 最终回填 `region`
7. 新增地区接口：
   - `GET /ops/admin/region-options`

地区数据源：

- [https://github.com/uiwjs/province-city-china](https://github.com/uiwjs/province-city-china)
- [https://unpkg.com/province-city-china/dist/province.json](https://unpkg.com/province-city-china/dist/province.json)
- [https://unpkg.com/province-city-china/dist/city.json](https://unpkg.com/province-city-china/dist/city.json)

业务约束：

- 一个地点可以有多张地图
- 一张地图只能属于一个地点

刚刚修复过一个关键前端脚本 bug：

- `managed-place-id` 隐藏状态字段在重构时被删掉
- 导致 `refresh-map-area` 前端脚本异常，只打印 `{ error: {} }`
- 现已补回，同时错误日志已展开成：
  - `name`
  - `message`
  - `stack`
  - `status/body/url`

---

## 7. 数据库与 migration 重要说明

开发库：

- `cmr20260401`

注意：

- backend 启动脚本不会自动帮你补所有历史 migration
- 之前已经遇到过“代码修了，库没跟上”的问题

开发库里曾手工补过的重要 migration：

1. [D:\dev\cmr-mini\backend\migrations\0012_managed_assets.sql](D:/dev/cmr-mini/backend/migrations/0012_managed_assets.sql)
2. [D:\dev\cmr-mini\backend\migrations\0013_ops_console.sql](D:/dev/cmr-mini/backend/migrations/0013_ops_console.sql)
3. [D:\dev\cmr-mini\backend\migrations\0015_guest_identity.sql](D:/dev/cmr-mini/backend/migrations/0015_guest_identity.sql)

这些都已经在当前开发库应用过。

如果新线程遇到“文档说修了，但接口还是异常”，先查两件事：

1. 当前 API 实例是不是连着 `cmr20260401`
2. 对应 migration 有没有真的进库

---

## 8. 关键文件入口

### 8.1 路由与中间件

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

### 8.2 调试后台

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

### 8.3 运维后台

- [D:\dev\cmr-mini\backend\internal\httpapi\handlers\ops_workbench_handler.go](D:/dev/cmr-mini/backend/internal/httpapi/handlers/ops_workbench_handler.go)
- [D:\dev\cmr-mini\backend\internal\httpapi\handlers\region_options_handler.go](D:/dev/cmr-mini/backend/internal/httpapi/handlers/region_options_handler.go)

### 8.4 地图默认体验活动 / 游客模式

- [D:\dev\cmr-mini\backend\internal\service\map_experience_service.go](D:/dev/cmr-mini/backend/internal/service/map_experience_service.go)
- [D:\dev\cmr-mini\backend\internal\httpapi\handlers\map_experience_handler.go](D:/dev/cmr-mini/backend/internal/httpapi/handlers/map_experience_handler.go)
- [D:\dev\cmr-mini\backend\internal\service\public_experience_service.go](D:/dev/cmr-mini/backend/internal/service/public_experience_service.go)
- [D:\dev\cmr-mini\backend\internal\httpapi\handlers\public_experience_handler.go](D:/dev/cmr-mini/backend/internal/httpapi/handlers/public_experience_handler.go)

### 8.5 运维总览

- [D:\dev\cmr-mini\backend\internal\store\postgres\ops_summary_store.go](D:/dev/cmr-mini/backend/internal/store/postgres/ops_summary_store.go)
- [D:\dev\cmr-mini\backend\internal\service\ops_summary_service.go](D:/dev/cmr-mini/backend/internal/service/ops_summary_service.go)

### 8.6 资源录入 / 受管资源

- [D:\dev\cmr-mini\backend\internal\service\admin_asset_service.go](D:/dev/cmr-mini/backend/internal/service/admin_asset_service.go)
- [D:\dev\cmr-mini\backend\internal\httpapi\handlers\admin_asset_handler.go](D:/dev/cmr-mini/backend/internal/httpapi/handlers/admin_asset_handler.go)
- [D:\dev\cmr-mini\backend\internal\store\postgres\asset_store.go](D:/dev/cmr-mini/backend/internal/store/postgres/asset_store.go)

---

## 9. 必读文档

新线程建议先看这些，不要一上来就只看代码。

1. [D:\dev\cmr-mini\backend\README.md](D:/dev/cmr-mini/backend/README.md)
2. [D:\dev\cmr-mini\backend\docs\开发说明.md](D:/dev/cmr-mini/backend/docs/开发说明.md)
3. [D:\dev\cmr-mini\backend\docs\后台管理最小方案.md](D:/dev/cmr-mini/backend/docs/后台管理最小方案.md)
4. [D:\dev\cmr-mini\backend\docs\资源对象与目录方案.md](D:/dev/cmr-mini/backend/docs/资源对象与目录方案.md)
5. [D:\dev\cmr-mini\backend\docs\接口清单.md](D:/dev/cmr-mini/backend/docs/接口清单.md)
6. [D:\dev\cmr-mini\b2t.md](D:/dev/cmr-mini/b2t.md)
7. [D:\dev\cmr-mini\b2f.md](D:/dev/cmr-mini/b2f.md)

其中：

- `b2t.md` 看 backend 写给总控的当前结论
- `b2f.md` 看 backend 写给前端的当前联调口径

---

## 10. 当前最值得继续做的事

新线程接手后，建议优先级如下：

### P0：把“地图/地点管理”真正做成列表 -> 详情流

目标：

1. 地图列表作为稳定主入口
2. 地图详情弹层稳定
3. 添加地图/添加地点弹层稳定
4. 地图上传能力放进地图管理流

这里的“上传地图”不是指调试式填 URL，而是最终要收成：

- 上传文件
- 或登记链接
- backend 统一纳管

### P1：把地图详情页做扎实

建议继续补：

- 当前瓦片版本
- 历史瓦片版本
- 简单预览
- 默认体验活动数量
- 关联活动数量
- 跳转到活动管理

注意：

- 地图页只看数量和摘要
- 活动详情不要重新塞回地图页

### P2：后续再做路线资源管理同样的列表 -> 详情流

KML/路线页也应遵守同一原则：

- 列表就是列表
- 点一项进详情
- 上传就是上传
- 不在首页平铺所有对象编辑器

---

## 11. 本线程最后一次真实修复

如果新线程接手后发现：

- 进入 `/admin/ops-workbench`
- 切到“地图 / 地点管理”
- 状态栏显示：
  - `失败：refresh-map-area`
- 响应日志里还是：
  - `{ "error": {} }`

先确认是否已经是本线程修后的代码版本。

本线程最后一次修复的是：

- 恢复 `managed-place-id` 隐藏状态字段
- 展开运维页前端异常日志

相关文件：

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

---

## 12. 本地验证方式

不要让新线程重复踩坑，直接照这个流程：

1. backend 编译

```powershell
cd D:\dev\cmr-mini\backend
go build ./...
```

2. 启动 backend

```powershell
cd D:\dev\cmr-mini\backend
.\start-backend.ps1
```

3. 浏览器强刷

```text
Ctrl + F5
```

4. 检查两个入口

- 调试后台：
  - [http://127.0.0.1:18090/dev/workbench](http://127.0.0.1:18090/dev/workbench)
- 运维后台：
  - [http://127.0.0.1:18090/admin/ops-workbench](http://127.0.0.1:18090/admin/ops-workbench)

---

## 13. 一句话交接

当前 backend 已经把：

- 调试后台
- 游客模式
- 默认体验地图接口
- 运维后台第一版骨架

都立起来了。

接下来最该继续的不是扩新对象，而是把：

**地图 / 地点管理 -> 路线资源管理 -> 活动管理 / 编排 -> 发布中心**

这条运维主流程，按“列表 -> 详情 -> 弹层 / 分步”的方式做扎实。
