补齐runtime story到STDB的兼容桥
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
- [STDB_AUTH_TAIL_PHASE2_TOKEN_SLOT_SPLIT_2026-04-20.md](./STDB_AUTH_TAIL_PHASE2_TOKEN_SLOT_SPLIT_2026-04-20.md):将 STDB token 与旧 HTTP Bearer token 拆成独立存储槽。
|
||||
- [RUNTIME_STORY_TO_STDB_PHASE1_TRANSPORT_ABSTRACTION_2026-04-20.md](./RUNTIME_STORY_TO_STDB_PHASE1_TRANSPORT_ABSTRACTION_2026-04-20.md):把 `runtimeStoryService` 改成可替换 transport,为后续 STDB provider 接入预留稳定边界。
|
||||
- [RUNTIME_STORY_TO_STDB_PHASE2_CONTRACT_DESIGN_2026-04-20.md](./RUNTIME_STORY_TO_STDB_PHASE2_CONTRACT_DESIGN_2026-04-20.md):梳理 runtime story 从 Express 迁到 STDB 所需的聚合 view、procedure、mapper 与前端 provider 设计。
|
||||
- [RUNTIME_STORY_TO_STDB_PHASE2A_COMPAT_BRIDGE_2026-04-20.md](./RUNTIME_STORY_TO_STDB_PHASE2A_COMPAT_BRIDGE_2026-04-20.md):确认 runtime story 当前 STDB/Express 快照真源分裂,并补一层只改 story 边界的 STDB 兼容桥。
|
||||
- [TASK_AUTO_COMMIT_WORKFLOW_2026-04-20.md](./TASK_AUTO_COMMIT_WORKFLOW_2026-04-20.md):任务完成后按文件边界自动提交的脚本与协作约定。
|
||||
- [NODE_DEV_STARTUP_HOTFIX_2026-04-20.md](./NODE_DEV_STARTUP_HOTFIX_2026-04-20.md):`npm run dev` 启动失败的热修记录、根因与验证结果。
|
||||
- [NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md](./NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md):当前 Node 运行时后端的技术栈、入口、鉴权、存储与接口知识图谱。
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
# Runtime Story 向 STDB 迁移 Phase 2A:兼容桥(2026-04-20)
|
||||
|
||||
## 1. 本轮目标
|
||||
|
||||
这轮不是直接把 `runtime story` 全量改成 SpacetimeDB provider,而是先补一层最小兼容桥,解决当前仓库里已经实际出现的两类断裂:
|
||||
|
||||
1. `runtime story` 前置快照写入已经走 STDB
|
||||
2. `/api/runtime/story/*` 仍然从 `server-node` 的旧 `RuntimeRepository` 读取 Postgres 快照
|
||||
3. 前端认证主链路已经切到 STDB,旧 HTTP Bearer token 不再保证可持续刷新
|
||||
|
||||
因此本轮目标是:
|
||||
|
||||
1. 保持 `runtimeStoryCoordinator` 和上层页面契约不变
|
||||
2. 保持 `server-node/src/modules/story/storyActionService.ts` 现有规则实现不重写
|
||||
3. 只在 `runtime story` 边界补齐:
|
||||
- 前端请求可携带 STDB token
|
||||
- `server-node` 的 story route 可直接使用 STDB token 解析身份
|
||||
- `server-node` 的 story route 可直接从 STDB 读写 snapshot
|
||||
|
||||
## 2. 当前问题确认
|
||||
|
||||
### 2.1 快照真源已经分裂
|
||||
|
||||
当前前端 [`src/hooks/story/runtimeStoryCoordinator.ts`](/home/Genarrative/src/hooks/story/runtimeStoryCoordinator.ts) 在读取或执行 runtime story 之前,会先调用:
|
||||
|
||||
1. [`putSaveSnapshot`](/home/Genarrative/src/services/storageService.ts)
|
||||
2. 该调用实际走 STDB `saveSnapshot` procedure
|
||||
|
||||
但旧的 `/api/runtime/story/*` 仍然走:
|
||||
|
||||
1. [`storyActionRoutes.ts`](/home/Genarrative/server-node/src/modules/story/storyActionRoutes.ts)
|
||||
2. [`storyActionService.ts`](/home/Genarrative/server-node/src/modules/story/storyActionService.ts)
|
||||
3. [`RuntimeRepository.getSnapshot()`](/home/Genarrative/server-node/src/repositories/runtimeRepository.ts)
|
||||
|
||||
也就是:
|
||||
|
||||
1. 写快照在 STDB
|
||||
2. 读快照在 Postgres
|
||||
|
||||
这已经不是“未来可能出现”的风险,而是当前迁移阶段的真实断链。
|
||||
|
||||
### 2.2 旧 HTTP token 不再是可靠前提
|
||||
|
||||
当前前端认证主链路已经切到:
|
||||
|
||||
1. [`src/services/authService.ts`](/home/Genarrative/src/services/authService.ts)
|
||||
2. [`src/spacetime/client.ts`](/home/Genarrative/src/spacetime/client.ts)
|
||||
|
||||
也就是说:
|
||||
|
||||
1. 页面登录、恢复会话、匿名建连主要依赖 STDB token
|
||||
2. 旧 HTTP access token 仅剩兼容用途
|
||||
3. `/api/auth/refresh` 也不再保证始终存在有效 refresh cookie
|
||||
|
||||
因此继续假设 `/api/runtime/story/*` 一定能依赖旧 JWT Bearer,是不稳的。
|
||||
|
||||
## 3. 本轮兼容桥方案
|
||||
|
||||
### 3.1 前端
|
||||
|
||||
[`runtimeStoryService.ts`](/home/Genarrative/src/services/runtimeStoryService.ts) 继续保留 HTTP transport,但在请求 `/api/runtime/story/*` 时:
|
||||
|
||||
1. 优先携带现有 HTTP access token
|
||||
2. 若不存在 HTTP access token,则回退携带 STDB token
|
||||
3. 新增专用 header,明确这是一条 runtime story 的 STDB 兼容认证链路
|
||||
|
||||
这样上层调用不变,但 `server-node` 侧已经能识别 STDB token。
|
||||
|
||||
### 3.2 后端鉴权
|
||||
|
||||
`server-node` 为 `/api/runtime/story/*` 单独补一层兼容认证:
|
||||
|
||||
1. 先尝试旧 JWT Bearer
|
||||
2. 若 Bearer 不是 JWT 或 JWT 校验失败,则尝试按 STDB token 建连解析身份
|
||||
3. 解析成功后,把 `request.userId` 设为 STDB account id
|
||||
|
||||
注意:
|
||||
|
||||
1. 这不是把所有 `server-node` 路由都改成 STDB 认证
|
||||
2. 只对 runtime story 这条仍未迁完的兼容链路生效
|
||||
|
||||
### 3.3 快照读写
|
||||
|
||||
`storyActionService` 现有规则仍保持不变,但其读取与写回的 `runtimeRepository` 改为支持 STDB snapshot 的兼容仓储。
|
||||
|
||||
优先级:
|
||||
|
||||
1. runtime story 若通过 STDB token 认证进入
|
||||
2. 则快照直接从 STDB `my_snapshot` / `save_snapshot` / `delete_snapshot` 读取和写回
|
||||
3. 旧 JWT 路径继续维持原来的 Postgres 仓储行为
|
||||
|
||||
这样可以最小化改动:
|
||||
|
||||
1. 不重写 story rule
|
||||
2. 不要求 runtime story 前端立刻切成 STDB provider
|
||||
3. 先让“当前真实主快照”恢复一致
|
||||
|
||||
## 4. 为什么不选其他方案
|
||||
|
||||
### 4.1 不恢复前端双写到 Postgres
|
||||
|
||||
不选原因:
|
||||
|
||||
1. 会把已经迁到 STDB 的快照主链路重新拉回双写状态
|
||||
2. 会继续制造写时漂移和清理成本
|
||||
3. 与 express -> stdb 迁移方向相反
|
||||
|
||||
### 4.2 不把所有 `/api/runtime/story/*` 立刻删掉
|
||||
|
||||
不选原因:
|
||||
|
||||
1. 现有 `storyActionService.ts` 承接了大量 battle / npc / inventory / quest 规则
|
||||
2. 一次性重写成 STDB procedure 风险过高
|
||||
3. 当前更紧急的是先修复“已断开的运行时快照来源”
|
||||
|
||||
## 5. 本轮边界
|
||||
|
||||
本轮只做:
|
||||
|
||||
1. runtime story 的 STDB token 兼容认证
|
||||
2. runtime story 的 STDB snapshot 兼容读写
|
||||
3. 保持现有前端 coordinator / response contract 不变
|
||||
|
||||
本轮不做:
|
||||
|
||||
1. 新的 STDB runtime story table / procedure / view 正式 contract
|
||||
2. `runtimeStoryService` 切为真正的 STDB transport
|
||||
3. 删除 `/api/runtime/story/*`
|
||||
|
||||
## 6. 下一步
|
||||
|
||||
Phase 2A 稳定后,再继续:
|
||||
|
||||
1. 把 `get state` 和 `resolve action` 的正式 contract 收到 STDB
|
||||
2. 在前端接入真正的 STDB transport
|
||||
3. 删除 `/api/runtime/story/*` 这层兼容桥
|
||||
Reference in New Issue
Block a user