Add SpacetimeDB schema guard
This commit is contained in:
@@ -159,6 +159,8 @@ npm run check:server-rs-ddd
|
||||
- 检查 `/healthz`。
|
||||
- 执行对应自动测试。
|
||||
- 涉及 SpacetimeDB 表、reducer、procedure、row shape 或绑定变化时,同步更新 `migration.rs`、表目录和生成绑定。
|
||||
- SpacetimeDB 已有表新增字段必须放在 Rust 表结构体最后,并设置明确默认值;需要修改字段名时,先询问用户并确认迁移计划,再同步更新 `server-rs/crates/spacetime-module/src/migration.rs`、表目录和生成绑定。
|
||||
- 修改 SpacetimeDB schema 后运行 `npm run check:spacetime-schema`,用自动检查拦截缺 default、插入中间、字段删除/改名/重排/改类型,以及漏改迁移、表目录或绑定。
|
||||
|
||||
关键文档:
|
||||
|
||||
|
||||
@@ -250,8 +250,8 @@
|
||||
|
||||
- 现象:发布时 schema 冲突、自动迁移拒绝、旧客户端调用 reducer 失败、private 表数据迁移遗漏。
|
||||
- 原因:SpacetimeDB 对字段删除、类型变化、索引/主键/RLS/reducer 变化有不同自动迁移边界。
|
||||
- 处理:变更前阅读 `SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md`;涉及表变化时同步 `migration.rs`、`SPACETIMEDB_TABLE_CATALOG.md` 和 bindings;必要时走 JSON 导入导出与分片导入迁移流程。
|
||||
- 验证:发布前完成 schema 检查、bindings 生成、表目录更新和相关 smoke。
|
||||
- 处理:变更前阅读 `SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md`;已有表新增字段必须放在 Rust 表结构体最后并设置明确默认值;需要修改字段名时,先询问用户并确认迁移计划;涉及表变化时同步 `migration.rs`、`SPACETIMEDB_TABLE_CATALOG.md` 和 bindings;必要时走 JSON 导入导出与分片导入迁移流程。
|
||||
- 验证:发布前运行 `npm run check:spacetime-schema`,完成 schema 检查、bindings 生成、表目录更新和相关 smoke。
|
||||
- 关联:`docs/technical/SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.md`、`docs/technical/SPACETIMEDB_TABLE_CATALOG.md`。
|
||||
|
||||
## SpacetimeDB publish 报 wasm-bindgen 时先查 shared-contracts feature
|
||||
|
||||
@@ -50,6 +50,8 @@ Single-context layout: read root `CONTEXT.md` when present and architecture deci
|
||||
- 后端最新技术约束以 [`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`、表目录和生成绑定。
|
||||
- SpacetimeDB 已有表新增字段时,字段必须放在 Rust 表结构体最后,并设置明确默认值(例如 `#[default(...)]`);需要修改字段名时,必须先询问用户并确认迁移计划,再改代码,同时更新 `server-rs/crates/spacetime-module/src/migration.rs`、表目录和生成绑定。
|
||||
- 修改 SpacetimeDB schema 后必须运行 `npm run check:spacetime-schema`;该检查会拦截新增字段缺 default、字段不在末尾、字段删除/改名/重排/改类型,以及漏改 `migration.rs`、表目录或生成绑定。
|
||||
- 后端路线固定为 `server-rs + Axum + SpacetimeDB`。旧 `server-node`、Express、PostgreSQL 不再作为兼容目标;历史实现只能作为迁移参考,若旧文档与 DDD 约束冲突,先修正文档和方案再编码。
|
||||
- DDD 分层边界按总纲执行:领域规则沉到 `module-*`,SpacetimeDB 表和事务编排留在 `spacetime-module`,后端访问 SpacetimeDB 统一经 `spacetime-client` facade,HTTP/SSE/BFF 留在 `api-server`,外部副作用留在 `platform-*`,前后端 DTO 留在 `shared-contracts`。
|
||||
- 前端只做表现、交互和临时 UI 状态,不承接正式业务真相,不绕过后端投影或后端 API 直接实现业务规则。
|
||||
|
||||
@@ -58,6 +58,14 @@ host 会比较新模块声明的 schema 和旧数据库 schema,然后尝试自
|
||||
4. 等数据迁移完成、旧客户端完成升级、旧表数据清空后,再移除旧表。
|
||||
5. 开发环境可以使用 `--delete-data` 重建数据库,生产环境不要用它作为数据迁移方案。
|
||||
|
||||
## 字段级硬性约束
|
||||
|
||||
- 对已有 SpacetimeDB 表新增字段时,必须把新字段追加在 Rust 表结构体的最后,不能插入已有字段中间。
|
||||
- 新增字段必须设置明确默认值,例如 Rust `#[default(...)]`;复杂集合默认值如果无法作为编译期常量表达,应优先使用 `Option<T>` 加 `#[default(None::<T>)]`,并在业务层归一化。
|
||||
- 修改已有字段名属于高风险 schema 变更。编码前必须先询问用户,确认旧字段名、新字段名、数据保留方式、客户端兼容窗口和发布顺序,并让用户准备或确认迁移计划。
|
||||
- 字段改名或任何 row shape 迁移都必须同步更新 `server-rs/crates/spacetime-module/src/migration.rs`、`SPACETIMEDB_TABLE_CATALOG.md` 和生成绑定;不要只改表结构体。
|
||||
- 修改 SpacetimeDB schema 后必须运行 `npm run check:spacetime-schema`。该检查会对比当前工作区与基准分支的 Rust table 字段,自动拦截新增字段缺 default、字段插入中间、字段删除/改名/重排/改类型,以及漏改 `migration.rs`、表目录或生成绑定。
|
||||
|
||||
## 通常安全的变更
|
||||
|
||||
这些变更一般可以自动迁移,并且通常不会破坏现有客户端:
|
||||
@@ -223,6 +231,8 @@ fn migrate_character_batch(ctx: &ReducerContext, limit: u32) {
|
||||
|
||||
- 是否删除、改名、重排或修改了已有列。
|
||||
- 新增列是否位于表定义末尾,并且是否有 default value。
|
||||
- 如需改字段名,是否已先询问用户并确认迁移计划,且已同步更新 `migration.rs`。
|
||||
- 是否已运行 `npm run check:spacetime-schema` 并通过。
|
||||
- 是否给已有表新增了 unique 或 primary key 约束。
|
||||
- 是否删除了非空表。
|
||||
- 是否修改了 event table、schedule table、RLS 或 view。
|
||||
|
||||
+3
-2
@@ -23,17 +23,18 @@
|
||||
"preview": "node scripts/vite-cli.mjs preview",
|
||||
"clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
|
||||
"check:encoding": "node scripts/check-encoding.mjs",
|
||||
"check:spacetime-schema": "node scripts/check-spacetime-schema-guard.mjs",
|
||||
"assets:child-motion-demo": "node scripts/generate-child-motion-demo-assets.mjs",
|
||||
"assets:match3d-style-references": "node scripts/generate-match3d-style-references.mjs",
|
||||
"check:visual-novel-vn11": "node scripts/check-visual-novel-vn11-negative-scan.mjs",
|
||||
"check:visual-novel-vn12": "node scripts/check-visual-novel-vn12-acceptance.mjs",
|
||||
"check:wechat-miniprogram-auth": "node scripts/check-wechat-miniprogram-auth-smoke.mjs",
|
||||
"check:server-rs-ddd": "node scripts/check-server-rs-ddd-boundaries.mjs",
|
||||
"check:server-rs-ddd": "npm run check:spacetime-schema && node scripts/check-server-rs-ddd-boundaries.mjs",
|
||||
"lint:eslint": "eslint . --ext .ts,.tsx,.js,.mjs,.cjs --max-warnings 0",
|
||||
"lint:guardrails": "npm run lint:eslint",
|
||||
"typecheck": "tsc -p tsconfig.typecheck-guardrails.json --noEmit",
|
||||
"typecheck:guardrails": "npm run typecheck",
|
||||
"lint": "npm run check:encoding && npm run lint:eslint && npm run typecheck",
|
||||
"lint": "npm run check:encoding && npm run check:spacetime-schema && npm run lint:eslint && npm run typecheck",
|
||||
"lint:fix": "eslint . --ext .ts,.tsx,.js,.mjs,.cjs --fix && prettier --write .",
|
||||
"format": "prettier --write .",
|
||||
"format:check": "prettier --check .",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user