- Зачем:
- необходимо синхронизировать документацию с фактически выполненными изменениями в коде.
- Что:
- отмечена как выполненная задача по явному указанию storage type для всех таблиц.
- обновлено обоснование для dds.dim_calendar (AO Row из-за малой ширины таблицы).
- отмечен как выполненный рефакторинг hashdiff в dim_routes_load.sql.
- Проверка:
- визуальная сверка docs/internal/architecture_review.md с файлами в sql/dds/ и sql/ods/.
- Зачем:
- старая инструкция была неполной (без ODS/DDS/DM) и содержала избыточные требования.
- Что:
- переписан docs/agent-dag-testing.md с фокусом на итеративную разработку и Airflow REST API.
- добавлены шаги по отладке упавших задач (логгирование через CLI) и проверке DWH слоев.
- Проверка:
- визуальная проверка текста руководства на соответствие актуальному пайплайну.
- Зачем:
- улучшение производительности аналитических запросов и упрощение витрин согласно принципам 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 проходят успешно).
- Зачем:
- необходимо упростить витрину dm.route_performance с 4-JOIN до 1-JOIN;
- привести измерение в соответствие с принципом Кимбалла («самодостаточное измерение»).
- Что:
- добавлена задача в TODO.md с описанием цели денормализации;
- создан детальный план реализации в docs/internal/dim_routes_denormalization_plan.md.
- Проверка:
- просмотр файлов TODO.md и docs/internal/dim_routes_denormalization_plan.md.
- Зачем:
- предоставить студентам полный набор аналитических витрин с примерами различных паттернов (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-скрипте.
- Зачем:
- необходимо визуализировать выбор типа хранения (Heap vs Append-Only) для учебных целей.
- автоматизировать проверку всей цепочки DWH для исключения ручных ошибок.
- сделать процесс отладки прозрачным и наглядным через стандартные инструменты Airflow.
- Что:
- внедрена клауза WITH (appendonly=...) во все DDL; ODS-справочники переведены на AO Row и TRUNCATE+INSERT.
- создан скрипт scripts/e2e_etl.sh для полного прогона ETL (DDL + 2 дня данных) через REST API.
- исправлены баги типизации (INTEGER[]), именования полей (amount, passenger_id) и удалены фантомные колонки (contact_data).
- обновлен e2e-etl-test-protocol.md: добавлен раздел по отладке, чтению логов и перезапуску задач через API.
- исправлены pytest-контракты под новую логику загрузки.
- Проверка:
- успешный прогон `make e2e-smoke` (полный цикл от очистки до витрины).
- Зачем:
- зафиксировать новые приоритеты по тестированию ETL и стабильности источника.
- Что:
- добавлены два новых пункта в backlog мейнтейнеров в TODO.md.
- уточнён статус файла, чтобы он отражал наличие открытых задач.
- Проверка:
- git diff --cached -- TODO.md.
- Зачем:
- 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.
- Зачем:
- исправление критических ошибок P0 (гонка HWM, ошибки в SQL CTE, непоследовательный lineage).
- использование временных таблиц делает код более читаемым для студентов и производительным для Greenplum.
- Что:
- в sql/ods/ (bookings, tickets, segments, boarding_passes, flights) выборка дельты вынесена в CREATE TEMP TABLE.
- HWM теперь вычисляется один раз, устраняя гонку между UPDATE и INSERT.
- во всех стейтментах используется оригинальный batch_id из STG для _load_id.
- поле _load_ts в ODS теперь берется из STG (load_dttm), что делает HWM-сравнение корректным.
- Проверка:
- визуальный аудит SQL-логики.
- Зачем:
- необходимо зафиксировать выполнение критической задачи (P0) в плане работ.
- Что:
- в архитектурном ревью пункт "ODS batch resolver теряет данные" отмечен как выполненный.
- Проверка:
- визуальная проверка docs/internal/architecture_review.md.
- Зачем:
- зафиксировать принятые архитектурные решения с обоснованием для менти,
чтобы студенты понимали границы учебных упрощений и реальную практику.
- Что:
- ADR-1: города/страны/модели — атрибуты измерений (star vs snowflake).
- ADR-2: партиционирование не используем (учебные объёмы), с примером
exchange partition и контекстом импортозамещения (Teradata/Exadata → GP).
- ADR-3: явный storage type для каждой таблицы — AO Column для write-once,
AO Row для snapshot-справочников (TRUNCATE+INSERT), heap для UPDATE-таблиц.
- добавлена задача P2 по реализации ADR-3, обновлена сводка трудозатрат.
- Проверка:
- cat docs/internal/architecture_review.md | grep "ADR-".
- Зачем:
- текущая реализация 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.
- Проверка:
- визуальная проверка добавленных комментариев и новых файлов.
- Зачем:
- зафиксировать оценку учебной ценности текущей конструкции (STG→ODS→DDS→DM)
и сформировать backlog задач для доработки стенда.
- Что:
- создан docs/internal/architecture_review.md с анализом 9 сильных сторон
и приоритизированным списком замечаний (P0–P3) с чеклистом задач.
- Проверка:
- cat docs/internal/architecture_review.md.
- Зачем:
- дизайн-документ описывал устаревший batch-driven подход и не фиксировал паттерн TEMP TABLE, используемый в реализации.
- Что:
- заменено описание загрузки всех UPSERT-витрин на HWM-инкрементальность через _load_ts.
- добавлена секция «Общий паттерн загрузки UPSERT-витрин» с SQL-скелетом и таблицей применимости.
- в секции «Учит» каждой витрины добавлены паттерны HWM и TEMP TABLE.
- Проверка:
- визуальная проверка docs/internal/bookings_dm_design.md.
- Зачем:
- фильтр `_load_id = '{{ run_id }}'` использовал run_id DM-DAG-а, который не совпадает с run_id DDS-DAG-а, записанным в факты — витрина не находила дельту.
- Что:
- load: заменён _load_id-фильтр на HWM-подзапрос `_load_ts > MAX(_load_ts)` из dm.sales_report.
- dq: источник затронутых дат переключён с DDS на саму витрину (где _load_id уже корректный).
- Проверка:
- `make test` — smoke-тесты зелёные.
- запуск `bookings_to_gp_dm` в Airflow после загрузки DDS.
- Зачем:
- жесткая привязка инкремента к логической дате Airflow ({{ ds }}) приводила к пустой витрине при обработке исторических и "опоздавших" (late-arriving) данных.
- Что:
- изменена фильтрация в скрипте загрузки витрины: теперь динамически определяются даты, затронутые текущим батчем (через _load_id).
- обновлены DQ-проверки для валидации только тех дат, которые были изменены в рамках запущенного батча.
- в дизайн-документ добавлено описание паттерна работы с late-arriving facts для студентов.
- Проверка:
- запуск пайплайна "с нуля" за логическую дату 2024-01-01 приводит к корректному расчету агрегатов для исторических данных 2017 года (>8000 строк).
- Зачем:
- файл позволяет AI-агентам быстро находить и использовать контекст из AGENTS.md
- Что:
- создан файл GEMINI.md с ссылкой на @AGENTS.md
- Проверка:
- cat GEMINI.md
- Зачем:
- источник хранит мультиязычные названия как JSON ({"en": "...", "ru": "..."}),
- для упрощения downstream-логики (DDS/DM) нужны чистые строки на одном языке.
- Что:
- добавлен парсинг JSON с извлечением поля 'ru' в sql/ods/airports_load.sql
(airport_name, city, country).
- добавлен парсинг JSON с извлечением поля 'ru' в sql/ods/airplanes_load.sql
(model).
- обновлена документация docs/internal/bookings_ods_design.md с примечаниями
о нормализации.
- обновлены тестовые данные в tests/test_ods_snapshot_integration.py для
соответствия JSON-формату STG.
- Проверка:
- uv run make test (15 passed).
- SELECT airport_name FROM ods.airports → "Аль-Баха" (вместо JSON).
- Зачем:
- зафиксировать архитектуру 5 витрин DM перед реализацией и отдать на ревью.
- Что:
- создан docs/internal/bookings_dm_design.md с описанием всех витрин, DAG-структуры, DQ-проверок и порядка реализации.
- Проверка:
- cat docs/internal/bookings_dm_design.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- dq_ods_segments падал на непустых батчах из-за orphan flight_id в ods.segments.
- Что:
- доработан sql/ods/flights_load.sql: добавлено добирание рейсов из истории stg.flights для flight_id из stg.segments текущего batch.
- добавлен контрактный тест в tests/test_ods_sql_contract.py на покрытие flight_id из segments.
- обновлена документация DAG в docs/bookings_to_gp_ods.md.
- Проверка:
- make test.
- airflow dags trigger bookings_to_gp_ods -c '{"stg_batch_id":"manual__2026-01-18T18:47:18.316091+00:00"}'.
- Зачем:
- подготовлен учебный 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.
- Зачем:
- синхронизировать db_schema.md с фактическим состоянием репозитория и текущим DDS-планом.
- Что:
- обновлён статус слоёв: STG/ODS отмечены как реализованные, DDS как слой в проектировании.
- приведены к актуальному виду DDS-объекты и нейминг (`dds.dim_*`, `dds.fact_flight_sales`, `dds.dim_routes` SCD2).
- обновлены mermaid-диаграмма, обучающие пояснения, TODO, связанные документы и история изменений.
- Проверка:
- git diff -- docs/internal/db_schema.md
- Зачем:
- устранить противоречия и пробелы в плане DDS перед реализацией.
- Что:
- HIGH: факт теперь использует point-in-time SCD2 lookup для routes,
UPDATE факта не перезаписывает dimension SK (историчность сохранена).
- MEDIUM: явная политика NULL FK в факте (3 группы: обязательные,
зависят от маршрута, зависят от расписания) + DQ с порогом 1%.
- MEDIUM: добавлены DQ-проверки SCD2 интервалов (valid_from < valid_to,
нет перекрытий версий).
- MEDIUM: DQ факта теперь проверяет calendar_sk и route_sk IS NULL
с порогом.
- LOW: добавлен стабильный tie-breaker (ticket_no) при дедупликации
passengers.
- добавлена секция backfill/reprocess политики.
- Проверка:
- cat docs/internal/bookings_dds_design.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- зафиксировать архитектурные решения DDS до начала реализации (для Codex).
- Что:
- создан docs/internal/bookings_dds_design.md с полным планом DDS.
- 6 измерений (calendar, airports, airplanes, tariffs, passengers, routes) + факт flight_sales.
- dim_routes реализует классический SCD2 с hashdiff.
- все остальные измерения — SCD1 UPSERT со стабильными SK.
- факт — инкрементальный UPSERT по зерну (ticket_no, flight_id).
- Проверка:
- cat docs/internal/bookings_dds_design.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- подготовлена учебная реализация 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`.
- Зачем:
- codex нашёл баги, которые сломали бы первый прогон ODS.
- Что:
- resolve batch: MAX(batch_id) заменён на ORDER BY load_dttm DESC LIMIT 1
(run_id — строка, лексикографический MAX не гарантирует хронологию).
- ручная проверка: добавлен make ddl-gp-ods (без него ODS-объекты не создадутся).
- routes/flights FK: расширено пояснение, почему проверка по route_no без
validity допустима в ODS и что учитывать при join в DDS.
- Проверка:
- make test (11 passed, 4 skipped).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- v2 содержал баги (CTE scope, distribution key), неточности маппинга
колонок и пробелы в описании DAG-контракта, что сломало бы реализацию.
- Что:
- исправлен CTE scope: дублирование CTE в UPDATE и INSERT statements.
- ods.tickets: DISTRIBUTED BY (ticket_no) вместо book_ref для UPSERT.
- добавлен Python-сниппет resolve_stg_batch_id (PythonOperator + XCom).
- заменены {{ params.stg_batch_id }} → {{ ti.xcom_pull(...) }} во всех SQL.
- <> заменён на IS DISTINCT FROM (NULL-safe change detection).
- DISTINCT ON заменён на ROW_NUMBER() (стандартный DE-паттерн).
- добавлена секция 4.3 с полной таблицей маппинга STG → ODS.
- routes: scheduled_departure_time → departure_time, duration без rename.
- DAG-граф: resolve_stg_batch_id как корневой таск, параллельные ветки.
- DQ: добавлена проверка «батч не пустой» для snapshot-справочников.
- DoD: убрано valid_from/valid_to, оставлено _load_id/_load_ts/event_ts.
- Проверка:
- make test (11 passed, 4 skipped).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- нужен единый стандарт именования полей, чтобы новые слои не расходились с учебными материалами.
- Что:
- добавлен единый документ с правилами нейминга `docs/internal/naming_conventions.md`.
- полностью переписан `docs/internal/bookings_ods_design.md` в эталонный учебный план ODS (SCD1, батч-контракт, DQ, граф DAG).
- добавлены ссылки на стандарт нейминга в `docs/README.md`, `docs/internal/db_schema.md` и `AGENTS.md`.
- Проверка:
- проверен diff по измененным файлам (`git diff`).
- Зачем:
- зафиксировать архитектурное решение для ODS слоя перед началом разработки.
- Что:
- создан файл docs/internal/bookings_ods_design.md.
- описана архитектура ODS и отличия от STG слоя.
- добавлены схемы таблиц (справочники с SCD Type 2, транзакции с UPSERT).
- Проверка:
- git show --stat HEAD
- Зачем:
- исключены ложные падения DQ при пустом source в bookings-db.
- Что:
- в TESTING.md добавлены pre-check команды COUNT(*) перед Trigger DAG.
- в docs/agent-dag-testing.md добавлена обязательная проверка source и fallback при COUNT(*) = 0.
- в таблицу типичных проблем добавлен кейс падения check_airports_dq/check_airplanes_dq с ошибкой "..._ext нет строк".
- Проверка:
- rg -n "source непустой|COUNT\(\*\) = 0|bookings-generate-day|check_airports_dq" TESTING.md docs/agent-dag-testing.md
- Зачем:
- AI-агенты пытались тестировать DAG через браузер вместо CLI/API,
так как не было явных инструкций по программному подходу.
- Что:
- добавлен docs/agent-dag-testing.md: CLI, REST API Airflow,
проверка параллельности, запросы в Greenplum, E2E-тест, шпаргалка команд.
- в AGENTS.md добавлена ссылка на новый гайд в раздел «Тестирование».
- из docs/README.md убрана ссылка (файл для людей, не для агентов).
- Проверка:
- cat docs/agent-dag-testing.md && grep agent-dag-testing AGENTS.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Зачем:
- необходимо зафиксировать контекст и правила работы с проектом для Claude AI.
- Что:
- создан файл CLAUDE.md с описанием структуры проекта.
- добавлены инструкции по коммитам и стилю кода.
- Проверка:
- git show --stat HEAD
- Зачем:
- линейный граф маскировал реальные зависимости данных; для эталонного
стенда важно показать менти параллельный граф там, где данные независимы.
- Что:
- 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>
- Зачем:
- исключить нестабильные режимы генератора, в которых bookings может перестать пополняться.
- сделать причину ошибки понятной студенту сразу при запуске команд и SQL-скриптов.
- Что:
- добавлен precheck `bookings-check-jobs` в Makefile и подключён к `bookings-init` и `bookings-generate-day`.
- добавлены явные проверки `bookings.jobs = 1` в `bookings/generate_next_day.sql` и `sql/src/bookings_generate_day_if_missing.sql`.
- обновлена документация и `.env.example`: зафиксировано, что в стенде поддерживается только `BOOKINGS_JOBS=1`.
- Проверка:
- uv run make fmt.
- uv run make test.
- env BOOKINGS_JOBS=2 make bookings-init.
- env BOOKINGS_JOBS=2 make bookings-generate-day.
- make bookings-init.
- make bookings-generate-day.
- Зачем:
- предыдущий фикс ломал make bookings-init из-за невалидного SQL в Makefile.
- Что:
- удалены SQL-блоки постобработки reference-данных и cume_dist из bookings-init.
- удалён случайно добавленный gitlink _vendor/demodb.
- удалён SET LOCAL application_name из generate_next_day.sql.
- Проверка:
- uv run make fmt.
- uv run make test.
- make bookings-init.
- make bookings-generate-day.
- Зачем:
- генератор demodb зависал при jobs=1 из-за самоблокировки busy()
- get_passenger_name() попадал в бесконечный цикл из-за NULL в cume_dist
- Что:
- добавлен SET LOCAL application_name = 'psql' после вызова generate/continue
- добавлена загрузка firstnames.dat и lastnames.dat в Makefile
- добавлено заполнение cume_dist для firstnames, lastnames и airport_to_prob
- Проверка:
- make bookings-generate-day выполняется успешно, создаётся ~45K бронирований
- Зачем:
- документ разросся и стал неструктурированным; нужно выделить ключевое правило про баланс production-ready и KISS для начинающих Data инженеров.
- Что:
- реструктуризация: введена нумерация разделов (1-6), удалены дублирующиеся детали команд и стиля кода.
- добавлен раздел 1 "Главное правило генерации кода (Баланс)" с принципами Production-ready, KISS и Фокус на «Почему».
- расширена карта проекта: добавлены все слои DWH (src/, stg/, ods/, dds/, dm/) и naming conventions.
- добавлен раздел 6 "Порядок работы Агента" с чек-листом валидации.
- Проверка:
- cat AGENTS.md && git log -1
- Зачем:
- зафиксировать архитектуру 5 витрин DM перед реализацией и отдать на ревью.
- Что:
- создан docs/internal/bookings_dm_design.md с описанием всех витрин, DAG-структуры, DQ-проверок и порядка реализации.
- Проверка:
- cat docs/internal/bookings_dm_design.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- dq_ods_segments падал на непустых батчах из-за orphan flight_id в ods.segments.
- Что:
- доработан sql/ods/flights_load.sql: добавлено добирание рейсов из истории stg.flights для flight_id из stg.segments текущего batch.
- добавлен контрактный тест в tests/test_ods_sql_contract.py на покрытие flight_id из segments.
- обновлена документация DAG в docs/bookings_to_gp_ods.md.
- Проверка:
- make test.
- airflow dags trigger bookings_to_gp_ods -c '{"stg_batch_id":"manual__2026-01-18T18:47:18.316091+00:00"}'.
- Зачем:
- подготовлен учебный 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.
- Зачем:
- синхронизировать db_schema.md с фактическим состоянием репозитория и текущим DDS-планом.
- Что:
- обновлён статус слоёв: STG/ODS отмечены как реализованные, DDS как слой в проектировании.
- приведены к актуальному виду DDS-объекты и нейминг (`dds.dim_*`, `dds.fact_flight_sales`, `dds.dim_routes` SCD2).
- обновлены mermaid-диаграмма, обучающие пояснения, TODO, связанные документы и история изменений.
- Проверка:
- git diff -- docs/internal/db_schema.md
- Зачем:
- устранить противоречия и пробелы в плане DDS перед реализацией.
- Что:
- HIGH: факт теперь использует point-in-time SCD2 lookup для routes,
UPDATE факта не перезаписывает dimension SK (историчность сохранена).
- MEDIUM: явная политика NULL FK в факте (3 группы: обязательные,
зависят от маршрута, зависят от расписания) + DQ с порогом 1%.
- MEDIUM: добавлены DQ-проверки SCD2 интервалов (valid_from < valid_to,
нет перекрытий версий).
- MEDIUM: DQ факта теперь проверяет calendar_sk и route_sk IS NULL
с порогом.
- LOW: добавлен стабильный tie-breaker (ticket_no) при дедупликации
passengers.
- добавлена секция backfill/reprocess политики.
- Проверка:
- cat docs/internal/bookings_dds_design.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- зафиксировать архитектурные решения DDS до начала реализации (для Codex).
- Что:
- создан docs/internal/bookings_dds_design.md с полным планом DDS.
- 6 измерений (calendar, airports, airplanes, tariffs, passengers, routes) + факт flight_sales.
- dim_routes реализует классический SCD2 с hashdiff.
- все остальные измерения — SCD1 UPSERT со стабильными SK.
- факт — инкрементальный UPSERT по зерну (ticket_no, flight_id).
- Проверка:
- cat docs/internal/bookings_dds_design.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- подготовлена учебная реализация 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`.
- Зачем:
- codex нашёл баги, которые сломали бы первый прогон ODS.
- Что:
- resolve batch: MAX(batch_id) заменён на ORDER BY load_dttm DESC LIMIT 1
(run_id — строка, лексикографический MAX не гарантирует хронологию).
- ручная проверка: добавлен make ddl-gp-ods (без него ODS-объекты не создадутся).
- routes/flights FK: расширено пояснение, почему проверка по route_no без
validity допустима в ODS и что учитывать при join в DDS.
- Проверка:
- make test (11 passed, 4 skipped).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- v2 содержал баги (CTE scope, distribution key), неточности маппинга
колонок и пробелы в описании DAG-контракта, что сломало бы реализацию.
- Что:
- исправлен CTE scope: дублирование CTE в UPDATE и INSERT statements.
- ods.tickets: DISTRIBUTED BY (ticket_no) вместо book_ref для UPSERT.
- добавлен Python-сниппет resolve_stg_batch_id (PythonOperator + XCom).
- заменены {{ params.stg_batch_id }} → {{ ti.xcom_pull(...) }} во всех SQL.
- <> заменён на IS DISTINCT FROM (NULL-safe change detection).
- DISTINCT ON заменён на ROW_NUMBER() (стандартный DE-паттерн).
- добавлена секция 4.3 с полной таблицей маппинга STG → ODS.
- routes: scheduled_departure_time → departure_time, duration без rename.
- DAG-граф: resolve_stg_batch_id как корневой таск, параллельные ветки.
- DQ: добавлена проверка «батч не пустой» для snapshot-справочников.
- DoD: убрано valid_from/valid_to, оставлено _load_id/_load_ts/event_ts.
- Проверка:
- make test (11 passed, 4 skipped).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Зачем:
- нужен единый стандарт именования полей, чтобы новые слои не расходились с учебными материалами.
- Что:
- добавлен единый документ с правилами нейминга `docs/internal/naming_conventions.md`.
- полностью переписан `docs/internal/bookings_ods_design.md` в эталонный учебный план ODS (SCD1, батч-контракт, DQ, граф DAG).
- добавлены ссылки на стандарт нейминга в `docs/README.md`, `docs/internal/db_schema.md` и `AGENTS.md`.
- Проверка:
- проверен diff по измененным файлам (`git diff`).
- Зачем:
- зафиксировать архитектурное решение для ODS слоя перед началом разработки.
- Что:
- создан файл docs/internal/bookings_ods_design.md.
- описана архитектура ODS и отличия от STG слоя.
- добавлены схемы таблиц (справочники с SCD Type 2, транзакции с UPSERT).
- Проверка:
- git show --stat HEAD
- Зачем:
- исключены ложные падения DQ при пустом source в bookings-db.
- Что:
- в TESTING.md добавлены pre-check команды COUNT(*) перед Trigger DAG.
- в docs/agent-dag-testing.md добавлена обязательная проверка source и fallback при COUNT(*) = 0.
- в таблицу типичных проблем добавлен кейс падения check_airports_dq/check_airplanes_dq с ошибкой "..._ext нет строк".
- Проверка:
- rg -n "source непустой|COUNT\(\*\) = 0|bookings-generate-day|check_airports_dq" TESTING.md docs/agent-dag-testing.md
- Зачем:
- AI-агенты пытались тестировать DAG через браузер вместо CLI/API,
так как не было явных инструкций по программному подходу.
- Что:
- добавлен docs/agent-dag-testing.md: CLI, REST API Airflow,
проверка параллельности, запросы в Greenplum, E2E-тест, шпаргалка команд.
- в AGENTS.md добавлена ссылка на новый гайд в раздел «Тестирование».
- из docs/README.md убрана ссылка (файл для людей, не для агентов).
- Проверка:
- cat docs/agent-dag-testing.md && grep agent-dag-testing AGENTS.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Зачем:
- необходимо зафиксировать контекст и правила работы с проектом для Claude AI.
- Что:
- создан файл CLAUDE.md с описанием структуры проекта.
- добавлены инструкции по коммитам и стилю кода.
- Проверка:
- git show --stat HEAD
- Зачем:
- линейный граф маскировал реальные зависимости данных; для эталонного
стенда важно показать менти параллельный граф там, где данные независимы.
- Что:
- 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>