# Rust workspace 依赖集中配置记录 日期:`2026-05-07` ## 1. 背景 `server-rs` workspace 已经包含 `api-server`、`spacetime-module`、`spacetime-client`、多个 `module-*` 领域 crate、`platform-*` 适配 crate 和共享 crate。随着 DDD 收口推进,成员 `Cargo.toml` 中重复散写了第三方 crate 版本和本地 path 依赖,后续升级 `serde`、`reqwest`、`tokio`、`time`、SpacetimeDB SDK 或内部 crate 路径时容易出现漂移。 本次只做 Cargo 配置收敛,不改变业务代码、表结构、reducer/procedure 签名、HTTP contract 或前端绑定。 ## 2. 配置规则 1. 共享第三方依赖版本统一维护在 `server-rs/Cargo.toml` 的 `[workspace.dependencies]`。 2. workspace 内部 crate 的 `path` 也统一维护在根 `server-rs/Cargo.toml`。 3. 成员 crate 默认使用 `{ workspace = true }` 继承依赖。 4. 成员 crate 只保留自身需要表达的差异,例如 `features`、`optional = true` 或 target-specific dependency。 5. 需要关闭 default features 的依赖,应优先在 workspace 根依赖中声明;成员 crate 不再重复覆盖同一项。 6. `module-assets` 这类有默认服务端 feature 的领域 crate,在 workspace 根内按 `default-features = false` 维护;需要服务端 OSS/HTTP 能力的 adapter crate 显式启用 `features = ["server-service"]`。 7. `shared-contracts` 只能承载前后端公开 DTO 和轻量枚举,禁止直接依赖 `platform-*` 服务实现 crate;需要把平台实现响应转换为公开 DTO 时,转换函数放在 `api-server` 等 adapter 层。 8. 面向 SpacetimeDB WASM 的依赖链不得隐式启用原生 HTTP / OSS / Web 平台依赖;例如 `shared-contracts` 的 `assets` 模块通过不依赖 `platform-oss` 的 `oss-contracts` feature 暴露给 `api-server`,`spacetime-module` 路径只消费关闭默认 feature 后的纯 DTO 子集。 9. `spacetime-module` 的传递依赖不能包含 `reqwest`、`web-sys`、`js-sys`、`wasm-bindgen` 等 Web/HTTP 客户端链路;发布前可用 `cargo tree -i wasm-bindgen --manifest-path server-rs/Cargo.toml -p spacetime-module --target wasm32-unknown-unknown` 排查。 ## 3. 本次收敛范围 已上提到 workspace 根的依赖包括: 1. 本地路径依赖:`module-*`、`platform-*`、`shared-*`、`spacetime-client`。 2. 常用第三方依赖:`serde`、`serde_json`、`serde_urlencoded`、`reqwest`、`tokio`、`time`、`tracing`、`base64`、`hmac`、`sha2`、`uuid`、`url` 等。 3. SpacetimeDB 相关依赖:`spacetimedb`、`spacetimedb-sdk`、`spacetimedb-lib`。 `spacetimedb-lib` 在 workspace 根统一关闭 default features,`spacetime-module` 只继承并补充 `features = ["serde"]`。这样避免成员 crate 尝试覆盖 workspace default-feature 设定导致 manifest 解析失败。 阿里云 OSS 相关签名不再依赖不推荐的 `sha1` crate,统一使用 `sha2::Sha256`: 1. 浏览器直传 ticket 使用 OSS V4 表单签名字段:`x-oss-signature-version=OSS4-HMAC-SHA256`、`x-oss-credential`、`x-oss-date`、`x-oss-signature`。 2. 服务端 OSS 读写请求和测试辅助签名统一使用 `OSS4-HMAC-SHA256` Authorization。 3. 阿里云短信 OpenAPI 请求统一使用 `ACS3-HMAC-SHA256` 请求头签名,不再在表单中传旧 `SignatureMethod=HMAC-SHA1` / `SignatureVersion=1.0`。 ## 4. 不在本次范围 1. 不新增或删除 crate。 2. 不修改 `server-rs` workspace `members` / `default-members` 语义。 3. 不修改 SpacetimeDB 表、reducer、procedure、migration 白名单或生成绑定。 4. 不改变 `module-*` 的 DDD 依赖方向。 ## 5. 验收口径 配置改动后至少执行: ```powershell cargo metadata --manifest-path server-rs\Cargo.toml --format-version 1 --no-deps cargo check -p api-server --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/RUST_WORKSPACE_DEPENDENCY_CONSOLIDATION_2026-05-07.md docs/technical/README.md server-rs/README.md .hermes/shared-memory/decision-log.md .hermes/shared-memory/project-overview.md ``` 若仅改 Cargo 依赖配置且未触碰 API smoke 相关代码,不强制启动 `npm run api-server`;若后续改动同时涉及 API 路由、SpacetimeDB facade 或运行时行为,仍按 `AGENTS.md` 和 DDD 文档执行后端 smoke。 ## 6. SpacetimeDB WASM 依赖边界 2026-05-11 本地重置 SpacetimeDB 并重新发布 `xushi-p4wfr` 时,`spacetime publish` 在 Rust 编译成功后报 `wasm-bindgen detected`。排查命令显示链路为: ```text spacetime-module -> module-runtime -> shared-contracts -> platform-oss -> reqwest -> wasm-bindgen ``` 根因是 `shared-contracts` 为了复用 OSS 直传/读签名返回类型,直接依赖了 `platform-oss`。这违反 DDD 分层边界:契约 crate 不能依赖平台副作用实现,否则所有引用契约的纯领域和 SpacetimeDB 模块都会被迫拉入 HTTP client。 `spacetime publish` 会构建 `spacetime-module` 的 `wasm32-unknown-unknown` 目标。这个目标不能包含 `wasm-bindgen`,也不应通过 DTO crate 间接拉入 `reqwest`、`web-sys` 或浏览器 WebAssembly 平台依赖。 修正口径: 1. `shared-contracts::assets` 定义独立的公开 DTO 和 `DirectUploadObjectAccess` 轻量枚举。 2. `platform-oss` 保持 OSS 签名、读写请求和错误分类实现,不被契约层引用。 3. `api-server::assets` 负责把 `platform_oss::OssPostObjectResponse` / `OssSignedGetObjectUrlResponse` 转成 `shared-contracts` DTO。 4. 后续新增外部平台能力时,重复使用这个边界:平台 crate 不得被 `shared-contracts`、`module-*` 或 `spacetime-module` 反向依赖。 已验证的排查命令: ```powershell cargo tree -i wasm-bindgen --manifest-path server-rs\Cargo.toml -p spacetime-module --target wasm32-unknown-unknown cargo tree -i wasm-bindgen --manifest-path server-rs\crates\spacetime-module\Cargo.toml --target wasm32-unknown-unknown cargo tree --manifest-path server-rs\crates\spacetime-module\Cargo.toml --target wasm32-unknown-unknown | Select-String -Pattern 'wasm-bindgen|platform-oss|reqwest' cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml --target wasm32-unknown-unknown cargo check -p shared-contracts --manifest-path server-rs\Cargo.toml cargo check -p api-server --manifest-path server-rs\Cargo.toml spacetime publish xushi-p4wfr --server local --module-path server-rs\crates\spacetime-module --build-options="--debug" -c=on-conflict --yes ``` 若反向树显示 `reqwest -> platform-oss -> shared-contracts -> module-* -> spacetime-module`,优先检查新增的 `shared-contracts` 或领域 crate 依赖是否忘记关闭默认 feature,或 `shared-contracts` feature 是否错误依赖了平台实现 crate。原生 `api-server` 需要资产上传契约时,应在自身 `Cargo.toml` 显式启用 `shared-contracts` 的 `oss-contracts` feature,而不是让 workspace 根依赖默认启用。