Add UUID/FK channel checks, agent whitelist/push APIs, bindings, super-admin LWW audit with rollback, reconcile rate limits, and sync docs. Default customers stay opt-in; company conflict UI is removed. Co-authored-by: Cursor <cursoragent@cursor.com>
113 lines
4.3 KiB
Markdown
113 lines
4.3 KiB
Markdown
# 跨库数据同步中间件
|
||
|
||
支持 **SQLite ↔ MySQL ↔ Postgres**。平台侧 worker 可轮询两端 outbox;**形态 B(本机 agent)** 下由终端 agent 经平台 **push** 写线上 A,平台**不直连用户本机 SQLite**。
|
||
|
||
冲突策略默认 **自动 LWW(源端覆盖)**;落败写入**平台超级管理员**覆盖日志。公司管理员**无冲突台**。
|
||
|
||
## 权限与隔离
|
||
|
||
| 项 | 说明 |
|
||
|----|------|
|
||
| 谁可配通道 | 公司**顶级权限(管理员)**,「数据同步」 |
|
||
| Agent push / 拉白名单 | JWT 含「数据同步」(人类管理员或智能体凭证) |
|
||
| LWW 覆盖审计 | **仅平台超级管理员**;公司 top → 403 |
|
||
| 数据隔离 | 通道带 `tenant_id`;公司 A 看不到公司 B |
|
||
|
||
## 推荐场景(松离线 B→A)
|
||
|
||
| 端 | 角色 |
|
||
|----|------|
|
||
| **B** | 本机正式库(UUID 主键);开通且白名单表本地可见 |
|
||
| **A** | 线上库;agent 经平台 push 幂等写入 |
|
||
| **Agent** | 读本机 outbox → `POST /api/v1/agent/sync/channels/:id/push` |
|
||
|
||
推荐配置:
|
||
|
||
1. 通道:`local` 描述本机表名单,`remote` = A 的 DSN;方向 **`local_to_remote`**;策略 **`lww_source`**。
|
||
2. 表白名单须 UUID TEXT PK + FK 闭包(保存时校验)。
|
||
3. 客户端显式 `local_dbsync`(见开通说明);未开通用户零感。
|
||
4. 怀疑漏数时点 **同步修复(对账)**(有最小间隔限流);双向通道自动对账约 **15 分钟** 一次。
|
||
|
||
如何保证**不漏、不多**:
|
||
|
||
| 手段 | 防什么 |
|
||
|------|--------|
|
||
| 触发器 / 本机 outbox → agent push | 漏 |
|
||
| `WithApplying` / 远端应用不回写 outbox | 多(回声) |
|
||
| 目标 meta 同 version 跳过 | 多(重复投递) |
|
||
| LWW + 超管覆盖日志 | 并发同 PK |
|
||
| 主键对账 reconcile | 漏(存量差) |
|
||
|
||
## 能力一览
|
||
|
||
| 项 | 说明 |
|
||
|----|------|
|
||
| 方言 | `sqlite` / `mysql` / `postgres` |
|
||
| 方向 | 本地→线上(推荐)/ 线上→本地 / 双向 |
|
||
| 冲突 | 默认 `lww_source`;`lww_target`;`queue` 仅调试(租户不可见) |
|
||
| Agent | `GET .../agent/sync/.../whitelist`;`POST .../push` |
|
||
| Binding | `GET/POST /api/v1/admin/sync/bindings` |
|
||
| 对账 | `POST .../reconcile`(默认最少间隔 300s) |
|
||
| 审计 | `GET /api/v1/platform/dbsync/lww-overrides`(超管) |
|
||
|
||
持久化:`data/dbsync/channels.json`、`lww_overrides.json`(及遗留 `conflicts.json`)。
|
||
|
||
## 控制台用法
|
||
|
||
1. **数据同步** → 新建通道(UUID 表白名单)→ 测试 → 保存 → 启动
|
||
2. 默认策略选 **源端覆盖**;方向首期用 **本地 → 线上**
|
||
3. 点 **同步修复** 做主键对账(勿连续狂点,有限流)
|
||
4. LWW 明细在 **平台工作台**(超管),不在公司同步页
|
||
|
||
开通与迁移:见 [数据同步-开通说明.md](./数据同步-开通说明.md)、[数据同步-迁移手册.md](./数据同步-迁移手册.md)。
|
||
|
||
## API
|
||
|
||
### 公司管理员(「数据同步」)
|
||
|
||
| 方法 | 路径 |
|
||
|------|------|
|
||
| GET/POST | `/api/v1/admin/sync/channels` |
|
||
| GET/PUT/DELETE | `/api/v1/admin/sync/channels/{id}` |
|
||
| POST | `/api/v1/admin/sync/test` |
|
||
| POST | `/api/v1/admin/sync/channels/{id}/prepare\|start\|stop` |
|
||
| POST | `/api/v1/admin/sync/channels/{id}/reconcile` |
|
||
| POST | `/api/v1/admin/sync/channels/{id}/ingest`(写通道 local,偏形态 A) |
|
||
| GET/POST | `/api/v1/admin/sync/bindings` |
|
||
| GET/POST | `/api/v1/admin/sync/conflicts*` → **403**(已迁超管审计) |
|
||
|
||
### 本机 Agent
|
||
|
||
| 方法 | 路径 |
|
||
|------|------|
|
||
| GET | `/api/v1/agent/sync/channels/{id}/whitelist` |
|
||
| POST | `/api/v1/agent/sync/channels/{id}/push` |
|
||
| POST | `/api/v1/agent/sync/channels/{id}/push/batch` |
|
||
|
||
### 平台超级管理员
|
||
|
||
| 方法 | 路径 |
|
||
|------|------|
|
||
| GET | `/api/v1/platform/dbsync/lww-overrides` |
|
||
| POST | `/api/v1/platform/dbsync/lww-overrides/{id}/rollback` |
|
||
|
||
### push 示例
|
||
|
||
```json
|
||
POST /api/v1/agent/sync/channels/{id}/push
|
||
{
|
||
"table": "orders",
|
||
"op": "insert",
|
||
"row_pk": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
|
||
"row": { "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "title": "x" },
|
||
"version": 1710000000000000000,
|
||
"client_outbox_id": "..."
|
||
}
|
||
```
|
||
|
||
## 相关
|
||
|
||
- [同步表约定.md](./同步表约定.md)
|
||
- [数据同步-开通说明.md](./数据同步-开通说明.md)
|
||
- [数据同步-迁移手册.md](./数据同步-迁移手册.md)
|