Учебный гайд: Часть 16. Витрина Customer 360

Урок 3 из 5 в модуле «Часть 16. Витрина Customer 360»
Вы просматриваете урок без входа. Войдите, чтобы сохранять прогресс и проходить тесты.

Тема: Часть 16. Витрина Customer 360

Уровень сложности: Средний

Расчётное время изучения: 4-6 часов

Предварительные требования: Базовое понимание SQL и моделей данных

Знакомство с dbt (data build tool) и концепцией ref()

Понимание принципов построения витрин данных (data marts)

Знание концепции SDD (Specification-Driven Development)

Базовое понимание PII (Personally Identifiable Information) и принципов работы с персональными данными

Опыт работы с YAML-файлами и markdown-документацией

Цели обучения: Объяснить назначение и архитектуру витрины mart_customer_360 как первого финального мартa в проекте

Сопоставить SQL-реализацию, схему, спецификацию и приёмочные факты для выявления пробелов покрытия

Применять матрицу приёмки для верификации выполнения каждого приёмочного факта конкретным типом доказательства

Выявлять и предотвращать утечку PII-полей из staging/raw слоёв в финальный mart

Конструировать dbt-тесты (unique, not_null, singular) для доказательства приёмочных фактов

Обзор: Часть 16 курса посвящена витрине mart_customer_360 — первой финальной витрине в проекте, которая объединяет атрибуты клиента, остатки на счетах и карточную активность. Этот раздел является центральным учебным примером, демонстрирующим, как должны согласованно работать спецификация продукта, ODCS (Open Data Contract Standard), спецификация модели, dbt-тесты и проверочные факты. Особое внимание уделяется дисциплине продукта: витрина намеренно ограничена — одна строка на клиента, без прямых PII, остаток считается из счетов, а риск-события берутся из синтетического окна активности. Такое ограничение делает пример «честным»: каждое поле можно связать со спецификацией и проверкой. Студент учится понимать, почему название поля (например, risk_event_count_7d) становится частью контракта, и почему политику PII нельзя оставлять общей фразой. Витрина Customer 360 — это отправная точка для понимания принципов SDD (Specification-Driven Development), где доказательство готовности строится на матрице приёмки, а не на визуальном ревью SQL.

Ключевые концепции: Mart customer 360: Первая финальная витрина (mart) в проекте, которая объединяет атрибуты клиента, остатки на счетах и карточную активность. Является главным учебным примером интеграции спецификации, реализации и тестирования. Ограничена одной строкой на customer_id.

Приёмочные факты (acceptance facts): Конкретные проверяемые утверждения о витрине, которые должны быть покрыты доказательствами. Включают: одна строка на customer_id, customer_id not null и unique, нет прямого PII, total_balance_rub not null, risk_event_count_7d not null, обязательные поля контракта присутствуют, lineage читается через ref().

Матрица приёмки (acceptance matrix): Таблица, сопоставляющая каждый приёмочный факт с конкретным доказательством (dbt-тест unique, not_null, singular-тест схемы, singular-тест колонок контракта). Если строка доказательства пустая, это не готовность, а пробел.

Odcs (open data contract standard): Стандарт контракта данных, используемый для формального описания спецификации продукта. В контексте витрины — файл specs/customer_360_contract.odcs.yaml, описывающий обязательства по структуре и качеству данных.

Sdd (specification-driven development): Подход к разработке, при котором спецификация пишется до SQL-кода. SDD заставляет выбрать одну версию обещания продукта и записать её заранее, что снижает риск дрейфа контракта.

Dbt-тесты: Автоматизированные проверки в dbt (data build tool), которые служат доказательствами приёмочных фактов. Включают generic-тесты (unique, not_null) и singular-тесты (произвольный SQL для проверки схемы, колонок контракта, отсутствия PII).

Lineage через ref(): Способность читать происхождение данных (data lineage) через функции ref() в dbt. Один из приёмочных фактов: lineage должен быть прозрачным и восстанавливаемым.

Pii (personally identifiable information): Персональные данные, позволяющие идентифицировать субъекта. Политика PII в SDD не может быть общей фразой: в raw и staging допускается pii_email для учебных целей, но в mart его быть не должно. Это граница продукта, а не вопрос эстетики схемы.

Risk event count 7d: Поле счётчика риск-событий за семидневное окно. Само имя обещает семидневное окно, поэтому если SQL просто считает все риск-события, поле выглядит правдоподобно, но обманывает пот消费者. Окно должно быть описано и проверено отдельным тестом. Название поля — часть контракта.

Дрейф контракта (contract drift): Расхождение между заявленной спецификацией и фактической реализацией. Должен иметь отдельные проверки, а не выявляться только визуальным ревью SQL.

Доказательство приёмки: Конкретный артефакт (dbt-тест, ревью схемы, явный проверочный факт, отчёт ревьюера), подтверждающий выполнение приёмочного факта. Без доказательства готовность не засчитывается.

Заметка ревьюера (reviewer note): Минимальный выход артефакта ревью, содержащий: гранулярность, статус PII, поля контракта, перечень проверок и открытые вопросы. Пример: «Гранулярность: одна строка на customer_id. PII: нет прямых PII. Поля контракта: customer_id, total_balance_rub, risk_event_count_7d. Проверки: dbt build, mart-тесты, список запрещённых PII, колонки контракта. Открытые вопросы: определение risk_event_count_7d зависит от входного риск-флага».

Qwen-запрос для ревью: Типовой промпт для LLM-ассистента (Qwen) для сравнения SQL, схемы, ODCS и валидационных файлов с целью выявления покрытых, ручных и отсутствующих приёмочных фактов. Файлы при этом не меняются.

Практические упражнения: Название: Аудит матрицы приёмки

Проблема: Вам передана витрина mart_customer_360. Студент-стажёр утверждает, что всё готово, потому что dbt build прошёл успешно. Проведите аудит: пройдитесь по каждому приёмочному факту и сопоставьте его с доказательством из матрицы приёмки. Определите, какие факты покрыты автоматически, какие требуют ручного ревью, а какие вовсе не имеют доказательства. Файлы: models/marts/mart_customer_360.sql, models/schema.yml, specs/customer_360_contract.odcs.yaml, specs/validation/customer_360.md.

Решение: Шаг 1. Выпишите все приёмочные факты из спецификации: (1) одна строка на customer_id, (2) customer_id not null, (3) customer_id unique, (4) нет прямых PII, (5) total_balance_rub not null, (6) risk_event_count_7d not null, (7) обязательные поля контракта присутствуют, (8) lineage читается через ref(). Шаг 2. Откройте models/schema.yml. Найдите тесты unique и not_null для customer_id, total_balance_rub, risk_event_count_7d. Зафиксируйте: факты (2), (3), (5), (6) покрыты generic-тестами. Шаг 3. Проверьте наличие singular-теста, перечисляющего запрещённые PII-поля (pii_email, pii_phone и т.п.) и сравнивающего со списком колонок mart. Если тест есть — факт (4) покрыт автоматически; если нет — отметьте как требующий ручного ревью. Шаг 4. Найдите singular-тест для колонок контракта (проверка, что в mart присутствуют именно customer_id, total_balance_rub, risk_event_count_7d и другие обязательные поля из ODCS). Шаг 5. Проверьте, что в SQL используются только ref() для upstream-моделей — иначе факт (8) не покрыт. Шаг 6. Сформируйте таблицу покрытия. Если хотя бы одна строка пустая — это пробел готовности, а не готовность.

Сложность: intermediate

Название: Написание singular-теста на отсутствие PII

Проблема: В staging-слое присутствует поле pii_email (для учебных целей и демонстрации риска). Напишите singular-тест для dbt, который проверяет, что в финальной витрине mart_customer_360 это поле отсутствует, а также отсутствуют любые другие колонки, содержащие подстроки 'email', 'phone', 'passport', 'inn'.

Решение: Создайте файл tests/mart_customer_360_no_pii.sql со следующим содержимым:

{{ config(severity='error') }}

with mart_columns as (
    select column_name
    from information_schema.columns
    where table_schema = 'marts'
      and table_name = 'mart_customer_360'
),
forbidden_substrings as (
    select unnest(array['email', 'phone', 'passport', 'inn', 'snils']) as forbidden
)
select m.column_name, f.forbidden
from mart_columns m
cross join forbidden_substrings f
where lower(m.column_name) like '%' || f.forbidden || '%'

Разместите файл в папке tests/ (или в models/marts/ с конфигом {{ config(materialized='test') }}). Тест должен возвращать строки — если результат пуст, PII-полей нет. Добавьте описание теста в schema.yml: description: "Проверяет отсутствие прямых PII-полей в mart_customer_360". Это singular-тест схемы, который служит доказательством приёмочного факта «нет прямого PII».

Сложность: intermediate

Название: Защита окна risk_event_count_7d

Проблема: Поле risk_event_count_7d обещает семидневное окно риск-событий. Текущая реализация в mart_customer_360.sql считает все события из stg_risk_events без фильтрации по дате. Напишите проверочный тест, который (а) фиксирует окно в SQL, (б) добавляет dbt-тест, доказывающий, что счётчик действительно ограничен последними 7 днями относительно даты загрузки.

Решение: Шаг 1. Исправьте SQL-модель mart_customer_360.sql так, чтобы подсчёт шёл только за окно: добавьте условие event_date >= current_date - interval '7 days' или используйте макрос dbt_date. Пример фрагмента: count(case when r.event_date >= current_date - interval '7 days' then 1 end) as risk_event_count_7d. Шаг 2. Создайте singular-тест tests/mart_customer_360_risk_window.sql, который сравнивает подсчёт в mart с эталонным подсчётом за окно из stg_risk_events:

{{ config(severity='warn') }}

with mart as (
    select customer_id, risk_event_count_7d
    from {{ ref('mart_customer_360') }}
),
stg_window as (
    select customer_id,
           count(*) as expected_7d
    from {{ ref('stg_risk_events') }}
    where event_date >= current_date - interval '7 days'
    group by 1
)
select m.customer_id
from mart m
join stg_window s on m.customer_id = s.customer_id
where m.risk_event_count_7d <> s.expected_7d

Шаг 3. Зафиксируйте в спецификации specs/validation/customer_360.md определение окна: «risk_event_count_7d — количество риск-событий клиента за последние 7 календарных дней относительно даты расчёта витрины». Шаг 4. Добавьте в schema.yml у поля risk_event_count_7d описание с указанием окна. Теперь название поля, SQL, тест и спецификация согласованы.

Сложность: intermediate

Название: Проверка lineage через ref()

Проблема: Ревизор подозревает, что в mart_customer_360.sql одна из upstream-моделей подключена не через ref(), а через прямую ссылку на источник (source()). Найдите это нарушение, объясните риск и предложите исправление.

Решение: Шаг 1. Откройте models/marts/mart_customer_360.sql. Проверьте все вызовы в with-блоках и from-секциях: должны быть только {{ ref('stg_customers') }}, {{ ref('stg_accounts') }}, {{ ref('stg_cards') }}, {{ ref('stg_risk_events') }}. Шаг 2. Найдите вызовы {{ source('...', '...') }} — это означает обращение к raw напрямую, минуя staging. Шаг 3. Объясните риск: source() обходит слой трансформаций, нарушает data lineage, делает невозможной проверку качества до mart и создаёт дрейф контракта. Шаг 4. Замените source() на ref() к соответствующей staging-модели. Шаг 5. Запустите dbt compile и убедитесь, что lineage строится корректно (dbt docs generate → откройте визуализацию). Шаг 6. Добавьте singular-тест, сканирующий SQL на наличие source() (опционально, продвинутый уровень).

Сложность: intermediate

Название: Составление заметки ревьюера

Проблема: Подготовьте минимальный выход ревьюера витрины mart_customer_360 по шаблону из материалов курса. Используйте следующие вводные: витрина прошла dbt build, в schema.yml есть тесты unique и not_null на customer_id, total_balance_rub, risk_event_count_7d. Singular-теста на PII нет, но в коде визуально pii_email не выбирается. Singular-тест на колонки контракта присутствует, но проверяет только 3 из 5 обязательных полей ODCS. SQL использует ref() корректно. Определение risk_event_count_7d в specs/validation/customer_360.md упоминает окно в 7 дней, но не указывает якорную дату.

Решение: Готовая заметка ревьюера:

Гранулярность: одна строка на customer_id (покрыто dbt-тестом unique).
PII: визуально отсутствуют, но автоматического доказательства нет — статус «ручное ревью, требуется singular-тест схемы».
Поля контракта: customer_id, total_balance_rub, risk_event_count_7d (покрыто частично — 3 из 5 полей по ODCS, пробел в 2 полях).
Проверки: dbt build — ok, mart-тесты unique/not_null — ok, singular-тест колонок контракта — неполный, список запрещённых PII — отсутствует.
Открытые вопросы:
  1. Определение risk_event_count_7d не фиксирует якорную дату (current_date vs event_date vs дата расчёта витрины) — риск дрейфа.
  2. Какие ещё 2 поля из ODCS должны присутствовать в mart? Требуется сверка с customer_360_contract.odcs.yaml.
  3. PII-проверка существует только как визуальное ревью — необходимо добавить singular-тест.

Вывод: витрина не готова к продакшену. Требуется закрыть 3 открытых вопроса до merge.

Сложность: intermediate

Кейсы: Название: Утечка pii_email в маркетинговую витрину банка

Сценарий: Крупный розничный банк строит витрину Customer 360 для отдела CRM. Маркетинговая команда запрашивает «всё, что есть по клиенту», чтобы делать сегментацию и персонализацию. Разработчик dbt-модели в слое marts собирает таблицу из 47 колонок, включая pii_email и pii_phone, ссылаясь на то, что эти поля «уже есть в stg_customers и нужны для рассылок». Витрина проходит ревью code-only: ревьюер смотрит SQL, видит аккуратный join, но не сверяет список колонок с политикой PII и ODCS-контрактом.

Задача: Через 4 месяца служба безопасности проводит аудит и обнаруживает, что маркетинговая витрина содержит прямые PII, которые по внутреннему регламенту должны маскироваться или хешироваться на уровне mart. Витрина уже использовалась в 12 дашбордах и 3 ML-модели churn-прогнозирования. Утечка данных не состоялась (доступ был ограничен), но регуляторный риск реализовался: выявлено нарушение политики обработки ПДн, банку грозит предписание ЦБ.

Решение: Команда внедряет SDD-подход: (1) переписывает ODCS-контракт customer_360_contract.odcs.yaml, явно перечисляя разрешённые и запрещённые поля; (2) удаляет pii_email и pii_phone из mart, заменяя на hash_email для безопасной сегментации; (3) добавляет singular-тест mart_customer_360_no_pii.sql, который сканирует information_schema и падает при появлении запрещённых подстрок в именах колонок; (4) вводит обязательный шаг матрицы приёмки в PR-шаблон — ревьюер обязан заполнить таблицу покрытия фактов; (5) подключает Qwen-ассистента, который в каждом PR сравнивает SQL, schema.yml и ODCS и подсвечивает расхождения.

Результат: За 6 месяцев после внедрения SDD количество инцидентов с PII в mart слое сократилось до нуля. Среднее время ревью витрины выросло на 15 минут, но снизилось количество откатов и доработок. Регуляторный риск закрыт: банк прошёл повторный аудит без замечаний. Команда масштабировала практику на 14 других витрин.

Извлечённые уроки: Code-only ревью недостаточно — нужны автоматические singular-тесты, доказывающие выполнение политики PII.

ODCS-контракт должен быть единственным источником истины о составе полей mart, а не визуальное впечатление ревьюера.

Названия вроде «Customer 360» обманчиво понятны — у разных стейкхолдеров разные ожидания; SDD фиксирует одну версию обещания.

Матрица приёмки превращает абстрактное «готово» в дискретный список фактов с доказательствами.

Связанные концепции: mart_customer_360

PII (Personally Identifiable Information)

ODCS (Open Data Contract Standard)

Матрица приёмки

singular-тест схемы

SDD (Specification-Driven Development)

Название: Дрейф контракта risk_event_count_30d в страховой компании

Сценарий: Страховая компания использует витрину Customer 360 для скоринга мошенничества. Поле risk_event_count_30d обещает 30-дневное окно. Аналитик данных вносит изменение в stg_risk_events: добавляет фильтр where event_status = 'confirmed', чтобы убрать «сырые» алерты. Технически поле остаётся «риск-событиями за 30 дней», но его смысл смещается с «все алерты» на «подтверждённые алерты». В mart_customer_360 SQL не меняется, dbt build проходит, никто не замечает изменение.

Задача: Через 2 месяца скоринговая модель начинает выдавать ложноположительные блокировки полисов: клиенты, у которых были только неподтверждённые алерты, теперь не блокируются, а должны. Убытки от мошенничества растут на 8% за квартал. Расследование выявляет, что mart продолжает называть поле risk_event_count_30d, но его семантика изменилась. Контракт и реализация разошлись незаметно.

Решение: Команда внедряет многоуровневую защиту: (1) в specs/validation/customer_360.md добавляется формальное определение: «risk_event_count_30d — количество записей в stg_risk_events со статусом event_status in ('confirmed', 'investigating') за последние 30 дней относительно даты расчёта витрины»; (2) в mart_customer_360.sql жёстко фиксируется фильтр event_status in ('confirmed', 'investigating') с комментарием; (3) создаётся singular-тест, который сравнивает значение поля в mart с эталонным подсчётом по зафиксированной формуле — любое расхождение ломает сборку; (4) в schema.yml у поля появляется описание со ссылкой на раздел спецификации.

Результат: Скоринговая модель возвращается к ожидаемой семантике, убытки от мошенничества возвращаются к целевому уровню. Внедрение формального контрактного теста снижает подобные инциденты с 2-3 в год до нуля. Команда формализует правило: «если имя поля содержит окно, статус, валюту или уровень агрегации — это часть контракта и требует отдельного теста».

Извлечённые уроки: Название поля — часть контракта. Негласные изменения в upstream-слое незаметно дрейфуют семантику downstream-витрин.

Прохождение dbt build ≠ готовность. Нужны тесты, проверяющие именно смысл, а не только структуру.

Фильтр в staging-слое меняет семантику mart-поля, даже если SQL в mart не изменился. Нужен end-to-end-тест.

Определение окна должно содержать якорную дату и условия включения/исключения событий.

Связанные концепции: risk_event_count_7d

Дрейф контракта

Спецификация валидации

singular-тест

Название поля как часть контракта

Название: Миграция 14 витрин на SDD за один квартал

Сценарий: Финтех-стартап имеет 14 витрин в слое marts, написанных за 2 года разными разработчиками. Подход к контрактам разный: у одних витрин есть ODCS, у других — только wiki-страница, у третьих — никаких документов. Ревью витрин — полностью ручное, занимает 2-3 дня на каждую. Качество данных непредсказуемо: потребители жалуются на «дрейфующие» метрики, витрина Customer 360 пересобирается с разными результатами на разных ветках.

Задача: Продуктовый директор требует за квартал стабилизировать качество и снизить time-to-market новых витрин. Команда из 5 dbt-разработчиков должна одновременно мигрировать существующие витрины на SDD, не останавливая поставку данных. Высокий риск: при миграции можно сломать то, что работало годами.

Решение: Команда применяет инкрементальный подход: (1) выбирает mart_customer_360 как пилот — это «первая финальная витрина» с понятной бизнес-логикой и ограниченным числом полей; (2) для пилота пишет ODCS-контракт, спецификацию модели, спецификацию валидации и матрицу приёмки, как описано в Части 16; (3) внедряет 3 типа dbt-тестов: unique/not_null для обязательных полей, singular-тест на отсутствие PII, singular-тест на соответствие колонкам контракта; (4) автоматизирует проверку через Qwen-ассистента: PR триггерит ревью, которое сравнивает SQL, schema.yml и ODCS и генерирует таблицу покрытия фактов; (5) после успешного пилота шаблонизирует артефакты и масштабирует на остальные 13 витрин по 2 витрины в неделю.

Результат: За 12 недель все 14 витрин мигрированы на SDD. Время code review сократилось с 2-3 дней до 4-6 часов благодаря автоматической проверке покрытия. Количество инцидентов с дрейфом данных снизилось с 8-10 в квартал до 1 за полугодие. Потребители отмечают, что витрины стали «предсказуемыми» — документация и реализация больше не расходятся. Бонус: новые разработчики онбордятся за 1 неделю вместо 1 месяца благодаря стандартизированным шаблонам.

Извлечённые уроки: Customer 360 — идеальный пилот для SDD: название знакомое, поэтому каждый думает, что понимает, но у разных людей разные ожидания. Письменная спецификация снимает разночтения.

Матрица приёмки превращает абстрактное «готово» в конкретный чек-лист с доказательствами. Пустая строка доказательства = пробел готовности.

LLM-ассистент (Qwen) ускоряет рутинное ревью покрытия фактов, но не заменяет человеческого решения по открытым вопросам.

Шаблонизация артефактов (ODCS, spec, validation) ускоряет масштабирование и снижает вариативность между витринами.

Связанные концепции: SDD (Specification-Driven Development)

ODCS (Open Data Contract Standard)

Матрица приёмки

Qwen-запрос для ревью

Заметка ревьюера

Дрейф контракта

Советы по изучению: Начните с матрицы приёмки, а не с SQL. Пройдитесь по каждому факту и найдите доказательство, прежде чем читать код — это перевернёт восприятие с «что делает модель» на «что модель обещает».

Составьте таблицу «факт → доказательство → тип теста» для каждой витрины. Пустая ячейка = пробел готовности. Это ваш главный рабочий артефакт.

Для каждого поля с «обещанием» в имени (7d, 30d, confirmed, rub, count) спрашивайте: «где в коде это обещание зафиксировано?» Если только в названии — это технический долг.

Используйте Qwen-запрос из курса как шаблон для собственных PR: сравните SQL, schema.yml, ODCS и validation-файл, выведите таблицу покрытия. Файлы не меняйте — только анализируйте.

Не ограничивайтесь чтением SQL. Откройте information_schema и проверьте, что в mart физически нет PII-колонок, даже если в SELECT их не видно.

Пишите singular-тесты сразу, а не «когда-нибудь потом». Тест на отсутствие PII — это 10 строк, которые экономят недели расследований.

Для каждого PR заполняйте заметку ревьюера по шаблону из курса. Это дисциплинирует: факты, а не впечатления.

Запускайте dbt build --select mart_customer_360 и анализируйте вывод построчно — какая строка соответствует какому факту матрицы.

Не путайте «визуально нет PII» с «доказано отсутствие PII». Первое — это ревью, второе — это тест. SDD требует доказательства.

Используйте якорение даты в полях-окнах: всегда фиксируйте, относительно какой даты считается окно (current_date, дата загрузки, event_date).

Дополнительные ресурсы: Dbt-документация по тестам: https://docs.getdbt.com/docs/build/data-tests — официальное руководство по generic-тестам (unique, not_null, accepted_values, relationships) и singular-тестам.

Dbt-документация по ref(): https://docs.getdbt.com/reference/dbt-jinja-functions/ref — описание функции ref() и построения data lineage.

Odcs (open data contract standard): https://bitol-io.github.io/open-data-contract-standard/ — спецификация стандарта контрактов данных, используемого в SDD.

Dbt-utils пакет: https://github.com/dbt-labs/dbt-utils — коллекция макросов, включая тесты на PII и колонки контракта (expression_is_true, relationships, etc.).

Sqlfluff линтер для dbt: https://sqlfluff.com/ — статический анализ SQL-кода dbt-моделей, помогает поддерживать стиль и находить базовые ошибки.

Dbt-expectations пакет: https://github.com/calogica/dbt-expectations — расширенные тесты в стиле Great Expectations для dbt.

Книга «data contracts» (andrew jones): Концептуальное введение в контракты данных как продуктовый артефакт. Полезна для понимания, почему SDD работает.

Great expectations: https://greatexpectations.io/ — фреймворк валидации данных, концепции которого перекликаются с singular-тестами dbt.

Резюме: Часть 16 «Витрина Customer 360» — это центральный учебный пример применения SDD (Specification-Driven Development) к финальному слою данных. Витрина mart_customer_360 намеренно ограничена: одна строка на customer_id, без прямых PII, остаток из счетов, риск-события из синтетического окна. Каждое поле можно связать со спецификацией и проверкой. Ключевая идея: матрица приёмки превращает абстрактное «готово» в дискретный список фактов с конкретными доказательствами (dbt-тесты unique/not_null, singular-тесты схемы и колонок контракта, проверка lineage через ref()). Если строка доказательства пустая — это пробел готовности, а не готовность. Названия полей — часть контракта: если имя содержит окно (7d), статус или уровень агрегации, это обещание должно быть зафиксировано в коде и подтверждено тестом. Политика PII не может быть общей фразой — она проверяется автоматическим singular-тестом, сканирующим колонки mart. Минимальный выход артефакта — заметка ревьюера с гранулярностью, статусом PII, списком полей контракта, перечнем проверок и открытыми вопросами. Qwen-ассистент может ускорить рутинную проверку покрытия фактов, но не заменяет человеческого решения. Главный урок: в SDD недостаточно написать правильный SQL — нужно доказать каждое обещание тестом или явным фактом.

Мои заметки
0 / 10000

Заметки сохраняются в этом браузере. На другом устройстве они не появятся.

Меню курса

Курс

SDD Data. Дата-платформа банка с Qwen Code и dbt
Прогресс 0 / 110