Files
Genarrative/docs/technical/SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md

25 KiB
Raw Blame History

基于 SpacetimeDB + Axum + 阿里云 OSS 的后端重写设计文档

日期:2026-04-20

1. 文档定位

这份文档不是继续扩写当前 server-node/ 的实现细节,而是基于当前仓库已经落地的后端能力,为下一版 Rust 后端提供一份可以直接落地编码的重写设计。

目标很明确:

  1. 保留当前项目已经具备的后端能力面,不做需求缩水。
  2. 把后端实现从 Express + PostgreSQL + 本地 public/generated-* 文件 重写为:
    • Axum:唯一 HTTP 边界层与流式接口层
    • SpacetimeDB:唯一运行时状态与实时订阅真相源
    • 阿里云 OSS:唯一大文件与二进制资产存储
  3. 让前端在第一阶段尽量少改,优先兼容当前 /api/*/healthz、SSE 与资源路径习惯。

2. 当前工程必须继承的能力基线

docs/technical/NODE_BACKEND_MODULE_AND_API_INDEX.md 当前生成结果为准,现有 Node 后端的能力基线是:

  • 对外挂载面:6
  • 已登记路由:96
  • 内部模块目录:12
  • 公开接口:10
  • JWT 接口:69
  • 环境开关接口:17
  • 流式接口:6

重写后的 Rust 后端,第一阶段必须至少完整覆盖这 6 个挂载面:

  1. health
  2. auth
  3. editor
  4. assets
  5. runtime-main
  6. runtime-story-action

当前后端内部模块也不能“凭感觉重设计”,而要按现有职责做映射:

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

3. 技术选型后的硬边界

3.1 SpacetimeDB 的平台约束与本项目边界

根据 SpacetimeDB 官方 Rust crate 文档,reducer 不能直接使用 std::netstd::fs 进行外部 IO而 2.0 官方文档又提供了 procedure + ctx.http 的受控 HTTP 能力。
也就是说,平台层面并不是完全不能做外部调用,但对于本项目这次重写,我们仍然主动把下面这些副作用统一放到 Axum而不是塞进 SpacetimeDB

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

这样设计不是因为“SpacetimeDB 绝对做不到”,而是因为这类能力都要求:

  1. 更强的重试、超时、日志和熔断能力
  2. 更自由的 SDK / multipart / 签名上传实现
  3. 与 HTTP 头、cookie、回调、对象存储策略深度耦合
  4. 与游戏状态 schema 解耦,避免把第三方供应商能力直接绑进数据库模块发布周期

结论:

  • SpacetimeDB 负责状态、规则、订阅、命令执行与读模型。
  • Axum 负责所有外部副作用与 HTTP 协议。
  • 在本次重写中,不为 SpacetimeDB module 增加任何外部副作用例外通道。

3.2 Axum 的边界

根据 Axum 官方文档,Router<S> 通过 .with_state(...) 注入共享状态后才成为可真正 serve() 的路由树;因此 Axum 适合作为:

  1. 统一 HTTP 入口
  2. Bearer / Cookie 鉴权入口
  3. SSE 输出入口
  4. OSS 上传凭证签发入口
  5. 与 SpacetimeDB 的应用层编排入口

结论:

  • Axum 是唯一 BFF / API Gateway。
  • 前端第一阶段仍然只认识 Axum不直接依赖 SpacetimeDB 原生接口。
  • M0 ~ M6 迁移期内,不新增前端直连 SpacetimeDB 的主链方案。

3.3 OSS 的边界

根据阿里云 OSS 官方文档:

  1. PostObject 适合浏览器表单直传,服务端可以下发 policysignature 与上传条件。
  2. STS 临时访问凭证适合把上传权限以有限时、有限范围的方式下发给客户端。
  3. PutObject / PostObject 都支持 x-oss-meta-* 元数据与标签。

结论:

  • 所有图片、动画、精灵表、场景图、封面图、视频参考素材都存 OSS。
  • SpacetimeDB 只存对象键、版本、尺寸、状态、逻辑元数据,不存二进制。
  • Axum 负责下发直传凭证、校验上传结果、补写元数据。

4. 目标总体架构

Web / Mobile Frontend
├─ 继续访问 /api/*、/healthz、/generated-*
└─ 第一阶段不直接依赖 SpacetimeDB 原生协议

Axum API Server
├─ auth登录、refresh cookie、JWT/OIDC 签发
├─ runtime facade兼容当前 REST / SSE contract
├─ asset gatewayOSS 直传签名、对象确认、媒体任务编排
├─ ai gatewayDashScope / Ark / 其他模型调用
├─ editor gateway开发态文件读写或对象化编辑能力
├─ background workers异步作业执行与回写
└─ SpacetimeDB client调用 reducer、查询 view / public table、订阅任务状态

SpacetimeDB Module
├─ auth tables用户、身份、session、风控、审计
├─ runtime tables存档、设置、浏览历史、个人面板
├─ gameplay tablesstory / npc / quest / inventory / combat / progression
├─ custom-world tables问答会话、agent 会话、草稿卡、操作记录
├─ asset metadata tables生成任务、对象清单、引用关系
├─ reducers唯一状态写入口
└─ views / public tables唯一读模型与订阅面

Aliyun OSS
├─ generated-character-drafts
├─ generated-characters
├─ generated-animations
├─ generated-custom-world-scenes
├─ generated-custom-world-covers
├─ generated-qwen-sprites
└─ editor-exports / temp-uploads / workflow-cache

5. 重写后的核心原则

5.1 先兼容当前 API 面,再逐步让前端吃到实时能力

第一阶段不要强推前端直接改成 SpacetimeDB 客户端模式,而是:

  1. Axum 保持当前 /api/* 路由空间。
  2. Axum 保持当前 x-request-id / x-api-version / x-route-version 头和响应 envelope。
  3. Axum 保持当前 story / custom-world-agent 的 SSE 体验。
  4. SpacetimeDB 先做后端内部真相源。

第二阶段再按模块把只读页改成直接订阅 SpacetimeDB。

5.2 命令与读模型分离

SpacetimeDB 官方文档明确说明:

  1. reducer 是唯一可修改表的入口。
  2. reducer 不直接返回业务数据给客户端。
  3. view 可被查询与订阅,并会随底层表变化自动更新。

因此本项目必须采用:

  • Reducer = 命令入口
  • View / Public Table = 读模型入口
  • Axum = HTTP 兼容层与聚合层

5.3 大对象不进数据库

当前 Node 后端把生成结果落在 public/generated-*。重写后统一改成:

  • OSS 存二进制
  • SpacetimeDB 存引用和状态
  • Axum 输出 URL、签名 URL 或 CDN URL

5.4 Schema 必须按 SpacetimeDB 的迁移约束设计

SpacetimeDB 官方文档对自动迁移的限制很强:

  1. 删表、改列类型、改列名、调整列顺序都不是安全日常操作。
  2. 新列只能追加到表末尾,且要提供默认值。
  3. reducer 改名或删除会直接影响客户端调用。

因此本项目的数据模型必须尽量满足:

  1. 主表稳定、字段追加式演进
  2. 高频变化数据优先事件表化
  3. 聚合结果优先投影表 / view而不是频繁重塑旧表结构

6. 推荐工程结构

本次重写固定在仓库根目录新增 Rust 工作区 server-rs/,并与 server-node/ 同级:

server-rs/
├─ Cargo.toml
├─ crates/
│  ├─ api-server/                # Axum 入口
│  ├─ spacetime-module/          # SpacetimeDB Rust 模块(编译为 wasm
│  ├─ application/               # 用例编排层
│  ├─ domain/                    # 纯领域类型、枚举、ID、值对象
│  ├─ contracts/                 # HTTP DTO / SSE event / 内部 command DTO
│  ├─ auth-service/              # JWT、cookie、provider adapter
│  ├─ oss-service/               # OSS 直传、签名、对象管理
│  ├─ llm-service/               # DashScope / Ark / 其他模型适配
│  ├─ spacetime-client/          # 生成 bindings 后的 DB client adapter
│  └─ tests/                     # 集成测试、contract 测试、smoke
└─ scripts/
   ├─ dev.sh / dev.ps1
   ├─ spacetime-publish.sh
   └─ smoke.sh

目录职责约束:

  1. spacetime-module/ 只能写纯状态逻辑,不写网络 / 文件系统。
  2. api-server/ 只做协议装配、鉴权、中间件、handler。
  3. application/ 编排 Axum、OSS、LLM、SpacetimeDB 之间的流程。
  4. domain/ 只放纯数据结构和规则,不碰框架。
  5. contracts/ 负责与当前前端兼容的 JSON / SSE 协议。

7. 目标模块映射

当前模块 重写后主归属 次归属 说明
auth Axum auth-service + SpacetimeDB private tables 登录入口、refresh cookie、JWT/OIDC、审计与风控拆为“Axum 处理副作用 + SpacetimeDB 落状态”。
runtime SpacetimeDB module Axum facade 存档、设置、浏览历史、profile dashboard 统一进入 SpacetimeDB。
story SpacetimeDB module Axum SSE facade story action、状态推进、可选项构造、恢复态读取以后端 reducer/view 为准。
combat SpacetimeDB module 纯规则计算,天然适合 reducer。
inventory SpacetimeDB module 背包、赠礼、交易、物品副作用全部 reducer 化。
npc SpacetimeDB module Axum for LLM dialogue 关系、招募、状态机在 SpacetimeDBLLM 台词生成留在 Axum。
progression SpacetimeDB module 关卡、等级、敌对 scaling、章节推进都做领域表和 reducer。
quest SpacetimeDB module Axum for AI quest drafting 任务主状态在 SpacetimeDB生成型内容由 Axum 生产后回写。
runtime-item SpacetimeDB module Axum for AI intent 物品奖励和解析归 reducerAI 意图生成由 Axum 负责。
custom-world SpacetimeDB module + Axum orchestration OSS 会话、草稿、agent 状态放 SpacetimeDB世界编译、资产生成、发布编排在 Axum。
ai Axum llm-service SpacetimeDB task tables 外部模型调用全部放 Axum。
assets Axum oss-service SpacetimeDB asset metadata 二进制进 OSS元数据进 SpacetimeDB。
editor Axum editor namespace OSS / local fs 开发态保留本地文件适配,线上默认走对象化资源。

8. 数据建模方案

8.1 表的分层

建议在 SpacetimeDB 中至少拆成 5 组表:

A. 身份与会话表

  • user_account
  • auth_identity
  • refresh_session
  • auth_audit_log
  • auth_risk_block
  • sms_auth_event
  • wechat_auth_state

说明:

  1. 这些表默认都应为 private。
  2. 密码哈希、短信验证码校验、微信 code 换 token 的动作在 Axum 完成。
  3. Axum 再调用 reducer 写入最终结果。

B. 运行时主状态表

  • runtime_snapshot
  • runtime_setting
  • profile_dashboard_state
  • profile_wallet_ledger
  • profile_played_world
  • profile_save_archive
  • user_browse_history

说明:

  1. runtime_snapshot 继续作为“恢复游戏”的主聚合表。
  2. profile_* 作为只读页投影表,避免每次从大快照现算。
  3. browse_historysave_archive 单独建表,不要藏进 snapshot blob。

C. Gameplay 领域表

  • story_session
  • story_event
  • npc_state
  • quest_record
  • inventory_slot
  • treasure_record
  • battle_state
  • player_progression
  • chapter_progression

说明:

  1. story_action 不直接改大 JSON而是 reducer 驱动多个领域表。
  2. 是否继续保留兼容快照,可由投影 reducer 汇总生成。
  3. 旧前端仍需要 gameState + currentStory 时,由 Axum 聚合成兼容 DTO。

D. Custom World 表

  • custom_world_profile
  • custom_world_session
  • custom_world_agent_session
  • custom_world_agent_message
  • custom_world_agent_operation
  • custom_world_draft_card
  • custom_world_asset_link
  • custom_world_gallery_entry

说明:

  1. 传统问答流与 Agent 流不再混一个 payload。
  2. 卡片、操作、消息必须拆表,不能再都塞进一个大 JSON 会话体。
  3. 公开画廊作为独立投影,避免从 profile 运行时拼装。

E. 资产与对象元数据表

  • asset_job
  • asset_object
  • asset_manifest
  • character_visual_asset
  • character_animation_asset
  • scene_image_asset
  • sprite_sheet_asset

说明:

  1. 任务状态在 SpacetimeDB。
  2. 二进制对象在 OSS。
  3. 所有业务实体只引用 asset_object_key / cdn_url / version / hash

8.2 public / private 原则

依据 SpacetimeDB 官方访问权限文档:

  1. private table 默认只给 reducer / view / owner 看。
  2. public table 才适合直接查询和订阅。

本项目建议:

  • auth_*refresh_session、风控、验证码全部 private
  • runtime_snapshot private
  • story_session private
  • custom_world_agent_* 绝大多数 private
  • gallery、公共角色卡、公共作品索引可 public
  • 如需“用户自己的读模型”,优先用 ViewContext view 暴露

8.3 view 设计原则

依据 SpacetimeDB 官方 view 文档:

  1. view 可以被查询和订阅,底层表变化时会自动更新。
  2. AnonymousViewContext 可被所有用户共享物化结果,性能明显优于按用户单独计算。
  3. view 不适合全表 .iter() 扫描,应该通过索引查找或返回可分析的 query。

所以本项目的 view 设计规则必须是:

  1. 画廊、排行榜、商店、公共世界列表,优先匿名 view。
  2. “我的背包 / 我的档案 / 我的当前会话”这类按用户隔离的读模型,才用带身份上下文的 view。
  3. 首页、资料库、历史记录、存档列表都必须先有索引,再写 view。

9. 鉴权设计

9.1 总体方案

建议保留当前“密码 / 手机验证码 / 微信”三类登录能力,但把实现改成:

  1. Axum 负责登录副作用:
    • 密码校验
    • 短信发送与校验
    • 微信 OAuth code 交换
    • refresh cookie 签发与轮换
  2. Axum 负责签发OIDC 兼容 JWT
  3. 同一张 JWT 同时用于:
    • Axum 自身 Bearer 鉴权
    • SpacetimeDB reducer / view 的身份透传

这是可行的,因为 SpacetimeDB 官方文档说明其可以从 OIDC 兼容 JWT 中提取身份声明,并在模块上下文中使用这些 claims。

9.2 Token 设计

建议:

  • iss:固定为 Axum 网关身份发行者,例如 https://api.genarrative.example/auth
  • sub:稳定用户 ID
  • 扩展 claims
    • sidsession id
    • providerpassword / phone / wechat
    • roles
    • phone_verified
    • display_name

9.3 Refresh Session

建议保留当前模式:

  1. 浏览器短期 Bearer access token
  2. HttpOnly refresh cookie
  3. refresh session 服务端可吊销

但新的会话 ledger 写入 SpacetimeDB private 表即可。

10. Axum 侧设计

10.1 进程职责

Axum 进程建议拆成以下子系统:

  1. http::middleware
    • request id
    • tracing
    • envelope / 错误标准化
    • auth extractor
  2. http::routes
    • /healthz
    • /api/auth/*
    • /api/runtime/*
    • /api/runtime/story/*
    • /api/assets/*
    • /api/editor/*
  3. application::services
    • story facade
    • runtime snapshot facade
    • custom world facade
    • asset facade
  4. infra
    • SpacetimeDB client
    • OSS adapter
    • DashScope / Ark adapter
    • SMS / WeChat adapter

10.2 流式接口

当前项目已经有 6 条流式接口,重写时不建议一上来全部改成 WebSocket。

第一阶段建议:

  1. 继续使用 Axum SSE 输出流式文本与阶段事件。
  2. Axum 在处理流式过程中,持续把阶段状态写回 SpacetimeDB。
  3. 前端仍按当前 SSE 协议消费。

适合继续保留为 Axum SSE 的场景:

  1. story/initial
  2. story/continue
  3. chat/character/*
  4. chat/npc/*
  5. custom-world/generate/stream
  6. custom-world/agent/messages/stream

10.3 兼容 contract

Axum 第一阶段需要兼容当前项目的这些约定:

  1. 路径空间不变
  2. x-request-id
  3. x-api-version
  4. x-route-version
  5. x-response-time-ms
  6. 可选 envelopex-genarrative-response-envelope

这样前端可以在不大改 src/services/* 的前提下切换后端实现。

11. OSS 设计

11.1 对象键规划

建议统一对象键前缀,保持与当前前端路径习惯接近:

generated-character-drafts/{character_id}/{job_id}/{file}
generated-characters/{character_id}/visual/{asset_id}/{file}
generated-animations/{character_id}/{animation_set_id}/{action}/{file}
generated-custom-world-scenes/{profile_id}/{landmark_id}/{asset_id}/{file}
generated-qwen-sprites/{role_id}/{sheet_id}/{file}
generated-custom-world-covers/{profile_id}/{asset_id}/{file}
editor-cache/{resource_type}/{resource_id}/{file}
workflow-cache/{workflow_type}/{workflow_id}.json

11.2 上传模式

建议:

  1. 前端直传图片、封面、小文件:PostObject
  2. 大文件或需要细粒度控制时:STS + PutObject / Multipart
  3. 生成型资产Axum worker 直接上传 OSS

其中:

  • PostObject 用于浏览器上传时Axum 负责生成 policy 与 signature。
  • policy 中必须明确:
    • key 前缀
    • content-type 白名单
    • content-length-range
    • success_action_status

11.3 元数据与标签

建议所有业务对象写入统一元数据:

  • x-oss-meta-owner-user-id
  • x-oss-meta-profile-id
  • x-oss-meta-entity-id
  • x-oss-meta-asset-kind
  • x-oss-meta-source-job-id
  • x-oss-meta-content-hash
  • x-oss-meta-origin

注意:

  1. OSS 官方文档要求自定义元数据使用 x-oss-meta-* 前缀。
  2. 所有元数据总大小不能超过 8 KB

11.4 URL 策略

建议:

  1. 业务表里统一存 object_key
  2. 对外输出 cdn_url
  3. 私有对象额外输出短期签名 URL

为了兼容当前前端相对路径使用习惯,第一阶段可以让 Axum 或 CDN 兼容以下历史前缀:

  1. /generated-character-drafts/*
  2. /generated-characters/*
  3. /generated-animations/*
  4. /generated-custom-world-scenes/*
  5. /generated-custom-world-covers/*
  6. /generated-qwen-sprites/*

12. 关键业务流设计

12.1 Story Action

目标:

  1. storyActionService 当前承担的跨模块结算必须迁到 SpacetimeDB reducer。
  2. Axum 只做 request parse、auth、调用 reducer、读取 view、拼回当前前端响应。

推荐流程:

  1. 前端 POST /api/runtime/story/actions/resolve
  2. Axum 校验请求并附带 JWT
  3. Axum 调用 SpacetimeDB resolve_story_action reducer
  4. reducer 内部联动:
    • story
    • combat
    • inventory
    • npc
    • quest
    • runtime-item
    • progression
  5. reducer 写回领域表
  6. Axum 再读取 current_story_viewruntime_snapshot_view
  7. Axum 返回兼容当前前端的 RuntimeStoryActionResponse

12.2 存档与恢复

目标:

  1. 仍保留当前“完整恢复游戏”的能力。
  2. 但底层不再由 PostgreSQL 单大 JSON 承担全部职责。

建议:

  1. runtime_snapshot 继续保留兼容聚合快照,满足现有恢复链路。
  2. gameplay 真相由领域表维护。
  3. 每次重要 reducer 提交后,异步或同步刷新 snapshot projection。

这样可以兼顾:

  1. 旧前端兼容
  2. 新后端可审计
  3. SpacetimeDB 实时订阅能力

12.3 Custom World Agent

当前 Node 后端中,customWorldAgentOrchestrator + SessionStore + Operation 已经是一条清晰主链。
重写后建议进一步正规化:

  1. SpacetimeDB
    • 存会话
    • 存消息
    • 存卡片
    • 存操作状态
    • 存草稿 profile
  2. Axum
    • 调 LLM
    • 调图片生成
    • 调 OSS
    • 发 SSE
    • 把阶段结果回写 reducer

不再允许“一整个 agent 会话对象 JSON 一把写回”作为长期形态。

12.4 资产生成

资产链路拆成四步:

  1. Axum 创建 asset_job
  2. Axum worker 调外部模型
  3. 产物上传 OSSasset_object
  4. Axum 调 reducer 将对象绑定到:
    • 角色
    • 地点
    • 世界草稿
    • Qwen sprite sheet

所有“对象是否已经被业务引用”的事实,以 SpacetimeDB 绑定表为准,而不是以 OSS 是否存在某个 key 为准。

13. 迁移阶段建议

迁移期仓库边界补充约束:

  1. server-node/M0 ~ M6 期间继续保留,作为协议对照、回归基线与回退锚点。
  2. 只有在 M7 切流、回归、回退方案都稳定后,才评估是否清理旧 Node 后端。

Phase 0冻结能力清单

交付:

  1. 固定当前 96 条接口为重写验收基线
  2. 固定当前 12 个模块为迁移映射基线
  3. 固定当前前端 contract 与 SSE 协议

Phase 1先搭 Axum 外壳与鉴权

交付:

  1. /healthz
  2. /api/auth/*
  3. response envelope
  4. request id / tracing
  5. Axum -> SpacetimeDB 基础 client
  6. OIDC-compatible JWT 签发

Phase 2迁移 runtime snapshot / settings / profile

交付:

  1. 存档
  2. 设置
  3. 浏览历史
  4. profile dashboard
  5. save archives

这是最容易先跑通的闭环。

Phase 3迁移 story action 主循环

交付:

  1. story reducer
  2. combat / inventory / npc / quest / runtime-item / progression 联动
  3. /api/runtime/story/*

这一阶段完成后,运行时真相就真正从 Node 版切出去了。

Phase 4迁移 custom world 与 agent

交付:

  1. legacy custom world session
  2. custom world library / gallery
  3. custom world agent 会话、卡片、操作
  4. scene npc / entity generation

Phase 5迁移 assets / editor

交付:

  1. OSS 直传
  2. 生成任务
  3. 对象元数据
  4. 编辑器读写开发态适配
  5. /generated-* 路径兼容

14. 验收标准

重写完成至少要满足:

  1. 当前 96 条已登记路由全部有对应实现或明确兼容替代。
  2. 当前 6 个挂载面全部保留。
  3. 浏览器无需直接知道 SpacetimeDB 原生接口即可跑通主流程。
  4. story action、存档、custom world、agent、assets 都以后端为唯一真相。
  5. 所有生成图片、动画、精灵表都不再依赖本地 public/generated-* 持久化。
  6. Axum 和 SpacetimeDB 的职责边界稳定,不把外部网络 IO 偷放进 module。

15. 关键风险

15.1 不能把 SpacetimeDB 当 PostgreSQL 替身直接套

SpacetimeDB 更像“带强实时订阅能力的状态机数据库”,不是传统 SQL 仓储替身。
如果仍沿用“单大 JSON + 巨型路由文件 + 过程式 handler”思路重写后仍然会很快回到旧热点。

15.2 schema 演进成本高于 PostgreSQL

SpacetimeDB 自动迁移更适合“增量追加”,不适合高频改列结构。
所以必须提前定好:

  1. 稳定主键
  2. 稳定 reducer 命名
  3. 事件表 / 投影表边界

15.3 view 滥用会造成性能问题

如果把资料库、画廊、排行榜写成按用户逐个计算、又缺索引的 view性能会很差。
因此 read model 必须先建索引,再决定用匿名 view 还是按用户 view。

15.4 资产路径兼容是迁移成败关键

当前前端大量相对路径、角色图、场景图、动画图都是围绕 /generated-* 组织的。
如果不先做路径兼容层,存档恢复和世界资料库会大面积失效。

16. 内部实现依据

这份设计稿对当前工程的判断,主要依据以下仓库现状:

  1. server-node/src/server.ts
  2. server-node/src/app.ts
  3. server-node/src/routes/authRoutes.ts
  4. server-node/src/routes/runtimeRoutes.ts
  5. server-node/src/modules/story/storyActionRoutes.ts
  6. server-node/src/repositories/runtimeRepository.ts
  7. server-node/src/services/customWorldAgentOrchestrator.ts
  8. docs/technical/NODE_BACKEND_MODULE_AND_API_INDEX.md
  9. docs/technical/NODE_SERVER_KNOWLEDGE_GRAPH_2026-04-08.md

17. 外部技术依据

以下外部依据用于确定本次新架构的技术边界,均来自官方文档或官方 crate 文档:

  1. SpacetimeDB Tables
  2. SpacetimeDB Table Access Permissions
  3. SpacetimeDB Reducers Overview
  4. SpacetimeDB Views
  5. SpacetimeDB Authorization
  6. SpacetimeDB Authentication
  7. SpacetimeDB Using Auth Claims
  8. SpacetimeDB Rust crate docs
  9. SpacetimeDB Rust Client SDK
  10. Axum crate docs
  11. Axum SSE
  12. 阿里云 OSS 服务端签名表单上传
  13. 阿里云 OSS STS 临时授权访问
  14. 阿里云 OSS PutObject
  15. 阿里云 OSS PostObject

18. 一句话结论

这次重写最正确的落点不是“把 Express 改成 Axum”而是

让 Axum 成为唯一外部副作用和 HTTP 边界,让 SpacetimeDB 成为唯一状态机真相源,让 OSS 成为唯一资产对象仓,从而在不丢当前 96 条能力面的前提下,把项目升级成真正可持续扩展的 Rust 后端。