- Зачем:
- студент реализует 9 объектов DWH без автоматической обратной связи;
- ошибки (NULL в PK, дубли BK, сломанный SCD2) обнаруживались только на слое DM
через 2–3 слоя, где отладка многократно сложнее.
- Что:
- создан DAG bookings_validate.py — три параллельных TaskGroup (validate_ods,
validate_dds, validate_dm), schedule=None (только ручной trigger);
- создано 17 SQL-скриптов в sql/validate/: ODS BK coverage vs STG-батч,
согласованность _load_id между ods.airplanes и ods.seats, дубли BK, NULL в PK,
покрытие ODS→DDS для измерений (dim_routes требует открытой версии valid_to IS NULL),
SCD2 активный тест backup→mutate→student_load→check(5 инвариантов)→restore
(trigger_rule=all_done), проверка «дыр» между SCD2-версиями,
exists-чеки для 4 DM-витрин;
- добавлен класс TestBookingsValidate (5 smoke-тестов) в tests/test_dags_smoke.py.
- Проверка:
- make test — 4 passed, 14 skipped (DAG-тесты скипаются без Airflow, норма);
- ручной trigger bookings_validate в Airflow UI на solution-ветке — все таски зелёные.
- Зачем:
- STG-слой использовал legacy-имена (batch_id, load_dttm, src_created_at_ts),
тогда как ODS/DDS/DM уже работали с каноном (_load_id, _load_ts, event_ts).
Студент видел разные имена для одного понятия — это убрано.
- Что:
- переименованы колонки в 9 STG DDL: batch_id→_load_id, load_dttm→_load_ts,
src_created_at_ts→event_ts; добавлен NOT NULL для _load_id во всех таблицах.
- обновлены 9 STG Load, 9 STG DQ, 9 ODS Load, 9 ODS DQ (INSERT/SELECT/WHERE).
- обновлены DAG-файлы bookings_to_gp_stage.py и bookings_to_gp_ods.py
(встроенный SQL резолвера, комментарии; Python-идентификаторы не тронуты).
- обновлены тесты и ~15 документов (naming_conventions, PRD, db_schema,
design-docs, qa-plan, README, TESTING и др.).
- Проверка:
- grep -rn 'load_dttm\|src_created_at_ts' sql/ airflow/ tests/ — 0 совпадений.
- make test — 4 passed.
- e2e-etl: day1 прошёл полностью, day2 стартовал без ошибок.
- Зачем:
- Пример базовой загрузки CSV перенесен в отдельный репозиторий `airflow-manual` для разделения учебных треков.
- Что:
- удалены DAG-файлы `csv_to_greenplum` и вспомогательные скрипты `helpers/greenplum.py`, `orders_ddl.sql`.
- из `docker-compose.yml` и `.env.example` удалены переменные и тома (`airflow_data`), необходимые для CSV.
- очищена документация (`README.md`, `TESTING.md`, `educational-tasks.md`) и тесты (`test_dags_smoke.py`, `conftest.py`).
- отмечен выполненным 'Этап 1' в `TODO.md`.
- Проверка:
- `make test` проходит успешно (smoke-тесты оставшихся DAG-ов не затронуты).
- Зачем:
- улучшение производительности аналитических запросов и упрощение витрин согласно принципам Kimball Star Schema.
- Что:
- в dds.dim_routes добавлены денормализованные поля городов и моделей самолетов.
- в скрипт загрузки dim_routes_load.sql добавлена фаза refresh для актуализации атрибутов.
- загрузка dm.route_performance упрощена до 1 JOIN к измерению маршрутов.
- обновлен DAG bookings_to_gp_dds и smoke-тесты структуры графа.
- в документации (db_schema.md) отражены денормализация и lineage версий.
- в dim_routes_load.sql исправлено затирание _load_id при refresh исторических версий.
- Проверка:
- make test (smoke-тесты структуры DAG проходят успешно).
- Зачем:
- предоставить студентам полный набор аналитических витрин с примерами различных паттернов (UPSERT, Full Rebuild, UNION ALL, двухуровневая агрегация).
- Что:
- реализованы витрины: sales_report, route_performance, passenger_loyalty, airport_traffic, monthly_overview.
- исправлен баг в route_performance_load.sql: добавлены JOIN к dim_airports и dim_airplanes для корректной денормализации атрибутов.
- обновлен скрипт e2e_etl.sh: добавлена верификация всех 5 витрин и проверка бизнес-логики (load factor).
- обновлены DAGи, тесты и главный DDL скрипт.
- Проверка:
- автоматизированный прогон e2e_etl.sh через REST API Airflow.
- Зачем:
- необходимо продемонстрировать студентам работу с одной сущностью в разных ролях (вылет/прилет) через UNION ALL.
- Что:
- созданы DDL, Load и DQ скрипты для витрины dm.airport_traffic (пассажиропоток аэропортов).
- реализован паттерн Unpivot через UNION ALL для консолидации метрик вылета и прилета в одном разрезе.
- внедрена инкрементальная загрузка по затронутым датам (HWM) с честным подсчетом рейсов через COUNT(DISTINCT).
- добавлены подробные комментарии к колонкам выручки, предупреждающие о риске двойного счета.
- обновлены DAGи bookings_dm_ddl и bookings_to_gp_dm для включения витрины в общий пайплайн.
- Проверка:
- визуальный аудит SQL-кода на предмет использования airport_bk и корректной агрегации по ролям.
- наличие DQ-инварианта total_passengers = departures + arrivals.
- верификация блока UPDATE: теперь обновляются и денормализованные атрибуты (city, airport_bk).
- Зачем:
- необходимо продемонстрировать студентам метод инкрементального пересчета "затронутых ключей" для больших справочных витрин.
- Что:
- созданы DDL, Load и DQ скрипты для витрины dm.passenger_loyalty (лояльность пассажиров).
- реализован расчет моды (самый частый тариф) через PostgreSQL-специфику DISTINCT ON.
- внедрена корректная агрегация SCD2-измерений (unique_routes) по бизнес-ключу route_bk.
- настроено Heap-хранилище (WITH appendonly=false) для эффективного выполнения UPSERT.
- обновлены DAGи bookings_dm_ddl и bookings_to_gp_dm для включения новой витрины в конвейер.
- Проверка:
- визуальный аудит SQL на предмет использования p.passenger_id (BK) и r.route_bk.
- наличие учебной DQ-проверки ссылочной целостности и инварианта дат (first <= last).
- проверка параллельности задач в Airflow DAG.
- Зачем:
- необходимо продемонстрировать студентам альтернативный паттерн загрузки (Full Rebuild) и использование AO Column Store в Greenplum.
- Что:
- созданы DDL, Load и DQ скрипты для витрины dm.route_performance (эффективность маршрутов).
- реализована агрегация по бизнес-ключу route_bk для корректной обработки SCD2-измерений.
- настроен формат хранения AO Column Store с компрессией zstd (уровень 1).
- обновлены DAGи bookings_dm_ddl и bookings_to_gp_dm для параллельной оркестрации новой витрины.
- Проверка:
- визуальный аудит SQL-кода на соответствие naming_conventions.md.
- проверка структуры DAG в Airflow (параллельные ветки load -> dq).
- наличие бизнес-инварианта total_boarded <= total_tickets в DQ-скрипте.
- Зачем:
- zstd (level 1) является современным стандартом для Greenplum 6.0+, обеспечивая более высокую скорость декомпрессии и лучшее сжатие.
- Что:
- обновлены все DDL стейджинга (STG) и базовых таблиц.
- обновлена архитектурная документация (ADR-3) и планы реализации.
- исправлены примеры кода в Airflow DAG и описании ETL.
- Проверка:
- успешное выполнение CREATE TABLE с новыми параметрами в Greenplum 6.27.1.
- Зачем:
- формализация проверки всей цепочки ETL (STG -> ODS -> DDS -> DM).
- Что:
- создан docs/e2e-etl-test-protocol.md и sql/truncate_gp.sql.
- в Makefile добавлена команда dwh-truncate.
- start_date во всех DAG изменен на 2017-01-01.
- Проверка:
- выполнение make dwh-truncate и прогон DAG.
- Зачем:
- текущая реализация ODS batch_id теряла данные транзакционных таблиц, если между запусками ODS STG успевал отработать дважды (брался только последний батч).
- Что:
- изменены скрипты загрузки транзакционных таблиц (bookings, tickets, flights, segments, boarding_passes) для использования паттерна HWM по _load_ts вместо фильтрации по конкретному батчу.
- обновлен комментарий в DAG bookings_to_gp_ods, объясняющий разное поведение для справочников и транзакционных данных.
- сохранено использование оригинального batch_id из STG для поля _load_id в слое ODS для сквозного трассирования.
- Проверка:
- запуск пайплайнов и проверка, что все батчи загружаются из STG в ODS без потерь.
- Зачем:
- закрыты задачи P0 и P1 из ревью архитектуры для повышения понятности стенда для студентов.
- Что:
- исправлен distribution key для airport_traffic в дизайн-документе.
- добавлены комментарии о генерации SK и отсутствии SK в фактах.
- создан документ docs/dag_execution_order.md с описанием порядка запуска DAG-ов.
- объяснена логика late-arriving dimensions и batch resolver.
- добавлена legacy-пометка для хелпера greenplum.py.
- Проверка:
- визуальная проверка добавленных комментариев и новых файлов.
- Зачем:
- подготовлен учебный Star Schema слой для перехода от ODS к аналитике и витринам.
- Что:
- добавлены 21 SQL-файл для DDS (DDL/LOAD/DQ) с SCD1/SCD2 и фактом `fact_flight_sales`.
- добавлены DAG `bookings_dds_ddl` и `bookings_to_gp_dds`, а также smoke-тесты структуры DAG.
- обновлены `sql/ddl_gp.sql` и документация (`README`, `docs/*`, `db_schema`) под поток `stg -> ods -> dds`.
- Проверка:
- make test.
- Зачем:
- подготовлена учебная реализация ODS слоя с типизацией, UPSERT и DQ, чтобы продолжить работу от STG к DDS/DM.
- Что:
- добавлены SQL-скрипты `sql/ods/*_ddl.sql`, `sql/ods/*_load.sql`, `sql/ods/*_dq.sql` для 9 сущностей bookings.
- добавлены DAG `bookings_ods_ddl` и `bookings_to_gp_ods`, а также smoke-тесты для новых графов.
- ODS DDL интегрирован в `sql/ddl_gp.sql`; документация и план обновлены под единый запуск через `make ddl-gp`.
- Проверка:
- `make test`.
- `make ddl-gp`.
- Зачем:
- линейный граф маскировал реальные зависимости данных; для эталонного
стенда важно показать менти параллельный граф там, где данные независимы.
- Что:
- airports и airplanes грузятся параллельно после check_tickets_dq.
- routes ждёт обоих (DQ проверяет ссылочную целостность на оба справочника).
- seats зависит только от airplanes и работает параллельно с веткой
routes → flights → segments → boarding_passes.
- finish_summary ждёт обе ветки (check_boarding_passes_dq + check_seats_dq).
- datetime.utcnow() заменён на datetime.now(UTC) в csv_to_greenplum.py.
- smoke-тесты дополнены проверкой параллельности и второй ветки.
- документация обновлена с ASCII-схемой нового графа.
- Проверка:
- make test (11 passed, 4 skipped), make lint — чисто.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>