From d98ae9c48ad80807e6df056ce977026a2f71eeaf Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Sat, 6 Jun 2026 18:41:15 +0300 Subject: [PATCH] =?UTF-8?q?docs(course):=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D1=8B=D0=B9=20ai-text-lint,=20=D1=81=D0=B8=D0=BD?= =?UTF-8?q?=D1=85=D1=80=D0=BE=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20?= =?UTF-8?q?PRD=20=C2=A77=20=D0=B8=20=D1=83=D0=B1=D0=BE=D1=80=D0=BA=D0=B0?= =?UTF-8?q?=20handoff'=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - финализация подготовки уроков: пройти обязательный QA-шаг (ai-text-lint по LESSON_STANDARD §2), привести PRD к факту и убрать отработанные handoff'ы. - Что: - урок 4: убран AI-маркер S01 («не только… но и» → «и… и») по итогам прогона ai-text-lint; остальные 6 уроков чисты от маркеров. - PRD §7: закрыты устаревшие открытые вопросы (глубина урока 5, Superset), оставлен только реальный пункт — ретроспектива после первого прогона. - удалены 3 отработанных handoff'а в .scratch/handoffs/. - Проверка: - git show --stat HEAD; визуальная сверка PRD §7 и урока 4. --- .../2026-06-06-lesson6-consistency.md | 76 --------------- ...superset-dashboard-redesign-implemented.md | 96 ------------------- .../2026-06-06-superset-dashboard-redesign.md | 79 --------------- docs/course/PRD.md | 21 ++-- .../lessons/04_airflow_orchestration.md | 2 +- 5 files changed, 16 insertions(+), 258 deletions(-) delete mode 100644 .scratch/handoffs/2026-06-06-lesson6-consistency.md delete mode 100644 .scratch/handoffs/2026-06-06-superset-dashboard-redesign-implemented.md delete mode 100644 .scratch/handoffs/2026-06-06-superset-dashboard-redesign.md diff --git a/.scratch/handoffs/2026-06-06-lesson6-consistency.md b/.scratch/handoffs/2026-06-06-lesson6-consistency.md deleted file mode 100644 index ac089b7..0000000 --- a/.scratch/handoffs/2026-06-06-lesson6-consistency.md +++ /dev/null @@ -1,76 +0,0 @@ -# Handoff: консистентность урока 6 (Superset BI) - -Дата: 2026-06-06 · Язык сессии: русский - -## Задача следующей сессии - -Урок 6 — **наш** (не Codex), и он должен быть консистентен с реальным кодом -стенда. Дашборд за эту сессию менялся трижды, текст урока подтянули, но остался -**один известный зазор** + стоит сделать сквозную проверку код-сниппетов. - -**Главное (известный зазор):** в §3 урока -[`docs/course/lessons/06_superset_bi.md`](../../docs/course/lessons/06_superset_bi.md) -код-сниппет чарта `🪜 Page Funnel` (примерно строки 274–291) показывает -**урезанный** набор `params` **без многоточия** — выглядит как полный конфиг, но -реальный в [`superset/create_dashboard.py`](../../superset/create_dashboard.py) -богаче (`color_scheme`, `show_legend`, `legendOrientation`, `tooltip_label_type`, -`number_format`, `show_labels` и др.). Привести к честному виду: либо добавить -`...`/комментарий «здесь только ключевые поля», либо показать поля, которые -реально объясняются в тексте. Для задания §4 (менять `row_limit`) сниппет не -мешает, но как учебный эталон он вводит в заблуждение «это весь конфиг». - -**Заодно (сквозная проверка):** пройтись по остальным код-сниппетам урока 6 -(§3 `DASHBOARD_CONFIG` стр. ~304–309, `init_superset.py` datasets стр. ~250–258, -`v_events_enriched` JOIN стр. ~210–213) и сверить, что они не разошлись с -актуальным кодом. Метод тот же: открыть реальный файл и сравнить. - -## Контекст: что уже сделано и запушено (НЕ переделывать) - -Состав/числа дашборда уже выверены и синхронизированы с уроком. Ветка -`docs/advanced-clickstream-course`, всё запушено. Коммиты этой сессии: - -- `281d9d2` feat — честный row-lineage по слоям вместо ложной DQ-воронки - (`create_dashboard.py` + `sql/dm/40_dds_to_dm.sql`). -- `2563c79` docs — синхронизация доков и термин «зерно». -- `c9300e7` fix — 5-мин бакеты в `Events over Time` (был `Events by Hour`). -- `bf940cc` docs — пункт интро §1 урока 6 выровнен под row-lineage. - -Актуальный состав дашборда (10 чартов): KPI `Total Events / Unique Users / -Avg Events/Visit / Conversion to /confirmation`; `Events over Time` (PT5M); -`Traffic by Device`; `Geography Map`; `UTM Effectiveness Table`; `Page Funnel`; -`🧱 Rows by Layer (event)`. Имена и эти числа в уроке уже верны — менять не нужно. - -## Источники истины - -- Реализация чартов: [`superset/create_dashboard.py`](../../superset/create_dashboard.py) - (`CHARTS_CONFIG` / `DASHBOARD_CONFIG` / `DASHBOARD_ROWS`). -- Урок: [`docs/course/lessons/06_superset_bi.md`](../../docs/course/lessons/06_superset_bi.md). -- Доменные термины: [`CONTEXT.md`](../../CONTEXT.md) (визит/сессия = `click_id` — в UI - предпочитаем «визит», не «клик»). -- Стандарт уроков: `docs/course/LESSON_STANDARD.md` (регистр/голос/шапка/грабли) — - читать перед правкой текста. -- Прошлые handoff'ы по дашборду: `2026-06-06-superset-dashboard-redesign*.md` - (исторические, задача там закрыта). - -## Проверка - -- Текст не требует прогона стенда; правка чисто в `.md`. Достаточно открыть - реальный код и сверить сниппеты глазами. -- Если захочется перепроверить дашборд: стенд поднят (`docker ps`), логин - Superset формой `admin`/`admin` на `http://localhost:8088/login/` (заполнять - поля через refs снапшота, не по name-селекторам — последние давали Access - Denied), дашборд `…/superset/dashboard/ecommerce-analytics/?standalone=1`. - -## Git-гигиена - -- Ветка `docs/advanced-clickstream-course`, на ней **параллельно пишет Codex**. - Git строго **аддитивно**: не amend/rebase/reset чужих коммитов, `git add` - только своих файлов. Перед push — `git fetch` и проверить, что не разошлись. -- Коммиты — через скилл `conventional-commits` (русский, тело Зачем/Что/Проверка). - -## Suggested skills - -- `conventional-commits` — для коммита правки. -- `ai-text-lint` — прогнать изменённый фрагмент урока на AI-маркеры перед коммитом - (урок учебный, голос важен). -- `playwright-cli` — только если понадобится переснять дашборд для сверки. diff --git a/.scratch/handoffs/2026-06-06-superset-dashboard-redesign-implemented.md b/.scratch/handoffs/2026-06-06-superset-dashboard-redesign-implemented.md deleted file mode 100644 index 52c9e45..0000000 --- a/.scratch/handoffs/2026-06-06-superset-dashboard-redesign-implemented.md +++ /dev/null @@ -1,96 +0,0 @@ -# Handoff: Superset dashboard redesign implemented - -Дата: 2026-06-06 · Язык сессии: русский - -## Статус - -Редизайн Superset-дашборда реализован и закоммичен. - -Коммит: - -```text -04995af832743ed984c25af08a185f7abe0485f1 -feat(superset): обновлен состав KPI и воронки дашборда -``` - -Рабочее дерево было чистым перед созданием этого handoff; сам handoff создан после коммита. - -## Источники истины - -- Спека: [`docs/specs/2026-06-06-superset-dashboard-redesign.md`](../../docs/specs/2026-06-06-superset-dashboard-redesign.md) -- Реализация: [`superset/create_dashboard.py`](../../superset/create_dashboard.py) -- Пользовательская документация: [`docs/SUPERSET_DASHBOARD.md`](../../docs/SUPERSET_DASHBOARD.md) -- Урок 6: [`docs/course/lessons/06_superset_bi.md`](../../docs/course/lessons/06_superset_bi.md) -- Предыдущий handoff: [`2026-06-06-superset-dashboard-redesign.md`](./2026-06-06-superset-dashboard-redesign.md) - -## Что сделано - -- KPI-полоса теперь: - `Total Events · Unique Users · Avg Events/Visit · Conversion to /confirmation`. -- `Unique Sessions` удалён из KPI и из Superset metadata как obsolete chart. -- `Avg Events/Session` переименован в `Avg Events/Visit` идемпотентно через `previous_slice_names`. -- `Top Pages` переименован в `Page Funnel` и переведён на `viz_type: funnel`. -- Conversion считается как page-funnel metric: - `countIf(page_url_path = '/confirmation') / countIf(page_url_path = '/home')`. -- UTM-таблица оставлена без мёртвых колонок `purchases` / `add_to_cart`. -- `Events by Hour` оставлен: на полном датасете есть два часовых бакета. -- Документация и урок 6 синхронизированы с полным датасетом и новым dashboard flow. - -## Проверки - -Выполнено: - -```bash -make data -make transform -python3 -m py_compile superset/create_dashboard.py -make superset-dashboard -make superset-dashboard -``` - -Результаты: - -- полный датасет в DM: `1000` events, `99` visits, `99` users; -- `Avg Events/Visit = 10.1`; -- `Conversion to /confirmation = 35 / 426 = 8.2%`; -- Superset dashboard metadata: - - `dashboard_charts = 10`; - - `obsolete_unique_sessions = 0`; - - `page_funnel_type = funnel`; -- Superset API `/api/v1/dashboard/1/datasets` вернул `200`; -- browser chart-data для `Page Funnel` вернул `status: success`, 6 строк; -- browser chart-data для `Data Quality Summary` вернул `errors: []`, `status: success`. - -## Визуальная проверка - -Пользователь визуально подтвердил: «Визуально - выглядит норм». - -Скриншоты были сохранены в `/tmp` во время сессии: - -- `/tmp/ecommerce-analytics-dashboard-desktop.png` -- `/tmp/ecommerce-analytics-dashboard-lower.png` - -Они могут исчезнуть после очистки `/tmp`; при необходимости переснять через `playwright-cli`. - -## Важные детали реализации - -- Для Superset 4.1.2 `funnel` проверялся через MCP Context7 по `/apache/superset`; Context7 не дал точную строку `viz_type`. -- Решение подтверждено по установленному Superset 4.1.2: bundled example `Featured Charts/Funnel.yaml` использует `viz_type: funnel`. -- `create_dashboard.py` ищет старые имена через `previous_slice_names`, чтобы не плодить дубли при rename. -- Cleanup obsolete charts удаляет все найденные `🎯 Unique Sessions`, если metadata уже была загрязнена дублями. - -## Что осталось - -Обязательных незакрытых задач по редизайну нет. - -Возможные следующие шаги, если продолжать dashboard-направление: - -- экспортировать обновлённый dashboard JSON через `make superset-export`, если экспортный артефакт должен соответствовать новой metadata; -- отдельно модернизировать legacy chart types (`pie`, `world_map`, `dist_bar`) на ECharts, если это станет целью следующего захода; -- при развитии генератора перенести требования из спеки в его `KNOWN_ISSUES.md`. - -## Suggested skills - -- `playwright-cli` — если нужно переснять визуальную проверку dashboard. -- `conventional-commits` — если нужно коммитить этот handoff или дальнейшие правки. -- `diagnose` — если Superset chart-data или layout начнут падать после сброса volumes. diff --git a/.scratch/handoffs/2026-06-06-superset-dashboard-redesign.md b/.scratch/handoffs/2026-06-06-superset-dashboard-redesign.md deleted file mode 100644 index fd367be..0000000 --- a/.scratch/handoffs/2026-06-06-superset-dashboard-redesign.md +++ /dev/null @@ -1,79 +0,0 @@ -# Handoff: реализация редизайна Superset-дашборда - -Дата: 2026-06-06 · Язык сессии: русский · Понять-режим был включён (можно не продолжать) - -> **СТАТУС: ВЫПОЛНЕНО (2026-06-06).** Редизайн реализован (коммит `04995af`/amend -> `1bec6bb`) и визуально принят. Этот файл — исходная постановка «иди реализуй», -> оставлен как след. Актуальная сводка сделанного и возможных следующих шагов → -> [`2026-06-06-superset-dashboard-redesign-implemented.md`](./2026-06-06-superset-dashboard-redesign-implemented.md). -> Ниже — **историческая** постановка, НЕ список текущих дел. - -## Источник истины - -**Сначала прочитать спеку:** [`docs/specs/2026-06-06-superset-dashboard-redesign.md`](../../docs/specs/2026-06-06-superset-dashboard-redesign.md) -— там весь дизайн (проблема, числа данных, триаж чартов, состав KPI, решения, риски, -критерии проверки). Этот handoff — только «как возобновить», не дублирует дизайн. -Доменные термины — [`CONTEXT.md`](../../CONTEXT.md). - -## Решение одной строкой - -KPI-полоса = `Total Events · Unique Users · Avg Events/Visit · Conversion to /confirmation` -(дубль «Unique Sessions» убрать); `Top Pages → Funnel`-чарт по страницам; различие -user/session — текстом, не двумя одинаковыми цифрами; мёртвые колонки purchases — выкинуть. - -## Сделать ПЕРВЫМ делом - -1. **Снять open questions из спеки** (без них реализация буксует): - - точная формула Conversion (доля визитов с ≥1 pageview `/confirmation`?); - - поддерживает ли Superset **4.1.2** `viz_type` воронки (иначе — упорядоченный bar); - - судьба `Events by Hour` (проверить, не пустой ли на полных данных). -2. **Перегрузить стенд на ПОЛНЫЕ данные** — сейчас в ClickHouse отладочный срез - (50 событий). Нужно: `make data` (без `LIMIT`) + `make transform`. На полных - данных: 1000 событий, 99 визитов, 99 пользователей. - -## Где править и как прогонять - -- Единственный файл реализации: `superset/create_dashboard.py` - (`CHARTS_CONFIG` / `DASHBOARD_ROWS` / `ROW_HEIGHTS`). -- Прогон: `make superset-dashboard` — идемпотентно (чарты по `slice_name`, дашборд - по `slug`, обновляются на месте). При переименовании чартов следить, чтобы не - плодились дубли. - -## Проверка - -- `GET /api/v1/dashboard//datasets` → 200; DQ Summary без `Columns missing in datasource`. -- Визуально: `playwright-cli` — логин формой `admin`/`admin` на `http://localhost:8088/login/`, - затем `goto .../superset/dashboard/ecommerce-analytics/`, `screenshot --filename=/tmp/x.png` (читать через Read). - Скриншоты — в `/tmp`. `.playwright-cli/` НЕ коммитить. -- Сверка чисел с ClickHouse: креды в `configs/default_user.xml` (default / `123456`), - `docker exec clickstream-ch-kafka-superset-demo-clickhouse-1 clickhouse-client --password 123456 -q "..."`. - (Через `docker exec printenv` креды НЕ дёргать — классификатор блокирует.) - -## Если задачу берёт Codex (разрез по приёмке) - -Codex силён в реализации/рассуждении, **слаб в визуальной оценке** — а приёмка -дашборда визуальна (обе прошлые сессии были про поломки раскладки: ROW-оверлапы, -«прыгающие» KPI). Поэтому: - -- Codex делает реализацию + **не**визуальные само-проверки: API `/datasets → 200`, - числа сходятся с прямым запросом в ClickHouse, скриншоты складывает в `/tmp`. -- Codex **НЕ объявляет done по визуалу.** Самый рискованный пункт (отрисовалась ли - воронка вообще, нет ли наездов плиток) — чисто визуальный. Остановиться и передать - скриншоты на визуальный sign-off человеку или vision-агенту. - -## Синхронизировать доки ПРИ реализации - -- `docs/SUPERSET_DASHBOARD.md` — раздел «Структура дашборда» (новый состав чартов/KPI). -- `docs/course/lessons/06_superset_bi.md` — убрать `LIMIT=50 make data`, синхронизировать состав/скриншоты. - -## Git-гигиена - -- Ветка `docs/advanced-clickstream-course`, на ней **параллельно пишет Codex** — - git строго **аддитивно**, не amend/rebase/reset чужих коммитов. `git add` только своих файлов. -- Артефакты этой сессии (если ещё не закоммичены): `CONTEXT.md`, `docs/adr/0001` (правка), - `docs/adr/0002`, `docs/adr/0003`, `docs/specs/2026-06-06-...`, `AGENTS.md` (правка), этот handoff. - -## Suggested skills - -`conventional-commits` (любой коммит) · `playwright-cli` (визуальная проверка) · -`diagnose` (если чарт/датасет отвалится). diff --git a/docs/course/PRD.md b/docs/course/PRD.md index 518d2e2..81b5c9f 100644 --- a/docs/course/PRD.md +++ b/docs/course/PRD.md @@ -129,9 +129,18 @@ Kafka → ClickHouse → BI). ## 7. Открытые вопросы / на будущее -- Глубина урока 5 (мониторинг): сколько внутреннего устройства показывать против - «просто наблюдай дашборд». Кандидат — мини-правка «погаси сервис → алерт краснеет» - (зеркало урока 4), см. `LEARNING_PLAN.md` §3.1. -- Нужна ли BI-витрина (Superset) уже в первой версии или переносим на следующую. -- Переиспользование: после первого прогона — ретроспектива и обобщение материала - под других менти. +Закрыто при написании уроков (2026-06-06): + +- ~~Глубина урока 5 (мониторинг): сколько устройства показывать против «просто + наблюдай дашборд».~~ **Решено:** взяли мини-правку «погаси сервис → алерт краснеет» + (зеркало урока 4) — урок 5 даёт «сломал-увидел», а не чистое наблюдение. См. + `LEARNING_PLAN.md` §3.1. +- ~~Нужна ли BI-витрина (Superset) уже в первой версии.~~ **Решено:** урок 6 написан и + синхронизирован с реальным дашбордом; остаётся опциональным (обязательные уроки не + блокирует). + +Остаётся на будущее: + +- Переиспользование: после **первого реального прогона менти** — ретроспектива и + обобщение материала под других менти. Это валидация уже собранного курса, а не + часть его подготовки. diff --git a/docs/course/lessons/04_airflow_orchestration.md b/docs/course/lessons/04_airflow_orchestration.md index c328202..2b3ec5c 100644 --- a/docs/course/lessons/04_airflow_orchestration.md +++ b/docs/course/lessons/04_airflow_orchestration.md @@ -351,7 +351,7 @@ make clean && make up && make ddl && LIMIT=50 make data ## Вся цепочка разом: STG → ODS → DDS → DM -Теперь у нас есть не только отдельные слои, но и порядок их жизни: +Теперь у нас есть и сами слои, и порядок их жизни: - **STG** принимает поток и хранит сырой JSON; - **ODS** типизирует и разделяет чистое/битое;