Enable Binding-scoped agent push/pull, empty-table schema ensure, SyncPage inspect/drop-table, default module import, and agent-bound publish docs from the 宇恒联调意见. Co-authored-by: Cursor <cursoragent@cursor.com>
6.7 KiB
6.7 KiB
智建修改意见(松离线 + UUID 主键一致性)
配套文档:同目录
database_fastapi修改意见.md(宇恒客户端写网关 / 双轨写)
目标:离线写入不破坏联网后的数据一致 + 主键一致;对账可兜底。
对照能力:本仓库docs/数据同步-中间件.md(dbsync outbox / ingest / reconcile / 冲突队列)。
一、结论摘要
| 项 | 结论 |
|---|---|
| 对账引擎 | 不必从零重做;dbsync 已有按主键 upsert、ingest、reconcile、冲突队列 |
| 真正要改 | 表主键约定(UUID) + 写入口语义(认客户端 id / upsert) + 与宇恒绑定对齐 |
| 推荐模型 | 松 + UUID:离线本地先按最终主键落库;联网同主键幂等 upsert 到线上 |
| 禁止 | 同步键依赖两端各自 INTEGER AUTOINCREMENT |
宇恒侧(客户端)负责:补 UUID、松离线本地落库 + pending、回放幂等。
智建侧负责:线上按 UUID upsert、通道/对账/冲突、表结构与发号规则。
二、与宇恒文档的分工
| 端 | 文档 | 职责 |
|---|---|---|
| 宇恒客户端 | database_fastapi修改意见.md |
apply_write、pending、binding、online_primary |
| 智建平台 | 本文 | 线上主库语义、dbsync、表约定、对账 API 对业务可用 |
接法二选一(长期建议 ①):
| 接法 | 含义 | 智建改动量 |
|---|---|---|
| ① 走 dbsync | 宇恒本地 = B;松离线写 B(带 UUID);通道 B↔A | 表结构 + 配置为主,代码改少 |
| ② HTTP 双写 | 宇恒直打 /database/permanent/... |
线上 insert 必须变 upsert,且强制客户端 id |
三、表结构约定(A / B 两端)
- 参与同步的业务表主键为
id TEXT(UUID 字符串),不用自增整数当同步键。 - 建议列:
updated_at/version(与 dbsync 版本跳过、冲突策略对齐)。 - 通道
pk_columns:非默认id时显式配置。 - 存量自增表:迁移生成 UUID,或暂不纳入同步白名单,仅新表用 UUID。
- dbsync 触发器已
CAST(pk AS TEXT),字符串 UUID 原生兼容;改的是建表习惯,不是中间件内核。
四、接法 ①:走 dbsync(推荐)
已有、可直接用
- 本地变更 →
_ajz_sync_outbox→ worker 推线上 POST .../ingest:按主键 upsert(示例已是"id": "c-001")POST .../reconcile:主键集合补缺- 冲突队列 + LWW / queue 策略
- 双向通道约每分钟自动对账
建议补强
| 优先级 | 项 | 说明 |
|---|---|---|
| P0 | 文档/控制台规范 | 写死:同步表白名单必须 UUID 主键;松离线以客户端已带 id 为准 |
| P0 | 写入口拒无 id | ingest / 业务写:无 id → 400,或服务端生成 UUID 并回写响应(松离线仍优先客户端生成) |
| P1 | 库绑定对齐 | 宇恒 online_db_id 与智建租户库 / 通道 remote 可查询、可登记;避免仅本地 hash 对不上真实库 |
| P1 | 业务可调对账 | 现 sync API 偏管理员;提供租户内用户/agent 代理调用 ingest/reconcile,或网关代调 |
| P2 | 同 PK 内容对账 | 当前 reconcile 偏主键集合;可选 version/hash 不一致 → 冲突队列 |
松离线数据流(①)
离线:宇恒本地 B 按最终 UUID 落库(可标未同步)+ 可选 pending
联网:触发器/回放 → 同 PK upsert → A
兜底:reconcile 补主键集合差;冲突进 conflicts
五、接法 ②:HTTP 双写(短期兼容宇恒网关)
宇恒当前:online_primary 下同 body 先写线上再写本地,不会把线上自增 inserted_id 回填本地。
智建线上 permanent 写接口必须:
insert= upsert byid(有则更新,无则插入);请求必须带id。- 响应带回
id+version(可选),便于客户端校验。 update/delete统一按同一id;禁止「无 id 靠自增」。- 建表默认主键模板改为 UUID,不再默认
INTEGER AUTOINCREMENT。 - (可选)按
online_db_id+ 表暴露 reconcile,或复用 dbsync reconcile。
未改以上语义时,即使客户端用 UUID,线上若仍自增,双轨主键仍会漂。
六、落地顺序(智建)
- 规范 + 迁移:同步表白名单,主键 UUID。
- 选定接法:优先 ①;若短期 ②,先改 permanent 写为 upsert。
- 写入口强制带
id(缺则 400 或服务端生成并返回)。 - 绑定:租户/用户 ↔ 线上库 ID 可查,与宇恒
cache/db_bindings对齐。 - 对账:业务可读 API 或网关代调;冲突走现有 conflicts。
- 文档:离线写入 = 最终主键;联网只做同 PK 幂等,不重新发号。
七、验收标准
- 离线插入一行(客户端 UUID)→ 联网后线上与本地 同一
id,无重复行。 - 同一 UUID 重复提交 / 回放 → 幂等,不多行。
- 断网窗口结束回放后,主键集合对账无持续缺口(或缺口可一键 reconcile 清掉)。
- 并发改同 PK → 进冲突队列或按约定 LWW,不静默改主键。
- 未纳入白名单的自增旧表:不同步或明确排除,避免误配通道。
八、勿做事项
- 不要用「两端自增 + 事后对账」充当主路径。
- 不要只靠触发器异步 outbox 充当客户端主写路径却仍让 HTTP insert 自增发号(两套语义打架)。
- 不要在回放失败时换新主键重试。
- 不要让管理员专用 sync API 成为唯一对账入口却要求终端用户自愈(需代理或网关)。
九、相关路径
| 项 | 路径 |
|---|---|
| 本文 | E:\project\ai建站\智建修改意见.md |
| 宇恒写网关意见 | E:\project\ai建站\database_fastapi修改意见.md |
| dbsync 说明 | E:\project\ai建站\docs\数据同步-中间件.md |
| dbsync 实现 | platform/internal/dbsync/ |
| 宇恒网关实现 | yuhengyihao_client/yxd/app_fastapi/db_write_gateway.py 等 |
十一、模块导入默认能力(方案 A)
正式条目已写入联调意见,请以此为准:
E:\project\ai建站\联调后修改意见-宇恒松离线.md→ §5.6 Z9(方案 A)
(§0 结论表已挂「Z9 模块导入默认能力」)
摘要:生成/发布时业务 resource 默认带 import(及 export),列表 actions 对齐;publish/merge 可兜底。绑定权限解决「谁能调」,方案 A 解决「表是否允许导入」。
十二、一句话(同步 + 导入)
松离线要对齐的是 UUID 主键 + upsert;模块灌数要对齐的是 绑定权限 + 蓝图默认开放 import(方案 A / Z9)——细则见联调意见 §5.6。