Merge remote-tracking branch 'origin/master' into codex/publish-flow
Some checks failed
CI / verify (pull_request) Has been cancelled

# Conflicts:
#	docs/technical/JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md
#	docs/technical/README.md
#	jenkins/Jenkinsfile.database-export
#	jenkins/Jenkinsfile.database-import
This commit is contained in:
2026-05-03 03:46:39 +08:00
1041 changed files with 53757 additions and 49983 deletions

View File

@@ -44,8 +44,8 @@ spacetime generate --lang typescript|csharp|rust|unrealcpp --out-dir ./bindings
### Publishing & Deployment
```bash
# Publish to Maincloud (default)
spacetime publish my-database --yes
# Publish to an explicit server
spacetime publish my-database --server http://127.0.0.1:3101 --yes
# Publish to local server
spacetime publish my-database --server local --yes
@@ -133,8 +133,8 @@ spacetime logout
| Name | URL | Description |
|------|-----|-------------|
| `maincloud` | `https://maincloud.spacetimedb.com` | Production cloud (default) |
| `local` | `http://127.0.0.1:3000` | Local development server |
| `dev` | `http://127.0.0.1:3101` | Genarrative local development server |
## Common Workflows
@@ -224,6 +224,6 @@ rustup target add wasm32-unknown-unknown
## Notes
- Many commands are marked UNSTABLE and may change
- Default server is `maincloud` unless configured otherwise
- Genarrative scripts should pass `--server` or `--server-url` explicitly instead of relying on the CLI default
- Use `--yes` flag in scripts to avoid interactive prompts
- Dev mode watches files and auto-rebuilds on changes

View File

@@ -119,6 +119,11 @@ RPG_LLM_WEB_SEARCH_ENABLED="true"
DASHSCOPE_BASE_URL="https://dashscope.aliyuncs.com/api/v1"
DASHSCOPE_API_KEY="YOUR_DASHSCOPE_API_KEY"
# Server-side APIMart image generation config for optional puzzle image models.
APIMART_BASE_URL="https://api.apimart.ai/v1"
APIMART_API_KEY="YOUR_APIMART_API_KEY"
APIMART_IMAGE_REQUEST_TIMEOUT_MS="180000"
# 阿里云 OSS 配置。
# Rust `server-rs` 的 `api-server` 会优先从 `.env` / `.env.local` 读取这些变量,
# 用于签发浏览器 PostObject 直传票据,并保持 `/generated-*` 旧路径习惯。

View File

@@ -54,11 +54,7 @@ GENARRATIVE_SPACETIME_SERVER_URL="http://127.0.0.1:3101"
GENARRATIVE_SPACETIME_DATABASE="xushi-p4wfr"
GENARRATIVE_SPACETIME_TOKEN=""
GENARRATIVE_SPACETIME_MAINCLOUD_SERVER_URL="https://maincloud.spacetimedb.com"
GENARRATIVE_SPACETIME_MAINCLOUD_DATABASE="xushi-p4wfr"
GENARRATIVE_SPACETIME_MAINCLOUD_TOKEN=""
# admin
GENARRATIVE_ADMIN_USERNAME=admin
GENARRATIVE_ADMIN_PASSWORD=123456
ADMIN_API_TARGET=http://127.0.0.1:8082
ADMIN_API_TARGET=http://127.0.0.1:8082

1
.gitignore vendored
View File

@@ -29,3 +29,4 @@ temp*build*/
/public/generated-characters
/.codex-temp
/target/
/logs

View File

@@ -1,7 +1,6 @@
# AGENTS.md
## 项目约束
- 在修改server-rs的内容时不要去兼容server-node中的任何内容只允许参考以及把server-node中未迁移到server-rs的内容迁移过来
- 代码需要有完善的中文注释
- 在落地工程修改前检查是否有详细指导本次落地的文档,若没有文档或文档的完善程度仍有落地过程中编码级别的歧义优先优化文档后落地工程迭代。
- 对工程的修改不仅要落地到代码更面还要更改对应文档若没有生成新的文档文档统一存在doc目录中
@@ -14,13 +13,20 @@
- UI设计需要兼顾网页端、移动端双端的使用体验确保在不同设备上都能正常显示和操作移动端优先考虑。
- 不要在gitignore中添加.env.local文件。
- 严格遵循简洁的代码风格
- 前端只负责做表现所有的逻辑、数据都放到后端工程后端使用server-rs中用Rust+spacetimeDB的方案实现禁止继续使用server-nodeExpress和postgreSQL
- 后端采用多crate设计
- 请默认保持系统的简洁性,能复用、修改、扩展现有系统、页面就不新建新系统新页面。
- 禁止将功能说明描述类的文本默认写入UI界面中。
- prd文档中每个模块的描述要落地设计到可以精准编码到位不能出现需求落地漂移。
- 点击按钮弹出独立的面板的设计不要实现成在当前面板下面显示内容。
- 每个阶段任务完成后自动压缩上下文,确保后续阶段在清晰、低噪音的上下文基础上继续推进。
## 后端技术约束
- 后端最新技术约束以 [`docs/technical/SERVER_RS_DDD_FULL_REFACTOR_2026-04-28.md`](docs/technical/SERVER_RS_DDD_FULL_REFACTOR_2026-04-28.md) 为总纲;执行和收口状态以 [`docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md`](docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md) 为准。
- 契约、路由、DTO 去留和 breaking change 以 [`docs/technical/SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md`](docs/technical/SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md) 为准;不得在前端、`api-server` 或临时兼容层中重新发明旧接口。
- SpacetimeDB 表结构、自动迁移限制和冲突处理以 [`docs/technical/SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md`](docs/technical/SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md) 为准;涉及 table、reducer、procedure、row shape 或绑定变化时,必须同步 `migration.rs`、表目录和生成绑定。
- 后端路线固定为 `server-rs + Axum + SpacetimeDB`。旧 `server-node`、Express、PostgreSQL 不再作为兼容目标;历史实现只能作为迁移参考,若旧文档与 DDD 约束冲突,先修正文档和方案再编码。
- DDD 分层边界按总纲执行:领域规则沉到 `module-*`SpacetimeDB 表和事务编排留在 `spacetime-module`,后端访问 SpacetimeDB 统一经 `spacetime-client` facadeHTTP/SSE/BFF 留在 `api-server`,外部副作用留在 `platform-*`,前后端 DTO 留在 `shared-contracts`
- 前端只做表现、交互和临时 UI 状态,不承接正式业务真相,不绕过后端投影或后端 API 直接实现业务规则。
- 修改后端代码后,按对应 DDD 文档中的验收命令执行测试;涉及 API smoke 时使用 `npm run api-server` 重新拉起后端并执行相应自动测试,同时确认 `/healthz`
- 凡是涉及 SpacetimeDB 的设计、实现、脚本、调试、前端绑定接入,统一显式使用以下 skill 作为执行依据:
- [$spacetimedb-cli](.codex\\skills\\spacetimedb-cli\\SKILL.md)
- [$spacetimedb-rust](.codex\\skills\\spacetimedb-rust\\SKILL.md)
@@ -30,7 +36,7 @@
- 涉及 `crates/spacetime-module` 的表、reducer、view、Rust API 使用时,按 `spacetimedb-rust``spacetimedb-concepts` 执行。
- 涉及前端或 Node 侧的 SpacetimeDB TypeScript SDK、订阅、绑定使用时`spacetimedb-typescript``spacetimedb-concepts` 执行。
- 若仓库内旧实现或旧文档与这些 skill 冲突,先修正文档和方案,再继续编码。
- 修改后端代码后,必须使用 `npm run api-server:maincloud` 自动重新运行后端,并执行相应自动测试;不要再使用旧的后端重启命令。
- 修改后端代码后,必须使用 `npm run api-server` 自动重新运行后端,并执行相应自动测试;不要再使用旧的后端重启命令。
- 数据库表结构更改后需要对齐migration.rs
## 文档图谱

77
PLAN.md Normal file
View File

@@ -0,0 +1,77 @@
# server-rs DDD 一次性重构方案
## Summary
当前仓库已不再存在 `server-node`,本次只针对现有 `server-rs` 做一次性 DDD 化。
目标是把 Rust + SpacetimeDB 后端统一成清晰边界:领域规则在 `module-*`,事务和持久化在 `spacetime-module`HTTP/BFF 在 `api-server`,外部能力在 `platform-*`,共享值处理和 DTO 分别在 `shared-kernel` / `shared-contracts`
全局并行执行任务清单见 `docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md`。runtime story 去兼容层属于该清单中的 `WP-RS` 工作包,不再单独维护专项清单。
## Target Architecture
- `module-*`:领域模型、值对象、聚合方法、领域服务、命令、领域错误、领域事件、纯应用编排结果;禁止直接依赖 Axum、reqwest、OSS、LLM、文件系统、SpacetimeDB table 操作。
- `spacetime-module`SpacetimeDB adapter只保留 table、reducer、procedure、row/snapshot mapper、事务内查询写回、event table核心规则必须调用 `module-*`
- `api-server`HTTP/BFF adapter只保留路由、鉴权上下文、请求响应映射、SSE、SpacetimeDB client 调用、平台服务调用。
- `platform-*`JWT/SMS/微信/OSS/LLM/HTTP client 等外部能力实现。
- `shared-kernel`:跨领域纯值处理;`shared-contracts`HTTP/前端契约 DTO。
## Required Refactor
- 为所有业务上下文统一目录:
- `domain.rs``domain/*`:聚合、值对象、领域方法。
- `commands.rs`:写入用例输入。
- `application.rs`:用例处理函数。
- `events.rs`:领域事件与跨上下文事件。
- `errors.rs`:领域错误。
- `mapper.rs` 仅允许出现在 adapter crate。
- 一次性处理混合边界:
- `module-auth` 拆出认证、会话、验证码、微信绑定领域;内存 store / 文件持久化移出领域核心。
- `module-assets` 拆出资产对象确认规则OSS head、reqwest、fallback store 移出领域核心。
- `spacetime-module` 全量拆分 table、reducer/procedure、mapper、跨上下文事务编排。
- `api-server` 中 handler 只保留 transport 逻辑,业务分支迁移到领域或应用层。
- `runtime_story``custom_world``puzzle``big_fish``inventory``quest``npc``combat``progression` 全部对齐同一结构。
- 去兼容层任务边界:
- `module-runtime-story-compat` 不作为目标架构保留,迁移为无 `compat` 命名的 `module-runtime-story` 或拆入对应领域模块。
- `api-server/src/runtime_story/compat*` 只允许作为待删除历史入口,不再新增兼容分支。
- 前端 runtime story / chat client 统一改到 `POST /api/runtime/story/sessions/:sessionId/...` 新接口族。
- 旧请求体里的 `worldType / character / monsters / history / context` 不再作为正式主链输入。
- 表结构硬约束:
- 默认保持现有 SpacetimeDB 主表兼容。
- 表结构变更采用最小必要原则。
- 只有为修正聚合边界、读写分离、事件化、查询索引或生命周期独立性不可避免时,才新增或调整表。
- 优先新增 optional 字段、投影表、事件表,不做破坏性 rename/delete/type change。
- 任何 table 变更必须同步 `migration.rs`、SpacetimeDB 表目录、相关 reducer/procedure 测试。
- 统一跨上下文协作:
- 单聚合内部变化由聚合方法完成。
- 跨聚合流程由应用服务或 SpacetimeDB 事务 adapter 编排。
- 战斗奖励、任务奖励、成长记账、画廊投影、agent 操作进度等副作用必须显式表达为事件或应用结果。
- 统一查询策略:
- 写模型不复用给复杂查询。
- 每个前端场景有独立 query/result DTO。
- SpacetimeDB private table 默认不暴露public table 只服务明确订阅读模型。
## Documentation
- 新增 `docs/technical/SERVER_RS_DDD_FULL_REFACTOR_2026-04-28.md`,写清 DDD 规则、依赖方向、crate 职责矩阵、每个上下文的聚合/命令/事件/读模型、SpacetimeDB adapter 映射、表结构变更约束。
- 更新现有后端基线、SpacetimeDB 表目录、API 路由索引、相关模块技术文档。
- 表结构或 reducer/procedure 变化同步 `migration.rs`
## Acceptance Criteria
- `server-rs` 所有业务模块通过统一 DDD 目录和依赖边界检查。
- `spacetime-module/src/lib.rs` 不再承载大段业务流程,拆到上下文 adapter。
- 默认不破坏现有 SpacetimeDB 主表确需改表时有文档、migration 和测试。
- 所有领域规则都有纯 Rust 单元测试。
- 所有 reducer/procedure 有事务适配测试或最小 smoke。
- HTTP contract shape 不发生未记录 breaking change。
- 执行并通过:
- `cargo test --workspace --manifest-path server-rs/Cargo.toml`
- `cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml`
- `npm run api-server:maincloud`
- 仓库编码检查

View File

@@ -15,6 +15,8 @@
生产部署切换到 systemd + Nginx + SpacetimeDB 自托管的总方案见 [PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md](./technical/PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md),该文档也是当前生产 Jenkinsfile 的唯一入口。SpacetimeDB 表结构变更、自动迁移边界和保留旧数据的分阶段迁移流程见 [SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md](./technical/SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md)private 表迁移 JSON 导入导出、HTTP 413 分片导入和旧数据库迁移流水线经验见 [SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md](./technical/SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md) 与 [JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md](./technical/JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md);后台管理独立前端工程技术方案见 [ADMIN_WEB_CONSOLE_TECHNICAL_SOLUTION_2026-04-30.md](./technical/ADMIN_WEB_CONSOLE_TECHNICAL_SOLUTION_2026-04-30.md)。
SpacetimeDB 表结构变更、自动迁移边界和保留旧数据的分阶段迁移流程见 [SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md](./technical/SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md)。
## 推荐阅读顺序
1. 先看 [经验沉淀](./experience/README.md),快速建立这个项目的开发共识。

View File

@@ -628,7 +628,7 @@ SpacetimeDB 方向:
4. LLM、OSS、图片生成等外部 I/O 放在 `api-server` / `platform-*` crate 中,再把确定结果写回 SpacetimeDB。
5. 前端调用 reducer 使用生成绑定和对象参数,不编辑生成代码。
6. 涉及表结构修改时同步更新 `migration.rs`
7. 修改后端代码后统一执行 `npm run api-server:maincloud`,并跑对应自动测试。
7. 修改后端代码后统一执行 `npm run api-server`,并跑对应自动测试。
## 9. 最小验收标准

View File

@@ -109,7 +109,7 @@
1. `package.json` 中不存在 `server-node:*``dev:node``m7:api-compare``check:server-node-freeze` 等旧入口。
2. `scripts/` 下不存在 `dev-node.mjs``smoke-server-node.ts``m7-api-compare.ts``smoke-same-origin-stack.ts` 等旧 Node 后端脚本。
3. `package.json``package-lock.json` 中不存在 `express``@types/express``pg``postgres` 依赖。
4. 当前开发入口继续固定为 `npm run dev``npm run dev:web``npm run api-server:maincloud` 与 Rust / SpacetimeDB 相关脚本,不恢复旧 Node 后端切换开关。
4. 当前开发入口继续固定为 `npm run dev``npm run dev:web``npm run api-server` 与 Rust / SpacetimeDB 相关脚本,不恢复旧 Node 后端切换开关。
## 9. Caddy 本地服务入口移除2026-04-26

View File

@@ -255,14 +255,14 @@ node scripts/vite-cli.mjs --port=3000 --host=0.0.0.0
后端代码更新后统一执行:
```bash
npm run api-server:maincloud
npm run api-server
```
执行要求:
- 该命令是后端更新后的默认重启入口,不再使用此前的后端重启命令。
- 重启后必须继续执行与本次后端改动对应的自动测试;涉及 Rust workspace 时优先跑 `server-rs` 下的检查或测试脚本。
- 若本次改动涉及 SpacetimeDB 发布、绑定生成或 Maincloud 联调,按 `spacetimedb-cli` 经验执行,并在验证记录中写清楚实际命令与结果。
- 若本次改动涉及 SpacetimeDB 发布、绑定生成或本地联调,按 `spacetimedb-cli` 经验执行,并在验证记录中写清楚实际命令与结果。
## 14. 一句话总结

View File

@@ -493,12 +493,15 @@ interface CustomWorldCoverProfile {
第一版必须有:
1. `进入世界`
2. `删除作品`
可选:
1. `查看作品`
2. `基于此作品继续创作`
`删除作品` 必须放在已发布卡片主操作的左侧,并在创作页内弹出二次确认面板后再执行删除。
第一版不强制做“基于已发布作品继续创作”,避免先把发布后再开草稿链带复杂。
---
@@ -884,7 +887,7 @@ type SelectionStage =
1. 不做完整 Agent 工作区
2. 不做世界底稿生成
3. 不做作品删除确认流
3. 不做独立的作品删除管理后台,删除确认统一收口在创作页内完成
4. 不做作品搜索排序高级功能
5. 不做发布世界管理后台
6. 不做已发布作品的二次派生创作
@@ -901,9 +904,10 @@ type SelectionStage =
2. 创作页面能同时展示草稿和已发布作品。
3. 草稿作品可以继续创作。
4. 已发布作品可以进入世界。
5. 新建作品入口可以正确创建 Agent session 并跳转到创作工作区
6. 页面在移动端首屏可用,信息层级清楚
7. 草稿与已发布作品都通过后端聚合接口返回,前端不自己拼数据来源
5. 已发布作品卡的删除按钮位于主操作左侧,点击后先弹出创作页内的二次确认面板
6. 新建作品入口可以正确创建 Agent session 并跳转到创作工作区
7. 页面在移动端首屏可用,信息层级清楚
8. 草稿与已发布作品都通过后端聚合接口返回,前端不自己拼数据来源。
---

View File

@@ -753,7 +753,7 @@ RPG 运行时链:
这些脚本不直接参与玩法,但直接支撑开发、发布、绑定和检查:
### `scripts/api-server-maincloud.mjs`
### `scripts/api-server-dev.mjs`
职责:

View File

@@ -259,7 +259,7 @@ export interface ProfileInviteCodeAdminResponse {
`tableStats` 中单表失败必须展示 `errorMessage`不能让整页变成空白。SpacetimeDB private 表或当前身份不可见的表在 `/sql` 下可能返回 `no such table` / `marked private`后台服务必须将这类错误归一为“不可统计private 或当前身份不可见)”,避免把预期的访问边界展示成原始 HTTP 400 故障。
线上如果大量表都显示“不可统计private 或当前身份不可见)”,优先检查 `api-server` 启动环境中的 `GENARRATIVE_SPACETIME_TOKEN` / `GENARRATIVE_SPACETIME_MAINCLOUD_TOKEN` 是否存在且属于目标库 owner。Jenkins 覆盖发布包时必须保留部署目录已有运行 token只带迁移 token 不能让后台概览读取 private 表。
线上如果大量表都显示“不可统计private 或当前身份不可见)”,优先检查 `api-server` 启动环境中的 `GENARRATIVE_SPACETIME_TOKEN` 是否存在且属于目标库 owner。Jenkins 覆盖发布包时必须保留部署目录已有运行 token只带迁移 token 不能让后台概览读取 private 表。
### 4.6 API 调试 contract
@@ -380,7 +380,7 @@ export interface ProfileInviteCodeAdminResponse {
### 7.1 本地联调
1. 启动后端:`npm run api-server:maincloud`
1. 启动后端:`npm run api-server`
2. 启动后台前端:在 `apps/admin-web` 执行 `npm run dev`
3. 后台 dev server 通过 Vite proxy 转发 `/admin/api``ADMIN_API_TARGET`;未配置时默认 `http://127.0.0.1:3100`
4. 若使用非 3100 端口,在仓库根目录 `.env.local` 设置 `ADMIN_API_TARGET=http://127.0.0.1:<api-server-port>`,并重启后台前端 dev server。
@@ -437,7 +437,7 @@ export interface ProfileInviteCodeAdminResponse {
- 后续接入根 workspace 后,补充后台工程 build/typecheck 脚本。
3. 后端:
- 继续保留 `cargo test -p api-server --manifest-path server-rs/Cargo.toml admin`
- 修改后端管理 API 后必须运行 `npm run api-server:maincloud` 并手动验证 `/admin` 为 404、`/admin/api/login` 可用。
- 修改后端管理 API 后必须运行 `npm run api-server` 并手动验证 `/admin` 为 404、`/admin/api/login` 可用。
## 9. 后续扩展边界

View File

@@ -0,0 +1,66 @@
# api-server 合并后编译修复记录
日期:`2026-05-02`
## 背景
`codex/ddd` 合入 `master` 后,`api-server` 编译失败。问题集中在合并后的跨 crate 契约缺口:`api-server` 已引用新接口或新字段,但对应的领域 crate 与 HTTP 转接层没有同步补齐。
## 修复范围
1. `module-auth` 补齐个人资料更新契约:
- 新增 `UpdateProfileInput``UpdateProfileResult`
- `AuthUser` 增加 `avatar_url``created_at`,并通过 `serde(default)` 兼容旧认证快照。
- `PasswordEntryService::update_profile` 统一校验昵称与头像 data URL并写回认证快照。
2. 微信绑定手机号结果补齐 `activated_new_user`
- 待绑定微信账号绑定新手机号时返回 `true`,用于注册奖励发放。
- 待绑定微信账号合并到已有手机号账号时返回 `false`
3. 拼图运行态补齐 HTTP 转接:
- `POST /api/runtime/puzzle/runs/{run_id}/drag` 读取 `DragPuzzlePieceRequest`
- 转发到 SpacetimeDB client 的 `drag_puzzle_piece_or_group` procedure 包装。
4. runtime story 聊天接口改用当前 shared contract
-`runtime_story::RuntimeStorySnapshotPayload` 已删除。
- `api-server` 侧临时别名到 `story::StoryRuntimeSnapshotPayload`,保持现有请求结构不漂移。
5. `api-server` 全量测试修复:
- `custom_world_foundation_draft` 的 mock LLM 响应仍是旧 Chat Completions 结构。
- 当前 `LlmClient` 默认走 Responses API测试 mock 已改为 `output[].content[].text` 结构。
6. 前端全量测试期望补齐:
- 自定义世界结果页的第二幕场景预览断言改为校验第二幕生成图。
- 拼图下一关交互测试保留后端下一关调用断言,并明确只调用一次。
- 拼图正式 run 客户端补回 `/drag` 调用包装,测试 mock 同步走正式 run 的 `swap/drag` 服务路径。
7. 前端门禁合并缺口修复:
- 拼图测试运行前更新作品时同步提交 `levels`,对齐当前 `updatePuzzleWork` 契约。
- 大鱼和 Match3D 测试 mock 对齐当前共享契约,避免 typecheck 阻塞。
- 移除 Vite dev proxy 中重复的 `/api/creation` key避免 build gate 将 warning 视为失败。
## 验证
本次修复应至少通过:
```powershell
cargo check -p module-auth --manifest-path server-rs\Cargo.toml
cargo check -p api-server --manifest-path server-rs\Cargo.toml
cargo test -p module-auth --manifest-path server-rs\Cargo.toml
cargo test -p api-server --manifest-path server-rs\Cargo.toml
npm run check:encoding
npm test
npm run typecheck
npm run build
npm run check:content
```
后端代码变更后,按项目约束还需要用 `npm run api-server:maincloud` 做一次启动验证。
本轮最终结果:
- `cargo test -p module-auth --manifest-path server-rs\Cargo.toml` 已通过,结果为 `17 passed; 0 failed`
- `cargo test -p api-server --manifest-path server-rs\Cargo.toml` 已通过,结果为 `237 passed; 0 failed; 4 ignored`
- `cargo test --manifest-path server-rs\Cargo.toml` 已通过,结果同 `api-server` 默认测试。
- `npm test` 已通过,结果为 `160 passed` 个测试文件、`704 passed` 个用例。
- `npm run typecheck``npm run build``npm run check:content``npm run check:encoding``git diff --check` 已通过。
- `npm run api-server:maincloud` 已完成启动烟测,`/healthz` 返回 `200`;期间 Maincloud 订阅恢复出现 `503` warning但未阻止服务启动。
仍需单独处理的非本轮阻塞:
- `cargo test --workspace --manifest-path server-rs\Cargo.toml` 在 Windows 原生测试链接 SpacetimeDB module crate 时失败,缺失 `bytes_sink_write``console_log``table_id_from_name``identity``datastore_table_scan_bsatn` 等 SpacetimeDB 宿主符号;这是 module crate 原生 Windows test 链接环境问题。
- `npm run check` 当前仍会停在全仓 `lint:eslint`,涉及大量既有 import 排序、未使用符号和 hook dependency lint debt本轮触碰文件已清掉 lint error`PlatformEntryFlowShellImpl.tsx` 保留既有 hook dependency warnings。

View File

@@ -11,7 +11,7 @@
## 2. 根因
### 2.1 Maincloud 目标库挂起
### 2.1 远端目标库挂起
CLI 直接查询 `xushi-p4wfr` 返回:
@@ -20,7 +20,7 @@ Error: database is suspended
HTTP status server error (503 Service Unavailable)
```
这说明 `maincloud.spacetimedb.com` 入口在线,但具体数据库 `xushi-p4wfr` 当前不可订阅、不可查 schema、不可执行 SQL。所有依赖该库的 procedure 都会失败。
这说明远端 SpacetimeDB 入口在线,但具体数据库 `xushi-p4wfr` 当前不可订阅、不可查 schema、不可执行 SQL。所有依赖该库的 procedure 都会失败。
### 2.2 认证快照同步被当成硬失败
@@ -64,7 +64,7 @@ HTTP status server error (503 Service Unavailable)
## 4. 本地可跑链路
Maincloud `xushi-p4wfr` 挂起期间,抓大鹅本地体验应使用本地 SpacetimeDB
远端 `xushi-p4wfr` 挂起期间,抓大鹅本地体验应使用本地 SpacetimeDB
```powershell
spacetime --root-dir=server-rs/.spacetimedb/local start --edition standalone --listen-addr 127.0.0.1:3101
@@ -75,10 +75,10 @@ spacetime --root-dir=server-rs/.spacetimedb/local publish xushi-p4wfr --server h
再让 Rust API 指向本地库:
```powershell
$env:GENARRATIVE_SPACETIME_MAINCLOUD_SERVER_URL="http://127.0.0.1:3101"
$env:GENARRATIVE_SPACETIME_MAINCLOUD_DATABASE="xushi-p4wfr"
$env:GENARRATIVE_SPACETIME_MAINCLOUD_TOKEN=""
npm run api-server:maincloud
$env:GENARRATIVE_SPACETIME_SERVER_URL="http://127.0.0.1:3101"
$env:GENARRATIVE_SPACETIME_DATABASE="xushi-p4wfr"
$env:GENARRATIVE_SPACETIME_TOKEN=""
npm run api-server
```
最后重启前端:
@@ -96,10 +96,10 @@ npm run dev:web
1. `GET http://127.0.0.1:3000/api/auth/login-options` 返回 `["phone","password"]`
2. `GET http://127.0.0.1:3000/api/runtime/match3d/gallery` 返回 `{"items":[]}`,不再返回 SpacetimeDB 503。
3. 未登录请求 `POST http://127.0.0.1:3000/api/creation/match3d/sessions` 返回 `401`,说明同源请求已进入 Rust 鉴权层,不再被 Vite `404`
4. 隔离端口指向挂起的 Maincloud 并使用 mock 短信时,手机号验证码登录返回 `200` 和 token日志只记录“认证快照写入 SpacetimeDB 失败,当前认证流程继续”。
4. 隔离端口指向挂起的远端库并使用 mock 短信时,手机号验证码登录返回 `200` 和 token日志只记录“认证快照写入 SpacetimeDB 失败,当前认证流程继续”。
## 6. 后续
1. Maincloud `xushi-p4wfr` 仍需恢复数据库挂起状态,否则正式云端玩法 procedure 仍不可用。
1. 远端 `xushi-p4wfr` 仍需恢复数据库挂起状态,否则对应玩法 procedure 仍不可用。
2. 本地开发如只为体验抓大鹅,可继续使用本地 SpacetimeDB 链路。
3. 认证快照同步失败会影响进程重启后的端恢复完整性,需要在 Maincloud 恢复后重新完成一次成功同步。
3. 认证快照同步失败会影响进程重启后的端恢复完整性,需要在目标库恢复后重新完成一次成功同步。

View File

@@ -7,7 +7,7 @@
但当前链路仍暴露出两个直接体验问题:
1. 前端草稿进度页仍把大鱼吃小鱼展示成单个 `compile` 步骤,用户会感觉“整个生成过程只有一步,而且一直卡在第一步”。
2. 前端在打开大鱼草稿或结果页时,会通过 `GET /api/runtime/big-fish/agent/sessions/:sessionId` 拉取完整会话;当 Maincloud 上游偶发抖动时Rust `spacetime-client` 统一 10 秒超时会直接映射成 `502`,用户会看到反复报错。
2. 前端在打开大鱼草稿或结果页时,会通过 `GET /api/runtime/big-fish/agent/sessions/:sessionId` 拉取完整会话;当 SpacetimeDB 上游偶发抖动时Rust `spacetime-client` 统一 10 秒超时会直接映射成 `502`,用户会看到反复报错。
## 修复口径
@@ -39,7 +39,7 @@
这样可以覆盖两类常见情况:
1. Maincloud 连接偶发抖动,第一次 procedure 超时但第二次马上恢复。
1. SpacetimeDB 连接偶发抖动,第一次 procedure 超时但第二次马上恢复。
2. 用户打开草稿页时碰到短暂断链,不再被立即判定成稳定的坏网关故障。
## 落地范围

View File

@@ -31,3 +31,12 @@
- 本地与远端部署:`RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md``JENKINS_RUST_BUILD_DEPLOY_PIPELINES_2026-04-23.md`
如果旧文档与本基线冲突,以本基线和更新日期更近的 Rust / SpacetimeDB 文档为准。
## 4. DDD 重构总纲补充
`2026-04-28` 起,`server-rs` 后续后端改动还必须同时遵循 [SERVER_RS_DDD_FULL_REFACTOR_2026-04-28.md](./SERVER_RS_DDD_FULL_REFACTOR_2026-04-28.md)
- `module-*` 只承载领域模型、命令、应用编排结果、领域事件和领域错误。
- `spacetime-module` 只承载 SpacetimeDB 表、reducer、procedure、事务 adapter 与 mapper。
- `api-server` 只承载 HTTP / SSE / BFF adapter 和外部平台服务编排。
- 任何表结构变化仍必须同步 `migration.rs` 与 [SPACETIMEDB_TABLE_CATALOG.md](./SPACETIMEDB_TABLE_CATALOG.md)。

View File

@@ -95,7 +95,7 @@ Genarrative-Database-Import
## 5. 本地部署测试参数
`Genarrative-Build-And-Deploy` 增加以下本地发布包参数,便于在 Jenkins 中测试本地 SpacetimeDB,不依赖 Maincloud
`Genarrative-Build-And-Deploy` 增加以下本地发布包参数,便于在 Jenkins 中测试本地 SpacetimeDB
1. `DATABASE`:发布包默认数据库名,默认 `genarrative-pipeline-local-test`。SpacetimeDB CLI 当前要求数据库名匹配 `^[a-z0-9]+(-[a-z0-9]+)*$`,只能使用小写字母、数字,并用单个短横线分隔;不要使用大写字母、点号、下划线、首尾短横线或连续短横线。
2. `API_PORT`:发布包内 api-server 端口,默认 `8082`
@@ -111,7 +111,7 @@ SERVER_URL=http://127.0.0.1:3101
DEPLOY_DIRECTORY=/var/lib/jenkins/deploy/Genarrative
```
这样脚本会自动使用 `/var/lib/jenkins/deploy/Genarrative/.spacetimedb` 作为 `spacetime --root-dir`,避免回退到 Jenkins 用户全局 CLI 登录态,也避免误连 Maincloud
这样脚本会自动使用 `/var/lib/jenkins/deploy/Genarrative/.spacetimedb` 作为 `spacetime --root-dir`,避免回退到 Jenkins 用户全局 CLI 登录态,也避免误连非本地目标
## 6. 文件清单

View File

@@ -76,4 +76,4 @@ Responses 非流式解析优先读取 `output_text`,再兼容 `output[].conten
3. `platform-llm` 单测覆盖 Responses 非流式、Responses SSE、Responses web_search tools 请求体。
4. `cargo test -p platform-llm --manifest-path server-rs/Cargo.toml` 通过。
5. `cargo test -p api-server creation_agent_llm_turn --manifest-path server-rs/Cargo.toml` 通过。
6. 修改后按项目约束使用 `npm run api-server:maincloud` 重新启动后端,并执行相应自动测试。
6. 修改后按项目约束使用 `npm run api-server` 重新启动后端,并执行相应自动测试。

View File

@@ -2,7 +2,7 @@
日期:`2026-04-22`
归档说明:截至 `2026-04-26`Rust 迁移已完成,旧 `server-node/` 已删除M7 阶段性预检包装入口已移除。后续长期检查统一使用 `server-rs/scripts/check.ps1``server-rs/scripts/smoke.ps1``server-rs/scripts/oss-smoke.ps1``npm run api-server:maincloud`
归档说明:截至 `2026-04-26`Rust 迁移已完成,旧 `server-node/` 已删除M7 阶段性预检包装入口已移除。后续长期检查统一使用 `server-rs/scripts/check.ps1``server-rs/scripts/smoke.ps1``server-rs/scripts/oss-smoke.ps1``npm run api-server`
## 1. 文档目标

View File

@@ -277,56 +277,56 @@ Rust DTO 只承载 HTTP contract 和跨 crate 稳定模型,不直接暴露 `mo
## 6.1 创作链
1. `create_match3d_agent_session(input)`
1. `create_match3d_agent_session(input)`
创建会话,写入初始配置或空配置,返回 session snapshot。
2. `get_match3d_agent_session(input)`
2. `get_match3d_agent_session(input)`
获取会话、消息和当前 draft。
3. `submit_match3d_agent_message(input)`
3. `submit_match3d_agent_message(input)`
只写 user message不调用 LLM不生成 assistant 回复。
4. `finalize_match3d_agent_message_turn(input)`
4. `finalize_match3d_agent_message_turn(input)`
`api-server` LLM turn 完成后写入 assistant message、配置状态、进度和 `last_assistant_reply`
5. `compile_match3d_draft(input)`
5. `compile_match3d_draft(input)`
校验题材、需要消除次数、难度,生成草稿和作品 draft profile。
## 6.2 作品链
1. `update_match3d_work(input)`
1. `update_match3d_work(input)`
更新游戏名称、标签、封面、题材、需要消除次数和难度。
2. `publish_match3d_work(input)`
2. `publish_match3d_work(input)`
校验基础信息完整后发布作品,不要求试玩通关。
3. `list_match3d_works(input)`
3. `list_match3d_works(input)`
查询当前用户作品。
4. `get_match3d_work_detail(input)`
4. `get_match3d_work_detail(input)`
查询作品详情,支持结果页恢复和作品详情页。
5. `delete_match3d_work(input)`
5. `delete_match3d_work(input)`
可后置;若接入创作中心删除,需要与其他玩法卡片删除语义一致。
## 6.3 运行态链
1. `start_match3d_run(input)`
1. `start_match3d_run(input)`
基于作品配置生成单局快照,返回 `Match3DRunSnapshot`
2. `get_match3d_run(input)`
2. `get_match3d_run(input)`
返回当前权威运行态快照。
3. `click_match3d_item(input)`
3. `click_match3d_item(input)`
根据 `run_id / item_instance_id / client_snapshot_version` 权威确认点击、入槽、三消、失败或胜利,返回新快照和确认结果。
4. `stop_match3d_run(input)`
4. `stop_match3d_run(input)`
把运行态标记为 `Stopped`,供试玩中止和返回结果页使用。
5. `restart_match3d_run(input)`
5. `restart_match3d_run(input)`
复用同一作品配置创建新 run返回新快照。
6. `finish_match3d_time_up(input)`
6. `finish_match3d_time_up(input)`
可选。若倒计时由前端触发,前端在倒计时归零时调用该 procedure后端确认 `TimeUp`。也可以由 `click_match3d_item``get_match3d_run` 懒确认超时。
## 6.4 procedure 输入输出约束
@@ -784,7 +784,7 @@ B3 当前落地状态:
1. 创作到发布到试玩主链通过。
2. 运行态点击、入槽、三消、失败、胜利通过。
3. 移动端视口检查通过。
4. `npm run api-server:maincloud` 通过。
4. `npm run api-server` 通过。
5. 对应测试与 `npm run check:encoding` 通过。
---
@@ -820,7 +820,7 @@ npm run check:encoding -- docs/technical/MATCH3D_CREATION_AND_RUNTIME_MINIMAL_IM
```powershell
cargo test -p module-match3d
cargo test -p shared-contracts
npm run api-server:maincloud
npm run api-server
npm run check:encoding
```

View File

@@ -110,4 +110,4 @@ server-rs/crates/module-match3d
1. `cargo test -p module-match3d` 通过。
2. `cargo test -p shared-contracts match3d` 通过。
3. `npm run check:encoding` 覆盖新增中文文档和新增源码。
4. 本阶段不要求运行 `npm run api-server:maincloud`因为未修改后端运行服务入口、SpacetimeDB 表或 `api-server` facade。
4. 本阶段不要求运行 `npm run api-server`因为未修改后端运行服务入口、SpacetimeDB 表或 `api-server` facade。

View File

@@ -143,4 +143,4 @@ npm run check:encoding
3. 不把 Match3D 公开广场并入更复杂的推荐、排行和运营榜单策略。
4. 不删除 `/match3d` 本地 playground它作为开发调试入口继续保留。
5. 全量 `npm run typecheck` 曾存在非 Match3D 既有阻塞,本轮以 Q1 定向测试和后端定向检查作为集成验收口径。
6. Maincloud 运行态仍依赖当前 SpacetimeDB 环境稳定性;如 `npm run api-server:maincloud` 现场遇到订阅 HTTP 500应按 Maincloud/SpacetimeDB 联调链路单独排查。
6. 运行态仍依赖当前 SpacetimeDB 环境稳定性;如 `npm run api-server` 现场遇到订阅 HTTP 500应按本地 SpacetimeDB 联调链路单独排查。

View File

@@ -0,0 +1,74 @@
# 抓大鹅运行态 3D 几何体实验 2026-05-02
## 1. 实验目标
本轮只验证抓大鹅运行态把可消除物从 2D 纯色几何图案切换为 3D 几何体后的可读性、点击手感和堆叠碰撞观感。
3D 表现层必须满足:
1. 圆形图案映射为球体。
2. 方形图案映射为方块。
3. 三角形、菱形、五角星、六边形、胶囊、心形、梯形、平行四边形等现有视觉键映射为近似 3D 几何体。
4. 物体在圆形空间内保持边界约束,并使用物理模拟产生轻微碰撞、堆叠、晃动效果。
5. 点击、备选栏、消除、胜负判定仍使用当前后端权威快照与前端即时反馈协议,不把规则真相迁到前端。
## 2. 回退要求
这是一次可取消实验,不替换现有 2D 方案。
1. 现有 `Match3DVisualIcon``Match3DToken` 和托盘 2D 图案渲染代码必须保留。
2. 新增 3D 表现层只作为运行态棋盘的可选渲染分支。
3. 当浏览器不支持 WebGL、3D 依赖加载失败或实验开关关闭时,运行态必须自动回到现有 2D 图案表现。
4. 托盘继续使用当前 2D 图标,便于玩家识别已选物品,也便于实验失败时快速回滚。
## 3. 工程落点
本轮只改前端表现层:
```text
src/components/match3d-runtime/Match3DPhysicsBoard.tsx
src/components/match3d-runtime/Match3DRuntimeShell.tsx
src/components/match3d-runtime/Match3DRuntimeShell.test.tsx
src/components/match3d-runtime/match3dRuntimePresentation.ts
src/components/match3d-runtime/match3dVisualAssets.tsx
```
新增依赖:
```text
three
cannon-es
@types/three
```
3D 棋盘默认启用;需要快速回到当前 2D demo 表现时,在运行态 URL 上追加任一参数:
```text
?match3dRender=2d
?match3d3d=off
```
3D 分支只读取后端快照中的物品坐标、层级、可点击状态和视觉键。物理碰撞、轻微堆叠和几何体姿态只作为前端表现层,不改变消除规则、备选栏规则、胜负判定或最终权威快照。
`match3dVisualAssets.tsx` 保留 2D 纯色几何图案映射,运行态托盘继续使用该 2D 图标;`match3dRuntimePresentation.ts` 收口显示层坐标和状态兼容,避免异常旧坐标把 2D 或 3D 物体推到圆形边界外。
## 4. 验收口径
1. `/match3d` 能打开并默认看到 3D 几何体棋盘。
2. 3D 几何体保持在圆形区域内,不被圆形边界裁切到不可点。
3. 物体进入场景后有轻微物理碰撞和堆叠稳定过程。
4. 点击 3D 物体后仍执行原有乐观入槽、后端确认、三消反馈和结算。
5. 单元测试仍覆盖 2D 回退图案,确保回退路径没有被删除。
6. 390px 移动端与桌面端均不能出现横向溢出,顶部状态、圆形棋盘和 7 格备选栏都要完整可见。
## 5. 锅型容器优化
2026-05-02 追加一轮 3D 表现优化,把运行态圆形空间明确解释为一口有固定深度和确定边界的锅。
编码口径:
1. 相机改为俯视角,玩家优先看到锅内物体的平面分布、遮挡关系和向上堆叠。
2. 3D 场景里的圆形区域拆成锅底、锅壁和锅沿三层视觉结构,锅壁有固定高度,锅沿明确标出边界。
3. 物理世界使用同一个锅内半径作为水平活动边界,所有可消除物体的初始位置和运行中位置都必须被约束在圆形锅内。
4. 物体受到重力后只允许在锅内碰撞、滑动、翻滚和向上堆叠,不能因为碰撞或初始坐标散落到圆形区域外。
5. 该优化仍只属于前端 3D 表现层,不改变后端运行态坐标、点击权威判定、备选栏、消除和胜负规则。

View File

@@ -119,10 +119,10 @@ cargo check -p spacetime-client --manifest-path server-rs\Cargo.toml
cargo check -p api-server --manifest-path server-rs\Cargo.toml
cargo test -p shared-contracts match3d --manifest-path server-rs\Cargo.toml
npm run check:encoding
npm run api-server:maincloud
npm run api-server
```
`api-server:maincloud` 是修改后端后的必跑项;如果本地缺少 Maincloud 环境或 SpacetimeDB 发布态不一致,需要在最终结果里明确说明。
`api-server` 是修改后端后的必跑项;如果本地 SpacetimeDB 发布态不一致,需要在最终结果里明确说明。
## 7. 后续接入点

View File

@@ -0,0 +1,33 @@
# 新建作品入口配置说明 2026-05-01
## 背景
创作中心顶部“新建作品”入口和平台创作类型弹层都依赖同一组玩法模板。此前入口开放状态、隐藏状态和中文文案集中写在 `src/components/platform-entry/platformEntryCreationTypes.ts` 与入口组件中,后续切换玩法开放节奏时容易出现多个入口不一致。
## 落地规则
1. 新建作品入口配置统一放在 `src/config/newWorkEntryConfig.ts`
2. `visible` 控制玩法是否展示在新建作品入口和创作类型弹层中。
3. `open` 控制玩法是否允许点击创建;`open: false` 时入口保持展示但禁用。
4. `title``subtitle``badge` 控制玩法卡片文案。
5. `startCard` 控制创作中心顶部新建作品模块的标题、辅助文案和移动端角标文案。
6. `typeModal` 控制平台创作类型弹层标题和描述。
7. 入口排序仍遵循“可创建玩法在前,未开放玩法在后”;同组内部沿用配置顺序。
## 当前状态
| 玩法 | 展示 | 开放 | 说明 |
| --- | --- | --- | --- |
| 角色扮演 | 是 | 是 | 点击后进入 RPG Agent 共创工作台 |
| 大鱼吃小鱼 | 否 | 是 | 功能仍保留,不在新建作品入口展示 |
| 拼图 | 是 | 是 | 点击后进入拼图 Agent 共创工作台 |
| 抓大鹅 | 是 | 是 | 点击后进入抓大鹅 Agent 共创工作台 |
| AIRP | 是 | 否 | 保留入口,显示敬请期待 |
| 视觉小说 | 是 | 否 | 保留入口,显示敬请期待 |
## 验收
1. 修改 `src/config/newWorkEntryConfig.ts` 后,创作中心顶部卡带和平台创作类型弹层应同步变化。
2. 隐藏玩法不触发入口预加载,也不出现在新建作品入口中。
3. 未开放玩法点击态保持禁用,不应进入鉴权或创建会话链路。
4. 已开放玩法点击后必须进入对应创建链路;若用户未登录,先走登录保护。

View File

@@ -0,0 +1,37 @@
# Profile 主链 Vite 代理修复
## 1. 问题
“我的”和“存档”页面在本地开发环境报:
```text
Unexpected token '<', "<!doctype "... is not valid JSON
```
这不是后端返回了坏 JSON而是前端请求 `/api/profile/*` 时没有命中 Vite 代理Vite 将请求按 SPA fallback 返回了 `index.html``requestJson` 随后对 HTML 执行 `JSON.parse`,首字符 `<` 触发该错误。
## 2. 现有约束
DDD 路由矩阵已冻结 profile 主链:
1. “我的”与存档读取统一走 `/api/profile/*`
2.`/api/runtime/profile/*` 已取消挂载,不允许前端回退到旧路径。
3. 后端 `api-server` 已挂载 `/api/profile/dashboard``/api/profile/save-archives` 等路由,问题只在本地 Vite 代理层。
## 3. 修复
`vite.config.ts` 在现有 `/api/auth``/api/runtime` 等代理旁补齐:
```ts
'/api/profile': {
target: runtimeServerTarget,
changeOrigin: true,
secure: false,
},
```
这样 profile 主链请求在 `npm run dev:web` 下会直接转发到 Rust API server不再落到前端入口页。
## 4. 回归
新增 `src/config/viteProxyConfig.test.ts`,断言 Vite server proxy 必须包含 `/api/profile`。后续若再调整 profile route 或代理配置,先更新本文和测试,再改工程实现。

View File

@@ -31,4 +31,3 @@
7. `server-rs/crates/shared-contracts/src/runtime.rs`
8. `packages/shared/src/contracts/runtime.ts`
9. `src/components/rpg-entry/RpgEntryHomeView.tsx`

View File

@@ -128,4 +128,4 @@
- Rust/module-runtime覆盖公共码、唯一码、私有码、失败场景、流水来源和余额累加。
- Axum覆盖用户鉴权、管理员鉴权、runtime error 到 400 的映射和兼容路径。
- 前端:覆盖入口替换、独立 modal、成功刷新余额和失败展示后端 message。
- 验证命令:`cargo test`、目标前端测试、`npm run api-server:maincloud``npm run check:encoding`
- 验证命令:`cargo test`、目标前端测试、`npm run api-server``npm run check:encoding`

View File

@@ -0,0 +1,29 @@
# 公开作品详情页自有作品编辑分流
更新时间:`2026-05-02`
## 背景
平台统一作品详情页左下角一直使用“作品改造”动作。这个动作适合打开其他作者作品时复制一份新草稿,但当详情页展示的是当前登录用户自己的作品时,继续复制会产生一份新的自己的作品,和用户预期的“编辑原作品”不一致。
## 落地规则
1. 作品详情页以 `ownerUserId === 当前登录用户 id` 判断作品归属。
2. 非本人作品保持“作品改造”,点击后继续走现有 remix / 复制草稿链路。
3. 本人作品把左下角按钮显示为“作品编辑”,点击后进入该作品绑定的原草稿或结果编辑页。
4. 本人作品编辑不调用 remix 接口,不创建新的同款作品。
5. 如果本人作品缺少可恢复的草稿会话,只展示可定位错误,不静默复制。
## 分玩法入口
1. RPG复用已保存作品编辑入口直接打开当前 profile 的结果编辑页。
2. 拼图:优先使用当前详情项的 `sourceSessionId` 恢复原拼图草稿。
3. 大鱼吃小鱼:使用公开作品的 `sourceSessionId` 恢复原玩法草稿。
4. 抓大鹅:保留并传递 `sourceSessionId`,恢复原创作会话后进入结果页。
## 验收标准
1. 登录用户打开自己的公开作品详情时,左下角按钮为“作品编辑”。
2. 点击“作品编辑”不会调用对应玩法的 remix 接口。
3. 登录用户打开他人公开作品详情时,左下角按钮仍为“作品改造”。
4. 未登录用户点击“作品改造”仍先触发登录拦截。

View File

@@ -0,0 +1,75 @@
# 拼图 APIMart 图片模型路由接入 2026-05-01
## 背景
拼图创作已收口为填表式流程,首图生成和结果页关卡重新生成都由 `server-rs/crates/api-server/src/puzzle.rs` 执行外部图片 I/O再把正式图写入 OSS 与 SpacetimeDB。新的模型选择只影响图片生成上游不改变 SpacetimeDB 表结构、拼图草稿结构或前端运行时规则。
本轮参考 APIMart 文档:
1. `https://docs.apimart.ai/cn/api-reference/images/gpt-image-2/generation`
2. `https://docs.apimart.ai/cn/api-reference/images/gemini-3.1-flash/generation`
两条文档均指向 OpenAI 兼容风格的图片生成入口:`POST https://api.apimart.ai/v1/images/generations`,头部使用 `Authorization: Bearer {APIMART_API_KEY}`。请求体至少包含 `model``prompt``n``size`。返回体按 OpenAI images 兼容格式优先读取 `data[].url`,若供应商返回异步任务结构,则继续按 `task_id` / `tasks/{task_id}` 轮询并提取图片 URL。
## 模型选项
拼图图片生成支持两个选项:
| 前端显示 | 请求值 | 上游 |
| --- | --- | --- |
| `gpt-image-2` | `gpt-image-2` | APIMart `/v1/images/generations` |
| `nanobanana2` | `gemini-3.1-flash-image-preview` | APIMart `/v1/images/generations` |
默认值为 `gpt-image-2`。前端只负责展示和传递所选模型,不能把模型路由逻辑、上游请求体拼装或 API Key 暴露到浏览器。历史草稿或旧请求中的空值、`original`、未知值统一按 `gpt-image-2` 处理,不再把拼图生图路由回 DashScope 原模型。
## 前端交互
1. 拼图创作表单的“画面描述”输入框左下角显示当前调用模型。
2. 拼图结果页关卡详情的“画面描述”输入框左下角同样显示当前调用模型。
3. 点击模型标识弹出轻量选择菜单,只支持 `gpt-image-2``nanobanana2` 两项。
4. 菜单只是模型选择控件,不写入说明性规则文案。
5. 参考图入口继续在画面描述输入框右下角,模型选择在左下角,两者不得遮挡文本。
6. 表单创建 session、自动保存表单草稿、首图生成失败重试时都要保留当前模型选择。
7. 结果页关卡重新生成时将当前模型随 `generate_puzzle_images` action 传给后端。
8. “生成草稿”和关卡详情“生成画面 / 重新生成画面”按钮文本右侧展示 `消耗2光点`
9. 关卡详情点击“生成画面 / 重新生成画面”后先弹出确认消耗光点弹窗,确认后开始请求;按钮区域切换为 30 秒倒计时进度条,并展示预计剩余生成完成时间。
## 后端路由
1. `CreatePuzzleAgentSessionRequest``ExecutePuzzleAgentActionRequest` 增加可选 `imageModel` 字段;该字段不进入 SpacetimeDB reducer 输入结构。
2. `compile_puzzle_draft_with_initial_cover``generate_puzzle_image_candidates` 增加图片模型参数。
3. `imageModel` 归一化规则:
- 空值、`original` 或未知值统一回落为 `gpt-image-2`
- `gpt-image-2` 走 APIMart
- `gemini-3.1-flash-image-preview` 走 APIMart前端显示名为 `nanobanana2`
4. APIMart 文生图和图生图共用 `POST /v1/images/generations`。有参考图时,后端将参考图 Data URL 作为 `image_urls` 数组传入;若上游不接受该字段,错误按上游失败返回,不在前端降级伪造结果。
5. APIMart 尺寸使用文档要求的比例写法 `1:1``gemini-3.1-flash-image-preview` 额外带 `resolution = "1K"`,对齐约 1024px 的拼图正方形素材。
6. APIMart 生成成功后仍下载远程图片,沿用现有 OSS 私有对象、`asset_object``asset_entity_binding` 写入流程。若图片已成功上传 OSS但 Maincloud / SpacetimeDB 短暂返回 `503 Service Unavailable`,资产索引写入允许降级跳过,并返回本次生成图片;日志必须记录 `拼图图片资产索引写入因 SpacetimeDB 连接不可用而降级跳过`
7. `save_puzzle_generated_images` 写回草稿时若遇到 Maincloud 连接级 `503` 或断线API 层基于本次生成结果合成 session 快照返回给前端,避免 APIMart 已成功出图却被后置持久化误报成服务不可用。余额不足、参数错误、上游生图失败仍按原错误返回,不做伪成功。
8. 结果页 `generate_puzzle_images` 会携带当前作品信息和 `levelsJson`。当 Maincloud / SpacetimeDB 在读取 session 阶段就返回连接级 `503` 或断线时,后端必须先用这份结果页快照构造最小内存 session再继续调用 APIMart外部图片已经生成后仍按第 6、7 条处理持久化降级。余额不足、参数错误、缺少草稿快照、关卡不存在等业务错误不走此降级。
9. APIMart 异步任务轮询按文档口径在提交后先等待 `10s`,再调用 `GET /v1/tasks/{task_id}`;图片地址提取同时支持 `url: "..."``url: ["..."]` 两种结构。
10. APIMart 错误统一映射为 `502 UPSTREAM_ERROR``details.provider = "apimart"`,保留上游状态码、业务 message 和截断后的 raw excerpt。
11. 拼图首图生成 `compile_puzzle_draft` 与关卡图片生成 `generate_puzzle_images` 每次预扣 `2` 光点;余额不足仍返回 `409 CONFLICT`Maincloud 连接级 503 仍按既有降级策略处理。
## 环境变量
新增服务端环境变量:
```text
APIMART_BASE_URL="https://api.apimart.ai/v1"
APIMART_API_KEY="YOUR_APIMART_API_KEY"
APIMART_IMAGE_REQUEST_TIMEOUT_MS=180000
```
`APIMART_API_KEY` 只能存在于本地或部署环境,不写入 Git 跟踪文件。若选择 APIMart 模型但缺少 key后端返回服务不可用错误前端展示现有错误面板。
## 验收
1. 创作表单和关卡详情的画面描述框左下角能切换 `gpt-image-2``nanobanana2`,默认显示 `gpt-image-2`
2. 点击“生成草稿”时,后端首图生成使用当前表单选择的模型。
3. 点击“生成画面 / 重新生成画面”时,后端当前关卡图片生成使用关卡详情选择的模型。
4. 历史 `original` 或空模型值不会再触发 DashScope统一按 `gpt-image-2` 请求 APIMart。
5. 选择 APIMart 模型时,请求 `POST {APIMART_BASE_URL}/images/generations`,使用 `Authorization: Bearer {APIMART_API_KEY}``model` 等于请求值,`size = 1:1`
6. “生成草稿”和关卡详情生图按钮展示 `消耗2光点`;关卡详情确认后展示 30 秒预计剩余进度条。
7. 不改 SpacetimeDB 表结构,因此无需更新 `migration.rs` 或重新生成 bindings。
8. 后端改动后运行对应 Rust 测试,并按项目约束用 `npm run api-server:maincloud` 重启验证。

View File

@@ -14,9 +14,9 @@
4. 玩家在生成草稿前退出,再次从创作中心点击这条拼图草稿时,必须恢复到填表页,并回填之前自动保存的作品名称、作品描述和画面描述;只有执行 `compile_puzzle_draft` 且生成结果页草稿后,草稿入口才进入结果页。
5. 表单自动保存走 `save_puzzle_form_draft` action不消耗光点不生成图片不改变 `stage = collecting_anchors`;生成草稿按钮仍单独触发 `compile_puzzle_draft` 并进入进度页。
6. 点击拼图入口始终创建新草稿,不复用上一次未完成 session恢复旧草稿只通过“我的创作”中的草稿卡进入。
7. Maincloud 仍运行旧 wasm缺少 `save_puzzle_form_draft` procedure前端提交生成或生成失败页重试时不得继续复用空 `seedText` 的表单 session必须用当前表单 payload 新建带真实 seed 的 session 再执行 `compile_puzzle_draft`
7. 若运行中的旧 wasm 缺少 `save_puzzle_form_draft` procedure前端提交生成或生成失败页重试时不得继续复用空 `seedText` 的表单 session必须用当前表单 payload 新建带真实 seed 的 session 再执行 `compile_puzzle_draft`
8. api-server 也要兼容旧 wasm`save_puzzle_form_draft` 缺失时,自动保存 action 降级返回当前 session`compile_puzzle_draft` 前置保存缺失且当前 session 为空 seed 时,创建一条带表单 seed 的替代 session 后继续编译,避免再次暴露 `No such procedure`
9. 正式修复仍是发布最新 SpacetimeDB wasm。当前 Maincloud `xushi-p4wfr` 的迁移操作员表为空,但旧库引导密钥来自旧 wasm本次临时生成的新引导密钥无法授权导出迁移需使用已有迁移操作员 token 或数据库 owner 重新授权后发布;禁止为绕过冲突直接清库,除非明确接受数据丢失。
9. 正式修复仍是发布最新 SpacetimeDB wasm。如果目标库的迁移操作员表为空,但旧库引导密钥来自旧 wasm本次临时生成的新引导密钥无法授权导出迁移需使用已有迁移操作员 token 或数据库 owner 重新授权后发布;禁止为绕过冲突直接清库,除非明确接受数据丢失。
1. 作品名称为必填字段,保存到 `workTitle`,兼容写入旧 `seedText`,同时作为作品级 `workTitle` 的真相源。
2. 作品描述为必填字段,保存到 `workDescription`,作为作品详情页、作品列表和发布资料中的 `summary` 真相源。

View File

@@ -14,13 +14,13 @@
### 1. 图片生成
1. 拼图生成图固定使用 `1024*1024`
2. 文生图和参考图生图共用同一个尺寸常量,禁止一条链路仍生成竖屏或横版图
3. 拼图图片提示词明确写入 `1:1 正方形画布`,继续保留适配 `3x3 / 4x4 / 5x5 / 6x6 / 7x7` 拼图切块、主体清晰、层次明确、无文字水印等约束
4. 文生图正向 prompt 必须由后端压缩到 `500` 字符以内,优先保留玩家画面描述开头与固定拼图约束,避免 DashScope 旧 text2image 协议把超长 prompt 判为“请求参数不合法”
5. DashScope 上游失败时api-server 必须在错误 details 中保留业务 message、`upstreamStatus` 和截断后的 `rawExcerpt`,日志也要记录同样的摘要,避免生成进度页只能看到通用 HTTP 文案
6. 图片生成仍由 `api-server` 执行。SpacetimeDB reducer 不做网络 I/O
7. 拼图文生图请求体按 DashScope Wan text2image 协议收口:`input``prompt` 与非空 `negative_prompt``parameters``n``size``prompt_extend``watermark`。不要在 `input``parameters` 里重复写入反向提示词,否则上游容易返回参数非法
1. 拼图默认使用 APIMart `gpt-image-2` 生成图,外部请求尺寸固定为 `1:1``nanobanana2` 仍映射为 `gemini-3.1-flash-image-preview`
2. 历史 `original` 或空模型值只做兼容输入,不再进入 DashScope 原模型链路,统一按 `gpt-image-2` 路由
3. 文生图和参考图生图共用同一个正方形尺寸口径,禁止一条链路仍生成竖屏或横版图
4. 拼图图片提示词明确写入 `1:1 正方形画布`,继续保留适配 `3x3 / 4x4 / 5x5 / 6x6 / 7x7` 拼图切块、主体清晰、层次明确、无文字水印等约束
5. 文生图正向 prompt 必须由后端压缩到 `500` 字符以内,优先保留玩家画面描述开头与固定拼图约束,避免上游把超长 prompt 判为“请求参数不合法”
6. APIMart 上游失败时api-server 必须在错误 details 中保留业务 message、`upstreamStatus` 和截断后的 `rawExcerpt`,日志也要记录同样的摘要,避免生成进度页只能看到通用 HTTP 文案
7. 图片生成仍由 `api-server` 执行。SpacetimeDB reducer 不做网络 I/O
8. 光点预扣失败属于钱包或 SpacetimeDB 服务链路错误,不得映射成 `400 BAD_REQUEST`。除余额不足返回 `409 CONFLICT` 外,其余预扣异常统一按上游/服务错误暴露,避免生成页误提示“请求参数不合法”。
### 2. 前端规则裁决
@@ -47,10 +47,10 @@
## 验收
1. 点击拼图草稿生成或重新生成画面时,后端请求 DashScope`size``1024*1024`
1. 点击拼图草稿生成或重新生成画面时,后端请求 APIMart`size``1:1`,默认模型为 `gpt-image-2`
2. 图片提示词包含 `1:1 正方形拼图关卡`
3. 图片提示词长度不超过 `500` 字符,超长画面描述会被截断,但适配 `3x3 / 4x4 / 5x5 / 6x6 / 7x7` 拼图切块、`避免文字、水印、边框和 UI 元素` 等玩法约束不能丢。
4. DashScope 返回参数错误、任务失败或非 2xx 时,前端错误优先展示后端 details.message后端日志能看到 `upstreamStatus``rawExcerpt`
4. APIMart 返回参数错误、任务失败或非 2xx 时,前端错误优先展示后端 details.message后端日志能看到 `upstreamStatus``rawExcerpt`
5. 正式拼图 run 中拖动拼块后,前端立即更新棋盘、合并块和通关状态,不再等待 `/drag`
6. 移动端运行时棋盘为正方形,并尽量贴近屏幕两侧边缘。
7. 基础单块和合并块都能看到圆角,合并块的外凸角与内凹角都不是直角,且图片不会溢出圆角裁剪。

View File

@@ -28,4 +28,4 @@
1. `npm run check:encoding`
2. `cargo check -p api-server --manifest-path server-rs/Cargo.toml`
3. `npm run api-server:maincloud` 重启后,点击拼图结果页“生成或更换图片”,候选图应能写回并正常展示。
3. `npm run api-server` 重启后,点击拼图结果页“生成或更换图片”,候选图应能写回并正常展示。

View File

@@ -2,6 +2,8 @@
更新时间:`2026-04-26`
> 2026-05-01 更新:正式平台入口已切到后端真相源。`startLocalPuzzleRun`、`swapLocalPuzzlePieces`、`dragLocalPuzzlePiece` 和 `advanceLocalPuzzleNextLevel` 只代表早期 V1/调试直达页背景,不再作为平台内 Puzzle 运行态主链。
## 1. 本次目标
玩家每完成拼图运行时的一关后,立即弹出独立结算弹窗。弹窗需要显示:

View File

@@ -13,7 +13,7 @@
1. 通关后默认点击“下一关”,优先加载当前拼图作品的下一关。
2. 当前作品没有下一关时,后端按标签语义相似度选出相似度最高的三个已发布作品。
3. 用户在通关弹窗里点击候选作品后,进入该作品并从第 `1` 关重新开始
3. 用户在通关弹窗里点击候选作品后,切换到候选作品的第一张图,但运行时关卡序号、切割规格和倒计时继续按当前 run 累进
4. 移动端优先,候选卡片要紧凑,不写玩法说明类文案。
## 数据契约
@@ -51,7 +51,8 @@
- 返回最高的 3 个候选
4. `advance_puzzle_next_level`
- `nextLevelMode = sameWork` 时加载当前作品的下一关,并继续当前 run。
- `nextLevelMode = similarWorks` 时默认加载候选第一项,并把 `entryProfileId / clearedLevelCount / currentLevelIndex` 重置到目标作品第 `1`
- `nextLevelMode = similarWorks` 时默认加载候选第一项的第一张图;正式 UI 点击具体候选作品时通过 `targetProfileId` 指定候选
- 任何跨作品进入都只切换图片来源,不重置 `entryProfileId / clearedLevelCount / currentLevelIndex`,并按当前 run 的下一关配置切割规格和倒计时。
5. `local-next-level` 兼容接口同样优先找同作品下一关;没有时返回 `similarWorks` 候选并保持当前通关 run只有候选池为空时才进入旧草稿兜底。
## 前端规则
@@ -70,6 +71,6 @@
1. 当前作品有下一关时,点击“下一关”进入当前作品下一关。
2. 当前作品没有下一关时,通关弹窗显示最多 3 个相似作品。
3. 点击相似作品后进入该作品第 `1`HUD 关卡序号、切割规格和倒计时都按第 `1` 关显示。
3. 点击相似作品后进入该作品第一张图HUD 关卡序号、切割规格和倒计时继续按运行时下一关显示。
4.`recommendedNextProfileId` 为空时,只要 `nextLevelMode = sameWork`,按钮仍可用。
5. 拼图 runtime 单测、Rust 拼图模块测试和编码检查通过。

View File

@@ -0,0 +1,46 @@
# 拼图运行时首次退出改造引导 2026-05-02
## 背景
玩家从公开拼图作品进入运行态后,左上角返回会直接离开玩法。若玩家因为体验不佳准备退出,需要在首次退出时给出改造入口,让玩家可以把当前作品复制为自己的草稿继续调整。
本轮只改拼图运行时前端交互与既有改造链路,不新增后端表,不改变拼图存档投影规则,不接入旧 `server-node`
## 交互规则
1. 触发点只限拼图运行态左上角返回按钮。
2. 对同一浏览器里的同一拼图 `profileId`,首次点击返回时不直接退出,而是弹出独立面板。
3. 面板标题固定为两行:
- `体验不佳?`
- `试试改造功能!`
4. 面板主按钮为 `作品改造`,点击后复用公开详情页已有的拼图改造链路:
- 使用当前运行关卡的 `currentLevel.profileId` 调用 `remixPuzzleGalleryWork(profileId)`,避免下一关或相似作品运行态误用旧详情页作品。
- 成功后写入 `puzzleFlow.session`
- 进入 `puzzle-result`,即游戏作品改造页。
5. 面板次按钮为 `保存并退出`,点击后关闭面板并执行原返回逻辑。
6. 非首次点击返回不再弹出面板,直接执行原返回逻辑。
## UI 布局
1. 面板保持居中独立弹层,移动端宽度不超过屏幕安全边距,桌面端保持紧凑。
2. 面板只展示标题与两个行动按钮,不增加说明性文案。
3. 标题使用两行居中排版,顶部可以放无文字图标强化游戏感。
4. `作品改造` 为主按钮,视觉权重高于 `保存并退出`
5. 两个按钮纵向排列,固定触控高度,确保移动端易点击。
## 首次状态
首次曝光是浏览器侧 UI 引导状态,不是业务真相态:
1.`currentLevel.profileId` 作为作品粒度。
2. 使用 `localStorage` 记录已展示状态。
3. `localStorage` 不可用时,使用当前组件生命周期内的内存集合兜底,避免同一挂载周期重复弹出。
4. 点击 `作品改造``保存并退出` 都视为已经完成本次引导曝光。
## 验收
1. 首次点击拼图运行态左上角返回,出现标题为 `体验不佳?试试改造功能!` 的独立面板。
2. 点击 `作品改造` 后进入拼图结果页改造草稿。
3. 点击 `保存并退出` 后返回原目标页面。
4. 同一作品再次点击左上角返回,不再出现面板。
5. 不影响设置面板里的返回按钮、失败续时、通关结算和下一关入口。

View File

@@ -0,0 +1,46 @@
# 拼图运行态低延迟交互前端化修正 2026-05-02
## 背景
本次检查发现正式平台入口的拼图运行态存在后端裁决回流:
1. 作品详情、公开作品卡和结果页试玩会启动后端 run。
2. `PuzzleRuntimeShell` 的交换和拖动回调在非本地 run 时会调用 `swapPuzzlePieces``dragPuzzlePieceOrGroup`
3. 服务端 run snapshot 如果直接覆盖前端当前棋盘,会让移动、交换、合并和通关反馈出现延迟或回退。
这与 PRD 中“前端以本地计算得到的 `allTilesResolved = true``status = cleared` 作为本关通关真相;后端不再参与拼块布局裁决”的规则冲突。
## 修正口径
正式平台入口采用混合运行态:
1. 正式平台开局仍调用后端 `startPuzzleRun`,保留真实 `runId`、游玩记录、排行榜和下一关存储锚点。
2. 点击交换只调用 `swapLocalPuzzlePieces`
3. 拖动单块或合并块只调用 `dragLocalPuzzlePiece`
4. 自动合并、拆分、合并块整体平移、被覆盖块交换和通关判定都以前端当前 `PuzzleRunSnapshot` 为准。
5. 通关后调用后端 `submitPuzzleLeaderboard` 持久化成绩并读取真实排行榜;前端只合并排行榜与下一关 handoff不用后端棋盘覆盖当前棋盘。
6. 点击同作品下一关调用后端 `advancePuzzleNextLevel`,由 SpacetimeDB 返回新的运行态快照。
7. 当前作品没有下一关时,通关弹窗展示后端 handoff 返回的相似作品;用户点击具体候选作品时直接 `startPuzzleRun(profileId, null)`,从目标作品第 `1` 关重新开始。
8. 失败状态点击“重新开始”时,正式 run 使用当前关 `levelId` 重新 `startPuzzleRun`,草稿/本地 run 使用本地重建,二者都保留当前失败关卡。
9. 结果页草稿试玩没有正式后端 run 时,继续使用本地 run、local leaderboard 和本地下一关兜底。
## 工程落点
1. `src/services/puzzle-runtime/puzzleLocalRuntime.ts`
- `startLocalPuzzleRun` 支持按 `levelId` 启动。
- `advanceLocalPuzzleLevel` 仅作为草稿试玩和无后端 run 的兜底。
- 正式平台的移动、交换、合并、拆分和通关裁决仍复用本地函数,避免交互延迟。
2. `src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`
- 平台拼图开局、恢复存档、排行榜、下一关接回后端。
- 正式平台入口不再调用 `/api/runtime/puzzle/runs/{runId}/swap``/drag`
- 后端排行榜返回的 run 只合并排行榜和 `nextLevelMode / nextLevelProfileId / nextLevelId / recommendedNextWorks`,不覆盖当前棋盘。
- 相似作品候选卡点击启动目标作品新 run失败重开按当前关 `levelId` 启动新 run。
3. `src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx`
- 公开拼图玩法交互测试断言前端本地交换函数被调用。
- 同时断言后端 `swap / drag` 不参与棋盘交互,后端 `leaderboard / next-level` 继续参与非即时链路。
## 边界
本次只收回拼图玩法内的移动、交换、合并、拆分和通关裁决。创作 Agent、作品保存、发布、公开广场读取、作品详情读取、作品改造、排行榜、同作品下一关、相似候选生成、失败重开和游玩记录仍走现有后端链路。
`SERVER_RS_DDD_WP_PZ_RUNTIME_BACKEND_TRUTH_CLOSURE_2026-05-01.md` 作为历史收尾记录保留;若与本文冲突,以本文的“低延迟棋盘前端裁决,非即时链路后端持久化”口径为准。

View File

@@ -41,7 +41,7 @@
第 11 关开始,每 6 关循环复用第 5 关到第 10 关的配置,即 `5x5/210000ms``6x6/240000ms``5x5/210000ms``7x7/270000ms``5x5/240000ms``7x7/270000ms`
同作品下一关必须使用同一个运行时关卡序号继续推进。跨作品相似推荐代表进入新作品,必须从目标作品第 `1` 关重新开始
同作品下一关必须使用同一个运行时关卡序号继续推进。跨作品相似推荐只切换到候选作品的第一张图,运行时关卡序号、切割规格和倒计时继续按当前 run 累进,不重置难度循环
失败状态点击“重新开始”时,不进入作品第 `1` 关,而是重开当前失败关卡:前端需要传当前关 `levelId`,服务端按该 `levelId` 在作品内的位置恢复 `currentLevelIndex`、切割规格和倒计时。

View File

@@ -4,11 +4,60 @@
## 文档列表
- [PRODUCT_NAMING_BAIMENG_RENAME_2026-05-01.md](./PRODUCT_NAMING_BAIMENG_RENAME_2026-05-01.md):冻结当前对外中文命名,产品展示名统一为“百梦”,消费单位为“光点”,公开账号标识为“百梦号”,创作侧称谓为“百梦主”。
- [PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md](./PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md):冻结单机生产部署目标,从旧一体化启动脚本切到 Nginx、systemd 托管 SpacetimeDB 与 Rust `api-server`,并记录生产 Jenkins 流水线拆分计划和首批部署骨架。
- [PUZZLE_RUNTIME_FRONTEND_LOGIC_REHOME_2026-05-02.md](./PUZZLE_RUNTIME_FRONTEND_LOGIC_REHOME_2026-05-02.md):记录拼图正式平台入口移动、交换、合并、拆分和通关裁决收回前端即时运行态,排行榜、下一关和游玩记录继续由后端持久化处理。
- [RPG_FOUNDATION_DRAFT_ROLE_DOSSIER_TIMEOUT_FALLBACK_2026-05-02.md](./RPG_FOUNDATION_DRAFT_ROLE_DOSSIER_TIMEOUT_FALLBACK_2026-05-02.md):记录 `agent-foundation-*-dossier-batch-*` 无搜索 Responses 请求超时后的本地养成档案兜底,避免底稿主链被尾部角色润色阶段阻断。
- [RPG_IMAGE_GENERATION_GPT_IMAGE_2_MIGRATION_2026-05-02.md](./RPG_IMAGE_GENERATION_GPT_IMAGE_2_MIGRATION_2026-05-02.md):记录 RPG 角色主图与场景幕背景图统一迁移到 APIMart OpenAI 兼容 `gpt-image-2` 生图入口的边界、配置和验收口径。
- [RPG_FOUNDATION_DRAFT_LANDMARK_SEED_BATCH_TIMEOUT_FIX_2026-05-02.md](./RPG_FOUNDATION_DRAFT_LANDMARK_SEED_BATCH_TIMEOUT_FIX_2026-05-02.md):记录 `agent-foundation-landmark-seed-batch-1` 无搜索 Responses 请求超时的根因,并将场景骨架批次收敛为单场景生成。
- [PROFILE_MAIN_ROUTE_VITE_PROXY_FIX_2026-05-02.md](./PROFILE_MAIN_ROUTE_VITE_PROXY_FIX_2026-05-02.md):记录“我的”和“存档”页面在本地把 `/api/profile/*` 请求落到 Vite SPA fallback、导致 HTML 被当 JSON 解析的根因,以及 `/api/profile` 代理补齐与回归测试。
- [SERVER_RS_DDD_WP_DEL_CLEANUP_2026-05-01.md](./SERVER_RS_DDD_WP_DEL_CLEANUP_2026-05-01.md):记录 `WP-DEL 删除旧层与命名收口`,物理删除旧 runtime story HTTP DTO、前端 `Rpg*` alias、旧 `/api/custom-world/*` 非 runtime 前缀、Puzzle `local-next-level` 入口和 `/generated-*` 资产直读代理;生成资产读取统一走 OSS read-url 链路。
- [SERVER_RS_DDD_WP_API_BFF_CLOSURE_2026-05-01.md](./SERVER_RS_DDD_WP_API_BFF_CLOSURE_2026-05-01.md):记录 `WP-API api-server BFF` 收尾,补齐 `/api/llm/chat/completions``stream=true` SSE 代理,明确手机号/微信配置门控和角色动画资产占位不阻塞本次 BFF 关闭。
- [SERVER_RS_DDD_WP_AS_ASSET_CHAIN_CLOSURE_2026-05-01.md](./SERVER_RS_DDD_WP_AS_ASSET_CHAIN_CLOSURE_2026-05-01.md):记录 `WP-AS Assets` 资产主链收尾,补齐资产领域事件、`asset_event` event table、OSS 确认、API facade、Rust bindings、表目录和 migration 白名单。
- [SERVER_RS_DDD_WP_CW_FULL_CHAIN_CLOSURE_2026-05-01.md](./SERVER_RS_DDD_WP_CW_FULL_CHAIN_CLOSURE_2026-05-01.md):记录 `WP-CW Custom World` 当前主链收尾,补齐 runtime Custom World 场景图入口、RPG 创作资产 client 主路径、DashScope 缺配置测试口径和旧 `/api/custom-world/*` 兼容入口边界。
- [SERVER_RS_DDD_WP_ST_CLOSURE_2026-05-01.md](./SERVER_RS_DDD_WP_ST_CLOSURE_2026-05-01.md):记录 `WP-ST SpacetimeDB Adapter` 当前稳定范围收尾,补齐 `asset_event`、表目录、migration 白名单、Rust bindings 和 Windows bindings 生成 fallback。
- [SERVER_RS_DDD_WP_RPG_GAMEPLAY_CLOSURE_2026-05-01.md](./SERVER_RS_DDD_WP_RPG_GAMEPLAY_CLOSURE_2026-05-01.md):记录 `WP-RPG Gameplay 域` 全域收口,将战斗胜利、任务交付和宝箱奖励的跨域结算计划下沉到 `module-story`
- [SERVER_RS_DDD_WP_PZ_RUNTIME_BACKEND_TRUTH_CLOSURE_2026-05-01.md](./SERVER_RS_DDD_WP_PZ_RUNTIME_BACKEND_TRUTH_CLOSURE_2026-05-01.md):记录 `WP-PZ Puzzle` 正式平台运行态从前端本地裁决切到后端真相源,补齐 owner draft 预览 run、交换/拖动/下一关/排行榜后端调用和无 schema 变更口径。
- [SERVER_RS_DDD_WP_RS_RUNTIME_STORY_CLOSURE_2026-05-01.md](./SERVER_RS_DDD_WP_RS_RUNTIME_STORY_CLOSURE_2026-05-01.md):记录 `WP-RS Runtime Story` 写链路收尾,补齐 `/api/story/sessions/runtime``/api/story/sessions/{storySessionId}/actions/resolve`,统一返回 `StoryRuntimeMutationResponse.projection`,并保持旧 `/api/runtime/story/*` 未挂载。
- [SERVER_RS_DDD_WP_CW_ACTION_AND_DOMAIN_SPLIT_2026-04-30.md](./SERVER_RS_DDD_WP_CW_ACTION_AND_DOMAIN_SPLIT_2026-04-30.md):记录 `WP-CW Custom World` 的领域拆分与 Agent action 收口,将 `module-custom-world``lib.rs` 拆入 DDD 骨架,并移除 Custom World 运行代码中的最小兼容占位动作。
- [SERVER_RS_DDD_WP_BF_AND_G2_DRIFT_CLEANUP_2026-04-30.md](./SERVER_RS_DDD_WP_BF_AND_G2_DRIFT_CLEANUP_2026-04-30.md):记录 `WP-BF Big Fish` 物理拆分漂移和 G2 迁移期口径清理,将 Big Fish 创作域类型、命令、应用规则和错误层拆入 DDD 文件,并清理剩余 `过渡落位` 注释。
- [SERVER_RS_DDD_TESTS_SUPPORT_CRATE_CLOSURE_2026-04-30.md](./SERVER_RS_DDD_TESTS_SUPPORT_CRATE_CLOSURE_2026-04-30.md):记录 `tests-support` 从目录占位收口为 `server-rs` workspace 共享测试支撑 crate首版提供 Maincloud healthz 与 HTTP smoke 通用断言。
- [SERVER_RS_DDD_WP_BF_RUNTIME_BACKEND_TRUTH_2026-04-29.md](./SERVER_RS_DDD_WP_BF_RUNTIME_BACKEND_TRUTH_2026-04-29.md):记录 `WP-BF Big Fish` 运行态从前端本地规则切到 Rust 领域真相源、SpacetimeDB run 表、API facade 和前端新接口接入的关闭口径。
- [SERVER_RS_DDD_WP_PF_PLATFORM_ERROR_CLASSIFICATION_2026-04-29.md](./SERVER_RS_DDD_WP_PF_PLATFORM_ERROR_CLASSIFICATION_2026-04-29.md):记录 `WP-PF platform side effects` 平台副作用收口,统一 LLM、OSS、SMS、微信平台错误分类与 API 映射,并将微信 OAuth provider 下沉到 `platform-auth`
- [SERVER_RS_DDD_WP_RT_ADAPTER_API_CLOSURE_2026-04-29.md](./SERVER_RS_DDD_WP_RT_ADAPTER_API_CLOSURE_2026-04-29.md):记录 `WP-RT Runtime/Profile/Save` Adapter/API 收口,将 checkpoint、profile/save archive meta、充值/邀请/兑换/钱包等剩余纯规则迁入 `module-runtime`,移除 `/api/runtime/profile/*` 旧兼容挂载并对齐前端 `/api/profile/*` 请求路径。
- [SERVER_RS_DDD_WP_SC_SPACETIME_CLIENT_REFACTOR_2026-04-29.md](./SERVER_RS_DDD_WP_SC_SPACETIME_CLIENT_REFACTOR_2026-04-29.md):记录 `WP-SC Spacetime Client` 在当前稳定 facade 范围内的关闭口径,收口 `spacetime-client` 的 typed facade、错误映射、row snapshot mapper、story runtime inventory source 接线和 README 状态;后续只随 `WP-ST` 新 facade 稳定后增量接线。
- [SERVER_RS_DDD_WP_RT_APPLICATION_RECORD_REFACTOR_2026-04-29.md](./SERVER_RS_DDD_WP_RT_APPLICATION_RECORD_REFACTOR_2026-04-29.md):记录 `WP-RT Runtime/Profile/Save` 的应用记录投影拆分切片,将 settings、browse history、profile/save 等 `build_runtime_*_record` 迁入 `module-runtime/src/application.rs`,不改回包字段语义。
- [SERVER_RS_DDD_WP_RT_COMMANDS_REFACTOR_2026-04-29.md](./SERVER_RS_DDD_WP_RT_COMMANDS_REFACTOR_2026-04-29.md):记录 `WP-RT Runtime/Profile/Save` 的命令构造拆分切片,将 settings、browse history、profile/save 等 `build_runtime_*_input` 和写入归一化函数迁入 `module-runtime/src/commands.rs`,不改校验语义。
- [SERVER_RS_DDD_WP_AI_INTERNAL_MODULE_SPLIT_2026-04-29.md](./SERVER_RS_DDD_WP_AI_INTERNAL_MODULE_SPLIT_2026-04-29.md):记录 `WP-AI AI Task``module-ai` 内部子模块拆分,将 domain、commands、application 与行为测试继续拆到职责更细的子文件,同时保持 `module_ai::*` 公开导出、SpacetimeDB schema、BFF route 和前端契约不变。
- [SERVER_RS_DDD_WP_AI_TASK_BFF_CLOSURE_2026-04-29.md](./SERVER_RS_DDD_WP_AI_TASK_BFF_CLOSURE_2026-04-29.md):记录 `WP-AI AI Task` BFF 收口与关闭口径,补齐 AI task mutation route 鉴权和 SpacetimeDB 未发布错误 envelope 的定向验证不改表结构、LLM provider、SSE 或前端消费。
- [SERVER_RS_DDD_WP_CW_DOMAIN_ENUM_REHOME_2026-04-29.md](./SERVER_RS_DDD_WP_CW_DOMAIN_ENUM_REHOME_2026-04-29.md):记录 `WP-CW Custom World` 基础领域枚举归位切片,将 Custom World / RPG Agent 基础枚举、进度常量和字符串口径迁入 `module-custom-world/src/domain.rs`,不改 SpacetimeDB、API 或前端行为。
- [SERVER_RS_DDD_WP_RPG_GAMEPLAY_DOMAIN_SPLIT_2026-04-30.md](./SERVER_RS_DDD_WP_RPG_GAMEPLAY_DOMAIN_SPLIT_2026-04-30.md):记录 `WP-RPG Gameplay 域` 的 combat、inventory、NPC、quest、runtime-item 领域拆分收口,将真实规则从 `lib.rs` 拆入 DDD 骨架文件并保留原公开 API。
- [SERVER_RS_DDD_WP_RPG_PROGRESSION_DOMAIN_SPLIT_2026-04-30.md](./SERVER_RS_DDD_WP_RPG_PROGRESSION_DOMAIN_SPLIT_2026-04-30.md):记录 `WP-RPG Gameplay 域``module-progression` 领域拆分收口,将玩家成长、章节预算、章节账本、自动定级、领域事件和错误层从 `lib.rs` 拆入 DDD 骨架文件。
- [SERVER_RS_DDD_WP_RS_RUNTIME_STORY_DOMAIN_SPLIT_2026-04-30.md](./SERVER_RS_DDD_WP_RS_RUNTIME_STORY_DOMAIN_SPLIT_2026-04-30.md):记录 `WP-RS Runtime Story 去兼容层``module-runtime-story` 顶层领域拆分收口,将 action 结果、状态 patch、响应组装参数、领域事件和错误从 `lib.rs` 拆入 DDD 骨架文件。
- [SERVER_RS_DDD_WP_RPG_STORY_DOMAIN_SPLIT_2026-04-29.md](./SERVER_RS_DDD_WP_RPG_STORY_DOMAIN_SPLIT_2026-04-29.md):记录 `WP-RPG Gameplay 域``module-story` 领域拆分收口,将 story session 领域模型、命令、事件、应用映射和错误层从 `lib.rs` 拆入 DDD 骨架文件,并修正 README 不再指向旧 `/api/runtime/story/*` 兼容链路。
- [SERVER_RS_DDD_WP_PZ_DOMAIN_SPLIT_2026-04-29.md](./SERVER_RS_DDD_WP_PZ_DOMAIN_SPLIT_2026-04-29.md):记录 `WP-PZ Puzzle` 领域类型与规则拆分切片,将 Agent/作品/运行态领域类型、写入命令、应用规则、字段错误和最小领域事件归位到 `module-puzzle` 的 DDD 骨架文件,不改 SpacetimeDB、API 或前端行为。
- [SERVER_RS_DDD_WP_PZ_DOMAIN_ENUM_REHOME_2026-04-29.md](./SERVER_RS_DDD_WP_PZ_DOMAIN_ENUM_REHOME_2026-04-29.md):记录 `WP-PZ Puzzle` 基础领域常量与枚举归位切片,将 Puzzle Agent、发布状态、运行态状态、ID 前缀、标签数量和洗牌次数口径迁入 `module-puzzle/src/domain.rs`,不改 SpacetimeDB、API 或前端行为。
- [SERVER_RS_DDD_WP_RPG_COMBAT_DOMAIN_ENUM_REHOME_2026-04-29.md](./SERVER_RS_DDD_WP_RPG_COMBAT_DOMAIN_ENUM_REHOME_2026-04-29.md):记录 `WP-RPG Gameplay 域` 的 combat 基础领域常量与枚举归位切片,将战斗 ID 前缀、版本、伤害、切磋保底生命、旧攻击 function 列表和基础枚举迁入 `module-combat/src/domain.rs`,不改 SpacetimeDB、API 或前端行为。
- [SERVER_RS_DDD_WP_ST_AUTH_ADAPTER_SPLIT_2026-04-29.md](./SERVER_RS_DDD_WP_ST_AUTH_ADAPTER_SPLIT_2026-04-29.md):记录 `WP-ST` Auth SpacetimeDB adapter 目录化切片将认证表、procedure 和快照 JSON mapper 拆入 `auth/` 子模块,不改 schema、procedure 签名或绑定形状。
- [SERVER_RS_DDD_WP_RS_COMPAT_RESIDUE_AUDIT_2026-04-29.md](./SERVER_RS_DDD_WP_RS_COMPAT_RESIDUE_AUDIT_2026-04-29.md):记录 `WP-RS Runtime Story 去兼容层` 的 compat 残留审计切片2026-05-01 后运行写链路已迁到 story session scoped route旧展示 DTO 和历史命名统一留给 `WP-DEL` 清理。
- [SERVER_RS_DDD_WP_AS_ASSET_OBJECT_TYPE_REHOME_2026-04-29.md](./SERVER_RS_DDD_WP_AS_ASSET_OBJECT_TYPE_REHOME_2026-04-29.md):记录 `WP-AS Assets` 资产对象类型归位切片,将领域快照、命令 DTO、应用返回 DTO 和字段错误拆入 `module-assets` 的 DDD 骨架文件,不改 SpacetimeDB、API、OSS 或前端行为。
- [SERVER_RS_DDD_WP_RT_ERROR_LAYER_REFACTOR_2026-04-29.md](./SERVER_RS_DDD_WP_RT_ERROR_LAYER_REFACTOR_2026-04-29.md):记录 `WP-RT Runtime/Profile/Save` 的错误层拆分切片,将 settings、browse history、profile/save 三组字段错误和中文错误文案迁入 `module-runtime/src/errors.rs`,不改校验语义。
- [SERVER_RS_DDD_WP_RT_DOMAIN_SNAPSHOT_RECORD_REFACTOR_2026-04-29.md](./SERVER_RS_DDD_WP_RT_DOMAIN_SNAPSHOT_RECORD_REFACTOR_2026-04-29.md):记录 `WP-RT Runtime/Profile/Save` 的 snapshot、profile、wallet、played world 与 save archive 领域快照和记录类型拆分切片,只移动纯类型和枚举方法,不改 SpacetimeDB、API 或前端接线。
- [SERVER_RS_DDD_WP_RT_RUNTIME_SETTINGS_DOMAIN_REFACTOR_2026-04-29.md](./SERVER_RS_DDD_WP_RT_RUNTIME_SETTINGS_DOMAIN_REFACTOR_2026-04-29.md):记录 `WP-RT Runtime/Profile/Save` 的 runtime settings 领域值对象拆分切片,将默认设置、平台主题和值对象迁入 `module-runtime/src/domain.rs`,不改 SpacetimeDB、API 或前端接线。
- [SERVER_RS_DDD_WP_A_AUTH_DOMAIN_VALUE_OBJECT_REFACTOR_2026-04-29.md](./SERVER_RS_DDD_WP_A_AUTH_DOMAIN_VALUE_OBJECT_REFACTOR_2026-04-29.md):记录 `WP-A Auth` DDD 分层收口,将账号、会话、验证码、微信 state/绑定规则、命令输入、应用返回、领域错误和领域事件归位到 `module-auth` 骨架,并核查 API、platform 与 SpacetimeDB adapter 边界。
- [SERVER_RS_DDD_WP_ST_CUSTOM_WORLD_ROOT_SPLIT_2026-04-29.md](./SERVER_RS_DDD_WP_ST_CUSTOM_WORLD_ROOT_SPLIT_2026-04-29.md):记录 `WP-ST` Custom World SpacetimeDB adapter 从根入口迁入 `custom_world/mod.rs` 的边界、无 schema 变更口径和验收命令。
- [SERVER_RS_DDD_WP_FE_S_RPG_RUNTIME_STORY_CLIENT_MIGRATION_2026-04-29.md](./SERVER_RS_DDD_WP_FE_S_RPG_RUNTIME_STORY_CLIENT_MIGRATION_2026-04-29.md):记录 `WP-FE-S` RPG runtime story client 迁到 `storySessionId` scoped runtime projection并在 2026-05-01 收尾切片中关闭旧 `/api/runtime/story/*` 开局与动作写侧调用。
- [SERVER_RS_DDD_WP_FE_H_RPG_RUNTIME_STORY_HOOKS_PROJECTION_2026-04-29.md](./SERVER_RS_DDD_WP_FE_H_RPG_RUNTIME_STORY_HOOKS_PROJECTION_2026-04-29.md):记录 `WP-FE-H` RPG runtime story hooks 接线切片,将 option catalog、继续游戏刷新与正式动作结算统一接入 story runtime projection client。
- [SERVER_RS_DDD_WP_FE_C_RPG_RUNTIME_SHELL_TEST_FIXTURE_2026-04-29.md](./SERVER_RS_DDD_WP_FE_C_RPG_RUNTIME_SHELL_TEST_FIXTURE_2026-04-29.md):记录 `WP-FE-C` RPG runtime shell 组件测试夹具接线切片,将组件测试 mock 对齐当前 hooks 暴露的 UI 对象形状,并确认组件层不拼接 runtime story API 路径。
- [SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_PROGRESS_2026-04-29.md](./SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_PROGRESS_2026-04-29.md):记录 `G1 契约与路由矩阵` 已完成的本地进度、验证结果、单 owner 边界和下一批并行任务入口。
- [SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md](./SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md):冻结 `server-rs` DDD G1 契约与路由矩阵,明确新旧 HTTP 路由去留、DTO 删除/保留/重命名、页面到 query/result DTO 映射、breaking change、API 错误 envelope 和共享契约单 owner 边界。
- [SERVER_RS_DDD_WP_API_BFF_START_2026-04-29.md](./SERVER_RS_DDD_WP_API_BFF_START_2026-04-29.md):记录 `WP-API api-server BFF` 启动切片,先收口旧 runtime story 兼容路由挂载、错误 envelope 回归和后续依赖,不越过 `spacetime-client` 接线边界。
- [SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md](./SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md):把 `server-rs` DDD 一次性重构拆成全局可并行工作包,覆盖 `module-*``spacetime-module``spacetime-client``api-server``platform-*`、共享契约和前端接入的依赖、边界与验收命令。
- [SERVER_RS_DDD_FULL_REFACTOR_2026-04-28.md](./SERVER_RS_DDD_FULL_REFACTOR_2026-04-28.md):冻结 `server-rs` 一次性 DDD 重构总纲,明确 crate 依赖方向、模块目录、上下文聚合/命令/事件/读模型、SpacetimeDB adapter 映射和表结构变更约束。
- [SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md](./SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md):冻结 SpacetimeDB 表结构变更约束、自动迁移可接受范围、冲突后的系统行为,以及保留旧数据的增量迁移流程;凡涉及 `spacetime publish`、表字段调整或 `migration.rs` 对齐时优先参考。
- [PRODUCT_NAMING_BAIMENG_RENAME_2026-05-01.md](./PRODUCT_NAMING_BAIMENG_RENAME_2026-05-01.md):冻结当前对外中文命名,产品展示名统一为“百梦”,消费单位为“光点”,公开账号标识为“百梦号”,创作侧称谓为“百梦主”。
- [SPACETIMEDB_CLOUD_CONFIG_REMOVAL_2026-05-02.md](./SPACETIMEDB_CLOUD_CONFIG_REMOVAL_2026-05-02.md):记录旧云端 SpacetimeDB 配置、发布脚本和默认文档口径的移除结果,冻结后续仅使用本地或显式 `SERVER_URL` 的运维规则。
- [SPACETIMEDB_LOCAL_REPLICA_IDENTITY_MISMATCH_FIX_2026-04-30.md](./SPACETIMEDB_LOCAL_REPLICA_IDENTITY_MISMATCH_FIX_2026-04-30.md):记录本地 standalone 启动时报 `mismatched database identity` 的 root-dir/replica 数据残留根因、备份重建步骤和脚本诊断口径。
- [AUTH_SNAPSHOT_AND_MATCH3D_LOCAL_DEV_FIX_2026-05-01.md](./AUTH_SNAPSHOT_AND_MATCH3D_LOCAL_DEV_FIX_2026-05-01.md):记录 Maincloud `xushi-p4wfr` 挂起导致认证快照同步和抓大鹅创作失败的根因、认证同步非阻断修复、`/api/creation` Vite 代理补齐和本地 SpacetimeDB 可跑链路。
- [AUTH_SNAPSHOT_AND_MATCH3D_LOCAL_DEV_FIX_2026-05-01.md](./AUTH_SNAPSHOT_AND_MATCH3D_LOCAL_DEV_FIX_2026-05-01.md):记录远端库挂起导致认证快照同步和抓大鹅创作失败的根因、认证同步非阻断修复、`/api/creation` Vite 代理补齐和本地 SpacetimeDB 可跑链路。
- [LLM_MODEL_ROUTING_RPG_AND_CREATION_2026-04-30.md](./LLM_MODEL_ROUTING_RPG_AND_CREATION_2026-04-30.md):冻结 RPG 运行时剧情推理使用 `doubao-seed-character-251128``/chat/completions`,以及所有模板创作大模型推理使用 `deepseek-v3-2-251201``/responses`
- [PROFILE_INVITE_CODE_REGISTRATION_AND_ADMIN_2026-04-30.md](./PROFILE_INVITE_CODE_REGISTRATION_AND_ADMIN_2026-04-30.md):冻结邀请码从“我的 Tab 填写”迁到注册环节的前后端边界、`profile_invite_code.metadata_json` 表结构扩展、管理员邀请码虚拟主体和奖励规则。
- [MATCH3D_CREATION_AND_RUNTIME_MINIMAL_IMPLEMENTATION_2026-04-30.md](./MATCH3D_CREATION_AND_RUNTIME_MINIMAL_IMPLEMENTATION_2026-04-30.md):冻结抓大鹅 Match3D 首版 demo 的独立玩法域、表与 procedure、HTTP facade、前端即时反馈/后端权威确认协议,以及可并行开发包。
@@ -18,6 +67,7 @@
- [MATCH3D_SPACETIME_CLIENT_AND_API_FACADE_2026-04-30.md](./MATCH3D_SPACETIME_CLIENT_AND_API_FACADE_2026-04-30.md):记录抓大鹅 B4+B5 已落地的 SpacetimeDB bindings、`spacetime-client` facade、`api-server` HTTP 路由、shared contract 对齐和验收命令。
- [MATCH3D_CREATION_ENTRY_COMING_SOON_2026-05-01.md](./MATCH3D_CREATION_ENTRY_COMING_SOON_2026-05-01.md):记录抓大鹅创作页入口重新开放、首屏与弹层分流一致,以及公开广场失败不污染创作错误态的边界。
- [MATCH3D_Q1_INTEGRATION_ACCEPTANCE_2026-05-01.md](./MATCH3D_Q1_INTEGRATION_ACCEPTANCE_2026-05-01.md):记录抓大鹅 Match3D 第一至第三波完成度复核、Q1 主链集成落点、定向验收命令和遗留风险。
- [MATCH3D_RUNTIME_3D_GEOMETRY_EXPERIMENT_2026-05-02.md](./MATCH3D_RUNTIME_3D_GEOMETRY_EXPERIMENT_2026-05-02.md):记录抓大鹅运行态 3D 几何体与物理碰撞实验的前端表现层边界、2D 回退要求和验收口径。
- [PLATFORM_MOBILE_BOTTOM_DOCK_VIEWPORT_FIX_2026-04-30.md](./PLATFORM_MOBILE_BOTTOM_DOCK_VIEWPORT_FIX_2026-04-30.md):记录平台首页底部 dock 在手机浏览器地址栏展开时脱离可见区域的根因,以及 `100dvh`、固定底部锚点和安全区占位的修复口径。
- [SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md](./SPACETIMEDB_JSON_STRING_MIGRATION_PROCEDURE_2026-04-27.md):记录 SpacetimeDB private 表迁移 JSON 导出/导入 procedure、迁移操作员授权、HTTP 413 分片导入、Jenkins 自动迁移回灌和导入脚本参数。
- [JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md](./JENKINS_SPACETIMEDB_DATABASE_MIGRATION_PIPELINES_2026-04-29.md):历史记录,保留 `Genarrative-Database-Export` / `Genarrative-Database-Import` 迁移参数、默认 dry-run、token 边界和 `CHUNK_SIZE` 413 规避经验;旧 Jenkinsfile 已删除,生产版入口以 `PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md` 为准。
@@ -26,7 +76,7 @@
- [RPG_CREATION_RESULT_VIEW_BACKEND_TRUTH_MIGRATION_2026-04-28.md](./RPG_CREATION_RESULT_VIEW_BACKEND_TRUTH_MIGRATION_2026-04-28.md):冻结 RPG 创作结果页保存、Agent session/result preview 真相优先级和结果页入口裁决迁移到后端 result-view 的落地边界。
- [RPG_CREATION_PROFILE_GENERATION_BACKEND_MIGRATION_2026-04-28.md](./RPG_CREATION_PROFILE_GENERATION_BACKEND_MIGRATION_2026-04-28.md):记录 RPG 创作 profile 生成移除非浏览器 legacy AI 回退,统一通过 `server-rs``/api/runtime/custom-world/profile` 生成世界底稿。
- [CREATION_PUBLIC_GALLERY_AND_AGENT_RESTORE_GUARD_FIX_2026-04-28.md](./CREATION_PUBLIC_GALLERY_AND_AGENT_RESTORE_GUARD_FIX_2026-04-28.md):记录 RPG Agent 旧 URL 恢复指针必须有本机用户归属才读取受保护 session以及 Big Fish 公开广场读取失败按空广场降级的修复口径。
- [BIG_FISH_DRAFT_PROGRESS_AND_SESSION_TIMEOUT_GUARD_FIX_2026-04-28.md](./BIG_FISH_DRAFT_PROGRESS_AND_SESSION_TIMEOUT_GUARD_FIX_2026-04-28.md):记录大鱼吃小鱼草稿进度页从单步 compile 改为多阶段感知展示,以及大鱼会话读取在 Maincloud 抖动时增加短重试与超时语义收口的修复口径。
- [BIG_FISH_DRAFT_PROGRESS_AND_SESSION_TIMEOUT_GUARD_FIX_2026-04-28.md](./BIG_FISH_DRAFT_PROGRESS_AND_SESSION_TIMEOUT_GUARD_FIX_2026-04-28.md):记录大鱼吃小鱼草稿进度页从单步 compile 改为多阶段感知展示,以及大鱼会话读取在 SpacetimeDB 抖动时增加短重试与超时语义收口的修复口径。
- [BIG_FISH_PROMPT_MODULE_EXTRACTION_2026-04-28.md](./BIG_FISH_PROMPT_MODULE_EXTRACTION_2026-04-28.md):记录大鱼吃小鱼草稿生成、生图、动作三类提示词从业务脚本中抽离到独立 `prompt/big_fish.rs` 模块的边界与职责划分。
- [BIG_FISH_MAIN_IMAGE_TRANSPARENT_BACKGROUND_ALIGNMENT_2026-04-28.md](./BIG_FISH_MAIN_IMAGE_TRANSPARENT_BACKGROUND_ALIGNMENT_2026-04-28.md):记录大鱼吃小鱼等级主图与动作关键帧正式图在 Rust 后端复用 RPG 角色主图透明背景 alpha 后处理的对齐口径,并明确场地背景不走该处理。
- [PUZZLE_IMAGE_AND_FRONTEND_RULES_ALIGNMENT_2026-04-29.md](./PUZZLE_IMAGE_AND_FRONTEND_RULES_ALIGNMENT_2026-04-29.md):记录拼图生成图片回到 1:1运行时拖动、交换、合并与拆分由前端即时裁决以及移动端棋盘贴近屏幕边缘的落地边界。
@@ -46,7 +96,7 @@
- [SPACETIMEDB_TABLE_CATALOG.md](./SPACETIMEDB_TABLE_CATALOG.md):持续维护当前 SpacetimeDB 表目录,按领域说明每张表的作用、字段结构、索引和常用 `spacetime sql` 查询模板。
- [RPG_OPENING_SCENE_ACT_IMAGE_PRESENTATION_SYNC_2026-04-26.md](./RPG_OPENING_SCENE_ACT_IMAGE_PRESENTATION_SYNC_2026-04-26.md):记录开局场景与普通场景复用同一场景展示解析服务,修复列表幕缩略图和详情幕背景预览图片不一致的问题。
- [FRONTEND_FIRST_LOAD_PERFORMANCE_FIX_2026-04-26.md](./FRONTEND_FIRST_LOAD_PERFORMANCE_FIX_2026-04-26.md):记录网站启动后首次加载约三分钟的前端根因,收口 `RouteImageReadyGate` 首屏图片门控和 Vite dev server 无关文件监听范围。
- [RPG_WORK_DELETE_SPACETIMEDB_PROCEDURE_EXPORT_FIX_2026-04-25.md](./RPG_WORK_DELETE_SPACETIMEDB_PROCEDURE_EXPORT_FIX_2026-04-25.md):记录 RPG 作品删除时报 `No such procedure` 的根因,补齐 `delete_custom_world_agent_session` 在有效 SpacetimeDB 模块入口中的导出,并要求发布后核验 Maincloud schema。
- [RPG_WORK_DELETE_SPACETIMEDB_PROCEDURE_EXPORT_FIX_2026-04-25.md](./RPG_WORK_DELETE_SPACETIMEDB_PROCEDURE_EXPORT_FIX_2026-04-25.md):记录 RPG 作品删除时报 `No such procedure` 的根因,补齐 `delete_custom_world_agent_session` 在有效 SpacetimeDB 模块入口中的导出,并要求发布后核验 schema。
- [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 方向只允许作为迁移参考。
- [RPG_DRAFT_GENERATION_CONTINUE_AND_ETA_FIX_2026-04-25.md](./RPG_DRAFT_GENERATION_CONTINUE_AND_ETA_FIX_2026-04-25.md):记录世界草稿生成失败/中断后进度不再误到 `100%`、主按钮改为“继续生成草稿”并复用已保存底稿续跑,以及按阶段耗时模型估算预计等待时间的修复口径。
- [RUNTIME_NPC_CHAT_LLM_MIGRATION_2026-04-25.md](./RUNTIME_NPC_CHAT_LLM_MIGRATION_2026-04-25.md):冻结运行时 NPC 聊天从 Rust 确定性兜底迁到 `platform-llm` 的边界,要求旧 Node 聊天提示词原样迁移,覆盖回复、建议、好感变化与限轮收束。
@@ -86,7 +136,7 @@
- [JENKINS_RUST_BUILD_DEPLOY_PIPELINES_2026-04-23.md](./JENKINS_RUST_BUILD_DEPLOY_PIPELINES_2026-04-23.md):历史记录,保留旧 Jenkins `构建 / 部署 / 构建并部署` 三条流水线的职责、版本号传递、上游触发门禁、本地目录部署脚本、发布包覆盖策略,以及部署阶段 SpacetimeDB schema 冲突自动导出、清库发布、导入回灌经验;旧 Jenkinsfile 已删除,生产版入口以 `PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md` 为准。
- [JENKINS_DEPLOY_ENV_BOM_FIX_2026-04-25.md](./JENKINS_DEPLOY_ENV_BOM_FIX_2026-04-25.md):记录 Jenkins 部署时 `.env.local` 首行 UTF-8 BOM 导致 `start.sh` 加载失败的根因,并冻结发布包构建、部署脚本和启动脚本的环境文件净化规则。
- [RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md](./RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md):历史记录,保留 Rust 本地一键联调脚本与旧 Ubuntu 发布包构建脚本的执行口径;生产发布链路以 `PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md` 的 systemd、Nginx、生产 Jenkinsfile 与归档产物拆分为准。
- [RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md](./RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md):记录当前 Rust `api-server` 已挂载的 Axum 路由,并补充管理 API 索引,按 auth、assets、runtime、custom world、story、generated path 等挂载面归类,用于对照 Node 能力基线与切流 smoke 清单。
- [RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md](./RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md):记录当前 Rust `api-server` 已挂载的 Axum 路由,并补充管理 API 索引,按 auth、assets、runtime、custom world、story 等挂载面归类,用于对照 Node 能力基线与切流 smoke 清单`/generated-*` 直读代理已下线
- [BACKEND_REWRITE_CROSS_CUTTING_GOVERNANCE_2026-04-22.md](./BACKEND_REWRITE_CROSS_CUTTING_GOVERNANCE_2026-04-22.md):冻结后端重写收口阶段的横向治理规则,覆盖 TypeScript contract 到 Rust DTO 映射、SpacetimeDB schema 演进、大对象 / workflow cache 存储边界和文档维护门禁。
- [PLATFORM_LLM_TEXT_GATEWAY_DESIGN_2026-04-21.md](./PLATFORM_LLM_TEXT_GATEWAY_DESIGN_2026-04-21.md)`platform-llm` 文本模型网关首版设计,冻结 OpenAI 兼容 `/chat/completions`、SSE 增量解析、错误模型与重试边界。
- [API_SERVER_PLATFORM_LLM_PROXY_DESIGN_2026-04-21.md](./API_SERVER_PLATFORM_LLM_PROXY_DESIGN_2026-04-21.md)`api-server` 接入 `platform-llm` 的最小代理设计,冻结 `/api/llm/chat/completions` 的配置、状态注入与首版非流式兼容边界。

View File

@@ -48,4 +48,4 @@ Agent 路由保持原有 submit/finalize 分工:
3. `cargo test -p api-server runtime_chat`
4. `cargo test -p api-server creation_agent_llm_turn`
5. `node scripts/check-encoding.mjs docs/technical/RPG_AND_AGENT_CHAT_TRUE_SSE_STREAMING_2026-04-26.md server-rs/crates/api-server/src/runtime_chat.rs server-rs/crates/api-server/src/custom_world.rs server-rs/crates/api-server/src/big_fish.rs docs/technical/README.md`
6. 修改后端代码后,使用 `npm run api-server:maincloud` 重启后端。
6. 修改后端代码后,使用 `npm run api-server` 重启后端。

View File

@@ -0,0 +1,40 @@
# RPG foundation draft 场景骨架批次超时修正2026-05-02
## 背景
现场底稿生成失败信息:
```text
agent-foundation-landmark-seed-batch-1 LLM 请求失败LLM 请求超时,累计尝试 2 次
```
本次 `logs/llm-raw` 对应请求体没有 `tools` / `web_search` 字段,说明 2026-05-01 已落地的联网搜索降级并不是本次失败根因。失败发生在无搜索 Responses 请求自身超时。
## 根因
`agent-foundation-landmark-seed-batch-1` 原本一次要求模型生成 2 个场景。每个场景又必须包含:
1. 场景基础字段。
2. `sceneTaskDescription`
3. 3 条 `actBackgroundPromptTexts`
4. 3 条 `actEventDescriptions`
5. 3 个 `actNPCNames`
6. 相连场景和进入钩子。
这个批次的输出密度明显高于角色 outline 批次。深海题材现场输入下,单次 prompt 已要求开局场景和普通关键场景同时生成Responses 请求在默认 30 秒超时窗口内连续两次未完成,最终导致 operation 失败。
## 落地策略
1. 保持 `FOUNDATION_DRAFT_LANDMARK_COUNT = 2` 不变,仍生成 1 个开局场景和 1 个普通关键场景。
2.`FOUNDATION_LANDMARK_BATCH_SIZE``2` 收敛为 `1`
3. 第一批只生成开局场景,并继续作为 `camp` 写入。
4. 第二批只生成普通关键场景,带上已生成场景名作为 forbidden names避免重复开局场景。
5. 单场景开局 prompt 不再写“一次性生成开局场景和普通关键场景”,避免模型在 batch_count=1 时被旧文案诱导多产。
## 验收标准
1. `generate_custom_world_foundation_draft_uses_seed_text_and_normalizes_fields` 中必须捕获 2 个 `场景框架名单` 请求。
2. 第 1 个场景请求必须明确“本批场景必须是玩家进入世界时所在的开局场景”。
3. 第 2 个场景请求必须明确“本批只生成普通关键场景”,并带上已生成开局场景名的禁止重复约束。
4. 编译后的 `camp` 仍来自第 1 个生成场景,`landmarks` 仍只保留后续普通关键场景。
5. 运行 `cargo test -p api-server custom_world_foundation_draft --manifest-path server-rs/Cargo.toml` 通过。

View File

@@ -0,0 +1,45 @@
# RPG foundation draft LLM 联网搜索降级修正2026-05-01
## 背景
本次现场错误为:
```text
agent-foundation-story-outline-batch-1 LLM 请求失败LLM 请求超时,累计尝试 2 次
```
同一轮 `logs/llm-raw` 还记录了前置 `ToolNotOpen`
```text
Your account has not activated web search.
```
当前 `custom_world_foundation_draft.rs` 的分阶段底稿生成全部硬编码 `.with_web_search(true)`。但这些批次只根据 Agent 已收集的八锚点、世界骨架、角色名单和场景名单生成结构化 JSON本身不需要实时联网检索联网搜索只能作为模板创作的增强能力不能成为 foundation draft 的必经前置。
## 根因
1. `generate_custom_world_foundation_draft(...)` 没有接收 `AppConfig.creation_agent_llm_web_search_enabled`
2. `request_foundation_json_stage(...)` 对所有 Responses 请求固定开启 `web_search`
3. 非流式 foundation draft 调用没有复用创作 Agent SSE turn 中的 `ToolNotOpen` 降级策略。
4. 当账号未开通 web search 或搜索工具链响应慢时,底稿批次会在内部 JSON 生成阶段失败,最终 operation 进入 failed。
## 落地策略
1. `api-server` 调用 foundation draft 生成器时显式传入 `state.config.creation_agent_llm_web_search_enabled`
2. foundation draft 每个业务 JSON 阶段先按配置决定是否带 `tools: [{ type: "web_search", max_keyword: 3 }]`
3. 若开启搜索后出现以下错误,自动使用同一 system/user prompt 无搜索重试一次:
- `ToolNotOpen`
- `has not activated web search`
- `未开通`
- 上游连接失败
- 请求超时
4. JSON 修复阶段继续不启用搜索,因为修复只处理已有响应文本。
5. SpacetimeDB reducer / procedure 不新增任何外部 I/O仍只接收 api-server 已生成的确定性 `draftProfile` 并落库。
## 验收标准
1. `agent-foundation-*-batch-*` 首次搜索增强失败时,日志出现一次降级 warningoperation 不应直接失败。
2. 降级重试请求体不再包含 `tools` / `web_search`
3. `GENARRATIVE_CREATION_AGENT_LLM_WEB_SEARCH_ENABLED=false`foundation draft 全流程直接不带搜索工具。
4. `cargo test -p api-server custom_world_foundation_draft --manifest-path server-rs/Cargo.toml` 通过。
5. 修改后按项目约束使用 `npm run api-server:maincloud` 重启后端。

View File

@@ -0,0 +1,43 @@
# RPG foundation draft 角色养成档案超时兜底2026-05-02
## 背景
场景骨架批次拆小后,现场底稿生成继续失败在角色养成档案阶段:
```text
agent-foundation-story-dossier-batch-1 LLM 请求失败LLM 请求超时,累计尝试 2 次
```
同一轮 `logs/llm-raw` 还出现过:
```text
agent-foundation-playable-dossier-batch-1 LLM 请求失败LLM 请求超时,累计尝试 2 次
```
这些请求体都没有 `tools` / `web_search` 字段,说明本次不是联网搜索降级问题,而是无搜索 Responses 请求在角色 `dossier` 阶段自身超时。
## 根因
`dossier` 阶段要求模型为角色补齐 `backstoryReveal``skills``initialItems`。这部分属于结果页和运行时可继续编辑的养成档案润色,不是底稿主链必须依赖 LLM 才能成立的业务真相。
在深海题材现场输入下,即使单个可扮演角色的养成档案请求也发生超时;继续只靠减小 batch size 不能保证主链稳定。
## 落地策略
1. `narrative` 阶段仍保持 LLM 生成,因为它补的是角色背景、性格、动机和行动风格。
2. `dossier` 阶段改为 LLM 优先。
3.`dossier` 阶段发生请求超时、连接失败、上游失败、空响应或 JSON 解析失败,不再让底稿 operation 失败。
4. 兜底使用当前角色对象本地生成:
- `backstoryReveal.publicSummary`
- 4 个固定好感档位章节,档位为 `15 / 30 / 60 / 90`
- 3 个技能
- 3 个初始物品
5. 本地兜底只补缺字段,不覆盖模型已经成功生成的完整字段。
6. SpacetimeDB 仍只接收 api-server 生成后的确定性 `draftProfile`;不新增外部 I/O。
## 验收标准
1. `story-dossier` 超时后,底稿生成继续完成,角色仍包含 `backstoryReveal / skills / initialItems`
2. fallback 后的角色名必须与输入角色名一致,不能增删改名。
3. `backstoryReveal.chapters` 必须恰好 4 个,`affinityRequired` 固定为 `15 / 30 / 60 / 90`
4. `cargo test -p api-server custom_world_foundation_draft --manifest-path server-rs/Cargo.toml` 通过。

View File

@@ -10,7 +10,7 @@
2. `GET /api/runtime/custom-world-gallery`
3. 个人看板、浏览历史、存档等私有数据
其中 `custom-world-library` 通过 `api-server -> spacetime-client -> list_custom_world_profiles procedure` 读取当前用户作品。旧实现把每个作品的完整 `profile_payload_json` 一并返回给首页列表,而首页卡片只需要标题、摘要、封面、状态和计数字段。用户作品较多或 Maincloud 连接抖动时,这个 procedure 容易超过 `spacetime-client` 固定 `10s` 等待窗口,最终由 Axum 映射成 `502 Bad Gateway`,前端控制台显示 `SpacetimeDB procedure 调用超时`
其中 `custom-world-library` 通过 `api-server -> spacetime-client -> list_custom_world_profiles procedure` 读取当前用户作品。旧实现把每个作品的完整 `profile_payload_json` 一并返回给首页列表,而首页卡片只需要标题、摘要、封面、状态和计数字段。用户作品较多或 SpacetimeDB 连接抖动时,这个 procedure 容易超过 `spacetime-client` 固定 `10s` 等待窗口,最终由 Axum 映射成 `502 Bad Gateway`,前端控制台显示 `SpacetimeDB procedure 调用超时`
## 2. 修复口径
@@ -19,8 +19,8 @@
1. `list_custom_world_profiles` 仍保持旧 procedure 名称和返回 envelope避免本轮重新生成 bindings。
2. 列表返回的 `profile_payload_json` 改为轻量摘要 JSON只包含首页卡片和标签兜底需要的少量字段。
3. 单条详情、发布、下架、编辑继续使用完整 profile snapshot确保进入详情或结果页时仍有完整世界数据。
4. `spacetime-client` 的 procedure 等待窗口从硬编码 `10s` 改为可配置,Maincloud 默认使用更宽的窗口吸收连接冷启动与短时抖动。
5. Axum 的 `GET /api/runtime/custom-world-library` 首屏接口改走已有 `custom-world/works` 轻量读模型,并在用户点击详情/编辑时再调用 owner-only detail 接口取完整 profile避免 Maincloud wasm 尚未发布轻量 profile procedure 时首页继续命中重 procedure。
4. `spacetime-client` 的 procedure 等待窗口从硬编码 `10s` 改为可配置,用更宽的窗口吸收连接冷启动与短时抖动。
5. Axum 的 `GET /api/runtime/custom-world-library` 首屏接口改走已有 `custom-world/works` 轻量读模型,并在用户点击详情/编辑时再调用 owner-only detail 接口取完整 profile避免 wasm 尚未发布轻量 profile procedure 时首页继续命中重 procedure。
## 3. 轻量 profile JSON 字段
@@ -47,4 +47,4 @@
3. `cargo check -p spacetime-client` 通过。
4. `cargo check -p api-server` 通过。
5. `npm run check:encoding` 通过。
6. 修改后按项目约束使用 `npm run api-server:maincloud` 重启后端。
6. 修改后按项目约束使用 `npm run api-server` 重启后端。

View File

@@ -0,0 +1,76 @@
# RPG 图片生成 gpt-image-2 迁移 2026-05-02
## 背景
RPG 创作链路里有两类正式图片资产需要统一模型:
1. 角色主图候选生成。
2. 场景幕背景图生成。
旧实现中角色主图默认使用 `wan2.7-image-pro`,场景图根据是否有参考图分别使用 DashScope 文生图与图生图模型。拼图链路已经接入 APIMart 的 OpenAI 兼容 `/images/generations`,并以 `gpt-image-2` 作为默认图片模型,因此本次 RPG 图片迁移复用同一类服务端配置与请求口径。
## 落地范围
1. `POST /api/assets/character-visual/generate`
- 前端默认 `imageModel` 改为 `gpt-image-2`
- 后端把空值、历史 `wan2.7-image-pro``wan2.7-image` 统一归一为 `gpt-image-2`
- 继续保留角色主图 prompt、负向 prompt、审核失败后原创安全 prompt 兜底、PNG 去绿幕/去白底、OSS 草稿与发布链路。
2. `POST /api/runtime/custom-world/scene-image`
- 文生图与参考图生图统一走 `gpt-image-2`
- 参考图继续只支持 Data URL 与 `/generated-*` 旧路径,经服务端回读后传给上游。
- 继续保留场景 prompt 编译、负向 prompt、OSS、`asset_object``asset_entity_binding` 链路。
3. 自动草稿资产生成中的角色主图与幕背景图分别复用上述后端函数,因此同步使用 `gpt-image-2`
## 上游协议
服务端使用:
```text
POST {APIMART_BASE_URL}/images/generations
Authorization: Bearer {APIMART_API_KEY}
model = gpt-image-2
```
请求体统一包含:
1. `model`
2. `prompt`
3. `n`
4. `size`
5. 有参考图时增加 `image_urls`
尺寸归一规则:
1. `1024*1024``1024x1024``1:1` -> `1:1`
2. `1280*720``1600*900``16:9` -> `16:9`
响应解析兼容同步 `data[].url``data[].b64_json` 与异步 `task_id` / `GET /tasks/{task_id}` 结构。
## 非范围
1. 不迁移角色动作图片序列帧或视频模型。
2. 不迁移 Custom World 封面图生成。
3. 不改变 SpacetimeDB 表结构、migration 或 bindings。
4. 不改变前端 UI 面板文案。
## 配置
本次复用已有 APIMart 配置:
```text
APIMART_BASE_URL=https://api.apimart.ai/v1
APIMART_API_KEY=...
APIMART_IMAGE_REQUEST_TIMEOUT_MS=180000
```
`APIMART_API_KEY` 缺失时,角色主图与场景图返回 `SERVICE_UNAVAILABLE``details.provider = "apimart"`
## 验收
1. 角色主图生成请求上游 `model``gpt-image-2`
2. 场景图生成请求上游 `model``gpt-image-2`
3. 旧前端或历史草稿传 `wan2.7-image-pro` 时不会回退旧模型。
4. 场景参考图生成仍能把参考图 Data URL 放入 `image_urls`
5. 角色主图生成后仍执行原有 PNG 透明背景处理与 OSS 写入。
6. `cargo test -p api-server character_visual --manifest-path server-rs/Cargo.toml` 通过。
7. `cargo test -p api-server custom_world_ai --manifest-path server-rs/Cargo.toml` 通过。

View File

@@ -83,7 +83,7 @@
6. 修改后执行:
- Rust 相关测试。
- TypeScript 相关测试。
- `npm run api-server:maincloud`
- `npm run api-server`
## 5. 本次实现结果

View File

@@ -91,7 +91,7 @@ server-rs/crates/api-server/src/prompt/rpg/
1. `npm run check:encoding`
2. `npm run test -- src/services/ai.test.ts src/hooks/rpg-runtime-story/storyResponseOptions.test.ts`
3. `cargo check -p api-server`
4. `npm run api-server:maincloud`
4. `npm run api-server`
## 后续编辑约定

View File

@@ -81,7 +81,7 @@ npm run typecheck -- --pretty false
npm run check:encoding
```
局部测试、局部 ESLint、全量类型检查与编码检查均通过。后端代码未在本次任务中修改因此未执行 `npm run api-server:maincloud`
局部测试、局部 ESLint、全量类型检查与编码检查均通过。后端代码未在本次任务中修改因此未执行 `npm run api-server`
## 2026-04-27 第二轮复查修正
@@ -123,7 +123,7 @@ npm test -- --run src/data/sceneEncounterPreviews.test.ts src/hooks/rpg-runtime-
npx eslint src/data/sceneEncounterPreviews.ts src/data/sceneEncounterPreviews.test.ts src/services/customWorldSceneActRuntime.ts src/hooks/rpg-runtime-story/storyChoiceRuntime.ts src/hooks/rpg-runtime-story/storyChoiceRuntime.test.ts src/hooks/rpg-runtime-story/uiTypes.ts src/components/rpg-runtime-panels/RpgAdventurePanelOverlays.tsx
```
以上局部测试与局部 ESLint 已通过。后端代码未在本轮修改中触碰,因此不需要执行 `npm run api-server:maincloud`
以上局部测试与局部 ESLint 已通过。后端代码未在本轮修改中触碰,因此不需要执行 `npm run api-server`
## 2026-04-27 第三轮复查修正
@@ -149,7 +149,7 @@ npx eslint src/hooks/rpg-session/useRpgSessionBootstrap.ts src/hooks/useGameFlow
npm run typecheck -- --pretty false
```
以上局部测试、局部 ESLint 与全量类型检查已通过。后端代码未在本轮修改中触碰,因此仍不需要执行 `npm run api-server:maincloud`
以上局部测试、局部 ESLint 与全量类型检查已通过。后端代码未在本轮修改中触碰,因此仍不需要执行 `npm run api-server`
## 2026-04-27 第四轮复查修正
@@ -183,7 +183,7 @@ npm run typecheck -- --pretty false
npm run check:encoding
```
以上相关测试、局部 ESLint、全量类型检查与编码检查均通过。后端代码未在本轮修改中触碰因此未执行 `npm run api-server:maincloud`
以上相关测试、局部 ESLint、全量类型检查与编码检查均通过。后端代码未在本轮修改中触碰因此未执行 `npm run api-server`
## 2026-04-27 第五轮误导链路闭口
@@ -232,4 +232,4 @@ npx eslint src/hooks/rpg-session/useRpgSessionBootstrap.ts src/hooks/useGameFlow
npm run typecheck -- --pretty false
```
以上测试、ESLint 与类型检查已通过。后端代码未在本轮修改中触碰,因此仍不需要执行 `npm run api-server:maincloud`
以上测试、ESLint 与类型检查已通过。后端代码未在本轮修改中触碰,因此仍不需要执行 `npm run api-server`

View File

@@ -4,15 +4,15 @@
创作页或作品详情删除 RPG 作品时报 `No such procedure`
本次核对 Maincloud `xushi-p4wfr` schema 后确认:
本次核对 `xushi-p4wfr` schema 后确认:
1. 已发布 / 作品库 profile 删除依赖 `delete_custom_world_profile_and_return`
2. 草稿作品删除依赖 `delete_custom_world_agent_session`
3. 本地 Rust client 绑定里存在 `delete_custom_world_agent_session`,但 Maincloud schema 中没有该 procedure。
3. 本地 Rust client 绑定里存在 `delete_custom_world_agent_session`,但目标 schema 中没有该 procedure。
## 根因
`server-rs/crates/spacetime-module/src/custom_world/mod.rs` 中有一份草稿删除实现,但当前有效发布入口仍是 `server-rs/crates/spacetime-module/src/lib.rs` 中的 custom world 实现。`lib.rs` 未导出 `delete_custom_world_agent_session`,导致发布到 Maincloud 的模块 schema 缺少该 procedure。
`server-rs/crates/spacetime-module/src/custom_world/mod.rs` 中有一份草稿删除实现,但当前有效发布入口仍是 `server-rs/crates/spacetime-module/src/lib.rs` 中的 custom world 实现。`lib.rs` 未导出 `delete_custom_world_agent_session`,导致发布的模块 schema 缺少该 procedure。
## 落地口径
@@ -31,7 +31,7 @@
1. `cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml`
2. `npm run check:encoding`
3. `npm run spacetime:publish:maincloud`
4. 发布后用 `spacetime describe xushi-p4wfr --server maincloud --json` 确认 schema 包含:
3. 发布最新 SpacetimeDB wasm。
4. 发布后用 `spacetime describe xushi-p4wfr --server <目标服务> --json` 确认 schema 包含:
- `delete_custom_world_profile_and_return`
- `delete_custom_world_agent_session`

View File

@@ -2,6 +2,10 @@
更新时间:`2026-05-01`
> 2026-04-29 补充本文件保留为迁移期路由快照。DDD G1 后续并行工作的契约冻结口径以 [`SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md`](./SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md) 为准,尤其是新增的 Big Fish、Puzzle、profile、runtime chat、story facade 和兼容路由删除计划。
>
> 2026-04-29 WP-RS 进度:旧 `/api/runtime/story/*` HTTP compat 路由已从 `api-server/src/app.rs` 取消挂载,并删除 `api-server/src/runtime_story*` 兼容实现。当前 Rust `api-server` 对外 story 主链只保留 `/api/story/*`、`/api/runtime/sessions/{runtime_session_id}/inventory` 与 runtime chat 相关路由。
## 1. 文档目标
本文件记录当前 `server-rs/crates/api-server/src/app.rs` 中已挂载的 Rust Axum 路由面,用于对照 Node 后端 `96` 条路由能力基线。
@@ -22,7 +26,7 @@
8. llm proxy 接口:`1` 条。
9. profile / runtime profile 接口:`12` 条。
10. runtime story / story gameplay 接口:`15` 条。
11. legacy generated 静态路径兼容`6`
11. legacy generated 静态标识`6` 类历史路径字符串,直读代理已下线
12. health check`1` 条。
## 3. 路由清单
@@ -154,28 +158,18 @@
1. `POST /api/runtime/save/snapshot`
2. `GET /api/runtime/settings`
3. `GET /api/runtime/story/state/{session_id}`
4. `POST /api/runtime/story/state/resolve`
5. `POST /api/runtime/story/actions/resolve`
6. `POST /api/runtime/story/initial`
7. `POST /api/runtime/story/continue`
8. `POST /api/story/sessions`
9. `POST /api/story/sessions/continue`
10. `GET /api/story/sessions/{story_session_id}/state`
11. `POST /api/story/battles`
12. `POST /api/story/battles/resolve`
13. `GET /api/story/battles/{battle_state_id}`
14. `POST /api/story/npc/battle`
15. `GET /api/runtime/sessions/{runtime_session_id}/inventory`
3. `POST /api/story/sessions`
4. `POST /api/story/sessions/continue`
5. `GET /api/story/sessions/{story_session_id}/state`
6. `POST /api/story/battles`
7. `POST /api/story/battles/resolve`
8. `GET /api/story/battles/{battle_state_id}`
9. `POST /api/story/npc/battle`
10. `GET /api/runtime/sessions/{runtime_session_id}/inventory`
### 3.11 Legacy Generated 路径
1. `GET /generated-character-drafts/{*path}`
2. `GET /generated-characters/{*path}`
3. `GET /generated-animations/{*path}`
4. `GET /generated-custom-world-scenes/{*path}`
5. `GET /generated-custom-world-covers/{*path}`
6. `GET /generated-qwen-sprites/{*path}`
`/generated-*` 直读代理已下线。生成资产读取统一走 `GET /api/assets/read-url` 或 asset object projection`/generated-*` 字符串仅作为 `legacyPublicPath` / OSS object key 兼容标识保留。
### 3.12 Health

View File

@@ -114,9 +114,9 @@ npm run dev:rust:logs -- --follow
2. 仅供测试断言使用的辅助函数使用 `#[cfg(test)]` 限定,避免进入 `cargo run -p api-server` 的普通二进制编译。
3. 已无调用入口且无迁移价值的映射函数直接删除;如果后续新增同类 SpacetimeDB 记录映射,再按实际调用路径补回,避免提前保留死代码。
Maincloud API 重启补充:
api-server 单独重启补充:
1. `npm run api-server:maincloud` 会先读取 `.env``.env.local``GENARRATIVE_SPACETIME_MAINCLOUD_*` 映射为 `api-server` 使用 `GENARRATIVE_SPACETIME_*`,再运行 `cargo run -p api-server --manifest-path server-rs/Cargo.toml`
1. `npm run api-server` 会先读取 `.env``.env.local`,使用 `GENARRATIVE_SPACETIME_*` 启动 `cargo run -p api-server --manifest-path server-rs/Cargo.toml`
2. Windows 下脚本会尽力停止本仓库 `server-rs/target/debug/api-server.exe` 对应的旧进程,避免 cargo 重新编译时 exe 被占用。
3. 旧进程已经退出或清理过程中出现瞬时等待失败时,不应阻断新的 `api-server` 启动;脚本只记录清理失败并继续启动。
@@ -193,7 +193,7 @@ cd build/<timestamp>
./stop.sh
```
如果后续通过 Jenkins 的部署脚本把发布包覆盖到固定部署目录,部署阶段默认只替换 `web/``api-server``spacetime_module.wasm``migration-bootstrap-secret.txt``scripts/``.env*``start.sh``stop.sh``web-server.mjs``README.md` 等发布产物;后台管理前端位于 `web/admin/`,随 `web/` 一并覆盖。文件产物使用普通复制,`web/``scripts/` 等目录产物递归复制,不会删除部署目录中的 `.spacetimedb/``logs/``run/``deploy-state/``database-migrations/` 这类运行态目录。Jenkins 覆盖 `.env.local` 时会保留目标部署目录已有的 `GENARRATIVE_SPACETIME_TOKEN` / `GENARRATIVE_SPACETIME_MAINCLOUD_TOKEN`,避免后台表统计在部署后失去读取 private 表所需的 owner 身份。
如果后续通过 Jenkins 的部署脚本把发布包覆盖到固定部署目录,部署阶段默认只替换 `web/``api-server``spacetime_module.wasm``migration-bootstrap-secret.txt``scripts/``.env*``start.sh``stop.sh``web-server.mjs``README.md` 等发布产物;后台管理前端位于 `web/admin/`,随 `web/` 一并覆盖。文件产物使用普通复制,`web/``scripts/` 等目录产物递归复制,不会删除部署目录中的 `.spacetimedb/``logs/``run/``deploy-state/``database-migrations/` 这类运行态目录。Jenkins 覆盖 `.env.local` 时会保留目标部署目录已有的 `GENARRATIVE_SPACETIME_TOKEN`,避免后台表统计在部署后失去读取 private 表所需的 owner 身份。
安全边界:

View File

@@ -0,0 +1,393 @@
# server-rs DDD 一次性重构落地方案
日期:`2026-04-28`
## 1. 背景与当前结论
当前仓库已经进入 `server-rs + Axum + SpacetimeDB` 单一后端路线,旧 `server-node` 已不存在,后续不再围绕 Express / PostgreSQL 做兼容设计。本轮重构目标不是新增玩法,而是把已有 Rust 后端统一成可长期演进的 DDD 边界:
1. 领域规则沉到 `module-*`
2. SpacetimeDB 事务、表、reducer、procedure 留在 `spacetime-module`
3. HTTP / SSE / BFF 留在 `api-server`
4. 外部副作用留在 `platform-*``api-server` 应用编排层。
5. 前后端 DTO 留在 `shared-contracts`,跨领域纯值处理留在 `shared-kernel`
本文件是后续编码前的总纲。若局部历史文档与本文冲突,以本文和对应 SpacetimeDB skill 为准;若本文仍无法精准指导某一处编码,必须先补本文或新增更细技术文档,再继续改工程。
## 2. 依赖方向
允许方向:
```text
api-server
-> shared-contracts
-> module-*
-> spacetime-client
-> platform-*
spacetime-module
-> module-*
-> shared-kernel
module-*
-> shared-kernel
-> 其他 module-* 的纯领域类型(仅在确有跨域规则复用时)
platform-*
-> shared-kernel
shared-contracts
-> shared-kernel
```
禁止方向:
1. `module-*` 直接依赖 Axum、HTTP client、OSS、LLM、文件系统、SpacetimeDB table/reducer/procedure API。
2. `module-*` 新增 `mapper.rs`,映射只能落在 adapter crate。
3. `spacetime-module` 反向依赖 `api-server``spacetime-client``platform-*`
4. `shared-kernel` / `shared-contracts` 依赖业务 crate。
5. 前端绕过 Axum 直接承接后端业务规则或数据真相。
阶段性例外必须满足三个条件:
1. 在本文“阶段性债务表”登记。
2. 有明确迁出目标 crate。
3. 不允许继续扩大例外范围。
## 3. crate 职责矩阵
| crate | 职责 | 禁止内容 |
| --- | --- | --- |
| `module-ai` | AI 任务、阶段、流式片段、结果引用的纯领域模型和状态机 | 真实 LLM 调用、HTTP、SSE |
| `module-assets` | 资产对象、资产绑定、历史查询输入输出和纯校验规则 | OSS head、reqwest、进程内 fallback store 扩散到领域核心 |
| `module-auth` | 用户、会话、验证码、微信绑定、密码规则、领域错误 | 文件持久化、真实短信副作用、HTTP cookie 写入 |
| `module-big-fish` | 大鱼创作会话、素材槽、运行态规则 | 图片生成、OSS 上传、HTTP handler |
| `module-combat` | 战斗聚合、行动结算、奖励结果 | 直接写背包表、直接发放成长账本 |
| `module-custom-world` | 世界 profile、Agent 会话、草稿卡、发布门禁规则 | LLM 推理、OSS、Axum response shape |
| `module-inventory` | 背包、装备槽、堆叠与消耗规则 | SpacetimeDB table 操作 |
| `module-npc` | NPC 关系、好感、互动、招募规则 | 战斗表初始化事务 |
| `module-progression` | 玩家等级、章节预算、经验记账规则 | 查询前端视图拼装 |
| `module-puzzle` | 拼图创作与运行态纯规则 | 图片生成、排行榜 HTTP shape |
| `module-quest` | 任务领取、推进、完成、交付规则 | 奖励跨域副作用直接写表 |
| `module-runtime` | 运行时设置、快照、个人页状态、存档领域模型 | 直接读写 SpacetimeDB |
| `module-runtime-item` | 宝箱、奖励物品、运行时物品快照 | 背包持久化事务 |
| `module-runtime-story` | RPG runtime story 新接口下的纯应用编排、剧情投影、场景旅行、战后收束、prompt context 投影 | Axum、LLM、SpacetimeDB |
| `module-story` | story session、story event 与推进输入输出 | 直接调用 LLM 或 HTTP |
| `spacetime-module` | 表、reducer、procedure、事务内查询写回、row/snapshot mapper、event table | 领域规则大段堆叠 |
| `spacetime-client` | api-server 调用 SpacetimeDB 的客户端 facade 与绑定 mapper | 领域规则 |
| `api-server` | 路由、鉴权上下文、请求响应映射、SSE、平台服务编排 | 表结构定义、领域规则主逻辑 |
| `platform-*` | JWT/SMS/微信/OSS/LLM/HTTP client 等外部能力 | 玩法领域规则 |
| `shared-kernel` | 字符串、时间、ID、纯值归一化 | 业务流程 |
| `shared-contracts` | HTTP/前端 DTO、兼容 response shape | 领域状态机 |
## 4. 统一目录结构
所有 `module-*` 必须具备以下文件。第一阶段允许旧实现仍在 `lib.rs` 或历史子模块中,但新增和迁移代码必须进入对应落点。
```text
src/
├─ lib.rs
├─ domain.rs 或 domain/
├─ commands.rs
├─ application.rs
├─ events.rs
└─ errors.rs
```
落位规则:
1. `domain.rs` / `domain/*`:聚合、值对象、领域方法、纯校验、状态迁移。
2. `commands.rs`:写入用例输入,只表达意图和必要参数,不含 adapter 类型。
3. `application.rs`:纯应用编排函数,输出领域事件或应用结果,不执行外部副作用。
4. `events.rs`:领域事件和跨上下文事件,例如奖励待入账、画廊投影待刷新。
5. `errors.rs`:领域错误,优先可测试、可映射,不直接绑定 HTTP status。
6. `mapper.rs`:只允许在 `api-server``spacetime-module``spacetime-client` 等 adapter crate 中出现。
## 5. 上下文设计清单
### 5.1 认证 `module-auth`
聚合:
1. `AuthUser`账号、公开百梦号、登录方式、绑定状态、token version。
2. `RefreshSession`refresh token hash、客户端信息、过期、吊销、last seen。
3. `SmsVerification`:手机号、场景、验证码状态、冷却、失败次数。
4. `WechatBinding`:微信 provider 身份、union id、绑定状态。
命令:
1. `PasswordEntryInput`
2. `SendPhoneCodeInput`
3. `PhoneLoginInput`
4. `CreateRefreshSessionInput`
5. `RevokeRefreshSessionInput`
6. `ResolveWechatLoginInput`
事件:
1. `AuthUserCreated`
2. `RefreshSessionIssued`
3. `RefreshSessionRevoked`
4. `PhoneCodeAccepted`
5. `WechatIdentityLinked`
读模型:
1. `AuthMeResult`
2. `PublicUserSearchResult`
3. `AuthSessionListResult`
迁移要求:文件持久化和内存 store 从领域核心剥离到 adapter 或临时测试支撑;短信真实发送继续在 `platform-auth`
### 5.2 资产 `module-assets`
聚合:
1. `AssetObject`bucket、object key、访问策略、hash、版本、业务归属。
2. `AssetEntityBinding`:实体类型、实体 id、slot、资产对象 id。
命令:
1. `ConfirmAssetObjectInput`
2. `AssetObjectUpsertInput`
3. `AssetEntityBindingInput`
4. `AssetHistoryListInput`
事件:
1. `AssetObjectConfirmed`
2. `AssetEntityBindingChanged`
读模型:
1. `AssetObjectUpsertSnapshot`
2. `AssetEntityBindingSnapshot`
3. `AssetHistoryEntrySnapshot`
迁移要求OSS `head_object`、reqwest client 和 fallback store 不再放入领域核心SpacetimeDB 持久化由 `spacetime-module` 完成。
### 5.3 RPG 运行时
覆盖 `module-story``module-combat``module-inventory``module-npc``module-progression``module-quest``module-runtime-item`
聚合:
1. `StorySession``StoryEvent`
2. `BattleState`
3. `InventorySlot`
4. `NpcState`
5. `PlayerProgression``ChapterProgression`
6. `QuestRecord``QuestLog`
7. `TreasureRecord`
跨上下文事件:
1. `CombatVictoryResolved`
2. `QuestTurnedIn`
3. `InventoryItemsGranted`
4. `ProgressionXpGranted`
5. `NpcRelationChanged`
6. `RuntimeStoryProjectionChanged`
事务边界:
1. 单聚合变更在对应 `module-*` 纯函数中完成。
2. 战斗奖励、任务奖励、背包写入、成长记账由 `spacetime-module` 或应用服务显式编排。
3. reducer/procedure 不允许复制领域规则,只负责取 row、调用领域函数、写回 row 和事件表。
### 5.4 世界创作 `module-custom-world`
聚合:
1. `CustomWorldProfile`
2. `CustomWorldSession`
3. `CustomWorldAgentSession`
4. `CustomWorldAgentMessage`
5. `CustomWorldAgentOperation`
6. `CustomWorldDraftCard`
7. `CustomWorldGalleryEntry`
命令:
1. 创建/恢复 Agent 会话。
2. 写入用户消息。
3. 写入 LLM 最终回复。
4. 更新草稿卡。
5. 发布/下架 profile。
事件:
1. `CustomWorldDraftChanged`
2. `CustomWorldProfilePublished`
3. `CustomWorldGalleryProjectionChanged`
4. `CustomWorldAgentOperationProgressed`
迁移要求LLM 提示词和推理在 `api-server + platform-llm`SpacetimeDB 只落真相表和投影。
### 5.5 拼图 `module-puzzle`
聚合:
1. `PuzzleAgentSession`
2. `PuzzleAgentMessage`
3. `PuzzleWorkProfile`
4. `PuzzleRuntimeRun`
事件:
1. `PuzzleDraftChanged`
2. `PuzzleWorkPublished`
3. `PuzzleRunAdvanced`
读模型:
1. 作品卡片。
2. 运行态快照。
3. 排行榜结果。
### 5.6 大鱼吃小鱼 `module-big-fish`
聚合:
1. `BigFishCreationSession`
2. `BigFishAgentMessage`
3. `BigFishAssetSlot`
4. `BigFishRuntimeRun`
事件:
1. `BigFishDraftChanged`
2. `BigFishAssetSlotChanged`
3. `BigFishRunTicked`
### 5.7 AI `module-ai`
聚合:
1. `AiTask`
2. `AiTaskStage`
3. `AiTextChunk`
4. `AiResultReference`
事件:
1. `AiTaskStarted`
2. `AiTaskStageCompleted`
3. `AiTaskFailed`
4. `AiResultAttached`
边界:真实模型调用只在 `platform-llm``module-ai` 只表达状态机。
## 6. SpacetimeDB adapter 映射
`spacetime-module` 中每个上下文遵循:
```text
src/<context>/
├─ mod.rs
├─ tables.rs # table 和 public/event 标记
├─ reducers.rs # 客户端可调用写入口
├─ procedures.rs # 需要同步返回或外部 procedure 语义的入口
├─ mapper.rs # row <-> module-* snapshot/input
└─ queries.rs # 事务内查询辅助,只返回 adapter DTO
```
当前已有历史拆分与本文不同名时,先按现有文档继续维护;新增或迁移时逐步对齐上面结构。
Reducer / procedure 规则:
1. reducer 使用 `&ReducerContext`,返回 `Result<(), String>` 处理预期错误。
2. reducer 内授权必须基于 `ctx.sender()`,禁止信任参数中的身份。
3. reducer 禁止网络、文件系统、外部随机数和全局状态。
4. procedure 使用 SpacetimeDB 2.0 正确 API涉及事务必须显式 `with_tx` / `try_with_tx`
5. 表访问必须使用 `ctx.db.table()`,更新只通过主键。
6. 复杂查询不复用写模型;需要前端订阅时新增明确读模型或 public 投影表。
## 7. 表结构约束
默认不改现有 SpacetimeDB 主表。确需改表时按以下优先级:
1. 新增 optional 字段。
2. 新增投影表或 event table。
3. 新增索引。
4. 最后才考虑 rename/delete/type change且必须单独写迁移方案。
任何 table 变更必须同步:
1. `server-rs/crates/spacetime-module/src/migration.rs`
2. `docs/technical/SPACETIMEDB_TABLE_CATALOG.md`
3. 对应 reducer/procedure 测试或最小 smoke
4. 绑定生成和前端/`spacetime-client` 映射
本阶段只做目录、文档和边界检查,不变更表结构,因此不需要改 `migration.rs`
## 8. 查询策略
1. 写模型不直接服务复杂前端页面。
2. 每个前端场景必须有独立 query/result DTO。
3. private table 默认不暴露给前端。
4. public table 只服务明确订阅场景。
5. event table 用于 reducer 后广播一次性事件,客户端必须显式订阅。
## 9. 第一阶段落地范围
第一阶段只做低风险基础设施:
1. 新增本文作为 DDD 总纲。
2. 所有 `module-*` 补齐 `domain / commands / application / events / errors` 过渡落位文件。
3. 新增 `scripts/check-server-rs-ddd-boundaries.mjs`,检查 DDD 骨架、禁用 mapper 落位和 SpacetimeDB/Axum 绝对边界。
4. 更新文档索引和后端 README。
5. 不改表、不改 reducer/procedure 名、不改 HTTP contract。
### 9.1 首个样板切片
`module-assets` 先作为 DDD 分层导出样板:
1. `domain.rs` 对外导出资产对象、实体绑定、访问策略、快照和纯校验函数。
2. `commands.rs` 对外导出确认资产、绑定实体、资产历史查询等输入。
3. `application.rs` 对外导出应用结果和纯构建函数。
4. `errors.rs` 对外导出资产领域错误。
5. `asset_object_core.rs` 暂作为内部历史实现文件保留,不再由 `lib.rs` 直接对外导出;后续触碰资产规则时继续把实现逐段迁到 DDD 文件。
## 10. 阶段性债务表
| 债务 | 当前位置 | 迁出目标 | 约束 |
| --- | --- | --- | --- |
| 资产 OSS head 与 reqwest 服务仍在 `module-assets` server-service feature | `module-assets/src/asset_object_service.rs` | `api-server` 应用服务或独立 adapter crate | 不得被 `domain.rs` 引用,不得新增更多 OSS 领域规则 |
| 认证内存 store / 文件持久化仍在 `module-auth` | `module-auth/src/lib.rs` | adapter / repository 目录或 `api-server` 启动恢复层 | 新业务规则不得继续依赖文件路径 |
| `spacetime-module/src/lib.rs` 仍有大量 gameplay 入口 | `spacetime-module/src/lib.rs` | `src/gameplay/*``src/custom_world/*``src/puzzle/*` | 新增实现禁止继续堆回根入口 |
| 部分 `module-*` 仍是单文件领域实现 | 多个 `module-*``src/lib.rs` | 对应 DDD 文件 | 每次触碰模块时顺手迁移相关片段 |
| runtime story 兼容层仍存在 | `module-runtime-story-compat``api-server/src/runtime_story/compat*`、前端旧 runtime story client | `module-runtime-story`、session scoped 新接口、前端新 client | 本轮允许 breaking change不再为旧 HTTP shape 保留双接口 |
## 11. 全局并行执行清单
`2026-04-29` 起,`server-rs` DDD 全局重构按 `SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md` 执行。该清单覆盖:
1. 文档、契约、DDD 骨架和边界检查。
2. `module-auth``module-assets``module-ai``module-custom-world``module-big-fish``module-puzzle``module-runtime`、RPG gameplay 域和 runtime story 域。
3. `spacetime-module``spacetime-client``api-server``platform-*` 和前端接入。
4. 旧层删除、命名收口、全链验证和 Maincloud smoke。
## 12. 去兼容层任务
`2026-04-29`runtime story / chat 改造按 `SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md` 中的 `WP-RS Runtime Story 去兼容层` 工作包执行。该工作包明确:
1. 当前 `compat` 层可以物理删除。
2. 新接口采用 `POST /api/runtime/story/sessions/:sessionId/...` 的 session scoped 口径。
3. 前端允许同步修改以匹配新 contract。
4. `api-server` 不再为旧 `worldType / character / monsters / history / context` 请求体保留正式主链分支。
## 13. 验收命令
阶段验收至少执行:
```powershell
node scripts/check-server-rs-ddd-boundaries.mjs
cargo fmt --all --check --manifest-path server-rs/Cargo.toml
cargo test --workspace --manifest-path server-rs/Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml
npm run api-server:maincloud
npm run check:encoding
```
`npm run api-server:maincloud` 因本机未配置 Maincloud 数据库或令牌失败,必须记录具体错误;不能改用旧后端重启命令。

View File

@@ -0,0 +1,178 @@
# server-rs DDD G1 契约与路由矩阵冻结2026-04-29
## 1. 冻结范围
本文是 `SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md``G1 契约与路由矩阵` 的串行冻结结果。G1 只冻结契约、路由和后续并行任务边界,不实现业务逻辑,不迁移 reducer不改前端页面。
G1 单 owner 文件范围:
1. `server-rs/crates/shared-contracts/src/**`
2. `packages/shared/src/contracts/**`
3. `packages/shared/src/index.ts`
4. `docs/technical/RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md`
5. 本文档
后续并行任务只能消费本文冻结的 route、DTO 和 error envelope。确实需要新增或调整 DTO shape 时,先在对应工作包交接中写清变更原因,再回到 G1 owner 文件集中改动,避免多个并行线同时抢改契约。
## 2. HTTP 路由矩阵
状态含义:
1. `保留`:作为 DDD 改造后的主链路由继续存在。
2. `重命名`:后续改成新的 route family旧路径删除不做兼容双主链。
3. `删除`:兼容层或临时调试入口,前端迁移后物理删除。
4. `收敛`:保留功能,但 route、DTO 或返回 envelope 需要归一到新的主链。
| 分组 | 当前路由 | G1 决议 | 新主链目标 | 所属后续任务 |
| --- | --- | --- | --- | --- |
| 健康检查 | `GET /healthz` | 保留 | 不变,统一 envelope 可例外保留轻量 health payload | WP-API |
| 管理后台页面 | `GET /admin` | 保留 | 不变 | WP-API |
| 管理后台 API | `POST /admin/api/login``GET /admin/api/me``GET /admin/api/overview``POST /admin/api/debug/http` | 保留 | `Admin*` DTO 继续由 `admin.rs` 管理 | WP-A、WP-API |
| 管理兑换码 | `POST /admin/api/profile/redeem-codes``POST /admin/api/profile/redeem-codes/disable` | 收敛 | 继续走 admin 路由DTO 归入 profile/runtime 管理命令组 | WP-RT、WP-API |
| 内部鉴权调试 | `GET /_internal/auth/claims``GET /_internal/auth/refresh-cookie` | 删除 | 只允许本地诊断脚本或 admin debug 能力使用,不作为前端契约 | WP-DEL |
| 鉴权公开查询 | `GET /api/auth/login-options``GET /api/auth/public-users/by-code/{code}``GET /api/auth/public-users/by-id/{user_id}` | 保留 | `AuthLoginOptionsResponse``PublicUserSearchResponse` | WP-A |
| 鉴权会话 | `GET /api/auth/me``GET /api/auth/sessions``POST /api/auth/refresh``POST /api/auth/logout``POST /api/auth/logout-all` | 保留 | `AuthMeResponse``AuthSessionsResponse``RefreshSessionResponse``LogoutResponse``LogoutAllResponse` | WP-A |
| 鉴权登录 | `POST /api/auth/phone/send-code``POST /api/auth/phone/login``GET /api/auth/wechat/start``GET /api/auth/wechat/callback``POST /api/auth/wechat/bind-phone``POST /api/auth/entry``POST /api/auth/password/change``POST /api/auth/password/reset` | 保留 | TS 命名统一使用 `Auth*` 前缀Rust 命名维持领域语义 | WP-A |
| 旧本地生成资产代理 | `GET /generated-character-drafts/{*path}``/generated-characters/{*path}``/generated-animations/{*path}``/generated-big-fish-assets/{*path}``/generated-puzzle-assets/{*path}``/generated-custom-world-scenes/{*path}``/generated-custom-world-covers/{*path}``/generated-qwen-sprites/{*path}` | 已删除 | 正式读取统一走 `GET /api/assets/read-url` 或 asset object projection`/generated-*` 仅允许作为 legacyPublicPath/object key 标识,不再作为可裸读路由 | WP-AS、WP-FE、WP-DEL |
| LLM 代理 | `POST /api/llm/chat/completions` | 收敛 | 仅作为平台能力代理;玩法 prompt 不允许由前端直接传入 | WP-PF、WP-API |
| Runtime chat | `POST /api/runtime/chat/character/suggestions``/summary``/reply/stream``/npc/dialogue/stream``/npc/turn/stream``/npc/recruit/stream` | 重命名 | 收敛到 session scoped story/chat 命令;请求体不得携带前端拼装的世界真相 | WP-RS、WP-RPG、WP-FE |
| 文档输入 | `POST /api/runtime/creation-agent/document-inputs/parse` | 保留 | `ParseCreationAgentDocumentInputRequest/Response` | WP-CW、WP-BF、WP-PZ |
| AI task | `POST /api/ai/tasks``/{task_id}/start``/{task_id}/stages/{stage_kind}/start``/{task_id}/chunks``/{task_id}/stages/{stage_kind}/complete``/{task_id}/references``/{task_id}/complete``/{task_id}/fail``/{task_id}/cancel` | 保留 | `AiTask*` 命令/result DTO后续接 module-ai 状态机 | WP-AI |
| Assets object | `POST /api/assets/direct-upload-tickets``POST /api/assets/sts-upload-credentials``POST /api/assets/objects/confirm``POST /api/assets/objects/bind``GET /api/assets/read-url``GET /api/assets/history` | 保留 | `CreateDirectUploadTicket*``ConfirmAssetObject*``BindAssetObject*``GetReadUrlQuery/Response``AssetHistory*` | WP-AS |
| 角色资产工作流 | `POST /api/assets/character-visual/generate``GET /api/assets/character-visual/jobs/{task_id}``POST /api/assets/character-visual/publish``POST /api/assets/character-animation/generate``GET /api/assets/character-animation/jobs/{task_id}``POST /api/assets/character-animation/publish``POST /api/assets/character-animation/import-video``GET /api/assets/character-animation/templates``POST /api/assets/character-workflow-cache``GET /api/assets/character-workflow-cache/{character_id}``POST/PUT /api/runtime/custom-world/asset-studio/role/{character_id}/workflow` | 收敛 | Asset object、AI task、role workflow 三组 DTO 拆清workflow 不再把业务真相藏在 cache body | WP-AS、WP-CW、WP-API |
| Runtime settings/save | `GET/PUT /api/runtime/settings``GET/PUT/DELETE /api/runtime/save/snapshot` | 保留 | `RuntimeSettingsResponse``PutRuntimeSettingsRequest``SavedGameSnapshotResponse``PutSavedGameSnapshotRequest` | WP-RT |
| RPG 作品库 | `GET /api/runtime/custom-world-library``GET/PUT/DELETE /api/runtime/custom-world-library/{profile_id}``POST /publish``POST /unpublish``GET /api/runtime/custom-world-gallery``GET /api/runtime/custom-world-gallery/{owner_user_id}/{profile_id}``GET /api/runtime/custom-world-gallery/by-code/{code}` | 收敛 | 命名后续改为 RPG creation/work route family删除 `custom-world` 旧泛名歧义 | WP-CW、WP-FE |
| RPG Agent | `POST /api/runtime/custom-world/agent/sessions``GET/DELETE /sessions/{session_id}``GET /result-view``GET /works``GET /cards/{card_id}``POST /messages``POST /messages/stream``POST /actions``GET /operations/{operation_id}` | 收敛 | DTO 重命名为 `RpgAgent*`Rust 当前 `CustomWorldAgent*` 后续物理重命名 | WP-CW、WP-FE、WP-DEL |
| Big Fish Agent/Works/Runtime | `POST /api/runtime/big-fish/agent/sessions``GET /sessions/{session_id}``POST /messages``POST /messages/stream``POST /actions``GET /works``DELETE /works/{session_id}``GET /gallery``POST /sessions/{session_id}/play``POST /works/{session_id}/play``POST /sessions/{session_id}/runs``GET /runs/{run_id}``POST /runs/{run_id}/input` | 保留 | `BigFish*` DTO运行态正式使用 `BigFishRunResponse``SubmitBigFishInputRequest``sessions/{id}/play``works/{id}/play` 后续二选一保留 | WP-BF |
| Puzzle Agent/Works/Runtime | `POST /api/runtime/puzzle/agent/sessions``GET /sessions/{session_id}``POST /messages``POST /messages/stream``POST /actions``GET /works``GET/PUT/DELETE /works/{profile_id}``GET /gallery``GET /gallery/{profile_id}``POST /runs``GET /runs/{run_id}``POST /runs/{run_id}/swap``POST /runs/{run_id}/drag``POST /runs/{run_id}/next-level``POST /runs/{run_id}/leaderboard`;旧 `POST /runs/local-next-level` 已取消挂载 | 保留 | `PuzzleAgent*``PuzzleWork*``PuzzleRun*` DTO`AdvanceLocalPuzzleNextLevelRequest` 已删除 | WP-PZ、WP-DEL |
| RPG profile/asset generation | `POST /api/runtime/custom-world/profile``POST /api/runtime/custom-world/entity``POST /api/runtime/custom-world/scene-npc``POST /api/runtime/custom-world/scene-image``POST /api/runtime/custom-world/cover-image``POST /api/runtime/custom-world/cover-upload`;旧 `/api/custom-world/*` 非 runtime 前缀已取消挂载 | 重命名 | 去掉非 runtime 前缀旧入口;统一到 RPG creation asset/profile route family | WP-CW、WP-AS、WP-DEL |
| Profile | `GET/POST/DELETE /api/profile/browse-history``GET /api/profile/dashboard``GET /api/profile/wallet-ledger``GET /api/profile/recharge-center``POST /api/profile/recharge/orders``GET /api/profile/referrals/invite-center``POST /api/profile/referrals/redeem-code``POST /api/profile/redeem-codes/redeem``GET /api/profile/play-stats``GET /api/profile/save-archives``POST /api/profile/save-archives/{world_key}`;旧 `GET/POST/DELETE /api/runtime/profile/*` 已取消挂载 | 重命名 | 保留 `/api/profile/*` 主链,删除 `/api/runtime/profile/*` 旧兼容入口 | WP-RT、WP-FE、WP-DEL |
| Runtime inventory | `GET /api/runtime/sessions/{runtime_session_id}/inventory` | 保留 | `RuntimeInventoryStateResponse` | WP-RPG、WP-RT |
| Runtime story 旧层 | `POST /api/runtime/story/sessions``POST /api/runtime/story/state/resolve``GET /api/runtime/story/state/{session_id}``POST /api/runtime/story/actions/resolve``POST /api/runtime/story/initial``POST /api/runtime/story/continue` | 已删除 | 已从 `api-server` 取消挂载并删除 `api-server/src/runtime_story*` 兼容实现;后续前端迁移到 `GET/POST /api/story/*` 和 session scoped story/chat facade | WP-RS、WP-FE、WP-DEL |
| Story/Game facade | `POST /api/story/sessions``GET /api/story/sessions/{story_session_id}/state``GET /api/story/sessions/{story_session_id}/runtime-projection``POST /api/story/sessions/continue``POST /api/story/battles``GET /api/story/battles/{battle_state_id}``POST /api/story/npc/battle``POST /api/story/battles/resolve` | 保留 | `BeginStorySession*``ContinueStory*``StoryRuntimeProjection*``CreateStoryBattle*``StoryBattleState*``ResolveStoryBattle*` DTO 已补齐到 `shared-contracts` | WP-RPG、WP-RS |
## 3. DTO 冻结清单
### 3.1 保留
| 契约文件 | 保留 DTO |
| --- | --- |
| `shared-contracts/src/api.rs` | `ApiResponseMeta``ApiErrorPayload``ApiSuccessEnvelope<T>``ApiErrorEnvelope` |
| `shared-contracts/src/admin.rs` | `AdminLoginRequest/Response``AdminSessionPayload``AdminMeResponse``AdminOverviewResponse``AdminDebugHttpRequest/Response` |
| `shared-contracts/src/auth.rs` | `AuthLoginOptionsResponse``AuthUserPayload``PublicUserSummaryPayload``PublicUserSearchResponse``PasswordEntry*``PasswordChange*``PasswordReset*``AuthMeResponse``AuthSessionsResponse``RefreshSessionResponse``Logout*``Phone*``Wechat*` |
| `shared-contracts/src/ai.rs` | `CreateAiTaskRequest``AppendAiTextChunkRequest``CompleteAiStageRequest``AttachAiResultReferenceRequest``FailAiTaskRequest``AiTask*Payload``AiTaskMutationResponse``AiTaskAcceptedResponse` |
| `shared-contracts/src/assets.rs` | Direct upload、read url、asset object、asset binding、asset history、character visual/animation、workflow cache、role asset workflow 相关 DTO |
| `shared-contracts/src/creation_agent_document_input.rs` | `ParseCreationAgentDocumentInputRequest/Response``CreationAgentDocumentInputPayload` |
| `shared-contracts/src/big_fish*.rs` | `CreateBigFishSessionRequest``SendBigFishMessageRequest``ExecuteBigFishActionRequest``RecordBigFishPlayRequest``SubmitBigFishInputRequest``BigFish*Response``BigFishRunResponse``BigFishWorksResponse` |
| `shared-contracts/src/puzzle_*.rs` | `CreatePuzzleAgentSessionRequest``SendPuzzleAgentMessageRequest``ExecutePuzzleAgentActionRequest``PuzzleAgent*Response``PuzzleWork*``PuzzleRun*``PuzzleGallery*` |
| `shared-contracts/src/runtime.rs` | runtime settings/save/profile/browse history/custom world library/agent/result view/inventory 现有 DTO 在迁移窗口保留 |
| `shared-contracts/src/story.rs` | `BeginStorySessionRequest``ContinueStoryRequest``StorySessionPayload``StoryEventPayload``StorySessionMutationResponse``StorySessionStateResponse``StoryRuntimeProjectionRequest/Response``CreateStoryBattleRequest``CreateStoryNpcBattleRequest``StoryBattleStateResponse``ResolveStoryBattleRequest/Response` |
| `packages/shared/src/contracts/runtime.ts` | `RuntimeSettings``SavedGameSnapshot*`、profile、browse history、library/gallery DTO迁移窗口继续作为前端消费主入口 |
| `packages/shared/src/contracts/creationAgentDocumentInput.ts` | `ParseCreationAgentDocumentInputRequest/Response``CreationAgentDocumentInputPayload` |
| `packages/shared/src/contracts/rpgAgent*.ts` | RPG Agent、draft、anchors、result view、work summary DTO |
| `packages/shared/src/contracts/bigFish*.ts` | Big Fish Agent、backend runtime run/input、本地作品列表 DTO |
| `packages/shared/src/contracts/puzzle*.ts` | Puzzle Agent、work、gallery、runtime DTO |
### 3.2 重命名
| 当前 DTO | 新命名 | 说明 |
| --- | --- | --- |
| Rust `CustomWorldAgent*` | `RpgAgent*` | Rust 与 TS 命名对齐,`custom world` 只作为历史目录语义,不再作为 RPG 主链契约名。 |
| Rust `CustomWorldLibrary*` / `CustomWorldWorks*` | `RpgCreationWork*` / `RpgCreationLibrary*` | 前端已有 `RpgCreationWorkSummary`,后端后续对齐 RPG 创作域命名。 |
| Rust `GenerateCustomWorldProfile*` | `GenerateRpgCreationProfile*` | 去掉泛化 custom world 命名,明确 RPG 创作 profile。 |
| TS `AuthEntry*` | `PasswordEntry*` 或统一后端 `AuthPasswordEntry*` | 需要在 WP-A 中二选一收口,避免 entry 与 phone/wechat 登录语义混杂。 |
| `RuntimeStory*` view model | `RpgRuntimeStory*` 或拆到 `Story*``Battle*``Inventory*` | 旧聚合大 DTO 后续拆分为 story session、battle、inventory、npc interaction 投影。 |
| Profile 旧兼容入口 DTO | `RuntimeProfile*` | `/api/runtime/profile/*` 旧兼容入口已删除,契约命名可继续保留 RuntimeProfile 领域语义HTTP 主链固定为 `/api/profile/*`。 |
### 3.3 删除
| DTO/文件 | 删除条件 | 替代 |
| --- | --- | --- |
| `LegacyApiErrorResponse` | 全部路由完成 envelope 归一后 | `ApiErrorEnvelope` |
| Rust `RuntimeStoryStateResolveRequest` | 已在 WP-DEL 删除 | `StorySessionStateResponse` 与 story runtime projection |
| Rust/TS `RuntimeStoryBootstrapRequest/Response` | 已在 WP-DEL 删除 | `BeginStoryRuntimeSessionRequest``StoryRuntimeMutationResponse` |
| Rust/TS `RuntimeStoryAiRequest/Response` | `POST /api/runtime/story/continue` 删除后 | `ContinueStoryRequest``StorySessionMutationResponse` |
| Rust/TS `RuntimeStoryActionResponse` 旧总入口形态 | 已在 WP-DEL 删除 | `StoryRuntimeMutationResponse.projection` 与 story/battle/npc/inventory 分投影 |
| TS `StoryRequestPayload``PlainTextPromptRequest``PlainTextResponse` | runtime chat 不再由前端传 prompt 后 | 后端 session scoped chat/story command |
| TS `CreateCustomWorldSessionRequest``AnswerCustomWorldSessionQuestionRequest``CustomWorldSessionRecord` 等旧问答生成 DTO | 确认无前端运行引用后 | RPG Agent session DTO |
| `/api/runtime/profile/*` 旧兼容 DTO 别名 | 前端全量迁到 `/api/profile/*` 后 | Runtime profile DTO |
## 4. 页面/功能到 query/result DTO 映射
| 页面/功能 | Query DTO | Command DTO | Result DTO |
| --- | --- | --- | --- |
| 管理后台登录 | 无 | `AdminLoginRequest` | `AdminLoginResponse` |
| 管理后台概览 | 无 | 无 | `AdminMeResponse``AdminOverviewResponse` |
| 管理后台 API 调试 | 无 | `AdminDebugHttpRequest` | `AdminDebugHttpResponse` |
| 登录方式页 | 无 | 无 | `AuthLoginOptionsResponse` |
| 手机号登录 | 无 | `PhoneSendCodeRequest``PhoneLoginRequest` | `PhoneSendCodeResponse``PhoneLoginResponse` |
| 密码登录/改密/重置 | 无 | `PasswordEntryRequest``PasswordChangeRequest``PasswordResetRequest` | `PasswordEntryResponse``PasswordChangeResponse``PasswordResetResponse` |
| 会话中心 | refresh cookie / bearer token | `logout``logout-all` 无 body | `AuthMeResponse``AuthSessionsResponse``RefreshSessionResponse``LogoutResponse``LogoutAllResponse` |
| 公开用户卡片 | route param `code``user_id` | 无 | `PublicUserSearchResponse` |
| 创作中心 RPG 作品货架 | bearer token | 无 | `CustomWorldWorksResponse`,后续重命名 `RpgCreationWorksResponse` |
| RPG Agent 工作区 | route param `session_id` / `operation_id` | `CreateCustomWorldAgentSessionRequest``SendCustomWorldAgentMessageRequest``ExecuteCustomWorldAgentActionRequest` | `CustomWorldAgentSessionResponse``CustomWorldAgentOperationResponse``CustomWorldCreationResultViewResponse`,后续重命名 `RpgAgent*` |
| RPG 结果页 | route param `session_id` | section patch/action request | `CustomWorldCreationResultViewResponse``CustomWorldAgentCardDetailResponse` |
| RPG 资产工坊 | route param `character_id``GetReadUrlQuery` | `CharacterVisualGenerateRequest``CharacterAnimationGenerateRequest``CharacterWorkflowCacheSaveRequest``CharacterRoleAssetWorkflowResolveRequest` | `CharacterVisualGenerateResponse``CharacterAnimationGenerateResponse``CharacterWorkflowCacheGetResponse``CharacterRoleAssetWorkflowResponse` |
| Big Fish Agent/Runtime | route param `session_id` / `run_id` | `CreateBigFishSessionRequest``SendBigFishMessageRequest``ExecuteBigFishActionRequest``SubmitBigFishInputRequest` | `BigFishSessionResponse``BigFishActionResponse``BigFishRunResponse` |
| Big Fish 广场/作品 | bearer token 或公开 gallery query | `RecordBigFishPlayRequest` | `BigFishWorksResponse``BigFishGalleryResponse``BigFishSessionResponse` |
| Puzzle Agent | route param `session_id` | `CreatePuzzleAgentSessionRequest``SendPuzzleAgentMessageRequest``ExecutePuzzleAgentActionRequest` | `PuzzleAgentSessionResponse``PuzzleAgentActionResponse` |
| Puzzle 作品/广场 | route param `profile_id` | `PutPuzzleWorkRequest` | `PuzzleWorksResponse``PuzzleWorkDetailResponse``PuzzleGalleryResponse``PuzzleGalleryDetailResponse` |
| Puzzle 运行态 | route param `run_id` | `StartPuzzleRunRequest``SwapPuzzlePiecesRequest``DragPuzzlePieceRequest``SubmitPuzzleLeaderboardRequest` | `PuzzleRunResponse` |
| Runtime 设置与存档 | bearer token | `PutRuntimeSettingsRequest``PutSavedGameSnapshotRequest``PutRuntimeSaveCheckpointRequest` | `RuntimeSettingsResponse``SavedGameSnapshotResponse``BasicOkResponse` |
| 个人中心 | bearer token | `CreateProfileRechargeOrderRequest``RedeemProfileReferralInviteCodeRequest``RedeemProfileRewardCodeRequest``PlatformBrowseHistoryUpsertRequest` | `ProfileDashboardSummaryResponse``ProfileWalletLedgerResponse``ProfileRechargeCenterResponse``ProfileReferralInviteCenterResponse``ProfilePlayStatsResponse``ProfileSaveArchiveListResponse``PlatformBrowseHistoryResponse` |
| RPG Story 运行态 | route param `story_session_id``battle_state_id` | `BeginStorySessionRequest``ContinueStoryRequest``CreateStoryBattleRequest``CreateStoryNpcBattleRequest``ResolveStoryBattleRequest` | `StorySessionMutationResponse``StorySessionStateResponse``StoryRuntimeProjectionResponse``StoryBattleStateResponse``ResolveStoryBattleResponse``RuntimeInventoryStateResponse` |
| Runtime chat/NPC 私聊 | route param `runtime_session_id``story_session_id` | 后续新增 session scoped chat command | 后续新增 chat turn result`rpgRuntimeChat.ts` DTO 只作为迁移参考 |
## 5. Breaking change 清单
1. 删除兼容层是本轮默认策略。旧 `/api/runtime/story/*``/api/custom-world/*` 非 runtime 前缀、`/api/runtime/puzzle/runs/local-next-level``/api/runtime/profile/*` 兼容入口和 `/generated-*` 资产直读代理均在对应前端迁移完成后物理删除。
2. Runtime story/chat 不再接受前端拼装的 `worldType``character``monsters``history``context`、prompt 文本作为正式真相。正式命令必须以 `runtimeSessionId``storySessionId``battleStateId` 等后端 session id 为索引。
3. `CustomWorld*` 作为 RPG 主链命名将被重命名为 `RpgCreation*``RpgAgent*`。前端可同步修改,不保留旧命名适配层。
4. `/api/custom-world/*` 非 runtime 前缀旧入口删除,统一进入 RPG creation route family 或 asset route family。
5. `/api/runtime/profile/*` 兼容入口删除,统一使用 `/api/profile/*`
6. 资产读取不再依赖 `/generated-*` 静态代理作为正式 contract统一走 asset object、read url 或后端投影里的正式 URL 字段;`/generated-*` 只保留为 legacyPublicPath/object key 兼容标识。
7. LLM 代理不得作为玩法 prompt 透传入口。玩法 prompt 由 `api-server`/`platform-llm` 内部编排,前端只提交用户动作和展示态输入。
8. API 错误体统一为 `ApiErrorEnvelope`。旧 `{ error, meta }` 只允许在已列入删除计划的旧接口中短期存在。
## 6. API 错误 envelope
所有主链 HTTP JSON 响应统一使用:
```json
{
"ok": false,
"data": null,
"error": {
"code": "BAD_REQUEST",
"message": "请求参数不合法",
"details": {
"message": "具体中文错误说明"
}
},
"meta": {
"apiVersion": "2026-04-08",
"requestId": "req-xxx",
"routeVersion": "2026-04-08",
"operation": "POST /api/example",
"latencyMs": 12,
"timestamp": "2026-04-29T00:00:00Z"
}
}
```
冻结规则:
1. 成功响应使用 `ApiSuccessEnvelope<T>``ok=true``data` 为 result DTO、`error=null``meta` 必填。
2. 失败响应使用 `ApiErrorEnvelope``ok=false``data=null``error` 必填、`meta` 必填。
3. `error.message` 是稳定的分类中文文案,`error.details.message` 是可展示给用户的具体中文错误。
4. 前端展示业务错误时优先读取 `error.details.message`,再退回 `error.message`
5. `code` 使用稳定英文枚举值,禁止把中文错误全文塞进 `code`
6. `LegacyApiErrorResponse` 只服务迁移窗口,不能用于新增主链 route。
## 7. 后续并行任务交接
1. 第 1 批领域任务不得改 `shared-contracts``packages/shared/src/contracts/**`。需要新字段时先写入任务交接,等 G1 owner 合流。
2. `WP-ST` 负责 SpacetimeDB 表、reducer/procedure 和 `migration.rs`,不得由玩法领域任务直接抢改。
3. `WP-API` 负责 `api-server/src/app.rs` 和 route 挂载入口,领域任务只提供应用结果和错误模型。
4. `WP-FE` 在后端新接口稳定后删除旧前端兼容层,不新增对旧 route 的二次适配。
5. `WP-DEL` 只能在搜索确认无运行引用后删除旧 DTO、旧 route 和旧静态代理;`/generated-*` 直读代理已移除后,后续不得重新引入裸读转发。

View File

@@ -0,0 +1,67 @@
# server-rs DDD G1 契约与路由矩阵进度记录2026-04-29
## 1. 当前状态
`G1 契约与路由矩阵` 已完成串行冻结,当前可作为第 1 批领域规则并行任务的契约输入。
本次只落地文档与索引,不修改 Rust / TypeScript 契约源码,不改业务实现,不启动前端迁移。
## 2. 已完成内容
1. 新增 G1 冻结文档:[`SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md`](./SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md)。
2. 冻结新旧 HTTP 路由清单,按 `保留``重命名``删除``收敛` 标记后续处理。
3. 冻结 DTO 保留、删除、重命名清单。
4. 冻结页面/功能到 query、command、result DTO 的映射。
5. 冻结 breaking change 清单,明确本轮不保留旧兼容层作为约束。
6. 冻结 API 错误 envelope主链统一使用 `ApiSuccessEnvelope<T>` / `ApiErrorEnvelope`
7. 在全局并行任务清单中补充 G1 冻结文档入口和单 owner 文件边界。
8. 在旧 Rust API route index 中补充 2026-04-29 提示,避免继续把 2026-04-23 快照当作最新契约。
9. 在技术 README 中补充 G1 冻结文档入口。
## 3. 单 owner 边界
G1 后续合流文件:
1. `server-rs/crates/shared-contracts/src/**`
2. `packages/shared/src/contracts/**`
3. `packages/shared/src/index.ts`
4. `docs/technical/RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md`
5. `docs/technical/SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md`
第 1 批并行领域任务不得直接改这些文件。确实需要新增字段或调整 DTO shape 时,先在任务交接里记录变更原因,再由 G1 owner 文件集中合流。
## 4. 验证结果
已执行:
```powershell
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md docs/technical/README.md docs/technical/RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md
```
结果通过4 个文档文件 UTF-8 编码检查正常。
## 4.1 持续巡检记录
2026-04-29 本轮持续巡检已补齐迁移后漂移:
1. `Profile` 路由矩阵从旧 `/api/runtime/profile/*` 主链修正为当前 `/api/profile/*` 主链,并明确 `/api/runtime/profile/*` 已作为旧兼容入口取消挂载。
2. `Big Fish Agent/Works` 路由矩阵补齐后端真相源运行态接口:`POST /api/runtime/big-fish/sessions/{session_id}/runs``GET /api/runtime/big-fish/runs/{run_id}``POST /api/runtime/big-fish/runs/{run_id}/input`
3. `Story/Game facade` 补齐 `GET /api/story/sessions/{story_session_id}/runtime-projection`,并将 story runtime projection、story battle command/result DTO 标记为已进入 `shared-contracts/src/story.rs`
4. DTO 保留清单补齐 `shared-contracts/src/creation_agent_document_input.rs``packages/shared/src/contracts/creationAgentDocumentInput.ts`
5. `packages/shared/src/index.ts` 已导出 `creationAgentDocumentInput` 类型,避免前端继续绕过共享契约包入口深路径引用。
## 5. 后续入口
下一步可以按全局清单进入第 1 批领域规则并行任务:
1. `WP-A Auth`
2. `WP-AS Assets`
3. `WP-AI AI Task`
4. `WP-CW Custom World`
5. `WP-BF Big Fish`
6. `WP-PZ Puzzle`
7. `WP-RT Runtime/Profile/Save`
8. `WP-RPG Gameplay 域`
9. `WP-RS Runtime Story 去兼容层`
进入下一批前,先以 G1 冻结文档确认 route、DTO、error envelope 和 breaking change避免并行任务各自定义接口。

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
# server-rs DDD tests-support 共享测试支撑 crate 收口记录
日期:`2026-04-30`
## 1. 收口目标
本次关闭 `4.1 未完整收口内容整合清单``tests-support` 仍只是目录占位的问题,将其补成 `server-rs` workspace 中的真实共享测试支撑 crate。
## 2. 已完成
1. `server-rs/Cargo.toml` 已把 `crates/tests-support` 纳入 workspace member。
2. 新增 `server-rs/crates/tests-support/Cargo.toml`
3. 新增 `server-rs/crates/tests-support/src/lib.rs`,提供 Maincloud healthz 默认地址、smoke URL 归一化、HTTP 2xx 断言和 healthz 非空响应体断言。
4. 更新 `server-rs/crates/tests-support/README.md`,明确当前首版边界和后续可扩展方向。
5. 更新 `SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md`,将 `tests-support` 从目录占位改为已收口的真实测试支撑 crate。
## 3. 边界说明
1. 本次不引入业务规则、不创建伪领域 fixture。
2. 本次不修改 SpacetimeDB 表、reducer、procedure、绑定或 `migration.rs`
3. Contract DTO、reducer/view/projection 共享夹具仍等待对应接口与最终 smoke 策略稳定后继续扩展。
## 4. 验证
```powershell
cargo test -p tests-support --manifest-path server-rs\Cargo.toml
cargo check -p tests-support --manifest-path server-rs\Cargo.toml
```
结果:通过,`tests-support` 4 个单元测试通过crate 编译通过。

View File

@@ -0,0 +1,94 @@
# server-rs DDD WP-AI 内部子模块拆分记录2026-04-29
## 1. 背景
`WP-AI AI Task` 已完成领域层、SpacetimeDB adapter、spacetime-client facade 与 BFF route 闭环。当前继续推进 DDD 收口时,`module-ai` 虽然已经从首轮 `lib.rs` 大文件拆成 `domain / commands / application / events / errors`,但 `domain.rs``commands.rs``application.rs` 仍承载多类职责,后续继续演进阶段规则、任务结果聚合或 store 实现时容易重新堆成大文件。
本次只做 `module-ai` crate 内部子模块拆分,保持 `module_ai::*` 对外公开导出不变,不改变 SpacetimeDB table / reducer / procedure / event table不改变 HTTP DTO、route 或前端调用。
## 2. 本次拆分范围
允许修改:
1. `server-rs/crates/module-ai/src/domain.rs`
2. `server-rs/crates/module-ai/src/domain/*`
3. `server-rs/crates/module-ai/src/commands.rs`
4. `server-rs/crates/module-ai/src/commands/*`
5. `server-rs/crates/module-ai/src/application.rs`
6. `server-rs/crates/module-ai/src/application/*`
7. `server-rs/crates/module-ai/src/lib.rs`
8. `server-rs/crates/module-ai/src/tests.rs`
9. `server-rs/crates/module-ai/README.md`
10. 本文档、`docs/technical/README.md` 与全局任务清单进度记录
禁止修改:
1. `server-rs/crates/spacetime-module/src/**`
2. `server-rs/crates/spacetime-client/src/**`
3. `server-rs/crates/api-server/src/**`
4. `server-rs/crates/shared-contracts/src/**`
5. `packages/shared/src/contracts/**`
6. `server-rs/crates/spacetime-module/src/migration.rs`
## 3. 拆分落点
```text
server-rs/crates/module-ai/src/
├─ application.rs
├─ application/
│ ├─ result.rs
│ ├─ service.rs
│ └─ store.rs
├─ commands.rs
├─ commands/
│ ├─ inputs.rs
│ └─ validation.rs
├─ domain.rs
├─ domain/
│ ├─ ids.rs
│ ├─ stages.rs
│ └─ types.rs
├─ errors.rs
├─ events.rs
├─ lib.rs
└─ tests.rs
```
职责说明:
1. `domain/types.rs` 只放 AI task、stage、chunk、result reference 的领域类型与快照。
2. `domain/stages.rs` 只放默认阶段蓝图、阶段 slug、阶段中文标签与终态判断。
3. `domain/ids.rs` 只放 ID 前缀、ID helper 和共享字符串归一 helper re-export。
4. `commands/inputs.rs` 只放写入输入结构。
5. `commands/validation.rs` 只放创建任务输入校验。
6. `application/result.rs` 只放面向 SpacetimeDB procedure 的轻量结果结构。
7. `application/service.rs` 只放 AI task 状态机应用服务。
8. `application/store.rs` 只放当前内存 store 与流式文本片段聚合。
9. `tests.rs` 承接原 `lib.rs` 行为测试,`lib.rs` 只保留模块声明与公开导出。
## 4. 行为不变口径
本次必须保持:
1. `module_ai::*` 公开导出兼容。
2. 默认阶段蓝图顺序不变。
3. 任务状态迁移不变。
4. 终态任务不允许继续写入阶段、文本片段、结果引用或完成状态。
5. 流式文本片段继续按 `sequence` 聚合到阶段输出和 `latest_text_output`
6. 中文错误文案不改写为英文。
7. 不新增真实 LLM provider、prompt 组装、SSE 协议或前端消费逻辑。
## 5. 验收
必须执行:
```powershell
cargo fmt -p module-ai --manifest-path server-rs/Cargo.toml --check
cargo test -p module-ai --manifest-path server-rs/Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_AI_INTERNAL_MODULE_SPLIT_2026-04-29.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md server-rs/crates/module-ai/README.md server-rs/crates/module-ai/src/lib.rs server-rs/crates/module-ai/src/domain.rs server-rs/crates/module-ai/src/domain/ids.rs server-rs/crates/module-ai/src/domain/stages.rs server-rs/crates/module-ai/src/domain/types.rs server-rs/crates/module-ai/src/commands.rs server-rs/crates/module-ai/src/commands/inputs.rs server-rs/crates/module-ai/src/commands/validation.rs server-rs/crates/module-ai/src/application.rs server-rs/crates/module-ai/src/application/result.rs server-rs/crates/module-ai/src/application/service.rs server-rs/crates/module-ai/src/application/store.rs server-rs/crates/module-ai/src/tests.rs
npm.cmd run api-server:maincloud
```
`api-server:maincloud` 是常驻后端启动命令,验收时以命令启动和 `GET http://127.0.0.1:3100/healthz` 探测结果记录为准。

View File

@@ -0,0 +1,73 @@
# server-rs DDD WP-AI AI Task BFF 收口记录2026-04-29
## 1. 背景
`WP-AI AI Task` 的领域层已完成 DDD 拆分,`spacetime-module/src/ai/*` 已具备 AI task 真相表、阶段表、文本片段、结果引用、事件表和最小 reducer / procedure`spacetime-client` 已提供 typed facade`api-server` 已挂载 AI task mutation route。
本次认领的目标不是新增模型供应商能力,也不是改表,而是把现有 AI task BFF 链路做闭环验证,确认前端或后续业务模块调用 AI task 写接口时不会绕过鉴权、不会在 SpacetimeDB 未发布时返回错误形态不一致的响应。
## 2. 本次完成范围
1. 补齐 `api-server/src/ai_tasks.rs` 的 AI task mutation route 定向测试。
2. 覆盖以下写接口的未登录拦截:
- `POST /api/ai/tasks/{task_id}/stages/{stage_kind}/start`
- `POST /api/ai/tasks/{task_id}/chunks`
- `POST /api/ai/tasks/{task_id}/stages/{stage_kind}/complete`
- `POST /api/ai/tasks/{task_id}/references`
- `POST /api/ai/tasks/{task_id}/complete`
- `POST /api/ai/tasks/{task_id}/fail`
- `POST /api/ai/tasks/{task_id}/cancel`
3. 覆盖上述写接口在 token 有效但 SpacetimeDB 未发布时统一返回 `502 BAD_GATEWAY`,并保持错误详情 `provider = spacetimedb`
4. 复核 `module-ai``spacetime-client``spacetime-module` 与 BFF 定向测试,确认本次不需要修改 `migration.rs`
## 3. 边界
本次未进入:
1. 真实 LLM provider 调用、prompt 组装和供应商降级策略。
2. SSE 流式输出协议。
3. AI task 订阅 projection、清理调度或前端消费 UI。
4. SpacetimeDB table、reducer、procedure、event table 的结构变更。
5. 共享契约字段调整或前端 API client 改造。
这些能力继续归入 `WP-PF platform side effects``WP-API api-server BFF``WP-FE` 和后续对应业务域工作包,不在 `module-ai` 领域核心中混入。
## 4. 验收
已执行:
```powershell
cargo fmt -p api-server --manifest-path server-rs\Cargo.toml --check
cargo test -p api-server ai_task --manifest-path server-rs\Cargo.toml
cargo test -p module-ai --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-client --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml
cargo check -p api-server --manifest-path server-rs\Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md docs/technical/SERVER_RS_DDD_WP_AI_TASK_BFF_CLOSURE_2026-04-29.md docs/technical/README.md server-rs/crates/api-server/src/ai_tasks.rs server-rs/crates/api-server/src/wechat_auth.rs
npm.cmd run api-server:maincloud
```
结果:
1. `api-server ai_task` 定向测试通过7 个测试全部通过。
2. `module-ai` 测试通过9 个测试全部通过。
3. `spacetime-client` 编译通过。
4. `spacetime-module` 编译通过。
5. `api-server` 编译通过,仅保留既有未使用代码 warning。
6. `npm.cmd run check:server-rs-ddd` 通过。
7. 编码检查通过5 个文件均为 UTF-8。
8. `npm.cmd run api-server:maincloud` 已启动本仓库 `server-rs/target/debug/api-server.exe``GET http://127.0.0.1:3100/healthz` 返回 `200`
9. 未执行 SpacetimeDB 发布、绑定生成或 migration 更新,原因是本次未改变 SpacetimeDB schema、reducer/procedure 签名或绑定形状。
## 5. 关闭口径
`WP-AI AI Task` 当前已完成:
1. 领域层 DDD 拆分。
2. SpacetimeDB AI task 真相表、阶段表、文本片段、结果引用和事件表 adapter。
3. `spacetime-client` typed facade。
4. `api-server` AI task mutation route 与错误 envelope。
5. BFF 鉴权和 SpacetimeDB 未发布错误形态的定向回归测试。
因此本次将工作包认领状态从 `已认领` 更新为 `已关闭`。后续真实模型调用、SSE 和前端消费不再阻塞 `WP-AI` 关闭分别由平台副作用、API 编排和前端迁移工作包继续承接。

View File

@@ -0,0 +1,64 @@
# server-rs DDD WP-AI AI Task 领域层重构方案2026-04-29
## 1. 背景
`G1 契约与路由矩阵` 已冻结,`WP-AI AI Task` 进入第 1 批领域规则并行泳道。当前 `module-ai` 已有 AI task 状态机、输入类型、错误和内存服务,但主要实现集中在 `src/lib.rs`,与全局 DDD 清单要求的 `domain / commands / application / events / errors` 分层不一致。
本次只整理 `module-ai` 纯领域层,不改 HTTP route不改 SpacetimeDB table / reducer / procedure不改前端。
## 2. 目标
1. 保持 `module_ai::*` 公开 API 兼容,让 `spacetime-module` 现有引用不需要跟随修改。
2. 将 AI task 领域模型、命令、应用服务、事件、错误拆入对应文件。
3. 保持 AI task 状态迁移规则不变:
- `Pending -> Running`
- `Running -> Completed / Failed / Cancelled`
- 终态不允许继续写入阶段、文本片段、结果引用或任务结束状态
4. 保持流式文本片段按 `sequence` 聚合到阶段输出和任务 `latest_text_output`
5. 保持中文错误信息,便于 HTTP adapter 与 SpacetimeDB adapter 显式映射。
## 3. 文件边界
本次允许修改:
1. `server-rs/crates/module-ai/src/lib.rs`
2. `server-rs/crates/module-ai/src/domain.rs`
3. `server-rs/crates/module-ai/src/commands.rs`
4. `server-rs/crates/module-ai/src/application.rs`
5. `server-rs/crates/module-ai/src/events.rs`
6. `server-rs/crates/module-ai/src/errors.rs`
7. `server-rs/crates/module-ai/README.md`
8. 本文档和全局任务清单进度记录
本次禁止修改:
1. `server-rs/crates/spacetime-module/src/**`
2. `server-rs/crates/spacetime-client/src/**`
3. `server-rs/crates/api-server/src/**`
4. `server-rs/crates/shared-contracts/src/**`
5. `packages/shared/src/contracts/**`
## 4. 分层落点
| 文件 | 职责 |
| --- | --- |
| `domain.rs` | AI task kind/status、stage kind/status、snapshot、ID helper、文本归一 helper |
| `commands.rs` | create/start/stage/chunk/result/fail/cancel 等写入输入,以及创建命令校验 |
| `application.rs` | `AiTaskService``InMemoryAiTaskStore` 和纯内存状态迁移 |
| `events.rs` | AI task 领域事件枚举,供后续 adapter / event table 映射 |
| `errors.rs` | `AiTaskFieldError``AiTaskServiceError` 与中文 Display |
| `lib.rs` | 模块声明、公开 re-export、既有行为测试 |
## 5. 验收
必须执行:
```powershell
cargo test -p module-ai --manifest-path server-rs/Cargo.toml
cargo fmt --all --check --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_AI_TASK_DOMAIN_REFACTOR_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md server-rs/crates/module-ai/README.md server-rs/crates/module-ai/src/lib.rs server-rs/crates/module-ai/src/domain.rs server-rs/crates/module-ai/src/commands.rs server-rs/crates/module-ai/src/application.rs server-rs/crates/module-ai/src/events.rs server-rs/crates/module-ai/src/errors.rs
npm.cmd run api-server:maincloud
```
说明:本次不改 `api-server` route、SpacetimeDB table/reducer/procedure 或前端接线,但按仓库约束,后端 Rust 代码变更后仍执行 `npm.cmd run api-server:maincloud` 重新启动后端。

View File

@@ -0,0 +1,65 @@
# server-rs DDD WP-API BFF 收尾2026-05-01
## 1. 背景
`WP-API api-server BFF` 的启动切片已关闭旧 `/api/runtime/story/*` 兼容挂载,并把 `/api/story/*`、runtime projection、battle facade、平台错误模型等入口接到当前稳定的 `spacetime-client``platform-*` 能力上。
本收尾切片只处理 BFF 层还可以独立闭合的缺口:`/api/llm/chat/completions` 已具备非流式代理,但 `stream=true` 仍返回 `501``platform-llm` 已提供 OpenAI 兼容 SSE 解析和 `stream_text` 增量回调,因此 API 层可以补齐真正 SSE 输出,而不新增领域规则、不改 SpacetimeDB schema。
## 2. 收尾目标
1. `POST /api/llm/chat/completions` 保持非流式 JSON envelope 行为不变。
2. `POST /api/llm/chat/completions``stream=true` 时返回 `text/event-stream`,由 `platform-llm` 负责上游 SSE 解析API 层只转成前端可消费事件。
3. 流式事件固定为:
- `delta`:包含 `delta``content``finishReason`
- `complete`:复用 `LlmChatCompletionResponse``id/model/content/finishReason`
- 普通 data `[DONE]`:标记流结束。
4. 上游流式过程中失败时HTTP 已经开始返回 `200`,因此用 `error` SSE 事件携带 `code/message`,随后发送 `[DONE]`
5. 缺 LLM API Key 仍在开始流之前返回标准 `SERVICE_UNAVAILABLE` 错误 envelope。
## 3. 不变边界
1. 本次不新增、修改 SpacetimeDB table、reducer、procedure、绑定 shape 或 `migration.rs`
2. 本次不把 LLM prompt、剧情、玩法规则放进 `api-server`API 层只做鉴权、DTO 映射、SSE 转发和平台错误转换。
3.`/api/runtime/story/*` 继续不挂载;新 `/api/story/*` 继续只通过 `spacetime-client` facade。
4. 手机号登录与微信登录属于配置门控和 `platform-auth` 能力接入,不是 WP-API 缺失实现;角色动画 Stage 1 占位链继续归资产/模型生成深水区,不阻塞本次 BFF 收尾。
## 4. 验收
```powershell
cargo fmt -p api-server --manifest-path server-rs\Cargo.toml --check
cargo test -p api-server llm --manifest-path server-rs\Cargo.toml
cargo test -p api-server custom_world_ai --manifest-path server-rs\Cargo.toml
cargo test -p api-server runtime_story_legacy_routes_are_not_mounted --manifest-path server-rs\Cargo.toml
cargo check -p api-server --manifest-path server-rs\Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_API_BFF_CLOSURE_2026-05-01.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md server-rs/crates/api-server/src/llm.rs server-rs/crates/api-server/src/custom_world_ai.rs
npm.cmd run api-server:maincloud
```
说明:`api-server:maincloud` 是常驻服务命令,验收时以启动后 `/healthz` 探测 `200` 作为成功证据。
## 5. 验证结果
本轮已执行:
```powershell
cargo fmt --all --check --manifest-path server-rs\Cargo.toml
cargo test -p api-server llm --manifest-path server-rs\Cargo.toml
cargo test -p api-server custom_world_ai --manifest-path server-rs\Cargo.toml
cargo test -p api-server runtime_story_legacy_routes_are_not_mounted --manifest-path server-rs\Cargo.toml
cargo test -p api-server --manifest-path server-rs\Cargo.toml
cargo test -p module-runtime-story --manifest-path server-rs\Cargo.toml
cargo check --workspace --manifest-path server-rs\Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_API_BFF_CLOSURE_2026-05-01.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md server-rs/crates/api-server/src/llm.rs server-rs/crates/api-server/src/custom_world_ai.rs server-rs/crates/module-runtime-story/src/lib.rs server-rs/crates/module-runtime-story/src/bootstrap.rs server-rs/crates/module-runtime-story/src/session_action.rs
npm.cmd run api-server:maincloud
```
结果:通过。`api-server` 全量 203 个测试通过、4 个真实外部服务测试按预期 ignored`module-runtime-story` 11 个测试通过workspace 编译通过DDD 边界检查通过 15 个 module crate编码检查通过 8 个文件。`api-server:maincloud` 启动后 `GET http://127.0.0.1:3100/healthz` 返回 `200 {"ok":true,"service":"genarrative-api-server"}`,本轮 smoke 未留下常驻进程。启动日志中 Maincloud WebSocket 恢复认证快照短暂返回 `503 Service Unavailable`,未阻止 API server 就绪,属于外部 Maincloud 可用性告警。
本次为完成全量验证,还补齐了 `module-runtime-story` 测试编译门槛:
1. `module-runtime-story/src/lib.rs` 提高 `json!` 宏展开递归上限,避免开局快照大 JSON 构造在测试编译时触发 recursion limit。
2. `StoryRuntimeActionResolveOutput``Debug` derive满足 `expect_err` 测试约束。
3. 移除 `bootstrap.rs``session_action.rs` 的未用 import减少验证噪声。

View File

@@ -0,0 +1,98 @@
# server-rs DDD WP-API BFF 启动切片2026-04-29
## 1. 背景
`G1 契约与路由矩阵` 已冻结,`WP-RS` 已把旧 `module-runtime-story-compat` 迁为 `module-runtime-story`,当前可以启动 `WP-API api-server BFF` 的第一段边界收口。
`WP-ST SpacetimeDB Adapter``WP-SC Spacetime Client``WP-RS` 已提供 runtime projection 所需 facade 与领域投影 builder因此本切片继续完成 BFF 层接线:路由挂载收口、错误 envelope 门禁、健康检查、runtime projection 新主链 route 接入,不新增领域规则,不改 SpacetimeDB table/reducer/procedure不绕过 `spacetime-client`
## 2. 本切片目标
1. 确认旧 `/api/runtime/story/*` 兼容路由不再挂载到 `api-server/src/app.rs`
2. 保留新主链 `/api/story/*` route family后续只通过 `spacetime-client` facade 访问 SpacetimeDB。
3. 对旧 runtime story 路由补充 404 + `ApiErrorEnvelope` 回归测试,避免后续重新接回兼容入口。
4. 保持 `/healthz` 轻量健康检查可用,并在请求方声明 envelope 时返回标准成功 envelope。
5. 接入 story runtime projection 主链路由,固定鉴权、错误 envelope 与 `StoryRuntimeProjectionResponse` 输出。
6. 记录 WP-API 后续接线边界与前端迁移前置条件。
## 3. 文件边界
本切片允许修改:
1. `server-rs/crates/api-server/src/app.rs`
2. `server-rs/crates/api-server/src/story_sessions.rs`
3. `docs/technical/SERVER_RS_DDD_WP_API_BFF_START_2026-04-29.md`
4. `docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md`
5. `docs/technical/README.md`
本切片不修改:
1. `server-rs/crates/spacetime-module/src/**`
2. `server-rs/crates/spacetime-client/src/**`
3. `server-rs/crates/shared-contracts/src/**`
4. `packages/shared/src/contracts/**`
5. `src/services/**``src/hooks/**``src/components/**`
## 4. 当前 API 边界
### 4.1 已收口
旧 runtime story 兼容入口不再挂载:
1. `POST /api/runtime/story/sessions`
2. `POST /api/runtime/story/state/resolve`
3. `GET /api/runtime/story/state/{session_id}`
4. `POST /api/runtime/story/actions/resolve`
5. `POST /api/runtime/story/initial`
6. `POST /api/runtime/story/continue`
这些路径请求 `x-genarrative-response-envelope: v1` 时应返回:
1. HTTP status`404`
2. `ok=false`
3. `error.code=NOT_FOUND`
4. `error.message=资源不存在`
### 4.2 保留主链
当前保留的新主链入口:
1. `POST /api/story/sessions`
2. `GET /api/story/sessions/{story_session_id}/state`
3. `GET /api/story/sessions/{story_session_id}/runtime-projection`
4. `POST /api/story/sessions/continue`
5. `POST /api/story/battles`
6. `GET /api/story/battles/{battle_state_id}`
7. `POST /api/story/npc/battle`
8. `POST /api/story/battles/resolve`
这些 route 只能做鉴权、请求响应 DTO 映射、错误 envelope 和 `spacetime-client` 调用,不在 `api-server` 中复制 RPG 领域规则。
`runtime-projection` 已接入新主链鉴权通过后route 只读取当前用户身份,调用 `spacetime-client::get_story_runtime_projection_source`,再交给 `module-runtime-story::build_story_runtime_projection` 输出 `StoryRuntimeProjectionResponse`。API 层不得重新挂回旧 `/api/runtime/story/*` compat 总入口,也不得复制 actor、inventory、option、status 等领域投影规则。
## 5. 后续依赖
`WP-API` 后续继续接线前必须保持:
1. runtime projection 只通过 `spacetime-client` facade 读取 SpacetimeDB。
2. 投影规则只由 `module-runtime-story` 输出,`api-server` 只做 BFF 编排。
3. `WP-PF` 稳定 LLM、OSS、SMS、微信等平台副作用错误模型。
4. `G1` owner 合流必要 DTO shape 变更。
`runtime-projection` route/DTO 已可作为 `WP-FE-S` 迁移输入;前端仍需按 `services -> hooks -> components` 顺序推进,不在 hooks/components 中重建正式业务规则。
## 6. 验收
本切片验证命令:
```powershell
cargo test -p api-server runtime_story_legacy_routes_are_not_mounted --manifest-path server-rs/Cargo.toml
cargo test -p api-server healthz_returns_standard_envelope_when_requested --manifest-path server-rs/Cargo.toml
cargo test -p api-server get_story_runtime_projection --manifest-path server-rs/Cargo.toml
cargo check -p api-server --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_API_BFF_START_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md docs/technical/README.md server-rs/crates/api-server/src/app.rs server-rs/crates/api-server/src/story_sessions.rs
npm.cmd run api-server:maincloud
```
说明:本切片未修改 SpacetimeDB 表结构、reducer 或 procedure因此不需要更新 `migration.rs`,也不执行绑定生成。

View File

@@ -0,0 +1,40 @@
# WP-AS Assets 资产主链收尾记录2026-05-01
## 1. 收尾目标
关闭 `WP-AS Assets` 当前主链资产对象确认、实体槽位绑定、历史读取、OSS 对象确认、API facade、SpacetimeDB adapter 和订阅事件需要形成同一条后端真相链。
收尾后,`WP-AS` 不再以“资产 API/OSS/facade/event table 尚未全链收口”的口径挂起。后续 `asset_job``asset_manifest`、专业生成任务表和旧兼容入口物理删除,按新增需求或 `WP-DEL/WP-V` 另开切片。
## 2. 已完成内容
1. `module-assets` 补齐资产领域事件:`AssetDomainEvent``AssetObjectConfirmedEvent``AssetEntityBindingChangedEvent`
2. `spacetime-module` 新增 `asset_event` public event table记录 `ObjectConfirmed``EntityBindingChanged` 两类轻量事实。
3. `confirm_asset_object*` 成功 upsert `asset_object` 后写入对象确认事件;`bind_asset_object_to_entity*` 成功 upsert `asset_entity_binding` 后写入绑定变更事件。
4. `migration.rs` 已纳入 `asset_event``SPACETIMEDB_TABLE_CATALOG.md` 已补齐资产事件表结构、索引和查询模板。
5. Rust `module_bindings` 已补齐 `asset_event_type.rs``asset_event_kind_type.rs``asset_event_table.rs``mod.rs` 事件 diff 接线。
6. `module-assets/README.md` 已更新为当前状态资产对象、绑定、历史、OSS 确认、API facade 和 event table 已闭环,生成任务和 manifest 仍是后续扩展。
## 3. 边界说明
1. 正式资产状态仍以 `asset_object``asset_entity_binding` 为准;`asset_event` 只用于订阅端、BFF 和审计流程感知主链变化。
2. OSS 上传、HEAD Object、读代理和平台错误仍由 `api-server + platform-oss` 承接,领域 crate 不直接触碰网络副作用。
3. 本次不新增 `asset_job``asset_manifest` 或角色/动作/场景专用资产生成表。
4.`/generated-*` 读兼容入口暂不物理删除,后续归 `WP-DEL/WP-V` 统一处理。
## 4. 验收命令
```powershell
spacetime generate --no-config --lang rust --out-dir C:\g\rs --module-path server-rs\crates\spacetime-module --yes
cargo fmt -p module-assets -p spacetime-module --manifest-path server-rs\Cargo.toml --check
cargo test -p module-assets --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml --target wasm32-unknown-unknown
cargo check -p spacetime-client --manifest-path server-rs\Cargo.toml
cargo check -p api-server --manifest-path server-rs\Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_AS_ASSET_CHAIN_CLOSURE_2026-05-01.md docs/technical/SPACETIMEDB_TABLE_CATALOG.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md docs/technical/README.md server-rs/crates/module-assets/README.md server-rs/crates/module-assets/src/events.rs server-rs/crates/module-assets/src/lib.rs server-rs/crates/spacetime-module/src/asset_metadata/objects.rs server-rs/crates/spacetime-module/src/asset_metadata/bindings.rs server-rs/crates/spacetime-module/src/migration.rs server-rs/crates/spacetime-client/src/module_bindings/mod.rs server-rs/crates/spacetime-client/src/module_bindings/asset_event_kind_type.rs server-rs/crates/spacetime-client/src/module_bindings/asset_event_type.rs server-rs/crates/spacetime-client/src/module_bindings/asset_event_table.rs
npm.cmd run api-server:maincloud
```
执行结果以全局任务清单的本次记录为准。

View File

@@ -0,0 +1,58 @@
# WP-AS Assets 资产对象类型归位落地说明
## 背景
`module-assets` 已具备 `domain / commands / application / errors / events` DDD 骨架,但 `asset_object_core.rs` 仍同时承载领域模型、命令 DTO、应用返回 DTO、字段错误和纯构建函数。继续推进资产对象、实体绑定、OSS adapter 与 SpacetimeDB row mapper 时,容易把纯领域事实和外层编排混在同一个文件里。
本次作为 `WP-AS Assets` 的小切片,只在 `module-assets` crate 内做类型归位,不改变现有公开 API、SpacetimeDB 表结构、reducer/procedure、OSS 行为、api-server 路由或前端行为。
## 本次范围
允许修改:
1. `server-rs/crates/module-assets/src/domain.rs`
2. `server-rs/crates/module-assets/src/commands.rs`
3. `server-rs/crates/module-assets/src/application.rs`
4. `server-rs/crates/module-assets/src/errors.rs`
5. `server-rs/crates/module-assets/src/asset_object_core.rs`
6. `server-rs/crates/module-assets/src/lib.rs`
7. `server-rs/crates/module-assets/README.md`
8. 本文档与全局 DDD 任务清单
禁止修改:
1. `server-rs/crates/spacetime-module/src/**`
2. `server-rs/crates/spacetime-client/src/**`
3. `server-rs/crates/api-server/src/**`
4. `server-rs/crates/platform-oss/src/**`
5. 前端 services/hooks/components
## 设计
本次按 DDD 骨架进行类型归位:
1. `domain.rs` 承接资产对象、资产历史、实体绑定的纯快照、记录、访问策略、ID 前缀和版本常量。
2. `commands.rs` 承接确认资产对象、资产历史查询、对象 upsert、实体绑定等输入 DTO。
3. `application.rs` 承接 procedure result 和确认资产对象结果等应用返回 DTO。
4. `errors.rs` 承接 `AssetObjectFieldError` 及其中文错误文案。
5. `asset_object_core.rs` 保留字段校验、输入构建、记录构建、ID 生成和可复用归一化函数。
`lib.rs` 继续按原名称导出,避免影响 `spacetime-module``api-server` 或既有测试。
## 边界说明
1. 本次不移动 `AssetObjectService`,因为它仍依赖 `platform-oss` 的对象探测和进程内仓储。
2. 本次不新增资产任务、manifest 或专业资产表。
3. 本次不修改 `migration.rs`,因为没有表结构变更。
4. 本次不改变 `bucket + object_key` 双列真相字段。
## 验收
```powershell
cargo fmt -p module-assets --manifest-path server-rs/Cargo.toml --check
cargo test -p module-assets --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_AS_ASSET_OBJECT_TYPE_REHOME_2026-04-29.md server-rs/crates/module-assets/src/domain.rs server-rs/crates/module-assets/src/commands.rs server-rs/crates/module-assets/src/application.rs server-rs/crates/module-assets/src/errors.rs server-rs/crates/module-assets/src/asset_object_core.rs server-rs/crates/module-assets/src/lib.rs server-rs/crates/module-assets/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md docs/technical/README.md
```
后端启动按项目约束执行 `npm.cmd run api-server:maincloud`,若命令以前台服务常驻,则以 `/healthz` 结果记录。

View File

@@ -0,0 +1,121 @@
# WP-A Auth DDD 分层收口说明
## 背景
`module-auth` 当前已经具备 `domain / commands / application / events / errors` 文件骨架,但真实认证类型、服务、内存仓、文件持久化、短信 provider、密码哈希和微信状态逻辑仍主要集中在 `src/lib.rs`。这会让后续继续迁移 Auth 领域规则时难以区分纯领域模型和外层 adapter 能力。
本次从原先的领域值对象启动切片继续推进到 `WP-A Auth` 收口:把认证上下文的纯领域事实、命令输入、应用返回、领域错误和领域事件落回 DDD 骨架文件,同时核查 `api-server / platform-auth / spacetime-module` 的职责边界。
## 本次范围
允许修改:
1. `server-rs/crates/module-auth/src/domain.rs`
2. `server-rs/crates/module-auth/src/commands.rs`
3. `server-rs/crates/module-auth/src/application.rs`
4. `server-rs/crates/module-auth/src/events.rs`
5. `server-rs/crates/module-auth/src/errors.rs`
6. `server-rs/crates/module-auth/src/lib.rs`
7. `server-rs/crates/spacetime-module/src/auth.rs`
8. `server-rs/crates/module-auth/README.md`
9. 本文档
10. 全局 DDD 任务清单进度记录
本次只核查但不改动:
1. `server-rs/crates/api-server/src/auth*.rs`
2. `server-rs/crates/api-server/src/password_entry.rs`
3. `server-rs/crates/api-server/src/phone_auth.rs`
4. `server-rs/crates/api-server/src/refresh_session.rs`
5. `server-rs/crates/api-server/src/wechat_auth.rs`
6. `server-rs/crates/platform-auth/src/**`
禁止修改:
1. 其他玩法域。
2. 前端 services / hooks / components。
3. `server-node` 或旧 PostgreSQL 实现。
4. SpacetimeDB 表结构、reducer/procedure 签名和 `migration.rs`
## 设计
本次将以下纯领域事实和规则落入 `domain.rs`
1. `AuthLoginMethod`
2. `AuthBindingStatus`
3. `AuthUser`
4. `PhoneNumberSnapshot`
5. `PhoneAuthScene`
6. `WechatIdentityProfile`
7. `WechatAuthScene`
8. `WechatAuthStateRecord`
9. `RefreshSessionClientInfo`
10. `RefreshSessionRecord`
11. `AuthStoreSnapshotRecord`
12. 密码长度、短信验证码长度、验证码 TTL、冷却、失败次数等领域常量。
13. 手机号规范化、手机号脱敏、公开百梦号规范化、验证码 key 构造等纯函数。
本次将以下写入输入落入 `commands.rs`
1. `PasswordEntryInput`
2. `ChangePasswordInput`
3. `ResetPasswordInput`
4. `SendPhoneCodeInput`
5. `PhoneLoginInput`
6. `ResolveWechatLoginInput`
7. `CreateWechatAuthStateInput`
8. `BindWechatPhoneInput`
9. `CreateRefreshSessionInput`
10. `RotateRefreshSessionInput`
11. `LogoutCurrentSessionInput`
12. `LogoutAllSessionsInput`
13. `AuthStoreSnapshotUpsertInput`
本次将以下应用返回落入 `application.rs`
1. 登录、换密、重置密码、验证码发送、手机号登录、微信登录、微信绑定、会话签发/轮换/查询/登出等 result。
2. `AuthStoreSnapshotProcedureResult`
本次将以下错误落入 `errors.rs`
1. `PasswordEntryError`
2. `PhoneAuthError`
3. `WechatAuthError`
4. `RefreshSessionError`
5. `LogoutError`
6. 错误展示文案和模块内错误映射辅助函数。
本次将领域事件落入 `events.rs`
1. `UserCreated`
2. `RefreshSessionIssued`
3. `RefreshSessionRevoked`
4. `PhoneVerified`
5. `WechatIdentityBound`
`lib.rs` 保留当前服务、进程内仓储和文件持久化实现,但不再继续拥有上述命令、结果、错误、事件和领域值对象定义;公开 API 继续通过 `pub use application::* / commands::* / domain::* / errors::* / events::*` 导出,避免影响现有 BFF 调用。
## 边界说明
1. `module-auth` 承接账号、refresh session、短信验证码状态、微信 state 和微信绑定规则,不依赖 Axum、SpacetimeDB table API、HTTP status、真实短信 SDK、微信 HTTP 或 JWT/cookie 细节。
2. `platform-auth` 继续承接短信 provider、微信 OAuth provider、密码哈希、refresh token、JWT 和 cookie 等平台副作用。
3. `api-server` 只做请求解析、鉴权、DTO 映射、session cookie/JWT 编排和平台/领域服务装配;本次核查未发现 Auth route 需要复制领域状态机。
4. `spacetime-module/src/auth.rs` 当前仍是认证快照与正式表之间的 SpacetimeDB adapter不调用短信、微信、JWT、HTTP 或文件系统;本次只修正历史乱码中文注释和错误文案,不改变表结构或 procedure 签名。
5. `InMemoryAuthStore` 和文件持久化仍保留在 `lib.rs`,作为当前 Auth 运行支撑;总纲中“仓储剥离到 adapter 或测试支撑”的更彻底物理拆分可作为后续非 WP-A 阻塞项继续推进,但本次 WP-A 已完成 DDD 骨架归位和边界核查。
## 验收
```powershell
cargo fmt -p module-auth --manifest-path server-rs/Cargo.toml --check
cargo test -p module-auth --manifest-path server-rs/Cargo.toml
cargo check -p module-auth --manifest-path server-rs/Cargo.toml --all-features
cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml
cargo test -p api-server auth --manifest-path server-rs/Cargo.toml
cargo test -p api-server wechat --manifest-path server-rs/Cargo.toml
cargo check -p api-server --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_A_AUTH_DOMAIN_VALUE_OBJECT_REFACTOR_2026-04-29.md server-rs/crates/module-auth/src/domain.rs server-rs/crates/module-auth/src/commands.rs server-rs/crates/module-auth/src/application.rs server-rs/crates/module-auth/src/errors.rs server-rs/crates/module-auth/src/events.rs server-rs/crates/module-auth/src/lib.rs server-rs/crates/module-auth/README.md server-rs/crates/spacetime-module/src/auth.rs docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md docs/technical/README.md
npm.cmd run api-server:maincloud
```
本次不发布 SpacetimeDB、不生成绑定、不修改 `migration.rs`原因是没有表结构、reducer、procedure 或绑定形状变更。

View File

@@ -0,0 +1,34 @@
# WP-BF 与 G2 迁移期口径清理
日期:`2026-04-30`
## 1. 本次目标
本次收口 `4.1 未完整收口内容整合清单``G2/跨包清理``过渡落位` 的残留命中,重点处理:
1. `module-big-fish` 已标记 `WP-BF` 完成,但 `lib.rs` 仍承载大量创作域类型、命令、校验和序列化规则。
2. `module-runtime``module-puzzle``module-assets` 只剩文件头迁移期口径,与当前真实边界不一致。
## 2. 已完成
1. `module-big-fish/src/domain.rs` 承接创作阶段、锚点、资产槽、草稿、会话、作品摘要、发布门禁和运行态领域类型。
2. `module-big-fish/src/commands.rs` 承接会话、消息、草稿、资产、发布、游玩记录和运行态输入 DTO。
3. `module-big-fish/src/application.rs` 承接锚点推断、默认草稿编译、资产覆盖、资产槽构造、字段校验、序列化与运行态真相源规则。
4. `module-big-fish/src/errors.rs` 承接应用错误、字段错误和中文错误文案。
5. `module-big-fish/src/lib.rs` 收口为模块声明、公开导出和测试,继续保持 `module_big_fish::*` 公开 API。
6. `module-runtime``module-puzzle``module-assets` 的文件头已从迁移期“过渡落位”口径改为当前领域边界口径。
## 3. 边界说明
1. 本次不改 Big Fish SpacetimeDB 表、procedure、API route、前端 client 或绑定 shape。
2. 本次不为 Assets 新增未消费 event API`module-assets/src/events.rs` 只修正口径。
3. 本次不把 Puzzle/API/前端未完成链路误标为完成,只清理 DDD 物理拆分和注释漂移。
## 4. 验证
```powershell
cargo test -p module-runtime -p module-puzzle -p module-assets -p module-big-fish --manifest-path server-rs\Cargo.toml
cargo fmt -p module-runtime -p module-puzzle -p module-assets -p module-big-fish --manifest-path server-rs\Cargo.toml --check
```
结果:通过;上述源码不再命中 `过渡落位`

View File

@@ -0,0 +1,84 @@
# server-rs DDD WP-BF Big Fish 运行态后端真相源关闭记录2026-04-29
## 1. 背景
`WP-BF Big Fish` 已完成发布门禁领域化,但运行态仍由前端本地规则推进,导致前端同时承担输入、实体移动、碰撞、合成、胜负结算和快照更新。按照本轮 DDD 重构边界,前端只负责表现和提交输入,正式运行态规则必须落到 `server-rs`
本次关闭目标是把 Big Fish 从“前端本地运行态”切到“Rust 领域规则 + SpacetimeDB 运行表 + API facade + 前端 client 接入”的单主链,同时移除 Big Fish works mapper 中的旧形状兼容解析。
## 2. 本次完成范围
1. `module-big-fish` 新增运行态领域快照:
- `BigFishRunStatus`
- `BigFishVector2`
- `BigFishRuntimeEntitySnapshot`
- `BigFishRuntimeSnapshot`
2. `module-big-fish` 新增运行态应用服务:
- `start_big_fish_run`
- `submit_big_fish_input`
- `serialize_runtime_snapshot`
- `deserialize_runtime_snapshot`
3. 运行态规则已由领域层统一负责:
- 初始己方和野生实体生成。
- 输入向量归一化。
- 领队、跟随者和野生实体移动。
- 同级收编、强弱碰撞、三合一升级。
- 离屏野生实体裁剪和补刷。
- 胜利、失败和结算事件。
4. `spacetime-module/src/big_fish/runtime.rs` 新增 Big Fish 运行态 procedure
- `start_big_fish_run`
- `get_big_fish_run`
- `submit_big_fish_input`
5. 新增 `big_fish_runtime_run` 表,保存 run 快照、最后输入方向、tick、归属用户和会话来源并已同步 `migration.rs` 与表目录。
6. `spacetime-client` 新增 Big Fish runtime typed facade 和 record mapper并重新生成 Rust 绑定。
7. `api-server` 新增鉴权路由:
- `POST /api/runtime/big-fish/sessions/{session_id}/runs`
- `GET /api/runtime/big-fish/runs/{run_id}`
- `POST /api/runtime/big-fish/runs/{run_id}/input`
8. `shared-contracts` 与前端 shared contract 新增 `BigFishRunResponse`、运行态实体/坐标 DTO 和 `SubmitBigFishInputRequest`
9. 前端 Big Fish 运行态 client 改为调用后端 run/input 接口,`PlatformEntryFlowShellImpl` 不再推进本地规则。
10. 删除 `src/services/big-fish-runtime/bigFishLocalRuntime.ts``/big-fish` 调试直达页降级回平台入口,避免继续暴露本地运行态主链。
## 3. 边界说明
1. 本次不接入 `server-node`、Express 或 PostgreSQL也不为旧 Node 兼容层保留双主链。
2. `spacetime-module` 只负责表读写、授权、事务编排和调用领域服务,不在 adapter 内复制 Big Fish 玩法规则。
3. `api-server` 只负责鉴权、请求校验、DTO 映射和 `spacetime-client` facade 调用,不直接访问 SpacetimeDB table。
4. 前端只提交方向输入并渲染后端返回快照,正式实体状态、胜负和事件日志都以后端响应为准。
5. Big Fish works mapper 已移除旧 JSON 兼容解析,后续要求 SpacetimeDB procedure 返回新的 `owner_user_id``play_count` 等稳定字段。
6. `big_fish_runtime_run` 是运行态快照表,不替代创作会话、资产槽或发布门禁真相;删除作品时同步清理来源会话下的 run。
## 4. 后续边界
1. Big Fish 运行态资源展示仍复用现有 session / work 的资产槽数据;若要让公开作品 run 响应直接携带资产包,应由后续契约任务单独扩展 DTO。
2. 真实 Maincloud 发布和订阅侧 smoke 仍归 `WP-V 全链验证与发布 smoke`
3. 若后续把运行态拆为更细表,而不是整份 `snapshot_json`,必须重新同步 `migration.rs`、绑定和 `SPACETIMEDB_TABLE_CATALOG.md`
## 5. 验收
关闭前必须执行:
```powershell
cargo test -p module-big-fish --manifest-path server-rs/Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml
cargo check -p spacetime-client --manifest-path server-rs/Cargo.toml
cargo check -p api-server --manifest-path server-rs/Cargo.toml
npm.cmd run test -- src/components/big-fish-runtime/BigFishRuntimeShell.test.tsx src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_BF_RUNTIME_BACKEND_TRUTH_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md docs/technical/README.md docs/technical/SPACETIMEDB_TABLE_CATALOG.md server-rs/crates/module-big-fish/src/application.rs server-rs/crates/module-big-fish/src/domain.rs server-rs/crates/module-big-fish/src/commands.rs server-rs/crates/module-big-fish/src/errors.rs server-rs/crates/module-big-fish/src/events.rs server-rs/crates/module-big-fish/src/lib.rs server-rs/crates/spacetime-module/src/big_fish/runtime.rs server-rs/crates/spacetime-module/src/big_fish/tables.rs server-rs/crates/spacetime-module/src/big_fish/session.rs server-rs/crates/spacetime-module/src/migration.rs server-rs/crates/spacetime-client/src/big_fish.rs server-rs/crates/spacetime-client/src/mapper.rs server-rs/crates/spacetime-client/src/lib.rs server-rs/crates/shared-contracts/src/big_fish.rs server-rs/crates/api-server/src/big_fish.rs server-rs/crates/api-server/src/app.rs packages/shared/src/contracts/bigFish.ts src/services/big-fish-runtime/bigFishRuntimeClient.ts src/services/big-fish-runtime/index.ts src/components/platform-entry/PlatformEntryFlowShellImpl.tsx src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx src/BigFishPlaygroundApp.tsx
npm.cmd run api-server:maincloud
```
最终执行结果:
1. `cargo test -p module-big-fish --manifest-path server-rs/Cargo.toml` 通过6 个测试通过。
2. `cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml` 通过。
3. `cargo check -p spacetime-client --manifest-path server-rs/Cargo.toml` 通过。
4. `cargo check -p api-server --manifest-path server-rs/Cargo.toml` 通过,仅保留既有 `api-server/src/prompt/rpg/runtime_chat.rs` 未使用 helper warning。
5. `npm.cmd run check:server-rs-ddd` 通过。
6. `npm.cmd run test -- src/components/big-fish-runtime/BigFishRuntimeShell.test.tsx` 通过4 个测试通过;测试已改为真实定时等待,不再使用全局 fake timers。
7. `npm.cmd run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "public code search opens a published big fish work by BF code"` 通过,确认 BF 编号搜索进入后端 run 主链。
8. `npm.cmd run check:encoding -- ...` 对本次触达文件通过,收尾补充检查对 3 个文件通过。
9. `npm.cmd run api-server:maincloud` 已按常驻服务启动;`GET http://127.0.0.1:3100/healthz` 返回 `200`,验收后已停止本次启动进程。
补充说明:完整 `src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx` 当前单独运行仍有既有长流程用例失败,失败集中在 RPG/拼图/创作结果页路径,例如 `create tab opens compiled agent draft in result refinement page``published puzzle detail returns to the source platform tab``agent draft result test button enters current draft without publish gate`。这些失败在不并跑 Big Fish runtime 测试时也存在,未指向本次 WP-BF 运行态迁移文件,后续应由对应 RPG/Puzzle/Custom World 前端接线包继续收口。

View File

@@ -0,0 +1,43 @@
# WP-CW Custom World 动作与领域拆分收口
日期:`2026-04-30`
## 1. 本次目标
本次收口 `4.1 未完整收口内容整合清单``WP-CW Custom World` 的两个漂移点:
1. `module-custom-world` 仍由 `lib.rs` 承载主要领域类型、命令、错误和应用规则。
2. `spacetime-module/src/custom_world/mod.rs` 中多个 Agent action 仍走最小兼容占位。
## 2. 已完成
1. `module-custom-world/src/lib.rs` 已收口为模块声明、公开导出和测试,继续保持 `module_custom_world::*` 公开 API。
2. `src/domain.rs` 承接 Custom World / RPG Agent 枚举、进度常量、profile/session/card/gallery/publish gate 快照与结果类型。
3. `src/commands.rs` 承接 profile、library/gallery、Agent session/message/operation/action、published profile compile 和 publish world 输入 DTO。
4. `src/application.rs` 承接字段校验、默认 JSON、profile canonicalize、published profile compile 和 publish gate 相关纯规则。
5. `src/errors.rs` 承接 `CustomWorldFieldError` 与中文错误文案。
6. `src/events.rs` 承接 Custom World 领域事件与 payload struct避免 `spacetime-types` feature 下使用结构体式 enum 变体。
7. `spacetime-module/src/custom_world/mod.rs` 已移除 `execute_placeholder_custom_world_action`,以下动作改为确定性状态编排:
- `generate_characters`
- `generate_landmarks`
- `generate_role_assets`
- `sync_role_assets`
- `generate_scene_assets`
- `sync_scene_assets`
- `expand_long_tail`
## 3. 边界说明
1. 本次不引入 LLM、图片生成、OSS 上传或外部网络副作用。
2. SpacetimeDB procedure/reducer 内只组合当前会话状态、payload、draft card、asset coverage 和 publish gate保持确定性。
3. 本次不改表结构、绑定 shape 或 `migration.rs`
4. 完整 profile/agent/draft/gallery/publish gate 全链仍按 `WP-CW/WP-ST/WP-SC/WP-API/WP-FE` 后续推进。
## 4. 验证
```powershell
cargo test -p module-custom-world --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml
```
结果:通过,`module-custom-world` 13 个单元测试通过,`spacetime-module` 编译通过Custom World 源码不再命中 `execute_placeholder_custom_world_action``最小兼容占位``过渡落位`

View File

@@ -0,0 +1,41 @@
# WP-CW Custom World 基础领域枚举归位切片
## 背景
`module-custom-world/src/lib.rs` 仍直接承载 Custom World 和 RPG Agent 的基础枚举、字符串口径与进度常量。随着 `custom_world` SpacetimeDB adapter 已完成根入口瘦身,领域 crate 也需要继续把纯领域对象迁入 `domain.rs`,避免后续 profile、agent session、draft card、gallery 与 publish gate 规则继续堆回根文件。
## 本次范围
1. 认领 `WP-CW Custom World` 的基础领域枚举归位切片。
2.`MAX_PROGRESS_PERCENT` 迁入 `module-custom-world/src/domain.rs`
3. 将 Custom World / RPG Agent 基础枚举迁入 `domain.rs`
- `CustomWorldPublicationStatus`
- `CustomWorldThemeMode`
- `CustomWorldGenerationMode`
- `CustomWorldSessionStatus`
- `RpgAgentStage`
- `RpgAgentMessageRole`
- `RpgAgentMessageKind`
- `RpgAgentOperationType`
- `RpgAgentOperationStatus`
- `RpgAgentDraftCardKind`
- `RpgAgentDraftCardStatus`
- `CustomWorldRoleAssetStatus`
4. 将这些枚举的 `as_str``CustomWorldThemeMode::from_client_str` 一并迁入 `domain.rs`
5. `lib.rs` 通过 `pub use domain::*` 保持既有 `module_custom_world::*` 公开 API。
## 边界
1. 本次不改 SpacetimeDB table、reducer、procedure、row mapper 或 `migration.rs`
2. 本次不改 `api-server``spacetime-client`、platform adapter 或前端。
3. 本次不移动 profile、agent session、draft card、publish gate 的结构体和校验函数,避免把大包拆分与本切片混在一起。
4. 本次不改变任何序列化字段、枚举字符串值或中文错误文案。
## 验收
```powershell
cargo fmt -p module-custom-world --manifest-path server-rs/Cargo.toml --check
cargo test -p module-custom-world --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_CW_DOMAIN_ENUM_REHOME_2026-04-29.md server-rs/crates/module-custom-world/src/domain.rs server-rs/crates/module-custom-world/src/lib.rs docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
```

View File

@@ -0,0 +1,98 @@
# WP-CW Custom World 全链收尾
日期:`2026-05-01`
## 1. 收尾目标
本次收尾关闭 `SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md``WP-CW Custom World` 的剩余主链漂移:
1. `module-custom-world` 已完成 DDD 物理拆分,本次不再重拆领域 crate。
2. `spacetime-module/src/custom_world/*` 已完成 Agent action 确定性状态编排,本次不改表结构、不改 reducer/procedure 对外名称。
3. `spacetime-client/src/custom_world.rs` 已具备 profile、gallery、agent session、message、action、operation、card detail、works facade本次只把 API 和前端主入口对齐到这些稳定 facade。
4. `api-server` 中 Custom World 图片链路测试必须稳定,不允许因本机 `.env.local` 中真实 DashScope Key 让“缺配置”测试变成真实上游调用。
5. 前端 RPG 创作资产 client 统一使用 `/api/runtime/custom-world/*` 主链,旧 `/api/custom-world/*` 仅作为过渡入口保留给历史调用。
## 2. 主链路由
Authenticated 创作链路:
1. `POST /api/runtime/custom-world/profile`
2. `GET /api/runtime/custom-world-library`
3. `GET /api/runtime/custom-world-library/{profile_id}`
4. `PUT /api/runtime/custom-world-library/{profile_id}`
5. `DELETE /api/runtime/custom-world-library/{profile_id}`
6. `POST /api/runtime/custom-world-library/{profile_id}/publish`
7. `POST /api/runtime/custom-world-library/{profile_id}/unpublish`
8. `POST /api/runtime/custom-world/agent/sessions`
9. `GET /api/runtime/custom-world/agent/sessions/{session_id}`
10. `DELETE /api/runtime/custom-world/agent/sessions/{session_id}`
11. `GET /api/runtime/custom-world/agent/sessions/{session_id}/result-view`
12. `GET /api/runtime/custom-world/works`
13. `GET /api/runtime/custom-world/agent/sessions/{session_id}/cards/{card_id}`
14. `POST /api/runtime/custom-world/agent/sessions/{session_id}/messages`
15. `POST /api/runtime/custom-world/agent/sessions/{session_id}/messages/stream`
16. `POST /api/runtime/custom-world/agent/sessions/{session_id}/actions`
17. `GET /api/runtime/custom-world/agent/sessions/{session_id}/operations/{operation_id}`
18. `POST /api/runtime/custom-world/entity`
19. `POST /api/runtime/custom-world/scene-npc`
20. `POST /api/runtime/custom-world/scene-image`
21. `POST /api/runtime/custom-world/cover-image`
22. `POST /api/runtime/custom-world/cover-upload`
Public gallery 链路:
1. `GET /api/runtime/custom-world-gallery`
2. `GET /api/runtime/custom-world-gallery/{owner_user_id}/{profile_id}`
3. `GET /api/runtime/custom-world-gallery/by-code/{code}`
## 3. 兼容入口边界
以下旧入口本次不物理删除,避免影响历史编辑器、旧测试或外部草稿工具,但 RPG 创作主 client 不再使用它们:
1. `POST /api/custom-world/entity`
2. `POST /api/custom-world/scene-npc`
3. `POST /api/custom-world/scene-image`
4. `POST /api/custom-world/cover-image`
5. `POST /api/custom-world/cover-upload`
旧入口只转到同一批 Axum handler不拥有独立业务规则。
## 4. 资产与外部副作用边界
1. LLM、DashScope 图片生成、OSS 上传仍位于 `api-server + platform-*`,不进入 reducer/procedure。
2. 成功生成或上传后的资产对象确认、绑定通过 `spacetime-client` 调用 `spacetime-module`,不由前端自行维护真相。
3. DashScope 缺配置返回 `SERVICE_UNAVAILABLE`;上游请求已发出但失败返回 `UPSTREAM_ERROR`
4. 测试中验证“缺配置”必须显式构造无 key 配置,避免受开发机 `.env.local` 影响。
## 5. 验收
本次收尾后至少执行:
```powershell
cargo test -p module-custom-world --manifest-path server-rs\Cargo.toml
cargo test -p api-server custom_world --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-client --manifest-path server-rs\Cargo.toml
npm.cmd run test -- src/services/rpg-creation/rpgCreationGenerationClient.test.ts src/services/rpg-creation/rpgCreationGenerationClient.node.test.ts src/services/rpg-creation/rpgCreationAssetClient.test.ts
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_CW_FULL_CHAIN_CLOSURE_2026-05-01.md
```
若本机 Maincloud 常驻服务导致 `npm.cmd run api-server:maincloud` 超时或端口占用,记录 `healthz` 探测结果即可,不改用旧后端重启命令。
## 6. 本轮验证结果
已通过:
1. `cargo test -p module-custom-world --manifest-path server-rs\Cargo.toml`13 个单元测试通过。
2. `cargo test -p api-server custom_world --manifest-path server-rs\Cargo.toml`30 个 Custom World 定向测试通过。
3. `cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml`:通过。
4. `cargo check -p spacetime-client --manifest-path server-rs\Cargo.toml`:通过。
5. `npm.cmd run test -- src/services/rpg-creation/rpgCreationGenerationClient.test.ts src/services/rpg-creation/rpgCreationGenerationClient.node.test.ts src/services/rpg-creation/rpgCreationAssetClient.test.ts`3 个测试文件 7 个用例通过。
6. `npm.cmd run check:server-rs-ddd`15 个 module crate 边界检查通过。
7. `npm.cmd run check:encoding -- docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md docs/technical/SERVER_RS_DDD_WP_CW_FULL_CHAIN_CLOSURE_2026-05-01.md server-rs/crates/api-server/src/custom_world_ai.rs src/services/rpg-creation/rpgCreationAssetClient.ts src/services/rpg-creation/rpgCreationAssetClient.test.ts`6 个文件通过。
8. `npm.cmd run api-server:maincloud`:按常驻服务形态在工具侧超时;超时前 `/healthz` 返回 `200``{"ok":true,"service":"genarrative-api-server"}`,随后已清理本次 smoke 启动留下的 `api-server``cargo``node` 子进程并确认 `3100` 端口释放。
已知非本轮阻塞:
1. `cargo fmt --all --check --manifest-path server-rs\Cargo.toml` 仍被当前工作区非 WP-CW 的 `module-story` 格式漂移阻塞;本轮 `api-server` 包格式检查已通过。

View File

@@ -0,0 +1,80 @@
# WP-DEL 旧层删除与命名收口
日期2026-05-01
## 目标
本轮 `WP-DEL` 只处理已被新主链完全替代的旧 HTTP contract、旧 route、旧前端 alias 和旧测试夹具,不新增业务能力,不恢复 `server-node` 兼容,不修改 SpacetimeDB 表结构。
## 已删除范围
1. Runtime Story 旧 HTTP DTO
- Rust `RuntimeStoryStateResolveRequest`
- Rust/TS `RuntimeStoryBootstrapRequest/Response`
- Rust/TS `RuntimeStoryActionResponse`
- TS 泛型 `RuntimeActionRequest/Response`
-`RuntimeStorySnapshotPayload` 只作为旧 HTTP 总入口快照结构删除;当前 story session scoped 写侧使用 `StoryRuntimeMutationResponse.projection`
2. Runtime Story 前端旧命名:
- `beginRpgRuntimeStorySession`
- `resolveRpgRuntimeStoryAction`
- `getRpgStoryRuntimeProjection`
- `getRpgRuntimeActionSnapshot`
- `rpgRuntimeStoryClient` 聚合对象
- 其他 `Rpg*RuntimeStory*` alias 统一删除,前端只导出当前主链命名。
3. Custom World 旧非 runtime 前缀路由:
- `POST /api/custom-world/entity`
- `POST /api/custom-world/scene-npc`
- `POST /api/custom-world/scene-image`
- `POST /api/custom-world/cover-image`
- `POST /api/custom-world/cover-upload`
- 当前主链固定为 `/api/runtime/custom-world/*`
4. Puzzle 旧本地下一关入口:
- `POST /api/runtime/puzzle/runs/local-next-level`
- Rust/TS `AdvanceLocalPuzzleNextLevelRequest`
- API 层本地 next-level 拼装 helper 与对应旧测试。
5. `/generated-*` 资产直读代理:
- `GET /generated-character-drafts/{*path}`
- `GET /generated-characters/{*path}`
- `GET /generated-animations/{*path}`
- `GET /generated-big-fish-assets/{*path}`
- `GET /generated-puzzle-assets/{*path}`
- `GET /generated-custom-world-scenes/{*path}`
- `GET /generated-custom-world-covers/{*path}`
- `GET /generated-qwen-sprites/{*path}`
-`api-server` 同源代理模块 `legacy_generated_assets.rs`
- Vite 与发布静态服务器中的 `/generated-*` 直读转发配置。
## 保留边界
1. `/generated-*` 字符串仍可作为历史 DTO 与测试夹具里的 `legacyPublicPath` 标识OSS object key 前缀和 `LegacyAssetPrefix` 继续保留但浏览器、Vite、本地发布静态服务器和 `api-server` 不再提供 `/generated-*` 裸读入口。
2. 正式读取契约固定为 `asset_object``GET /api/assets/read-url``ResolvedAssetImage/useResolvedAssetReadUrl` 或业务投影里的签名读 URL 字段。
3. `RuntimeStoryActionRequest` 仍保留为 `module-runtime-story` 内部动作规则输入,不作为旧 HTTP route contract。
4. `RuntimeStoryViewModel``RuntimeStoryPresentation``RuntimeStoryPatch` 和 battle presentation 仍作为当前投影/表现构件保留,不再代表旧 `/api/runtime/story/*` 总入口响应。
5. 历史设计文档中对旧 route/DTO 的引用只作为时间点记录保留,不批量改写旧档案。
## 验收门禁
计划执行:
```powershell
cargo fmt --all --manifest-path server-rs\Cargo.toml
cargo fmt --all --check --manifest-path server-rs\Cargo.toml
npm.cmd run check:server-rs-ddd
cargo check --workspace --manifest-path server-rs\Cargo.toml
cargo test --workspace --exclude spacetime-module --manifest-path server-rs\Cargo.toml
npm.cmd run test -- src/services/rpg-runtime/rpgRuntimeStoryClient.test.ts src/hooks/rpg-runtime-story/runtimeStoryCoordinator.test.ts src/services/ai.test.ts src/services/puzzle-runtime
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_DEL_CLEANUP_2026-05-01.md docs/technical/README.md docs/technical/SERVER_RS_DDD_G1_CONTRACT_AND_ROUTE_MATRIX_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md server-rs/crates/shared-contracts/README.md server-rs/crates/api-server/README.md server-rs/crates/module-puzzle/README.md
```
实际结果:
1. `cargo fmt --all --manifest-path server-rs\Cargo.toml`:通过。
2. `cargo fmt --all --check --manifest-path server-rs\Cargo.toml`:通过。
3. `npm.cmd run check:server-rs-ddd`通过15 个 module crate 边界检查通过。
4. `cargo check --workspace --manifest-path server-rs\Cargo.toml`:通过;仅保留既有 runtime chat prompt dead code warning。
5. `cargo test --workspace --exclude spacetime-module --manifest-path server-rs\Cargo.toml`:通过;`api-server` 207 个测试通过、4 个 live/外部依赖测试按既有条件忽略。
6. `npm.cmd run test -- src/services/rpg-runtime/rpgRuntimeStoryClient.test.ts src/hooks/rpg-runtime-story/runtimeStoryCoordinator.test.ts src/services/ai.test.ts src/services/puzzle-runtime`通过4 个测试文件 45 个用例通过。
7. `npm.cmd run check:encoding`:通过,全量 2816 个文件通过 UTF-8/乱码检查。
8. `npm.cmd run spacetime:generate -- --rust-only`通过SpacetimeDB CLI 在 Windows 长路径格式化阶段触发已知失败后,项目脚本使用短路径分批 `rustfmt` fallback 完成。
9. `cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml`:通过。
10. `npm.cmd run api-server:maincloud`:通过;后端拉起后 `GET http://127.0.0.1:3100/healthz` 返回 `200 {"ok":true,"service":"genarrative-api-server"}`,随后已清理本次 smoke 进程并确认 3100 端口释放。启动期 Maincloud 订阅恢复出现两条 `503 Service Unavailable` 警告,不影响 healthz smoke。

View File

@@ -0,0 +1,34 @@
# WP-FE-C RPG runtime shell 组件测试夹具接线切片
## 背景
`WP-FE-S``WP-FE-H` 已经把 RPG runtime story 读取侧收口到 `storySessionId` scoped projection client 与 hooks 网关。组件层仍不能迁移完整开局、动作结算等写接口,但 `RpgRuntimeShell` 组件测试夹具还保留旧 hook UI 形状,导致 `typecheck` 在组件测试文件中失败。
## 本次范围
1. 认领 `WP-FE-C Frontend components 接线` 中可并行的 RPG runtime shell 组件测试夹具接线切片。
2. 修正 `src/components/rpg-runtime-shell/RpgRuntimeShell.test.tsx`
- `StoryMoment` mock 使用当前 `text/options` 字段。
- `Character` mock 对齐当前角色类型,不再写入旧 `motivation/combatStyle/role/imageSrc/initialItems` 等字段。
- `npcUi/characterChatUi/inventoryUi/battleRewardUi/questUi/npcChatQuestOfferUi/goalUi` mock 对齐当前 hooks 暴露的稳定 UI 对象形状。
3. 保持 `RpgRuntimeShell` 正式组件行为不变,只消除测试夹具对旧组件接线形状的依赖。
## 2026-05-01 收尾切片
`WP-FE-S/H` 写侧切到新 story session scoped 主链后,本切片只确认组件层夹具继续消费 hooks 出口,不在组件中补业务规则:
1. `RpgRuntimeShell` 正式组件不拼接 `/api/runtime/story/*``/api/story/*` 路径。
2. 组件测试 mock 继续对齐 `hydratedSnapshot/nextStory` 与当前 UI 对象形状。
3. 不新增 UI 文案,不改视觉布局;服务端动作表现差异只通过 hooks 状态进入组件。
4. 旧 runtime story contract 和旧 alias 仍由 `WP-DEL` 统一删除。
## 验收
```powershell
npm.cmd run typecheck -- --pretty false
npm.cmd run test -- src/components/rpg-runtime-shell/RpgRuntimeShell.test.tsx
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_FE_C_RPG_RUNTIME_SHELL_TEST_FIXTURE_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md src/components/rpg-runtime-shell/RpgRuntimeShell.test.tsx
git diff --check -- docs/technical/SERVER_RS_DDD_WP_FE_C_RPG_RUNTIME_SHELL_TEST_FIXTURE_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md src/components/rpg-runtime-shell/RpgRuntimeShell.test.tsx
```
结果:`RpgRuntimeShell.test.tsx` 定向测试通过;编码检查和空白检查通过。`typecheck` 未全量通过,但不再报本切片文件,剩余阻塞来自既有非本切片文件 `src/data/sceneEncounterPreviews.ts``src/services/ai.ts`

View File

@@ -0,0 +1,39 @@
# WP-FE-H RPG runtime story 读取侧 hooks 接线切片
## 背景
`WP-FE-S` 已经补齐 story session 新主链 client并提供 `getRpgStoryRuntimeProjection` 读取 `/api/story/sessions/{storySessionId}/runtime-projection``WP-FE-H` 的完整 hooks 迁移仍依赖后端 session scoped 开局和动作结算写接口;但读取侧 option catalog 与继续游戏刷新已经具备稳定 projection contract可以先把 hooks 网关的读取语义收口到 projection client。
## 本次范围
1. 认领 `WP-FE-H Frontend hooks 迁移` 中可并行的 RPG runtime story 读取侧 hooks 接线切片。
2.`src/hooks/rpg-runtime-story/rpgRuntimeStoryGateway.ts` 的读取侧从历史别名 `getRpgRuntimeStoryState` 改为显式调用 `getRpgStoryRuntimeProjection`
3. `loadServerRuntimeOptionCatalog` 继续只读取服务端 option catalog不上传本地 `GameState` 参与动作合法性解析。
4. `resumeServerRuntimeStory` 继续保持本地已水合快照主体,只同步服务端 `runtimeSessionId / storySessionId / runtimeActionVersion` 和投影故事。
5. 更新 `runtimeStoryCoordinator.test.ts` mock 命名,确保 hooks 测试明确断言读取侧走 projection client。
6. 补齐 `src/hooks/useGameFlow.customWorld.test.tsx``beginRpgRuntimeStorySession` 测试桩,避免 hooks 全量测试在 Node 环境直接 fetch 相对路径,同时保持自定义世界开局 hooks 仍消费服务端快照。
## 2026-05-01 收尾切片
后端补齐 `/api/story/sessions/runtime``/api/story/sessions/{storySessionId}/actions/resolve`hooks 写侧同步收口:
1. `resolveServerRuntimeChoice` 不再调用旧 `/api/runtime/story/actions/resolve` client。
2. 正式动作只提交 `storySessionId/functionId/actionText/payload`,并从新 `StoryRuntimeProjectionResponse.gameState` 水合快照。
3. `resumeServerRuntimeStory` 继续以服务端投影刷新 story/runtime 版本,同时保留本地 UI 临时态职责。
4. 组件层仍不拼 API不新增规则说明文案`WP-FE-C` 只消费 hooks 返回的 `hydratedSnapshot/nextStory`
边界:
1. 本次保留旧 client alias 名称,避免大面积 import churn行为已经切到新主链。
2. battle presentation 的逐帧表现只在响应仍含 presentation 时触发;新 projection 写侧先提交最终快照和故事,后续战斗表现由 story battle 专用接口继续增强。
3. 旧 runtime story contract 的物理删除仍属于 `WP-DEL`
## 验收
```powershell
npm.cmd run test -- src/hooks/rpg-runtime-story/runtimeStoryCoordinator.test.ts
npm.cmd run test -- src/hooks/useGameFlow.customWorld.test.tsx
npm.cmd run test -- src/hooks
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_FE_H_RPG_RUNTIME_STORY_HOOKS_PROJECTION_2026-04-29.md src/hooks/rpg-runtime-story/rpgRuntimeStoryGateway.ts src/hooks/rpg-runtime-story/inventoryActions.ts src/hooks/rpg-runtime-story/runtimeStoryCoordinator.test.ts src/hooks/useGameFlow.customWorld.test.tsx docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
git diff --check -- docs/technical/SERVER_RS_DDD_WP_FE_H_RPG_RUNTIME_STORY_HOOKS_PROJECTION_2026-04-29.md src/hooks/rpg-runtime-story/rpgRuntimeStoryGateway.ts src/hooks/rpg-runtime-story/inventoryActions.ts src/hooks/rpg-runtime-story/runtimeStoryCoordinator.test.ts src/hooks/useGameFlow.customWorld.test.tsx docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
```

View File

@@ -0,0 +1,58 @@
# WP-FE-S RPG runtime story client 迁移记录
## 背景
`WP-API` 已提供新主链读取接口:
```text
GET /api/story/sessions/{storySessionId}/runtime-projection
```
该接口返回 `StoryRuntimeProjectionResponse`,不再返回旧 runtime story 的 `snapshot / viewModel / presentation / patches` 组合。前端读取侧必须改用 `storySessionId`,不能继续把 `runtimeSessionId` 当成 story 会话主键。
## 本轮落地边界
已落地:
1.`packages/shared/src/contracts/story.ts` 补齐前端 story session / runtime projection 契约,字段对齐 Rust `shared-contracts/src/story.rs` 的 camelCase 回包。
2.`GameState`、快照水合类型与水合逻辑中新增 `storySessionId?: string | null`
3. `src/services/rpg-runtime/rpgRuntimeStoryClient.ts` 的读取侧改为:
- `getRuntimeStoryState({ storySessionId })` 请求 `/api/story/sessions/{storySessionId}/runtime-projection`
- `loadRuntimeInventoryView``StoryRuntimeProjectionResponse` 映射背包视图。
- 缺失 `storySessionId` 时直接抛出中文错误,不回退到 `runtimeSessionId`
4. `src/hooks/rpg-runtime-story/rpgRuntimeStoryGateway.ts` 的读取侧改为消费新投影:
- 选项目录来自 `projection.options`
- 继续游戏时保留本地已水合快照主体,只同步 `runtimeSessionId / storySessionId / runtimeActionVersion` 和展示故事。
5. `src/services/rpg-runtime/rpgRuntimeStoryClient.ts` 新增 story session 新主链 API client
- `beginStorySession` 请求 `POST /api/story/sessions`
- `continueStorySession` 请求 `POST /api/story/sessions/continue`
- `getStorySessionState` 请求 `GET /api/story/sessions/{storySessionId}/state`
- `getStoryRuntimeProjection` 请求 `GET /api/story/sessions/{storySessionId}/runtime-projection`
-`storySessionId` 做统一 trim 与空值中文错误,避免后续 hooks 继续散落路径常量和空 ID 分支。
6. `src/services/rpg-runtime/index.ts` 已导出新 client 函数与结果类型,供后续 `WP-FE-H` 迁 hook 时直接接入。
7. 为满足 `WP-FE-S``src/services` 全量验收,补回 `src/services/customWorldAgentGenerationProgress.ts` 缺失的“建立场景连接”阶段,使草稿生成进度重新对齐既有 13 步文档与测试口径。
## 2026-05-01 收尾切片
本次收尾把先前“等待后端写接口”的缺口正式关闭,执行口径如下:
1. 不恢复旧 `/api/runtime/story/*` compat route前端 runtime story 开局、动作结算和读取统一走 `/api/story/sessions*`
2. `/api/story/sessions/runtime` 作为新开局 BFF后端生成 `runtimeSessionId/storySessionId`,写入 SpacetimeDB `runtime_snapshot`,并返回可水合的 runtime projection。
3. `/api/story/sessions/{storySessionId}/actions/resolve` 作为 session scoped 动作入口:前端只提交 function id、动作文案和 payload后端基于已持久化 snapshot 更新 `currentStory/storyHistory/runtimeActionVersion` 后返回 projection。
4. `StoryRuntimeProjectionResponse` 补齐 `gameState`,让前端从后端投影水合 `HydratedSavedGameSnapshot`,不再消费旧 `snapshot/viewModel/presentation/patches` 组合。
5. `beginRuntimeStorySession``resolveRuntimeStoryAction` 保留前端导出名以减少调用面震荡,但实现已切到新 story session scoped 主链。
收尾后的旧层边界:
1. `packages/shared/src/contracts/rpgRuntimeStoryState.ts` 中的 view model / presentation / patch 类型暂不物理删除,留给 `WP-DEL` 统一清理。
2. 后续更完整的 battle/forge/NPC/quest 跨域结算仍由 `WP-RS/WP-ST/WP-SC/WP-API` 增量增强,但前端不再回退旧 runtime story 写路径。
## 验收命令
```powershell
npm.cmd run test -- src/services/rpg-runtime/rpgRuntimeStoryClient.test.ts
npm.cmd run test -- src/hooks/rpg-runtime-story/runtimeStoryCoordinator.test.ts
npm.cmd run test -- src/hooks/rpg-runtime-story/storyChoiceRuntime.test.ts
npm.cmd run test -- src/components/rpg-runtime-shell/RpgRuntimeShell.test.tsx
npm.cmd run check:encoding -- packages/shared/src/contracts/story.ts src/services/rpg-runtime/rpgRuntimeStoryClient.ts src/services/rpg-runtime/index.ts src/hooks/rpg-runtime-story/rpgRuntimeStoryGateway.ts src/hooks/rpg-runtime-story/inventoryActions.ts src/hooks/rpg-runtime-story/storyChoiceRuntime.ts src/hooks/rpg-runtime-story/runtimeStoryCoordinator.test.ts docs/technical/SERVER_RS_DDD_WP_FE_S_RPG_RUNTIME_STORY_CLIENT_MIGRATION_2026-04-29.md
```

View File

@@ -0,0 +1,69 @@
# WP-PF 平台副作用错误分类收口记录2026-04-29
## 1. 背景
`WP-PF platform side effects` 负责承载 LLM、OSS、SMS、微信等外部副作用实现。当前 `platform-llm``platform-oss``platform-auth` 已经各自有错误枚举,但 `api-server` 后续接入时仍容易重复用字符串或具体枚举分支判断 HTTP 错误类别。
第一段切片已补平台错误分类基础设施。继续收口时,需要把 `api-server` 中已接入的平台副作用统一改为消费这些稳定分类,并把微信 OAuth HTTP provider 下沉到 `platform-auth`,让 `api-server` 只保留 BFF 编排、会话签发、redirect 与错误 envelope 映射。
## 2. 范围
允许修改:
1. `server-rs/crates/platform-llm/src/lib.rs`
2. `server-rs/crates/platform-oss/src/lib.rs`
3. `server-rs/crates/platform-auth/src/lib.rs`
4. `server-rs/crates/api-server/src/platform_errors.rs`
5. `server-rs/crates/api-server/src/llm.rs`
6. `server-rs/crates/api-server/src/assets.rs`
7. 已经直接映射 OSS 错误的资产相关 BFF 模块
8. `server-rs/crates/api-server/src/state.rs`
9. `server-rs/crates/api-server/src/wechat_auth.rs`
10. `server-rs/crates/api-server/src/wechat_provider.rs`
11. 本文档
12. 全局任务清单进度记录
禁止修改:
1. `spacetime-module/src/**`
2. `spacetime-client/src/**`
3. `module-*`
4. 前端 services/hooks/components
5. SpacetimeDB table / reducer / procedure / migration
6. 玩法状态机和领域规则
## 3. 设计
每个 platform crate 暴露自己的错误分类枚举:
1. `LlmErrorKind`
2. `OssErrorKind`
3. `AuthPlatformErrorKind`
并在既有错误枚举上增加 `kind()` 方法。分类只表达 adapter 可消费的稳定错误类别,不承载业务状态机,也不直接绑定 HTTP status。
`api-server` 增加内部 `platform_errors` 模块,负责把平台错误分类映射到 HTTP status、统一 provider details 与中文 envelope。映射原则
1. `InvalidRequest` / `InvalidConfig` 等本地配置或请求错误不再散落在业务 route 中重复 match。
2. `ObjectNotFound` 稳定映射为 `404`
3. LLM 上游 `429` 保留 `429`,其他上游、网络、序列化、签名类错误映射为 `502`
4. SMS/微信 provider 错误统一走 `platform-auth` 错误分类,领域态错误仍由 `module-auth` 自己的应用错误映射。
5. `platform-*` 不绑定 HTTP status不生成 Axum response不持有玩法领域状态。
微信 OAuth provider 的 HTTP 请求、授权 URL 拼接、mock provider 和回调资料解析归入 `platform-auth`。由于 `platform-auth` 不能依赖 `module-auth`,微信 provider 输出独立的 `WechatIdentityProfile``api-server` 在 BFF 边界把它转换为 `module_auth::WechatIdentityProfile` 后再调用领域服务。
图像/视频模型直连接口仍分布在角色形象、角色动画、拼图和自定义世界资产模块中,当前属于视觉资产生成专项遗留,不在本次 WP-PF LLM/OSS/SMS/微信统一 adapter 收口内;后续若新建 image/video platform crate需要另立工作包迁移。
## 4. 验收
```powershell
cargo test -p platform-llm -p platform-oss -p platform-auth --manifest-path server-rs/Cargo.toml
cargo fmt -p platform-llm -p platform-oss -p platform-auth --manifest-path server-rs/Cargo.toml --check
cargo test -p api-server platform_errors --manifest-path server-rs/Cargo.toml
cargo test -p api-server llm --manifest-path server-rs/Cargo.toml
cargo test -p api-server wechat --manifest-path server-rs/Cargo.toml
cargo check -p api-server --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_PF_PLATFORM_ERROR_CLASSIFICATION_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md server-rs/crates/platform-llm/src/lib.rs server-rs/crates/platform-oss/src/lib.rs server-rs/crates/platform-auth/src/lib.rs server-rs/crates/api-server/src/platform_errors.rs server-rs/crates/api-server/src/llm.rs server-rs/crates/api-server/src/state.rs server-rs/crates/api-server/src/wechat_provider.rs server-rs/crates/api-server/src/wechat_auth.rs
npm.cmd run api-server:maincloud
```

View File

@@ -0,0 +1,43 @@
# WP-PZ Puzzle 基础领域常量与枚举归位切片
## 背景
`module-puzzle/src/lib.rs` 当前仍承载 Puzzle Agent、作品发布和运行态拼图的基础枚举、ID 前缀、标签数量规则与洗牌尝试次数。随着 DDD 骨架已经具备 `domain.rs``commands.rs``application.rs``events.rs``errors.rs`,本切片先把纯领域常量和基础枚举迁入 `domain.rs`,避免后续 Agent session、work profile、runtime run 与排行榜规则继续堆回根文件。
## 本次范围
1. 认领 `WP-PZ Puzzle` 的基础领域常量与枚举归位切片。
2. 将以下常量迁入 `module-puzzle/src/domain.rs`
- `PUZZLE_AGENT_SESSION_ID_PREFIX`
- `PUZZLE_AGENT_MESSAGE_ID_PREFIX`
- `PUZZLE_PROFILE_ID_PREFIX`
- `PUZZLE_RUN_ID_PREFIX`
- `PUZZLE_MIN_TAG_COUNT`
- `PUZZLE_MAX_TAG_COUNT`
- `PUZZLE_INITIAL_SHUFFLE_ATTEMPTS`
3. 将以下基础枚举迁入 `domain.rs`
- `PuzzleAgentStage`
- `PuzzleAnchorStatus`
- `PuzzleAgentMessageRole`
- `PuzzleAgentMessageKind`
- `PuzzlePublicationStatus`
- `PuzzleRuntimeLevelStatus`
4. 将这些枚举的 `as_str` 方法一并迁入 `domain.rs`
5. `lib.rs` 通过 `pub use domain::*` 保持既有 `module_puzzle::*` 公开 API。
## 边界
1. 本次不改 SpacetimeDB table、reducer、procedure、row mapper 或 `migration.rs`
2. 本次不改 `api-server``spacetime-client`、platform adapter 或前端。
3. 本次不移动 Agent session、work profile、runtime run、leaderboard 的结构体和校验函数,避免把大包拆分与本切片混在一起。
4. 本次不改变任何序列化字段、枚举字符串值、标签数量规则、洗牌规则或中文错误文案。
## 验收
```powershell
cargo fmt -p module-puzzle --manifest-path server-rs/Cargo.toml --check
cargo test -p module-puzzle --manifest-path server-rs/Cargo.toml
cargo check -p module-puzzle --features spacetime-types --target wasm32-unknown-unknown --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_PZ_DOMAIN_ENUM_REHOME_2026-04-29.md server-rs/crates/module-puzzle/src/domain.rs server-rs/crates/module-puzzle/src/lib.rs server-rs/crates/module-puzzle/README.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
```

View File

@@ -0,0 +1,33 @@
# WP-PZ Puzzle 领域类型与规则拆分切片
## 背景
上一轮 `WP-PZ Puzzle` 已经把基础常量与枚举迁入 `module-puzzle/src/domain.rs`,但 `module-puzzle/src/lib.rs` 仍然承载 Agent 会话快照、作品 profile、运行态棋盘、procedure 输入、procedure 返回、字段错误与全部纯规则函数。
按照 `SERVER_RS_DDD_FULL_REFACTOR_2026-04-28.md``module-puzzle` 应继续把纯领域内容落入 `domain.rs``commands.rs``application.rs``events.rs``errors.rs`,让根入口只保留模块声明和公开导出。
## 本次范围
1. 将 Puzzle Agent、锚点包、草稿、作品 profile、运行态棋盘、排行榜等纯领域类型迁入 `module-puzzle/src/domain.rs`
2. 将 SpacetimeDB procedure/reducer 写入输入迁入 `module-puzzle/src/commands.rs`
3. 将 procedure 返回包装和拼图纯规则函数迁入 `module-puzzle/src/application.rs`
4.`PuzzleFieldError` 和中文错误文案迁入 `module-puzzle/src/errors.rs`
5.`module-puzzle/src/events.rs` 增加最小 `PuzzleDomainEvent`,先表达草稿变化、作品发布和运行态推进事实。
6. `module-puzzle/src/lib.rs` 只保留 DDD 子模块声明和 `pub use`,保持既有 `module_puzzle::*` 外部 API。
## 边界
1. 本次不改 SpacetimeDB table、reducer、procedure、row mapper 或 `migration.rs`
2. 本次不改 `api-server``spacetime-client`、platform adapter 或前端。
3. 本次不改变序列化字段、procedure 输入结构、procedure 返回 JSON 包装、标签数量规则、洗牌规则、移动/合并/拆分语义或中文错误文案。
4. 本次新增的 `PuzzleDomainEvent` 只作为领域事件落位,不接入 `spacetime-module` event table。
## 验收
```powershell
cargo fmt -p module-puzzle --manifest-path server-rs/Cargo.toml --check
cargo test -p module-puzzle --manifest-path server-rs/Cargo.toml
cargo check -p module-puzzle --features spacetime-types --target wasm32-unknown-unknown --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_PZ_DOMAIN_SPLIT_2026-04-29.md server-rs/crates/module-puzzle/src/lib.rs server-rs/crates/module-puzzle/src/domain.rs server-rs/crates/module-puzzle/src/commands.rs server-rs/crates/module-puzzle/src/application.rs server-rs/crates/module-puzzle/src/events.rs server-rs/crates/module-puzzle/src/errors.rs server-rs/crates/module-puzzle/README.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
```

View File

@@ -0,0 +1,76 @@
# WP-PZ Puzzle 运行态后端真相源收尾
日期:`2026-05-01`
## 1. 收尾目标
本轮收尾只关闭正式平台入口的 Puzzle 运行态链路,不扩大到 `/puzzle` 调试直达页和后续旧接口物理删除。
必须达成:
1. 平台内从作品详情或结果页进入拼图玩法时,开局、交换、拖动、通关排行榜和下一关全部调用 Rust API再由 `spacetime-client` 进入 SpacetimeDB procedure。
2. `PlatformEntryFlowShellImpl` 不再导入 `puzzleLocalRuntime`,不再在浏览器侧裁决棋盘、合并、拆分、通关或排行榜。
3. 结果页“试玩当前草稿”先把当前草稿轻量字段写回 `puzzle_work_profile`,再启动后端 run该预览 run 只允许草稿 owner 启动。
4. 发布作品的公开开局规则不放松:非 owner 只能启动已发布作品。
5. 本轮不新增表字段,不修改 `migration.rs`
## 2. 后端口径
`start_puzzle_run_tx` 继续以 `puzzle_work_profile` 作为入口 profile 真相源:
1. `Published` 作品维持既有公开可玩语义。
2. `Draft` 作品仅当 `owner_user_id` 与请求用户一致时可启动,用于结果页预览。
3. 草稿预览 run 不计入公开作品播放次数,也不写入 played work 记录。
4. 下一关推荐仍只从已发布 gallery 中选择候选,草稿只作为当前入口关卡,不参与公共推荐池。
5. 排行榜写入只面向已发布作品;草稿预览通关时后端返回当前 run 快照,不生成公开榜单记录。
## 3. 前端口径
正式平台入口只保留表现态:
1. `PuzzleRuntimeShell` 继续只接收后端 run snapshot 与回调。
2. 作品详情开局调用 `startPuzzleRun`
3. 结果页试玩调用 `updatePuzzleWork` 同步草稿,再调用 `startPuzzleRun` 启动 owner draft run。
4. 交换、拖动、下一关和排行榜分别调用 `swapPuzzlePieces``dragPuzzlePieceOrGroup``advancePuzzleNextLevel``submitPuzzleLeaderboard`
5. `/puzzle` 调试直达页仍可保留本地 runtime用于开发期视觉和交互调试它不再是正式平台链路。
## 4. 验收命令
本轮修改完成后至少执行:
1. `npm.cmd run check:encoding`
2. `npm.cmd run check:server-rs-ddd`
3. `cargo fmt --all --check --manifest-path server-rs\Cargo.toml`
4. `cargo test -p module-puzzle --manifest-path server-rs\Cargo.toml`
5. `cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml`
6. `cargo check -p spacetime-client --manifest-path server-rs\Cargo.toml`
7. `cargo check -p shared-contracts --manifest-path server-rs\Cargo.toml`
8. `cargo check -p api-server --manifest-path server-rs\Cargo.toml`
9. `npm.cmd run typecheck`
10. `npm.cmd run api-server:maincloud`
若全量 workspace 测试受其他工作包既有失败影响,本轮只记录失败归属,不把 WP-PZ 已收口代码回退。
## 5. 本轮验证结果
已通过:
1. `npm.cmd run check:encoding`
2. `npm.cmd run check:server-rs-ddd`
3. `cargo test -p module-puzzle --manifest-path server-rs\Cargo.toml`
4. `cargo check -p module-puzzle --features spacetime-types --target wasm32-unknown-unknown --manifest-path server-rs\Cargo.toml`
5. `cargo check -p shared-contracts --manifest-path server-rs\Cargo.toml`
6. `cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml`
7. `cargo check -p spacetime-client --manifest-path server-rs\Cargo.toml`
8. `cargo check -p api-server --manifest-path server-rs\Cargo.toml`
9. `npm.cmd run test -- src/components/puzzle-runtime src/services/puzzle-runtime`
10. `cargo fmt --manifest-path server-rs\Cargo.toml --package module-puzzle --check`
11. `cargo fmt --manifest-path server-rs\Cargo.toml --package spacetime-module --check`
12. `cargo fmt --manifest-path server-rs\Cargo.toml --package spacetime-client --check`
13. `cargo fmt --manifest-path server-rs\Cargo.toml --package api-server --check`
未作为本轮阻塞:
1. `cargo fmt --all --check --manifest-path server-rs\Cargo.toml` 当前会检查到非 WP-PZ 的 `module-runtime-story/src/bootstrap.rs``module-runtime-story/src/session_action.rs` 未跟踪新增文件格式差异。
2. `npm.cmd run typecheck` 当前失败在非 WP-PZ 文件:`src/data/sceneEncounterPreviews.ts``slot` 可能为 `undefined``src/services/ai.ts` 缺少 `hasMixedNarrativeLanguage``src/services/rpg-creation/rpgCreationAssetClient.test.ts` 的 Custom World scene image 请求字段不匹配。
3. `npm.cmd run api-server:maincloud` 已完成编译并尝试启动,但 Maincloud 连接出现 `503 Service Unavailable`,随后 `api-server.exe``0xffffffff` 退出;本地 `3100` 未留下可用监听,残留进程已确认清理。

View File

@@ -0,0 +1,41 @@
# WP-RPG Combat 基础领域常量与枚举归位切片
## 背景
`WP-RPG Gameplay 域` 覆盖 combat、inventory、npc、progression、quest、runtime-item、story 等多个玩法 crate。本次选择其中最小且可并行的 `module-combat` 切片:`module-combat/src/lib.rs` 仍直接承载战斗 ID 前缀、版本/伤害常量、旧攻击 function 列表以及基础枚举。随着 DDD 骨架已经具备 `domain.rs`,这些纯领域对象应先归位到 `domain.rs`,为后续拆分命令、错误、应用结果和跨域事件留出边界。
## 本次范围
1. 认领 `WP-RPG Gameplay 域` 的 combat 基础领域常量与枚举归位切片。
2. 将以下常量迁入 `module-combat/src/domain.rs`
- `BATTLE_STATE_ID_PREFIX`
- `INITIAL_BATTLE_VERSION`
- `BASIC_FIGHT_COUNTER_RATIO`
- `MIN_FIGHT_COUNTER_DAMAGE`
- `SPAR_MIN_HP`
- `LEGACY_ATTACK_FUNCTION_IDS`
3. 将以下基础枚举迁入 `domain.rs`
- `BattleMode`
- `BattleStatus`
- `CombatOutcome`
4. 将这些枚举的 `as_str` 方法一并迁入 `domain.rs`
5. `lib.rs` 通过 `pub use domain::*` 保持既有 `module_combat::*` 公开 API。
6. `module-combat``spacetime-types` feature 同步启用 `module-runtime-item/spacetime-types`,确保战斗快照里引用的 `RuntimeItemRewardItemSnapshot` 在 wasm 目标下具备 SpacetimeDB 类型派生。
## 边界
1. 本次不改 SpacetimeDB table、reducer、procedure、row mapper 或 `migration.rs`
2. 本次不改 `api-server``spacetime-client`、platform adapter 或前端。
3. 本次不移动 `BattleStateInput``BattleStateSnapshot``ResolveCombatActionInput``CombatFieldError` 和战斗结算函数,避免把常量枚举归位与大包拆分混在一起。
4. 本次不改变任何战斗数值、支持的 function id、枚举字符串值或中文错误文案。
5. Cargo feature 传播仅用于修复 `spacetime-types` 组合编译,不引入新依赖路径或运行时行为。
## 验收
```powershell
cargo fmt -p module-combat --manifest-path server-rs/Cargo.toml --check
cargo test -p module-combat --manifest-path server-rs/Cargo.toml
cargo check -p module-combat --features spacetime-types --target wasm32-unknown-unknown --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_RPG_COMBAT_DOMAIN_ENUM_REHOME_2026-04-29.md server-rs/crates/module-combat/Cargo.toml server-rs/crates/module-combat/src/domain.rs server-rs/crates/module-combat/src/lib.rs server-rs/crates/module-combat/README.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
```

View File

@@ -0,0 +1,38 @@
# WP-RPG Gameplay 全域收口记录2026-05-01
## 1. 收口目标
本次关闭 `SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md``WP-RPG Gameplay 域` 的剩余项:领域文件已完成物理拆分后,战斗胜利奖励、任务交付奖励、宝箱奖励仍由 `spacetime-module/src/gameplay/mod.rs` 直接拼装背包、成长和章节账本命令。
本次目标是把这些跨域组合规则收回 RPG 领域层,让 SpacetimeDB adapter 只负责事务内幂等检查、执行 mutation、写表和查询。
## 2. 已完成内容
1. `module-story` 新增 `RpgGameplaySettlementPlan`,作为 RPG story/gameplay 跨域结算计划。
2. `build_combat_victory_settlement_plan` 收口战斗胜利后的背包掉落、敌对经验和章节 hostile 账本计划。
3. `build_quest_turn_in_settlement_plan` 收口任务交付后的奖励物品、任务经验和章节 quest 账本计划。
4. `build_treasure_settlement_plan` 收口宝箱奖励到背包 mutation 的计划生成,并保持宝箱记录本身仍由 `module-runtime-item` 建模。
5. `spacetime-module/src/gameplay/mod.rs` 改为消费 `RpgGameplaySettlementPlan`,不再在 adapter 中重复映射战斗/任务奖励物品、稀有度、装备槽和物品来源。
6. `spacetime-module` 继续保留事务幂等检查、`inventory_slot` 写回、`player_progression` 经验发放和 `chapter_progression` 可选记账。
7. 未修改 SpacetimeDB 表结构、reducer/procedure 签名、绑定 shape 或 `migration.rs`
## 3. 边界说明
1. 本次不接 `WP-RS Runtime Story 去兼容层` 的完整动作写接口,不修改 `/api/story/*` 路由和前端 hooks。
2. 本次不新增 public/event table结算计划仍是纯领域对象由 adapter 转换为已有表写入。
3. `WP-ST/WP-SC/WP-API/WP-FE` 后续若继续做 runtime story 写侧,只能消费本次的领域计划或对应 facade不应在 BFF/前端重新拼奖励规则。
4. 章节计划不存在时仍不反向阻断战斗胜利或任务交付主链,只跳过章节账本写入。
## 4. 验证
已执行:
```powershell
cargo fmt -p module-story -p spacetime-module --manifest-path server-rs\Cargo.toml
cargo test -p module-story --manifest-path server-rs\Cargo.toml
cargo test -p module-combat -p module-inventory -p module-npc -p module-progression -p module-quest -p module-runtime-item -p module-story --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml
npm.cmd run check:server-rs-ddd
```
结果通过。RPG 七个领域 crate 共 49 个单元测试通过,`spacetime-module` 编译通过DDD 边界检查通过 15 个 module crate。

View File

@@ -0,0 +1,44 @@
# WP-RPG Gameplay 子域领域拆分收口2026-04-30
## 1. 收口目标
本切片关闭 `SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md` 中 RPG 子域的 DDD 物理拆分漂移:
1. `module-combat``module-inventory``module-npc``module-quest``module-runtime-item` 的真实规则仍主要集中在 `lib.rs`
2. 上述 crate 的 `domain / commands / application / events / errors` 文件仍停留在“过渡落位”口径。
3. `module-progression` 已在前一切片完成物理拆分,本切片把 RPG 子域剩余同类壳层一起收口。
本次只做纯领域文件拆分、最小领域事件补位和文档对齐,不修改 SpacetimeDB 表结构、reducer/procedure 签名、绑定 shape、Axum route 或前端契约。
## 2. 已完成内容
1. `module-combat` 将战斗输入、战斗快照、行动结算、错误和战斗领域事件拆入对应 DDD 文件,`lib.rs` 只保留公开导出和测试。
2. `module-inventory` 将背包槽、物品快照、背包 mutation 输入、状态投影、应用规则、错误和背包领域事件拆入对应 DDD 文件。
3. `module-npc` 将 NPC 状态、关系、立场、互动输入、互动结算、错误和 NPC 领域事件拆入对应 DDD 文件。
4. `module-quest` 将任务模型、任务命令、任务状态流转、错误和任务领域事件拆入对应 DDD 文件。
5. `module-runtime-item` 将宝箱奖励模型、宝箱结算输入、奖励到背包映射、错误和运行时物品领域事件拆入对应 DDD 文件。
6. 五个 crate 的 `lib.rs` 均收口为 `mod` 声明、`pub use` 和原有测试,继续保持现有 `module_*::*` 公开 API。
7. RPG 六个子域源码已不再命中 `过渡落位`
## 3. 边界
1. 本切片不新增 `inventory_use`、完整掉落、好感、任务信号、story AI 续写、多目标战斗或完整 build/cooldown 真相建模。
2. 本切片不把任务货币、好感、情报统一发放提前塞进 `module-quest`,也不把背包落库塞进 `module-runtime-item`
3. 跨域副作用仍由 `spacetime-module` 事务 adapter、`spacetime-client` facade、`api-server` BFF 和前端主链分批接入。
4. 完整 story action 写侧、inventory action、NPC interaction、forge/battle/quest 组合结算继续跟随 `WP-RS/WP-ST/WP-SC/WP-API/WP-FE`
## 4. 验收
已执行:
```powershell
cargo fmt -p module-combat --manifest-path server-rs\Cargo.toml --check
cargo fmt -p module-inventory --manifest-path server-rs\Cargo.toml --check
cargo fmt -p module-npc --manifest-path server-rs\Cargo.toml --check
cargo fmt -p module-quest --manifest-path server-rs\Cargo.toml --check
cargo fmt -p module-runtime-item --manifest-path server-rs\Cargo.toml --check
cargo test -p module-combat -p module-inventory -p module-npc -p module-progression -p module-quest -p module-runtime-item --manifest-path server-rs\Cargo.toml
cargo check -p module-combat -p module-inventory -p module-npc -p module-progression -p module-quest -p module-runtime-item --manifest-path server-rs\Cargo.toml
```
结果通过。RPG 六个子域共 39 个单元测试通过。

View File

@@ -0,0 +1,39 @@
# WP-RPG module-progression 领域拆分收口2026-04-30
## 1. 收口目标
本切片关闭 `SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md``module-progression` 的 DDD 物理拆分漂移:
1. `domain / commands / application / events / errors` 文件仍停留在“过渡落位”口径。
2. 玩家等级、章节预算、章节账本、章节自动定级和敌对奖励规则集中在 `lib.rs`
本次只做纯领域分层和文档对齐,不修改 SpacetimeDB 表结构,不触碰 `migration.rs`,不新增 HTTP、LLM、OSS 或前端接线。
## 2. 已完成内容
1. `src/domain.rs` 收口等级常量、玩家成长快照、章节成长快照、章节节奏、实体定级角色和定级来源。
2. `src/commands.rs` 收口玩家成长查询/授予经验、章节预算、章节账本和章节自动定级输入。
3. `src/application.rs` 收口经验曲线、等级解析、玩家成长快照构造、章节预算、章节账本、章节自动定级、敌对生命值和经验奖励规则。
4. `src/events.rs` 收口玩家经验授予、章节账本应用和章节自动定级解析领域事件。
5. `src/errors.rs` 收口 `ProgressionFieldError` 与中文错误文案。
6. `src/lib.rs` 收口为模块声明和公开导出,继续保持 `module_progression::*` 公开 API。
7. `module-progression/README.md` 更新为当前真实边界,明确 DDD 物理拆分已经收口。
## 3. 边界
1. 本切片不改变 `player_progression``chapter_progression` 的 SpacetimeDB row shape、reducer/procedure 签名或绑定生成结果。
2. 本切片不把 `custom-world` 章节蓝图编译、`repeatPenalty`、超预算衰减和完整章节偏差审计提前迁入。
3. 任务、战斗、NPC 和章节成长联动继续通过领域事件与 `spacetime-module` adapter 编排,不让单个 RPG 子域互相直连。
4. 后续完整成长闭环仍随 `WP-CW/WP-RPG/WP-ST/WP-SC/WP-API` 分批推进。
## 4. 验收
已执行:
```powershell
cargo fmt -p module-progression --manifest-path server-rs\Cargo.toml --check
cargo test -p module-progression --manifest-path server-rs\Cargo.toml
cargo check -p module-progression --manifest-path server-rs\Cargo.toml
```
结果:通过,`module-progression` 7 个单元测试通过。

View File

@@ -0,0 +1,38 @@
# WP-RPG module-story 领域拆分收口2026-04-29
## 1. 收口目标
本切片关闭 `SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md``module-story` 的两类漂移:
1. README 仍写“目录占位”和旧 `/api/runtime/story/*` 兼容链路。
2. `domain / commands / application / events / errors` 文件仍停在“过渡落位”注释,真实规则集中在 `lib.rs`
本次只做物理分层和文档对齐,不新增 story action 写接口,不修改 SpacetimeDB 表结构,不触碰 `migration.rs`
## 2. 已完成内容
1. `src/domain.rs` 收口剧情会话领域快照、状态、ID 前缀和 `generate_story_session_id`
2. `src/commands.rs` 收口 `StorySessionInput``StoryContinueInput``StorySessionStateInput`、输入构造和字段校验。
3. `src/events.rs` 收口 `StoryEventKind``StoryEventSnapshot`、开局事件和事件 ID 生成。
4. `src/application.rs` 收口会话快照构造、续写应用服务、procedure result 类型和只读 record mapper。
5. `src/errors.rs` 收口 `StorySessionFieldError` 与中文错误文案。
6. `src/lib.rs` 只保留模块声明和 `pub use`,继续保持 `module_story::*` 公开 API。
7. `module-story/README.md` 改为当前真实边界,明确不恢复旧 `/api/runtime/story/*` 兼容路由。
## 3. 边界
1. 本切片不改变 `story_session``story_event` 的 SpacetimeDB row shape、reducer/procedure 签名或前端 DTO。
2. 本切片不接入 LLM、SSE、HTTP route 或前端 hooks。
3. 后续完整动作结算仍等待 `WP-RS/WP-ST/WP-SC/WP-API/WP-FE` 继续推进。
4. `module-story` 只承载纯 story session 规则;运行态投影、背包/NPC/战斗/任务联动继续由相邻领域模块和 adapter 编排。
## 4. 验收
已执行:
```powershell
cargo test -p module-story --manifest-path server-rs\Cargo.toml
cargo check -p module-story --manifest-path server-rs\Cargo.toml
```
结果通过8 个单元测试通过。

View File

@@ -0,0 +1,55 @@
# WP-RS Runtime Story Compat 残留审计切片
## 背景
`WP-RS Runtime Story 去兼容层` 已完成 crate 迁名、旧 HTTP compat 路由下线、runtime projection 契约/API/读取侧迁移等多轮推进。2026-05-01 收尾后,运行时开局和动作写侧也已迁到 story session scoped route当前仍存在一些 `compat` 或旧 `/api/runtime/story/*` 命名残留,需要区分“可以立即清理的工程语义残留”和“历史展示 DTO / 旧命名的物理删除窗口”。
本次切片只处理前者,并冻结后者的交接清单。
## 本次范围
允许修改:
1. `server-rs/crates/module-runtime-story/src/**` 中只描述历史兼容阶段的注释。
2. `server-rs/crates/module-runtime-story/README.md`
3. 本文档
4. `docs/technical/README.md`
5. `docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md`
禁止修改:
1. `src/services/rpg-runtime/rpgRuntimeStoryClient.ts`
2. `src/hooks/rpg-runtime-story/**`
3. `packages/shared/src/contracts/rpgRuntimeStoryState.ts`
4. `server-rs/crates/shared-contracts/src/runtime_story.rs`
5. `api-server` route 挂载和 BFF 行为
6. SpacetimeDB 表、procedure、绑定和 `migration.rs`
## 本次处理
1. 清理 `module-runtime-story` 运行代码注释中的 `compat` 定位,将 crate 口径改为 runtime story 主链纯规则收口。
2. 保留“历史 payload”相关说明因为这些字段仍是实际输入兼容范围不属于旧层命名。
3. 更新 `module-runtime-story/README.md`,明确旧 `/api/runtime/story/*` 写侧能力已迁到 session scoped 新接口,后续不再扩展兼容桥。
## 残留清单
以下残留本次不删除:
1. `packages/shared/src/contracts/rpgRuntimeStoryState.ts``server-rs/crates/shared-contracts/src/runtime_story.rs` 仍保留历史 view model / presentation / patch DTO原因是 story battle 表现、历史测试和 `WP-DEL` 物理删除窗口仍需统一评估。
2. `src/hooks/rpg-runtime-story/**` 仍保留部分旧命名兼容注释,但运行写链路已经通过 `storySessionId` scoped client不再调用旧 `/api/runtime/story/*`
3. 历史文档中仍会记录旧 compat 路由阶段,用于审计时间线;当前执行入口以 `SERVER_RS_DDD_WP_RS_RUNTIME_STORY_CLOSURE_2026-05-01.md` 为准。
## 后续边界
1. 不恢复旧前端写 client也不重新挂载旧 `/api/runtime/story/*`
2. `WP-DEL` 只能在确认 story battle 等展示语义不再依赖旧 DTO 后,删除 `RuntimeStoryActionResponse` 等历史 contract。
3. 历史文档清理只改当前状态说明,不抹掉已执行过的审计记录。
## 验收
```powershell
cargo fmt -p module-runtime-story --manifest-path server-rs/Cargo.toml --check
cargo test -p module-runtime-story --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_RS_COMPAT_RESIDUE_AUDIT_2026-04-29.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md server-rs/crates/module-runtime-story/README.md server-rs/crates/module-runtime-story/src/domain.rs server-rs/crates/module-runtime-story/src/commands.rs server-rs/crates/module-runtime-story/src/errors.rs server-rs/crates/module-runtime-story/src/events.rs server-rs/crates/module-runtime-story/src/core.rs server-rs/crates/module-runtime-story/src/game_state.rs server-rs/crates/module-runtime-story/src/battle.rs server-rs/crates/module-runtime-story/src/forge.rs server-rs/crates/module-runtime-story/src/forge_actions.rs server-rs/crates/module-runtime-story/src/npc_support.rs
```

View File

@@ -0,0 +1,47 @@
# WP-RS Runtime Story 收尾设计
日期2026-05-01
## 目标
本轮收尾只关闭运行代码中的旧 `/api/runtime/story/*` 写链路,不恢复旧 compat route不兼容 `server-node`,也不新增 SpacetimeDB 表结构。
## 新路由
1. `POST /api/story/sessions/runtime`
- 用于前端进入运行时故事。
- 后端生成 `runtimeSessionId``storySessionId`,创建 story session写入 runtime snapshot。
- 响应返回 `StoryRuntimeMutationResponse { projection }`,其中 `projection.gameState` 是前端水合快照的唯一状态来源。
2. `POST /api/story/sessions/{story_session_id}/actions/resolve`
- 用于正式运行时选项结算。
- 路径中的 `story_session_id` 是唯一会话边界;请求体必须携带同一个 `storySessionId`,不再接受 `sessionId` 作为主键兜底。
- 后端读取 story session 与当前用户 runtime snapshot校验 snapshot 中 `runtimeSessionId` 必须匹配 story session。
- 后端调用 `module-runtime-story` 纯规则结算动作,推进 `runtimeActionVersion`,写回 runtime snapshot并用 `continue_story` 记录本轮 narrative event。
- 响应同样返回 `StoryRuntimeMutationResponse { projection }`,不返回旧 `viewModel / presentation / patches / snapshot` 组合。
## 契约收口
本轮新增 story contract 下的运行时写侧 DTO
1. `BeginStoryRuntimeSessionRequest`
2. `ResolveStoryRuntimeActionRequest`
3. `StoryRuntimeMutationResponse`
4. `StoryRuntimeProjectionResponse.gameState`
`StoryRuntimeBootstrapRequest/Response``StoryRuntimeActionRequest/Response` 已从 `packages/shared/src/contracts/story.ts``server-rs/crates/shared-contracts/src/story.rs` 移除。`runtime_story` 下的 view model、presentation、patch 类型暂作为历史展示 DTO 和 story battle 表现输入保留;它们不是旧 HTTP route。
## 不做事项
1. 不恢复 `/api/runtime/story/*`
2. 不新增或修改 SpacetimeDB table因此不改 `migration.rs`
3. 不把前端本地快照重新作为动作真相上传。
4. 不把 Node/Express/PostgreSQL 路径作为兼容目标。
## 完成判定
1. `src/services/rpg-runtime/rpgRuntimeStoryClient.ts` 不再包含 `/api/runtime/story`
2. 前端 `beginRpgRuntimeStorySession``resolveRpgRuntimeStoryAction` 只调用 `/api/story/*`
3. `server-rs/crates/api-server/src/app.rs` 仍保持旧 `/api/runtime/story/*` 未挂载测试。
4. 共享 story 写侧契约和测试不再引用旧 `StoryRuntimeBootstrapRequest/Response``StoryRuntimeActionResponse`
5. 文档进度从“旧写接口等待迁移”更新为“写链路已切到 story session scoped route”。

View File

@@ -0,0 +1,38 @@
# WP-RS module-runtime-story 领域拆分收口2026-04-30
## 1. 收口目标
本切片关闭 `module-runtime-story` 顶层 DDD 文件仍停留在“过渡落位”的漂移:
1. 顶层 `StoryResolution``RuntimeStoryActionResponseParts`、NPC 任务上下文、常量和 helper 仍集中在 `lib.rs`
2. `domain / commands / application / events / errors` 文件没有承载真实类型或规则。
本次只做顶层纯规则拆分和文档对齐,不迁移旧 `/api/runtime/story/*` 写侧接口,不修改 SpacetimeDB 表结构、reducer/procedure、BFF route 或前端 client。
## 2. 已完成内容
1. `src/domain.rs` 收口 runtime story 顶层常量、`StoryResolution`、生成故事 payload、当前 NPC 任务上下文和待接任务上下文。
2. `src/commands.rs` 收口 `resolve_action_text`,固定从 action payload 读取展示文本的写入命令口径。
3. `src/application.rs` 收口 `RuntimeStoryActionResponseParts``simple_story_resolution``build_status_patch``current_world_type`
4. `src/errors.rs` 补入 `RuntimeStoryRuleError`,用于表达运行时剧情纯规则错误。
5. `src/events.rs` 补入 `RuntimeStoryDomainEvent`,用于表达快照变化、战斗表现变化和跨域同步待处理事实。
6. `src/lib.rs` 收口为模块声明、公开导出和既有子模块 re-export继续保持现有 `module_runtime_story::*` 公开 API。
## 3. 边界
1. 本切片不改 battle、forge、NPC、quest、presentation 等大模块内部逻辑。
2. 本切片不恢复旧 `/api/runtime/story/*`,也不新增 session scoped 写 route。
3. `RuntimeStoryActionResponse`、旧前端写 client 和旧 contract 删除仍等待后续 `WP-FE-S/WP-FE-H/WP-FE-C/WP-DEL`
4. 完整 story action 写侧、inventory action、NPC interaction、forge/battle/quest 组合结算仍需跟随 `WP-ST/WP-SC/WP-API` 接入。
## 4. 验收
已执行:
```powershell
cargo fmt -p module-runtime-story --manifest-path server-rs\Cargo.toml --check
cargo test -p module-runtime-story --manifest-path server-rs\Cargo.toml
cargo check -p module-runtime-story --manifest-path server-rs\Cargo.toml
```
结果:通过,`module-runtime-story` 8 个单元测试通过。

View File

@@ -0,0 +1,130 @@
# WP-RT Adapter/API 收口落地说明
## 背景
`WP-RT Runtime/Profile/Save` 已完成 runtime settings、snapshot/profile/save archive 类型、错误层、命令构造和应用记录投影拆分。剩余风险集中在 Adapter/API 层仍保留部分纯规则,以及 profile 旧兼容路径继续挂载,容易让后续前端或 BFF 再走 `/api/runtime/profile/*` 旧入口。
本次收口目标是继续遵循 DDD 边界:`module-runtime` 承载 runtime/profile/save 的纯规则和字段错误,`spacetime-module` 只保留 SpacetimeDB table、事务读写和 row mapper`api-server` 只负责 HTTP/BFF 映射,前端请求层改用新的 profile API。
## 本次范围
允许修改:
1. `server-rs/crates/module-runtime/src/domain.rs`
2. `server-rs/crates/module-runtime/src/errors.rs`
3. `server-rs/crates/module-runtime/src/commands.rs`
4. `server-rs/crates/module-runtime/src/application.rs`
5. `server-rs/crates/module-runtime/src/lib.rs`
6. `server-rs/crates/spacetime-module/src/runtime/profile.rs`
7. `server-rs/crates/api-server/src/app.rs`
8. `server-rs/crates/api-server/src/runtime_save.rs`
9. `server-rs/crates/api-server/src/runtime_profile.rs`
10. `server-rs/crates/api-server/src/runtime_browse_history.rs`
11. `src/services/rpg-runtime/rpgRuntimeRequest.ts`
12. `src/services/rpg-entry/rpgProfileClient.test.ts`
13. `src/services/rpg-entry/rpgEntryClients.routing.test.ts`
14. 相关 README、技术文档和全局任务清单
禁止修改:
1. SpacetimeDB 表结构和 `migration.rs`
2. RPG story / runtime story 玩法规则
3.`server-node` / PostgreSQL 兼容逻辑
4. 非 WP-RT 并行包文件
## 设计
### 1. checkpoint 规则下沉
`api-server/src/runtime_save.rs` 不再本地维护 checkpoint 的 sessionId 校验、预览/测试态拒绝和 runtimeStats 时间水位刷新规则。
新增或迁入 `module-runtime`
1. `RuntimeSaveCheckpointInput`
2. `RuntimeSaveCheckpointSnapshotUpdate`
3. `build_runtime_save_checkpoint_input`
4. `build_runtime_save_checkpoint_update`
5. `refresh_runtime_snapshot_play_time`
6. `is_non_persistent_runtime_snapshot`
7. checkpoint 相关 `RuntimeProfileFieldError`
`api-server` 只把 HTTP payload 转为领域输入,并把领域错误映射为 runtime-save 的 API envelope。
### 2. profile/save archive 投影 meta 规则下沉
`spacetime-module/src/runtime/profile.rs` 不再本地维护 save archive/world meta 的 JSON 解析规则。
新增或迁入 `module-runtime`
1. `RuntimeProfileWorldSnapshotMeta`
2. `RuntimeProfileSaveArchiveMeta`
3. `resolve_runtime_profile_world_snapshot_meta`
4. `resolve_runtime_profile_save_archive_meta`
5. `read_runtime_json_non_negative_u64`
6. `read_runtime_json_string_field`
7. `build_runtime_builtin_world_title`
`spacetime-module` 继续负责读取 snapshot、写入 dashboard / played world / save archive 表,但 meta 判断和默认标题、摘要兜底由领域模块统一维护。
### 3. profile 剩余纯规则下沉
本次继续把留在 SpacetimeDB adapter 中的纯规则收回 `module-runtime`
1. played world、snapshot wallet ledger、save archive、recharge order、recharge wallet ledger、redeem usage、redeem ledger 等 ID 生成规则。
2. 首充光点奖励计算。
3. 会员购买续期时间计算。
4. 邀请码 deterministic 生成、邀请链接、每日奖励窗口和邀请人奖励上限判断。
5. 兑换码 public / unique / private 模式使用资格校验。
6. 钱包正负 delta 转换、余额溢出和余额不足校验。
`spacetime-module` 中仍保留必须依赖表状态的逻辑:查找已有邀请码、统计当天奖励次数、读取/更新 wallet dashboard、写入 wallet ledger、membership、recharge order、redeem usage 和 referral relation。
### 4. profile 旧兼容路径移除
`api-server/src/app.rs` 移除 `/api/runtime/profile/*` 旧兼容挂载,只保留 `/api/profile/*` 新主路径。
保留的新路径:
1. `/api/profile/browse-history`
2. `/api/profile/dashboard`
3. `/api/profile/wallet-ledger`
4. `/api/profile/recharge-center`
5. `/api/profile/recharge/orders`
6. `/api/profile/referrals/invite-center`
7. `/api/profile/referrals/redeem-code`
8. `/api/profile/redeem-codes/redeem`
9. `/api/profile/save-archives`
10. `/api/profile/save-archives/{world_key}`
新增 `runtime_profile_legacy_routes_are_not_mounted` 测试,确认 `/api/runtime/profile/*` 旧路径返回 `404`
### 5. 前端 profile 请求路径对齐
`src/services/rpg-runtime/rpgRuntimeRequest.ts` 对以 `/profile/` 开头的 runtime request 直接发送到 `/api/profile/*`,其他 runtime 路径继续发送到 `/api/runtime/*`
`rpgProfileClient` 与 entry routing 测试同步改为断言 `/api/profile/*`
## 边界说明
1. 本次没有新增、删除或调整 SpacetimeDB 表字段,因此不修改 `migration.rs`
2. 本次没有改 reducer/procedure 对外签名,也没有改 generated binding。
3. 本次删除的是 HTTP 兼容挂载,不保留 `/api/runtime/profile/*` fallback。
4. 本次不把 SpacetimeDB 表查询搬进 `module-runtime`;领域模块只接收纯输入并返回纯结果。
5. 本次不处理 runtime story / RPG story 规则;相关内容仍归 `WP-RS``WP-RPG`
## 验收
```powershell
cargo fmt -p module-runtime -p spacetime-module -p api-server --manifest-path server-rs/Cargo.toml --check
cargo test -p module-runtime --manifest-path server-rs/Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml
cargo test -p api-server runtime_profile --manifest-path server-rs/Cargo.toml
cargo test -p api-server runtime_browse_history --manifest-path server-rs/Cargo.toml
cargo test -p api-server runtime_snapshot --manifest-path server-rs/Cargo.toml
cargo test -p api-server profile_save_archives --manifest-path server-rs/Cargo.toml
npm.cmd run test -- src/services/rpg-entry/rpgProfileClient.test.ts src/services/rpg-entry/rpgEntryClients.routing.test.ts
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_RT_ADAPTER_API_CLOSURE_2026-04-29.md server-rs/crates/module-runtime/src/domain.rs server-rs/crates/module-runtime/src/errors.rs server-rs/crates/module-runtime/src/commands.rs server-rs/crates/module-runtime/src/application.rs server-rs/crates/module-runtime/src/lib.rs server-rs/crates/module-runtime/README.md server-rs/crates/spacetime-module/src/runtime/profile.rs server-rs/crates/api-server/src/app.rs server-rs/crates/api-server/src/runtime_save.rs server-rs/crates/api-server/src/runtime_profile.rs server-rs/crates/api-server/src/runtime_browse_history.rs src/services/rpg-runtime/rpgRuntimeRequest.ts src/services/rpg-entry/rpgProfileClient.test.ts src/services/rpg-entry/rpgEntryClients.routing.test.ts docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
git diff --check -- docs/technical/SERVER_RS_DDD_WP_RT_ADAPTER_API_CLOSURE_2026-04-29.md server-rs/crates/module-runtime/src/domain.rs server-rs/crates/module-runtime/src/errors.rs server-rs/crates/module-runtime/src/commands.rs server-rs/crates/module-runtime/src/application.rs server-rs/crates/module-runtime/src/lib.rs server-rs/crates/module-runtime/README.md server-rs/crates/spacetime-module/src/runtime/profile.rs server-rs/crates/api-server/src/app.rs server-rs/crates/api-server/src/runtime_save.rs server-rs/crates/api-server/src/runtime_profile.rs server-rs/crates/api-server/src/runtime_browse_history.rs src/services/rpg-runtime/rpgRuntimeRequest.ts src/services/rpg-entry/rpgProfileClient.test.ts src/services/rpg-entry/rpgEntryClients.routing.test.ts docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
npm.cmd run api-server:maincloud
```

View File

@@ -0,0 +1,47 @@
# WP-RT 应用记录投影拆分落地说明
## 背景
`module-runtime` 已完成领域类型、错误类型和命令构造拆分。根入口 `lib.rs` 仍承载大量 `build_runtime_*_record`,负责把 SpacetimeDB/procedure 快照转换为 BFF 或上层 facade 使用的记录投影。该职责更接近应用层读模型映射,应迁入 `application.rs`
## 本次范围
允许修改:
1. `server-rs/crates/module-runtime/src/application.rs`
2. `server-rs/crates/module-runtime/src/lib.rs`
3. `server-rs/crates/module-runtime/README.md`
4. `docs/technical/README.md`
5. 全局 DDD 任务清单进度记录
禁止修改:
1. `server-rs/crates/spacetime-module/src/**`
2. `server-rs/crates/spacetime-client/src/**`
3. `server-rs/crates/api-server/src/**`
4. 前端 services/hooks/components
5. `server-rs/crates/spacetime-module/src/migration.rs`
## 设计
本次将以下记录投影函数迁入 `application.rs`
1. settings、browse history、profile dashboard、wallet ledger、recharge center、membership、referral、reward code、redeem code、played world、play stats、runtime snapshot、save archive 的 `build_runtime_*_record`
2. 记录投影专用 JSON helper`parse_optional_json_value`
`format_utc_micros` 暂留 `lib.rs`,作为跨 commands/application 复用的时间格式化工具。充值商品目录函数也暂留 `lib.rs`,因为命令构造仍需要用它校验充值商品 ID。
## 边界说明
1. 本次不改变任何记录投影字段、时间格式、JSON 解析或错误语义。
2. 本次不迁移充值商品目录和商品查找函数。
3. 本次不改 SpacetimeDB 表结构、reducer、procedure 或 API route。
## 验收
```powershell
cargo fmt -p module-runtime --manifest-path server-rs/Cargo.toml --check
cargo test -p module-runtime --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_RT_APPLICATION_RECORD_REFACTOR_2026-04-29.md server-rs/crates/module-runtime/src/application.rs server-rs/crates/module-runtime/src/lib.rs server-rs/crates/module-runtime/README.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
```

View File

@@ -0,0 +1,50 @@
# WP-RT 命令构造拆分落地说明
## 背景
`module-runtime` 已将领域类型迁入 `domain.rs`,错误类型迁入 `errors.rs`。根入口 `lib.rs` 仍承载大量 `build_runtime_*_input`、浏览历史写入准备、snapshot upsert JSON 归一化、邀请码/兑换码归一化等命令构造函数。为了继续推进 DDD 分层,本次将写入命令构造与字段归一化迁入 `commands.rs`
## 本次范围
允许修改:
1. `server-rs/crates/module-runtime/src/commands.rs`
2. `server-rs/crates/module-runtime/src/lib.rs`
3. `server-rs/crates/module-runtime/README.md`
4. `docs/technical/README.md`
5. 全局 DDD 任务清单进度记录
禁止修改:
1. `server-rs/crates/spacetime-module/src/**`
2. `server-rs/crates/spacetime-client/src/**`
3. `server-rs/crates/api-server/src/**`
4. 前端 services/hooks/components
5. `server-rs/crates/spacetime-module/src/migration.rs`
## 设计
本次将以下函数迁入 `commands.rs`
1. settings、browse history、profile dashboard、wallet、recharge、referral、reward code、redeem code、play stats、runtime snapshot、save archive 的 `build_runtime_*_input`
2. `build_runtime_browse_history_sync_input``prepare_runtime_browse_history_entries``build_runtime_browse_history_id`
3. `normalize_invite_code``normalize_redeem_code`
4. 仅服务命令构造的私有 helper`normalize_runtime_*_user_id``parse_utc_rfc3339_to_micros``normalize_bottom_tab``normalize_current_story_json`
`lib.rs` 继续通过 `pub use commands::*` 暴露原公开函数名。记录投影 builder、充值商品目录、通用时间格式化和 JSON 读取 helper 暂留 `lib.rs`,后续再拆 `application.rs`
## 边界说明
1. 本次不改变任何输入构造的校验语义。
2. 本次不移动记录投影 builder避免命令层和应用读模型混写。
3. 本次不改 SpacetimeDB 表结构、reducer、procedure 或 API route。
4. 本次不触发 `migration.rs` 更新。
## 验收
```powershell
cargo fmt -p module-runtime --manifest-path server-rs/Cargo.toml --check
cargo test -p module-runtime --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_RT_COMMANDS_REFACTOR_2026-04-29.md server-rs/crates/module-runtime/src/commands.rs server-rs/crates/module-runtime/src/lib.rs server-rs/crates/module-runtime/README.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
```

View File

@@ -0,0 +1,52 @@
# WP-RT Snapshot/Profile/Save Archive 领域快照与记录类型拆分落地说明
## 背景
`module-runtime/src/lib.rs` 仍集中承载 runtime snapshot、browse history、profile dashboard、wallet ledger、recharge、referral、played world、play stats 和 save archive 的大量快照、输入、过程结果与 BFF 记录类型。上一切片已将 runtime settings 值对象迁入 `domain.rs`,本次继续把这些纯数据事实迁入领域模型文件,降低根入口体积,并为后续 `commands.rs``application.rs` 和 SpacetimeDB adapter 接线拆分留出边界。
本次只移动纯类型和类型自带的字符串格式化方法不修改构造函数、归一化函数、测试、SpacetimeDB 表结构、API route 或前端。
## 本次范围
允许修改:
1. `server-rs/crates/module-runtime/src/domain.rs`
2. `server-rs/crates/module-runtime/src/lib.rs`
3. `server-rs/crates/module-runtime/README.md`
4. `docs/technical/README.md`
5. 全局 DDD 任务清单进度记录
禁止修改:
1. `server-rs/crates/spacetime-module/src/**`
2. `server-rs/crates/spacetime-client/src/**`
3. `server-rs/crates/api-server/src/**`
4. 前端 services/hooks/components
5. `server-rs/crates/spacetime-module/src/migration.rs`
## 设计
本次将以下类型迁入 `domain.rs`
1. runtime snapshot、runtime setting、browse history、profile dashboard、wallet ledger、recharge、reward code、redeem code、referral、played world、play stats、save archive 的 snapshot/input/procedure result。
2. `RuntimeProfileWalletLedgerSourceType``RuntimeProfileRedeemCodeMode``RuntimeProfileRechargeProductKind``RuntimeProfileMembershipStatus``RuntimeProfileMembershipTier``RuntimeProfileRechargeOrderStatus``RuntimeBrowseHistoryThemeMode` 等领域枚举及其 `as_str` / `from_client_str` 方法。
3. `RuntimeSettingsRecord``RuntimeProfileDashboardRecord``RuntimeProfileWalletLedgerEntryRecord``RuntimeProfilePlayedWorldRecord``RuntimeProfilePlayStatsRecord``RuntimeSnapshotRecord``RuntimeProfileSaveArchiveRecord` 等回包投影记录类型。
4. 与这些类型强绑定、但不携带构造逻辑的默认常量:`DEFAULT_BROWSE_HISTORY_AUTHOR_DISPLAY_NAME``MAX_BROWSE_HISTORY_BATCH_SIZE``PROFILE_WALLET_LEDGER_LIST_LIMIT``PROFILE_REFERRAL_REWARD_POINTS``PROFILE_REFERRAL_DAILY_INVITER_REWARD_LIMIT``SAVE_SNAPSHOT_VERSION``DEFAULT_SAVE_ARCHIVE_SUMMARY_TEXT``PROFILE_RECHARGE_PAYMENT_CHANNEL_MOCK`
`lib.rs` 继续通过 `pub use domain::*` 保持原公开 API。构造函数、归一化函数、充值商品目录函数、错误枚举和测试暂留 `lib.rs`,避免在同一切片里混入命令层与错误层重排。
## 边界说明
1. 这些类型包含条件 `SpacetimeType` 派生,但不是 SpacetimeDB table本次只移动自定义类型位置不修改 table/reducer/procedure。
2. 本次不移动 `RuntimeSettingsFieldError``RuntimeBrowseHistoryFieldError``RuntimeProfileFieldError`,后续可单独迁入 `errors.rs`
3. 本次不移动 `build_runtime_*` 构造函数,后续可按 settings、browse history、profile/save 三组拆入 `commands.rs` / `application.rs`
4. 本次不触发 `migration.rs` 更新。
## 验收
```powershell
cargo fmt -p module-runtime --manifest-path server-rs/Cargo.toml --check
cargo test -p module-runtime --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_RT_DOMAIN_SNAPSHOT_RECORD_REFACTOR_2026-04-29.md server-rs/crates/module-runtime/src/domain.rs server-rs/crates/module-runtime/src/lib.rs server-rs/crates/module-runtime/README.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
```

View File

@@ -0,0 +1,48 @@
# WP-RT 错误层拆分落地说明
## 背景
`module-runtime` 已将 runtime settings 值对象,以及 snapshot/profile/save archive 的快照、输入、过程结果和记录投影类型迁入 `domain.rs`。根入口 `lib.rs` 仍承载 `RuntimeSettingsFieldError``RuntimeBrowseHistoryFieldError``RuntimeProfileFieldError` 及其中文错误文案,后续继续拆 `commands.rs``application.rs` 前,需要先把错误语义归位到 `errors.rs`
## 本次范围
允许修改:
1. `server-rs/crates/module-runtime/src/errors.rs`
2. `server-rs/crates/module-runtime/src/lib.rs`
3. `server-rs/crates/module-runtime/README.md`
4. `docs/technical/README.md`
5. 全局 DDD 任务清单进度记录
禁止修改:
1. `server-rs/crates/spacetime-module/src/**`
2. `server-rs/crates/spacetime-client/src/**`
3. `server-rs/crates/api-server/src/**`
4. 前端 services/hooks/components
5. `server-rs/crates/spacetime-module/src/migration.rs`
## 设计
本次将以下错误类型迁入 `errors.rs`
1. `RuntimeSettingsFieldError`
2. `RuntimeBrowseHistoryFieldError`
3. `RuntimeProfileFieldError`
同步迁移三组 `Display` 实现,保持中文错误文案和 `MAX_BROWSE_HISTORY_BATCH_SIZE` 上限提示不变。`lib.rs` 继续通过 `pub use errors::*` 暴露原公开 API调用点无需修改。
## 边界说明
1. 本次不调整错误枚举变体,不改任何业务校验语义。
2. 本次不移动 `build_runtime_*` 构造函数;这些函数仍在 `lib.rs` 使用错误类型。
3. 本次不改 SpacetimeDB 表结构、reducer、procedure 或 API route。
## 验收
```powershell
cargo fmt -p module-runtime --manifest-path server-rs/Cargo.toml --check
cargo test -p module-runtime --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_RT_ERROR_LAYER_REFACTOR_2026-04-29.md server-rs/crates/module-runtime/src/errors.rs server-rs/crates/module-runtime/src/lib.rs server-rs/crates/module-runtime/README.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
```

View File

@@ -0,0 +1,52 @@
# WP-RT Runtime Settings 领域值对象拆分落地说明
## 背景
`module-runtime` 已承接运行时设置、快照、浏览历史、资料页、钱包、充值、邀请、兑换码、游玩记录和存档等纯规则,但当前大量类型仍集中在 `src/lib.rs``WP-RT Runtime/Profile/Save` 需要逐步把纯领域事实和写入命令拆入 DDD 分层文件,避免后续 `spacetime-module``api-server` 接线时继续依赖巨型根文件。
本次只启动 `runtime settings` 这一条最小切片,不改 SpacetimeDB 表结构、不改 HTTP route、不改前端。
## 本次范围
允许修改:
1. `server-rs/crates/module-runtime/src/domain.rs`
2. `server-rs/crates/module-runtime/src/lib.rs`
3. `server-rs/crates/module-runtime/README.md`
4. 本文档
5. 全局 DDD 任务清单进度记录
禁止修改:
1. `server-rs/crates/spacetime-module/src/**`
2. `server-rs/crates/spacetime-client/src/**`
3. `server-rs/crates/api-server/src/**`
4. 前端 services/hooks/components
## 设计
本次将以下运行时设置领域对象迁入 `domain.rs`
1. `DEFAULT_MUSIC_VOLUME`
2. `DEFAULT_PLATFORM_THEME`
3. `RuntimePlatformTheme`
4. `RuntimeSettings`
`RuntimePlatformTheme::as_str``RuntimePlatformTheme::from_client_str``RuntimeSettings::defaults``RuntimeSettings::normalized` 同步迁入 `domain.rs``lib.rs` 继续通过 `pub use domain::*` 暴露原有 API保证 `spacetime-module``spacetime-client` 和既有测试无需改调用点。
## 边界说明
1. 本次不移动 `RuntimeSettingSnapshot``RuntimeSettingGetInput``RuntimeSettingUpsertInput` 和 procedure result因为它们仍与 SpacetimeDB procedure DTO 强绑定,后续可作为 `commands.rs` / Adapter mapper 切片单独拆分。
2. 本次不移动 `RuntimeSettingsFieldError`,避免把错误 Display 与多个 profile 错误枚举混在同一切片里改动。
3. 本次不移动浏览历史、钱包、充值、邀请、兑换码、游玩记录和存档类型。
## 验收
```powershell
cargo test -p module-runtime --manifest-path server-rs/Cargo.toml
cargo fmt -p module-runtime --manifest-path server-rs/Cargo.toml --check
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_RT_RUNTIME_SETTINGS_DOMAIN_REFACTOR_2026-04-29.md server-rs/crates/module-runtime/src/domain.rs server-rs/crates/module-runtime/src/lib.rs server-rs/crates/module-runtime/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
```
本次不改后端运行接线、不改 SpacetimeDB table/reducer/procedure因此不触发 `migration.rs` 更新。

View File

@@ -0,0 +1,154 @@
# server-rs DDD WP-SC Spacetime Client 重构方案2026-04-29
## 1. 背景
`WP-SC Spacetime Client` 位于 `spacetime-module``api-server` 之间,只负责把 SpacetimeDB 生成绑定、procedure / reducer 调用、row snapshot 和错误语义收口成 BFF 可消费的 typed facade。
当前 `spacetime-client` 已经具备连接池、生成绑定、多个领域 facade 和 mapper。本文件用于冻结并关闭当前稳定 SpacetimeDB facade 范围内的 `WP-SC` 收口:不预判新的 table、reducer、procedure 或 row shape只把已存在调用层、错误 helper、mapper 与 README 状态闭环。
## 2. 本次目标
1. 明确 `spacetime-client` 的 DDD 边界和后续接入顺序。
2. 新增统一的 SDK 调用错误、业务 procedure 错误、缺失快照错误 helper。
3. 用 AI task 与 Big Fish 现有 facade 作为第一批示范,减少重复的 `SpacetimeClientError::Procedure(error.to_string())`
4. 保持现有公开 facade 方法和返回 record 不变,不改 `api-server` 调用方。
5. 不修改 `spacetime-module``shared-contracts``api-server` 路由挂载或前端。
## 3. 文件边界
本次允许修改:
1. `server-rs/crates/spacetime-client/src/lib.rs`
2. `server-rs/crates/spacetime-client/src/ai.rs`
3. `server-rs/crates/spacetime-client/src/big_fish.rs`
4. `server-rs/crates/spacetime-client/src/mapper.rs`
5. `server-rs/crates/spacetime-client/README.md`
6. 本文档
7. `docs/technical/README.md`
8. `docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md` 的进度记录
本次禁止修改:
1. `server-rs/crates/spacetime-module/src/**`
2. `server-rs/crates/shared-contracts/src/**`
3. `server-rs/crates/api-server/src/app.rs`
4. `server-rs/crates/api-server/src/**` 路由行为
5. `src/services/**``src/hooks/**``src/components/**`
6. `server-rs/crates/spacetime-client/src/module_bindings/**` 生成绑定
## 4. 分层落点
| 层 | 职责 | 本次落点 |
| --- | --- | --- |
| 连接层 | 连接池、握手、超时、断线处理 | 保持现状,不改连接策略 |
| 调用层 | procedure / reducer then 回调、SDK 错误映射 | 新增统一错误 helper并先接 AI / Big Fish |
| mapper 层 | 绑定类型到 BFF record / DTO 的转换 | 新增通用 procedure 失败与缺快照 helper后续逐步替换重复代码 |
| facade 层 | 面向 `api-server` 的 typed 方法 | 方法签名保持不变 |
## 5. 后续依赖
1. `WP-ST` 每稳定一个 SpacetimeDB facade 后,再由 `WP-SC` 接对应 mapper / facade。
2. `WP-API` 只能通过 `spacetime-client` 调用 SpacetimeDB不直接拼接生成绑定。
3. 前端迁移必须等待 `WP-API` route 和 DTO 稳定后,再按 `services -> hooks -> components` 接入。
4. 若后续改变 table / reducer / procedure必须由 `WP-ST` 同步表目录和必要的绑定生成记录。
## 6. 本次完成范围
1. `SpacetimeClientError` 已新增并接入统一 helper
- `from_sdk_error`
- `procedure_failed`
- `missing_snapshot`
2. 已覆盖现有稳定 facade 的 SDK 错误映射,包含 AI、Big Fish、assets、auth、story、combat、inventory、npc、runtime、puzzle、custom world。
3. `mapper.rs` 中稳定 procedure result 的重复 `ok=false` 默认错误和缺快照错误已收口到统一 helper。
4. auth store snapshot import mapper 中历史乱码错误文案已恢复为中文语义。
5. 领域语义错误继续保留原样,例如 `custom_world_profile 不存在`,避免把业务不存在误归类为缺快照。
## 7. 验收
必须执行:
```powershell
cargo fmt --all --check --manifest-path server-rs/Cargo.toml
cargo check -p spacetime-client --manifest-path server-rs/Cargo.toml
cargo check -p api-server --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_SC_SPACETIME_CLIENT_REFACTOR_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md docs/technical/README.md server-rs/crates/spacetime-client/README.md server-rs/crates/spacetime-client/src/lib.rs server-rs/crates/spacetime-client/src/ai.rs server-rs/crates/spacetime-client/src/big_fish.rs server-rs/crates/spacetime-client/src/mapper.rs
npm.cmd run api-server:maincloud
```
说明:本次不改 SpacetimeDB 表、reducer、procedure不刷新生成绑定不同步 `migration.rs`
## 8. story runtime inventory source 接线切片
### 8.1 目标
本轮继续在 `WP-SC` 内认领一个可并行切片:在 `SpacetimeClient::get_story_runtime_projection_source` 中复用已稳定的 `get_runtime_inventory_state` typed facade将 SpacetimeDB 背包/装备快照折回投影所需的 `game_state.playerInventory``game_state.playerEquipment`
目标是让 `/api/story/sessions/{story_session_id}/runtime-projection` 的读取投影优先消费新的 inventory adapter 结果,而不是只依赖 runtime snapshot 中的历史 JSON 背包副本。
### 8.2 边界
本轮允许修改:
1. `server-rs/crates/spacetime-client/src/story_runtime.rs`
2. 本文档
3. `docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md`
本轮禁止修改:
1. `server-rs/crates/spacetime-module/src/**`
2. `server-rs/crates/spacetime-client/src/module_bindings/**`
3. `server-rs/crates/api-server/src/app.rs`
4. HTTP DTO、前端 services/hooks/components
5. `migration.rs`
### 8.3 实现约束
1. 只在 `spacetime-client` 中组合已存在 facade不新增 table、reducer、procedure。
2. `StoryRuntimeProjectionSource` 的输出结构保持不变,投影规则继续由 `module-runtime-story::build_story_runtime_projection` 承接。
3. inventory slot 到 runtime story JSON 的转换只做字段映射,不新增玩法规则。
4. `get_runtime_inventory_state` 若返回作用域不匹配,必须中止投影,避免把其他会话的背包装进当前 story session。
### 8.4 验收
```powershell
cargo test -p spacetime-client story_runtime --manifest-path server-rs/Cargo.toml
cargo check -p spacetime-client --manifest-path server-rs/Cargo.toml
cargo fmt -p spacetime-client --manifest-path server-rs/Cargo.toml --check
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_SC_SPACETIME_CLIENT_REFACTOR_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md server-rs/crates/spacetime-client/src/story_runtime.rs
npm.cmd run api-server:maincloud
```
## 9. 收尾关闭口径2026-05-01
当前稳定 facade 范围内,`WP-SC` 已完成:
1. `SpacetimeClientError` 统一 helper 补齐:
- `from_sdk_error`
- `validation_failed`
- `reducer_failed`
- `procedure_failed`
- `missing_snapshot`
2. reducer callback 的业务错误统一走 `reducer_failed`,保持 API 层可继续按 `Runtime` 分类映射为调用方输入或状态错误。
3. combat、inventory、runtime、story 等 facade 的本地命令构造 / 校验错误统一走 `validation_failed`,避免各文件继续散落 `Runtime(error.to_string())`
4. story runtime projection source 已接入 runtime inventory typed facade并已有定向测试覆盖 session guard、inventory guard、背包/装备覆盖和 option 解析。
5. `spacetime-client/README.md` 已从早期占位口径更新为当前完成口径,明确后续只随 `WP-ST` 新 facade 稳定后按领域增量接线。
关闭边界:
1. 本次不修改 `spacetime-module``migration.rs`、生成绑定、HTTP route、shared contract 或前端。
2. `WP-ST` 后续若新增或调整 SpacetimeDB facade需要另开对应领域切片继续补 typed facade / row mapper这不再阻塞当前 `WP-SC` 工作包关闭。
3. `WP-RS/WP-API/WP-FE/WP-DEL` 仍可因旧 runtime story 写侧和前端迁移保持进行中,但不应再把 `spacetime-client` 基础设施视为未完成。
最终验收命令:
```powershell
cargo fmt -p spacetime-client --manifest-path server-rs/Cargo.toml --check
cargo test -p spacetime-client --manifest-path server-rs/Cargo.toml
cargo check -p spacetime-client --manifest-path server-rs/Cargo.toml
cargo check -p api-server --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_SC_SPACETIME_CLIENT_REFACTOR_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md docs/technical/README.md server-rs/crates/spacetime-client/README.md server-rs/crates/spacetime-client/src/lib.rs server-rs/crates/spacetime-client/src/ai.rs server-rs/crates/spacetime-client/src/combat.rs server-rs/crates/spacetime-client/src/inventory.rs server-rs/crates/spacetime-client/src/runtime.rs server-rs/crates/spacetime-client/src/story.rs
npm.cmd run api-server:maincloud
```

View File

@@ -0,0 +1,78 @@
# server-rs DDD WP-ST AI Task 事件 Adapter 落地记录2026-04-29
## 1. 背景
`WP-AI AI Task` 已完成领域层拆分,`WP-ST SpacetimeDB Adapter` 可以开始把稳定领域状态变化接入 SpacetimeDB。当前 AI 任务已有真相表:
1. `ai_task`
2. `ai_task_stage`
3. `ai_text_chunk`
4. `ai_result_reference`
本次不改变这些真相表的字段,不改 HTTP/BFF不改前端只补齐 AI 任务状态变化的 SpacetimeDB 事件流。
## 2. 本次范围
允许修改:
1. `server-rs/crates/spacetime-module/src/ai/**`
2. `server-rs/crates/spacetime-module/src/migration.rs`
3. `docs/technical/SPACETIMEDB_TABLE_CATALOG.md`
4. 本文档
禁止修改:
1. `server-rs/crates/api-server/src/**`
2. `server-rs/crates/spacetime-client/src/**`
3. `src/services/**`
4. `src/hooks/**`
5. `src/components/**`
## 3. 设计
新增 `ai_task_event``public event` 表,供订阅端和后续 BFF 增量消费 AI 任务变化。
事件类型:
1. `TaskCreated`
2. `TaskStatusChanged`
3. `StageStarted`
4. `StageCompleted`
5. `TextChunkAppended`
6. `ResultReferenceAttached`
事件字段只保存用于路由和定位的轻量信息:
1. `task_id`
2. `owner_user_id`
3. `event_kind`
4. `task_status`
5. `stage_kind`
6. `text_chunk_row_id`
7. `result_reference_row_id`
8. `occurred_at`
## 4. 边界说明
1. `ai_task_event` 不是业务真相表,不能替代 `ai_task` / `ai_task_stage` / `ai_text_chunk` / `ai_result_reference`
2. reducer 和 procedure 仍只在事务成功后写入事件。
3. reducer 继续返回 `Result<(), String>`procedure 继续返回现有 `AiTaskProcedureResult`
4. 本次没有引入网络、文件、外部随机数或全局可变状态。
5. 本次新增表已同步 `migration.rs` 迁移白名单。
## 5. 验收命令
```powershell
cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml
cargo test -p module-ai --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_ST_AI_TASK_EVENT_ADAPTER_2026-04-29.md docs/technical/SPACETIMEDB_TABLE_CATALOG.md server-rs/crates/spacetime-module/src/ai/events.rs server-rs/crates/spacetime-module/src/ai/mod.rs server-rs/crates/spacetime-module/src/ai/snapshots.rs server-rs/crates/spacetime-module/src/ai/stages.rs server-rs/crates/spacetime-module/src/ai/tasks.rs server-rs/crates/spacetime-module/src/migration.rs
```
若后续生成前端绑定或发布数据库,需要继续执行:
```powershell
spacetime build
spacetime generate --lang typescript --out-dir <前端绑定目录> --module-path server-rs/crates/spacetime-module
spacetime describe <database> --json
```

View File

@@ -0,0 +1,51 @@
# server-rs DDD WP-ST Asset Row Mapper Adapter 落地记录2026-04-29
## 1. 背景
`module-assets` 已提供资产对象和实体绑定的领域 snapshot / record 构建能力。`spacetime-module` 的资产 Adapter 之前在 upsert 过程中直接重复拼装 SpacetimeDB row 与返回 snapshot字段规则分散在 Adapter 内。
本次不改变资产表结构,不改变 reducer / procedure 签名,只把 row 构造收口到更明确的 snapshot -> row mapper。
## 2. 本次范围
允许修改:
1. `server-rs/crates/spacetime-module/src/asset_metadata/objects.rs`
2. `server-rs/crates/spacetime-module/src/asset_metadata/bindings.rs`
3. 本文档
4. 全局任务清单进度记录
禁止修改:
1. `server-rs/crates/spacetime-module/src/migration.rs`
2. `docs/technical/SPACETIMEDB_TABLE_CATALOG.md`
3. `server-rs/crates/api-server/src/**`
4. `server-rs/crates/spacetime-client/src/**`
5. 前端 services/hooks/components
## 3. 设计
本次新增两个 Adapter 内部 mapper
1. `build_asset_object_row(&AssetObjectUpsertSnapshot) -> AssetObject`
2. `build_asset_entity_binding_row(&AssetEntityBindingSnapshot) -> AssetEntityBinding`
`upsert_asset_object``upsert_asset_entity_binding` 先构造领域 snapshot再由 mapper 落 SpacetimeDB row。这样后续继续迁移到 `module-assets` 应用服务时Adapter 的职责会更清楚:只做 row 查询、幂等定位、snapshot 持久化和 procedure result 返回。
## 4. 边界说明
1. 本次不新增、删除或修改 SpacetimeDB table 字段。
2. 本次不改 `migration.rs`
3. 本次不改 `spacetime-client` 绑定和 facade。
4. 本次不改 HTTP/BFF 和前端。
## 5. 验收命令
```powershell
cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml
cargo test -p module-assets --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_ST_ASSET_ROW_MAPPER_ADAPTER_2026-04-29.md server-rs/crates/spacetime-module/src/asset_metadata/objects.rs server-rs/crates/spacetime-module/src/asset_metadata/bindings.rs
```
结果:通过。

View File

@@ -0,0 +1,56 @@
# WP-ST Auth Adapter 目录化切片说明
## 背景
`spacetime-module/src/auth.rs` 同时承接认证表定义、procedure 入口、事务内导入导出逻辑和 module-auth 快照 JSON mapper。随着 `WP-A Auth` 已完成 DDD 骨架归位SpacetimeDB 侧也需要把 Auth adapter 从单文件拆到上下文目录,避免后续继续堆回根文件。
本次属于 `WP-ST SpacetimeDB Adapter` 的可并行切片,只做 Auth adapter 目录化,不改变 SpacetimeDB schema、procedure 名称、procedure 入参/出参或绑定形状。
## 本次范围
允许修改:
1. `server-rs/crates/spacetime-module/src/auth.rs`
2. `server-rs/crates/spacetime-module/src/auth/mod.rs`
3. `server-rs/crates/spacetime-module/src/auth/tables.rs`
4. `server-rs/crates/spacetime-module/src/auth/procedures.rs`
5. `server-rs/crates/spacetime-module/src/auth/mapper.rs`
6. 本文档
7. `docs/technical/README.md`
8. `docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md`
禁止修改:
1. `spacetime-module/src/lib.rs`
2. `spacetime-module/src/migration.rs`
3. `docs/technical/SPACETIMEDB_TABLE_CATALOG.md`
4. `spacetime-client/src/module_bindings/**`
5. `api-server/src/**`
6. 前端 services / hooks / components
## 设计
本次将原 `auth.rs` 拆成:
1. `auth/mod.rs`Auth adapter 子模块入口,继续 `pub use procedures::*``pub use tables::*`,保持根模块 `pub use auth::*` 的对外导出不变。
2. `auth/tables.rs`:保留 `AuthStoreSnapshot``UserAccount``AuthIdentity``RefreshSession` 四张表定义和索引不改字段、可见性、accessor 或索引名。
3. `auth/procedures.rs`:保留 `get_auth_store_snapshot``upsert_auth_store_snapshot``import_auth_store_snapshot``export_auth_store_snapshot_from_tables` 四个 procedure 入口,以及对应事务内读写逻辑。
4. `auth/mapper.rs`:收口 module-auth 持久化快照 JSON 结构、refresh session client info JSON 结构和 identity id 组件清理函数,仅供 Auth procedure 内部使用。
## 边界说明
1. 本次未新增 reducer现有 Auth 同步仍通过 procedure 完成。
2. 本次未改变表结构,不需要修改 `migration.rs`
3. 本次未生成 SpacetimeDB 绑定,原因是导出的表、类型和 procedure 名称未改变。
4. Auth adapter 仍只负责认证快照与正式表的导入导出,不承接短信、微信 OAuth、JWT、cookie、HTTP 或文件持久化。
## 验收
```powershell
cargo fmt -p spacetime-module --manifest-path server-rs/Cargo.toml --check
cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_ST_AUTH_ADAPTER_SPLIT_2026-04-29.md docs/technical/README.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md server-rs/crates/spacetime-module/src/auth/mod.rs server-rs/crates/spacetime-module/src/auth/tables.rs server-rs/crates/spacetime-module/src/auth/procedures.rs server-rs/crates/spacetime-module/src/auth/mapper.rs
```
`cargo check -p spacetime-module` 被非 WP-ST 依赖 crate 当前并行改动阻断,应记录具体阻断 crate 和错误位置;本切片不越界修改其他已认领工作包。

View File

@@ -0,0 +1,69 @@
# server-rs DDD WP-ST Big Fish 发布门禁 Adapter 落地记录2026-04-29
## 1. 背景
`WP-BF Big Fish` 已在领域层新增 `evaluate_publish_readiness`,用于评估草稿和资产槽是否满足发布条件。`spacetime-module` 之前在 Big Fish adapter 内直接调用 `build_asset_coverage` 判断发布就绪,容易让门禁规则继续散落在 Adapter。
本次将 SpacetimeDB Adapter 的发布门禁收口到 `module-big-fish` 应用服务,并新增轻量事件表记录成功事务中的门禁评估事实。
## 2. 本次范围
允许修改:
1. `server-rs/crates/spacetime-module/src/big_fish/**`
2. `server-rs/crates/spacetime-module/src/migration.rs`
3. `docs/technical/SPACETIMEDB_TABLE_CATALOG.md`
4. 本文档
禁止修改:
1. `server-rs/crates/api-server/src/**`
2. `server-rs/crates/spacetime-client/src/**`
3. `src/services/**`
4. `src/hooks/**`
5. `src/components/**`
## 3. 设计
新增 `big_fish_event``public event` 表,当前只承接 `PublishReadinessEvaluated`
事件字段:
1. `session_id`
2. `owner_user_id`
3. `event_kind`
4. `publish_ready`
5. `blockers_json`
6. `occurred_at`
接入点:
1. `compile_big_fish_draft_tx`
2. `generate_big_fish_asset_tx`
3. `publish_big_fish_game_tx`
这些接入点先从 SpacetimeDB row 读取草稿和资产槽,再调用 `module_big_fish::evaluate_publish_readiness`,最后把 readiness 回写到 `big_fish_creation_session.publish_ready``asset_coverage_json`
## 4. 边界说明
1. `big_fish_event` 不是作品真相表,不能替代 `big_fish_creation_session``big_fish_asset_slot`
2. 发布门禁规则由 `module-big-fish` 领域应用服务决定SpacetimeDB Adapter 只负责 row 映射、持久化和事件落表。
3. 由于 SpacetimeDB 事务在 `Err` 时回滚,发布失败路径中的事件不会持久化;事件表只记录成功事务内完成的门禁评估事实。
4. 本次没有引入 HTTP、OSS、图片生成、文件系统或外部随机数。
5. 本次新增表已同步 `migration.rs` 迁移白名单。
## 5. 验收命令
```powershell
cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml
cargo test -p module-big-fish --manifest-path server-rs/Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_WP_ST_BIG_FISH_READINESS_ADAPTER_2026-04-29.md docs/technical/SPACETIMEDB_TABLE_CATALOG.md server-rs/crates/spacetime-module/src/big_fish/events.rs server-rs/crates/spacetime-module/src/big_fish/mod.rs server-rs/crates/spacetime-module/src/big_fish/assets.rs server-rs/crates/spacetime-module/src/big_fish/session.rs server-rs/crates/spacetime-module/src/migration.rs
```
若后续具备 CLI 环境,需要继续执行:
```powershell
spacetime build --project-path server-rs/crates/spacetime-module
spacetime generate --lang rust --out-dir server-rs/crates/spacetime-client/src/module_bindings --module-path server-rs/crates/spacetime-module
```

View File

@@ -0,0 +1,66 @@
# WP-ST SpacetimeDB Adapter 收尾记录2026-05-01
## 1. 收尾目标
本次关闭 `SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md``WP-ST SpacetimeDB Adapter` 当前稳定范围已经落地的表、reducer、procedure、event table 和上下文 adapter 必须完成 `migration.rs`、表目录、Rust bindings 与自动门禁闭环。
收尾后,`WP-ST` 不再以“多个上下文和绑定生成仍待推进”的口径挂起;后续只有新增 table / reducer / procedure 或 row shape 时,才按增量切片重新认领。
## 2. 已完成内容
1. `asset_event` 已作为 `public event` 表进入资产主链,覆盖资产对象确认和实体槽位绑定变更事件。
2. `asset_event` 已对齐 `migration.rs``SPACETIMEDB_TABLE_CATALOG.md` 和 Rust `module_bindings`
3. `SPACETIMEDB_TABLE_CATALOG.md` 补齐 `database_migration_operator`、邀请/推荐/会员/充值等 profile 表,以及 `asset_event` 的结构、索引和查询模板。
4. `scripts/check-server-rs-ddd-boundaries.mjs` 新增 SpacetimeDB 表漂移检查,自动核对 table accessor、`migration.rs` 白名单和表目录项,阻止新增表漏迁移或漏文档。
5. `scripts/generate-spacetime-bindings.mjs` 在 Windows 下继续先输出短临时目录;当 SpacetimeDB CLI 已生成文件但自身 formatter 失败时,由脚本分批 `rustfmt` 后再同步生成目录。
6. `spacetime-client/src/module_bindings` 已通过 `npm.cmd run spacetime:generate -- --rust-only` 重新生成,包含 `asset_event_table.rs``asset_event_type.rs``asset_event_kind_type.rs`
7. `spacetime-client/README.md` 已同步生成物维护口径:禁止手写 generated code格式化 fallback 只能由仓库生成脚本托管。
## 3. 边界说明
1. 本次收尾不把未稳定的新 story action 写接口、前端迁移或旧 compat 删除并入 `WP-ST`
2. `database_migration_operator` 是迁移权限表,本身不导出到业务迁移包;其他业务表必须纳入 `migration.rs`
3. `spacetime-client/src/module_bindings/**` 仍是生成物,不承载手写 facade 或领域规则。
4. 后续若新增 SpacetimeDB 表,必须同时更新表目录、`migration.rs`、绑定生成结果,并让 DDD 边界检查通过。
## 4. 验收命令
本轮收尾至少执行:
```powershell
npm.cmd run spacetime:generate -- --rust-only
cargo fmt --all --check --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-client --manifest-path server-rs\Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding
npm.cmd run api-server:maincloud
```
执行结果以本次任务清单记录为准。
## 5. 本次执行结果
已执行并通过:
```powershell
npm.cmd run spacetime:generate -- --rust-only
cargo fmt --all --check --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml
cargo check -p spacetime-client --manifest-path server-rs\Cargo.toml
cargo test -p module-assets --manifest-path server-rs\Cargo.toml
cargo test -p spacetime-client --manifest-path server-rs\Cargo.toml
cargo check -p api-server --manifest-path server-rs\Cargo.toml
npm.cmd run check:server-rs-ddd
npm.cmd run check:encoding
npm.cmd run api-server:maincloud
```
结果:
1. Rust bindings 已生成并同步,`asset_event` 三个生成文件已落盘。
2. `spacetime-module``spacetime-client` 编译通过,`module-assets` 8 个测试通过,`spacetime-client` 10 个测试通过。
3. DDD 边界检查通过 15 个 module crate编码检查通过 2815 个文件。
4. `api-server:maincloud` 启动后 `/healthz` 返回 `200 {"ok":true,"service":"genarrative-api-server"}`,本次启动进程已清理并释放 `3100` 端口。
已知 warning`module-runtime-story``api-server` 仍有非本次 WP-ST 引入的未使用 helper / prompt warning后续按对应工作包收口不阻塞本次 WP-ST 关闭。

View File

@@ -0,0 +1,30 @@
# WP-ST Custom World 根入口瘦身落地说明
## 背景
`spacetime-module/src/lib.rs` 已完成 gameplay 根入口瘦身,但仍直接承载 Custom World 的 SpacetimeDB 表、reducer、procedure 与私有事务 helper。根入口继续膨胀会让后续 `module-custom-world` 领域化、绑定生成检查和并行任务边界都难以维护。
本次迁移按 WP-ST Adapter 边界执行:根入口只负责声明模块与 re-exportCustom World 的 SpacetimeDB adapter 真正落到 `spacetime-module/src/custom_world/mod.rs`
## 落地范围
1. `lib.rs` 新增 `mod custom_world;``pub use custom_world::*;`,保留根模块对绑定生成需要的公开导出。
2. 将当前 `lib.rs` 已公开的 Custom World 表、procedure、reducer、事务 helper 与单测整体迁移到 `custom_world/mod.rs`
3. `custom_world/mod.rs``use crate::*;` 复用根模块已经公开的领域类型、SpacetimeDB 类型和 JSON helper避免复制跨模块前置导入。
4. 移除 `lib.rs` 中 Custom World 的重复实现,让根入口只承担组合职责。
## 边界
1. 不新增、删除或重命名 Custom World 表。
2. 不新增、删除或重命名当前已公开的 reducer / procedure。
3. 不修改 `CustomWorldProfile``CustomWorldGalleryEntry` 等表字段,本次不触发 `migration.rs` 更新。
4. 不启用 `custom_world` 子目录中尚未成为根入口正式导出的新过程,避免把后续行为变更混入本次根入口迁移。
5. 不修改前端、BFF、`server-node` 或 PostgreSQL 兼容逻辑。
## 验收
1. `cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml`
2. `cargo test -p module-custom-world --manifest-path server-rs/Cargo.toml`
3. `npm.cmd run check:server-rs-ddd`
4. `npm.cmd run check:encoding -- docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md docs/technical/SERVER_RS_DDD_WP_ST_CUSTOM_WORLD_ROOT_SPLIT_2026-04-29.md server-rs/crates/spacetime-module/src/lib.rs server-rs/crates/spacetime-module/src/custom_world/mod.rs`
5. 修改后端 Rust 代码后,按项目约束运行 `npm.cmd run api-server:maincloud` 并探测 `/healthz`

View File

@@ -0,0 +1,31 @@
# WP-ST Gameplay 根入口瘦身落地说明
## 背景
`spacetime-module/src/gameplay/mod.rs` 已经承接 RPG gameplay 的 SpacetimeDB table、reducer、procedure、row mapper 和事务 helper但根入口 `spacetime-module/src/lib.rs` 仍保留同一批 gameplay 代码,导致根文件继续承担 Custom World 与 RPG gameplay 两条大链路。
本次切片属于 `WP-ST SpacetimeDB Adapter`目标是让根入口只做模块声明、re-export 和仍未拆出的 Custom World adapter不改变 SpacetimeDB schema、reducer/procedure 对外名称或业务规则。
## 落地范围
1.`spacetime-module/src/lib.rs` 接入 `mod gameplay; pub use gameplay::*;`
2. 将根入口中已迁入 `gameplay/mod.rs` 的 RPG gameplay table、reducer、procedure、row mapper 和事务 helper 删除。
3.`gameplay/mod.rs` 补齐模块内依赖导入。
4. 补齐 story session 继续推进与读取所需的内部 helper
- `continue_story_tx`
- `get_story_session_state_tx`
5. 保留根入口中的 Custom World table、procedure、reducer 和测试,本次不拆 Custom World。
## 边界
1. 本次不修改 `migration.rs`因为表名、字段、reducer/procedure 名称没有变化。
2. 本次不修改 `SPACETIMEDB_TABLE_CATALOG.md`,因为表目录没有变化。
3. 本次不修改 `api-server``spacetime-client`、前端 services/hooks/components。
4. 本次只移动 adapter 归属,不把业务规则从 `module-*` 拉回 SpacetimeDB adapter。
## 验收
1. `cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml`
2. `npm.cmd run check:server-rs-ddd`
3. `npm.cmd run check:encoding -- server-rs/crates/spacetime-module/src/lib.rs server-rs/crates/spacetime-module/src/gameplay/mod.rs docs/technical/SERVER_RS_DDD_WP_ST_GAMEPLAY_ROOT_SPLIT_2026-04-29.md docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md`
4. 如需联调发布,再执行当前 CLI 支持的 `spacetime build -p server-rs/crates/spacetime-module`

Some files were not shown because too many files have changed in this diff Show More