Версионный ODS заказов: строгий переход, брак и ods.order_v #94
Notifications
Due Date
No due date set.
Blocks
Depends on
#96 Стартовый мир: слепки дней 0…6 при make up
ddmitry/clickstream-data-platform
#93 Топик orders, байтовый чтец и даг приёма: забор в STG
ddmitry/clickstream-data-platform
Reference: ddmitry/clickstream-data-platform#94
Reference in New Issue
Block a user
Part of #5.
Цель
Типизированные версии заказов: один следующий
task_idдага приёма, двапоследовательных
INSERT SELECTпо неизменному срезу_load_id— годныестроки в
ods.order_snapshot, брак в_errors;ods.order_v—единственный корректный способ прочитать текущее состояние. Учебный
результат (
ingestion.md): менти различает версию бизнес-сущности,наблюдение источника и запуск загрузки.
Что войдёт
ods.order_snapshot_rep/_dist:ReplacingMergeTree(updated_at),ORDER BY order_id, партиция по дню неизменногоcreated_at,шардирование
cityHash64(order_id)— только так версии одного заказаоказываются на одном шарде и
FINALкорректен через распределённуютаблицу.
ods.order_snapshot_errors_rep/_dist: сырой текст, метаданныедоставки,
_load_id, класс брака. Сроки хранения и типы — по конвенциямstorage.md.task_idдага приёма после забора: общийпредикат брака и его буквальное отрицание; функции предиката не бросают
исключений, предикат всегда заканчивается в
true/false, не вNULL.Транзакции между целями нет: при частичном сбое повторяется весь
task_id, служебные метки не вычисляются заново.11 ключей; скаляры по типу JSON; деньги — строки с ровно двумя знаками;
времена — RFC 3339 в UTC с миллисекундами;
snapshot_date—YYYY-MM-DD;items— только JSON-массив, внутрь не смотреть.not_an_object→keyset_mismatch→field_invalid; имя поля в класс не входит.ods.order_v: сначала простое представление над_dist FINAL; способвыбора можно заменить, не меняя потребителей.
ingestion.mdтем же PR;storage.md— при расхождении.Границы
ingestion.md, «Не входит», целиком: поля внутриitems, переходы статусаи равенства сумм не проверять; модель DDS не строить (
_load_idвыше ODS —#85, этап 4); удаление заказа по отсутствию в слепке не делать; маркер конца
слепка и транзакция между целями не заводятся.
Кому что
Строгий предикат и DDL — Opus: учебный SQL, на котором стоит урок тикета. Кодексу — опыты: малая порция брака, повторы
task_id, уборка партиции-донора. Бриф Кодексу обязан требовать: проверять свойство, а не текст вывода грепом; только POSIX-инструменты (ripgrep на машине стенда нет); вердикт «недостижимо» перепроверять на достижимость, а не на факт.Сначала прочитать
docs/architecture/orders/ingestion.md— целиком, это спека тикета;docs/adr/0010-order-versions-in-ods.md;docs/research/2026-08-16-order-snapshot-wire-format.md;docs/architecture/storage.md— конвенции и сроки;docs/architecture/testing.md— «Интеграционная проверка постояннойцелью не становится»: за опытами прибираются;
приёмника; при показе красного через правку Python —
PYTHONDONTWRITEBYTECODE=1; ожидание — опросом с таймаутом; инструментыPOSIX.
Проверка
Опыты — разовая приёмка, не постоянные сторожа; результаты — в тело PR.
Опытные строки кладутся в партицию за границей оси мира (день вне эталона)
и сносятся после опыта — данные, которых мир не рождал, не должны лечь в
лабы менти. Расхождение опыта с ожиданием — вопрос владельцу, а не починка
на месте.
make lint,make config-test; на стендеmake smoke,make check-clickhouseзелёные._errorsпуст, сумма «годные плюс брак» равначислу отправленных.
годные версии одного
order_id— обе цели сохранили все непустыесообщения,
ods.order_vвернула новую версию независимо от фоновогослияния.
task_idс тем же_load_id: строка вods.order_vи её_load_tsне изменились; версии одного заказа — на одном шарде и водной партиции. Таблица ошибок может записать тот же брак повторно:
совпавшие
_load_idи Kafka-координаты показывают повтор задачи._errorsне остались.