← назад к разделу

Каждый проект накапливает десятки выборов: взяли ClickHouse вместо PostgreSQL, события вместо REST, пакетный потребитель вместо Kafka-движка. Пока решение свежее, оно живёт в голове команды. Через год приходит новый разработчик — или вы сами после отпуска — и спрашивает: «почему здесь так сделано?» Если ответ лежит в закрытом треде мессенджера или вообще нигде — решение будут пересматривать заново, с теми же спорами и теми же граблями.

ADR (Architecture Decision Record) — короткий документ, который фиксирует одно архитектурное решение: что решили, в каком контексте и чем заплатили. Не проектная документация и не описание системы — именно конкретный выбор в конкретной ситуации.

Откуда взялся формат

В 2011 году Майкл Найгард описал простой шаблон: контекст, решение, последствия. Позже появился MADR (Markdown Architecture Decision Records) — чуть расширенный вариант с явными альтернативами. Оба варианта сводятся к одному ядру, разница — в деталях оформления.

Как выглядит ADR

Минимальный рабочий формат — четыре секции:

# ADR-007: События в ClickHouse через Kafka-потребитель, не Kafka-движок

Статус: accepted (2026-06-06)
Заменяет: —

## Контекст

Аналитика заказов переезжает в ClickHouse (ADR-005). События уже идут
через outbox в Kafka. Нужно выбрать способ доставки Kafka → ClickHouse:
потребитель в сервисе, Kafka-движок ClickHouse или Debezium-пайплайн.

## Решение

Пакетный потребитель в сервисе заказов.

## Альтернативы

- Kafka-движок ClickHouse: нет прикладного кода, но повторные попытки,
  маппинг и алерты уезжают в DDL, который команда сервиса не видит
  и не ревьюит.
- Debezium CDC: зеркалит строки, а нам нужны доменные события.

## Последствия

+ Маппинг и повторные попытки в кодовой базе сервиса, под обычным ревью и тестами.
+ Идемпотентность контролируем сами (ReplacingMergeTree по event_id).
− Потребитель — ещё один компонент сервиса: deployment, мониторинг lag.
− При смене схемы события правим и потребитель, и таблицу.

Две секции принципиальны. Контекст — без него решение нечитаемо: «взяли потребитель» бессмысленно, «взяли потребитель, потому что владение пайплайном должно остаться у команды сервиса» — знание. Последствия с минусами — ADR без минусов это реклама; честные «чем платим» избавляют будущего читателя от иллюзии, что решение бесплатное.

Статусы и жизненный цикл

ADR проходит через несколько статусов: proposedacceptedsuperseded или deprecated.

Важное правило: ADR не редактируют задним числом. Если решение изменилось — пишется новый документ, старый получает статус superseded со ссылкой на новый. История споров остаётся читаемой, а не затирается.

Нумерация сквозная и навсегда: ADR-007 не переиспользуется, даже если решение отменено. Это позволяет ссылаться на конкретный документ и всегда найти его по номеру.

Статус proposed удобен при обсуждении: ADR создаётся ещё в pull request, пока решение не принято. Это лучший способ обсудить развилку до того, как написаны тысячи строк кода.

Где хранить

В репозитории, рядом с кодом, который решение описывает: docs/adr/ADR-007-clickhouse-pipeline.md. Решения платформенного уровня — границы сервисов, общие контракты — хранят в архитектурном репозитории рядом с картой сервисов.

В вики ADR умирают: их не ревьюят вместе с кодом и не находят при чтении репозитория.

Когда писать ADR

Писать, когда решение дорого отменить и неочевидно без контекста: выбор хранилища, способа интеграции, формата событий, стратегии миграции, отказ от чего-то ожидаемого («не используем этот ORM», «не версионируем этот API»).

Хорошая проверка: если на ревью или в чате возник спор длиннее десяти сообщений — итог спора стоит ADR.

Не писать: на решения, продиктованные стандартом команды (для этого есть руководство по стилю — оно само по себе большой ADR), на обратимые мелочи (имя пакета, вспомогательная библиотека), на то, что очевидно из кода. ADR на каждый чих обесценивает жанр — их перестают читать.

Типичные ошибки

ADR по памяти через год. Решили «задокументировать всё, что есть» и написали двадцать ADR постфактум. Контекст уже утерян, получились описания, а не решения. ADR пишется в момент выбора.

ADR без альтернатив. «Решили взять X» — а что отвергли и почему? Без отвергнутых вариантов следующий человек принесёт их снова.

Правка вместо superseded. Тихо переписали ADR-003 под новое решение — история умерла, ссылки на старое врут.

ADR как длинное сочинение. Десять страниц с диаграммами — это проектный документ, не ADR. Решение должно читаться за пару минут; детали — по ссылкам.

Решение есть, ADR «потом». «Потом» не наступает. ADR входит в критерии готовности той задачи, где развилка решилась.

Коротко

  • ADR — короткий документ об одном архитектурном решении: что решили, почему, какие были альтернативы и чем заплатили.
  • Формат: контекст + решение + альтернативы + последствия (с плюсами и минусами).
  • Статусы: proposedacceptedsuperseded / deprecated; старый ADR не редактируется, пишется новый.
  • Хранить рядом с кодом в docs/adr/, не в вики — иначе не найдут и не ревьюят.
  • Писать в момент выбора, не постфактум; вносить в критерии готовности задачи.
  • Не писать на стандартные решения, обратимые мелочи и очевидное из кода.

Что почитать дальше

  • Монолит или микросервисы — классическая развилка, итог которой стоит ADR.
  • Что делает архитектор — чья обязанность довести развилку до записанного решения.
  • Модель C4 — диаграммы описывают структуру, ADR — причины; работают в паре.