Prune obsolete docs and update navigation

This commit is contained in:
2026-04-25 15:10:24 +08:00
parent 1c5f9303a2
commit 2ebfd1cf55
341 changed files with 1352 additions and 90709 deletions

View File

@@ -0,0 +1,56 @@
# api-server 本地 Rust 栈冷编译等待修复记录
日期:`2026-04-25`
## 1. 背景
本地执行 `npm run dev:rust` 时,日志出现:
```text
[dev:rust] 等待 api-server 就绪
Compiling api-server v0.1.0
[dev:rust] 等待 api-server 就绪超时: http://127.0.0.1:8082/healthz
[dev:rust] 停止 api-server
error: linking with `link.exe` failed: exit code: 143
```
这类失败发生在 `api-server` 仍处于 `cargo run` 的冷编译或链接阶段时,`/healthz` 还没有机会监听端口。
## 2. 根因
根目录 `scripts/dev-rust-stack.sh` 同时使用 `SPACETIME_TIMEOUT_SECONDS=60` 控制:
1. SpacetimeDB standalone 的启动等待。
2. Rust `api-server``/healthz` 就绪等待。
SpacetimeDB 的本地启动通常较快,但 `api-server` 在 Windows MSVC 链接、依赖增量失效、首次构建或新增大依赖后可能超过 60 秒。脚本在超时后执行清理逻辑,主动杀掉仍在运行的 `cargo run` 子进程,因此 `link.exe exit code: 143` 是被本地栈脚本中断后的表现,不应优先判断为 Visual Studio Build Tools 损坏。
## 3. 修复口径
`scripts/dev-rust-stack.sh` 将 SpacetimeDB 与 `api-server` 的等待窗口拆开:
1. `SPACETIME_TIMEOUT_SECONDS` 继续只控制 SpacetimeDB 就绪等待,默认 `60` 秒。
2. 新增 `API_SERVER_TIMEOUT_SECONDS` 控制 `api-server` `/healthz` 就绪等待,默认 `300` 秒。
3. 新增命令行参数 `--api-timeout-seconds <seconds>` 便于本地低性能机器或全量重编译时临时放宽。
4. `api-server` 进程如果在等待窗口内自行退出,仍立即报错,不吞掉真实编译错误。
## 4. 使用方式
常规本地启动继续使用:
```bash
npm run dev:rust
```
如本地需要更长冷编译窗口,可执行:
```bash
npm run dev:rust -- --api-timeout-seconds 600
```
## 5. 验收标准
1. 冷编译期间脚本不会在 60 秒时误杀 `cargo run -p api-server`
2. `/healthz` 真正可访问后,脚本继续启动 Vite。
3. 如果 `api-server` 编译失败或运行时提前退出,脚本仍能快速停止并输出原始错误。
4. SpacetimeDB 启动异常仍使用独立的 `--spacetime-timeout-seconds` 判断。

View File

@@ -112,7 +112,7 @@
1. 工程修改必须同步对应阶段任务清单。
2. 新增或改变接口时,同步更新 [RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md](./RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md)。
3. 仍存在 Node 旧能力差异时,同步更新 [NODE_BACKEND_MODULE_AND_API_INDEX.md](./NODE_BACKEND_MODULE_AND_API_INDEX.md) 的过期说明或新增 Rust 侧补充索引。
3. 仍存在旧能力差异时,同步更新 [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md) 或新增 Rust 侧补充索引。
4. M4 结构变更同步维护 RPG runtime 链路文档。
5. M5 结构变更同步维护 creation flow 链路文档。
6. M6 资产链路变更同步维护 OSS / asset_object / generated path 文档。
@@ -135,4 +135,3 @@
3. 关键 SSE 接口联调。
4. SpacetimeDB publish / rollback 演练。
5. 灰度环境双跑对比。

View File

@@ -0,0 +1,33 @@
# 当前后端实现基线2026-04-25
## 1. 当前唯一落地口径
后续正式后端实现统一以 `server-rs` 为准:
- HTTP 门面Rust `api-server` / Axum。
- 实时状态与业务真相:`crates/spacetime-module` / SpacetimeDB。
- 共享领域与契约:`server-rs` 多 crate 分层维护。
- 前端职责:只做表现、输入采集、临时 UI 状态与服务端结果渲染。
涉及 SpacetimeDB 的表、reducer、绑定生成、发布、本地联调必须按仓库内 SpacetimeDB skills 执行。
## 2. 已替代的旧方向
以下旧方向不再作为新功能设计和编码依据:
- `server-node` / Express / PostgreSQL 正式后端路线。
- Go 服务端试验路线。
- 浏览器侧承担正式运行时逻辑、正式生成编排或正式数据真相的路线。
旧实现只允许作为迁移参考:可以阅读其 contract、提示词、测试用例和边界经验但不得为了兼容旧服务端继续扩展新代码。
## 3. 新文档落点
后续补充后端方案时优先落到这些文档族:
- Rust / SpacetimeDB 架构与切流:`SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md``BACKEND_REWRITE_CROSS_CUTTING_GOVERNANCE_2026-04-22.md``M7_TEST_DEPLOY_CUTOVER_EXECUTION_PLAN_2026-04-22.md`
- SpacetimeDB 模块拆分:`SPACETIME_MODULE_LIB_RS_SPLIT_EXECUTION_2026-04-23.md`
- Rust API 路由索引:`RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md`
- 本地与远端部署:`RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md``JENKINS_RUST_BUILD_DEPLOY_PIPELINES_2026-04-23.md`
如果旧文档与本基线冲突,以本基线和更新日期更近的 Rust / SpacetimeDB 文档为准。

View File

@@ -1,101 +0,0 @@
# 编辑器与资产 API 迁移清单2026-04-08
## 1. 任务定位
对应 [EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md](../planning/EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md) 中的任务 8编辑器 API 归口与工具链隔离。
本轮目标是把编辑器写盘、资产生成、生成任务查询从旧的 Vite 本地 API 插件里收口到 `server-node`,并把前端编辑器组件改成通过统一 SDK 访问。
---
## 2. 新命名空间
编辑器写盘与读取:
- `GET /api/editor/catalog/items`
- `GET /api/editor/json/:resourceId`
- `POST /api/editor/json/:resourceId`
资产生成与任务查询:
- `POST /api/assets/character-visual/generate`
- `POST /api/assets/character-visual/publish`
- `GET /api/assets/character-visual/jobs/:taskId`
- `POST /api/assets/character-animation/generate`
- `POST /api/assets/character-animation/publish`
- `GET /api/assets/character-animation/jobs/:taskId`
- `POST /api/assets/character-animation/import-video`
- `GET /api/assets/character-animation/templates`
---
## 3. 前端接入
统一入口:
- `src/editor/shared/editorApiClient.ts`
已切换的编辑器链路:
- 角色预设覆盖保存
- 敌人预设覆盖保存
- 场景预设覆盖保存
- 场景角色覆盖保存
- NPC 形象覆盖与布局配置保存
- 物品目录读取与物品覆盖保存
- 状态行为覆盖保存
- 角色主形象生成、发布与任务查询
- 角色动作生成、导入、发布、模板读取与任务查询
---
## 4. 权限与环境边界
`server-node` 通过环境变量控制工具接口:
- `EDITOR_API_ENABLED`:控制 `/api/editor/*`
- `ASSETS_API_ENABLED`:控制 `/api/assets/*`
默认策略:
-`production` 环境默认开启。
- `production` 环境默认关闭。
- `ASSETS_API_ENABLED` 未设置时跟随 `EDITOR_API_ENABLED`
这批接口会读写 `src/data/*.json``public/generated-*`,不应作为正式运行时 API 使用。
---
## 5. 旧工具链隔离状态
`2026-04-19` 起,`scripts/dev-server/**` 中的旧 Vite 本地插件实现代码已经从仓库删除,也不再作为当前开发入口使用。
当前保留状态:
- `scripts/dev-server/` 目录只保留迁移说明 README。
- 旧链路的历史背景由 `docs/audits/engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-19.md` 等审计文档承接。
新增编辑器或资产能力时,应优先写入:
- `server-node/src/modules/editor/**`
- `server-node/src/modules/assets/**`
- `src/editor/shared/editorApiClient.ts`
不要再新增旧式散落接口:
- `/api/item-overrides`
- `/api/npc-visual-overrides`
- `/api/character-overrides`
- `/api/character-visual/*`
- `/api/animation/*`
- `/api/qwen-sprite/*`
---
## 6. 当前验收状态
- `/api/editor/*``/api/assets/*` 命名空间已落地。
- 前端编辑器组件已通过统一 SDK 或资源 ID 访问编辑器 API。
- Vite 已代理 `/api/editor``/api/assets` 到 Node 后端。
- 写接口已经有环境门禁。
- 旧 Vite 本地插件代码已删除,不再保留并行实现。

View File

@@ -1,108 +0,0 @@
# Express 后端接口冻结与集成清单2026-04-09
## 1. 目的
这份文档补齐 `docs/planning/EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md` 中任务 0 缺失的仓库内产物,用来明确:
- 当前 contract 的冻结版本
- 热点文件的编辑规则
- 各类改动进入集成窗口前的最小检查清单
它不是新的重构计划,而是给当前并行改造提供一个统一落库的“不要互相踩”的边界表。
---
## 2. Contract 版本表
| 范围 | 当前版本 | 源头文件 | 说明 |
| --- | --- | --- | --- |
| 统一 API envelope | `2026-04-08 / v1` | `packages/shared/src/http.ts` | `ApiResponse`、错误结构、`meta` 字段、envelope 头约定的统一来源。 |
| auth contract | `2026-04-08` | `packages/shared/src/contracts/auth.ts` | 前后端都以 shared auth contract 识别登录、用户信息与 token 响应。 |
| runtime snapshot/settings contract | `2026-04-08` | `packages/shared/src/contracts/runtime.ts` | 存档、设置、自定义世界会话与库表相关请求/响应来源。 |
| runtime story action contract | `2026-04-08` | `packages/shared/src/contracts/story.ts` | `RuntimeStoryActionRequest/Response`、Task5/Task6 function id 与 view model 来源。 |
| Node HTTP route meta | `2026-04-08` | `server-node/src/app.ts` | `/api/auth``/api/runtime/story``/api/editor``/api/assets` 都以这一轮 route version 为当前冻结口径。 |
| editor/assets route 命名空间 | `2026-04-08` | `server-node/src/modules/editor/editorRoutes.ts``server-node/src/modules/assets/**` | 编辑器与资产接口统一走 `/api/editor/*``/api/assets/*`。 |
---
## 3. 热点文件编辑规则
以下文件继续视为高冲突入口,默认不要在多个任务里并行大改:
- `server-node/src/context.ts`
- `server-node/src/routes/runtimeRoutes.ts`
- `server-node/src/app.ts`
- `src/services/apiClient.ts`
- `src/hooks/useStoryGeneration.ts`
- `src/hooks/useGameFlow.ts`
- `src/components/GameShell.tsx`
统一规则:
- 新需求优先新增独立模块,再通过桥接或小入口接入,不要直接把逻辑堆进热点文件。
- 需要改 `server-node/src/routes/runtimeRoutes.ts` 时,先确认 shared contract 是否已落库,再补 route 接入。
- 需要改 `src/hooks/useStoryGeneration.ts` 时,优先确认是否其实应该落到 `server-node/src/modules/**``src/services/runtimeStoryService.ts``src/hooks/story/**`
- 编辑器链路与正式运行时链路不要混在同一轮提交里。
- 如果同一轮同时碰到后端 action 与前端 UI 壳层,先冻结 action/view model再接 UI。
---
## 4. 集成窗口清单
### 4.1 shared contract 变更
- 只在 `packages/shared/**` 改类型、schema、纯序列化约定。
- 同步检查 `server-node/src/**``src/**` 是否都已切到 shared contract。
- 至少跑一次 `npm run server-node:test`
- 如果前端消费层也改了,再补 `npm run typecheck`
### 4.2 runtime action / domain module 变更
- 业务规则优先写在 `server-node/src/modules/**`,不要直接写回前端 hook。
- 如果影响 `RuntimeStoryActionResponse`,同步检查 `packages/shared/src/contracts/story.ts`
- 至少覆盖对应模块测试,或补到 `server-node/src/modules/story/storyActionRoutes.test.ts`
- 合并前至少跑一次 `npm run server-node:test`
### 4.3 persistence / repository / config 变更
- 只把 PostgreSQL 视为正式基线。
- 如果改到 `server-node/src/db.ts``repositories/**`、迁移脚本,优先确认 `pg-mem` 测试仍通过。
- 合并前至少跑一次 `npm run server-node:test`
### 4.4 editor / assets 变更
- 后端入口只放在 `/api/editor/*``/api/assets/*`
- 前端统一从 `src/editor/shared/editorApiClient.ts` 或对应 persistence 层进入。
- 不要新增旧 Vite 本地插件式散落接口。
### 4.5 前端壳层接入变更
- 优先消费 `runtime story state / action response / shared contract`,不要把正式规则写回前端。
- 如果恢复流程有改动,优先以后端 runtime state 为准。
- 若影响主流程,至少补对应 hook / view model 测试并跑 `npm run typecheck`
---
## 5. 当前剩余非冻结区
以下几块仍处于“可继续收口但尚未完全冻结”的状态,改动时要额外小心:
- `server-node/src/bridges/legacyBuildRuntimeBridge.ts`
- `server-node/src/bridges/legacyInventoryRuntimeBridge.ts`
- `server-node/src/modules/ai/storyOrchestrator.ts`
- `server-node/src/modules/ai/chatOrchestrator.ts`
- `server-node/src/modules/ai/customWorldOrchestrator.ts`
它们目前仍残留一部分对 `src/**` 历史实现的复用,不建议在没有额外测试兜底时顺手混改。
---
## 6. 本轮落库结论
从 2026-04-09 起,仓库内已经具备任务 0 要求的这几类最小产物:
- contract 版本表
- 热点文件编辑规则
- 集成窗口检查清单
后续如果 shared contract、runtime action 或热点入口发生明显演进,应优先更新这份文档,而不是让口径只停留在聊天记录里。

View File

@@ -1,109 +0,0 @@
# Express 后端任务 4 AI 编排收口状态2026-04-08
## 1. 结论
`EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md` 的任务 4 定义,本轮已经把正式运行时的 `story / character chat / npc chat / custom world generation / quest intent / runtime item intent` 的主要 AI 编排入口收回到 Express 后端。
当前可以视为:
- 正式运行时主链已不再依赖浏览器端大体量 AI 实现作为兜底。
- prompt 组装、上游模型请求、SSE 转发已以后端为主。
- 前端保留的本地 AI 大模块只通过懒加载方式服务于非正式运行时遗留入口,不再作为正式运行时默认路径。
---
## 2. 已完成项
### 2.1 后端统一 orchestration 入口
- `server-node/src/modules/ai/storyOrchestrator.ts`
- `server-node/src/modules/ai/chatOrchestrator.ts`
- `server-node/src/modules/ai/customWorldOrchestrator.ts`
这些模块承接:
- story prompt 组装
- character chat prompt 组装
- npc chat / recruit prompt 组装
- custom world generation 后端入口封装
### 2.2 服务层收口
已收口到后端服务或模块的文件:
- `server-node/src/services/llmClient.ts`
- `server-node/src/services/storyService.ts`
- `server-node/src/services/chatService.ts`
- `server-node/src/services/customWorldGenerationService.ts`
- `server-node/src/services/questService.ts`
- `server-node/src/services/runtimeItemService.ts`
### 2.3 前端正式运行时 fallback 清理
`src/services/aiService.ts` 已完成以下收缩:
- story 正式路径不再 fallback 到浏览器本地 AI 编排
- character suggestions / summary / reply stream 不再 fallback 到浏览器本地 AI 编排
- npc dialogue / recruit stream 不再 fallback 到浏览器本地 AI 编排
- 移除了正式运行时对 `VITE_ENABLE_BROWSER_RUNTIME_AI_FALLBACK` 的依赖
- 移除了正式运行时对本地轻量离线文案 fallback 的默认依赖
-`./ai` 的引用改为懒加载,避免正式运行时默认把大体量 AI 模块打进主路径
- 正式运行时主流程 hook 已统一改走 `aiService`,不再直接从 `src/services/ai.ts` 获取 story/chat 主链能力
### 2.4 旧 bridge 清理
已移除:
- `server-node/src/bridges/legacyAiRuntimeBridge.ts`
---
## 3. 当前边界说明
以下项仍然存在于前端目录,但不再属于正式运行时默认 AI 执行路径:
- `src/services/ai.ts`
- `src/services/aiFallbacks.ts`
- `src/components/CustomWorldEntityEditorModal.tsx` 中的工具链直连调用
它们当前主要作为:
- 兼容性遗留实现
- 懒加载的非主路径工具能力
- 非本轮正式运行时链路的复用来源
这不再构成任务 4 的主阻塞,但后续仍应继续配合任务 1 / 任务 7 做彻底分层。
---
## 4. 非任务 4 主阻塞但需要记录的事项
### 4.1 仍属编辑器/工具链范畴的遗留调用
- `generateCustomWorldSceneImage` 仍通过懒加载复用旧实现。
原因:
- 该能力属于自定义世界工具链,不是正式运行时剧情 / 对话主链。
- 当前不会再影响“浏览器正式运行时是否依赖本地大 AI 编排”这一任务 4 验收项。
### 4.2 分层彻底闭合仍需后续任务配合
尽管任务 4 已完成主链收口,但以下更深层收敛仍建议交由后续任务继续推进:
- 继续减少 `server-node``src/**` 纯提示词/纯规则模块的历史复用
- 继续把共享 contract / schema 下沉到 `packages/shared`
- 继续把工具链与正式运行时拆分
这些属于任务 1、任务 7、任务 8 的后续工作,不再阻塞任务 4 验收。
---
## 5. 本轮建议验收口径
任务 4 可按以下口径验收:
- 浏览器正式运行时不再默认兜底到本地大体量 AI 编排
- story/chat/custom world generation 主链 prompt 组装与请求执行权在后端
- SSE 主链以后端转发为准
- upstream timeout / abort / error 统一走后端处理链

View File

@@ -1,425 +0,0 @@
# Express 后端并行任务完成度审计2026-04-09
## 1. 审计范围
本次审计以 `docs/planning/EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md` 为基准,只检查仓库内可直接验证的代码、测试、脚本和文档产物。
不能仅靠仓库静态内容确认的团队协作物,例如看板、口头冻结流程、每日集成节奏,只按“仓库内可见状态”记录,不把它们误判成完全验收。
---
## 2. 任务完成度总览
| 任务 | 状态 | 结论 |
| --- | --- | --- |
| 任务 0集成岗与接口冻结 | 基本完成 | 已补齐接口冻结与集成清单文档contract 版本表、热点文件编辑规则、集成窗口检查项都已落库;但团队执行节奏本身仍无法仅凭仓库静态确认。 |
| 任务 1共享 Contract 与目录抽离 | 部分完成 | `packages/shared` 已建立并承接 auth/runtime/story contract且 NPC Task6 bridge 与 chat prompt builder 已进一步下沉到后端本地模块;但 AI 编排主链仍残留少量 `src/**` 反向依赖,分层尚未完全闭合。 |
| 任务 2PostgreSQL 持久化基线收口 | 已完成 | `server-node/src/config.ts``db.ts``repositories/**`、迁移脚本、`pg-mem` 测试与部署文档均已到位。 |
| 任务 3HTTP 基础设施与统一响应壳层 | 已完成 | 统一错误格式、`requestId`、route meta、响应壳层、观测测试已落地。 |
| 任务 4服务端 AI 编排收口 | 基本完成 | orchestration 模块、SSE 转发和主链调用已回到后端,但仍有少量 prompt/规则模块通过 `src/**` 复用,属于后续继续收敛项。 |
| 任务 5Story / Combat / NPC | 已完成 | 后端 story action route、session 组装、combat/npc 领域服务和对应回归测试已落地。 |
| 任务 6Inventory / Quest / Build / Runtime Item | 已完成 | 对应模块、服务与回归测试已经覆盖主要正式运行时结算。 |
| 任务 7前端 SDK、鉴权、持久化瘦身 | 部分完成 | `apiClient``authService``storageService` 已统一,但前端仍保留一部分存档归一化和主流程协调职责。 |
| 任务 8编辑器 API 归口与工具链隔离 | 基本完成 | editor/assets 模块、前端 editor client、迁移文档均已出现职责边界基本清晰。 |
| 任务 9测试、观测与部署基线 | 已完成 | baseline test、smoke、proxy smoke、部署与回滚清单、日志链路均已具备。 |
| 任务 10前端主流程壳层与大 Hook 瘦身 | 部分完成 | `GameShellRuntime` / `useGameShellRuntimeViewModel` 以及新的 `storyRequestCoordinator` 已拆出,但 `useStoryGeneration.ts` 仍然过重,主流程尚未彻底退回“表现层协调器”。 |
---
## 3. 本轮补齐项
本轮先补齐了任务 0 缺失的仓库内协作产物:
- 新增 `docs/technical/EXPRESS_BACKEND_INTEGRATION_FREEZE_2026-04-09.md`
- 落库当前 contract 版本表
- 明确热点文件编辑规则
- 补齐 shared/runtime/editor/frontend 壳层各自的集成窗口清单
这让任务 0 不再只停留在规划文档里,而是有了一份可随版本一起更新的冻结口径。
随后补上了一段此前仍偏向前端快照解释的恢复链路:
- `src/hooks/story/runtimeStoryCoordinator.ts`
- 新增 `resumeServerRuntimeStory`
- 继续游戏时,若当前是正式运行时故事快照,会先请求 `/api/runtime/story/state/:sessionId`
- 让当前 `storyText` 与可用 `options` 优先以后端 runtime state 为准
- `src/hooks/useGamePersistence.ts`
- `continueSavedGame()` 现在会优先走后端 runtime story 恢复
- 如果服务端恢复失败,再回退到本地快照归一化结果
- 额外补了 `bottomTab` 归一化,避免恢复时吃到宽泛字符串
- `src/hooks/story/runtimeStoryCoordinator.test.ts`
- 新增“继续游戏时优先从后端恢复 runtime story”的测试
- 新增“非正式运行时快照不额外请求后端”的测试
这次补丁对应的是任务 7 与任务 10 之间的一段未完全闭合边界:前端在恢复流程里不应该只把远端存档当作“原始 JSON 缓存”,而应优先相信后端当前 runtime state。
此外,本轮还继续补了任务 1 的一段后端分层收口:
- 新增 `server-node/src/modules/runtime/runtimeStatePrimitives.ts`
- 后端本地承接 `addInventoryItems`
- 后端本地承接 `removeInventoryItem`
- 后端本地承接 `incrementGameRuntimeStats`
- 后端本地承接 `buildRelationState`
- 新增 `server-node/src/modules/runtime/runtimeStatePrimitives.test.ts`
- 校验背包合并、移除、运行时统计累加、关系阶段映射
- 调整桥接层:
- `server-node/src/bridges/legacyInventoryRuntimeBridge.ts`
- `server-node/src/bridges/legacyNpcTask6Bridge.ts`
- `server-node/src/modules/quest/questTask6Bridge.ts`
这意味着任务 5/6 主链里最基础的一批状态原语,已经不再依赖前端 `src/data/runtimeStats.ts``src/data/attributeResolver.ts``src/data/npcInteractions.ts` 的对应实现。
本轮又继续把 NPC Task6 bridge 里最后一批直接挂到前端 `npcInteractions.ts` 的函数下沉到了后端本地:
- 新增 `server-node/src/modules/npc/npcTask6Primitives.ts`
- 后端本地承接 `applyStoryChoiceToStanceProfile`
- 后端本地承接 `buildInitialNpcState`
- 后端本地承接 `syncNpcTradeInventory`
- 后端本地承接 `getGiftCandidates`
- 后端本地承接 `buildNpcGiftCommitActionText`
- 后端本地承接 `buildNpcGiftResultText`
- 后端本地承接 `buildNpcTradeTransactionActionText`
- 后端本地承接 `buildNpcTradeTransactionResultText`
- 新增 `server-node/src/modules/npc/npcTask6Primitives.test.ts`
- 覆盖 NPC 初始库存生成
- 覆盖交易库存刷新时保留非交易物品
- 覆盖赠礼偏好排序
- 调整桥接层:
- `server-node/src/bridges/legacyNpcTask6Bridge.ts`
这意味着 Task6 的 NPC 交易/赠礼/初始库存这条支链,已经不再直接依赖前端 `src/data/npcInteractions.ts`
同时还把叙事语言检测工具下沉到了共享层:
- 新增 `packages/shared/src/llm/narrativeLanguage.ts`
- `src/services/narrativeLanguage.ts` 改为复用共享实现
- `server-node/src/modules/ai/storyOrchestrator.ts` 改为直接依赖共享层
这部分虽然不是大块业务迁移,但它属于任务 1 最稳定的一类收口:把纯函数共识从前端目录中抽离出来。
再补充一批已经完成的后端纯原语迁移:
- 新增 `server-node/src/modules/runtime/runtimeEconomyPrimitives.ts`
- 后端本地承接 `formatCurrency`
- 后端本地承接 `getInventoryItemValue`
- 后端本地承接 `getNpcPurchasePrice`
- 后端本地承接 `getNpcBuybackPrice`
- 新增 `server-node/src/modules/runtime/runtimeTreasureTexts.ts`
- 后端本地承接 `buildTreasureResultText`
- 新增 `server-node/src/modules/runtime/runtimeEconomyPrimitives.test.ts`
- 覆盖交易定价、货币文本、宝藏奖励文本
对应桥接层:
- `server-node/src/bridges/legacyNpcTask6Bridge.ts`
- 不再依赖前端 `src/data/economy.ts`
- `server-node/src/bridges/legacyTreasureRuntimeBridge.ts`
- 不再从前端导出 `buildTreasureResultText`
这说明任务 5/6 主链中一部分交易、礼物、宝藏结算反馈文本,也已经从前端数据层抽离。
本轮又进一步补了 NPC 状态与叙事记忆的后端本地原语:
- 新增 `server-node/src/modules/runtime/runtimeNpcStatePrimitives.ts`
- 后端本地承接 `normalizeNpcPersistentState`
- 后端本地承接 `markNpcFirstMeaningfulContactResolved`
- 新增 `server-node/src/modules/runtime/runtimeNarrativeMemory.ts`
- 后端本地承接 `appendStoryEngineCarrierMemory`
- 新增 `server-node/src/modules/runtime/runtimeNpcStatePrimitives.test.ts`
- 覆盖 NPC 状态归一化、首次有效接触标记、叙事载体记忆写入
对应桥接层:
- `server-node/src/bridges/legacyNpcTask6Bridge.ts`
- 不再依赖前端 `src/services/storyEngine/echoMemory.ts`
- 不再依赖前端 `src/data/npcInteractions.ts` 中的 NPC 状态归一化与首次接触标记逻辑
这进一步缩小了后端在任务 5/6 主链上对前端 story-engine 服务目录的借用范围。
本轮还整块收口了 Quest 与 Runtime Item 两条桥接链:
- 新增 `server-node/src/modules/quest/runtimeQuestModule.ts`
- 后端本地承接 `buildQuestForEncounter`
- 后端本地承接 `evaluateQuestOpportunity`
- 后端本地承接 `buildFallbackQuestIntent`
- 后端本地承接 `compileQuestIntentToQuest`
- 后端本地承接 `buildQuestGenerationContextFromState`
- 后端本地承接 `buildQuestIntentPrompt`
- 后端本地承接 Quest 进度归一化与 signal 推进
- 更新桥接层:
- `server-node/src/bridges/legacyQuestProgressBridge.ts`
- `server-node/src/bridges/legacyQuestRuntimeBridge.ts`
这意味着 Quest 的“确定性委托构建 + AI 意图上下文 + 任务推进”已经不再依赖前端 `src/data/questFlow.ts``src/services/questDirector.ts``src/services/questPrompt.ts`
同时Runtime Item 也已经收回到后端本地:
- 新增 `server-node/src/modules/runtime-item/runtimeItemModule.ts`
- 后端本地承接 `buildRuntimeItemAiIntent`
- 后端本地承接 `buildRuntimeItemIntentPrompt`
- 后端本地承接 `buildLooseRuntimeItemGenerationContext`
- 后端本地承接 `buildQuestRuntimeItemGenerationContext`
- 后端本地承接 `buildDirectedRuntimeReward`
- 后端本地承接 `buildRuntimeInventoryStock`
- 后端本地承接 `flattenDirectedRuntimeRewardItems`
- 新增 `server-node/src/modules/runtime-item/runtimeTreasureModule.ts`
- 后端本地承接 `resolveTreasureReward`
- 更新桥接层:
- `server-node/src/bridges/legacyRuntimeItemBridge.ts`
- `server-node/src/bridges/legacyRuntimeItemResolutionBridge.ts`
- `server-node/src/bridges/legacyTreasureRuntimeBridge.ts`
这说明 Runtime Item / Treasure 相关的 AI 意图、奖励生成和库存生成,也已经从前端目录中抽离。
本轮还继续整块收口了 Build / Inventory / Forge / Equipment 规则桥接:
- 新增 `server-node/src/modules/runtime/runtimeEquipmentModule.ts`
- 后端本地承接 `getEquipmentSlotFromItem`
- 后端本地承接 `getEquipmentSlotLabel`
- 后端本地承接 `getEquipmentBonuses`
- 后端本地承接 `applyEquipmentLoadoutToState`
- 新增 `server-node/src/modules/runtime/runtimeInventoryEffectsModule.ts`
- 后端本地承接 `isInventoryItemUsable`
- 后端本地承接 `resolveInventoryItemUseEffect`
- 后端本地承接 `buildInventoryUseResultText`
- 新增 `server-node/src/modules/runtime/runtimeForgeModule.ts`
- 后端本地承接 `getForgeRecipeViews`
- 后端本地承接 `executeForgeRecipe`
- 后端本地承接 `executeDismantleItem`
- 后端本地承接 `executeReforgeItem`
- 后端本地承接 `getReforgeCostView`
- 后端本地承接 `buildForgeSuccessText`
- 新增 `server-node/src/modules/runtime/runtimeBuildModule.ts`
- 后端本地承接 `appendBuildBuffs`
- 后端本地承接 `getPlayerBuildDamageBreakdown`
- 后端本地承接 `resolvePlayerOutgoingDamageResult`
对应桥接层:
- `server-node/src/bridges/legacyBuildRuntimeBridge.ts`
- `server-node/src/bridges/legacyInventoryRuntimeBridge.ts`
这意味着 Build / Inventory / Forge / Equipment 相关的后端主链结算,已经不再依赖前端 `src/data/buildDamage.ts``src/data/equipmentEffects.ts``src/data/forgeSystem.ts``src/data/inventoryEffects.ts`
本轮又补了一段任务 1 的 AI 编排收口:
- 新增 `server-node/src/modules/ai/chatPromptBuilders.ts`
- 后端本地承接 character chat reply / suggestions / summary prompt 组装
- 后端本地承接 npc chat / recruit prompt 组装
- 调整:
- `server-node/src/modules/ai/chatOrchestrator.ts`
- `server-node/src/modules/ai/orchestrator.test.ts`
这意味着 chat orchestration 已不再依赖前端 `src/services/characterChatPrompt.ts``src/services/prompt.ts`
本轮继续把 story orchestration 主链也收回到了后端本地:
- 新增 `server-node/src/modules/ai/storyPromptBuilders.ts`
- 后端本地承接 `SYSTEM_PROMPT`
- 后端本地承接 `buildUserPrompt`
- 重写 `server-node/src/modules/ai/storyOrchestrator.ts`
- 正式生产链不再依赖前端 `src/services/prompt.ts`
- 正式生产链不再依赖前端 `src/data/stateFunctions.ts`
- 正式生产链不再依赖前端 `src/data/scenePresets.ts`
- 正式生产链不再依赖前端 `src/data/hostileNpcs.ts`
- 调整:
- `server-node/src/modules/ai/orchestrator.test.ts`
到这里,`server-node` 正式生产代码路径里Story / Chat / Quest / Runtime Item / Treasure / Build / Inventory / Forge / NPC Task6 主链都已经从前端 `src/**` 目录脱钩。
本轮也继续推进了任务 10 的主流程瘦身:
- 新增 `src/hooks/story/storyRequestCoordinator.ts`
- 抽离运行时 option source 解析
- 抽离服务端 option catalog 回退策略
- 抽离 initial / next story 请求参数协调
- 新增 `src/hooks/story/storyRequestCoordinator.test.ts`
- 覆盖服务端 option catalog 切换
- 覆盖显式 option catalog 短路
- 覆盖服务端目录加载失败时回退本地可用项
- 调整:
- `src/hooks/useStoryGeneration.ts`
这说明 `useStoryGeneration.ts` 虽然仍重,但“故事请求协调”已经不再和主流程 UI 状态、NPC/战斗/宝藏后续处理混在同一个大段里。
本轮又补了一段任务 10 的纯展示逻辑拆分:
- 新增 `src/hooks/story/storyPresentation.ts`
- 抽离 story options 去重与补齐
- 抽离对白 turn 解析
- 抽离 dialogue story moment 组装
- 抽离 typewriter delay
- 新增 `src/hooks/story/storyPresentation.test.ts`
- 覆盖对白解析与 dialogue story moment
- 覆盖选项池去重与补齐
- 调整:
- `src/hooks/useStoryGeneration.ts`
这意味着 `useStoryGeneration.ts` 又减少了一批与 React 状态本身无关的纯函数逻辑,任务 10 的主流程壳层拆分继续向前推进。
本轮还补上了任务 1 的最后一条后端反向依赖:
- 删除 `server-node/src/bridges/legacyCustomWorldAiBridge.ts`
- 重写 `server-node/src/modules/ai/customWorldOrchestrator.ts`
- 后端本地承接 custom world generation 的 deterministic 生成流程
- 后端本地承接 generation progress 汇报
这意味着 `server-node/src/**` 的正式生产代码路径已经不再反向依赖前端 `src/**` 目录。
---
## 4. 仍需继续收口的重点
### 4.1 任务 1 的剩余问题
当前从仓库内直接扫描看,`server-node/src/**` 的正式生产代码路径已经不再存在对前端 `src/**` 的反向依赖。
其中 Story / Chat / Quest / Runtime Item / Treasure / Build / Inventory / Forge / Equipment / NPC Task6 / Custom World generation 相关正式生产链都已经从这个列表中退出。
同时,`server-node/src/modules/ai/orchestrator.test.ts` 已不再直接依赖前端 `src/services/prompt.ts``src/data/stateFunctions.ts`
这说明任务 1 在“后端正式生产运行时不反向依赖前端目录”这一层面已经完成。
#### 4.1.1 当前残留依赖的真实形态
从当前状态看,任务 1 后续不再是“补洞”,而是“优化”:
- 继续提高 custom world generation 的质量与保真度
- 继续把真正通用的 prompt / JSON repair / batch helper 整理进 `packages/shared``server-node/src/modules/ai/**`
- 维持后端不再回流引用前端目录的约束
#### 4.1.2 更适合的继续收口顺序
结合当前状态,任务 1 后续更适合做的是能力优化:
1. 继续增强 custom world generation 的语义保真度与校验强度。
2. 继续把 prompt builder、JSON repair、批处理工具整理到 `packages/shared``server-node/src/modules/ai/**`
3. 持续维持“后端正式生产代码不反向依赖前端目录”的约束,避免后续重新开洞。
### 4.2 任务 7 的剩余问题
前端虽然已经大量改成 SDK 消费层,但 `src/persistence/runtimeSnapshot.ts` 里仍保留较重的存档归一化与迁移修复逻辑。
这部分后续仍建议继续向后端迁移,避免前后端双边解释快照。
#### 4.2.1 `runtimeSnapshot.ts` 当前仍承担的职责
从文件本身看,`src/persistence/runtimeSnapshot.ts` 仍不是一个单纯的“读取后端结果并转成 UI 状态”的轻薄消费层。
它当前仍直接负责:
- 存档迁移 manifest 应用
- roster 归一化
- player currency 默认值补齐
- equipment loadout 回填与属性重算
- NPC persistent state 归一化
- quest log 归一化
- runtime stats 归一化
- scene encounter preview 修复
- story engine memory 缺省补齐
这说明任务 7 的剩余问题,不只是“前端还有一点 normalize 代码”,而是:
- 前端仍在解释正式存档的结构语义
- 前端仍在决定若干正式运行时字段的缺省和修复策略
- 后端与前端之间仍存在“双边都能定义快照有效形态”的空间
#### 4.2.2 下一步更合适的迁移方向
结合本轮已经补上的“继续游戏优先以后端 runtime story state 为准”这段恢复链路,任务 7 后续更适合继续向这个方向推进:
1.`runtimeSnapshot.ts` 中的迁移、归一化、缺省补齐继续下沉到后端持久化层或专门的 runtime snapshot service。
2. 让前端拿到的远端快照尽量已经是“可直接消费的正式形态”,而不是“仍需前端补算的半成品”。
3. 把前端保留的本地 hydrate 逻辑收缩到纯 UI 恢复字段,例如当前页签、面板开合、局部显示态。
只有这样,任务 7 才算真正回到“前端只做消费层,后端才是正式状态解释者”的目标。
### 4.3 任务 10 的剩余问题
当前最大的未完成项仍然是:
- `src/hooks/useStoryGeneration.ts`
它仍承担了大量:
- 正式运行时故事编排
- 本地 fallback 组织
- NPC / 宝藏 / 战斗后续协调
- 主流程状态推进
现阶段虽然已经有:
- `src/hooks/useGameShellRuntime.ts`
- `src/components/game-shell/useGameShellRuntimeViewModel.ts`
- `src/hooks/story/runtimeStoryCoordinator.ts`
- `src/hooks/story/storyRequestCoordinator.ts`
但主流程还没有彻底完成 action/view model 化,任务 10 仍应视为“进行中”。
#### 4.3.1 `useStoryGeneration.ts` 当前仍然为什么过重
从仓库现状看,`src/hooks/useStoryGeneration.ts` 目前仍有约 1700 行,且其过重问题已经不是单纯“文件太长”,而是它还保留着大量正式业务协调职责。
当前这个 hook 里仍集中着:
- `buildStoryContextFromState` 这一整块故事上下文拼装
- AI 请求前的 option catalog / fallback 组织
- NPC / 宝藏 / 战斗 / inventory / goal / session 多条子链的集中协调
- 本地 fallback story 生成
- 一部分运行时规则与 narrative context 的最终拼装入口
这意味着即使已经拆出了:
- `runtimeStoryCoordinator`
- `storyRequestCoordinator`
- `choiceActions`
- `npcEncounterActions`
- `sessionActions`
`useStoryGeneration.ts` 仍然不是“单纯的 UI 壳层 hook”而更像前端侧的运行时总协调器。
#### 4.3.2 任务 10 后续更值得优先拆的部分
按当前文件结构看,后续最值得优先继续抽离的不是零散按钮逻辑,而是下面三类真正还握在主 hook 里的核心块:
1. `buildStoryContextFromState` 这一整块 story-engine 叙事上下文装配。
2. `buildFallbackStoryForState` / `getAvailableOptionsForState` 这类“正式规则兜底与选项来源判断”。
3. NPC / Treasure / Character Chat / Session 这些子流之间的最终总装协调。
如果只是继续把零散函数拆到 `src/hooks/story/**`,但上述三块还留在主 hook 里,那么任务 10 仍然不会真正完成。
### 4.4 建议的下一轮补齐顺序
结合任务 1、任务 7、任务 10 当前的剩余形态,后续更合适的补齐顺序建议是:
1. 先继续收任务 7 的 runtime snapshot 解释权,把正式快照的迁移、修复、归一化口径继续回收到后端。
2. 再继续收任务 10`useStoryGeneration.ts` 压回主流程协调壳层,而不是继续让它承担正式运行时总装职责。
这样排的原因是:
- 任务 1 已经完成后,新的主阻塞就变成了任务 7 和任务 10。
- 如果任务 7 不继续收,前端仍会在恢复链路里保留正式状态解释权,任务 10 也很难真正变薄。
- 等到 runtime state 与 snapshot 口径都更稳定后,再继续瘦 `useStoryGeneration.ts`,返工会更少。
---
## 5. 本轮验证
已通过:
- `npm run server-node:test`
- `npx vitest run src/hooks/story/storyRequestCoordinator.test.ts src/hooks/story/runtimeStoryCoordinator.test.ts`
- `npm run typecheck`
- `npm run check:encoding`
---
## 6. 结论
从仓库可验证结果看,任务 2、3、5、6、9 已经达到“可认为完成”的状态;任务 0、4、8 基本完成;任务 1、7、10 仍有明显后续收口空间。
当前最主要的未完成中心已经不再是后端基建,而是:
**把前端主流程和存档恢复彻底收成“以后端 runtime state 和 view model 为唯一真相源”。**

View File

@@ -1,190 +0,0 @@
# 前端逻辑后移实施方案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 方案并存。
4. `AuthGate` 通过 refresh cookie / `/api/auth/me` 恢复出用户后,必须先确保本地 access token 可用,再把 `readyUser` 暴露给运行时、设置、作品列表等受保护业务 hook业务 hook 不能只凭 `user.id` 在 token 尚未补齐时启动远端请求。
本批涉及:
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` 不再是正式链路依赖。
5. 手机验证码登录、微信回调或 refresh cookie 会话恢复完成后,首屏并发读取设置、存档、个人看板、浏览历史、作品列表前,必须已经完成 access token 写入,避免出现“用户已 ready 但请求缺少 Authorization Bearer Token”的竞态。
### 第二批验收
1. `runtimeStoryCoordinator.ts` 不再在动作前独立 `PUT /runtime/save/snapshot`
2. `NPC` 待接委托 replace / abandon / accept 都以后端返回结果为准。
### 第三批验收
1. `questDirector.ts``runtimeItemAiDirector.ts` 不再保留正式 fallback orchestration。
2. custom world profile 的浏览器正式入口不再直接 import legacy `./ai`
---
## 7. 一句话结论
这轮迁移的重点不是“把几个 helper 挪到 server-node 目录”,而是:
**把前端里仍然承担正式真相、正式运行时解释和正式生成编排的那一层职责,继续收回到 Express 后端。**

View File

@@ -11,7 +11,7 @@
- [M3_RUNTIME_SETTINGS_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md](./M3_RUNTIME_SETTINGS_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md)
- [M3_BROWSE_HISTORY_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md](./M3_BROWSE_HISTORY_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md)
- [NODE_BACKEND_MODULE_AND_API_INDEX.md](./NODE_BACKEND_MODULE_AND_API_INDEX.md)
- [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md)
- `server-node/src/routes/rpg-profile/rpgProfileRoutes.ts`
- `server-node/src/repositories/runtimeRepository.ts`

View File

@@ -10,7 +10,7 @@
关联现状:
- [SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md](./SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md)
- [NODE_BACKEND_MODULE_AND_API_INDEX.md](./NODE_BACKEND_MODULE_AND_API_INDEX.md)
- [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md)
- `server-node/src/routes/rpg-profile/rpgProfileRoutes.ts`
- `server-node/src/repositories/runtimeRepository.ts`

View File

@@ -24,11 +24,8 @@
本文以以下现有文档和代码为准:
1. [SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md](./SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md)
2. [NODE_BACKEND_MODULE_AND_API_INDEX.md](./NODE_BACKEND_MODULE_AND_API_INDEX.md)
3. [EXPRESS_BACKEND_TASK4_AI_ORCHESTRATION_STATUS_2026-04-08.md](./EXPRESS_BACKEND_TASK4_AI_ORCHESTRATION_STATUS_2026-04-08.md)
4. `server-node/src/modules/ai/storyOrchestrator.ts`
5. `server-node/src/modules/ai/chatOrchestrator.ts`
6. `server-node/src/modules/ai/customWorldOrchestrator.ts`
2. [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md)
3. 历史 Node AI 编排代码仅作为迁移背景,不再作为当前实现依据。
## 3. 现状问题

View File

@@ -11,7 +11,7 @@ M7 的目标不是新增玩法功能,而是在 `M0 ~ M6` 已迁移的 Rust 后
1. 固定本地、灰度、切流前的检查命令。
2. 固定 `Axum + SpacetimeDB + OSS` 的部署与回滚口径。
3. 固定观测字段、慢请求、上游失败日志与资产任务日志。
4. 固定旧 `server-node` 与新 `server-rs` 的双跑和 API 对比方式。
4. 固定旧 `server-node` 删除后的 Rust 主线回归与部署验证方式。
5. 等价拆分 `server-rs/crates/spacetime-module/src/lib.rs`,避免 SpacetimeDB 主工程继续退化为单大文件。
## 2. 执行约束
@@ -19,8 +19,8 @@ M7 的目标不是新增玩法功能,而是在 `M0 ~ M6` 已迁移的 Rust 后
1. 不改变现有 HTTP contract、SSE contract、SpacetimeDB 表名、reducer 名、procedure 名和对象键前缀。
2. 不把 LLM、OSS、短信、微信等外部副作用移入 SpacetimeDB reducer。
3. `spacetime-module` 拆分只做物理结构收口,不做 schema 重命名、字段删除、字段重排或 reducer/procedure 改名。
4. 迁移期保留 `server-node` 作为回退锚点M7 不删除旧后端
5. 前端切换默认指向 Node只有显式设置 `GENARRATIVE_BACKEND_STACK=rust``GENARRATIVE_RUNTIME_SERVER_TARGET` 时才切到 Rust。
4. `server-node/` 已进入物理删除流程M7 不再把旧 Node 后端作为运行时回退锚点
5. 前端默认指向 Rust `api-server`;如需临时覆盖目标,只允许使用 `RUST_SERVER_TARGET``GENARRATIVE_RUNTIME_SERVER_TARGET` 指向 Rust 兼容服务
## 3. 测试体系
@@ -36,7 +36,6 @@ M7 固定四层测试入口:
```powershell
.\server-rs\scripts\m7-preflight.ps1
.\server-rs\scripts\smoke.ps1
node scripts\run-tsx.cjs scripts\m7-api-compare.ts
```
## 4. 部署准备
@@ -72,32 +71,32 @@ OSS / CDN / 域名方案:
6. `DASHSCOPE_BASE_URL``DASHSCOPE_API_KEY`
7. `SMS_AUTH_ENABLED` 与短信供应商变量
8. `WECHAT_AUTH_ENABLED` 与微信 OAuth 变量
9. `GENARRATIVE_BACKEND_STACK``NODE_SERVER_TARGET``RUST_SERVER_TARGET``GENARRATIVE_RUNTIME_SERVER_TARGET`
9. `RUST_SERVER_TARGET``GENARRATIVE_RUNTIME_SERVER_TARGET`
## 5. 灰度与切流
灰度环境固定为三段:
1. `shadow`Node 继续承接用户流量Rust 只由脚本和内部账号请求
2. `dual-run`同一组 smoke/API compare 同时打 Node 与 Rust差异必须登记
3. `rust-primary`:反向代理或 Vite dev proxy 指向 RustNode 进程保留但不作为主入口
1. `preflight`:只跑 Rust 预检、smoke 与人工主链验证,不接正式用户流量
2. `limited-rust`小范围账号或灰度域名访问 Rust `api-server`,差异必须登记到 M7 验收记录
3. `rust-primary`:反向代理或 Vite dev proxy 指向 Rust `api-server`,旧 Node 后端不作为运行时入口保留
前端切换方式:
1. 默认 `GENARRATIVE_BACKEND_STACK=node`
2. 本地或灰度切 Rust 设置 `GENARRATIVE_BACKEND_STACK=rust`,并配置 `RUST_SERVER_TARGET`
3. 紧急回退设置 `GENARRATIVE_BACKEND_STACK=node` 或直接覆盖 `GENARRATIVE_RUNTIME_SERVER_TARGET` 指回 Node
1. 默认使用 `RUST_SERVER_TARGET``GENARRATIVE_API_TARGET` 指向 Rust `api-server`
2. 本地或灰度可覆盖 `GENARRATIVE_RUNTIME_SERVER_TARGET`,但目标仍必须是 Rust 兼容服务
3. 紧急回退优先回滚到上一个 Rust 发布包或反向代理配置,不恢复 `server-node/` 工程目录
## 6. API 对比
## 6. API 回归
`scripts/m7-api-compare.ts` 负责对比 Node 与 Rust 的基础 contract
第一批删除后不再保留 Node/Rust 对比脚本M7 回归改为 Rust 主线 contract 验证
1. 默认对比 `/healthz``/api/auth/login-options`
2. 可通过 `M7_COMPARE_PATHS` 扩展只读路径清单
3. 对比时会固定传入 `x-request-id`,并归一化 `requestId / timestamp / latencyMs` 等波动字段
4. 默认严格模式下发现差异直接返回非零退出码
1. `server-rs/scripts/m7-preflight.ps1` 覆盖 Rust 工作区构建、测试与关键脚本门禁
2. `server-rs/scripts/smoke.ps1` 覆盖 `/healthz`、envelope 与 request id 基础 contract
3. `server-rs/scripts/oss-smoke.ps1` 覆盖真实 OSS 链路
4. 新增只读 contract 时优先补进 Rust 侧 smoke 或 handler 测试,不恢复 Node 对比脚本
该脚本只承担“无状态 GET contract”对比带登录、写入、OSS 或 SSE 的主流程仍由专门 smoke 脚本负责。
带登录、写入、OSS 或 SSE 的主流程仍由专门 smoke、handler 测试和人工验证清单负责。
## 7. 观测能力
@@ -113,10 +112,10 @@ M7 观测字段固定为:
## 8. 数据迁移与回滚
当前 M7 不做一次性“Node PostgreSQL 全量导入 SpacetimeDB的危险迁移,采用双跑验证与按主链确认的渐进策略:
当前 M7 不做一次性历史数据导入 SpacetimeDB 的危险迁移,采用按主链确认的渐进策略:
1. 已迁移主链以 SpacetimeDB 为真相源。
2. 未迁移或灰度失败主链继续回退到 Node。
2. 未迁移或灰度失败主链必须继续迁入 Rust 主线后再开放,不回退到 Node 工程
3. 资产二进制以 OSS 为真相,不回滚到本地 `public/generated-*` 写盘。
4. 若 SpacetimeDB schema 需要清库重发,只允许在开发库或明确灰度库执行 `--clear-database`
5. 生产回滚优先切反向代理目标,不优先改代码。
@@ -128,6 +127,6 @@ M7 完成时必须满足:
1. M7 文档、脚本、任务清单均同步。
2. `api-server``spacetime-module` 至少通过 `cargo check`
3. 基础 smoke 脚本可执行,并覆盖 `healthz + envelope + request id`
4. Node/Rust API 对比脚本可执行。
5. Vite dev proxy 已具备 Node/Rust 切换与回退开关。
4. Rust 主线预检和 smoke 脚本可执行。
5. Vite dev proxy 默认指向 Rust `api-server`,仅保留 Rust 目标覆盖开关。
6. `spacetime-module` 已从单 `lib.rs` 拆为按 `runtime / gameplay / custom_world / asset_metadata / ai` 组织的文件结构。

View File

@@ -1,399 +0,0 @@
# Node 后端模块与接口索引
> 该文档由 `server-node/src/manifest/backendCapabilityManifest.ts` 自动生成。
> 生成命令:`npm run server-node:manifest:backend`
> 生成时间:`2026-04-20T14:26:38.663Z`
>
> 过期说明:该索引生成于 `2026-04-20`,其中 `createQwenSpriteRoutes` 与 `/api/assets/qwen-sprite/*` 相关描述已在 `2026-04-21` 后失效。当前 Node 现役资产挂载面仅保留 `createCharacterAssetRoutes``Qwen` 仅剩 prompt 模板复用与 `/generated-qwen-sprites/*` 历史路径兼容,不再存在独立路由主链。
## 总览
- 对外挂载面6 个
- 已登记路由96 条
- 内部模块目录12 个
- 公开接口10 条
- JWT 接口69 条
- 受环境开关控制的接口17 条
- 流式接口6 条
## 产物
- JSON 清单:`server-node/manifests/backend-capability-index.json`
- Markdown 索引:`docs/technical/NODE_BACKEND_MODULE_AND_API_INDEX.md`
- Manifest 源:`server-node/src/manifest/backendCapabilityManifest.ts`
## 对外挂载面
### 资产生成工具面
- 标识:`assets`
- 路由数14
- 入口:`server-node/src/app.ts -> /api/assets -> createCharacterAssetRoutes``server-node/src/app.ts -> /api/assets/qwen-sprite -> createQwenSpriteRoutes`
- 关联模块:`assets`
- 责任:
- 生成角色主形象、动作、动作模板与工作流缓存。
- 承接 Qwen 精灵表主图、整表、修帧与保存链路。
- 把产物发布到 `public/generated-*` 目录并落地局部 manifest。
- 主要服务边界:
- 负责对接 DashScope、Ark 等外部媒体供应商,但不维护 runtime 快照与业务状态。
- 统一受 `ASSETS_API_ENABLED` 开关控制,产物以文件与 JSON manifest 形式落在仓库工作区。
### 鉴权与会话面
- 标识:`auth`
- 路由数17
- 入口:`server-node/src/app.ts -> /api/auth -> createAuthRoutes`
- 关联模块:无
- 责任:
- 承接本地账号、短信验证码与微信登录流程。
- 管理 refresh session、用户信息、会话吊销、审计日志与风险拦截。
- 主要服务边界:
- HTTP 层只做 schema 校验、请求上下文拼装与 Cookie 管理,核心鉴权逻辑统一收口到 `server-node/src/auth/*`
- 用户、身份、会话、风控与短信事件等持久化职责全部下沉到 repository 层,避免路由直接碰数据库细节。
### 编辑器工具面
- 标识:`editor`
- 路由数3
- 入口:`server-node/src/app.ts -> /api/editor -> createEditorRoutes`
- 关联模块:`editor`
- 责任:
- 读取编辑器资源 JSON。
- 回写编辑器覆盖文件。
- 枚举 `public/Icons` 下的物品图标资源。
- 主要服务边界:
- 只对工作区文件系统与 `public` 目录负责,不参与运行时数据库存储。
- 统一受 `EDITOR_API_ENABLED` 开关控制,生产环境可按需关闭。
### 基础健康检查
- 标识:`health`
- 路由数1
- 入口:`server-node/src/app.ts -> /healthz -> createApp`
- 关联模块:无
- 责任:
- 提供 Node 后端进程级健康探针。
- 给反向代理、部署平台和本地联调提供最小可用状态确认。
- 主要服务边界:
- 只返回服务静态信息,不触达数据库、鉴权或外部模型供应商。
### 运行时主能力面
- 标识:`runtime-main`
- 路由数59
- 入口:`server-node/src/app.ts -> /api -> createRuntimeRoutes``server-node/src/routes/runtimeRoutes.ts -> /runtime/custom-world/agent -> createCustomWorldAgentRoutes`
- 关联模块:`ai``custom-world``quest``runtime``runtime-item``story`
- 责任:
- 承接运行时资料库、公开画廊、存档、设置与个人档案接口。
- 承接剧情生成、聊天流、任务生成、运行时物品意图与自定义世界链路。
- 承接 Custom World Agent 会话、消息流和操作回放。
- 主要服务边界:
- HTTP contract 收口在 `runtimeRoutes.ts`,真正的世界生成、剧情、聊天、任务和资源逻辑继续下沉到 `services/*``src/modules/*`
- 除公开画廊外,运行时接口统一走 JWT 鉴权,并依赖 `runtimeRepository`、session store 与 LLM client 执行。
### 运行时 Story Action 面
- 标识:`runtime-story-action`
- 路由数2
- 入口:`server-node/src/app.ts -> /api/runtime/story -> createStoryActionRoutes`
- 关联模块:`story``quest``inventory``runtime-item``npc``progression``combat``runtime`
- 责任:
- 把前端 story choice 动作解析为新的运行时状态。
- 查询指定 story session 的可恢复状态。
- 主要服务边界:
- 路由层只做鉴权与 schema 校验,真正的动作分发与跨模块协作集中在 `storyActionService.ts`
- Story Action 会联动 quest、inventory、runtime-item、npc 等内部模块,但对前端只暴露 story 这一条稳定入口。
## 接口索引
| 方法 | 路径 | 访问 | 响应 | 挂载面 | 内部模块 | 说明 |
| --- | --- | --- | --- | --- | --- | --- |
| POST | `/api/assets/character-animation/generate` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 生成角色动作草稿。 |
| POST | `/api/assets/character-animation/import-video` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 导入动作参考视频并转为可消费素材。 |
| GET | `/api/assets/character-animation/jobs/:taskId` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 查询角色动作生成任务状态。 |
| POST | `/api/assets/character-animation/publish` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 发布角色动作帧集到 public 目录。 |
| GET | `/api/assets/character-animation/templates` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 列出内置角色动作模板。 |
| POST | `/api/assets/character-visual/generate` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 生成角色主形象候选图。 |
| GET | `/api/assets/character-visual/jobs/:taskId` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 查询角色主形象生成任务状态。 |
| POST | `/api/assets/character-visual/publish` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 发布选中的角色主形象到 public 目录。 |
| POST | `/api/assets/character-workflow-cache` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 保存角色资产工作流缓存。 |
| GET | `/api/assets/character-workflow-cache/:characterId` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 按角色读取角色资产工作流缓存。 |
| POST | `/api/assets/qwen-sprite/frame-repair` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 对单帧做 Qwen 修复。 |
| POST | `/api/assets/qwen-sprite/master` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 生成 Qwen 精灵主图。 |
| POST | `/api/assets/qwen-sprite/save` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 保存 Qwen 精灵资产到 public 目录。 |
| POST | `/api/assets/qwen-sprite/sheet` | 开关: ASSETS_API_ENABLED | json | `assets` | `assets` | 生成 Qwen 精灵表。 |
| GET | `/api/auth/audit-logs` | JWT | json | `auth` | 无 | 查询当前账号的鉴权审计日志。 |
| POST | `/api/auth/entry` | 公开 | json | `auth` | 无 | 用户名密码登录;不存在则创建本地账号。 |
| GET | `/api/auth/login-options` | 公开 | json | `auth` | 无 | 返回当前启用的登录方式与入口配置。 |
| POST | `/api/auth/logout` | JWT | json | `auth` | 无 | 退出当前会话并清理 refresh cookie。 |
| POST | `/api/auth/logout-all` | JWT | json | `auth` | 无 | 退出当前账号的全部会话。 |
| GET | `/api/auth/me` | JWT | json | `auth` | 无 | 读取当前登录用户的鉴权资料。 |
| POST | `/api/auth/phone/change` | JWT | json | `auth` | 无 | 已登录用户更换绑定手机号。 |
| POST | `/api/auth/phone/login` | 公开 | json | `auth` | 无 | 手机号验证码登录。 |
| POST | `/api/auth/phone/send-code` | 公开 | json | `auth` | 无 | 发送手机号登录或绑定验证码。 |
| POST | `/api/auth/refresh` | 公开 | json | `auth` | 无 | 使用 refresh session 刷新 JWT。 |
| GET | `/api/auth/risk-blocks` | JWT | json | `auth` | 无 | 查询当前用户命中的风控封禁。 |
| POST | `/api/auth/risk-blocks/:scopeType/lift` | JWT | json | `auth` | 无 | 请求解除指定维度的风控拦截。 |
| GET | `/api/auth/sessions` | JWT | json | `auth` | 无 | 列出当前账号的活跃会话。 |
| POST | `/api/auth/sessions/:sessionId/revoke` | JWT | json | `auth` | 无 | 吊销指定会话。 |
| POST | `/api/auth/wechat/bind-phone` | JWT | json | `auth` | 无 | 为已登录微信账号绑定手机号。 |
| GET | `/api/auth/wechat/callback` | 公开 | redirect | `auth` | 无 | 处理微信回调并重定向回前端。 |
| GET | `/api/auth/wechat/start` | 公开 | json | `auth` | 无 | 发起微信登录并返回授权 URL。 |
| POST | `/api/custom-world/cover-image` | JWT | json | `runtime-main` | `custom-world``assets` | 生成自定义世界封面图。 |
| POST | `/api/custom-world/cover-upload` | JWT | json | `runtime-main` | `custom-world``assets` | 上传并落地自定义世界封面图。 |
| POST | `/api/custom-world/entity` | JWT | json | `runtime-main` | `custom-world``ai` | 按世界 profile 生成单个角色或地标实体。 |
| POST | `/api/custom-world/scene-image` | JWT | json | `runtime-main` | `custom-world``assets` | 生成自定义世界场景图。 |
| POST | `/api/custom-world/scene-npc` | JWT | json | `runtime-main` | `custom-world``ai``npc` | 按地标生成场景 NPC。 |
| GET | `/api/editor/catalog/items` | 开关: EDITOR_API_ENABLED | json | `editor` | `editor` | 列出 `public/Icons` 下的物品图标资源。 |
| GET | `/api/editor/json/:resourceId` | 开关: EDITOR_API_ENABLED | json | `editor` | `editor` | 读取指定编辑器资源 JSON。 |
| POST | `/api/editor/json/:resourceId` | 开关: EDITOR_API_ENABLED | json | `editor` | `editor` | 回写指定编辑器资源 JSON。 |
| POST | `/api/llm/chat/completions` | JWT | proxy | `runtime-main` | `ai` | 把聊天补全请求透传到上游模型。 |
| DELETE | `/api/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 清空平台浏览历史。 |
| GET | `/api/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 读取平台浏览历史。 |
| POST | `/api/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 写入或批量同步平台浏览历史。 |
| GET | `/api/profile/dashboard` | JWT | json | `runtime-main` | `runtime` | 读取运行时个人主页汇总。 |
| GET | `/api/profile/play-stats` | JWT | json | `runtime-main` | `runtime` | 读取个人游玩统计。 |
| GET | `/api/profile/save-archives` | JWT | json | `runtime-main` | `runtime` | 列出个人存档摘要。 |
| POST | `/api/profile/save-archives/:worldKey` | JWT | json | `runtime-main` | `runtime` | 恢复指定世界的最近存档。 |
| GET | `/api/profile/wallet-ledger` | JWT | json | `runtime-main` | `runtime` | 列出个人资产流水。 |
| POST | `/api/runtime/chat/character/reply/stream` | JWT | stream | `runtime-main` | `ai``story` | 流式生成角色回复。 |
| POST | `/api/runtime/chat/character/suggestions` | JWT | json | `runtime-main` | `ai``story` | 生成角色聊天建议语。 |
| POST | `/api/runtime/chat/character/summary` | JWT | json | `runtime-main` | `ai``story` | 生成角色聊天摘要。 |
| POST | `/api/runtime/chat/npc/dialogue/stream` | JWT | stream | `runtime-main` | `ai``npc``story` | 流式生成 NPC 对话。 |
| POST | `/api/runtime/chat/npc/recruit/stream` | JWT | stream | `runtime-main` | `ai``npc``story` | 流式生成招募 NPC 对话。 |
| POST | `/api/runtime/chat/npc/turn/stream` | JWT | stream | `runtime-main` | `ai``npc``story` | 流式生成 NPC 单回合发言。 |
| GET | `/api/runtime/custom-world-gallery` | 公开 | json | `runtime-main` | `custom-world``runtime` | 列出公开的自定义世界画廊。 |
| GET | `/api/runtime/custom-world-gallery/:ownerUserId/:profileId` | 公开 | json | `runtime-main` | `custom-world``runtime` | 读取指定公开世界作品详情。 |
| GET | `/api/runtime/custom-world-library` | JWT | json | `runtime-main` | `custom-world``runtime` | 列出当前账号的自定义世界资料库。 |
| DELETE | `/api/runtime/custom-world-library/:profileId` | JWT | json | `runtime-main` | `custom-world``runtime` | 删除指定自定义世界 profile。 |
| PUT | `/api/runtime/custom-world-library/:profileId` | JWT | json | `runtime-main` | `custom-world``runtime` | 写入或更新指定自定义世界 profile。 |
| POST | `/api/runtime/custom-world-library/:profileId/publish` | JWT | json | `runtime-main` | `custom-world``runtime` | 发布指定世界到公开画廊。 |
| POST | `/api/runtime/custom-world-library/:profileId/unpublish` | JWT | json | `runtime-main` | `custom-world``runtime` | 撤回指定世界的公开发布状态。 |
| POST | `/api/runtime/custom-world/agent/sessions` | JWT | json | `runtime-main` | `custom-world``ai` | 创建 Custom World Agent 会话。 |
| GET | `/api/runtime/custom-world/agent/sessions/:sessionId` | JWT | json | `runtime-main` | `custom-world``ai` | 读取 Agent 会话快照。 |
| POST | `/api/runtime/custom-world/agent/sessions/:sessionId/actions` | JWT | json | `runtime-main` | `custom-world``ai``assets` | 执行 Agent 卡片生成、资产同步或发布动作。 |
| GET | `/api/runtime/custom-world/agent/sessions/:sessionId/cards/:cardId` | JWT | json | `runtime-main` | `custom-world``ai` | 读取 Agent 卡片详情。 |
| POST | `/api/runtime/custom-world/agent/sessions/:sessionId/messages` | JWT | json | `runtime-main` | `custom-world``ai` | 向 Agent 会话提交一条创作消息。 |
| POST | `/api/runtime/custom-world/agent/sessions/:sessionId/messages/stream` | JWT | stream | `runtime-main` | `custom-world``ai` | 流式提交 Agent 消息并实时接收回执。 |
| GET | `/api/runtime/custom-world/agent/sessions/:sessionId/operations/:operationId` | JWT | json | `runtime-main` | `custom-world``ai` | 查询 Agent 后台操作状态。 |
| POST | `/api/runtime/custom-world/entity` | JWT | json | `runtime-main` | `custom-world``ai` | 按世界 profile 生成单个角色或地标实体(兼容路径)。 |
| POST | `/api/runtime/custom-world/scene-npc` | JWT | json | `runtime-main` | `custom-world``ai``npc` | 按地标生成场景 NPC兼容路径。 |
| POST | `/api/runtime/custom-world/sessions` | JWT | json | `runtime-main` | `custom-world` | 创建传统自定义世界问答会话。 |
| GET | `/api/runtime/custom-world/sessions/:sessionId` | JWT | json | `runtime-main` | `custom-world` | 读取传统自定义世界问答会话。 |
| POST | `/api/runtime/custom-world/sessions/:sessionId/answers` | JWT | json | `runtime-main` | `custom-world` | 回答传统自定义世界问答题目。 |
| GET | `/api/runtime/custom-world/sessions/:sessionId/generate/stream` | JWT | stream | `runtime-main` | `custom-world``ai` | 流式编译传统自定义世界 profile。 |
| GET | `/api/runtime/custom-world/works` | JWT | json | `runtime-main` | `custom-world``runtime` | 列出当前账号的自定义世界作品汇总。 |
| POST | `/api/runtime/items/runtime-intent` | JWT | json | `runtime-main` | `runtime-item``ai` | 生成运行时物品意图。 |
| DELETE | `/api/runtime/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 清空平台浏览历史。(兼容路径) |
| GET | `/api/runtime/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 读取平台浏览历史。(兼容路径) |
| POST | `/api/runtime/profile/browse-history` | JWT | json | `runtime-main` | `runtime` | 写入或批量同步平台浏览历史。(兼容路径) |
| GET | `/api/runtime/profile/dashboard` | JWT | json | `runtime-main` | `runtime` | 读取运行时个人主页汇总。(兼容路径) |
| GET | `/api/runtime/profile/play-stats` | JWT | json | `runtime-main` | `runtime` | 读取个人游玩统计。(兼容路径) |
| GET | `/api/runtime/profile/save-archives` | JWT | json | `runtime-main` | `runtime` | 列出个人存档摘要。(兼容路径) |
| POST | `/api/runtime/profile/save-archives/:worldKey` | JWT | json | `runtime-main` | `runtime` | 恢复指定世界的最近存档(兼容路径)。 |
| GET | `/api/runtime/profile/wallet-ledger` | JWT | json | `runtime-main` | `runtime` | 列出个人资产流水。(兼容路径) |
| POST | `/api/runtime/quests/generate` | JWT | json | `runtime-main` | `quest``ai` | 按当前遭遇生成任务候选。 |
| DELETE | `/api/runtime/save/snapshot` | JWT | json | `runtime-main` | `runtime` | 删除当前用户的运行时存档。 |
| GET | `/api/runtime/save/snapshot` | JWT | json | `runtime-main` | `runtime``progression``quest` | 读取当前用户的运行时存档。 |
| PUT | `/api/runtime/save/snapshot` | JWT | json | `runtime-main` | `runtime``progression``quest` | 保存并归一化当前运行时存档。 |
| GET | `/api/runtime/settings` | JWT | json | `runtime-main` | `runtime` | 读取运行时设置。 |
| PUT | `/api/runtime/settings` | JWT | json | `runtime-main` | `runtime` | 更新运行时设置。 |
| POST | `/api/runtime/story/actions/resolve` | JWT | json | `runtime-story-action` | `story``quest``inventory``runtime-item``npc``progression``combat``runtime` | 解析前端 story choice 动作为新的运行时结果。 |
| POST | `/api/runtime/story/continue` | JWT | json | `runtime-main` | `story``ai` | 生成下一段故事内容。 |
| POST | `/api/runtime/story/initial` | JWT | json | `runtime-main` | `story``ai` | 生成首段故事内容。 |
| GET | `/api/runtime/story/state/:sessionId` | JWT | json | `runtime-story-action` | `story``runtime` | 读取指定 story session 的运行时状态。 |
| GET | `/api/ws/health` | JWT | json | `runtime-main` | `runtime` | 保留给未来实时链路的占位健康检查。 |
| GET | `/healthz` | 公开 | json | `health` | 无 | 返回 Node 后端进程健康状态。 |
## 内部模块边界
### AI 编排模块
- 标识:`ai`
- 目录:`server-node/src/modules/ai`
- 对外可见面:`runtime-main`
- 关联路由数23
- 职责:
- 统一剧情、多轮聊天与自定义世界编排器的 prompt 构造与输出归一化。
- 屏蔽前端对不同 AI 链路的直接拼装细节。
- 主要服务边界:
- 专注提示词与编排,不负责持久化与 HTTP 传输。
- 通过 `services/llmClient.ts` 与外部模型交互,由路由与 service 层决定何时调用。
- 关键文件:
- `server-node/src/modules/ai/chatOrchestrator.ts`
- `server-node/src/modules/ai/customWorldOrchestrator.ts`
- `server-node/src/modules/ai/storyOrchestrator.ts`
### 资产工具模块
- 标识:`assets`
- 目录:`server-node/src/modules/assets`
- 对外可见面:`assets`
- 关联路由数18
- 职责:
- 承接角色资产与 Qwen 精灵表的生成、查询、发布和保存。
- 维护资产流程需要的缓存、草稿与产物 manifest。
- 主要服务边界:
- 以文件系统和外部媒体模型为主要边界,不碰 runtimeRepository。
- 对外暴露稳定 HTTP 路径,对内通过私有 helper 处理媒体编码、任务轮询与写盘。
- 关键文件:
- `server-node/src/modules/assets/characterAssetRoutes.ts`
- `server-node/src/modules/assets/qwenSpriteRoutes.ts`
### 战斗结算模块
- 标识:`combat`
- 目录:`server-node/src/modules/combat`
- 对外可见面:`runtime-story-action`
- 关联路由数1
- 职责:
- 提供运行时战斗结算与数值变更能力。
- 为 story action 里的战斗型交互提供纯计算服务。
- 主要服务边界:
- 聚焦状态推导与结果计算,不负责 transport 与持久化。
- 关键文件:
- `server-node/src/modules/combat/combatResolutionService.ts`
### 自定义世界运行时模块
- 标识:`custom-world`
- 目录:`server-node/src/modules/custom-world`
- 对外可见面:`runtime-main`
- 关联路由数26
- 职责:
- 规范 creator intent、世界运行时类型与 profile compile。
- 把世界创作输入整理成运行时可消费的数据结构。
- 主要服务边界:
- 偏纯领域建模与 compile不直接做 HTTP、数据库查询或模型调用。
- 关键文件:
- `server-node/src/modules/custom-world/creatorIntentRuntime.ts`
- `server-node/src/modules/custom-world/runtimeProfile.ts`
- `server-node/src/modules/custom-world/runtimeTypes.ts`
### 编辑器资源模块
- 标识:`editor`
- 目录:`server-node/src/modules/editor`
- 对外可见面:`editor`
- 关联路由数3
- 职责:
- 提供编辑器资源目录枚举与 JSON 读写入口。
- 主要服务边界:
- 只负责工作区文件输入输出,不参与运行时业务计算。
- 关键文件:
- `server-node/src/modules/editor/editorRoutes.ts`
### 背包与物品变更模块
- 标识:`inventory`
- 目录:`server-node/src/modules/inventory`
- 对外可见面:`runtime-story-action`
- 关联路由数1
- 职责:
- 维护背包变更、NPC 背包交互与 story action 里的物品副作用。
- 主要服务边界:
- 对运行时状态做局部变更,不直接暴露 HTTP 路由。
- 关键文件:
- `server-node/src/modules/inventory/inventoryMutationService.ts`
- `server-node/src/modules/inventory/inventoryStoryActionService.ts`
- `server-node/src/modules/inventory/npcInventoryStoryActionService.ts`
### NPC 交互模块
- 标识:`npc`
- 目录:`server-node/src/modules/npc`
- 对外可见面:`runtime-story-action``runtime-main`
- 关联路由数6
- 职责:
- 维护 NPC 互动规则、任务 primitive 与关系变更逻辑。
- 主要服务边界:
- 专注 NPC 侧状态推导,供 story action 与聊天/任务链路复用。
- 关键文件:
- `server-node/src/modules/npc/npcInteractionService.ts`
- `server-node/src/modules/npc/npcTask6Primitives.ts`
### 成长与关卡进程模块
- 标识:`progression`
- 目录:`server-node/src/modules/progression`
- 对外可见面:`runtime-story-action``runtime-main`
- 关联路由数3
- 职责:
- 提供角色成长、敌对等级、章节推进与 benchmark 逻辑。
- 主要服务边界:
- 只做成长数值与章节进度计算,由 runtime hydrate 与 story action 复用。
- 关键文件:
- `server-node/src/modules/progression/playerProgressionService.ts`
- `server-node/src/modules/progression/hostileProgressionService.ts`
- `server-node/src/modules/progression/chapterProgressionPlanner.ts`
### 任务运行时模块
- 标识:`quest`
- 目录:`server-node/src/modules/quest`
- 对外可见面:`runtime-main``runtime-story-action`
- 关联路由数4
- 职责:
- 生成任务意图、维护任务日志与处理任务进度信号。
- 为运行时 quest 接口与 story action 提供统一任务语义。
- 主要服务边界:
- 领域逻辑以 quest module 为中心AI 生成只是一种输入来源。
- 不直接处理 HTTP 响应,统一由 routes/service 层调用。
- 关键文件:
- `server-node/src/modules/quest/runtimeQuestModule.ts`
- `server-node/src/modules/quest/questProgressionService.ts`
- `server-node/src/modules/quest/questStoryActionService.ts`
### 运行时状态基座模块
- 标识:`runtime`
- 目录:`server-node/src/modules/runtime`
- 对外可见面:`runtime-main``runtime-story-action`
- 关联路由数32
- 职责:
- 定义运行时状态 primitive、经济与装备规则。
- 负责存档 hydration、兼容迁移与状态归一化。
- 主要服务边界:
- 是 runtimeRepository 与 story action 的共同状态基座,不承担 HTTP 入口职责。
- 关键文件:
- `server-node/src/modules/runtime/runtimeSnapshotHydration.ts`
- `server-node/src/modules/runtime/runtimeStatePrimitives.ts`
- `server-node/src/modules/runtime/runtimeEquipmentModule.ts`
### 运行时物品模块
- 标识:`runtime-item`
- 目录:`server-node/src/modules/runtime-item`
- 对外可见面:`runtime-main``runtime-story-action`
- 关联路由数2
- 职责:
- 生成运行时物品意图、物品奖励与剧情指纹。
- 维护宝藏与物品解析逻辑。
- 主要服务边界:
- 聚焦物品领域编译与奖励拼装,由 route/service 选择具体触发时机。
- 关键文件:
- `server-node/src/modules/runtime-item/runtimeItemModule.ts`
- `server-node/src/modules/runtime-item/runtimeItemResolutionService.ts`
- `server-node/src/modules/runtime-item/treasureStoryActionService.ts`
### 故事会话模块
- 标识:`story`
- 目录:`server-node/src/modules/story`
- 对外可见面:`runtime-main``runtime-story-action`
- 关联路由数10
- 职责:
- 维护运行时故事会话状态与 action 分发。
- 为 story resolve、story state 查询提供统一入口。
- 主要服务边界:
- story 模块是 runtime 主循环的编排层,必要时再向 quest、inventory、combat 等领域模块分发。
- 关键文件:
- `server-node/src/modules/story/runtimeSession.ts`
- `server-node/src/modules/story/storyActionRoutes.ts`
- `server-node/src/modules/story/storyActionService.ts`
## 维护规则
- 新增 `server-node/src/modules/*` 目录时,必须先补充 manifest 里的模块说明,再重新生成产物。
- 新增或下线路由时,先更新 manifest 里的路由清单,再运行生成命令同步 JSON 与文档。
- 如果路由来自兼容路径或中间件派生路径,`sourceHint` 需要指向源代码里的真实表达式,确保生成脚本能做最小校验。

View File

@@ -1,245 +0,0 @@
# Node 后端知识图谱
日期:`2026-04-08`
## 1. 当前定位
当前运行时后端以 `server-node/` 为唯一有效服务端实现。
当前职责:
- 承接运行时鉴权
- 承接运行时持久化
- 承接运行时 AI 接口
- 承接编辑器写盘与资产生成工具接口
- 为 Vite 前端提供开发期代理目标
当前不再使用:
- 已删除的旧 Vite 本地 API 插件链路 `scripts/dev-server/*.ts`
## 2. 技术栈
- HTTP 框架:`Express`
- 语言与构建:`TypeScript` + `tsx` + `esbuild`
- 数据库:`PostgreSQL`
- JWT`jose`
- 密码哈希:`@node-rs/argon2`
- 日志:`pino` + `pino-http` + `pino-roll`
## 3. 运行入口
推荐命令:
```bash
npm run dev
```
相关脚本:
- 根目录联调:`npm run dev` / `npm run dev:node`
- 仅前端开发:`npm run dev:web`
- 单独启动后端开发模式:`npm run server-node:dev`
- 构建后端:`npm run server-node:build`
- 运行后端测试:`npm run server-node:test`
默认监听:
- 前端:`3000`
- Node 后端:`8081`
## 4. 目录与主入口
服务端主入口:
- `server-node/src/server.ts`
- `server-node/src/app.ts`
路由入口:
- `server-node/src/routes/authRoutes.ts`
- `server-node/src/routes/runtimeRoutes.ts`
- `server-node/src/modules/editor/editorRoutes.ts`
- `server-node/src/modules/assets/characterAssetRoutes.ts`
- `server-node/src/modules/assets/qwenSpriteRoutes.ts`
基础设施:
- `server-node/src/config.ts`
- `server-node/src/logging.ts`
- `server-node/src/db.ts`
- `server-node/src/context.ts`
数据访问:
- `server-node/src/repositories/userRepository.ts`
- `server-node/src/repositories/runtimeRepository.ts`
鉴权相关:
- `server-node/src/auth/authService.ts`
- `server-node/src/auth/token.ts`
- `server-node/src/auth/password.ts`
- `server-node/src/middleware/auth.ts`
## 5. 鉴权模型
当前采用:
- 前端本地保存 `JWT + 自动生成的用户名密码`
- 请求头使用 `Authorization: Bearer <token>`
- 后端 middleware 统一解析出 `UserID`
- handler 不直接解析 token
当前账号策略:
- 默认自动匿名账号启动
- 本地无 JWT 时,前端会自动生成随机用户名密码并调用 `POST /api/auth/entry`
- 本地 JWT 失效但仍保留随机凭据时,前端自动重新调用 `auth/entry` 恢复同一账号
JWT 现状:
- 当前为永久签发
- claim 仍保留:`sub``iat``iss``ver`
- `logout` 通过递增 `token_version` 立即失效旧 token
## 6. 数据存储
当前数据库:
- 当前运行时持久化已切换到 `PostgreSQL`
- 连接信息由后端 `DATABASE_URL` 环境变量注入
- 不再以本地 `SQLite` 文件作为正式运行时数据库
- 后端测试默认使用 `pg-mem` 作为内存级 PostgreSQL 兼容实现
- 基础表初始化通过 `schema_migrations` 基线管理
- 可通过 `npm run server-node:db:migrate` 主动校验并补齐数据库基线
当前核心表:
- `users`
- `save_snapshots`
- `runtime_settings`
- `custom_world_profiles`
当前隔离原则:
- 所有运行时数据按用户隔离
## 7. 已承接接口
鉴权:
- `POST /api/auth/entry`
- `GET /api/auth/me`
- `POST /api/auth/logout`
运行时持久化:
- `GET /api/runtime/save/snapshot`
- `PUT /api/runtime/save/snapshot`
- `DELETE /api/runtime/save/snapshot`
- `GET /api/runtime/settings`
- `PUT /api/runtime/settings`
- `GET /api/runtime/custom-world-library`
- `PUT /api/runtime/custom-world-library/:profileId`
- `DELETE /api/runtime/custom-world-library/:profileId`
运行时 AI
- `POST /api/llm/chat/completions`
- `POST /api/custom-world/scene-image`
- `POST /api/runtime/story/initial`
- `POST /api/runtime/story/continue`
- `POST /api/runtime/custom-world/agent/sessions`
- `GET /api/runtime/custom-world/agent/sessions/:sessionId`
- `POST /api/runtime/custom-world/agent/sessions/:sessionId/messages`
- `POST /api/runtime/custom-world/agent/sessions/:sessionId/actions`
- `GET /api/runtime/custom-world/works`
- `POST /api/runtime/chat/character/suggestions`
- `POST /api/runtime/chat/character/summary`
- `POST /api/runtime/chat/character/reply/stream`
- `POST /api/runtime/chat/npc/dialogue/stream`
- `POST /api/runtime/chat/npc/recruit/stream`
- `POST /api/runtime/items/runtime-intent`
- `POST /api/runtime/quests/generate`
补充说明(`2026-04-19`
- `POST /api/custom-world/scene-image` 现在支持前端仅提交 `profile + landmark + userPrompt` 上下文,由后端统一补齐场景图 prompt 与默认 negative prompt。
- runtime story option 的 `interaction` 元数据现在由后端随 option 一并返回,前端不再本地按 `functionId` 重建 NPC / treasure 交互语义。
编辑器工具:
- `GET /api/editor/catalog/items`
- `GET /api/editor/json/:resourceId`
- `POST /api/editor/json/:resourceId`
资产工具:
- `POST /api/assets/character-visual/generate`
- `POST /api/assets/character-visual/publish`
- `GET /api/assets/character-visual/jobs/:taskId`
- `POST /api/assets/character-animation/generate`
- `POST /api/assets/character-animation/publish`
- `GET /api/assets/character-animation/jobs/:taskId`
- `POST /api/assets/character-animation/import-video`
- `GET /api/assets/character-animation/templates`
编辑器与资产接口门禁:
- `EDITOR_API_ENABLED` 控制 `/api/editor/*`
- `ASSETS_API_ENABLED` 控制 `/api/assets/*`
- 非生产环境默认开启,生产环境默认关闭
## 8. Story 与 Custom World 现状
Story
- Node 后端直接复用前端成熟 prompt 与归一化逻辑
- 服务端走 `src/services/ai.ts` 中的严格版 story 生成链
Custom World
- Node 后端当前已自持 `server-node/src/modules/custom-world/**` 运行时模块
- 已承接 `creator intent` 归一化、`anchorPack / lockState` 推导、framework normalize、runtime profile compile
- `customWorldOrchestrator``customWorldAgentFoundationDraftService` 已不再运行时 import 前端 `src/services/customWorld*.ts``src/types.js`
- `server-node/src/prompts/customWorldPrompts.ts` 已承接 foundation draft 与 scene image 使用的 custom world prompt source
- 上述 prompt 迁移只改变源码归属位置,没有改动提示词正文
- 当前保留 `session + answers + SSE progress/result/error` 协议
- 前端已支持接收真实阶段进度对象
## 9. 前端接入点
鉴权与请求:
- `src/services/apiClient.ts`
- `src/services/authService.ts`
- `src/components/auth/AuthGate.tsx`
运行时服务层:
- `src/services/storageService.ts`
- `src/services/aiService.ts`
编辑器与资产工具层:
- `src/editor/shared/editorApiClient.ts`
- `src/components/preset-editor/characterAssetStudioPersistence.ts`
## 10. 当前 Vite 角色
Vite 当前只负责代理,不再提供本地 API 插件。
当前代理目标:
- `/api/auth`
- `/api/runtime`
- `/api/editor`
- `/api/assets`
- `/api/llm`
- `/api/custom-world/scene-image`
- `/api/ws`
全部转发到 Node 后端。
`scripts/dev-server/` 目录现仅保留 README 作为迁移说明,旧本地 API 实现代码已于 `2026-04-19` 删除。

View File

@@ -1,226 +0,0 @@
# Node 后端测试、观测与部署基线
日期:`2026-04-08`
## 1. 文档目标
这份文档用于落实 `EXPRESS_BACKEND_PARALLEL_WORKSTREAM_PLAN_2026-04-08.md` 中的任务 9
- 给 Node 后端补最小自动回归
- 给请求链路补最小可追踪基线
- 给部署、回滚、迁移补最小操作清单
当前目标不是一次性把监控平台、CI/CD、容器编排全部做完而是先确保
- 后端改动后有脚本能快速验证主链路
- 线上或联调失败时能快速定位到具体请求
- 发布前后有统一检查口径
## 2. 当前基线命令
推荐在仓库根目录执行:
```bash
npm run server-node:db:migrate
npm run server-node:test:baseline
npm run server-node:smoke
npm run server-node:smoke:proxy
```
说明:
- `npm run server-node:db:migrate`
- 用当前 `DATABASE_URL` 主动校验 PostgreSQL 基线是否可连接、可初始化
- 会确保 `schema_migrations` 和运行时基础表已补齐
- `npm run server-node:test:baseline`
- 当前先固定为任务 9 自己维护的观测基线测试
- 已覆盖 `requestId` 回传、访问日志字段、错误日志链路
- `npm run server-node:smoke`
- 启动一套基于 `pg-mem` 的临时 Express 服务
- 不依赖本地 PostgreSQL
- 走真实 HTTP 调用验证 `healthz -> auth -> runtime save/settings -> logout`
- `npm run server-node:smoke:proxy`
- 基于已构建的 `dist + server-node/dist`
- 自动拉起 `server-node + 同域反向代理 harness`
-`pg-mem` 跑同域反向代理链路 smoke
- 验证 `web -> reverse proxy -> /api/* -> server-node` 主链路
如果要一口气跑完整发布前基线,可执行:
```bash
npm run server-node:check:deploy
```
补充说明:
- `npm run server-node:test` 仍然可以继续作为更大范围的后端接口套件入口
- 但它会跟随其他并行任务一起变化,不应替代任务 9 自己的稳定基线
## 2.1 任务 9 对照清单
当前按并行任务规划中的任务 9 逐项对照:
- 后端接口测试:`npm run server-node:test`
- 关键主链路 smoke`npm run server-node:smoke`
- request/response 日志校验:`npm run server-node:test:baseline`
- 同域部署基线:本文第 6 节与 `npm run server-node:smoke:proxy`
- 反向代理 smoke 测试脚本:`scripts/smoke-same-origin-stack.ts`
- 回滚、备份、迁移检查清单:本文第 8 节与 `npm run server-node:db:migrate`
- 发布前一键检查:`npm run server-node:check:deploy`
## 3. 当前 smoke 覆盖范围
当前 smoke 脚本验证以下链路:
- `GET /healthz`
- `POST /api/auth/entry`
- `GET /api/auth/me`
- `PUT /api/runtime/save/snapshot`
- `GET /api/runtime/save/snapshot`
- `PUT /api/runtime/settings`
- `GET /api/runtime/settings`
- `DELETE /api/runtime/save/snapshot`
- `POST /api/auth/logout`
当前代理 smoke 额外验证:
- `GET /`
- `GET /healthz`(本地反向代理健康探针)
- `POST /api/auth/entry` 经反代可用
- `GET /api/auth/me` 经反代可用
- `PUT /api/runtime/save/snapshot` 经反代可用
- `GET /api/runtime/save/snapshot` 经反代可用
- `X-Request-Id` 能穿过反向代理返回给调用方
当前 smoke 的定位是:
- 优先覆盖后端化后最容易断的基础链路
- 优先覆盖前端最依赖的鉴权和持久化能力
- 不把 AI 上游依赖拉进最小回归集,避免把第三方波动误判成主链路回归
## 4. 当前观测基线
当前请求链路至少要满足以下约束:
- 支持读取外部传入的 `X-Request-Id`
- 如果调用方没有传 `X-Request-Id`,后端自动生成
- 响应头回写 `x-request-id`
- 访问日志至少包含:
- `request_id`
- `user_id`
- `method`
- `path`
- `status`
- `latency_ms`
- 错误日志至少包含:
- `request_id`
- `user_id`
- `err`
当前目的很明确:
- 浏览器、反向代理、Node 后端至少有一个共同可追踪的请求标识
- 接口失败后,能从日志里快速找到对应请求
## 5. 部署前检查清单
发布前至少执行一次:
- `npm run check:encoding`
- `npm run server-node:db:migrate`
- `npm run server-node:test:baseline`
- `npm run server-node:smoke`
- `npm run server-node:build`
- `npm run build`
- `npm run server-node:smoke:proxy`
环境变量至少确认:
- `DATABASE_URL`
- `JWT_SECRET`
- `NODE_SERVER_ADDR`
- `LOG_LEVEL`
- `LLM_API_KEY``ARK_API_KEY`
- `DASHSCOPE_API_KEY`
部署前数据库检查:
- 确认目标 PostgreSQL 可连接
- 确认发布账号具备建表或执行初始化所需权限
- 确认已执行 `npm run server-node:db:migrate` 或等效迁移步骤
- 确认现网数据已完成备份
## 6. 同域部署基线
当前推荐仍然是同域部署:
- Web 静态资源:`https://game.example.com/`
- Node API`https://game.example.com/api/*`
最小拓扑:
```text
Browser
-> Nginx / Caddy
-> dist
-> server-node
```
反向代理至少要保留这些头:
- `Host`
- `X-Forwarded-For`
- `X-Forwarded-Proto`
- `X-Request-Id`
流式接口还要确保:
- `proxy_buffering off`
- `X-Accel-Buffering: no`
## 7. 发布后 smoke 清单
发布完成后至少人工或脚本确认一次:
1. `GET /healthz` 返回 `200`
2. 响应头里能看到 `x-request-id`
3. `POST /api/auth/entry` 可正常注册或恢复账号
4. `GET /api/auth/me` 可正常识别 token
5. `PUT /api/runtime/save/snapshot``GET /api/runtime/save/snapshot` 正常
6. 日志中能用同一个 `request_id` 串起访问记录
如果线上使用反向代理生成请求 ID还要额外确认
- 代理传入的 `X-Request-Id` 没有在 Node 层丢失
- 同域入口 `/``/api/*` 可以通过同一个站点域名访问
## 8. 回滚与备份清单
回滚前先确认:
- 当前发布包版本号或 commit 可定位
- 当前数据库备份可恢复
- 当前 `.env` 或 secret 版本可回退
需要回滚时按顺序执行:
1. 停止新版本 Node 进程
2. 切回上一个稳定前端静态包和 Node 构建产物
3. 恢复上一个稳定环境变量版本
4. 如果本次发布包含数据库结构变更,先确认是否需要回滚数据
5. 回滚后重新执行 `healthz + auth + runtime save` 最小 smoke
如果本次发布已经写入了不兼容数据结构:
- 不要只回滚代码不验证数据兼容性
- 必须先确认旧版本代码是否还能读取当前数据
## 9. 后续扩展方向
任务 9 的下一轮可以继续补:
- 把 smoke 纳入 CI
- 为关键 API 增加结构化 contract 测试
- 给上游 AI 调用补 vendor/model/errorCode 维度日志
- 增加数据库迁移前后的自动检查脚本
- 增加反向代理与正式环境的联调 smoke

View File

@@ -1,185 +0,0 @@
# Prompt 目录收口方案2026-04-19
## 1. 这次调整解决什么问题
此前提示词分散在多个后端、前端和工具文件里:
- `server-node/src/modules/ai/**`
- `server-node/src/modules/quest/**`
- `server-node/src/modules/runtime-item/**`
- `server-node/src/services/customWorld*.ts`
- `server-node/src/services/eightAnchorPromptBuilder.ts`
- `server-node/src/modules/assets/characterAssetRoutes.ts`
- `src/services/**`
- `src/components/**`
问题主要有三类:
1. 业务逻辑和 prompt 文本混写,改提示词时容易顺手改坏运行时逻辑。
2. 同一类 prompt 缺少集中入口,排查系统 prompt / user prompt / repair prompt 成本高。
3. 老桥接层、测试和新业务链路同时依赖时,迁移成本高,容易出现导出断裂。
这次收口目标不是“重写全部 AI 链路”,而是把当前正式业务 prompt 主源收到独立目录,业务模块退化成“准备上下文 + 调用 prompt 脚本”。
## 2. 新目录
本轮落地后的目录:
```text
packages/shared/src/prompts/
└─ qwenSprite.ts
server-node/src/prompts/
├─ characterAssetPrompts.ts
├─ chatPromptBuilders.ts
├─ customWorldAgentPrompts.ts
├─ customWorldEntityPrompts.ts
├─ customWorldOrchestratorPrompts.ts
├─ customWorldSceneNpcPrompts.ts
├─ eightAnchorPrompts.ts
├─ questPrompts.ts
├─ runtimeItemPrompts.ts
├─ storyOrchestratorPrompts.ts
└─ storyPromptBuilders.ts
src/prompts/
├─ characterChatPrompts.ts
├─ customWorldEntityActionPrompts.ts
├─ customWorldOrchestratorPrompts.ts
├─ customWorldPrompts.ts
├─ customWorldRolePromptDefaults.ts
├─ questPrompts.ts
├─ runtimeItemPrompts.ts
├─ storyOrchestratorPrompts.ts
└─ storyPromptBuilders.ts
```
当前职责划分:
- `chatPromptBuilders.ts`
- 角色私聊 / NPC 聊天 / 招募对话 prompt
- `storyPromptBuilders.ts`
- 主剧情 system prompt 与 user prompt builder
- `storyOrchestratorPrompts.ts`
- 剧情语言修复 prompt
- `questPrompts.ts`
- 任务意图 system prompt 与 user prompt builder
- `runtimeItemPrompts.ts`
- 运行时物品意图 system prompt 与 user prompt 文本装配
- `customWorldOrchestratorPrompts.ts`
- 自定义世界主编排 JSON 生成与 repair prompt
- `customWorldAgentPrompts.ts`
- 世界草稿 JSON prompt、补角色 / 补地点 prompt
- `customWorldEntityPrompts.ts`
- 世界编辑器角色 / 场景实体生成 prompt
- `customWorldSceneNpcPrompts.ts`
- 世界编辑器场景 NPC 生成 prompt
- `characterAssetPrompts.ts`
- 角色主图 / 动作试片正式生成 prompt
- `eightAnchorPrompts.ts`
- 八锚点状态推断、模式规则与正式单轮共创 prompt
- `src/prompts/customWorldPrompts.ts`
- 自定义世界分阶段生成 prompt 与场景背景图 prompt
- `src/prompts/customWorldRolePromptDefaults.ts`
- 角色资产工作台默认 prompt 种子唯一主源
- `src/prompts/customWorldEntityActionPrompts.ts`
- 编辑器技能动作 prompt
- `packages/shared/src/prompts/qwenSprite.ts`
- 共享资产层的基础角色 prompt 模板
## 3. 落地规则
### 3.1 业务模块只做两件事
1. 整理运行时上下文
2. 调用 `server-node/src/prompts/**` 下的脚本输出 prompt
不要在业务模块里继续直接内联大段 system prompt / repair prompt / user prompt 模板文本。
### 3.2 Prompt 文件只放文本相关职责
允许放:
- system prompt 常量
- user prompt builder
- repair prompt builder
- prompt 专用的文本摘要函数
不建议放:
- 运行时状态 mutation
- 仓储读写
- HTTP 处理
- 与 prompt 无关的领域推导
### 3.3 兼容层保留旧导出
本轮对已有纯 prompt builder 文件采取了兼容迁移,旧路径保留为薄 re-export
- `server-node/src/modules/ai/chatPromptBuilders.ts`
- `server-node/src/modules/ai/storyPromptBuilders.ts`
- `server-node/src/services/eightAnchorPromptBuilder.ts`
- `src/services/prompt.ts`
- `src/services/characterChatPrompt.ts`
- `src/services/questPrompt.ts`
- `src/services/runtimeItemAiPrompt.ts`
- `src/components/asset-studio/customWorldRolePromptDefaults.ts`
- `packages/shared/src/assets/qwenSprite.ts`
对于 `runtimeQuestModule.ts``runtimeItemModule.ts` 这类被桥接层直接引用的模块,本轮保留原导出名,通过 re-export 指向新 prompt 文件,保证兼容性。
## 4. 后续新增 prompt 的写法
新增提示词时按下面顺序处理:
1. 先判断属于后端、前端/编辑器还是共享工具层。
2. 后端正式业务优先补到 `server-node/src/prompts/*.ts`
3. 前端/编辑器 prompt 优先补到 `src/prompts/*.ts`
4. 可复用的共享资产 prompt 优先补到 `packages/shared/src/prompts/*.ts`
5. 业务模块只传入已经整理好的上下文字段,不在模块内部继续拼长文本。
6. 至少补一条该 prompt 的调用链测试或现有测试断言。
建议命名:
- system prompt`XXX_SYSTEM_PROMPT`
- repair prompt`buildXXXRepairPrompt`
- user prompt`buildXXXPrompt`
- 纯文本装配:`buildXXXPromptText`
## 5. 本轮范围与当前状态
本轮已经收口:
- Story
- Chat
- Quest
- Runtime Item
- Custom World 主编排
- Custom World Agent 草稿增补
- Custom World 编辑器角色 / 场景 / 场景 NPC 生成
- Character Asset
- Eight Anchor
- Scene Image
- 前端剧情 / 私聊 / 任务 / 物品 prompt 兼容层
- 编辑器与工具链 prompt 种子
当前状态:
- 正式业务 prompt 主源已经集中到 prompt 目录。
-`services/``tools/``components/` 下保留的相关文件主要是兼容层或调用方。
- 当前没有再发现需要优先继续抽离的大块业务 prompt 正文。
## 6. 验证方式
本轮调整后建议至少执行:
- `npm run check:encoding`
- `npm run server-node:test`
- `npm --prefix server-node run build`
本轮实测结果:
- `npm run check:encoding` 通过
- `npm --prefix server-node run build` 通过
- `npm run build` 通过
- `npm run server-node:test` 143 项全部通过

View File

@@ -4,6 +4,8 @@
## 文档列表
- [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md):冻结当前后端唯一落地口径,明确新功能以 `server-rs + Axum + SpacetimeDB` 为准,旧 `server-node` / Express / PostgreSQL 与 Go 方向只允许作为迁移参考。
- [API_SERVER_DEV_STACK_COLD_BUILD_TIMEOUT_FIX_2026-04-25.md](./API_SERVER_DEV_STACK_COLD_BUILD_TIMEOUT_FIX_2026-04-25.md):记录 `npm run dev:rust` 在 Windows 冷编译/链接阶段误把 `api-server` `/healthz` 等待判定为超时并杀掉 `cargo run` 的根因,以及将 SpacetimeDB 与 api-server 等待窗口拆分的脚本口径。
- [API_ERROR_DETAILS_MESSAGE_DISPLAY_FIX_2026-04-25.md](./API_ERROR_DETAILS_MESSAGE_DISPLAY_FIX_2026-04-25.md):记录统一 API envelope 错误展示优先读取 `error.details.message` 的修复口径,避免 Big Fish 发布校验等业务错误只显示通用“请求参数不合法”。
- [BIG_FISH_DIRECTION_TOUCH_CONTROL_2026-04-24.md](./BIG_FISH_DIRECTION_TOUCH_CONTROL_2026-04-24.md):记录大鱼吃小鱼从固定摇杆改为屏幕首触点方向控制,并要求本地直达局在未操作时保持对象运动。
- [RUST_WORKSPACE_DEFAULT_BUILD_SCOPE_FIX_2026-04-25.md](./RUST_WORKSPACE_DEFAULT_BUILD_SCOPE_FIX_2026-04-25.md):记录 `server-rs` 无参数 `cargo build` 链接 `spacetime-module` 失败的根因,并冻结默认只构建原生 `api-server`、模块产物继续走 `spacetime build` 的命令边界。
@@ -70,7 +72,7 @@
- [SPACETIMEDB_REFRESH_SESSION_TABLE_DESIGN_2026-04-21.md](./SPACETIMEDB_REFRESH_SESSION_TABLE_DESIGN_2026-04-21.md)`M2` 第三张会话表 `refresh_session` 的 cookie/hash 边界、轮换与吊销语义、索引与迁移规则。
- [SPACETIMEDB_AUTH_IDENTITY_TABLE_DESIGN_2026-04-21.md](./SPACETIMEDB_AUTH_IDENTITY_TABLE_DESIGN_2026-04-21.md)`M2` 第二张身份表 `auth_identity` 的 provider 范围、唯一约束、手机号/微信身份写入规则与迁移策略。
- [SPACETIMEDB_AUTH_USER_ACCOUNT_TABLE_DESIGN_2026-04-21.md](./SPACETIMEDB_AUTH_USER_ACCOUNT_TABLE_DESIGN_2026-04-21.md)`M2` 第一张身份主表 `user_account` 的职责边界、字段、唯一约束、状态迁移、旧 `users` 映射与落地约束。
- [SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md](./SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md):基于当前 Node 后端能力清单,设计用 `SpacetimeDB + Axum + 阿里云 OSS` 重写后端的目标架构、模块映射、数据分层、迁移顺序与验收标准。
- [SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md](./SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md):基于 Node 后端能力清单,设计用 `SpacetimeDB + Axum + 阿里云 OSS` 重写后端的目标架构、模块映射、数据分层、迁移顺序与验收标准。
- [M6_OSS_SERVER_UPLOAD_AND_STS_POLICY_2026-04-21.md](./M6_OSS_SERVER_UPLOAD_AND_STS_POLICY_2026-04-21.md):冻结 M6 剩余的 STS 与服务端上传 helper 落地口径,明确当前上传主链为服务器上传 OSSWeb 端只负责签名读下载。
- [M6_ASSET_METADATA_HASH_VERSION_AND_SPECIALIZED_TABLE_BOUNDARY_2026-04-22.md](./M6_ASSET_METADATA_HASH_VERSION_AND_SPECIALIZED_TABLE_BOUNDARY_2026-04-22.md):冻结 M6 第一批内容 hash、版本、manifest、asset job 与强业务资产表的 Stage 1 边界,明确当前使用 `asset_object + asset_entity_binding + OSS manifest + AiTaskService` 闭合,不重复新增表。
- [M6_LEGACY_GENERATED_PATH_OSS_READ_COMPAT_2026-04-22.md](./M6_LEGACY_GENERATED_PATH_OSS_READ_COMPAT_2026-04-22.md):冻结 M6 旧 `/generated-*` 路径到 OSS 私有读同源代理的兼容口径,保证旧前端仍能直接消费图片、视频、动作帧与 manifest。
@@ -93,13 +95,11 @@
- [M6_CHARACTER_ANIMATION_IMPORT_AND_TEMPLATE_STAGE1_2026-04-22.md](./M6_CHARACTER_ANIMATION_IMPORT_AND_TEMPLATE_STAGE1_2026-04-22.md):冻结 `M6` 第一批角色动作模板查询与参考视频导入从旧 Node 本地草稿写盘切到 Rust `OSS` 草稿对象的接口 contract、对象键规划与暂不确认 `asset_object` 的边界。
- [M6_CHARACTER_WORKFLOW_CACHE_OSS_STAGE1_2026-04-22.md](./M6_CHARACTER_WORKFLOW_CACHE_OSS_STAGE1_2026-04-22.md):冻结 `M6` 第一批角色资产工作流缓存从旧 Node 本地 `workflow-cache.json` 切到 Rust `OSS` JSON 草稿对象的读写 contract、字段归一化与暂不落正式资产表的边界。
- [M6_CHARACTER_VISUAL_ASSET_OSS_INTEGRATION_STAGE1_2026-04-22.md](./M6_CHARACTER_VISUAL_ASSET_OSS_INTEGRATION_STAGE1_2026-04-22.md):冻结 `M6` 第一批角色主形象 `generate / jobs / publish` 接口从旧本地 `public/generated-*` 真相切到 `OSS + asset_object + asset_entity_binding + AI task` 的最小闭环与兼容 contract。
- [M7_TEST_DEPLOY_CUTOVER_EXECUTION_PLAN_2026-04-22.md](./M7_TEST_DEPLOY_CUTOVER_EXECUTION_PLAN_2026-04-22.md):冻结 `M7` 联调、回归、部署、观测、双跑对比、灰度切流、回滚和 `spacetime-module` 结构收口的可执行方案。
- [M7_TEST_DEPLOY_CUTOVER_EXECUTION_PLAN_2026-04-22.md](./M7_TEST_DEPLOY_CUTOVER_EXECUTION_PLAN_2026-04-22.md):冻结 `M7` 联调、回归、部署、观测、Rust 主线灰度、回滚和 `spacetime-module` 结构收口的可执行方案。
- [M3_BROWSE_HISTORY_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md](./M3_BROWSE_HISTORY_AXUM_SPACETIMEDB_DESIGN_2026-04-21.md):冻结 `M3` 第二批 `browse history` 纵向切片的 `user_browse_history` 表、双路径 facade、宽松归一化、去重排序规则与测试策略。
- [ASSET_ENTITY_BINDING_REDUCER_DESIGN_2026-04-21.md](./ASSET_ENTITY_BINDING_REDUCER_DESIGN_2026-04-21.md):冻结已确认 `asset_object` 绑定到业务实体槽位的首版 reducer/procedure、通用 `asset_entity_binding` 表与 Axum facade。
- [FRONTEND_TO_BACKEND_MIGRATION_EXECUTION_PLAN_2026-04-21.md](./FRONTEND_TO_BACKEND_MIGRATION_EXECUTION_PLAN_2026-04-21.md)把鉴权、浏览历史、runtime story 快照、NPC 待接委托与正式生成编排继续后移到 Express 后端的实施方案与验收口径。
- [REPO_NOISE_CLEANUP_BASELINE_2026-04-19.md](./REPO_NOISE_CLEANUP_BASELINE_2026-04-19.md):落实工程清理审计第一阶段后的仓库噪音清理范围、忽略规则闭合点与后续约束。
- [ENCODING_CHECK_TRANSIENT_WORKSPACE_FIX_2026-04-22.md](./ENCODING_CHECK_TRANSIENT_WORKSPACE_FIX_2026-04-22.md):冻结编码检查不扫描临时 Cargo / verify 工作区、同时把 Rust 源文件纳入 UTF-8 校验的修复口径。
- [PROMPT_DIRECTORY_MANAGEMENT_2026-04-19.md](./PROMPT_DIRECTORY_MANAGEMENT_2026-04-19.md):后端提示词收口到 `server-node/src/prompts/` 的目录方案、兼容策略与后续新增规则。
- [CUSTOM_WORLD_DRAFT_GENERATION_FAILURE_ANALYSIS_AND_FIX_2026-04-20.md](./CUSTOM_WORLD_DRAFT_GENERATION_FAILURE_ANALYSIS_AND_FIX_2026-04-20.md):世界草稿生成失败后等待页误显示为“卡在编译草稿卡”的根因拆解、主链与增强链路边界,以及本次修复策略。
- [CUSTOM_WORLD_AUTO_ASSET_VISIBILITY_FIX_2026-04-20.md](./CUSTOM_WORLD_AUTO_ASSET_VISIBILITY_FIX_2026-04-20.md):世界草稿里“资产已生成但结果页看不到”的根因拆解,包含角色主形象展示、分幕背景露出和 fallback 资源格式修复。
- [CUSTOM_WORLD_PHASE4_COUNT_SEMANTICS_ALIGNMENT_2026-04-20.md](./CUSTOM_WORLD_PHASE4_COUNT_SEMANTICS_ALIGNMENT_2026-04-20.md)Phase4 新增角色/地点后草稿作品卡数量统计与测试断言的语义对齐说明。
@@ -149,13 +149,6 @@
- [CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md#93-工作包-c前端结果页与编辑器拆分](./CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md#93-%E5%B7%A5%E4%BD%9C%E5%8C%85-c%E5%89%8D%E7%AB%AF%E7%BB%93%E6%9E%9C%E9%A1%B5%E4%B8%8E%E7%BC%96%E8%BE%91%E5%99%A8%E6%8B%86%E5%88%86):记录工作包 C 已完成的结果页壳层拆分、编辑器目标分发与 mapper 收口、角色资产工坊 section/workflow 拆分,以及仍保留的阶段性 shared 实现边界。
- [CREATION_PAGE_MOBILE_UI_FIX_2026-04-21.md](./CREATION_PAGE_MOBILE_UI_FIX_2026-04-21.md):创作页移动端底部 Tab、亮色主题 token 与滚动权责修复记录。
- [TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md](./TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md):把外部仓库 TXT 模式完整迁入当前项目的冻结边界、模块映射、分阶段计划与验收清单。
- [NODE_BACKEND_MODULE_AND_API_INDEX.md](./NODE_BACKEND_MODULE_AND_API_INDEX.md):由 `server-node/src/manifest/backendCapabilityManifest.ts` 生成的 Node 后端模块职责、挂载面与接口索引,后续新增模块/接口时同步更新这一份。
- [NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md](./NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md):当前 Node 运行时后端的技术栈、入口、鉴权、存储与接口知识图谱。
- [EXPRESS_BACKEND_INTEGRATION_FREEZE_2026-04-09.md](./EXPRESS_BACKEND_INTEGRATION_FREEZE_2026-04-09.md)Express 后端当前 contract 冻结版本、热点文件编辑规则与集成窗口清单。
- [EXPRESS_BACKEND_WORKSTREAM_AUDIT_2026-04-09.md](./EXPRESS_BACKEND_WORKSTREAM_AUDIT_2026-04-09.md):按并行工作流文档逐项核对后的完成度审计与剩余收口点。
- [EDITOR_ASSET_API_MIGRATION_2026-04-08.md](./EDITOR_ASSET_API_MIGRATION_2026-04-08.md):编辑器写盘、资产生成、任务查询从 Vite 本地插件迁到 Node 后端的接口与工具链清单。
- [GO_SERVER_RUNTIME_INTEGRATION_2026-04-07.md](./GO_SERVER_RUNTIME_INTEGRATION_2026-04-07.md)Go 服务端接入、运行时持久化迁移与当前进展记录。
- [GO_SERVER_TASKLIST_2026-04-08.md](./GO_SERVER_TASKLIST_2026-04-08.md)Go 服务端已完成与未完成事项的执行清单。
- [AI_CHARACTER_ANIMATION_TECHNICAL_SOLUTION_2026-04-04.md](./AI_CHARACTER_ANIMATION_TECHNICAL_SOLUTION_2026-04-04.md)AI 生成角色形象与角色动画的技术路线。
- [ALIYUN_NPC_IMAGE_ANIMATION_EXPERIMENT_2026-04-07.md](./ALIYUN_NPC_IMAGE_ANIMATION_EXPERIMENT_2026-04-07.md):面向编辑器的阿里云 NPC 形象与动作实验方案,按 4 条生成链路对比。
- [PIXELMOTION_TECHNICAL_BREAKDOWN_2026-04-04.md](./PIXELMOTION_TECHNICAL_BREAKDOWN_2026-04-04.md)PixelMotion 产品形态与能力拆解。
@@ -164,6 +157,5 @@
## 使用建议
- 做实现选型时,优先看这一组。
- 做后端实现前,先看 `CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`,再进入具体 Rust / SpacetimeDB 方案。
- 做阶段排期时,把这一组和 `docs/planning/``docs/prd/` 一起看,更容易判断先后顺序。

View File

@@ -44,8 +44,7 @@
2. `docs/design/SCENE_CHAPTER_LOOP_AND_FIRST_ENTRY_CHAPTER_QUEST_DESIGN_2026-04-08.md`
3. `docs/experience/CURRENT_GAME_FULL_FLOW_PLAYTEST_REPORT_2026-04-07.md`
4. `docs/technical/RUNTIME_STORY_BACKEND_BOUNDARY_MIGRATION_2026-04-19.md`
5. `docs/technical/FRONTEND_TO_BACKEND_MIGRATION_EXECUTION_PLAN_2026-04-21.md`
6. `docs/technical/NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md`
5. `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
### 1.3 本文刻意不覆盖的链路

View File

@@ -0,0 +1,56 @@
# Runtime NPC 聊天 LLM 迁移设计2026-04-25
## 背景
当前 `server-rs/crates/api-server/src/runtime_chat.rs` 已承接 `POST /api/runtime/chat/npc/turn/stream`但只返回确定性兜底文本。实际游戏聊天里NPC 回复、下一轮建议、好感变化和限轮收束都应该沿用旧 Node 服务器的 LLM 编排。
## 迁移源
本轮只参考旧 Node 已冻结实现,不恢复 `server-node` 服务,也不把前端切回 Express
1. `server-node/src/prompts/chatPromptBuilders.ts`
2. `server-node/src/modules/ai/chatOrchestrator.ts`
3. `server-node/src/services/chatService.ts`
4. `packages/shared/src/contracts/rpgRuntimeChat.ts`
提示词常量必须原样迁移,禁止改写:
1. `NPC_CHAT_TURN_REPLY_SYSTEM_PROMPT`
2. `NPC_CHAT_TURN_SUGGESTION_SYSTEM_PROMPT`
## 本轮落地边界
1. Rust `api-server` 在同一路由内优先调用 `platform-llm`
2. LLM 回复使用旧 Node 的 `buildNpcChatTurnReplyPrompt(...)` 等价构造逻辑,保持输入字段和中文上下文组织一致。
3. LLM 建议使用旧 Node 的 `buildNpcChatTurnSuggestionPrompt(...)` 等价构造逻辑,解析规则保持“最多 3 行、去掉编号/项目符号”。
4. 好感变化沿用旧 Node 的关键词打分规则:
- 正向与负向关键词计分。
- 首聊无明显关键词时给 `+1`
- 单轮变化限制在 `[-3, 3]`
5. `chatDirective.forceExitAfterTurn / closingMode=foreshadow_close` 时不生成建议,返回空数组,并在 `complete.chatDirective.forceExit` 中显式告知前端退出。
6. LLM 未配置或失败时继续返回后端兜底 SSE保证相遇和点击聊天链路不断。
## 暂不落地
1. 暂不迁移 `maybeBuildPendingNpcQuestOffer(...)` 的完整 quest 生成链。
2. 暂不新增 SpacetimeDB reducer本路由属于 Axum 侧 LLM 编排SpacetimeDB reducer 仍保持确定性。
3. 暂不扩展前端 UI 文案。
## 工程落点
1. 新增 `server-rs/crates/api-server/src/runtime_chat_prompt.rs`
- 承载旧 Node 提示词常量。
- 承载 NPC 聊天 prompt builder 与轻量 JSON 读取 helper。
2. 修改 `server-rs/crates/api-server/src/runtime_chat.rs`
- 注入 `State<AppState>`
- 优先 `LlmClient.stream_text(...)` 生成 `reply_delta`
- 再调用 `request_text(...)` 生成建议。
- 计算 `affinityDelta / affinityText / chatDirective` 后输出 `complete`
3. 修改 `server-rs/crates/api-server/src/main.rs`
- 注册 `runtime_chat_prompt` 模块。
## 验收
1. `cargo fmt -p api-server`
2. `cargo check -p api-server`
3. `node scripts/check-encoding.mjs docs/technical/RUNTIME_NPC_CHAT_LLM_MIGRATION_2026-04-25.md server-rs/crates/api-server/src/runtime_chat.rs server-rs/crates/api-server/src/runtime_chat_prompt.rs server-rs/crates/api-server/src/main.rs`

View File

@@ -163,6 +163,6 @@
## 4. 维护规则
1. 新增、删除或改名 Rust 路由时,必须同步更新本索引。
2. 如果 Node 后端 `NODE_BACKEND_MODULE_AND_API_INDEX.md` 的现役能力面发生变化,必须同时更新本索引与对应阶段任务清单。
2. 如果 Rust 后端公开能力面发生变化,必须同时更新本索引、当前后端实现基线与对应阶段任务清单。
3. 任何 breaking route change 都必须先更新阶段设计文档,再改代码。
4. 真实切流前,必须用本索引对照代理层、前端调用面和 smoke 清单,避免只完成编译而遗漏外部可访问路径。

View File

@@ -38,7 +38,7 @@ npm run dev:rust
5. 执行 `spacetime --root-dir=server-rs/.spacetimedb/local publish <本地数据库名> --server http://127.0.0.1:3101 --module-path server-rs/crates/spacetime-module -c=on-conflict --yes`,确保 publish 的签名身份与 standalone 的本地控制库一致,并在当前开发阶段允许新版模块表结构变化且发生 schema 冲突时清除旧模块数据。
6. 注入 `GENARRATIVE_API_*``GENARRATIVE_SPACETIME_*` 后启动 `cargo run -p api-server`;直接运行 `api-server` 时,如未显式设置 `GENARRATIVE_SPACETIME_DATABASE`,服务端也会向上查找 `spacetime.local.json` 作为本地默认库名。
7. 等待 `http://127.0.0.1:<api-port>/healthz` 返回 HTTP 响应后再启动 Vite避免前端初始化请求早于 Rust `api-server` 监听完成并在终端刷出 `ECONNREFUSED 127.0.0.1:<api-port>`
8. 注入 `GENARRATIVE_BACKEND_STACK=rust``RUST_SERVER_TARGET``GENARRATIVE_RUNTIME_SERVER_TARGET` 后启动 Vite。
8. 注入 `RUST_SERVER_TARGET``GENARRATIVE_RUNTIME_SERVER_TARGET` 后启动 Vite。
9. 任一子进程退出时,脚本回收其余子进程。
Vite 代理覆盖范围:

View File

@@ -30,7 +30,7 @@
### 3.1 启动前强制 publish
`scripts/dev-node.mjs` 在拉起 Rust `api-server` 前,必须先执行:
`scripts/dev-rust-stack.sh` 在拉起 Rust `api-server` 前,必须先执行:
```bash
spacetime publish xushi-p4wfr --server http://127.0.0.1:3101 --module-path D:\Genarrative\server-rs\crates\spacetime-module --yes

View File

@@ -9,7 +9,7 @@
关联现状:
- [EXPRESS_BACKEND_INTEGRATION_FREEZE_2026-04-09.md](./EXPRESS_BACKEND_INTEGRATION_FREEZE_2026-04-09.md)
- [CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md](./CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md)
- [AUTH_LOGIN_OPTIONS_DESIGN_2026-04-21.md](./AUTH_LOGIN_OPTIONS_DESIGN_2026-04-21.md)
- [AUTH_ME_QUERY_DESIGN_2026-04-21.md](./AUTH_ME_QUERY_DESIGN_2026-04-21.md)
- [AUTH_SESSIONS_QUERY_DESIGN_2026-04-21.md](./AUTH_SESSIONS_QUERY_DESIGN_2026-04-21.md)

View File

@@ -59,7 +59,7 @@
- 浏览器直连会遇到 CORS
- 更稳的方案是开发服务器代理,再由前端请求 `/api/llm/...`
[docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-03-29.md](/E:/Repos/Genarrative/docs/audits/engineering/ENGINEERING_OPTIMIZATION_REVIEW_2026-03-29.md) 也明确指出:
工程审计聚合结论也明确指出:
- 编辑器、运行时、类后端能力全部耦合在 Vite 配置里
- 未来如果做独立部署、多人协作、远程编辑、权限控制,会非常难迁移

View File

@@ -171,5 +171,5 @@
1. [SPACETIMEDB_ASSET_OBJECT_STORAGE_DESIGN_2026-04-21.md](./SPACETIMEDB_ASSET_OBJECT_STORAGE_DESIGN_2026-04-21.md)
2. [SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md](./SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md)
3. [../../../server-rs/crates/module-assets/README.md](../../../server-rs/crates/module-assets/README.md)
4. [../../../server-rs/crates/spacetime-module/README.md](../../../server-rs/crates/spacetime-module/README.md)
3. [../../server-rs/crates/module-assets/README.md](../../server-rs/crates/module-assets/README.md)
4. [../../server-rs/crates/spacetime-module/README.md](../../server-rs/crates/spacetime-module/README.md)

View File

@@ -17,7 +17,7 @@
## 2. 当前工程必须继承的能力基线
`docs/technical/NODE_BACKEND_MODULE_AND_API_INDEX.md` 当前生成结果为准,现有 Node 后端的能力基线是:
以下能力清单来自 `2026-04-20` 迁移设计时对旧 Node 后端的快照整理,只作为迁移参考,不再作为新功能扩展依据。后续实现方向`docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md` 为准。
- 对外挂载面:`6`
- 已登记路由:`96`
@@ -228,10 +228,10 @@ SpacetimeDB 官方文档对自动迁移的限制很强:
从当前版本开始,凡是涉及 `SpacetimeDB` 的设计、实现、脚本、调试与前端接入,统一要求显式使用以下 skill 作为执行依据:
1. [$spacetimedb-cli](.codex\\skills\\spacetimedb-cli\\SKILL.md)
2. [$spacetimedb-rust](.codex\\skills\\spacetimedb-rust\\SKILL.md)
3. [$spacetimedb-concepts](.codex\\skills\\spacetimedb-concepts\\SKILL.md)
4. [$spacetimedb-typescript](.codex\\skills\\spacetimedb-typescript\\SKILL.md)
1. [$spacetimedb-cli](../../.codex/skills/spacetimedb-cli/SKILL.md)
2. [$spacetimedb-rust](../../.codex/skills/spacetimedb-rust/SKILL.md)
3. [$spacetimedb-concepts](../../.codex/skills/spacetimedb-concepts/SKILL.md)
4. [$spacetimedb-typescript](../../.codex/skills/spacetimedb-typescript/SKILL.md)
执行要求:
@@ -895,8 +895,8 @@ SpacetimeDB 自动迁移更适合“增量追加”,不适合高频改列结
5. `server-node/src/modules/story/storyActionRoutes.ts`
6. `server-node/src/repositories/runtimeRepository.ts`
7. `server-node/src/services/customWorldAgentOrchestrator.ts`
8. `docs/technical/NODE_BACKEND_MODULE_AND_API_INDEX.md`
9. `docs/technical/NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md`
8. 本文第 2 节保留的旧 Node 能力快照
9. `docs/technical/CURRENT_BACKEND_IMPLEMENTATION_BASELINE_2026-04-25.md`
## 17. 外部技术依据

View File

@@ -872,9 +872,9 @@ TXT 模式不得直接改坏当前 `runtime story` 主链。
## 10.3 与 prompt 管理规范兼容
必须遵守 [PROMPT_DIRECTORY_MANAGEMENT_2026-04-19.md](./PROMPT_DIRECTORY_MANAGEMENT_2026-04-19.md) 中已冻结的规则
必须遵守当前 Rust 后端提示词迁移口径
1. prompt 主源收口到 `server-node/src/prompts/`
1. prompt 主源收口到 `server-rs` 对应生成与编排模块
2. 业务模块只装配上下文
3. 兼容层按需保留,但不新增业务内联 prompt