4.5 KiB
4.5 KiB
| name | description |
|---|---|
| world_snapshot | 世界状态快照模块(W-04 快照管理)——world_snapshot 表(checksum/version 递增)、快照生成(事务批量+checksum 一致性校验)、查询(分页 {list,total})、恢复(事务回滚无脏数据)、编码字典 snapshot_status/snapshot_type 幂等落库、REST /api/* 统一前缀与错误结构 {code,message,field,detail}。 |
world_snapshot 模块(W-04 快照管理)
架构
world_snapshot 是域内业务模块:聚合 world/scene/entity 当前状态生成快照,支持查询与恢复。
通过 load_world_snapshot() 挂载到宿主应用(唯一集成点),无独立 app.py/端口。
数据模型
表 world_snapshot(models/world_snapshot.json):
| 字段 | 类型 | 说明 |
|---|---|---|
| id | str(32) PK | 主键(getID) |
| world_id | str(32) | 世界ID(关联 world) |
| name | str(255) | 快照名称 |
| snapshot_type | str(32) | full / incremental |
| snapshot_json | text | 快照内容 JSON(world/scene/entity 聚合) |
| checksum | str(64) | sha256 校验和 |
| version | int | 快照版本,按 world 递增(max+1) |
| status | str(32) | active / restored / expired |
| snapshot_date | timestamp | 快照日期 |
| created_at / updated_at | timestamp | 审计时间 |
唯一索引 uk_snap_world_version(world_id, version) 保证同世界版本不重复。
编码字典(init/data.json 幂等落库):
snapshot_status:active 生效中 / restored 已恢复 / expired 已过期snapshot_type:full 全量快照 / incremental 增量快照
核心逻辑
快照生成 create_snapshot
- 输入白名单校验(world_id 必填且 ≤32、snapshot_type ∈ {full,incremental}、name ≤255)——非法输入 100% 拦截不落库
- 同一事务内:
select world ... for update行锁该世界 → 批量聚合 scene/entity → 拼 snapshot_json → sha256 checksum max(version)+1递增(行锁 + 唯一索引双保险)- 事务提交;任何异常整体回滚,返回
{code,message,field,detail}
快照查询 get_snapshot / list_snapshots
- get:读单条,checksum 重算比对,不匹配返回
CHECKSUM_MISMATCH(数据损坏检测) - list:分页
{list,total,page,page_size};page/page_size 非整数、status/snapshot_type 不在白名单 → 拦截
快照恢复 restore_snapshot
- 校验快照存在 + checksum 一致性
- 同一事务内:先删后插写回 scene/entity(按目标表 information_schema 字段过滤防脏列)→ 更新 world.mode=active → 快照置 restored
- 任一步异常 → 事务整体回滚,无脏数据
REST 端点(统一前缀 /api/*)
| 端点 | 方法 | 说明 |
|---|---|---|
| /world_snapshot/api/snapshot_create.dspy | POST | 生成快照 |
| /world_snapshot/api/snapshot_get.dspy | GET/POST | 查询单个(含 checksum 校验) |
| /world_snapshot/api/snapshot_list.dspy | GET/POST | 分页列表 {list,total} |
| /world_snapshot/api/snapshot_update.dspy | POST | 更新(白名单字段) |
| /world_snapshot/api/snapshot_delete.dspy | POST | 删除快照记录 |
| /world_snapshot/api/snapshot_restore.dspy | POST | 恢复快照(事务回滚) |
| /world_snapshot/api/snapshot_types.dspy | GET | 编码字典:快照类型 [{value,text}] |
| /world_snapshot/api/snapshot_statuses.dspy | GET | 编码字典:快照状态 [{value,text}] |
| /world_snapshot/api/snapshot_worlds.dspy | GET | 可选世界列表 [{value,text}] |
成功结构:{"success":true, ...}
错误结构:{"code":"...","message":"...","field":"...","detail":"..."}
函数注册(三处同步)
world_snapshot/world_snapshot/init.py 实现 + world_snapshot/world_snapshot/__init__.py import +
load_world_snapshot() 里 env.xxx = xxx。新增/删除函数必须三处同步。
陷阱
- 取库名禁止硬编码:
.py用ServerEnv().get_module_dbname('world_snapshot');.dspy 直接用全局get_module_dbname() - 事务 return 位置:
return必须在async with块外(块内 return 返回 None) - sor.U 仅 2 参数:主键放 data 里;仅主键时校验非空更新字段
- sqlExe 必须带 ns:无参数查询也传
{} - .dspy 禁止 import:函数经 load_*() 导出;预加载全局 json/debug/getID 等直接可用
- dbpools 单例 fork 陷阱:函数内
db = DBPools()局部创建 - sor.C 不自动补 created_at:插入时显式设置
created_at/updated_at= curDateString() - LIMIT/OFFSET 用整数:字符串会渲染成
LIMIT '5'语法错误