docs(all): реструктурирована документация — docs/internal/ заменён на design/, reference/, archive/, plans/

- Зачем:
  - docs/internal/ превратился в свалку: дизайн-документы, ревью, планы и справочники лежали вперемешку.
  - архивные планы были неотличимы от живых документов.
- Что:
  - docs/internal/ удалён; файлы распределены по docs/design/, docs/reference/, docs/archive/, docs/plans/, docs/assignment/.
  - educational-tasks.md убран из корня в архив (устарел).
  - обновлены все перекрёстные ссылки в AGENTS.md, TODO.md, README.md, docs/README.md и внутри design/reference/.
  - актуализированы architecture_review.md (статус DM-слоя), db_schema.md (DM-слой), TESTING.md, dag_execution_order.md, pxf_bookings.md.
  - добавлены заглушки docs/assignment/README.md и docs/plans/README.md.
- Проверка:
  - make test && make lint
  - rg 'docs/internal' --glob '!docs/archive/*' — должно быть пусто.
This commit is contained in:
2026-03-10 23:02:41 +03:00
parent 5972bcc2d8
commit 6655326caa
29 changed files with 322 additions and 64 deletions
+2 -2
View File
@@ -12,7 +12,7 @@
- `airflow/dags/` — DAG-файлы (напр. `bookings_to_gp_stage.py`). - `airflow/dags/` — DAG-файлы (напр. `bookings_to_gp_stage.py`).
- `sql/` — DDL и SQL-скрипты. Разделены на слои: src/ (исходные системы), stg/ (стейджинг), ods/ (операционное хранилище), dds/ (детальное хранилище), dm/ (слой витрин). - `sql/` — DDL и SQL-скрипты. Разделены на слои: src/ (исходные системы), stg/ (стейджинг), ods/ (операционное хранилище), dds/ (детальное хранилище), dm/ (слой витрин).
- *Правило ИИ:* DDL таблиц хранится строго рядом с объектом (напр. `sql/stg/bookings_ddl.sql`). - *Правило ИИ:* DDL таблиц хранится строго рядом с объектом (напр. `sql/stg/bookings_ddl.sql`).
- `docs/internal/naming_conventions.md` — Единый источник истины для нейминга служебных и SCD-полей. *Правило ИИ: Всегда сверяться с этим файлом при генерации новых DDL/SQL.* - `docs/design/naming_conventions.md` — Единый источник истины для нейминга служебных и SCD-полей. *Правило ИИ: Всегда сверяться с этим файлом при генерации новых DDL/SQL.*
- `tests/` — pytest-тесты (smoke-тесты DAG'ов и юнит-тесты). - `tests/` — pytest-тесты (smoke-тесты DAG'ов и юнит-тесты).
- `.env` — Настройки окружения (все секреты `GP_*`, `AIRFLOW_*` берем только отсюда). - `.env` — Настройки окружения (все секреты `GP_*`, `AIRFLOW_*` берем только отсюда).
@@ -42,7 +42,7 @@
- `sql/ods/` — скрипты ODS (операционное хранилище); - `sql/ods/` — скрипты ODS (операционное хранилище);
- `sql/dds/` — скрипты DDS (детальное хранилище, star schema); - `sql/dds/` — скрипты DDS (детальное хранилище, star schema);
- `sql/dm/` — скрипты DM (витрины / data marts). - `sql/dm/` — скрипты DM (витрины / data marts).
- Нейминг служебных полей и SCD-полей фиксирован в `docs/internal/naming_conventions.md` (единый источник для всех новых слоёв). - Нейминг служебных полей и SCD-полей фиксирован в `docs/design/naming_conventions.md` (единый источник для всех новых слоёв).
- Именование файлов: `{объект}_{роль}.sql`, где: - Именование файлов: `{объект}_{роль}.sql`, где:
- `объект` — логическое имя сущности (`bookings`, `orders`, и т.п.); - `объект` — логическое имя сущности (`bookings`, `orders`, и т.п.);
- `роль``ddl` (создание/изменение объектов), `load` (загрузка/инкремент), `dq` (проверки качества данных) и т.п. - `роль``ddl` (создание/изменение объектов), `load` (загрузка/инкремент), `dq` (проверки качества данных) и т.п.
+1 -1
View File
@@ -143,7 +143,7 @@ make clean # полный reset: удалить контейнер
## Документация ## Документация
- [Учебные задания](educational-tasks.md) - [Учебные задания](docs/assignment/README.md)
- [План тестирования/проверок и негативные кейсы](TESTING.md) - [План тестирования/проверок и негативные кейсы](TESTING.md)
- [Дополнительные заметки и технические детали](docs/README.md) - [Дополнительные заметки и технические детали](docs/README.md)
- [Детали по STG DAG](docs/bookings_to_gp_stage.md) - [Детали по STG DAG](docs/bookings_to_gp_stage.md)
+1 -1
View File
@@ -77,4 +77,4 @@
## Текущий статус (пример успешного прогона) ## Текущий статус (пример успешного прогона)
- `uv run pytest -q` — 14 passed, 9 smoke-тестов DAG пропущены (Airflow не установлен в venv). - `uv run pytest -q` — 14 passed, 9 smoke-тестов DAG пропущены (Airflow не установлен в venv).
- `make lint` — проходит (DAG‑файлы отформатированы black/isort). - `make lint` — проходит (DAG‑файлы отформатированы black/isort).
- Docker-стенд не запускался в рамках этой сессии; ожидается, что инструкции выше обеспечат полноценную проверку. - Полный ETL-цикл (STG→ODS→DDS→DM) проверен на стенде 2026-03-09: все DAG-и завершились с Success.
+6 -6
View File
@@ -3,8 +3,8 @@
Этот файл собирает задачи по подготовке стенда к курсовой работе Этот файл собирает задачи по подготовке стенда к курсовой работе
и идеи по доработке, которые не критичны для текущих задач менти. и идеи по доработке, которые не критичны для текущих задач менти.
Контекст и стратегия: [docs/internal/PRD.md](docs/internal/PRD.md). Контекст и стратегия: [docs/design/PRD.md](docs/design/PRD.md).
Дизайн задания: [docs/internal/assignment_design.md](docs/internal/assignment_design.md). Дизайн задания: [docs/design/assignment_design.md](docs/design/assignment_design.md).
--- ---
@@ -40,7 +40,7 @@
### Этап 2. Подготовка main ### Этап 2. Подготовка main
**Инструмент:** Sonnet — удаление файлов и добавление заглушек **Инструмент:** Sonnet — удаление файлов и добавление заглушек
по списку из [assignment_design.md](docs/internal/assignment_design.md). по списку из [assignment_design.md](docs/design/assignment_design.md).
- [ ] Оставить только эталонный срез (sales_report + цепочка) - [ ] Оставить только эталонный срез (sales_report + цепочка)
- [ ] Убрать реализации таблиц-заданий (airplanes, seats, routes в STG/ODS; - [ ] Убрать реализации таблиц-заданий (airplanes, seats, routes в STG/ODS;
@@ -118,14 +118,14 @@
- при необходимости доработать init‑скрипты в `pxf/init/` и/или документацию, - при необходимости доработать init‑скрипты в `pxf/init/` и/или документацию,
чтобы порядок действий для ментей был однозначным и воспроизводимым; чтобы порядок действий для ментей был однозначным и воспроизводимым;
- добавить краткий раздел в README/TESTING о типичных ошибках PXF/Greenplum и шагах по их устранению. - добавить краткий раздел в README/TESTING о типичных ошибках PXF/Greenplum и шагах по их устранению.
- диагностика текущего кейса: `docs/internal/pxf_bookings.md` (раздел «Известная проблема»). - диагностика текущего кейса: `docs/reference/pxf_bookings.md` (раздел «Известная проблема»).
- [x] Разобраться с генератором demodb: - [x] Разобраться с генератором demodb:
- после `make bookings-generate` таблица `bookings.bookings` остаётся пустой; - после `make bookings-generate` таблица `bookings.bookings` остаётся пустой;
- патчи `bookings/patches/engine_jobs1_sync.patch` и `bookings/patches/install_drop_if_exists.patch` - патчи `bookings/patches/engine_jobs1_sync.patch` и `bookings/patches/install_drop_if_exists.patch`
падают при применении (hunk failed / garbage in patch); падают при применении (hunk failed / garbage in patch);
- из‑за этого DAG `bookings_to_gp_stage` валится на проверках (источник пустой). - из‑за этого DAG `bookings_to_gp_stage` валится на проверках (источник пустой).
- детали: `docs/internal/bookings_db_issues.md` - детали: `docs/reference/bookings_db_issues.md`
- [x] Добавить раздел «Благодарности» в `README.md`: - [x] Добавить раздел «Благодарности» в `README.md`:
- явно поблагодарить Postgres Pro за демо‑БД bookings (репозиторий `postgrespro/demodb`); - явно поблагодарить Postgres Pro за демо‑БД bookings (репозиторий `postgrespro/demodb`);
@@ -138,4 +138,4 @@
- привести измерение в соответствие с принципом Кимбалла («самодостаточное измерение»); - привести измерение в соответствие с принципом Кимбалла («самодостаточное измерение»);
- упростить `dm.route_performance` с 4-JOIN до 1-JOIN; - упростить `dm.route_performance` с 4-JOIN до 1-JOIN;
- обновить DAG-зависимости: airports+airplanes DQ → routes load; - обновить DAG-зависимости: airports+airplanes DQ → routes load;
- подробный план: `docs/internal/dim_routes_denormalization_plan.md`. - подробный план: `docs/archive/dim_routes_denormalization_plan.md`.
+30 -9
View File
@@ -5,20 +5,41 @@
## Быстрый путь (для менти) ## Быстрый путь (для менти)
- [Быстрый старт и команды](../README.md) - [Быстрый старт и команды](../README.md)
- [Учебные задания](../educational-tasks.md) - [Учебные задания](assignment/README.md)
- [План тестирования и проверки](../TESTING.md) - [План тестирования и проверки](../TESTING.md)
- [Главный учебный DAG: bookings → stg](bookings_to_gp_stage.md) - [Главный учебный DAG: bookings → stg](bookings_to_gp_stage.md)
- [Учебный DAG: stg -> ods](bookings_to_gp_ods.md) - [Учебный DAG: stg -> ods](bookings_to_gp_ods.md)
- [Учебный DAG: ods -> dds](bookings_to_gp_dds.md) - [Учебный DAG: ods -> dds](bookings_to_gp_dds.md)
- [Учебный DAG: dds -> dm](bookings_to_gp_dm.md) - [Учебный DAG: dds -> dm](bookings_to_gp_dm.md)
## Технические детали (опционально) ## Дизайн (`design/`)
- [Единые конвенции нейминга DWH (служебные поля и SCD)](design/naming_conventions.md)
- [Схема БД всех слоёв DWH](design/db_schema.md)
- [Дизайн-документ STG](design/bookings_stg_design.md)
- [Дизайн-документ ODS](design/bookings_ods_design.md)
- [Дизайн-документ DDS](design/bookings_dds_design.md)
- [Дизайн-документ DM](design/bookings_dm_design.md)
- [Архитектурные решения (ADR)](design/architecture_review.md)
- [PRD: стратегия курсовой](design/PRD.md)
- [Дизайн задания](design/assignment_design.md)
## Справочники (`reference/`)
- [Как устроен Docker-стенд (образы, Connections, переменные окружения)](stack.md) - [Как устроен Docker-стенд (образы, Connections, переменные окружения)](stack.md)
- [Единые конвенции нейминга DWH (служебные поля и SCD)](internal/naming_conventions.md) - [PXF в этом проекте (проектная реализация)](reference/pxf_bookings.md)
- [PXF в этом проекте (проектная реализация)](internal/pxf_bookings.md) - [Про время/UTC в bookings](reference/bookings_tz.md)
- [Дизайн-документ STG](internal/bookings_stg_design.md) - [Известные проблемы bookings-db](reference/bookings_db_issues.md)
- [Дизайн-документ ODS](internal/bookings_ods_design.md) - [Бенчмарк генерации данных](reference/bookings_generation_benchmark.md)
- [Дизайн-документ DDS](internal/bookings_dds_design.md) - [QA-план отладки пайплайна](reference/qa-plan.md)
- [Дизайн-документ DM](internal/bookings_dm_design.md) - [Порядок запуска DAG-ов](dag_execution_order.md)
- [Про время/UTC в bookings](internal/bookings_tz.md) - [End-to-end протокол тестирования](e2e-etl-test-protocol.md)
- [Тестирование DAG-ов через API](agent-dag-testing.md)
## Планы (`plans/`)
Активные планы работ. После выполнения переносятся в `archive/`.
## Архив (`archive/`)
Выполненные планы, закрытые ревью. Ссылки внутри файлов могут быть устаревшими.
+220
View File
@@ -0,0 +1,220 @@
# План ревизии документации
> Статус: **ЧЕРНОВИК v3** | Дата: 2026-03-10
> Контекст: перед Этапом 2 (подготовка main) нужно навести порядок в docs/
---
## Проблемы
- `docs/internal/` — свалка: дизайн-документы, планы, ревью, баг-трекеры, стандарты
- 3 архивных плана лежат рядом с живыми документами (неотличимы)
- 3 осиротевших документа (никто не ссылается)
- `educational-tasks.md` в корне — устарел (раздел 2.2 говорит «ODS/DDS/DM будут позже»)
- 5 документов содержат устаревшие фрагменты
- `docs/README.md` не знает про несколько живых документов
---
## Принципы
- **Архив замораживается.** Файлы в `docs/archive/` не правим — ссылки внутри них
могут быть битыми, это ожидаемо. Они сохраняются как исторические артефакты.
- **Активные планы** живут в `docs/plans/`, после выполнения переезжают в `docs/archive/`.
- **Студенческий entry point** не должен исчезать: пока `analyst_spec.md` (Этап 3)
не создан, в `docs/assignment/` будет заглушка `README.md` со ссылкой на эталонный
срез для самостоятельного изучения.
---
## Фаза 1. Структура каталогов
Создать новые каталоги:
```
docs/design/ — дизайн-документы, стандарты, архитектура
docs/reference/ — техническая справка, баг-трекеры, бенчмарки
docs/plans/ — активные планы работ
docs/archive/ — выполненные планы, закрытые ревью
docs/assignment/ — заглушка README.md (подготовка для Этапа 3)
```
---
## Фаза 2. Перемещение файлов
### В `docs/archive/` (4 файла)
| Откуда | Файл | Причина |
|--------|-------|---------|
| корень | `educational-tasks.md` | Устарел, заменён `assignment_design.md` |
| `docs/internal/` | `stg_naming_unification_plan.md` | Выполнен |
| `docs/internal/` | `dim_routes_denormalization_plan.md` | Выполнен |
| `docs/internal/` | `bookings_stg_code_review.md` | Все замечания закрыты |
### В `docs/plans/` (1 файл)
| Откуда | Файл | Примечание |
|--------|-------|---------|
| `docs/internal/` | `docs_restructuring_plan.md` | Этот план — активный; после выполнения → `docs/archive/` |
### В `docs/design/` (9 файлов из `docs/internal/`)
| Файл | Роль |
|------|------|
| `PRD.md` | Стратегия продукта |
| `assignment_design.md` | Дизайн курсового задания |
| `naming_conventions.md` | Стандарт нейминга (единый источник) |
| `db_schema.md` | Схема БД всех слоёв DWH |
| `bookings_stg_design.md` | Дизайн STG-слоя |
| `bookings_ods_design.md` | Дизайн ODS-слоя |
| `bookings_dds_design.md` | Дизайн DDS-слоя |
| `bookings_dm_design.md` | Дизайн DM-слоя |
| `architecture_review.md` | Архитектурные решения (ADR) |
### В `docs/reference/` (5 файлов из `docs/internal/`)
| Файл | Роль |
|------|------|
| `pxf_bookings.md` | PXF: настройка, проблемы |
| `bookings_tz.md` | Источник bookings-db |
| `bookings_db_issues.md` | Известные проблемы bookings-db |
| `bookings_generation_benchmark.md` | Бенчмарк генерации |
| `qa-plan.md` | План отладки пайплайна |
**Итог:** `docs/internal/` опустеет → удалить.
---
## Фаза 3. Обновление перекрёстных ссылок
### Категория A. Корневые и публичные файлы (ссылаются на `docs/internal/`)
| Файл | Ссылок | Детали замен |
|------|--------|------|
| `AGENTS.md` | 2 | строки 15, 45: `docs/internal/naming_conventions.md``docs/design/naming_conventions.md` |
| `TODO.md` | 6 | строки 6, 7, 43: → `docs/design/`; строка 121: → `docs/reference/pxf_bookings.md`; строка 128: → `docs/reference/bookings_db_issues.md`; строка 141: → `docs/archive/dim_routes_denormalization_plan.md` |
| `docs/README.md` | 7 | строки 18-24: все `internal/*``design/*` или `reference/*` |
| `docs/bookings_to_gp_stage.md` | 2 | строка 151: → `reference/pxf_bookings.md`; строка 156: → `archive/bookings_stg_code_review.md` |
| `docs/stack.md` | 1 | строка 85: → `reference/pxf_bookings.md` |
### Категория B. Файлы внутри `docs/design/` и `docs/reference/`
Полный реестр ссылок с `docs/internal/` в файлах, которые переедут в `design/` или
`reference/`. Все требуют обновления — либо кросс-каталожные пути, либо display-тексты.
**B1. Кросс-каталожные ссылки (ссылка ведёт в другой каталог — путь сломается):**
| Файл (→ design/) | Строка | Ссылка | Новый путь |
|------|--------|--------|------|
| `db_schema.md` | 426 | `bookings_tz.md` (отн.) | `../reference/bookings_tz.md` |
| `db_schema.md` | 427 | `pxf_bookings.md` (отн.) | `../reference/pxf_bookings.md` |
| `db_schema.md` | 425 | `bookings_stg_code_review.md` (отн.) | `../archive/bookings_stg_code_review.md` |
| `bookings_stg_design.md` | 5 | `docs/internal/bookings_tz.md` | `../reference/bookings_tz.md` |
| `bookings_stg_design.md` | 130 | `docs/internal/bookings_tz.md` | `../reference/bookings_tz.md` |
| `bookings_stg_design.md` | 131 | `docs/internal/pxf_bookings.md` | `../reference/pxf_bookings.md` |
| Файл (→ reference/) | Строка | Ссылка | Новый путь |
|------|--------|--------|------|
| `qa-plan.md` | 10 | `docs/internal/bookings_db_issues.md` | `bookings_db_issues.md` (тот же каталог) |
**B2. Внутрикаталожные, но с полным путём `docs/internal/...` (путь не сломается
для ссылок с относительным target, но display-текст устареет):**
| Файл (→ design/) | Строки | Что обновить |
|------|--------|------|
| `PRD.md` | 209 | `docs/internal/naming_conventions.md``docs/design/naming_conventions.md` |
| `bookings_ods_design.md` | 48 | display-текст `docs/internal/naming_conventions.md``docs/design/naming_conventions.md` |
| `bookings_dds_design.md` | 8 | `docs/internal/bookings_ods_design.md``docs/design/bookings_ods_design.md` |
| `bookings_dds_design.md` | 185 | display-текст `docs/internal/naming_conventions.md``docs/design/naming_conventions.md` |
| `bookings_dds_design.md` | 828-829 | `docs/internal/bookings_dds_design.md`, `docs/internal/db_schema.md``docs/design/...` |
| `bookings_dds_design.md` | 945 | `docs/internal/db_schema.md``docs/design/db_schema.md` |
| `bookings_dm_design.md` | 279 | `docs/internal/db_schema.md``docs/design/db_schema.md` |
| `bookings_dm_design.md` | 283, 291 | `docs/internal/bookings_dm_design.md``docs/design/bookings_dm_design.md` |
| `bookings_dm_design.md` | 395 | `docs/internal/naming_conventions.md``docs/design/naming_conventions.md` |
| `db_schema.md` | 26 | display-текст `docs/internal/naming_conventions.md``docs/design/naming_conventions.md` |
| `db_schema.md` | 421-423 | display-тексты `docs/internal/bookings_*_design.md``docs/design/...` |
| `architecture_review.md` | 70 | `docs/internal/bookings_dm_design.md``docs/design/bookings_dm_design.md` |
| `architecture_review.md` | 146 | `docs/internal/distribution_strategy.md`**удалить путь** (файл не существует, оставить как текстовый backlog-пункт без ссылки) |
### Категория C. Ссылки на `educational-tasks.md`
| Файл | Действие |
|------|----------|
| `README.md` (корень) | Заменить ссылку на `educational-tasks.md``docs/assignment/` |
| `docs/README.md` | Заменить ссылку на `educational-tasks.md``assignment/` |
### Категория D. Файлы в `docs/archive/` — НЕ ТРОГАЕМ
Архивные файлы замораживаются. Ссылки внутри них могут быть битыми — это ожидаемо.
### Комментарий в SQL
`sql/dm/sales_report_ddl.sql` строка 52: `naming_conventions.md` (без пути) —
оставить как есть (комментарий, не ссылка; путь и так неточный).
---
## Фаза 4. Актуализация содержания
| Файл (новый путь) | Что сделать |
|------|-------------|
| `docs/design/architecture_review.md` | DM завершён (5/5 витрин), пометить выполненные P2; строка 146 — убрать путь к несуществующему `distribution_strategy.md`, оставить как текстовый backlog-пункт |
| `docs/design/db_schema.md` | Добавить DM-слой, убрать выполненный TODO |
| `TESTING.md` | Убрать артефакт «Docker-стенд не запускался» |
| `docs/dag_execution_order.md` | Добавить все 4 DDL DAG-а |
| `docs/reference/pxf_bookings.md` | Исправить нумерацию разделов (7→9→8→10 → последовательную) |
---
## Фаза 5. Обновление индексов и заглушка assignment
### `docs/README.md`
Переписать структуру: разделы по каталогам (`design/`, `reference/`, `plans/`,
`archive/`, `assignment/`). Включить ранее пропущенные документы: `db_schema.md`,
`dag_execution_order.md`, `e2e-etl-test-protocol.md`, `agent-dag-testing.md`.
### `README.md` (корень)
Заменить ссылку на `educational-tasks.md``docs/assignment/`, проверить остальные.
### `docs/assignment/README.md` (новый файл)
Временная заглушка:
- Указание, что курсовые задания появятся в Этапе 3
- Ссылка на эталонный срез (DAG-и STG→ODS→DDS→DM) для самостоятельного изучения
- Ссылка на `docs/design/assignment_design.md` для менторов
---
## Фаза 6. Финальная проверка
Шаги выполняются строго по порядку:
1. [ ] `make test` — тесты проходят
2. [ ] `make lint` — стиль кода
3. [ ] Удалить пустой каталог `docs/internal/`
4. [ ] Перенести план из `docs/plans/` в `docs/archive/docs_restructuring_plan.md`
5. [ ] grep по `internal/` в живых .md файлах (`rg --glob '!docs/archive/*'`) — нет битых ссылок
6. [ ] grep по `educational-tasks` в живых .md файлах (`rg --glob '!docs/archive/*'`) — нет битых ссылок
---
## Порядок выполнения
Фазы 1→2→3 делаются вместе (иначе ссылки будут битыми).
Фаза 4 — независима, можно параллельно.
Фаза 5 — после всех перемещений.
Фаза 6 — в конце.
---
## Что это даёт следующим этапам
| Этап | Как помогает |
|------|-------------|
| **Этап 2** (подготовка main) | Чистая структура — понятно, что удалять, что оставлять |
| **Этап 3** (ТЗ от аналитика) | Готовый каталог `docs/assignment/` с заглушкой, место для `analyst_spec.md` |
| **Этап 4** (валидационный DAG) | `docs/reference/qa-plan.md` — рядом с другими справочными |
| **Этап 5** (ветка solution) | Архив отделён — не попадёт в ветку solution |
+20
View File
@@ -0,0 +1,20 @@
# Учебные задания
> **Статус:** Задания появятся в Этапе 3 — сейчас ведётся подготовка.
Курсовые задания для студентов (ТЗ от аналитика, описания таблиц, маппинги, бизнес-правила)
будут опубликованы здесь в виде файла `analyst_spec.md`.
## Пока задания не готовы
Изучите эталонный срез самостоятельно:
- [DAG STG: bookings → Greenplum](../bookings_to_gp_stage.md)
- [DAG ODS: STG → ODS](../bookings_to_gp_ods.md)
- [DAG DDS: ODS → DDS](../bookings_to_gp_dds.md)
- [DAG DM: DDS → витрины](../bookings_to_gp_dm.md)
- [Порядок запуска DAG-ов](../dag_execution_order.md)
## Для менторов
Дизайн заданий и педагогическая логика: [docs/design/assignment_design.md](../design/assignment_design.md).
+2 -2
View File
@@ -148,9 +148,9 @@ LIMIT 10;
- `database "demo" does not exist`: демо‑БД не установлена → выполните `make bookings-init`. - `database "demo" does not exist`: демо‑БД не установлена → выполните `make bookings-init`.
- Ошибки про `stg.*`/`stg.*_ext`: не применён DDL → запустите `bookings_stg_ddl` или `make ddl-gp`. - Ошибки про `stg.*`/`stg.*_ext`: не применён DDL → запустите `bookings_stg_ddl` или `make ddl-gp`.
- Ошибки PXF (`protocol "pxf" does not exist`, connection refused): перезапустите `greenplum` и повторите DDL. - Ошибки PXF (`protocol "pxf" does not exist`, connection refused): перезапустите `greenplum` и повторите DDL.
Для технических деталей см. `docs/internal/pxf_bookings.md`. Для технических деталей см. `docs/reference/pxf_bookings.md`.
## Рекомендации по качеству решения ## Рекомендации по качеству решения
Ревью решения и список улучшений, которые делают пайплайн более “эталонным” для обучения: Ревью решения и список улучшений, которые делают пайплайн более “эталонным” для обучения:
`docs/internal/bookings_stg_code_review.md`. `docs/archive/bookings_stg_code_review.md`.
+5 -3
View File
@@ -8,10 +8,12 @@
## 1. DDL-скрипты (выполняются один раз) ## 1. DDL-скрипты (выполняются один раз)
Для создания структуры таблиц в аналитических слоях: Для создания структуры таблиц в аналитических слоях:
1. Запустите `bookings_dds_ddl` — создаст таблицы для измерений и фактов в слое DDS. 1. Запустите `bookings_stg_ddl` — создаст STG-таблицы и внешние `*_ext` через PXF.
2. Запустите `bookings_dm_ddl` — создаст таблицы витрин в слое DM. 2. Запустите `bookings_ods_ddl` — создаст таблицы ODS (типизированные, SCD1).
3. Запустите `bookings_dds_ddl` — создаст таблицы для измерений и фактов в слое DDS.
4. Запустите `bookings_dm_ddl` — создаст таблицы витрин в слое DM.
*(Слои STG и ODS создаются при старте стенда через `make ddl-gp` или могут быть пересозданы соответствующими DDL-скриптами).* *(Технический шорткат: `make ddl-gp` применяет DDL для всех 4 слоёв сразу).*
## 2. Ежедневная загрузка (ETL) ## 2. Ежедневная загрузка (ETL)
+1 -1
View File
@@ -206,7 +206,7 @@ solution (полное решение)
### Для ментора (ревью + защита) ### Для ментора (ревью + защита)
- [ ] Код соответствует naming conventions (`docs/internal/naming_conventions.md`) - [ ] Код соответствует naming conventions (`docs/design/naming_conventions.md`)
- [ ] SQL идемпотентен (повторный запуск не ломает данные) - [ ] SQL идемпотентен (повторный запуск не ломает данные)
- [ ] Distribution keys выбраны осмысленно - [ ] Distribution keys выбраны осмысленно
- [ ] Студент может объяснить: почему delete+insert, а не MERGE; - [ ] Студент может объяснить: почему delete+insert, а не MERGE;
@@ -67,7 +67,7 @@ GP-специфичная best practice, которую забывают даж
- `bookings_dm_design.md` (строка 182): `DISTRIBUTED BY (traffic_date)` - `bookings_dm_design.md` (строка 182): `DISTRIBUTED BY (traffic_date)`
- `sales_report_ddl.sql`: явно объясняет, почему distribution by date — антипаттерн - `sales_report_ddl.sql`: явно объясняет, почему distribution by date — антипаттерн
- **Нужно**: исправить на `DISTRIBUTED BY (airport_sk)` в дизайн-документе - **Нужно**: исправить на `DISTRIBUTED BY (airport_sk)` в дизайн-документе
- Файл: `docs/internal/bookings_dm_design.md` - Файл: `docs/design/bookings_dm_design.md`
### P1: Высокий эффект, минимум усилий (комментарии и документация) ### P1: Высокий эффект, минимум усилий (комментарии и документация)
@@ -129,10 +129,10 @@ GP-специфичная best practice, которую забывают даж
- Файлы: `sql/ods/airports_load.sql`, `sql/ods/flights_load.sql`, `sql/ods/routes_load.sql` - Файлы: `sql/ods/airports_load.sql`, `sql/ods/flights_load.sql`, `sql/ods/routes_load.sql`
- *Заметка*: Для всех транзакционных таблиц ODS внедрен паттерн TEMP TABLE для надежной работы HWM. - *Заметка*: Для всех транзакционных таблиц ODS внедрен паттерн TEMP TABLE для надежной работы HWM.
- [ ] **DM слой незавершён** - [x] **DM слой спроектирован**
- 1 из 5 витрин реализована, остальные — закомментированные заглушки - 5 витрин: `sales_report`, `route_performance`, `passenger_loyalty`, `airport_traffic`, `monthly_overview`
- **Решение**: реализовать `route_performance` (full rebuild + AO Column Store); остальные 3 — задания для студентов - `sales_report`, `route_performance` — эталонные реализации; `passenger_loyalty`, `airport_traffic`, `monthly_overview` — задания для студентов
- Файлы: `sql/dm/route_performance_*.sql` (новые), DAG, тесты - `route_performance` — full rebuild + AO Column Store
### P3: Хорошо бы, но не горит ### P3: Хорошо бы, но не горит
@@ -143,7 +143,7 @@ GP-специфичная best practice, которую забывают даж
- **Решение**: добавить один опциональный пример `sql/lib/dq_assert_no_duplicates()` как seed - **Решение**: добавить один опциональный пример `sql/lib/dq_assert_no_duplicates()` как seed
- [ ] **Нет документа по стратегии distribution** - [ ] **Нет документа по стратегии distribution**
- **Решение**: `docs/internal/distribution_strategy.md` с объяснением логики для каждого слоя - **Решение**: создать `docs/design/distribution_strategy.md` с объяснением логики для каждого слоя
- [ ] **Отсутствующие паттерны** (комментарии/заметки): - [ ] **Отсутствующие паттерны** (комментарии/заметки):
- Partitioning (когда и зачем, почему не здесь) - Partitioning (когда и зачем, почему не здесь)
@@ -5,7 +5,7 @@
STG (9 таблиц, TEXT, append-only) и ODS (9 таблиц, типизированные, SCD1) уже реализованы. STG (9 таблиц, TEXT, append-only) и ODS (9 таблиц, типизированные, SCD1) уже реализованы.
Этот план фиксирует реализацию DDS-слоя: Star Schema с измерениями и таблицей фактов. Этот план фиксирует реализацию DDS-слоя: Star Schema с измерениями и таблицей фактов.
Формат плана аналогичен `docs/internal/bookings_ods_design.md` — достаточно детальный, Формат плана аналогичен `docs/design/bookings_ods_design.md` — достаточно детальный,
чтобы реализация была однозначной. чтобы реализация была однозначной.
--- ---
@@ -182,7 +182,7 @@ DQ-проверки явно контролируют каждую группу
## 4) Нейминг служебных полей (консистентно с naming_conventions.md) ## 4) Нейминг служебных полей (консистентно с naming_conventions.md)
Источник правил: [`docs/internal/naming_conventions.md`](naming_conventions.md). Источник правил: [`docs/design/naming_conventions.md`](naming_conventions.md).
В DDS используем: В DDS используем:
@@ -825,8 +825,8 @@ airflow/dags/ (2 новых DAG)
sql/ddl_gp.sql (+ \i dds/*_ddl.sql в конец) sql/ddl_gp.sql (+ \i dds/*_ddl.sql в конец)
tests/test_dags_smoke.py (+ 2 smoke-теста) tests/test_dags_smoke.py (+ 2 smoke-теста)
docs/bookings_to_gp_dds.md (документация для студентов) docs/bookings_to_gp_dds.md (документация для студентов)
docs/internal/bookings_dds_design.md (этот план) docs/design/bookings_dds_design.md (этот план)
docs/internal/db_schema.md (обновить: добавить dim_routes, статус DDS) docs/design/db_schema.md (обновить: добавить dim_routes, статус DDS)
``` ```
--- ---
@@ -942,7 +942,7 @@ load_dds_fact_flight_sales >> dq_dds_fact_flight_sales >> finish_dds_summary
6. DAG `airflow/dags/bookings_to_gp_dds.py` 6. DAG `airflow/dags/bookings_to_gp_dds.py`
7. Smoke-тесты в `tests/test_dags_smoke.py` (+2 теста) 7. Smoke-тесты в `tests/test_dags_smoke.py` (+2 теста)
8. Документация `docs/bookings_to_gp_dds.md` 8. Документация `docs/bookings_to_gp_dds.md`
9. Обновить `docs/internal/db_schema.md` — отразить `dim_routes` и актуальный статус DDS 9. Обновить `docs/design/db_schema.md` — отразить `dim_routes` и актуальный статус DDS
Итого: **21 SQL-файл** + **2 DAG** + **обновления 3 существующих файлов** + **1 новый doc-файл**. Итого: **21 SQL-файл** + **2 DAG** + **обновления 3 существующих файлов** + **1 новый doc-файл**.
@@ -276,11 +276,11 @@ start_dm ──>> load_dm_passenger_loyalty → dq_dm_passenger_loyalty
18. `sql/ddl_gp.sql` — добавить `\i dm/*_ddl.sql` в конец 18. `sql/ddl_gp.sql` — добавить `\i dm/*_ddl.sql` в конец
19. `tests/test_dags_smoke.py` — 2 новых теста (DDL DAG + ETL DAG) 19. `tests/test_dags_smoke.py` — 2 новых теста (DDL DAG + ETL DAG)
20. `docs/internal/db_schema.md` — добавить DM-слой в описание/Mermaid 20. `docs/design/db_schema.md` — добавить DM-слой в описание/Mermaid
### Документация (2 шт.) ### Документация (2 шт.)
21. `docs/internal/bookings_dm_design.md` — полный дизайн-документ DM-слоя (этот файл) 21. `docs/design/bookings_dm_design.md` — полный дизайн-документ DM-слоя (этот файл)
22. `docs/bookings_to_gp_dm.md` — инструкция для студентов (аналог `bookings_to_gp_dds.md`) 22. `docs/bookings_to_gp_dm.md` — инструкция для студентов (аналог `bookings_to_gp_dds.md`)
--- ---
@@ -288,7 +288,7 @@ start_dm ──>> load_dm_passenger_loyalty → dq_dm_passenger_loyalty
## Порядок реализации ## Порядок реализации
### Этап 1: Инфраструктура + эталонная витрина `dm.sales_report` ### Этап 1: Инфраструктура + эталонная витрина `dm.sales_report`
- Дизайн-документ `docs/internal/bookings_dm_design.md` - Дизайн-документ `docs/design/bookings_dm_design.md`
- DDL + load + DQ для sales_report - DDL + load + DQ для sales_report
- Оба DAG (изначально с 1 витриной) - Оба DAG (изначально с 1 витриной)
- Обновить `ddl_gp.sql` - Обновить `ddl_gp.sql`
@@ -392,7 +392,7 @@ PL/pgSQL `DO $$` блоки (как в DDS):
| DQ PL/pgSQL (RAISE EXCEPTION/NOTICE) | `sql/dds/fact_flight_sales_dq.sql` | | DQ PL/pgSQL (RAISE EXCEPTION/NOTICE) | `sql/dds/fact_flight_sales_dq.sql` |
| DDL (CREATE TABLE IF NOT EXISTS) | `sql/dds/dim_airports_ddl.sql` | | DDL (CREATE TABLE IF NOT EXISTS) | `sql/dds/dim_airports_ddl.sql` |
| Smoke-тесты DAG | `tests/test_dags_smoke.py` | | Smoke-тесты DAG | `tests/test_dags_smoke.py` |
| Naming conventions | `docs/internal/naming_conventions.md` | | Naming conventions | `docs/design/naming_conventions.md` |
--- ---
@@ -45,7 +45,7 @@ ODS в учебном проекте — это:
## 2) Нейминг служебных полей (консистентно с de-roadmap) ## 2) Нейминг служебных полей (консистентно с de-roadmap)
Источник правил: [`docs/internal/naming_conventions.md`](naming_conventions.md). Источник правил: [`docs/design/naming_conventions.md`](naming_conventions.md).
В ODS используем такие техполя: В ODS используем такие техполя:
@@ -2,7 +2,7 @@
## 1. Цель и общий контур ## 1. Цель и общий контур
- Источник: Postgres в контейнере `bookings-db`, база `demo`, таблица `bookings.bookings` (см. `docs/internal/bookings_tz.md`). - Источник: Postgres в контейнере `bookings-db`, база `demo`, таблица `bookings.bookings` (см. [`docs/reference/bookings_tz.md`](../reference/bookings_tz.md)).
- Цель: показываем путь данных от операционной БД до сырого слоя DWH в Greenplum. - Цель: показываем путь данных от операционной БД до сырого слоя DWH в Greenplum.
- В этом документе описываем часть `src (bookings-db) → STG (Greenplum)`. STG — входной слой; далее данные обрабатываются в ODS → DDS → DM (см. соответствующие design-документы). - В этом документе описываем часть `src (bookings-db) → STG (Greenplum)`. STG — входной слой; далее данные обрабатываются в ODS → DDS → DM (см. соответствующие design-документы).
@@ -127,8 +127,8 @@ DDL определён в `sql/stg/bookings_ddl.sql` и подключается
## 5. Связь с остальными документами ## 5. Связь с остальными документами
- `docs/internal/bookings_tz.md` — как готовится и генерируется источник `bookings-db`. - [`docs/reference/bookings_tz.md`](../reference/bookings_tz.md) — как готовится и генерируется источник `bookings-db`.
- `docs/internal/pxf_bookings.md` — детали настройки PXF и внешней таблицы для чтения из `bookings-db`. - [`docs/reference/pxf_bookings.md`](../reference/pxf_bookings.md) — детали настройки PXF и внешней таблицы для чтения из `bookings-db`.
- `sql/stg/bookings_ddl.sql` — DDL для схемы `stg` и таблиц `stg.bookings_ext` / `stg.bookings` (подключается из `sql/ddl_gp.sql` и применяется через `make ddl-gp`). - `sql/stg/bookings_ddl.sql` — DDL для схемы `stg` и таблиц `stg.bookings_ext` / `stg.bookings` (подключается из `sql/ddl_gp.sql` и применяется через `make ddl-gp`).
Дальнейшая обработка данных описана в design-документах ODS/DDS/DM (см. раздел 5). Дальнейшая обработка данных описана в design-документах ODS/DDS/DM (см. раздел 5).
@@ -23,7 +23,7 @@
- **Даты**: как минимум различаем `book_date` (дата покупки) и `scheduled_departure` (дата/время вылета) - **Даты**: как минимум различаем `book_date` (дата покупки) и `scheduled_departure` (дата/время вылета)
- **Инкремент в STG**: для `tickets` опорная дата берётся из `bookings.book_date`, потому что в `tickets` нет собственного поля времени изменения - **Инкремент в STG**: для `tickets` опорная дата берётся из `bookings.book_date`, потому что в `tickets` нет собственного поля времени изменения
- **DQ-проверки**: проверки качества данных выполняем SQL-скриптами, но **не сохраняем результаты в отдельные таблицы/слой DQ** (при проблемах падаем с понятной ошибкой и останавливаем пайплайн) - **DQ-проверки**: проверки качества данных выполняем SQL-скриптами, но **не сохраняем результаты в отдельные таблицы/слой DQ** (при проблемах падаем с понятной ошибкой и останавливаем пайплайн)
- **Нейминг полей**: единый стандарт — в [`docs/internal/naming_conventions.md`](naming_conventions.md) - **Нейминг полей**: единый стандарт — в [`docs/design/naming_conventions.md`](naming_conventions.md)
### Статус реализации по слоям ### Статус реализации по слоям
@@ -33,6 +33,7 @@
| **STG** | ✅ Готово | 9 из 9 таблиц (bookings, tickets, airports, airplanes, routes, seats, flights, segments, boarding_passes) | | **STG** | ✅ Готово | 9 из 9 таблиц (bookings, tickets, airports, airplanes, routes, seats, flights, segments, boarding_passes) |
| **ODS** | ✅ Готово | 9 из 9 таблиц + DAG `bookings_ods_ddl` и `bookings_to_gp_ods` | | **ODS** | ✅ Готово | 9 из 9 таблиц + DAG `bookings_ods_ddl` и `bookings_to_gp_ods` |
| **DDS** | ✅ Готово | 6 измерений + 1 факт + DAG `bookings_dds_ddl` и `bookings_to_gp_dds` | | **DDS** | ✅ Готово | 6 измерений + 1 факт + DAG `bookings_dds_ddl` и `bookings_to_gp_dds` |
| **DM** | ✅ Готово | 5 витрин (sales_report, route_performance, passenger_loyalty, airport_traffic, monthly_overview) + DAG `bookings_dm_ddl` и `bookings_to_gp_dm` |
### Архитектура слоёв ### Архитектура слоёв
@@ -418,13 +419,13 @@ graph LR
## Связанные документы ## Связанные документы
- [`docs/internal/bookings_stg_design.md`](bookings_stg_design.md) — Детальный дизайн STG слоя для bookings - [`docs/design/bookings_stg_design.md`](bookings_stg_design.md) — Детальный дизайн STG слоя для bookings
- [`docs/internal/bookings_ods_design.md`](bookings_ods_design.md) — Детальный дизайн ODS слоя (SCD1, batch contract, DQ) - [`docs/design/bookings_ods_design.md`](bookings_ods_design.md) — Детальный дизайн ODS слоя (SCD1, batch contract, DQ)
- [`docs/internal/bookings_dds_design.md`](bookings_dds_design.md) — План реализации DDS слоя (Star Schema, SCD2 для routes) - [`docs/design/bookings_dds_design.md`](bookings_dds_design.md) — План реализации DDS слоя (Star Schema, SCD2 для routes)
- [`docs/bookings_to_gp_dds.md`](../bookings_to_gp_dds.md) — Запуск и проверка DAG `bookings_to_gp_dds` - [`docs/bookings_to_gp_dds.md`](../bookings_to_gp_dds.md) — Запуск и проверка DAG `bookings_to_gp_dds`
- [`docs/internal/bookings_stg_code_review.md`](bookings_stg_code_review.md) — Ревью решения и рекомендации по улучшению - [`docs/archive/bookings_stg_code_review.md`](../archive/bookings_stg_code_review.md) — Ревью решения и рекомендации по улучшению
- [`docs/internal/bookings_tz.md`](bookings_tz.md) — Работа с часовыми поясами в источнике - [`docs/reference/bookings_tz.md`](../reference/bookings_tz.md) — Работа с часовыми поясами в источнике
- [`docs/internal/pxf_bookings.md`](pxf_bookings.md) — Настройка PXF для чтения из bookings-db - [`docs/reference/pxf_bookings.md`](../reference/pxf_bookings.md) — Настройка PXF для чтения из bookings-db
- [`TESTING.md`](../../TESTING.md) — Пошаговый чек-лист для тестирования стенда - [`TESTING.md`](../../TESTING.md) — Пошаговый чек-лист для тестирования стенда
--- ---
@@ -439,12 +440,3 @@ graph LR
| 2025-01-17 | 1.1 | Исправлены названия таблиц (`aircrafts_data``airplanes_data`, `ticket_flights``segments`), удалено `dim.bookings`, добавлены суррогатные ключи, добавлен слой DQ, исправлены связи | | 2025-01-17 | 1.1 | Исправлены названия таблиц (`aircrafts_data``airplanes_data`, `ticket_flights``segments`), удалено `dim.bookings`, добавлены суррогатные ключи, добавлен слой DQ, исправлены связи |
| 2025-01-XX | 1.0 | Первоначальная версия | | 2025-01-XX | 1.0 | Первоначальная версия |
---
## TODO
- [x] Реализовать STG слой полностью (все 9 таблиц)
- [x] Реализовать ODS слой
- [x] Реализовать DDS слой (измерения и факт)
- [x] Создать DAG для загрузки ODS
- [x] Создать DAG для загрузки DDS
+3
View File
@@ -0,0 +1,3 @@
# Планы работ
Активные планы. После выполнения переносятся в [`archive/`](../archive/).
@@ -101,7 +101,7 @@
- причина: файлы уже лежат в `PXF_BASE` на томе, а seed из образа по умолчанию не перетирает их; - причина: файлы уже лежат в `PXF_BASE` на томе, а seed из образа по умолчанию не перетирает их;
- решение: `make build` + restart `greenplum` + (при необходимости) `PXF_SEED_OVERWRITE=1`. - решение: `make build` + restart `greenplum` + (при необходимости) `PXF_SEED_OVERWRITE=1`.
## 9. Известная проблема: `protocol "pxf" does not exist` на «холодном старте» (исправлено) ## 8. Известная проблема: `protocol "pxf" does not exist` на «холодном старте» (исправлено)
Раньше (воспроизводилось в `./scripts/e2e_smoke.sh`) при первом `make ddl-gp` можно было получить: Раньше (воспроизводилось в `./scripts/e2e_smoke.sh`) при первом `make ddl-gp` можно было получить:
@@ -137,7 +137,7 @@
2) Проверьте наличие extension: 2) Проверьте наличие extension:
`docker compose exec greenplum bash -lc "su - gpadmin -c '/usr/local/greenplum-db/bin/psql -d gp_dwh -t -A -c \"SELECT extname FROM pg_extension WHERE extname = ''pxf'';\"'"` `docker compose exec greenplum bash -lc "su - gpadmin -c '/usr/local/greenplum-db/bin/psql -d gp_dwh -t -A -c \"SELECT extname FROM pg_extension WHERE extname = ''pxf'';\"'"`
## 8. Связанные файлы ## 9. Связанные файлы
- `Dockerfile.greenplum` - `Dockerfile.greenplum`
- `docker-compose.yml` (сервис `greenplum`: `build`, `hostname`, env, healthcheck) - `docker-compose.yml` (сервис `greenplum`: `build`, `hostname`, env, healthcheck)
@@ -7,7 +7,7 @@
> Аудитория документа: AI-агент (Sonnet) или человек, выполняющий отладку. > Аудитория документа: AI-агент (Sonnet) или человек, выполняющий отладку.
> >
> Зависимость: перед запуском этого плана нужно починить bookings-db > Зависимость: перед запуском этого плана нужно починить bookings-db
> (см. `docs/internal/bookings_db_issues.md`). > (см. `docs/reference/bookings_db_issues.md`).
--- ---
+1 -1
View File
@@ -82,7 +82,7 @@ docker compose ps # проверить health
- `PXF_SEED_OVERWRITE=1` — перезаписать конфиги при старте; - `PXF_SEED_OVERWRITE=1` — перезаписать конфиги при старте;
- `PXF_SYNC_ON_START=1` — выполнить `pxf cluster sync` при старте. - `PXF_SYNC_ON_START=1` — выполнить `pxf cluster sync` при старте.
Подробнее: `docs/internal/pxf_bookings.md`. Подробнее: `docs/reference/pxf_bookings.md`.
## Airflow: свой образ ## Airflow: свой образ