Звено DQ конвейера и dm.dq_summary #158
Notifications
Due Date
No due date set.
Depends on
#155 Сверка purchase против заказов: dm.purchase_vs_orders (A+C)
ddmitry/clickstream-data-platform
#156 Конвейер etl_pipeline: сцепка дагов и пути запуска
ddmitry/clickstream-data-platform
#157 Опись мира: счётчики классов A и C
ddmitry/clickstream-data-platform
Reference: ddmitry/clickstream-data-platform#158
Reference in new issue
Block a user
Part of #6.
Цель
Контур качества конвейера: даг
dq_checkзвеномetl_pipelineпосле DMи сводка
dm.dq_summaryзерном «день данных × проверка» с заменойпартиций проверенных дней. Учебный результат (dm.md): контроль качества в
бою — по расписанию, с историей, рядом с трансформациями; звено — не
только сторож, но и экспонат.
Что войдёт
dm.dq_summaryпо конвенциям storage.md (_rep/_dist/_v):партиция — день данных; строка отвечает «каково качество дня сейчас»;
состав строки (имя проверки, стороны сверки, расхождение, статус) —
решить с DDL по рамке dm.md; грант
bi_readerна_v.dq_checkпо образцу слойных: без расписания, один активныйпрогон; встаёт звеном
etl_pipelineпослеdm_transform; имязадачи — имя проверки:
sessions_vs_reference— счётная сверка сессий с эталономVisitID,зерно «кука × день», эталон из
ods.event_v(session.md);classes_vs_inventory— счётчики классов сверки против описиdata/world-inventory.json: только дни, которые опись покрывает ичьё окно закрыто; дни, прожитые сверх стартового мира, опись не
описывает — они не проверяются. Проверка техническая, не урок DQ:
её оракул — опись генератора, у настоящего магазина такого нет
(резолюция в #157; dm.md «Звено DQ», термин в CONTEXT.md). Звеном
остаётся и в
dq_summaryпишет наравне с остальными;marts_vs_dds— счётные сверки каждой витрины стенда с еёDDS-источниками; точный список проверок зафиксировать в доке слоя DM
той же правкой.
Airflow, не в таблице.
Границы
dq_errors_daily— учебная витрина, не проверка контура.Кому что
Проверочные запросы — Opus: каждая проверка — урок; у технической
classes_vs_inventoryурок другой — честная табличка комментарием в SQL. Codex — прогон наискусственном расхождении по брифу: порча — в партиции за границей оси
мира, после опыта прибраться (testing.md).
Сначала прочитать
спека тикета;
опись;
Проверка
make lint; на стендеmake smoke,make check-clickhouseиmake check-services(родился даг) зелёные.etl_pipelineна честном мире: звено зелёное; вdq_summary— строка на каждую пару «проверенный день × проверка»,без красных.
искусственном расхождении и валит конвейер; строка дня называет
расхождение.
текущее качество, не история попыток.
Постановка дополнена по резолюции развилки из #157:
classes_vs_inventoryявно помечена технической проверкой (оракул — опись генератора, за урок DQ не выдаётся), остаётся звеном и пишет вdq_summary. Правки словаря — dm.md «Звено DQ», §8 мастер-спеки, inventory.md, термин «Техническая проверка» в CONTEXT.md — едут веткой 157.Аудит готовности постановки — 27 августа 2026
Сверено с живым Gitea и checkout: main / origin/main / удалённый main совпадают на 4e60aaf; открытых PR и рабочих удалённых веток нет. #158 свободна, нативные блокеры #155, #156 и #157 закрыты; необходимая витрина #154 тоже уже в main.
Механика источников описана достаточно: сессии сравниваются с uniqExact(VisitID) в зерне «кука × день»; опись доступна Airflow по /opt/airflow/world/data/world-inventory.json и покрывает только закрытые дни; три стендовые витрины и их прямые DDS-агрегаты уже приняты в #154/#155.
Для холодной реализации постановка пока недостаточна: не определён публичный контракт dm.dq_summary_v. Фраза «день × проверка; стороны, расхождение, статус» не отвечает, как одной строкой представить:
Веер вариантов:
Рекомендация: вариант 1. Он сохраняет принятое зерно и три имени задач, а таблица остаётся именно сводкой. Единица сравнения определяется запросом: кука для сессий, класс для описи, проверяемая мера/ключ для витрин; несовпадения между элементами не компенсируются.
Стык красной задачи и REPLACE PARTITION решается без all_done, в рамках ADR 0003: проверки сначала собирают общий донор; общая публикация заменяет дневные партиции; затем три задачи sessions_vs_reference, classes_vs_inventory и marts_vs_dds читают уже опубликованные строки и краснеют при ненулевом числе несовпадений. Ошибка сборки или публикации не затирает прежнюю сводку, а расхождение уже видно в dq_summary до падения именованной задачи.
До подтверждения владельцем вариант 1 — предложение, не решение. После выбора стоит отдельным комментарием закрепить точные колонки и смысл единицы сравнения; код и docs пока не трогать.
Принятая резолюция: договор DQ-сводки
Владелец подтвердил направление 27 августа 2026 года. Предыдущий комментарий с веером вариантов считать обсуждением; ниже — решение.
Чему учится менти
Проверка формулируется на естественном деловом зерне и возвращает нарушившие договор ключи. Общие итоги не имеют права скрыть две компенсировавшие друг друга ошибки. Сводка отвечает, что сломано сейчас; Airflow отвечает, в каком прогоне это случилось.
Публичный договор
Зерно dm.dq_summary_v — «день данных × атомарная проверка». Деловые колонки:
К ним добавляются обычные служебные координаты собравшего запуска. Порогов и промежуточного статуса нет. Публичное _v перечисляет колонки явно; bi_reader читает только его.
Имена атомарных проверок:
Единица сравнения
Каждый запуск проверяет всю покрытую историю стенда. Область всегда выводится из объединения сторон, чтобы полностью потерянный день не исчез из проверки: для сессий — завершённые дни из ods.event_v и dds.session_v; для описи — покрытые закрытые дни; для каждой витрины — дни её DDS-источников и самой витрины. На учебном объёме это быстро и не требует протаскивать между дагами внутренний список изменённых партиций. Производственное сокращение области проверки можно обсуждать отдельно, когда появится цена полного прогона.
Диагностика
Сводка остаётся короткой. Красная задача печатает малый ограниченный срез несовпавших ключей вместе со значениями обеих сторон; полный список воспроизводится тем же SQL проверки. Отдельную постоянную таблицу нарушивших строк, историю DQ-прогонов, сроки хранения и обработку чувствительных образцов сейчас не заводим: это отдельный урок, у которого пока нет читателя.
marts_vs_dds остаётся видимым семейством в графе, но становится группой трёх атомарных проверок витрин. Так граф показывает общий сюжет, а красная задача и check_name сразу называют сломавшуюся витрину.
Публикация и красный запуск
Все запросы сначала собирают общий донор. Только после успешной сборки общая задача заменяет партиции проверенных дней в dq_summary. Затем именованные задачи-утверждения читают уже опубликованные строки и краснеют при failed_rows > 0.
Так расхождение успевает попасть в dq_summary до отказа, а ошибка самой сборки или публикации не заменяет текущую сводку неполным результатом. all_done не нужен; правило ADR 0003 о красном конце графа сохраняется.
Следующий успешный прогон заменяет дневные партиции и убирает прежнее расхождение. В ClickHouse хранится текущее качество дня, история попыток остаётся в Airflow.
Не входит
С этой резолюцией архитектурных решений за исполнителем не остаётся. Итоговые формулировки и точный список сравниваемых деловых колонок переносятся в dm.md той же реализацией, как требует постановка.