155 lines
6.9 KiB
JSON
155 lines
6.9 KiB
JSON
{
|
||
"summary": [
|
||
{
|
||
"name": "pbl_runtime_event",
|
||
"title": "运行时事件流(append-only)",
|
||
"primary": [
|
||
"id"
|
||
],
|
||
"catelog": "relation",
|
||
"comment": "PBL 运行时事件表(world_sync 侧写入视图)。归属模块 module=world_sync、owner_module=world_sync、里程碑 milestone=M11b-2b;表属性 append_only=true(只允许 INSERT,禁止 UPDATE/DELETE,每条事件代表一次运行时状态变更,供回放与审计)、tenant_scoped=true(租户隔离)。【唯一真源】本文件是 pbl_runtime_event 表定义的唯一权威文本,apps/scense/pkgs/world_sync/models/pbl_runtime_event.json 只是由 scripts/sync_models_to_app.py(或 cp)从本文件同步出的打包镜像,禁止手工双写,二者 sha256 必须相同(由 scripts/m11b2_selftest.py 机械断言)。【写入约束】append-only:只允许 INSERT,禁止 UPDATE/DELETE。【事务约束】本表的 INSERT 必须与 pbl_entity_state 的更新处于同一数据库事务内(见 world_sync.pbl_runtime_tx.write_event_with_state),任一失败整事务回滚,不允许脱离事务单独写事件。【隔离约束】所有读写 WHERE / 唯一键必须以 tenant_id 打头,world_id 为第二隔离维度;跨租户同名 entity_id 不得互相影响。【ID 约定】主键 id 为 str(32),由应用层生成(uuid4().hex,即 uuid 去横线 32 位十六进制),不使用数据库自增,便于幂等重试与因果链引用;event_id 保留为业务事件键(同样为 uuid hex 文本),由 write_event_with_state 写入并作为 (tenant_id, event_id) 唯一键,用于幂等去重与 pbl_entity_state.updated_by_event 回指。【列真源】fields 与 world_sync/pbl_runtime_sql.py 的 EVENT_COLUMNS 及 pbl_runtime_tx.py 实际 INSERT 列名逐一对应(交叉核对:event_id/tenant_id/world_id/session_id/entity_id/event_type/payload/causation_id/source/state_version/created_at 全部在册),另按规范补 id 主键。【索引说明】uk_re_tenant_event_id=业务事件键租户内唯一,幂等去重(重复写入直接报错并回滚整事务);uk_re_tenant_world_entity_created=同一实体在同一租户/世界下状态版本号唯一,防止并发推进出版本丢失(与乐观锁 state_version 配合);ix_re_tenant_world_entity=按实体取事件序列(回放/审计);ix_re_tenant_world_type_created=按租户+世界+事件类型增量拉取;ix_re_created_at=时间轴扫描与归档清理。【与 M11b-1 的关系】modules/pbl_runtime_ext/models/pbl_runtime_event.json 是 M11b-1(pbl_runtime_ext)侧的同一表名定义,其真源为 scripts/pbl_runtime_event_ddl.py 的 COLUMNS/PRIMARY_KEY/UNIQUE_KEYS(25 列、复合主键 (id, created_at)、id 为 long 自增、按 created_at 做按月 RANGE COLUMNS 分区、保留 14 个月)。两者同名不同构,属双真源风险,已按 team-communication 规范向 agent.pm 冒泡请求裁决(见交付摘要冒泡单据),本任务不擅自改动 M11b-1 已批准的 json 与其 DDL 生成器。【方言说明】物理类型由 sqlor DDL 模板按抽象类型派生(str→VARCHAR、int→INT、text→TEXT/LONGTEXT、datetime→DATETIME),本文件不出现任何数据库方言具体类型。【键白名单】summary 仅含 name/title/primary/catelog/comment;fields 仅含 name/title/type/length/dec/nullable/default(说明文字一律写进 title,DDL 模板按 title 渲染 COMMENT);indexes 仅含 name/idxtype/idxfields;根键仅 summary/fields/indexes/codes 四段式。"
|
||
}
|
||
],
|
||
"fields": [
|
||
{
|
||
"name": "id",
|
||
"title": "主键ID(str32,应用层生成uuid4().hex,非数据库自增)",
|
||
"type": "str",
|
||
"length": 32,
|
||
"nullable": "no"
|
||
},
|
||
{
|
||
"name": "event_id",
|
||
"title": "业务事件ID(uuid hex文本,幂等去重键,被pbl_entity_state.updated_by_event回指)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "no"
|
||
},
|
||
{
|
||
"name": "tenant_id",
|
||
"title": "租户ID(隔离维度,强制打头,缺失即拒绝写入)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "no"
|
||
},
|
||
{
|
||
"name": "world_id",
|
||
"title": "世界ID(隔离维度,强制)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "no"
|
||
},
|
||
{
|
||
"name": "session_id",
|
||
"title": "运行时会话ID(可空,无会话上下文时为空)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "yes"
|
||
},
|
||
{
|
||
"name": "entity_id",
|
||
"title": "实体ID(事件关联的实体)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "no"
|
||
},
|
||
{
|
||
"name": "event_type",
|
||
"title": "事件类型(如state.updated,默认值同pbl_runtime_tx.DEFAULT_EVENT_TYPE)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "no",
|
||
"default": "state.updated"
|
||
},
|
||
{
|
||
"name": "payload",
|
||
"title": "事件体(JSON文本,规范抽象类型text,不用方言JSON类型)",
|
||
"type": "text",
|
||
"nullable": "yes"
|
||
},
|
||
{
|
||
"name": "causation_id",
|
||
"title": "因果上游事件ID(可空)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "yes"
|
||
},
|
||
{
|
||
"name": "source",
|
||
"title": "写入来源(模块名/引擎版本,默认值同pbl_runtime_tx.DEFAULT_SOURCE)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "no",
|
||
"default": "world_sync.m11b2"
|
||
},
|
||
{
|
||
"name": "state_version",
|
||
"title": "状态版本(本事件落库后实体状态版本,与pbl_entity_state.state_version一致,便于回放对账)",
|
||
"type": "int",
|
||
"nullable": "no",
|
||
"default": "0"
|
||
},
|
||
{
|
||
"name": "created_at",
|
||
"title": "创建时间(服务端UTC时间戳,应用层写入ISO8601文本;append-only表不设updated_at)",
|
||
"type": "datetime",
|
||
"nullable": "no"
|
||
}
|
||
],
|
||
"indexes": [
|
||
{
|
||
"name": "uk_re_tenant_event_id",
|
||
"idxtype": "unique",
|
||
"idxfields": [
|
||
"tenant_id",
|
||
"event_id"
|
||
]
|
||
},
|
||
{
|
||
"name": "uk_re_tenant_world_entity_created",
|
||
"idxtype": "unique",
|
||
"idxfields": [
|
||
"tenant_id",
|
||
"world_id",
|
||
"entity_id",
|
||
"state_version"
|
||
]
|
||
},
|
||
{
|
||
"name": "ix_re_tenant_world_entity",
|
||
"idxtype": "index",
|
||
"idxfields": [
|
||
"tenant_id",
|
||
"world_id",
|
||
"entity_id"
|
||
]
|
||
},
|
||
{
|
||
"name": "ix_re_tenant_world_type_created",
|
||
"idxtype": "index",
|
||
"idxfields": [
|
||
"tenant_id",
|
||
"world_id",
|
||
"event_type",
|
||
"created_at"
|
||
]
|
||
},
|
||
{
|
||
"name": "ix_re_created_at",
|
||
"idxtype": "index",
|
||
"idxfields": [
|
||
"created_at"
|
||
]
|
||
}
|
||
],
|
||
"codes": [
|
||
{
|
||
"field": "event_type",
|
||
"table": "appcodes_kv",
|
||
"valuefield": "k",
|
||
"textfield": "v",
|
||
"cond": "parentid='pbl_event_type'"
|
||
}
|
||
]
|
||
}
|