docs(course): каркас курса и переобвязка уроков 0–6 на путь import (#21)

Зачем: после редизайна пути менти курс ссылался на старый путь
generated-history-analytics/backfill и не проходился по новому стенду.

Что: в README курса — единый блок подготовки и канонического сброса
(make clean -> make up + ddl_init/world_init -> make superset-init),
таблица уроков дополнена лабами 07–08 («в работе»); LESSON_STANDARD и
уроки 0–6 ссылаются на канонический блок; урок 1 переведён на дозаливку
через world_next_day (кнопкой-анонсом, цена в минутах названа); урок 4 —
лесенка DAG-ов; урок 5 — словарь «база import / живой поток»; урок 6
обязателен; цифры старого мира помечены маркером «сверить-на-стенде».

Проверка: grep по generated-history-analytics/backfill в docs/course/
пуст; правки только в docs/course/; git diff --check чистый.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-23 13:22:41 +03:00
co-authored by Claude Opus 4.8
parent b57a4e2292
commit cc1cffe2f3
11 changed files with 142 additions and 171 deletions
+14 -13
View File
@@ -65,18 +65,12 @@
## 2. Руки: смотрим базовый прогон
Поднимаем стенд и создаём стартовую историю. Это штатный путь курса: готовый источник
данных стенда пишет события в Kafka, ClickHouse читает их в STG, затем batch строит
ODS, DDS и DM. Файлы `data/*.jsonl` пока остаются только кладовкой значений для этого
источника, а не источником аналитического контура.
Подготовь стенд по
[канонической инструкции курса](../README.md#подготовка-и-канонический-сброс).
После успешного `world_init` эталонный мир уже прошёл путь Kafka → STG → ODS → DDS → DM.
```bash
make generated-history-analytics
make up
```
Команда прогоняет всю цепочку слоёв и по дороге печатает в консоль блок **«Статистика DDS»** —
счётчики строк по двум нашим сущностям:
Ниже — форма блока **«Статистика DDS»**, который печатает `make transform`: счётчики
строк по двум нашим сущностям.
```
Статистика DDS:
@@ -104,6 +98,7 @@ make up
│ 2026-06-05 │ dds │ event_without_click │ orphan_events │ 0 │
└────────────┴───────┴─────────────────────┴───────────────┴─────────────┘
```
<!-- сверить-на-стенде -->
В колонке `check_date` стоит `today()` из кода витрины, так что у тебя там будет сегодняшняя
дата — не пугайся, если она не совпадёт с примером.
@@ -111,6 +106,7 @@ make up
`orphan_events = 0` — ни одной сироты. Каждое событие нашло свой клик в `dds.click`. На
чистой стартовой истории так и должно быть: данные аккуратные, ничего не потерялось. В секции
4 мы сироту устроим сами — и эта строка оживёт.
<!-- сверить-на-стенде -->
Проверь нолик сам, не верь на слово. Открой SQL-консоль `http://localhost:9123/play`
(пользователь `default`, пароль `123456`) и посчитай сирот напрямую:
@@ -126,6 +122,7 @@ WHERE click_id IS NOT NULL
`NOT IN (SELECT ...)` читается прямо по словам: «click_id события **не входит** в список всех
click_id из `dds.click`». То есть событие ссылается на клик, которого в карточках кликов нет.
Сейчас таких ноль — запомни этот запрос, в секции 4 он покажет другое число.
<!-- сверить-на-стенде -->
---
@@ -308,8 +305,10 @@ DDS — `make transform` чистит `dds.event` (`TRUNCATE`) и наполня
make transform
```
После этого `orphan_events` снова `0`, придуманное событие исчезло. А если стенд совсем «поплыл» —
полный чистый прогон: `make generated-history-analytics && make up`.
После этого `orphan_events` снова `0`, придуманное событие исчезло. А если стенд
совсем «поплыл», пройди
[канонический сброс](../README.md#подготовка-и-канонический-сброс).
<!-- сверить-на-стенде -->
---
@@ -322,6 +321,7 @@ make transform
| почему `click` меньше `event` | запрос `count()` по `dds.click` и `dds.event` | много событий ссылаются на меньшее число кликов — норма |
| правка из секции 4 (вставили сироту) | запрос `count()` сирот в play-консоли | `0 → 1` |
| та же сирота через `dm.v_events_enriched` | `SELECT device_type, geo_country ...` | поля клика пустые (`NULL`) — это `LEFT JOIN` |
<!-- сверить-на-стенде -->
---
@@ -332,6 +332,7 @@ make transform
- скрин запроса со счётчиком сирот: было `0`, после вставки стало `1`;
- либо выборка из `dm.v_events_enriched` по событию-сироте, где `device_type` и `geo_country`
пусты, — `LEFT JOIN` сохранил событие без клика.
<!-- сверить-на-стенде -->
И проверь себя на словах — примерно эти вопросы всплывут на еженедельном созвоне: