# Часть 11. Проверка данных: validation.md В SDD проверка — это не фраза «данные корректны». Это набор фактов. В дата-проекте факт должен связывать спецификацию, SQL и доказательство. Если факт нельзя выполнить командой, SQL-запросом или ручным шагом ревьюера, он пока не готов. ## Пример проверочных фактов ```markdown ### F1 — Customer 360 grain - Команда: `dbt test --profiles-dir . --select mart_customer_360` - Ожидание: `customer_id` unique и not_null. - Статус: принято. ### F2 — PII не попало в mart - Команда: `dbt test --profiles-dir . --select assert_customer_360_no_direct_pii` - Ожидание: тест возвращает 0 строк. - Статус: принято. ``` ## Автоматические и ручные факты Автоматические факты запускаются командой. Ручные факты требуют чтения изменения или подтверждения бизнеса. Оба типа нужны. dbt не знает, что «активный клиент» определён правильно, если это не записано в спецификации. Хороший ручной факт: ```markdown Ревьюер подтвердил, что добавление `product_code` изменило бы grain и не входит в эту фазу. ``` Плохой ручной факт: ```markdown Выглядит нормально. ``` ## Где хранить validation В учебном примере заметки о проверке лежат в `specs/validation/`. Это не обязательно единственное место, но правило такое: validation.md должен быть версионируемым и читаемым после `/clear`. Если факт живёт только в чате, он не может быть доказательством релиза. ## Qwen-запрос ```text Создай черновик validation.md для mart_customer_360. Используй specs/models/mart_customer_360.md, ODCS, ODPS и models/schema.yml. Не меняй dbt-модели. ``` ## Минимальный выход Минимальный `validation.md` для витрины должен содержать: - один факт про grain; - один факт про PII; - один факт про обязательные поля контракта; - один факт про lineage или список входных моделей; - один ручной факт: изменение не меняет поля контракта без утверждения. Если факт нельзя проверить, перепишите его как команду, SQL-запрос, dbt-тест или шаг ревьюера. ## Разбор для читателя `validation.md` — место, где учебник намеренно становится строгим. Пока факт не имеет команды, SQL-запроса или ручного шага ревьюера, он остаётся пожеланием. Фраза «данные корректны» ничего не защищает: агент может считать корректностью отсутствие ошибок выполнения, аналитик — отсутствие пустых значений, владелец продукта — сохранение grain. Проверочный факт убирает эту двусмысленность. Не все факты нужно автоматизировать. В данных есть решения, которые требуют чтения изменения и понимания контракта. Например, dbt может доказать, что `customer_id` уникален, но он не решит, допустимо ли добавление `product_code` в Customer 360. Такой факт лучше оставить ручным и явно назначить ревьюеру. Ручной не значит слабый; слабым он становится только тогда, когда не указано, что именно читать и какой вывод сделать. Хорошая заметка о проверке связывает несколько слоёв: спецификацию модели, ODCS, `models/schema.yml`, singular-тесты и отчёт ревьюера. Если один из слоёв изменился, `validation.md` должен показать, какие факты нужно пересмотреть. Это делает изменение данных похожим на инженерный процесс, а не на набор разрозненных SQL-патчей. Читателю стоит привыкнуть писать `validation.md` до SQL. Это неудобно только в первый раз. Потом проверочные факты начинают помогать: они ограничивают размер решения, подсказывают, какие тесты нужны, и дают ревьюеру готовую рубрику. Если `validation.md` пишется после SQL, этот файл часто превращается в оправдание уже сделанного. ## Практика Возьмите один слабый пункт вроде «проверить качество данных» и перепишите его в три формы: dbt-команда, SQL/singular-тест и ручной факт ревьюера. ## Типичная ошибка Писать «проверить качество данных». Это не факт. Факт звучит так: «`customer_id` уникален в `mart_customer_360`, команда `dbt test --select mart_customer_360` возвращает код выхода 0». ## Контрольные вопросы 1. Чем проверочный факт отличается от пожелания? 2. Какие факты нельзя полностью автоматизировать? 3. Почему ревьюер должен читать validation.md до изменения?