This commit is contained in:
2026-04-29 20:56:59 +08:00
parent fb6f455530
commit 730f485f48
200 changed files with 9881 additions and 2221 deletions

View File

@@ -0,0 +1,45 @@
# 拼图运行态 `run_json` 计时字段兼容修复 2026-04-29
## 背景
作品详情页点击“启动”时Rust API 通过 SpacetimeDB `start_puzzle_run` procedure 拿到字符串化的 `run_json`,再在 `spacetime-client` 映射层反序列化为拼图运行态快照。
本次线上报错为:
```text
puzzle run run_json 非法: missing field `started_at_ms`
```
说明主云 procedure 已成功返回快照,但返回的 JSON 仍可能是旧字段集,没有带上后续限时与排行榜迭代新增的计时字段。
## 根因
`PuzzleRuntimeLevelSnapshot` 在早期 PRD 中只包含关卡基础信息、棋盘和状态。后续版本新增:
1. `started_at_ms`
2. `cleared_at_ms`
3. `elapsed_ms`
4. `time_limit_ms`
5. `remaining_ms`
6. `paused_accumulated_ms`
7. `pause_started_at_ms`
8. `freeze_accumulated_ms`
9. `freeze_started_at_ms`
10. `freeze_until_ms`
11. `leaderboard_entries`
其中部分字段已经有 `serde(default)`,但 `started_at_ms``cleared_at_ms``elapsed_ms``leaderboard_entries` 仍按必填字段解析。只要主云旧模块或历史快照缺少这些字段API facade 就会在映射层失败,导致详情页启动中断。
## 修复口径
本次只做后端兼容,不改表结构,不改前端表现:
1. `module-puzzle` 的运行态快照新增字段统一允许缺省。
2. 旧 JSON 缺 `started_at_ms` 时,用当前毫秒时间作为兼容起点,保证前端倒计时不会从 `0` 时间戳开始。
3. 旧棋盘缺 `all_tiles_resolved` 时按 `false` 处理。
4. 旧 run / level 缺 `leaderboard_entries` 时按空榜单处理。
5. `spacetime-client` 增加回归测试,确保 `run_json` 缺新增计时字段仍能启动。
## 经验结论
`procedure -> run_json/items_json -> client record` 这类链路只要返回字符串化聚合快照,新增字段就必须默认具备向后兼容能力。平台入口级操作不应因为单个新增字段缺失直接 500能安全补默认值的字段应在服务端契约层统一兜底。