Часть 16. Витрина Customer 360
mart_customer_360 — первая финальная витрина. Она объединяет атрибуты клиента, остатки на счетах и карточную активность. Это главный учебный пример: здесь видно, как спецификация продукта, ODCS, спецификация модели, dbt-тесты и проверочные факты должны работать вместе.
Приёмочные факты
- одна строка на
customer_id; customer_idnot null и unique;- нет прямого PII;
total_balance_rubnot null;risk_event_count_7dnot null;- обязательные поля контракта присутствуют;
- lineage читается через
ref().
Реализация
Откройте:
models/marts/mart_customer_360.sql
models/schema.yml
specs/models/mart_customer_360.md
specs/validation/customer_360.md
Проверьте, что SQL следует спецификации, а тесты покрывают ключевые факты. Не ограничивайтесь чтением SQL: утечка PII и дрейф контракта должны иметь отдельные проверки.
Матрица приёмки
| Факт | Доказательство |
|---|---|
одна строка на customer_id | dbt-тест unique |
customer_id не пустой | dbt-тест not_null |
| нет прямых PII | singular-тест схемы |
| общий остаток присутствует | dbt-тест not_null |
| счётчик риска присутствует | dbt-тест not_null |
| поля контракта присутствуют | singular-тест колонок контракта |
Если строка доказательства пустая, это не готовность, а пробел.
Qwen-запрос
Сравни models/marts/mart_customer_360.sql, models/schema.yml,
specs/customer_360_contract.odcs.yaml и specs/validation/customer_360.md.
Покажи, какие приёмочные факты покрыты, какие ручные, а какие отсутствуют.
Файлы не меняй.
Минимальный выход
Подготовьте заметку ревьюера:
Гранулярность: одна строка на `customer_id`.
PII: нет прямых PII.
Поля контракта: `customer_id`, `total_balance_rub`, `risk_event_count_7d`.
Проверки: `dbt build`, mart-тесты, список запрещённых PII, колонки контракта.
Открытые вопросы: определение `risk_event_count_7d` зависит от входного риск-флага.
Разбор для читателя
Customer 360 — хороший первый mart, потому что название знакомое и поэтому опасное. Почти каждый участник проекта думает, что понимает его смысл, но у разных людей это разные таблицы. Для аналитика это может быть срез клиента. Для маркетинга — профиль с сегментами. Для риска — агрегаты поведения. Для операционной команды — набор идентификаторов. SDD заставляет выбрать одну версию обещания и записать её до SQL.
В этой книге Customer 360 намеренно ограничен. Одна строка на клиента. Прямые PII не раскрываются. Остаток считается из счетов. Риск-события берутся из синтетического окна активности. Такое ограничение может показаться бедным, но оно делает пример честным: каждое поле можно связать со спецификацией и проверкой. Если добавить всё сразу, студент увидит большую таблицу, но не увидит дисциплину продукта.
Особое внимание нужно уделить risk_event_count_7d. Само имя обещает семидневное окно. Если SQL просто считает все риск-события, поле выглядит правдоподобно, но обманывает потребителя. Поэтому окно должно быть описано и проверено отдельным тестом. Это маленький пример большой идеи: название поля становится частью контракта. Если имя содержит срок, валюту, статус или уровень агрегации, проверка должна подтвердить именно это.
Customer 360 также показывает, почему политику PII нельзя оставлять общей фразой. В raw и staging может быть pii_email, чтобы студент увидел риск. В mart его быть не должно. Это не вопрос эстетики схемы, а граница продукта. Ревьюер должен смотреть не только на итоговый select, но и на тест, который доказывает отсутствие прямых PII-полей.
Практика
Запустите только проверки Customer 360 и сопоставьте каждую строку вывода с матрицей приёмки. Если факт подтверждается только ручным ревью, так и запишите.
Типичная ошибка
Проверять только SQL глазами. В SDD нужно доказательство: dbt-тест, ревью схемы, явный проверочный факт или отчёт ревьюера.
Контрольные вопросы
- Почему
pii_emailне должен попасть в mart? - Какие поля делают витрину уровнем клиента?
- Что изменится, если добавить детализацию по продукту?