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:
+30
-9
@@ -5,20 +5,41 @@
|
||||
## Быстрый путь (для менти)
|
||||
|
||||
- [Быстрый старт и команды](../README.md)
|
||||
- [Учебные задания](../educational-tasks.md)
|
||||
- [Учебные задания](assignment/README.md)
|
||||
- [План тестирования и проверки](../TESTING.md)
|
||||
- [Главный учебный DAG: bookings → stg](bookings_to_gp_stage.md)
|
||||
- [Учебный DAG: stg -> ods](bookings_to_gp_ods.md)
|
||||
- [Учебный DAG: ods -> dds](bookings_to_gp_dds.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)
|
||||
- [Единые конвенции нейминга DWH (служебные поля и SCD)](internal/naming_conventions.md)
|
||||
- [PXF в этом проекте (проектная реализация)](internal/pxf_bookings.md)
|
||||
- [Дизайн-документ STG](internal/bookings_stg_design.md)
|
||||
- [Дизайн-документ ODS](internal/bookings_ods_design.md)
|
||||
- [Дизайн-документ DDS](internal/bookings_dds_design.md)
|
||||
- [Дизайн-документ DM](internal/bookings_dm_design.md)
|
||||
- [Про время/UTC в bookings](internal/bookings_tz.md)
|
||||
- [PXF в этом проекте (проектная реализация)](reference/pxf_bookings.md)
|
||||
- [Про время/UTC в bookings](reference/bookings_tz.md)
|
||||
- [Известные проблемы bookings-db](reference/bookings_db_issues.md)
|
||||
- [Бенчмарк генерации данных](reference/bookings_generation_benchmark.md)
|
||||
- [QA-план отладки пайплайна](reference/qa-plan.md)
|
||||
- [Порядок запуска DAG-ов](dag_execution_order.md)
|
||||
- [End-to-end протокол тестирования](e2e-etl-test-protocol.md)
|
||||
- [Тестирование DAG-ов через API](agent-dag-testing.md)
|
||||
|
||||
## Планы (`plans/`)
|
||||
|
||||
Активные планы работ. После выполнения переносятся в `archive/`.
|
||||
|
||||
## Архив (`archive/`)
|
||||
|
||||
Выполненные планы, закрытые ревью. Ссылки внутри файлов могут быть устаревшими.
|
||||
|
||||
@@ -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 |
|
||||
@@ -0,0 +1,91 @@
|
||||
# Учебные задания по стенду
|
||||
|
||||
Этот документ собирает в одном месте задания для менти.
|
||||
Он разбит на блоки: от архитектуры Greenplum и демо‑БД bookings до реализации аналитических слоев DWH.
|
||||
|
||||
Если вы только начинаете, выполняйте задания по порядку.
|
||||
|
||||
---
|
||||
|
||||
## 1. Greenplum и модель данных (введение)
|
||||
|
||||
В следующих заданиях мы будем опираться на демо‑БД bookings (Postgres) и слой STG в Greenplum.
|
||||
На этом этапе достаточно бегло посмотреть на структуру и понять общую идею, детальная проработка пойдёт позже.
|
||||
|
||||
### 1.1. Знакомство с демо‑БД bookings
|
||||
|
||||
1. Прочитайте `bookings/README.md` — какие сервисы и команды относятся к демобазе.
|
||||
2. Поднимите стенд и выполните:
|
||||
- `make up`
|
||||
- `make bookings-init`
|
||||
3. Подключитесь к демобазе:
|
||||
- `make bookings-psql`
|
||||
- посмотрите таблицы в схеме `bookings` (например, `\dt bookings.*`).
|
||||
4. Найдите таблицу `bookings.bookings` и посмотрите на её структуру:
|
||||
- какие типы колонок используются;
|
||||
- какие поля выглядят как ключи, даты, суммы.
|
||||
|
||||
### 1.2. Знакомство с STG в Greenplum
|
||||
|
||||
1. Прочитайте `sql/stg/bookings_ddl.sql` и краткое описание потока `docs/bookings_to_gp_stage.md` (если интересно — `docs/internal/bookings_stg_design.md`).
|
||||
2. Ответьте себе на вопросы:
|
||||
- чем внешняя таблица `stg.bookings_ext` отличается от внутренней `stg.bookings`;
|
||||
- зачем нужны тех.колонки `event_ts`, `_load_ts`, `_load_id`;
|
||||
- чем слой STG отличается от итоговых витрин (DDS/DM) с точки зрения моделирования.
|
||||
3. Выполните `make ddl-gp`, затем зайдите в Greenplum (`make gp-psql`) и проверьте наличие схемы и таблиц:
|
||||
- `\dn` и `\dt stg.*`
|
||||
- `SELECT * FROM stg.bookings LIMIT 5;` (после запуска соответствующего DAG).
|
||||
|
||||
### 1.3. Как генерируются учебные данные bookings
|
||||
|
||||
1. Откройте файл `bookings/generate_next_day.sql` и ответьте себе на вопросы:
|
||||
- с какой даты начинается генерация данных (посмотрите на GUC `bookings.start_date` и переменную `v_start_cfg`);
|
||||
- сколько дней генерируется при первой установке (переменная `bookings.init_days`);
|
||||
- что происходит, если таблица `bookings.bookings` уже не пустая.
|
||||
2. В демобазе (`make bookings-psql`) выполните:
|
||||
- `SELECT min(book_date), max(book_date) FROM bookings.bookings;`
|
||||
- затем запустите `make bookings-generate-day` и повторите запрос — как изменился максимальный день?
|
||||
3. Откройте `sql/src/bookings_generate_day_if_missing.sql` и обратите внимание, что:
|
||||
- логическая дата запуска DAG (`{{ ds }}`) не влияет на выбор дня генерации;
|
||||
- скрипт всегда смотрит на `max(book_date)` и добавляет **следующий** день (или несколько стартовых дней, если база пуста).
|
||||
4. Сделайте вывод: генератор всегда «шагает» по датам вперёд от максимальной даты, поэтому:
|
||||
- при `make bookings-init` вы получаете готовые данные из seed-дампа (при `make bookings-generate` генератор создаст `BOOKINGS_INIT_DAYS` дней начиная с `BOOKINGS_START_DATE`);
|
||||
- при последующих вызовах (`make bookings-generate-day` или DAG) добавляется ровно один новый день.
|
||||
|
||||
---
|
||||
|
||||
## 2. DAG bookings_to_gp_stage (заготовка заданий)
|
||||
|
||||
Этот DAG показывает путь данных от демо‑БД bookings в Postgres до сырого слоя STG в Greenplum.
|
||||
Сейчас он уже реализован как учебный пример, а в будущем вокруг него появятся отдельные задания по моделированию DWH.
|
||||
|
||||
### 2.1. Что есть сейчас
|
||||
|
||||
1. Откройте `airflow/dags/bookings_to_gp_stage.py`.
|
||||
2. Найдите в коде ссылки на SQL‑файлы:
|
||||
- `sql/src/bookings_generate_day_if_missing.sql`
|
||||
- `sql/stg/bookings_load.sql`
|
||||
- `sql/stg/bookings_dq.sql`
|
||||
3. Соотнесите шаги DAG с документом `docs/bookings_to_gp_stage.md`:
|
||||
- генерация учебного дня в `bookings.bookings`;
|
||||
- загрузка инкремента в `stg.bookings`;
|
||||
- проверка количества строк между источником и STG.
|
||||
4. Обратите внимание, как в DAG используется логическая дата запуска:
|
||||
- `{{ run_id }}` используется как `_load_id` — метка загрузки в таблице `stg.bookings` для конкретного запуска;
|
||||
- сами даты данных (какие дни есть в `bookings.bookings`) определяются генератором по `max(book_date)`, а не по `ds`.
|
||||
|
||||
На этом этапе достаточно понять общую цепочку. Детальные задания по переработке модели данных и построению ODS/DDS/DM слоёв будут добавлены позже.
|
||||
|
||||
### 2.2. Идеи для будущих заданий (черновик)
|
||||
|
||||
> Ниже — набросок задач, к которым мы вернёмся, когда базовые темы по Airflow будут освоены.
|
||||
|
||||
Планируемые направления:
|
||||
|
||||
- Спроектировать модель данных для основных сущностей демобазы bookings (рейсы, билеты, перелёты) в слоях ODS/DDS/DM.
|
||||
- Реализовать слой ODS поверх STG, аккуратно работая с временными атрибутами и ключами.
|
||||
- Построить витрины (DM) для типичных аналитических вопросов: загрузка рейсов, выручка по направлениям, динамика бронирований.
|
||||
- Добавить DAG’и, которые используют `stg.bookings` как источник и строят следующие слои DWH.
|
||||
- Расширить проверки качества данных для потоков bookings → STG → витрины.
|
||||
|
||||
Когда будете готовы к этим темам, вернитесь к этому разделу — он станет основой для следующего «модуля» лабораторных заданий.
|
||||
@@ -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).
|
||||
@@ -148,9 +148,9 @@ LIMIT 10;
|
||||
- `database "demo" does not exist`: демо‑БД не установлена → выполните `make bookings-init`.
|
||||
- Ошибки про `stg.*`/`stg.*_ext`: не применён DDL → запустите `bookings_stg_ddl` или `make ddl-gp`.
|
||||
- Ошибки 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`.
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
## 1. DDL-скрипты (выполняются один раз)
|
||||
|
||||
Для создания структуры таблиц в аналитических слоях:
|
||||
1. Запустите `bookings_dds_ddl` — создаст таблицы для измерений и фактов в слое DDS.
|
||||
2. Запустите `bookings_dm_ddl` — создаст таблицы витрин в слое DM.
|
||||
1. Запустите `bookings_stg_ddl` — создаст STG-таблицы и внешние `*_ext` через PXF.
|
||||
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)
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ solution (полное решение)
|
||||
|
||||
### Для ментора (ревью + защита)
|
||||
|
||||
- [ ] Код соответствует naming conventions (`docs/internal/naming_conventions.md`)
|
||||
- [ ] Код соответствует naming conventions (`docs/design/naming_conventions.md`)
|
||||
- [ ] SQL идемпотентен (повторный запуск не ломает данные)
|
||||
- [ ] Distribution keys выбраны осмысленно
|
||||
- [ ] Студент может объяснить: почему delete+insert, а не MERGE;
|
||||
@@ -67,7 +67,7 @@ GP-специфичная best practice, которую забывают даж
|
||||
- `bookings_dm_design.md` (строка 182): `DISTRIBUTED BY (traffic_date)`
|
||||
- `sales_report_ddl.sql`: явно объясняет, почему distribution by date — антипаттерн
|
||||
- **Нужно**: исправить на `DISTRIBUTED BY (airport_sk)` в дизайн-документе
|
||||
- Файл: `docs/internal/bookings_dm_design.md`
|
||||
- Файл: `docs/design/bookings_dm_design.md`
|
||||
|
||||
### P1: Высокий эффект, минимум усилий (комментарии и документация)
|
||||
|
||||
@@ -129,10 +129,10 @@ GP-специфичная best practice, которую забывают даж
|
||||
- Файлы: `sql/ods/airports_load.sql`, `sql/ods/flights_load.sql`, `sql/ods/routes_load.sql`
|
||||
- *Заметка*: Для всех транзакционных таблиц ODS внедрен паттерн TEMP TABLE для надежной работы HWM.
|
||||
|
||||
- [ ] **DM слой незавершён**
|
||||
- 1 из 5 витрин реализована, остальные — закомментированные заглушки
|
||||
- **Решение**: реализовать `route_performance` (full rebuild + AO Column Store); остальные 3 — задания для студентов
|
||||
- Файлы: `sql/dm/route_performance_*.sql` (новые), DAG, тесты
|
||||
- [x] **DM слой спроектирован**
|
||||
- 5 витрин: `sales_report`, `route_performance`, `passenger_loyalty`, `airport_traffic`, `monthly_overview`
|
||||
- `sales_report`, `route_performance` — эталонные реализации; `passenger_loyalty`, `airport_traffic`, `monthly_overview` — задания для студентов
|
||||
- `route_performance` — full rebuild + AO Column Store
|
||||
|
||||
### P3: Хорошо бы, но не горит
|
||||
|
||||
@@ -143,7 +143,7 @@ GP-специфичная best practice, которую забывают даж
|
||||
- **Решение**: добавить один опциональный пример `sql/lib/dq_assert_no_duplicates()` как seed
|
||||
|
||||
- [ ] **Нет документа по стратегии distribution**
|
||||
- **Решение**: `docs/internal/distribution_strategy.md` с объяснением логики для каждого слоя
|
||||
- **Решение**: создать `docs/design/distribution_strategy.md` с объяснением логики для каждого слоя
|
||||
|
||||
- [ ] **Отсутствующие паттерны** (комментарии/заметки):
|
||||
- Partitioning (когда и зачем, почему не здесь)
|
||||
@@ -5,7 +5,7 @@
|
||||
STG (9 таблиц, TEXT, append-only) и ODS (9 таблиц, типизированные, SCD1) уже реализованы.
|
||||
Этот план фиксирует реализацию DDS-слоя: Star Schema с измерениями и таблицей фактов.
|
||||
|
||||
Формат плана аналогичен `docs/internal/bookings_ods_design.md` — достаточно детальный,
|
||||
Формат плана аналогичен `docs/design/bookings_ods_design.md` — достаточно детальный,
|
||||
чтобы реализация была однозначной.
|
||||
|
||||
---
|
||||
@@ -182,7 +182,7 @@ DQ-проверки явно контролируют каждую группу
|
||||
|
||||
## 4) Нейминг служебных полей (консистентно с naming_conventions.md)
|
||||
|
||||
Источник правил: [`docs/internal/naming_conventions.md`](naming_conventions.md).
|
||||
Источник правил: [`docs/design/naming_conventions.md`](naming_conventions.md).
|
||||
|
||||
В DDS используем:
|
||||
|
||||
@@ -825,8 +825,8 @@ airflow/dags/ (2 новых DAG)
|
||||
sql/ddl_gp.sql (+ \i dds/*_ddl.sql в конец)
|
||||
tests/test_dags_smoke.py (+ 2 smoke-теста)
|
||||
docs/bookings_to_gp_dds.md (документация для студентов)
|
||||
docs/internal/bookings_dds_design.md (этот план)
|
||||
docs/internal/db_schema.md (обновить: добавить dim_routes, статус DDS)
|
||||
docs/design/bookings_dds_design.md (этот план)
|
||||
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`
|
||||
7. Smoke-тесты в `tests/test_dags_smoke.py` (+2 теста)
|
||||
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-файл**.
|
||||
|
||||
@@ -276,11 +276,11 @@ start_dm ──>> load_dm_passenger_loyalty → dq_dm_passenger_loyalty
|
||||
|
||||
18. `sql/ddl_gp.sql` — добавить `\i dm/*_ddl.sql` в конец
|
||||
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 шт.)
|
||||
|
||||
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`)
|
||||
|
||||
---
|
||||
@@ -288,7 +288,7 @@ start_dm ──>> load_dm_passenger_loyalty → dq_dm_passenger_loyalty
|
||||
## Порядок реализации
|
||||
|
||||
### Этап 1: Инфраструктура + эталонная витрина `dm.sales_report`
|
||||
- Дизайн-документ `docs/internal/bookings_dm_design.md`
|
||||
- Дизайн-документ `docs/design/bookings_dm_design.md`
|
||||
- DDL + load + DQ для sales_report
|
||||
- Оба DAG (изначально с 1 витриной)
|
||||
- Обновить `ddl_gp.sql`
|
||||
@@ -392,7 +392,7 @@ PL/pgSQL `DO $$` блоки (как в DDS):
|
||||
| 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` |
|
||||
| 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)
|
||||
|
||||
Источник правил: [`docs/internal/naming_conventions.md`](naming_conventions.md).
|
||||
Источник правил: [`docs/design/naming_conventions.md`](naming_conventions.md).
|
||||
|
||||
В ODS используем такие техполя:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 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.
|
||||
- В этом документе описываем часть `src (bookings-db) → STG (Greenplum)`. STG — входной слой; далее данные обрабатываются в ODS → DDS → DM (см. соответствующие design-документы).
|
||||
|
||||
@@ -127,8 +127,8 @@ DDL определён в `sql/stg/bookings_ddl.sql` и подключается
|
||||
|
||||
## 5. Связь с остальными документами
|
||||
|
||||
- `docs/internal/bookings_tz.md` — как готовится и генерируется источник `bookings-db`.
|
||||
- `docs/internal/pxf_bookings.md` — детали настройки PXF и внешней таблицы для чтения из `bookings-db`.
|
||||
- [`docs/reference/bookings_tz.md`](../reference/bookings_tz.md) — как готовится и генерируется источник `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`).
|
||||
|
||||
Дальнейшая обработка данных описана в design-документах ODS/DDS/DM (см. раздел 5).
|
||||
@@ -23,7 +23,7 @@
|
||||
- **Даты**: как минимум различаем `book_date` (дата покупки) и `scheduled_departure` (дата/время вылета)
|
||||
- **Инкремент в STG**: для `tickets` опорная дата берётся из `bookings.book_date`, потому что в `tickets` нет собственного поля времени изменения
|
||||
- **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) |
|
||||
| **ODS** | ✅ Готово | 9 из 9 таблиц + DAG `bookings_ods_ddl` и `bookings_to_gp_ods` |
|
||||
| **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/internal/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_stg_design.md`](bookings_stg_design.md) — Детальный дизайн STG слоя для bookings
|
||||
- [`docs/design/bookings_ods_design.md`](bookings_ods_design.md) — Детальный дизайн ODS слоя (SCD1, batch contract, DQ)
|
||||
- [`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/internal/bookings_stg_code_review.md`](bookings_stg_code_review.md) — Ревью решения и рекомендации по улучшению
|
||||
- [`docs/internal/bookings_tz.md`](bookings_tz.md) — Работа с часовыми поясами в источнике
|
||||
- [`docs/internal/pxf_bookings.md`](pxf_bookings.md) — Настройка PXF для чтения из bookings-db
|
||||
- [`docs/archive/bookings_stg_code_review.md`](../archive/bookings_stg_code_review.md) — Ревью решения и рекомендации по улучшению
|
||||
- [`docs/reference/bookings_tz.md`](../reference/bookings_tz.md) — Работа с часовыми поясами в источнике
|
||||
- [`docs/reference/pxf_bookings.md`](../reference/pxf_bookings.md) — Настройка PXF для чтения из bookings-db
|
||||
- [`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-XX | 1.0 | Первоначальная версия |
|
||||
|
||||
---
|
||||
|
||||
## TODO
|
||||
|
||||
- [x] Реализовать STG слой полностью (все 9 таблиц)
|
||||
- [x] Реализовать ODS слой
|
||||
- [x] Реализовать DDS слой (измерения и факт)
|
||||
- [x] Создать DAG для загрузки ODS
|
||||
- [x] Создать DAG для загрузки DDS
|
||||
@@ -0,0 +1,3 @@
|
||||
# Планы работ
|
||||
|
||||
Активные планы. После выполнения переносятся в [`archive/`](../archive/).
|
||||
@@ -101,7 +101,7 @@
|
||||
- причина: файлы уже лежат в `PXF_BASE` на томе, а seed из образа по умолчанию не перетирает их;
|
||||
- решение: `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` можно было получить:
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
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'';\"'"`
|
||||
|
||||
## 8. Связанные файлы
|
||||
## 9. Связанные файлы
|
||||
|
||||
- `Dockerfile.greenplum`
|
||||
- `docker-compose.yml` (сервис `greenplum`: `build`, `hostname`, env, healthcheck)
|
||||
@@ -7,7 +7,7 @@
|
||||
> Аудитория документа: AI-агент (Sonnet) или человек, выполняющий отладку.
|
||||
>
|
||||
> Зависимость: перед запуском этого плана нужно починить bookings-db
|
||||
> (см. `docs/internal/bookings_db_issues.md`).
|
||||
> (см. `docs/reference/bookings_db_issues.md`).
|
||||
|
||||
---
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ docker compose ps # проверить health
|
||||
- `PXF_SEED_OVERWRITE=1` — перезаписать конфиги при старте;
|
||||
- `PXF_SYNC_ON_START=1` — выполнить `pxf cluster sync` при старте.
|
||||
|
||||
Подробнее: `docs/internal/pxf_bookings.md`.
|
||||
Подробнее: `docs/reference/pxf_bookings.md`.
|
||||
|
||||
## Airflow: свой образ
|
||||
|
||||
|
||||
Reference in New Issue
Block a user