## 背景 这是一个独立的 CI 修复 PR,针对 Backend 与 Native shell 测试失败进行修复,不包含资源画布功能变更。 此前 CI 失败主要集中在: - 后台精选素材契约测试初始化缺少来源素材字段。 - `spacetime-module` host 测试因缺少 SpacetimeDB WASM 宿主 ABI 符号而无法链接。 - Native shell 自主创作模式、runtime action、provider batch 和测试初始化之间存在状态机断言不一致。 - 部分失败测试曾被临时绕过,本 PR 恢复这些测试门禁。 ## 变更内容 ### Backend - 补齐后台精选素材 payload 测试所需的来源素材字段。 - 增加 camelCase 序列化断言,防止 snake_case 字段泄漏。 - 调整 server-rs workspace 测试拆分: - 普通 workspace host 测试继续排除 `spacetime-module`,避免其 `spacetime-types` feature 污染其他领域 crate 的 host 链接。 - 新增独立的 `spacetime-module` 单元测试步骤,不再跳过该模块自身测试。 - 为 host 测试构建提供仅测试期的 SpacetimeDB ABI 链接支持。 - 同步更新 CI workflow 断言、开发流程文档和运维验证文档。 ### Native shell - 恢复被临时跳过的 Native shell 失败测试门禁。 - 修复自主创作模式下的完成条件、runtime action 执行、provider batch 和 finalization 状态流转。 - 修正 Tauri/native 测试初始化、恢复流程及断言,使测试与实际运行时协议保持一致。 - 保持自主创作模式的宽松行为,不通过忽略测试规避失败。 ## 验证 当前提交已完成以下本地验证: - `cargo test --locked -p spacetime-module --no-fail-fast` - 259 个测试 - 258 个通过 - 0 个失败 - 1 个已有的外部 fixture 测试 ignored - `cargo check --locked -p spacetime-module --target wasm32-unknown-unknown` - `cargo build --locked -p spacetime-module --target wasm32-unknown-unknown` - `cargo check --locked -p api-server --all-targets` - `npm run check:server-rs-ddd` - `npm run check:spacetime-schema` - `npm run check:encoding` - `npm run test -- scripts/project-ci-workflow.test.ts` - `cargo fmt --manifest-path server-rs/Cargo.toml --all -- --check` - `git diff --check` 没有新增 `#[ignore]` 来规避失败。 ## 测试边界说明 `spacetime-module` 的 host ABI 链接支持仅用于执行纯单元测试,不是 SpacetimeDB runtime 替身。Reducer、procedure 和真实数据库事务行为仍需要通过真实 SpacetimeDB runtime/integration harness 验证。 本机 Windows 上完整 workspace 测试中的 `wallet_refund_outbox` 测试仍有 11 项因 `os error 5(拒绝访问)`失败,表现为临时文件权限/锁定问题;该问题与本 PR 的 SpacetimeDB 模块测试改动无关,也没有通过忽略这些测试来掩盖。 Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/209 Co-authored-by: suzmii <suzmii@qq.com> Co-committed-by: suzmii <suzmii@qq.com>
spacetime-module 主工程 crate 说明
日期:2026-04-21
1. crate 职责
spacetime-module 是新后端的 SpacetimeDB 主工程 crate,后续负责:
- 聚合各独立模块 crate 的表定义
- 聚合各独立模块 crate 的 reducer
- 聚合各独立模块 crate 的 view / 读模型
- 生成可发布的 SpacetimeDB wasm 模块
- 由
../../scripts/spacetime-dev.ps1与../../scripts/spacetime-dev.sh驱动的本地 standalone 启动链路
2. 当前阶段说明
当前阶段已落下第一批真实 schema 骨架,并已补齐本地 standalone 启动脚本,先把 SpacetimeDB 进程入口、M3/M4 基础表以及 M5 custom world / agent 首批表骨架固定下来。
后续与本 crate 直接相关的任务包括:
- 继续扩充模块聚合入口
- 继续设计表、reducer、view 的聚合方式
- 接入身份 claims 透传
- 在当前 scaffold 基础上接入 publish / dev 循环
- 在
M7收口阶段拆分过大的src/lib.rs,按runtime、gameplay/*、custom_world、asset_metadata、ai等业务与 SpacetimeDB 聚合层次重组目录,避免主工程 crate 回退成单大包
当前已落地:
spacetime-module真实cdylibcrate scaffoldasset_object首版表骨架bucket + object_key双列对象定位索引module-assets的访问策略与字段校验类型接入- 面向 Axum 的
asset_object确认持久化入口 asset_entity_binding通用绑定表- 面向 Axum 的
bind_asset_object_to_entity_and_return绑定 procedure runtime_setting表与 procedurenpc_state、story_session、story_eventbattle_state、treasure_recordquest_record、quest_logM5首批custom_world_profile / session / agent / gallery表骨架custom world library / publish / galleryStage 2 procedurespublished profile compileStage 3 procedurepublish_worldStage 4 串联 procedureai_task / ai_task_stage / ai_text_chunk / ai_result_reference首版 AI 真相表- AI 任务最小 procedure / reducer:
create_ai_taskcreate_ai_task_and_returnstart_ai_taskstart_ai_task_stageappend_ai_text_chunk_and_returncomplete_ai_stage_and_returnattach_ai_result_reference_and_returncomplete_ai_task_and_returnfail_ai_task_and_returncancel_ai_task_and_return
turn_in_quest与resolve_combat_action(Victory)到player_progression / chapter_progression的最小经验联动
2.0.1 runtime 域拆分进度
截至 2026-04-23,runtime 域已完成第一轮真实内容拆分,根入口不再保留该域的业务 helper 实现。
当前 src/runtime/ 的实际落位如下:
src/runtime/settings.rsruntime_setting表- setting 读取 / upsert procedure 与快照 helper
src/runtime/snapshots.rsruntime_snapshot表- snapshot 读取 / upsert / delete helper
src/runtime/browse_history.rsuser_browse_history表- 浏览历史 list / upsert / clear procedure 与行转换 helper
src/runtime/profile.rsprofile_dashboard_stateprofile_wallet_ledgerprofile_played_worldprofile_save_archive- profile dashboard / ledger / play stats / save archive 投影与同步 helper
src/runtime/mod.rs 当前只承担聚合职责:
- 声明
settings / snapshots / browse_history / profile - 对外统一使用
pub use xxx::*;重新导出
后续新增 runtime 相关 table / reducer / procedure / helper 时,必须直接落到上述二级文件,禁止回写到 src/lib.rs。
2.0.2 ai 域拆分进度
截至 2026-04-23,ai 域也已完成第一轮真实内容拆分,根入口不再保留 ai_task / ai_task_stage / ai_text_chunk / ai_result_reference 的业务实现。
当前 src/ai/ 的实际落位如下:
src/ai/tasks.rsai_task表- task 创建、启动、完成、失败、取消的 reducer / procedure
- task 状态迁移与持久化 helper
src/ai/stages.rsai_task_stageai_text_chunkai_result_reference- stage 启动、chunk 追加、stage 完成、result reference 绑定的 procedure / helper
src/ai/snapshots.rs- AI 任务、阶段、chunk、reference 的 row / snapshot 转换 helper
src/ai/mod.rs 当前只承担聚合职责:
- 声明
tasks / stages / snapshots - 对外统一使用
pub use xxx::*; - 对内部共享的 row / snapshot helper 使用
pub(crate) use snapshots::*;
后续新增 AI 相关 table / reducer / procedure / helper 时,必须直接落到上述二级文件,禁止回写到 src/lib.rs。
2.1 src/lib.rs 拆分路由规则
从 2026-04-23 起,src/lib.rs 不再允许继续承载具体业务域的 table / reducer / procedure / tx helper。
根入口后续只允许保留:
use聚合mod声明- 少量跨域共享 helper
- 迁移过渡期测试
根入口与子模块的导入导出规则同步冻结为:
src/lib.rs对外统一优先使用pub use xxx::*;重新导出模块内容- 已拆业务模块内部统一优先使用
use crate::*;复用主入口已聚合的类型与函数 - 只有当
use crate::*;无法覆盖或会引入明显歧义时,才补局部显式use - 新增业务域内容禁止为了堆
use列表再回写到src/lib.rs
具体内容必须落到下面的模块:
src/entry.rs- SpacetimeDB
init入口
- SpacetimeDB
src/domain_types.rs- 跨域共享的 SpacetimeDB 类型
src/asset_metadata/- 资产对象与资产绑定真相表
src/big_fish/- Big Fish 创作与运行态
src/runtime/- runtime setting / snapshot / browse history / profile 投影
src/gameplay/story / combat / inventory / npc / quest / runtime_item / progression
src/custom_world/- custom world profile / session / agent / publishing / gallery / works
src/ai/- ai task / stage / chunk / result reference
src/puzzle.rs- 拼图玩法当前仍为单文件域模块
已冻结的二级模块落位点
src/asset_metadata/objects.rssrc/asset_metadata/bindings.rssrc/big_fish/tables.rssrc/big_fish/session.rssrc/big_fish/assets.rssrc/big_fish/runtime.rssrc/runtime/settings.rssrc/runtime/snapshots.rssrc/runtime/browse_history.rssrc/runtime/profile.rssrc/gameplay/combat.rssrc/gameplay/inventory.rssrc/gameplay/npc.rssrc/gameplay/progression.rssrc/gameplay/quest.rssrc/gameplay/runtime_item.rssrc/gameplay/story.rssrc/custom_world/profile.rssrc/custom_world/session.rssrc/custom_world/agent.rssrc/custom_world/publishing.rssrc/custom_world/gallery.rssrc/custom_world/works.rssrc/ai/tasks.rssrc/ai/stages.rssrc/ai/snapshots.rs
后续如果新增 SpacetimeDB 表、reducer、procedure 或同域 helper,必须先判断属于哪个一级模块与二级落位点,再写入对应文件;禁止直接追加到 src/lib.rs。
当前文档入口
当前长期工程口径已融合到:
- ../../../docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md
- ../../../docs/【玩法创作】平台入口与玩法链路-2026-05-15.md
- ../../../docs/【开发运维】本地开发验证与生产运维-2026-05-15.md
旧阶段设计文档不再作为实现依据。
3. 边界约束
spacetime-module只聚合状态模型,不直接承接 HTTP、Cookie、Header、OSS、短信、微信、LLM 等外部副作用。- 每个业务模块优先在自己的
crates/module-*中定义状态与规则,再由主工程聚合。 - 主工程不重新吞并各模块实现细节,避免回到单大包结构。
custom_world_asset_link仍等待M6 assets / OSS的对象槽位规则冻结后再补,不在本轮首批表骨架内提前硬落。