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

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

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

Формат

Минимальный рабочий формат — четыре секции (это ядро и классического шаблона Майкла Найгарда, и MADR):

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

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

## Контекст

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

## Решение

Батчевый Java-консьюмер в сервисе заказов.

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

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

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

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

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

Жизненный цикл

  • Статусы: proposedaccepted → (superseded by ADR-NNN | deprecated). ADR не редактируют задним числом: решение изменилось — пишется новый, старый получает superseded и ссылку. История споров остаётся читаемой.
  • Нумерация сквозная и навсегда: ADR-007 не переиспользуется, даже если решение отменено.
  • Хранение — в репозитории, рядом с кодом, который решение описывает: docs/adr/ADR-007-clickhouse-pipeline.md. Решения платформенного уровня (границы сервисов, общие контракты) — в архитектурном репо рядом с context map. В вики ADR умирают: их не ревьюят с кодом и не находят при чтении репозитория.
  • Ревью — тем же PR-процессом, что и код. proposed-ADR в PR — лучший способ обсудить развилку до того, как написаны тысячи строк.

Когда писать — и когда нет

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

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

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

  • ADR постфактум-археология. Через год решили «задокументировать всё, что есть» и написали двадцать ADR по памяти. Контекст уже утерян, получились описания, не решения. ADR пишется в момент выбора.
  • ADR без альтернатив. «Решили взять X» — а что отвергли и почему? Без отвергнутых вариантов следующий спорщик принесёт их снова.
  • Правка вместо superseded. Тихо переписали ADR-003 под новое решение — история умерла, ссылки на старое врут.
  • ADR как простыня. Десять страниц с диаграммами — это design doc, не ADR. Решение должно читаться за пару минут; детали — по ссылкам.
  • Решение есть, ADR «потом». «Потом» не наступает. ADR входит в definition of done той задачи, где развилка решилась.

ADR и UCP-спека

Это разные жанры, и они не заменяют друг друга: спека описывает, что система делает (use cases, инварианты, события) и обновляется при каждом изменении поведения; ADR фиксирует, почему она так устроена, и не меняется никогда. Спека — живая карта, ADR — журнал свернувших развилок. Платформенные решения дополнительно отражаются в context map архитектурного репозитория — но первоисточник «почему» всегда ADR.

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

  • Монолит или микросервисы, PG vs ClickHouse, sync vs async — развилки, итоги которых стоят ADR.
  • Что делает архитектор — чья обязанность довести развилку до записанного решения.
  • Модель C4 — диаграммы описывают структуру, ADR — причины; работают в паре.
  • Use Case спецификация — «что делает система», парный жанр к «почему так».