29 lines
5.4 KiB
JSON
29 lines
5.4 KiB
JSON
{
|
||
"summary": [
|
||
{
|
||
"name": "pbl_entity_state",
|
||
"title": "实体状态(服务端权威)",
|
||
"primary": ["id"],
|
||
"catelog": "entity",
|
||
"comment": "【本表定位 · world_sync 侧内联副本】实体状态表(服务端权威:state_version 单调递增,客户端禁写;由 world_sync 单事务写入路径 write_event_with_state 与事件行同事务更新,乐观锁冲突映射为 ConcurrentStateConflict)。【结构权威源 · PM 裁决】PM 裁决(任务 u0EO4x3ajntR41acaHj5H 问答):选 B —— 以 pbl_runtime_ext 为唯一真源;结构权威定义位于 modules/pbl_runtime_ext/models/pbl_entity_state.json(M11b-1 已批准产物,本任务禁止反向修改),建表 DDL 归该模块所有,本文件不复制其物理实现细节。world_sync 仅作为单事务写入的消费方,不拥有该表结构定义权。【为什么是内联而不是引用】database-table-definition-spec 只承认 summary/fields/indexes/codes 四段式;scripts/validate_models_json.py(M11b-2a 子任务 A 修复版)对 key=schema 引用式写法直接判 FAIL(QC #5),故本文件按真源逐字段内联权威列集(真源实为 10 列:tenant_id/id/session_id/entity_id/state_json/state_version/checksum/updated_by/created_at/updated_at,任务书所述「8 列」系早期口径,以真源实测为准),作为 world_sync 侧的消费方契约视图;一致性由 scripts/m11b2b_column_diff.py 与 scripts/m11b2b_selftest.py 机械核对,真源变更时必须同步本副本。【抽象类型归一说明】真源使用物理类型写法(id=int(20) unsigned auto_increment、session_id/state_version=bigint、state_json=json),本副本按 spec 归一为抽象类型(long/text),不保留 unsigned/length 物理修饰;bigint→long、json→text(存 JSON 文本,由应用层 json.dumps/loads)。【id 类型偏离处理 · 本子任务的选择与理由】真源 id 为自增 BIGINT 主键(真源侧以 auto_increment/unsigned 私有键表达该偏离);子任务 A 的最终登记表 COMPLIANCE_DEVIATIONS 为空 {}(A 按 QC #5 选 (a):不放行任何历史失效项),且本任务范围明确禁止修改校验器脚本,因此 world_sync 侧不走「登记放行 id 非 str(32)」路线,而是内联为 spec 合规写法 type=str / length=32、不带 auto_increment 键,主键值由应用层生成 32 位 uuid 去横线十六进制串(world_sync/pbl_runtime_tx.py::new_event_uid 同族工具函数);与真源的 id 类型差异由 world_sync 侧消费方代码适配:写路径 INSERT 不显式提交 id(见 pbl_runtime_tx.py 状态行 INSERT 列集 cols 不含 id),生产 MySQL 交由真源 DDL 的 AUTO_INCREMENT 生成 BIGINT,本地/测试库(authority 层渲染的 sqlite DDL)使用应用层生成的 str(32)。此差异为有意选择、非疏漏,评审请勿据此判为结构缺陷。【主键与唯一键说明】真源 summary[0] 未声明 primary,其物理主键由 indexes 中 PRIMARY(id) 表达,故本副本 primary=[\"id\"],并把真源 uk_es(tenant_id+session_id+entity_id 唯一键,即消费方定位键 STATE_KEY_COLUMNS)内联为 idxtype=unique;实体状态定位键为 tenant_id + session_id + entity_id,本表无 event_uid 概念。【消费方清单】modules/world_sync/world_sync/pbl_runtime_sql.py(STATE_TABLE/STATE_COLUMNS)、modules/world_sync/world_sync/pbl_runtime_tx.py::write_event_with_state(_fetch_state_version/_update_state/_insert_state)、modules/world_sync/world_sync/pbl_runtime_authority.py(列契约解析层);上述代码引用的列名必须全部出现在本文件 fields[] 中。【打包镜像说明】apps/scense/pkgs/world_sync/models/pbl_entity_state.json 是本文件的打包镜像,只由 modules/world_sync/scripts/sync_models_mirror.py 生成,禁止手工双写;一致性由 modules/world_sync/scripts/m11b2b_selftest.py 的 sha256 断言守护。【私有键剥离说明】真源使用的 spec 未定义键 summary[0].module/engine/charset/tenant_scoped、fields[].comment/null/unsigned/auto_increment、indexes[].unique/fields,在本副本中一律不保留或已归一为 spec 键(nullable/idxtype/idxfields);本文件根键仅 summary/fields/indexes/codes,codes 段本表无枚举编码列故为空数组。"
|
||
}
|
||
],
|
||
"fields": [
|
||
{"name": "tenant_id", "title": "租户ID", "type": "str", "length": 32, "nullable": "no"},
|
||
{"name": "id", "title": "主键ID(应用层生成)", "type": "str", "length": 32, "nullable": "no"},
|
||
{"name": "session_id", "title": "会话", "type": "long", "nullable": "no"},
|
||
{"name": "entity_id", "title": "实体标识", "type": "str", "length": 32, "nullable": "no"},
|
||
{"name": "state_json", "title": "状态JSON", "type": "text", "nullable": "yes"},
|
||
{"name": "state_version", "title": "单调版本", "type": "long", "nullable": "no"},
|
||
{"name": "checksum", "title": "状态摘要", "type": "str", "length": 32, "nullable": "no"},
|
||
{"name": "updated_by", "title": "写入者", "type": "str", "length": 32, "nullable": "no"},
|
||
{"name": "created_at", "title": "创建时间", "type": "datetime", "nullable": "no"},
|
||
{"name": "updated_at", "title": "更新时间", "type": "datetime", "nullable": "no"}
|
||
],
|
||
"indexes": [
|
||
{"name": "PRIMARY", "idxtype": "unique", "idxfields": ["id"]},
|
||
{"name": "uk_es", "idxtype": "unique", "idxfields": ["tenant_id", "session_id", "entity_id"]}
|
||
],
|
||
"codes": []
|
||
}
|