docs(orders): документация перестроена вокруг текущей модели

- Зачем:
  - описание вело нового читателя через историю исправления вместо действующего
    контракта слоёв.
- Что:
  - прямо описаны версия заказа, границы пакетного приёма и расчёт окна DDS.
  - ответственность ODS, DDS и конвейера разделена без ссылок на прежние
    ошибки как на основной довод.
  - исторический вывод исследования помечен до устаревшего абзаца, а ссылки
    ведут к отдельным решениям и контрактам.
- Проверка:
  - make lint.
  - make config-test.
This commit is contained in:
ddadmin committed 2026-08-26 18:47:22 +03:00
1 parent a82c75705d
commit a9cead2974
6 files changed
+68 -74

No files matched your search

+22 -26
View File
@@ -7,10 +7,10 @@
## Проблема
Заказы приезжают полным слепком окна изменяемости, но Kafka передаёт его
отдельными сообщениями и не сообщает потребителю, где слепок закончился. Прямое
чтение Kafka Engine возвращает одну порцию. Поэтому прежняя публикация через
`REPLACE PARTITION snapshot_date` приравнивала дату наблюдения к отсутствующей
транспортной границе и могла заменить день неполным набором строк.
отдельными сообщениями и не сообщает потребителю, где слепок закончился.
Прямое чтение Kafka Engine возвращает одну порцию без признака полноты.
Поэтому `snapshot_date` не может служить границей публикации: `REPLACE
PARTITION` могла бы заменить партицию дня неполным набором строк.
Одновременно типизированный ODS не должен принимать правдоподобные значения по
умолчанию из грязного JSON или останавливать весь пакет из-за одной строки.
@@ -81,11 +81,11 @@ JSON-объектом с точным набором ключей: `order_id`, `
малый контракт заказа нет причины. Граница строгости заканчивается на форме
провода: содержимое позиций и бизнес-инварианты намеренно остаются ниже.
Одно условие контракта предикатом не проверить, и названо оно всё равно
здесь: **одна дата — один слепок**. Вторую выгрузку того же дня приём не
отличит от первой, а колонка версии — дата слепка — на ней даёт ничью.
Модельный источник выгружает день один раз; настоящему такое условие ставят
договором, а не предикатом
Контракт источника задаёт частоту: **одной дате соответствует один слепок**. Это
свойство всего слепка, поэтому предикат одной строки его не проверяет. Вторая
выгрузка того же дня даст ничью по `snapshot_date`, и выбор строки потеряет
однозначность. Модельный источник выполняет условие; в настоящей интеграции
его фиксируют в договоре с источником
([ADR 0014](../../adr/0014-order-version-snapshot-date.md)).
Класс брака выбирается первым совпадением:
@@ -113,11 +113,11 @@ JSON-объектом с точным набором ключей: `order_id`, `
- `_load_id` — какой запуск Airflow принял строку;
- `_load_ts` — когда строка приехала в хранилище.
Версию выбирает `snapshot_date`: выживает строка позднейшего слепка
([ADR 0014](../../adr/0014-order-version-snapshot-date.md)). Поэтому ярлык
выжившей строки — правдивый ответ на вопрос «когда заказ видели в последний
раз», и по нему трансформация DDS читает объём пересборки. `_load_id` и
`_load_ts` выжившей строки говорят про ту же доставку.
Версию выбирает `snapshot_date`: выживает строка с максимальной датой слепка
([ADR 0014](../../adr/0014-order-version-snapshot-date.md)). Поэтому
`snapshot_date` показывает последнее наблюдение заказа. По строкам последней
даты слепка DDS определяет окно пересборки. `_load_id` и `_load_ts` принадлежат
той физической строке, которую сохранило слияние, и описывают её доставку.
Схема версий стоит на дисциплине источника: слепок с поздней датой не
показывает состояния старше. Модельный мир её держит — состояние читается на
@@ -211,19 +211,15 @@ dbt snapshots — стратегия `check` вместо `timestamp`.
`system.query_log` на первой ноде осталось ровно по одному завершённому запросу
пользователя `etl` для забора в STG, записи годных строк и записи брака.
Дисциплина источника замерена 22 августа 2026 года при исполнении #137: во
всех 3034 парах строк с равным `updated_at` деловые поля совпали побайтово, по
слепкам метка ни разу не убывала, а `ods.order_v` сошёлся построчно с эталоном
`argMax` по `updated_at`, посчитанным прямо из сырья. Тем же замером виден
произвол ярлыка при версии по деловой метке — довод, на котором стоит
[ADR 0014](../../adr/0014-order-version-snapshot-date.md).
Дисциплина источника замерена 22 августа 2026 года при исполнении #137.
Во всех 3034 парах строк с равным `updated_at` деловые поля совпали
побайтово, а по слепкам метка ни разу не убывала.
Правдивость ярлыка снята на пересобранном мире 26 августа 2026 года при
исполнении #165. После двух слепков `snapshot_date` каждой из 1917 строк
`ods.order_v` равен последнему слепку, который нёс её заказ: расхождений ноль
при 3356 физически лежащих строках — выбор был не единственным. Деловое
содержимое сменой колонки версии не тронулось: те же строки построчно совпали
с эталоном `argMax` по `updated_at` из сырья по всем полям.
Текущее состояние проверено на пересобранном мире 26 августа 2026 года при
исполнении #165. После двух слепков физическая таблица содержала 3356 версий
1917 заказов. У всех строк `ods.order_v` дата слепка совпала с последним
слепком заказа; деловые поля совпали с эталоном `argMax` по `updated_at` из
сырья. В обеих сверках расхождений нет.
Забор из Kafka в STG снят на живом стенде 18 августа 2026 года при исполнении
#93: одно прямое чтение приносит весь слепок дня, метаданные доставки доступны,