Files
cmr-mini/doc/archive/config/后台配置管理方案.md

422 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 配置驱动应用的后台管理方案建议
> 文档版本v1.0
> 最后更新2026-04-02
本文用于整理当前这类“配置驱动型地图游戏应用”的后台管理建议,面向:
- PostgreSQL 数据库
- Go 中间层
- 后台管理系统
- 客户端静态配置发布
目标是解决一个核心问题:
**配置文件会越来越大,如何在后台可维护、可复用、可审核、可发布、可回滚。**
---
## 1. 总体原则
最稳的方案不是“数据库直接存一大份 `game.json` 给客户端读”,而是:
**数据库管理编辑态,发布时编译成运行态静态配置文件。**
也就是两套形态:
### 编辑态
- 存在 PostgreSQL
- 适合后台表单编辑
- 支持版本管理
- 支持对象复用
- 支持审核、比对、回滚
### 运行态
- 由 Go 中间层装配生成
- 输出为静态 JSON
- 上传到 OSS/CDN
- 客户端只读取发布后的静态配置
这条路线最适合当前项目。
---
## 2. 不建议的做法
不建议把后台做成:
- 一张表里存一个超大的 `jsonb`
- 后台直接编辑整份 `game.json`
- 客户端通过 API 动态拼装所有配置
这样后面会遇到这些问题:
- 配置复用困难
- diff 难看
- 回滚困难
- 审核困难
- 局部编辑体验差
- 客户端运行态不稳定
---
## 3. 推荐的核心对象
建议后台和数据库先固定这 5 个核心对象:
### `Map`
地图底座。
负责:
- 瓦片资源
- meta 信息
- 磁偏角
- 初始视角
### `Playfield`
玩法空间对象定义。
负责:
- KML 来源
- 控制点覆盖信息
- 区域对象
- 危险区
- 采集物
- 起终点信息
说明:
- `Playfield` 是上位概念
- `course` 只是其中一种特化形式
### `GameMode`
玩法模板。
负责:
- 顺序赛
- 积分赛
- 后续幽灵赛、迷雾赛、金币赛等
也就是:
- `game.mode`
- `session`
- `punch`
- `scoring`
- `guidance`
- `visibility`
- `finish`
- `telemetry`
- `feedback`
### `ResourcePack`
资源包。
负责:
- 音效 profile
- 文创内容
- 图标
- HUD 主题
- 动效 profile
### `Event`
最终活动实例。
负责引用:
- 一个 `Map`
- 一个 `Playfield`
- 一个 `GameMode`
- 一个 `ResourcePack`
并允许少量活动级覆盖。
一句话:
**Event = Map + Playfield + GameMode + ResourcePack + EventOverrides**
---
## 4. 数据库建模建议
建议每个核心对象都分成:
- 主表
- version 表
### 4.1 主表
主表存稳定元信息:
- `id`
- `slug`
- `name`
- `status`
- `current_version_id`
- `created_at`
- `updated_at`
### 4.2 version 表
version 表存每个版本的具体内容:
- `id`
- `parent_id`
- `version_no`
- `schema_version`
- `content_jsonb`
- `created_by`
- `created_at`
- `change_note`
### 4.3 推荐表
建议至少有:
- `maps`
- `map_versions`
- `playfields`
- `playfield_versions`
- `game_modes`
- `game_mode_versions`
- `resource_packs`
- `resource_pack_versions`
- `events`
- `event_versions`
---
## 5. 为什么要做版本表
版本表的价值非常大:
- 支持草稿
- 支持发布版
- 支持 diff
- 支持回滚
- 支持审计
- 支持多人协作
如果没有版本表,后面后台管理一定会越来越难维护。
---
## 6. JSONB 的使用建议
推荐策略是:
- 稳定字段结构化
- 变化快的配置内容放 `jsonb`
例如主表中:
- `slug`
- `name`
- `status`
放结构化列。
而玩法具体配置、资源清单、覆盖字段,放在 `content_jsonb`
这样兼顾:
- 查询效率
- 结构灵活性
- 配置扩展性
---
## 7. 后台编辑方式建议
后台不要直接给运营一个大 JSON 编辑框作为主要方式。
推荐做法:
- 地图编辑页
- Playfield 编辑页
- 玩法规则页
- 资源包页
- 活动编排页
按模块表单化编辑。
最后由 Go 中间层负责装配成最终配置 JSON。
也就是:
**后台是“编辑结构化对象”,不是“手工拼最终运行文件”。**
---
## 8. 发布机制建议
发布时建议按下面流程:
1. 后台选定某个 `Event Version`
2. Go 中间层读取它引用的:
- `Map Version`
- `Playfield Version`
- `GameMode Version`
- `ResourcePack Version`
3. 做装配
4. 做校验
5. 生成最终运行态 JSON
6. 上传 OSS/CDN
7. 记录一条 release
客户端只读:
- 已发布的静态配置 URL
不要让客户端直接查数据库 API 动态拼。
---
## 9. 推荐增加 Release 层
建议增加:
- `event_releases`
字段例如:
- `id`
- `event_id`
- `event_version_id`
- `release_no`
- `manifest_url`
- `published_by`
- `published_at`
- `status`
它的作用:
- 一键回滚
- 客户端锁定某次 release
- 管理历史发布记录
- 灰度验证
---
## 10. Go 中间层建议职责
Go 中间层不要只做 CRUD。
建议它至少承担这 4 类职责:
### 10.1 校验
- schema 校验
- 引用存在校验
- 字段完整性校验
- 规则约束校验
### 10.2 装配
把:
- `Map`
- `Playfield`
- `GameMode`
- `ResourcePack`
- `Event Overrides`
装配成最终配置结构。
### 10.3 发布
- 生成最终静态 JSON
- 上传到 OSS/CDN
- 记录 release
### 10.4 对比与预览
- 给后台显示 diff
- 给发布前做预览
一句话:
**Go 中间层本质上是配置编译器。**
---
## 11. 校验建议
建议尽量做强校验。
至少包括:
- schemaVersion 合法
- 引用对象存在
- KML 路径存在
- 地图 meta 存在
- 玩法字段完整
以及玩法特定约束,例如:
- 顺序赛必须有 start / finish
- 积分赛 control set 需要 score 或可派生 score
- `punch.radiusMeters > 0`
- `skip.radiusMeters > punch.radiusMeters`
这样能把很多错误挡在发布前。
---
## 12. 和当前静态目录的关系
当前你已经有类似目录:
- `map/`
- `kml/`
- `event/`
这很好,可以继续保留。
建议把它理解成:
- 数据库 = 编辑态
- 这些目录 = 发布产物态
也就是后台发布后Go 中间层继续生成:
- `event/classic-sequential.json`
- `event/score-o.json`
- `map/...`
- `kml/...`
客户端保持现有读取方式不变。
---
## 13. 推荐的后续实施顺序
建议按这个顺序落地:
### 第一步
先建 5 个核心对象模型:
- `Map`
- `Playfield`
- `GameMode`
- `ResourcePack`
- `Event`
### 第二步
为每个对象补版本表。
### 第三步
Go 中间层实现“装配成最终 JSON”。
### 第四步
实现“发布到 OSS/CDN”。
### 第五步
后台逐步从 JSON 编辑过渡到模块化表单编辑。
---
## 14. 一句话总结
这类配置驱动应用最稳的后台方案是:
**PostgreSQL 管结构化、可版本化的编辑态对象Go 中间层负责校验、装配和发布;客户端只消费发布后的静态 JSON。**
这样才能做到:
- 可复用
- 可扩展
- 可审核
- 可回滚
- 可稳定运行