---
description: "领域建模的 ADR 格式：放在 docs/adr/ 顺序编号，一段话就够；三条全成立才写，哪些决策够格"
---

# ADR 格式

ADR 放在 `docs/adr/`，按顺序编号：`0001-slug.md`、`0002-slug.md`，依此类推。

`docs/adr/` 目录按需创建：需要第一份 ADR 时才建。

## 模板

```md
# {决策的简短标题}

{1–3 句话：背景是什么，决定了什么，为什么。}
```

就这些。一份 ADR 可以只有一段。价值在于记下*做过*这个决定、*为什么*，而不在于把各节填满。

## 可选的节

只在真有价值时才加。大多数 ADR 用不上。

- **Status** frontmatter（`proposed | accepted | deprecated | superseded by ADR-NNNN`）：决策会被重新审视时有用
- **Considered Options**（考虑过的选项）：只在被否掉的备选值得记住时
- **Consequences**（后果）：只在需要点出不明显的下游影响时

## 编号

扫一遍 `docs/adr/`，找到现有的最大编号，加一。

## 什么时候提出写 ADR

下面三条必须全部成立：

1. **难以回退**：日后改主意的代价不小
2. **缺了上下文会让人意外**：未来的读者看着代码会纳闷「他们到底为什么这么做？」
3. **真实取舍的结果**：确实有别的选项，出于具体理由选了其中一个

决策容易回退，就跳过：回退就是了。不让人意外，就没人会问为什么。没有真正的备选，除了「做了显而易见的事」也没什么可记。

### 哪些够格

- **架构形态。**「我们用 monorepo。」「写模型用事件溯源，读模型投影进 Postgres。」
- **上下文之间的集成方式。**「Ordering 和 Billing 之间走领域事件，不走同步 HTTP。」
- **带锁定效应的技术选型。** 数据库、消息总线、认证服务商、部署目标。不是每个库都算：只算那些换掉要花一个季度的。
- **边界与范围的决定。**「客户数据归 Customer 上下文所有；其他上下文只按 ID 引用。」明确说「不」的决定和说「是」的一样有价值。
- **有意偏离显而易见的路。**「我们手写 SQL、不用 ORM，因为 X。」凡是讲道理的读者会默认相反做法的地方都算。这类记录能拦住下一个工程师把有意为之的东西「修」掉。
- **代码里看不到的约束。**「合规要求不允许用 AWS。」「响应时间必须低于 200ms，因为合作方的 API 合同这么规定。」
- **否掉的备选，当否掉的理由不明显时。** 考虑过 GraphQL、出于微妙的原因选了 REST，就记下来；不然半年后又会有人提 GraphQL。
