# ADR-003：跨存储最终一致性

- 状态：Accepted
- 日期：2026-07-16

## 背景

平台同时写 PostgreSQL、Neo4j、MinIO 和 n8n。当前部分请求在一个路由内顺序调用多个系统，失败后可能留下半完成状态，也缺少统一重试和对账证据。

## 决策

1. PostgreSQL 是业务命令状态、映射和一致性事件的协调源；不尝试跨四个系统实现分布式 ACID。
2. 在同一 PostgreSQL 事务写业务记录与 `outbox_events`。后台消费者按 `event_id` 幂等地更新 Neo4j、MinIO 索引、n8n 或知识库。
3. 每个外部写入使用稳定业务 UUID 和幂等键；不使用 Neo4j 内部节点 ID 作为跨系统长期主键。
4. 消费失败采用有上限的指数退避，超过阈值进入 dead-letter 状态并暴露管理告警。
5. 数据治理知识库使用“治理对象变更后增量同步 + 每日全量一致性巡检”。全量巡检比较版本号和内容哈希，只修复差异对象。
6. DataFlow/n8n 激活采用状态机和补偿动作；不能补偿时标记人工处理，禁止返回伪成功。

## 一致性等级

| 数据 | 源真相 | 目标一致性 |
|---|---|---|
| 用户、角色、布局、版本映射 | PostgreSQL | 强一致事务 |
| 治理对象与血缘 | Neo4j | 命令落库后秒级最终一致 |
| 知识库文档与向量 | PostgreSQL/pgvector | 增量秒至分钟级；每日校验 |
| 附件原件 | MinIO | 上传完成后再发布可见状态 |
| Workflow 执行与激活 | n8n | 状态机协调和定期对账 |

## 可观测性和验收

- 每个跨存储操作贯穿 `correlation_id`、`event_id`、对象 UID 和操作者。
- 指标至少包含 outbox backlog、失败次数、同步延迟、知识库差异数、n8n 激活不一致数。
- 集成测试必须覆盖 PostgreSQL 成功但下游失败、重复投递、消费者重启、补偿失败和每日巡检修复。

## 结果

用户可看到明确的处理中/失败状态，运维可以重放和对账；系统不再依赖一次 HTTP 请求把全部存储恰好写成功。
