Files
ai_site/智建修改意见.md
whm b04b180d30 feat: harden loose-offline sync for user JWT, schema, and console ops
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>
2026-08-05 09:47:35 +08:00

150 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 智建修改意见(松离线 + 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 两端)
1. 参与同步的业务表主键为 **`id TEXT`UUID 字符串)**,不用自增整数当同步键。
2. 建议列:`updated_at` / `version`(与 dbsync 版本跳过、冲突策略对齐)。
3. 通道 `pk_columns`:非默认 `id` 时显式配置。
4. 存量自增表:迁移生成 UUID或暂不纳入同步白名单仅新表用 UUID。
5. 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 不一致 → 冲突队列 |
### 松离线数据流(①)
```text
离线:宇恒本地 B 按最终 UUID 落库(可标未同步)+ 可选 pending
联网:触发器/回放 → 同 PK upsert → A
兜底reconcile 补主键集合差;冲突进 conflicts
```
---
## 五、接法 ②HTTP 双写(短期兼容宇恒网关)
宇恒当前:`online_primary` 下同 body 先写线上再写本地,**不会**把线上自增 `inserted_id` 回填本地。
智建线上 permanent 写接口必须:
1. **`insert` = upsert by `id`**(有则更新,无则插入);请求**必须带 `id`**。
2. 响应带回 **`id` + `version`(可选)**,便于客户端校验。
3. `update` / `delete` 统一按同一 `id`;禁止「无 id 靠自增」。
4. 建表默认主键模板改为 UUID不再默认 `INTEGER AUTOINCREMENT`
5. (可选)按 `online_db_id` + 表暴露 reconcile或复用 dbsync reconcile。
未改以上语义时,即使客户端用 UUID线上若仍自增双轨主键仍会漂。
---
## 六、落地顺序(智建)
1. **规范 + 迁移**:同步表白名单,主键 UUID。
2. **选定接法**:优先 ①;若短期 ②,先改 permanent 写为 upsert。
3. **写入口强制带 `id`**(缺则 400 或服务端生成并返回)。
4. **绑定**:租户/用户 ↔ 线上库 ID 可查,与宇恒 `cache/db_bindings` 对齐。
5. **对账**:业务可读 API 或网关代调;冲突走现有 conflicts。
6. **文档**:离线写入 = 最终主键;联网只做同 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。