Files
Genarrative/docs/technical/FRONTEND_TO_BACKEND_MIGRATION_EXECUTION_PLAN_2026-04-21.md
kdletters cf8da3f50f Merge branch 'codex/dev' into codex/backend-rewrite-spacetimedb
# Conflicts:
#	docs/technical/README.md
#	server-node/src/modules/assets/qwenSpriteRoutes.ts
#	src/components/CustomWorldResultView.test.tsx
#	src/components/CustomWorldResultView.tsx
#	src/components/custom-world-agent/CustomWorldAgentDraftDetailPanel.tsx
#	src/components/game-shell/PreGameSelectionFlow.agent.interaction.test.tsx
#	src/components/rpg-creation-asset-studio/RpgCreationRoleAssetStudioModalImpl.tsx
#	src/components/rpg-creation-editor/RpgCreationEntityEditorShared.tsx
#	src/components/rpg-entry/RpgEntryCharacterSelectView.tsx
#	src/components/rpg-entry/RpgEntryHomeView.tsx
#	src/services/apiClient.ts
#	src/tools/QwenSpriteSheetTool.tsx
2026-04-21 20:16:01 +08:00

7.7 KiB
Raw Blame History

前端逻辑后移实施方案2026-04-21

更新时间:2026-04-21

1. 目标

本方案只回答一件事:

怎样把当前仍残留在前端的正式运行时逻辑、正式会话真相与正式生成编排,继续收回到 Express 后端。

这份文档不是泛泛而谈的方向说明,而是直接面向本轮与后续几轮编码落地的实施基线。


2. 本轮确定的硬边界

根据仓库约束与当前审计结果,本轮继续冻结以下边界:

  1. 前端只负责表现、输入采集、临时 UI 状态与服务端结果渲染。
  2. 后端负责正式鉴权、正式会话、正式运行时快照、正式任务生成、正式运行时物品意图生成、正式自定义世界生成。
  3. codex/backend-rewrite-spacetimedb 目标分支的鉴权仍以服务端签发 JWT、前端 Bearer token 携带为准;本轮合入不采用 codex/dev 的 access cookie 会话方案。
  4. 浏览器内不再把浏览历史作为本地正式真相,不再保留正式 quest / runtime item / custom world 生成编排。
  5. 运行时主链必须继续向“前端提交意图,后端解释快照并返回展示模型”收敛。

3. 现状拆分

当前残留问题已经收敛为三批:

3.1 第一批:正式真相仍在前端

  1. src/services/apiClient.ts
    • 浏览器当前仍保存 access token并在请求层拼接 Authorization: Bearer ...
    • 该链路在 codex/backend-rewrite-spacetimedb 仍是既定正式实现,不再按 cookie access session 改写
  2. src/services/authService.ts
    • 登录、微信绑定、回调消费流程都要与 JWT/Bearer 方案保持一致,避免混入 access cookie 分支语义
  3. src/components/game-shell/PreGameSelectionFlow.tsx
    • 浏览历史仍是本地写入 + 后端回填的双真相
  4. src/services/platformBrowseHistory.ts
    • 维护浏览历史本地存储、迁移标记与同步状态

3.2 第二批:运行时主链仍依赖前端预写快照

  1. src/hooks/story/runtimeStoryCoordinator.ts
    • 在请求 runtime state / runtime action 前,仍先 PUT /runtime/save/snapshot
  2. src/hooks/story/npcEncounterActions.ts
    • 待接委托的“更换任务”“放弃任务”仍由前端正式结算

3.3 第三批:正式生成编排仍残留在浏览器

  1. src/services/questDirector.ts
  2. src/services/runtimeItemAiDirector.ts
  3. src/services/aiService.ts 的 custom world profile 生成入口
  4. src/services/ai.ts 中仍保留的浏览器侧 legacy AI orchestration

4. 分批实施策略

4.1 第一批:先收正式真相

鉴权

目标状态:

  1. 后端继续通过 JWT 承载 access token并只从 Authorization: Bearer ... 读取当前访问身份。
  2. 前端请求层继续负责保存、刷新和携带 access token公开请求与静默探测不得误清正式 token。
  3. access cookie 会话方案不进入 codex/backend-rewrite-spacetimedb,避免和目标分支已有 JWT 方案并存。

本批涉及:

  1. server-node/src/routes/authRoutes.ts
  2. server-node/src/middleware/auth.ts
  3. src/services/apiClient.ts
  4. src/services/authService.ts
  5. src/components/auth/AuthGate.tsx

浏览历史

目标状态:

  1. 浏览历史唯一真相在 runtimeRepository
  2. 前端不再保留本地浏览历史、迁移标记、同步标记。
  3. 浏览历史只通过 storageService 读取和写入。

本批涉及:

  1. src/components/game-shell/PreGameSelectionFlow.tsx
  2. src/components/game-shell/PlatformHomeView.tsx
  3. src/services/storageService.ts
  4. src/services/platformBrowseHistory.ts

4.2 第二批:把 runtime story 快照解释权收回后端

目标状态:

  1. 前端不再通过单独的 PUT /runtime/save/snapshot 预写快照再触发动作。
  2. runtime state / runtime action 允许前端提交当前快照上下文,由后端内部决定是否写入、如何解释、何时持久化。
  3. NPC 待接委托的 replace / abandon / accept 全部走后端 runtime action。

建议实施方式:

  1. 扩展 packages/shared/src/contracts/story.ts
    • RuntimeStoryActionRequest 增加可选 snapshot
    • 新增 RuntimeStoryStateRequest
  2. 新增 POST /api/runtime/story/state/resolve
  3. storyActionService 内部统一处理“请求携带快照上下文时的服务端同步”
  4. npc_chat_quest_offer_replace / npc_chat_quest_offer_abandon 接到后端 runtime action

4.3 第三批:把正式生成编排收成后端唯一出口

目标状态:

  1. questDirector 只保留轻量 SDK。
  2. runtimeItemAiDirector 只保留轻量 SDK。
  3. custom world profile 正式生成走后端 route。
  4. 浏览器侧 src/services/ai.ts 不再承担正式浏览器主链。

建议实施方式:

  1. server-node/src/routes/runtimeRoutes.ts
    • custom-world/profile 正式 route
  2. src/services/aiService.ts
    • custom world 入口改走后端
  3. src/services/questDirector.ts
    • 只请求 /api/runtime/quests/generate
  4. src/services/runtimeItemAiDirector.ts
    • 只请求 /api/runtime/items/runtime-intent

5. 本轮落地范围

本轮优先完成以下内容:

  1. 鉴权维持 codex/backend-rewrite-spacetimedb 既有 JWT/Bearer 方案,不合入 codex/dev 的 access cookie 访问认证。
  2. 浏览历史从前端本地真相后移到后端唯一真相。
  3. custom world profile 正式生成入口补齐后端 route并把前端收成 SDK。
  4. questDirector / runtimeItemAiDirector 收缩为前端 SDK。
  5. runtime story contract 开始补“随请求提交快照上下文”的后端承接能力,并把 NPC 待接委托 replace / abandon 接到后端。

5.1 已完成

  1. codex/backend-rewrite-spacetimedb 本轮保留 JWT access token + refresh cookie 组合方案,不合入 access cookie 写入与读取链路。
  2. 浏览历史已收敛为后端唯一真相,前端不再维护正式本地 browse history 链。
  3. runtime story 已支持随请求提交 snapshot由后端内部解释与持久化。
  4. NPC 待接委托 replace / abandon / accept 已以后端 runtime action 为准。
  5. custom world profile 浏览器正式入口已改走后端 route。
  6. questDirector / runtimeItemAiDirector 已收缩为前端 SDK不再承担正式浏览器编排。
  7. NPC 招募正式结算已迁到后端:
    • 前端只负责招募对白展示与 release 目标选择
    • 后端负责 npcStates / companions / roster / currentEncounter / storyHistory 正式结算
    • 满员换队招募已由后端承接

5.2 剩余未完成

  1. src/services/ai.ts 仍保留 legacy fallback / test 能力,尚未彻底压缩出正式浏览器主链。
  2. 仍需继续审视是否存在其他 NPC / 运行时分支,把正式状态裁决留在前端。

6. 验收标准

第一批验收

  1. 浏览器继续保存 access token并由 fetchWithApiAuth 稳定拼接 Authorization: Bearer ...
  2. 401 刷新链只在已发送 Bearer token 时触发,并且刷新响应必须返回新的 JWT。
  3. 浏览历史仅通过远端接口读写。
  4. src/services/platformBrowseHistory.ts 不再是正式链路依赖。

第二批验收

  1. runtimeStoryCoordinator.ts 不再在动作前独立 PUT /runtime/save/snapshot
  2. NPC 待接委托 replace / abandon / accept 都以后端返回结果为准。

第三批验收

  1. questDirector.tsruntimeItemAiDirector.ts 不再保留正式 fallback orchestration。
  2. custom world profile 的浏览器正式入口不再直接 import legacy ./ai

7. 一句话结论

这轮迁移的重点不是“把几个 helper 挪到 server-node 目录”,而是:

把前端里仍然承担正式真相、正式运行时解释和正式生成编排的那一层职责,继续收回到 Express 后端。