feat: checkpoint m5 and bootstrap m6 asset flow

This commit is contained in:
2026-04-22 14:46:43 +08:00
parent 0773a0d0ca
commit 91fb8edee7
22 changed files with 5096 additions and 445 deletions

View File

@@ -68,14 +68,91 @@
40. 已再次执行 `cargo check -p spacetime-client --manifest-path D:\\Genarrative\\server-rs\\Cargo.toml``cargo check -p api-server --manifest-path D:\\Genarrative\\server-rs\\Cargo.toml`,当前 battle/story 新链路在编译层已恢复通过。
41. 已新增 `docs/technical/M4_RUNTIME_STORY_COMPAT_STATE_BRIDGE_DESIGN_2026-04-22.md`,冻结旧 `POST /api/runtime/story/state/resolve` 的首版兼容桥边界,明确当前先做 DTO 与状态桥,不提前误宣称 `actions/resolve` 已可迁移。
42. 已在 `server-rs/crates/shared-contracts` 中新增 `runtime_story` 模块,冻结 `RuntimeStoryStateResolveRequest``RuntimeStoryActionResponse` 以及 `viewModel / presentation / patches / snapshot` 的首版 camelCase DTO与当前前端消费口径对齐。
43. 已恢复并重建 `server-rs/crates/api-server/src/runtime_story.rs`,把上一轮误删留下的中间态收口回可编译实现。
44. 已在 Rust `api-server` 侧挂出旧 runtime story 兼容接口:
- `POST /api/runtime/story/state/resolve`
- `GET /api/runtime/story/state/:sessionId`
- `POST /api/runtime/story/actions/resolve`
- `POST /api/runtime/story/initial`
- `POST /api/runtime/story/continue`
45. `state/resolve``actions/resolve` 已统一复用 `runtime_save` 的 SpacetimeDB 快照持久化链:
- 请求带 `snapshot` 时先写入 `runtime_snapshot`
- 请求不带 `snapshot` 时从持久化 `runtime_snapshot` 读取
- 无可用快照时返回 `409`
46. `actions/resolve` 已补齐当前前端主链需要的确定性兼容动作闭环,覆盖:
- `story_continue_adventure`
- `story_opening_camp_dialogue`
- `camp_travel_home_scene`
- `idle_call_out`
- `idle_explore_forward`
- `idle_observe_signs`
- `idle_rest_focus`
- `idle_travel_next_scene`
- `npc_preview_talk`
- `npc_chat`
- `npc_help`
- `npc_leave`
- `npc_fight`
- `npc_spar`
- `npc_recruit`
- `battle_attack_basic`
- `battle_use_skill`
- `battle_all_in_crush`
- `battle_escape_breakout`
- `battle_feint_step`
- `battle_finisher_window`
- `battle_guard_break`
- `battle_probe_pressure`
- `battle_recover_breath`
- `treasure_secure`
- `treasure_inspect`
- `treasure_leave`
47. `actions/resolve` 已补 `clientVersion``gameState.runtimeActionVersion` 的冲突校验、动作后版本自增、`storyHistory` 追加和 snapshot 回写。
48. `initial` / `continue` 已先落稳定 `RuntimeStoryAiResponse`
- 优先透传 `requestOptions.availableOptions / optionCatalog`
- 未配置 LLM 时走确定性 fallback 文本
- 已配置 `platform-llm` 时可做文本增强,但不阻塞接口可用性
49. 已执行 `cargo test -p shared-contracts``cargo check -p api-server``cargo test -p api-server runtime_story` 并通过,当前 runtime story 兼容链在 Rust 侧已恢复到可编译、可测试状态。
50. 已补 Rust 侧 route boundary 回归:
- `runtime_story_routes_resolve_through_rust_route_boundary`
- `runtime_story_action_resolve_rejects_client_version_conflict`
- `runtime_story_npc_help_is_one_shot_and_restores_resources`
- `runtime_story_npc_recruit_requires_threshold_and_release_target_when_party_full`
51. 已把兼容桥里的关键 NPC 行为继续对齐到 Node 旧主链:
- `npc_chat` 好感增长改为 `max(2, 6 - chattedCount)`,首聊可从 `46 -> 52`
- `npc_help` 改为一次性援手,成功时恢复 `10 HP / 8 Mana` 且关系 `+4`
- `npc_recruit` 改为要求 `affinity >= 60`,队伍满员时必须透传 `releaseNpcId`
52. 已补测试环境专用的 runtime snapshot 内存兜底,仅在 `#[cfg(test)]` 下生效,用于在未启动本地 SpacetimeDB 时稳定回归 `PUT /api/runtime/save/snapshot -> GET /api/runtime/story/state -> POST /api/runtime/story/actions/resolve` 这条 Rust 边界链。
53. 已把 quest compat 主循环补到 Rust `runtime story` 兼容桥:
- `npc_chat_quest_offer_view`
- `npc_chat_quest_offer_replace`
- `npc_chat_quest_offer_abandon`
- `npc_quest_accept`
- `npc_quest_turn_in`
54. 已把 quest offer 对话态的 `currentStory.npcChatState.pendingQuestOffer` 与前端面板依赖的 `runtimePayload.npcChatQuestOfferAction` 一并回填到 Rust compat 回包,保证现有 quest 面板入口不回退。
55. 已把 `npc_quest_turn_in` 的最小奖励闭环补回 Rust compat handler
- quest 状态改为保留在 `gameState.quests` 中的 `turned_in`
- 同步写回 `playerCurrency`
- 同步写回 `playerInventory`
- 同步写回 `playerProgression.totalXp / level / xpToNextLevel / lastGrantedSource`
- 同步写回 NPC `affinity`
56. 已新增 quest compat Rust 回归:
- `runtime_story_quest_offer_replace_updates_pending_offer_and_payload`
- `runtime_story_quest_offer_abandon_clears_pending_offer_and_restores_chat_options`
- `runtime_story_quest_accept_writes_quest_runtime_stats_and_followup_story`
- `runtime_story_quest_turn_in_marks_quest_rewards_and_affinity`
57. 已再次执行 `cargo test -p api-server runtime_story``cargo check -p api-server``node scripts/check-encoding.mjs` 并通过,当前 quest compat 已恢复到可编译、可回归状态。
当前验证边界补充:
1. `story_sessions` / `story_battles` 的二进制测试目标在当前机器上编译耗时很长,已有多轮回归尝试,但还没有在单次时窗内收敛到最终断言结果
2. `npm run check:encoding` 已启动到 `node scripts/check-encoding.mjs`,但当前尚未在单次时窗内跑完,不能标记为已完成
3. 因此,当前可以确认的是 `module -> generated bindings -> spacetime-client -> api-server` 的编译链已打通;测试与编码检查仍应继续追。
1. `story_sessions` / `story_battles` 的二进制测试目标在当前机器上编译耗时仍然较长,还没有把更大范围的 story/battle 回归全部收拢到单次时窗内
2. `node scripts/check-encoding.mjs` 已再次执行并通过,当前本轮涉及的中文文件编码未被写坏
3. 当前可以确认的是
- `module -> generated bindings -> spacetime-client -> api-server` 的编译链已打通
- Rust `runtime story` compat route boundary 与关键 NPC 主循环规则已有回归覆盖
- 真正的 `resolve_story_action / sync_runtime_snapshot_projection` 真相链仍未完成
当前这轮仍未扩到 `resolve_story_action``sync_runtime_snapshot_projection`、旧 `/api/runtime/story/*` 兼容接口和前端实际 runtime story API 切换,这些继续保留在后续 `M4` 工作项中
当前这轮仍未扩到真正的 SpacetimeDB `resolve_story_action` / `sync_runtime_snapshot_projection` 真相 reducer也还没有完成前端默认切流到 Rust `api-server`。当前已完成的是“旧 `/api/runtime/story/*` 兼容接口在 Rust 侧的快照桥与确定性动作闭环”,后续 `M4` 继续推进真相态替换与前端切换
## 1. SpacetimeDB gameplay 表
@@ -106,7 +183,7 @@
- [ ] 迁移 `rpg-entry` 配套后端入口能力
- [ ] 迁移 `rpg-profile` 资料域
- [ ] 迁移 `rpg-runtime-story`
- [x] 迁移 `rpg-runtime-story`
- [x] 迁移 `combat`
- [ ] 迁移 `inventory`
- [ ] 迁移 `npc`
@@ -117,37 +194,67 @@
## 4. 兼容接口
- [ ] 兼容 `POST /api/runtime/story/actions/resolve`
- [ ] 兼容 `GET /api/runtime/story/state/:sessionId`
- [ ] 兼容 `POST /api/runtime/story/state/resolve`
- [ ] 兼容 `POST /api/runtime/story/initial`
- [ ] 兼容 `POST /api/runtime/story/continue`
- [x] 兼容 `POST /api/runtime/story/actions/resolve`
- [x] 兼容 `GET /api/runtime/story/state/:sessionId`
- [x] 兼容 `POST /api/runtime/story/state/resolve`
- [x] 兼容 `POST /api/runtime/story/initial`
- [x] 兼容 `POST /api/runtime/story/continue`
补充说明:
1. 当前已落地的是新的 Rust facade
1. 当前已落地的是两类 Rust facade
- 新真相态接口:
- `POST /api/story/sessions`
- `POST /api/story/sessions/continue`
- `GET /api/story/sessions/:storySessionId/state`
- `GET /api/story/battles/:battleStateId`
- `POST /api/story/npc/battle`
2. 其中前 3 个接口是 `story session` 真相链路,后 2 个接口是 battle / NPC 开战真相链路,都不等价于旧 Node 的 LLM `runtime/story/*` 兼容接口
3. 当前新增的 `story state` 查询只返回 `storySession + storyEvents`,还没有兼容旧 `RuntimeStoryActionResponse``currentStory``availableOptions`
4. 当前新增的 `battle state` 查询只返回单个 `battleState`,还没有拼回旧 runtime story state 视图。
5.`resolve_story_action / story state` contract 未冻结前,不应误勾选旧兼容接口。
-runtime story 兼容接口
- `POST /api/runtime/story/state/resolve`
- `GET /api/runtime/story/state/:sessionId`
- `POST /api/runtime/story/actions/resolve`
- `POST /api/runtime/story/initial`
- `POST /api/runtime/story/continue`
2. 其中新真相态接口仍是 `story session / battle / NPC 开战` 的底层切片;旧 `runtime/story/*` 则是复用 `runtime_snapshot` 的兼容桥,不等价于最终真相态实现。
3. 当前 `runtime/story/*` 已能返回旧前端需要的 `RuntimeStoryActionResponse / AIResponse` 形状,但内部动作仍以确定性兼容编排为主,不代表 `resolve_story_action` 真相 reducer 已完成。
4. 当前新增的 `battle state` 查询仍只返回单个 `battleState` 真相切片,不等价于 runtime story 全量视图。
5. 后续 `M4` 仍需把兼容桥逐步替换成真正的 story action / snapshot projection 真相链。
## 5. ViewModel 兼容
- [ ] 兼容当前 `RuntimeStoryActionResponse`
- [ ] 兼容当前 `RuntimeStoryOptionView`
- [ ] 兼容当前 `interaction` 元数据
- [ ] 兼容当前 battle / toast / patch 响应结构
- [ ] 兼容当前 `currentStory` 回填逻辑
- [x] 兼容当前 `RuntimeStoryActionResponse`
- [x] 兼容当前 `RuntimeStoryOptionView`
- [x] 兼容当前 `interaction` 元数据
- [x] 兼容当前 battle / toast / patch 响应结构
- [x] 兼容当前 `currentStory` 回填逻辑
## 6. 阶段验收
- [ ] 当前前端 story 选项点击后可走新后端闭环
- [x] 当前前端 story 选项点击后可走新后端闭环
- [ ] NPC / quest / treasure / combat 主循环行为不回退
- [ ] `story state` 恢复链可用
- [x] `story state` 恢复链可用
- [ ] 后端边界与当前 `rpgEntry -> rpgSession -> rpgRuntime -> rpgRuntimeStory -> rpgProfile` 口径一致
- [ ] 旧 Node 版 story route 回归用例完成平移
- [x] 旧 Node 版 story route 回归用例完成平移
阶段验收补充说明:
1. `当前前端 story 选项点击后可走新后端闭环` 当前按 Rust `api-server` 的真实边界回归判定已满足:
- `PUT /api/runtime/save/snapshot`
- `GET /api/runtime/story/state/runtime-main`
- `POST /api/runtime/story/actions/resolve`
但这不等于“生产默认流量已经切到 Rust”。
2. `story state 恢复链可用` 当前指:
- 请求带 `snapshot` 时可先写后读
- 请求不带 `snapshot` 时可从已持久化 `runtime_snapshot` 恢复
3. `旧 Node 版 story route 回归用例完成平移` 当前指:
- 已平移 Node 的 `rpg runtime story routes resolve through the new route boundary`
- 已补 `clientVersion` 冲突回归
- 已把 `npc_chat``46 -> 52` Node 旧语义对齐进 Rust compat handler
4. `NPC / quest / treasure / combat 主循环行为不回退` 仍不能勾选:
- 虽然 `npc_chat / npc_help / npc_recruit / npc_chat_quest_offer_* / npc_quest_accept / npc_quest_turn_in / npc_fight / npc_spar / treasure_* / battle_*` 已有确定性兼容闭环
- 且 quest 交付奖励、quest offer 对话态与 quest follow-up 选项已补到 Rust compat handler
- 但 treasure / combat 的更大范围 Node 回归还没全部平移
- 真相态 reducer 仍未替换 compat bridge
5. `后端边界与当前 rpgEntry -> ...` 仍不能勾选:
- 前端真实调用链已对齐 `/api/runtime/story/*`
- 但“默认走 Rust server”的联调证据仍未冻结