- Зачем: - отменённая подмена партиции snapshot_date противоречила порционному чтению Kafka и могла обучать потере ранее принятых версий. - Что: - добавлены спецификация приёма заказов и ADR о версионном ODS с ods.order_v. - согласованы мастер-спека, дока хранилища, ADR 0008 и исследование формата. - зафиксированы граница приёма, координаты загрузки, диагностические повторы и отложенное проектирование DDS. - Проверка: - git diff --cached --check. - горячее ревью по правилам репозитория и принятому решению. - два прохода холодного ревью.
38 lines
3.1 KiB
Markdown
38 lines
3.1 KiB
Markdown
# ADR 0010. Заказы в ODS: версии сущности вместо подмены слепка
|
||
|
||
Дата: 16 августа 2026 года. Статус: принято. Частично заменяет
|
||
[ADR 0008](0008-order-ingestion.md).
|
||
|
||
## Решение
|
||
|
||
Пакетный забор заказов остаётся прямым чтением байтового Kafka-чтеца по
|
||
команде Airflow, но порция чтения больше не считается полным слепком и не
|
||
публикуется заменой партиции `snapshot_date`. Прочитанные строки получают
|
||
`_load_id` запуска, разбираются из одного среза STG в годные строки и ошибки,
|
||
а `ods.order_snapshot` хранит принятые версии заказа в
|
||
`ReplacingMergeTree(updated_at)`. Ключ сущности — `order_id`, партиция строится
|
||
от неизменного `created_at`, все версии ключа направляются на один шард.
|
||
|
||
`snapshot_date` остаётся датой наблюдения источника, `_load_id` — координатой
|
||
запуска приёма, `_load_ts` — временем прибытия строки. Ни одна из них не
|
||
заменяет бизнес-версию `updated_at`. Физическая таблица может показывать
|
||
несколько версий; точное текущее состояние ODS открывает `ods.order_v`, которое
|
||
скрывает `FINAL` или равносильный способ выбора последней версии.
|
||
|
||
Модель заказа в DDS этим решением не задаётся. DDS получает устойчивую
|
||
типизированную поверхность ODS и отдельно решает зерно, связи и способ
|
||
материализации своей модели.
|
||
|
||
## Почему отменена подмена партиции
|
||
|
||
Прямой `SELECT` Kafka Engine заканчивается после одной полученной порции, а
|
||
протокол не несёт признака конца слепка. Поэтому `snapshot_date` не доказывает,
|
||
что в STG собрана полная партиция, и её подмена могла бы удалить уже принятые
|
||
версии прошлого дня. Маркер конца, опись или фиксация конечных офсетов сделали
|
||
бы границу настоящей, но добавили бы новый протокол без нужного стенду урока.
|
||
|
||
Малый объём позволяет оставить одно чтение на запуск как проверяемое
|
||
эксплуатационное допущение, а не границу полноты. Полный контракт разбора,
|
||
граница брака и поведение повторов заданы в
|
||
[спецификации приёма заказов](../specs/2026-08-16-order-ingestion.md).
|