Files
Genarrative/backend-rewrite-tasklist/M0_REPOSITORY_BOUNDARY_DECISIONS_2026-04-20.md
kdletters cbc27bad4a
Some checks failed
CI / verify (push) Has been cancelled
init with react+axum+spacetimedb
2026-04-26 18:06:23 +08:00

12 KiB
Raw Blame History

M0仓库边界决议

日期:2026-04-20

依据来源:

1. 文档目的

这份文档用于持续冻结 M0 中与仓库边界直接相关的决策,避免进入 M1 后再反复改目录、改职责口径。

当前已确认的事项会持续在这份文档上追加维护,后续若再有新的边界冻结结论,也统一收口到这里。

2. 边界决议状态

事项 当前状态 当前结论
Rust 后端新目录名与根目录落位方案 已确认 新 Rust 后端固定为仓库根目录下的 server-rs/,与 server-node/ 同级。
server-node/ 在迁移期继续保留,不提前删除 已确认 server-node/M0 ~ M6 期间持续保留,直到 M7 切流与回退验证完成后再评估清理。
前端第一阶段仍然只访问 Axum不直连 SpacetimeDB 已确认 M0 ~ M6 前端统一只访问 Axum 暴露的 /api/*/healthz、SSE 与静态资源兼容层,不新增直连 SpacetimeDB 原生协议路径。
外部副作用统一收口在 Axum不放进 SpacetimeDB 模块 已确认 OSS、LLM、短信、微信 OAuth、本地文件系统等外部副作用统一落在 Axum/application/infra不进入 SpacetimeDB reducer/module。
server-rs/ 内部采用多 crate 组织,由主工程 crate 统一引用模块 crate 已确认 server-rs/ 采用 crates/* 工作区结构,crates/api-servercrates/spacetime-module 作为主工程 crate独立模块以 crates/module-* 形式被主工程 crate 引用。
editor 为遗留无用模块,不纳入 server-rs 本轮重写范围 已确认 server-node/src/modules/editor/api/editor/* 仅作为历史基线保留对照;自 2026-04-21 起退出本轮 Rust 后端重写范围。

3. 已确认决议一:server-rs/ 固定落在仓库根目录

3.1 决议内容

本次重写固定采用以下仓库落位:

  1. 新后端目录名固定为 server-rs/
  2. 目录位置固定在仓库根目录
  3. 与以下目录保持同级:
    • server-node/
    • src/
    • docs/
    • packages/

目标形态:

Genarrative/
├─ server-node/
├─ server-rs/
├─ src/
├─ packages/
├─ docs/
└─ backend-rewrite-tasklist/

3.2 不采用的落位方案

以下方案当前明确不采用:

  1. 不放进 server-node/ 子目录中做“Node + Rust 混编后端”。
  2. 不放进 packages/,避免被前端 package/workspace 语义误导。
  3. 不使用过于泛化的根目录名如 server/backend/,避免和当前 server-node/ 职责混淆。

3.3 这样落位的原因

  1. 与当前重写设计文档、任务清单、后续 M1 多 crate 规划保持一致。
  2. 允许 server-node/server-rs/ 在迁移期并行存在,便于逐阶段切流。
  3. 让 Rust 工作区边界清晰,不污染现有前端 src/packages/、Vite 工具链。
  4. 后续新增 server-rs/scripts/*Cargo.tomlcrates/* 时路径最直接,不需要额外中间层。

3.4 对后续任务的直接约束

从这一条决议开始,后续任务必须统一按以下路径落位:

  1. M1 的工作区初始化在 server-rs/
  2. Axum 主工程 crate 在 server-rs/crates/api-server
  3. SpacetimeDB 主工程 crate 在 server-rs/crates/spacetime-module
  4. 独立模块 crate 在 server-rs/crates/module-*
  5. 相关脚本在 server-rs/scripts/

4. 本条任务完成定义

当以下条件成立时,这一条边界任务视为完成:

  1. 新 Rust 后端目录名已经书面固定为 server-rs/
  2. 目录位置已经书面固定为仓库根目录
  3. 后续 M1 的工作区初始化不会再出现 server-rs/backend-rs/server/ 等多套候选名并存

5. 已确认决议二:迁移期保留 server-node/

5.1 决议内容

在本次重写迁移期内,旧 server-node/ 固定继续保留,不提前删除、不整体挪位、不提前做破坏性收缩。

保留周期固定为:

  1. M0M6 全阶段
  2. 至少持续到 M7 的以下条件全部满足之后,才允许评估清理:
    • 新后端已切流
    • 旧接口 contract 回归通过
    • 关键主链 smoke 通过
    • 已具备明确回退方案

5.2 保留它的原因

  1. server-node/ 是当前 96 条路由、6 个挂载面、12 个模块的真实对照实现。
  2. 前面已经冻结的路由矩阵、模块迁移清单、SSE 协议、静态资源前缀,都需要它作为回归对照源。
  3. 如果在 M1 ~ M6 提前删除旧实现,就会失去最可靠的回退锚点与 diff 基准。

5.3 迁移期允许做什么

迁移期内允许:

  1. server-rs/ 中逐步补等价实现。
  2. 在文档和 manifest 中继续引用 server-node/ 作为当前系统基线。
  3. 在必要时从 server-node/ 补测试样例、补协议对照、补回归夹具。

迁移期内不允许:

  1. 提前整体删除 server-node/
  2. server-node/ 改成只剩空壳目录
  3. 在还没切流前,把旧服务关键实现批量迁走导致无法对照

5.4 对后续任务的直接约束

从这一条决议开始,后续任务必须遵守:

  1. M1 搭建 server-rs/ 时,不改动 server-node/ 的存在性。
  2. M2 ~ M6 迁移功能时,旧 server-node/ 继续作为验收基线与回退锚点。
  3. 真正评估清理旧 Node 后端的动作,只能放到 M7 切流完成之后。

6. 已确认决议三:前端第一阶段只访问 Axum

6.1 决议内容

M0 ~ M6 迁移期内,前端访问新后端的唯一入口固定为 Axum。

第一阶段允许前端继续访问的面固定为:

  1. /api/*
  2. /healthz
  3. 当前已冻结的 SSE 路由
  4. 当前已冻结的 /generated-* 静态资源兼容前缀

第一阶段明确不做的事:

  1. 不让 Web 前端直接接 SpacetimeDB 原生 HTTP 接口。
  2. 不让 Web 前端直接接 SpacetimeDB 订阅协议。
  3. 不要求前端新增一套“Axum + SpacetimeDB 双后端并行直连”调用模式。

6.2 这样决议的原因

  1. 当前前端已经直接依赖现有 /api/* 路由、response envelope、SSE、/generated-* 路径习惯。
  2. 如果在第一阶段就让前端同时认识 Axum 与 SpacetimeDB会把迁移面从“后端平移”扩大成“前后端协议双重重写”。
  3. Axum 需要承担统一鉴权、cookie、JWT、OSS 签名、错误格式与 contract 兼容职责,这些都不应分散到前端直连多个后端协议。

6.3 对后续任务的直接约束

从这一条决议开始,后续任务必须遵守:

  1. M1 ~ M2 的 Axum 中间件与鉴权必须先跑通,再谈前端联调。
  2. M3 ~ M6 新增的 SpacetimeDB reducer/view 先通过 Axum facade 暴露,不直接要求前端改成原生 SpacetimeDB 客户端。
  3. 若后续要让前端直连 SpacetimeDB只能作为第二阶段优化事项不能混入当前重写主链。

7. 已确认决议四:外部副作用统一收口在 Axum

7.1 决议内容

本次重写固定采用以下边界:

  1. SpacetimeDB 只负责状态、规则、reducer、view、订阅读模型。
  2. Axum/application/infra 统一负责所有外部副作用。

固定收口到 Axum 的外部副作用包括:

  1. 阿里云 OSS 上传、下载、签名、直传凭证
  2. DashScope / Ark / 其他 LLM 请求
  3. 微信 OAuth
  4. 手机验证码短信发送与校验编排
  5. 本地文件系统读写

7.2 明确不允许放进 SpacetimeDB 的内容

以下能力当前明确禁止进入 spacetime-module/

  1. 直接发 HTTP 请求给第三方供应商
  2. 直接访问 OSS SDK
  3. 直接读写本地磁盘
  4. 直接处理 Cookie、回调跳转、multipart 上传
  5. 直接承担供应商重试、熔断、超时与日志策略

7.3 这样决议的原因

  1. 这些能力都强依赖 HTTP 头、Cookie、SDK、签名、超时与日志不适合绑进 SpacetimeDB 模块发布周期。
  2. 当前前端 contract、鉴权、SSE、静态资源兼容都要求一个稳定的 HTTP 边界层Axum 更适合承担这个角色。
  3. 把副作用统一收口到 Axum才能让 SpacetimeDB 保持“状态机真相源”的纯度。

7.4 对后续任务的直接约束

从这一条决议开始,后续任务必须遵守:

  1. M1 crate 设计时,platform-ossplatform-llmplatform-auth 固定属于 Axum / 模块应用层一侧。
  2. M2 ~ M6 设计 reducer 时,只写状态变更,不直接发外部请求。
  3. 若确实需要异步副作用,也必须由 Axum worker 或应用层作业执行,再把结果回写 SpacetimeDB。

8. 已确认决议五:server-rs/ 内部采用多 crate 组织

8.1 决议内容

从当前版本开始,server-rs/ 内部结构固定采用:

  1. crates/*:统一收口主工程 crate、独立模块 crate 与共享 crate
  2. scripts/*:开发、发布、回归脚本

主工程 crate 固定包含:

  1. crates/api-server
  2. crates/spacetime-module

独立模块 crate 固定按“每个独立模块一个 crate”推进至少覆盖

  1. crates/module-auth
  2. crates/module-runtime
  3. crates/module-story
  4. crates/module-combat
  5. crates/module-inventory
  6. crates/module-npc
  7. crates/module-progression
  8. crates/module-quest
  9. crates/module-runtime-item
  10. crates/module-custom-world
  11. crates/module-assets
  12. crates/module-ai

跨模块共享 crate 固定包含:

  1. crates/shared-contracts
  2. crates/shared-kernel
  3. crates/platform-auth
  4. crates/platform-oss
  5. crates/platform-llm
  6. crates/spacetime-client
  7. crates/tests-support

8.2 这样决议的原因

  1. 用户已经明确要求后端采用 Rust workspace 下的多 crate 模式,独立模块不能继续堆回单个技术层大包。
  2. 当前后端已有 12 个内部模块边界,多 crate 方案更容易保持一一映射与独立演进。
  3. crates/api-servercrates/spacetime-module 只做组合与发布,更符合“主工程 crate 引用模块 crate”的组织方式。

8.3 对后续任务的直接约束

从这一条决议开始,后续任务必须遵守:

  1. M1 及后续目录任务统一按 crates/* 执行,不再保留 apps/*packages/* 并行规划。
  2. 每个业务模块默认先有自己的 workspace crate再由主工程 crate 引用。
  3. 只有共享 contract、共享领域内核、平台适配、SpacetimeDB client 这类跨模块能力,才允许使用共享 crate而不是业务模块混装。

9. 已确认决议六:editor 退出本轮 Rust 重写范围

9.1 决议内容

editor 在当前 Node 后端中确实存在真实模块与真实挂载面,但已于 2026-04-21 被确认为遗留无用模块,不再纳入本轮 server-rs/ 重写主链。

当前固定口径为:

  1. 历史基线继续保留 server-node/src/modules/editor/api/editor/* 的存在事实。
  2. server-rs/ 不再保留 crates/module-editor
  3. M1 ~ M6 的主线任务、阶段验收与 crate 规划,不再把 editor 计入 active rewrite scope。

9.2 这样决议的原因

  1. 用户已明确确认 editor 为遗留无用模块,应从本轮重写目标中剔除。
  2. 保留历史事实有助于后续对照清理,不会把“旧系统曾存在该模块”的信息抹掉。
  3. 从当前阶段开始继续为 editor 预留 Rust crate只会增加主线迁移噪音与工程负担。

9.3 对后续任务的直接约束

从这一条决议开始,后续任务必须遵守:

  1. 不再为 editor 创建或维护 server-rs 下的新 crate、Axum 路由树与迁移验收项。
  2. 所有涉及挂载面、模块、路由总量的文档,都要区分“历史基线”与“本轮 active rewrite target”。
  3. 若未来仍要清理 editor,应在 server-node/ 遗留链路依赖核对完成后单独立项。