完善 server-rs DDD 重构计划与骨架
This commit is contained in:
@@ -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)。
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
## 文档列表
|
||||
|
||||
- [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 映射和表结构变更约束。
|
||||
- [RPG_PROMPT_FRONTEND_REMOVAL_AND_SERVER_RS_MIGRATION_2026-04-28.md](./RPG_PROMPT_FRONTEND_REMOVAL_AND_SERVER_RS_MIGRATION_2026-04-28.md):冻结 RPG 提示词禁止存在前端的边界,明确前端只保留 API client,角色私聊/NPC 对话/剧情续写等 prompt 统一收口到 `server-rs`。
|
||||
- [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` 生成世界底稿。
|
||||
|
||||
393
docs/technical/SERVER_RS_DDD_FULL_REFACTOR_2026-04-28.md
Normal file
393
docs/technical/SERVER_RS_DDD_FULL_REFACTOR_2026-04-28.md
Normal 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 数据库或令牌失败,必须记录具体错误;不能改用旧后端重启命令。
|
||||
310
docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
Normal file
310
docs/technical/SERVER_RS_DDD_PARALLEL_TASKLIST_2026-04-29.md
Normal file
@@ -0,0 +1,310 @@
|
||||
# server-rs DDD 全局并行任务清单(2026-04-29)
|
||||
|
||||
## 1. 目标与范围
|
||||
|
||||
本文件是 `server-rs` DDD 一次性重构的总任务清单,覆盖所有后端 crate、SpacetimeDB adapter、HTTP/BFF、共享契约、平台能力和前端接入。runtime story 去兼容层不再单独维护专项清单,统一归入本文的 `WP-RS` 工作包。
|
||||
|
||||
本轮目标:
|
||||
|
||||
1. 全部业务规则沉到 `module-*`。
|
||||
2. `spacetime-module` 只保留 SpacetimeDB table、reducer、procedure、row mapper、事务编排和 event table。
|
||||
3. `api-server` 只保留 HTTP/BFF、鉴权、SSE、请求响应映射、SpacetimeDB client 调用和平台服务编排。
|
||||
4. `platform-*` 只承载外部副作用实现。
|
||||
5. `shared-contracts` 冻结 HTTP/前端 DTO;`shared-kernel` 承载跨领域纯值处理。
|
||||
6. 前端只消费后端新接口和后端投影,不承接正式业务真相。
|
||||
|
||||
用户已明确允许去掉现有兼容层并修改前端以匹配新接口,因此全局任务不以旧接口兼容为约束;任何 breaking change 必须记录在对应任务交接和 API 文档中。
|
||||
|
||||
## 2. 全局依赖图
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
G0["G0 文档、边界、冻结窗口"]
|
||||
G1["G1 契约与路由矩阵"]
|
||||
G2["G2 module-* DDD 骨架与边界检查"]
|
||||
A["WP-A Auth"]
|
||||
AS["WP-AS Assets"]
|
||||
AI["WP-AI AI Task"]
|
||||
CW["WP-CW Custom World"]
|
||||
BF["WP-BF Big Fish"]
|
||||
PZ["WP-PZ Puzzle"]
|
||||
RT["WP-RT Runtime/Profile/Save"]
|
||||
RPG["WP-RPG Gameplay 域"]
|
||||
RS["WP-RS Runtime Story 去兼容层"]
|
||||
ST["WP-ST SpacetimeDB Adapter"]
|
||||
SC["WP-SC Spacetime Client"]
|
||||
API["WP-API api-server BFF"]
|
||||
PF["WP-PF platform side effects"]
|
||||
FE["WP-FE Frontend Clients/UI"]
|
||||
DEL["WP-DEL 删除旧层与命名收口"]
|
||||
V["WP-V 全链验证与发布 smoke"]
|
||||
|
||||
G0 --> G1
|
||||
G0 --> G2
|
||||
G1 --> A
|
||||
G1 --> AS
|
||||
G1 --> AI
|
||||
G1 --> CW
|
||||
G1 --> BF
|
||||
G1 --> PZ
|
||||
G1 --> RT
|
||||
G1 --> RPG
|
||||
G1 --> RS
|
||||
G2 --> A
|
||||
G2 --> AS
|
||||
G2 --> AI
|
||||
G2 --> CW
|
||||
G2 --> BF
|
||||
G2 --> PZ
|
||||
G2 --> RT
|
||||
G2 --> RPG
|
||||
G2 --> RS
|
||||
A --> ST
|
||||
AS --> ST
|
||||
AI --> ST
|
||||
CW --> ST
|
||||
BF --> ST
|
||||
PZ --> ST
|
||||
RT --> ST
|
||||
RPG --> ST
|
||||
RS --> ST
|
||||
ST --> SC
|
||||
SC --> API
|
||||
PF --> API
|
||||
API --> FE
|
||||
FE --> DEL
|
||||
API --> DEL
|
||||
ST --> DEL
|
||||
DEL --> V
|
||||
```
|
||||
|
||||
## 3. 并行分批
|
||||
|
||||
### 3.1 第一批:冻结边界
|
||||
|
||||
只能串行完成,避免后续并行任务各自定义接口。
|
||||
|
||||
1. `G0 文档、边界、冻结窗口`
|
||||
2. `G1 契约与路由矩阵`
|
||||
3. `G2 module-* DDD 骨架与边界检查`
|
||||
|
||||
### 3.2 第二批:领域纯规则并行迁移
|
||||
|
||||
第二批互相并行,但每个任务只能改自己的 `module-*` 和对应文档。
|
||||
|
||||
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 去兼容层`
|
||||
|
||||
### 3.3 第三批:adapter 和 BFF 接线
|
||||
|
||||
领域任务有稳定应用结果后启动。
|
||||
|
||||
1. `WP-ST SpacetimeDB Adapter`
|
||||
2. `WP-SC Spacetime Client`
|
||||
3. `WP-PF platform side effects`
|
||||
4. `WP-API api-server BFF`
|
||||
|
||||
### 3.4 第四批:前端与旧层删除
|
||||
|
||||
后端新接口可用后启动。
|
||||
|
||||
1. `WP-FE Frontend Clients/UI`
|
||||
2. `WP-DEL 删除旧层与命名收口`
|
||||
3. `WP-V 全链验证与发布 smoke`
|
||||
|
||||
## 4. 工作包总表
|
||||
|
||||
| 工作包 | 可并行条件 | 主要文件边界 | 禁止触碰 | 交付物 | 验收 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| G0 文档、边界、冻结窗口 | 首个串行 | `PLAN.md`、`docs/technical/*DDD*`、`docs/planning/*` | 业务代码 | 全局任务清单、专项清单索引、阶段性交接模板 | 编码检查通过 |
|
||||
| G1 契约与路由矩阵 | G0 后 | `shared-contracts`、`packages/shared/src/contracts/*`、API 路由索引 | 领域实现 | DTO 分组、breaking change 清单、前后端路由矩阵 | shared contract 测试通过 |
|
||||
| G2 DDD 骨架与边界检查 | G0 后 | `module-*` 骨架、`scripts/check-server-rs-ddd-boundaries.mjs` | 业务重写 | 所有 `module-*` 具备 `domain/commands/application/events/errors`,检查脚本覆盖禁用依赖 | `npm.cmd run check:server-rs-ddd` |
|
||||
| WP-A Auth | G1/G2 后 | `module-auth`、`spacetime-module/src/auth*`、`api-server/src/auth*`、`platform-auth` | 其他玩法域 | 账号、会话、验证码、微信绑定领域化;真实短信/微信在 platform | `cargo test -p module-auth`,auth API 测试 |
|
||||
| WP-AS Assets | G1/G2 后 | `module-assets`、`spacetime-module/src/asset_metadata/*`、资产 API、OSS adapter | 玩法业务规则 | 资产对象与绑定规则纯化;OSS head/upload 移出领域核心 | `cargo test -p module-assets`,资产 facade 测试 |
|
||||
| WP-AI AI Task | G1/G2 后 | `module-ai`、`spacetime-module/src/ai/*`、AI task API | LLM prompt 业务规则 | AI task/stage/chunk/result 状态机领域化 | `cargo test -p module-ai`,AI task reducer/procedure smoke |
|
||||
| WP-CW Custom World | G1/G2 后 | `module-custom-world`、`spacetime-module/src/custom_world/*`、`api-server` custom world 路由、前端创作 client | Big Fish/Puzzle | profile、agent session、draft card、gallery、publish gate 领域化;LLM 留在 API/platform | `cargo test -p module-custom-world`,custom world 定向测试 |
|
||||
| WP-BF Big Fish | G1/G2 后 | `module-big-fish`、`spacetime-module/src/big_fish/*`、Big Fish API、Big Fish 前端 client | Puzzle/RPG | 会话、草稿、素材槽、运行态纯规则;草稿校验下沉 | `cargo test -p module-big-fish`,Big Fish API 测试 |
|
||||
| WP-PZ Puzzle | G1/G2 后 | `module-puzzle`、`spacetime-module/src/puzzle*`、Puzzle API、Puzzle 前端 client | Big Fish/RPG | Agent session、work profile、runtime run、排行榜规则领域化 | `cargo test -p module-puzzle`,Puzzle 定向测试 |
|
||||
| WP-RT Runtime/Profile/Save | G1/G2 后 | `module-runtime`、`spacetime-module/src/runtime/*`、runtime/save/profile API | RPG story 规则 | runtime setting、snapshot、wallet、played world、save archive 领域化 | `cargo test -p module-runtime`,runtime API 测试 |
|
||||
| WP-RPG Gameplay 域 | G1/G2 后 | `module-combat`、`module-inventory`、`module-npc`、`module-progression`、`module-quest`、`module-runtime-item`、`module-story` | 创作域 | 战斗、背包、NPC、成长、任务、宝箱、story session 纯规则与跨域事件 | 各 module 测试;跨域应用结果测试 |
|
||||
| WP-RS Runtime Story 去兼容层 | G1/G2 后 | `module-runtime-story`、`api-server/src/runtime_story/*`、`src/hooks/rpg-runtime-story/*` | 非 RPG 创作域 | 删除 compat 层、session scoped 新接口、前端匹配新接口 | 按专项文档验收 |
|
||||
| WP-ST SpacetimeDB Adapter | 领域任务输出稳定后 | `spacetime-module/src/**`、`migration.rs`、表目录 | `api-server` 业务逻辑 | table/reducer/procedure/mapper/queries 按上下文拆分;必要 event/projection table | `cargo check -p spacetime-module`,需要时 `spacetime build/generate` |
|
||||
| WP-SC Spacetime Client | WP-ST 接口稳定后 | `spacetime-client/src/**`、绑定 mapper | 领域规则 | typed facade、错误映射、row snapshot mapper | `cargo check -p spacetime-client` |
|
||||
| WP-PF platform side effects | 可与 WP-API 并行 | `platform-*`、`api-server` platform 接线 | 领域状态机 | LLM、OSS、SMS、微信等副作用统一 adapter | platform crate 测试或 API smoke |
|
||||
| WP-API api-server BFF | WP-SC/PF 可用后 | `api-server/src/**` | SpacetimeDB table 定义、领域主规则 | 路由、鉴权、SSE、请求响应映射、平台编排收口 | `cargo test -p api-server`,`cargo check -p api-server` |
|
||||
| WP-FE Frontend Clients/UI | G1 和 WP-API 接口稳定后 | `src/services/**`、`src/hooks/**`、`src/components/**` | 后端规则复刻 | API client、hooks、UI 流程对齐新 contract;删除前端正式规则 | vitest/ESLint 定向测试 |
|
||||
| WP-DEL 删除旧层与命名收口 | 新接口与前端迁移后 | 旧 compat、旧 facade、旧 contract、旧测试 | 新主链 | 物理删除旧入口、旧命名、旧 fixture 中非必要样本 | 搜索无运行代码引用旧层 |
|
||||
| WP-V 全链验证与发布 smoke | 最后 | 文档、测试脚本、README | 新功能扩展 | 全链命令、Maincloud smoke、文档交接 | 第 8 节命令通过或记录非本轮阻塞 |
|
||||
|
||||
## 5. 工作包边界细则
|
||||
|
||||
### 5.1 G1 契约与路由矩阵
|
||||
|
||||
必须先冻结:
|
||||
|
||||
1. 当前保留、重命名、删除的 HTTP 路由。
|
||||
2. 每个前端页面对应的 query/result DTO。
|
||||
3. 每个写入接口对应的 command DTO。
|
||||
4. breaking change 清单。
|
||||
5. API 错误 envelope 与中文错误字段。
|
||||
|
||||
禁止在 G1 中实现业务逻辑。
|
||||
|
||||
### 5.2 module-* 领域任务通用规则
|
||||
|
||||
每个 `module-*` 工作包必须输出:
|
||||
|
||||
1. `domain.rs` 或 `domain/*`:聚合和值对象。
|
||||
2. `commands.rs`:写入输入。
|
||||
3. `application.rs`:纯应用用例,输出应用结果或领域事件。
|
||||
4. `events.rs`:领域事件。
|
||||
5. `errors.rs`:领域错误。
|
||||
6. 单元测试。
|
||||
|
||||
禁止:
|
||||
|
||||
1. Axum / HTTP status。
|
||||
2. SpacetimeDB `ReducerContext`、table API。
|
||||
3. reqwest、OSS、真实 LLM、文件系统。
|
||||
4. `mapper.rs`。
|
||||
|
||||
### 5.3 WP-ST SpacetimeDB Adapter
|
||||
|
||||
按上下文拆到:
|
||||
|
||||
```text
|
||||
server-rs/crates/spacetime-module/src/<context>/
|
||||
├─ mod.rs
|
||||
├─ tables.rs
|
||||
├─ reducers.rs
|
||||
├─ procedures.rs
|
||||
├─ mapper.rs
|
||||
└─ queries.rs
|
||||
```
|
||||
|
||||
当前已有模块可渐进对齐,但新增实现不得继续堆回 `lib.rs`。
|
||||
|
||||
SpacetimeDB 硬要求:
|
||||
|
||||
1. reducer 使用 `&ReducerContext`。
|
||||
2. 预期失败返回 `Result<(), String>` 或 procedure 错误,不用 panic 表达业务失败。
|
||||
3. 授权基于 `ctx.sender()`。
|
||||
4. 表访问使用 `ctx.db.table()`。
|
||||
5. 更新只通过主键,非主键更新走 delete + insert。
|
||||
6. reducer 无网络、文件、外部随机数和全局可变状态。
|
||||
|
||||
### 5.4 WP-API api-server
|
||||
|
||||
允许:
|
||||
|
||||
1. 鉴权与 request context。
|
||||
2. route handler / extractor。
|
||||
3. DTO 映射。
|
||||
4. 调用 `spacetime-client`。
|
||||
5. 调用 `platform-*`。
|
||||
6. SSE stream。
|
||||
|
||||
禁止:
|
||||
|
||||
1. 大段领域分支。
|
||||
2. SpacetimeDB table 定义。
|
||||
3. 为旧接口继续保留双主链。
|
||||
|
||||
### 5.5 WP-FE Frontend Clients/UI
|
||||
|
||||
前端只负责表现:
|
||||
|
||||
1. 调用 API。
|
||||
2. 管理 loading/error/transition。
|
||||
3. 渲染服务端 query/result DTO。
|
||||
4. 保存 UI 临时输入。
|
||||
|
||||
禁止:
|
||||
|
||||
1. 正式业务状态机。
|
||||
2. 正式任务、战斗、背包、NPC、章节、世界 mutation 规则。
|
||||
3. prompt 正式组装。
|
||||
4. 绕过后端直接写真相。
|
||||
|
||||
## 6. 关键依赖与防冲突边界
|
||||
|
||||
1. `shared-contracts` 由 G1 统一所有权,其他任务只消费,不私自改 DTO shape。
|
||||
2. `spacetime-module/src/lib.rs` 由 WP-ST 统一所有权,领域任务不直接改根入口。
|
||||
3. `api-server/src/app.rs` 路由挂载由 WP-API 统一所有权。
|
||||
4. `src/services/aiService.ts`、`src/services/rpg-runtime/*` 由 WP-FE 统一所有权。
|
||||
5. `module-runtime-story` 与 runtime story 新接口由 WP-RS 所有,不和 WP-RPG 混写。
|
||||
6. 若某任务必须改别人的边界文件,先在交接记录中写明改动动机和待合流点。
|
||||
|
||||
## 7. 文档产出要求
|
||||
|
||||
每个工作包完成后必须更新或新增对应文档:
|
||||
|
||||
1. 技术方案:放 `docs/technical/`。
|
||||
2. 审计和迁移验证:放 `docs/audits/engineering/`。
|
||||
3. 用户体验或踩坑:放 `docs/experience/`。
|
||||
4. 表结构变化:更新 `docs/technical/SPACETIMEDB_TABLE_CATALOG.md`。
|
||||
5. API 路由变化:更新 `docs/technical/RUST_API_SERVER_ROUTE_INDEX_2026-04-22.md` 或新增新版路由索引。
|
||||
|
||||
交接摘要必须包含:
|
||||
|
||||
1. 已改文件。
|
||||
2. 未完成项。
|
||||
3. 依赖的上游/下游任务。
|
||||
4. 验证命令与结果。
|
||||
5. 是否触碰表结构、是否同步 `migration.rs`。
|
||||
|
||||
## 8. 全局验收命令
|
||||
|
||||
基础检查:
|
||||
|
||||
```powershell
|
||||
npm.cmd run check:server-rs-ddd
|
||||
cargo fmt --all --check --manifest-path server-rs/Cargo.toml
|
||||
cargo check -p api-server --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
|
||||
npm.cmd run check:encoding
|
||||
```
|
||||
|
||||
领域测试:
|
||||
|
||||
```powershell
|
||||
cargo test -p module-ai -p module-assets -p module-auth -p module-big-fish -p module-combat -p module-custom-world -p module-inventory -p module-npc -p module-progression -p module-puzzle -p module-quest -p module-runtime -p module-runtime-item -p module-runtime-story -p module-story --manifest-path server-rs/Cargo.toml
|
||||
```
|
||||
|
||||
接口与前端测试按触碰范围执行:
|
||||
|
||||
```powershell
|
||||
cargo test -p api-server --manifest-path server-rs/Cargo.toml
|
||||
npm.cmd run test -- src/services
|
||||
npm.cmd run test -- src/hooks
|
||||
```
|
||||
|
||||
后端代码变更后必须执行:
|
||||
|
||||
```powershell
|
||||
npm.cmd run api-server:maincloud
|
||||
```
|
||||
|
||||
若改 SpacetimeDB table / reducer / procedure:
|
||||
|
||||
```powershell
|
||||
spacetime build
|
||||
spacetime generate --lang typescript --out-dir <前端绑定目录> --module-path server-rs/crates/spacetime-module
|
||||
spacetime describe <database> --json
|
||||
```
|
||||
|
||||
不能用旧后端重启命令替代 `npm.cmd run api-server:maincloud`。
|
||||
|
||||
## 9. 专项任务引用
|
||||
|
||||
当前不再单独维护专项清单。`WP-RS Runtime Story 去兼容层` 已内联在本文第 4 节工作包总表中。
|
||||
|
||||
后续如果某个工作包仍存在编码级歧义,必须先在本文补齐边界;只有单个工作包过大且无法在本文清晰承载时,才新增对应专项清单。
|
||||
Reference in New Issue
Block a user