feat(superset): обновлен состав KPI и воронки дашборда

- Зачем:
  - нужно убрать дублирующий KPI Unique Sessions и сделать эталонный dashboard честнее для учебного анализа.
- Что:
  - обновлены KPI, добавлена Conversion to /confirmation и Page Funnel.
  - добавлена идемпотентная миграция старых chart names без дублей.
  - синхронизированы документация, урок 6 и спека редизайна.
  - добавлен handoff для продолжения работы в новой сессии.
- Проверка:
  - python3 -m py_compile superset/create_dashboard.py.
  - make superset-dashboard.
  - Superset metadata: dashboard_charts=10, obsolete_unique_sessions=0, page_funnel_type=funnel.
This commit is contained in:
2026-06-06 17:00:02 +03:00
parent 0fd8a08667
commit 1bec6bb8ad
5 changed files with 237 additions and 68 deletions
+15 -3
View File
@@ -59,10 +59,12 @@ make superset-dashboard
#### KPI-блок (верх дашборда)
- **📊 Total Events** — общее количество событий
- **👤 Unique Users** — уникальные пользователи
- **🎯 Unique Sessions** — уникальные сессии (click_id)
- **📈 Avg Events/Session** — среднее количество событий на сессию
- **📈 Avg Events/Visit** — среднее количество событий на визит (`click_id`)
- **🎯 Conversion to /confirmation** — доля просмотров `/confirmation` от просмотров `/home`
KPI разложены в одну строку по 12-колоночной сетке Superset: четыре блока по 3 колонки.
`Unique Sessions` не вынесен отдельной KPI-плиткой, потому что в демо-данных
`user_domain_id` и `click_id` идут 1:1 и дают то же число, что `Unique Users`.
#### Динамика трафика
- **📅 Events by Hour** — линейный график событий по часам
@@ -73,7 +75,13 @@ KPI разложены в одну строку по 12-колоночной с
#### Маркетинг
- **🔗 UTM Effectiveness Table** — таблица эффективности UTM-меток
- **📄 Top Pages** — bar chart топ-20 страниц
- **🪜 Page Funnel** — funnel chart по просмотрам страниц, от `/home` к `/confirmation`
> **Что проверили по Superset 4.1.2.** Через MCP Context7 проверили официальную
> библиотеку `/apache/superset`; документация не дала точной строки `viz_type`.
> В установленном Superset 4.1.2 дополнительно проверили bundled example
> `Featured Charts/Funnel.yaml` и frontend assets: для воронки используется
> `viz_type: funnel`, поэтому dashboard создаёт именно funnel chart.
#### Качество данных
- **🔍 Data Quality Summary** — статистика по слоям STG/ODS/DDS
@@ -219,7 +227,11 @@ make superset-restart
# Полная переинициализация
docker compose down -v
docker compose up -d
make ddl
make data
make transform
make superset-init
make superset-dashboard
```
### Нет данных в чартах
+47 -27
View File
@@ -63,17 +63,19 @@ DM-витрина — это SQL-объект в ClickHouse. Она задаёт
## 2. Руки: запускаем Superset и смотрим дашборд
Подними стенд и прогони маленький срез:
Подними стенд и прогони полный демо-датасет:
```bash
make up
make ddl
LIMIT=50 make data
make data
make transform
```
`make transform` прогоняет цепочку STG → ODS → DDS → DM вне Airflow. Для этого урока так
быстрее: нам нужен готовый DM-слой, а не разбор DAG.
быстрее: нам нужен готовый DM-слой, а не разбор DAG. Отладочный срез через
`LIMIT=50 make data` можно использовать для быстрых экспериментов, но эталонный dashboard
и числа урока рассчитаны на полном наборе данных.
Теперь инициализируй Superset:
@@ -84,7 +86,16 @@ make superset-init
Эта команда создаёт или обновляет:
- подключение `clickhouse_dwh`;
- 6 datasets поверх `dm.*`;
- 6 datasets поверх `dm.*`.
После этого создай или обнови charts и сам dashboard:
```bash
make superset-dashboard
```
Эта команда создаёт или обновляет:
- 10 charts;
- dashboard `E-commerce Analytics Dashboard`.
@@ -105,12 +116,17 @@ http://localhost:8088/superset/dashboard/1/
На экране должны быть блоки:
- KPI сверху: `Total Events`, `Unique Users`, `Unique Sessions`, `Avg Events/Session`;
- KPI сверху: `Total Events`, `Unique Users`, `Avg Events/Visit`,
`Conversion to /confirmation`;
- динамика: `Events by Hour`, `Traffic by Device`;
- география: `Geography Map`;
- маркетинг: `UTM Effectiveness Table`, `Top Pages`;
- маркетинг: `UTM Effectiveness Table`, `Page Funnel`;
- качество данных: `Data Quality Summary`.
`Conversion to /confirmation` считается как просмотры `/confirmation` / просмотры `/home`.
Это page-funnel метрика, а не доля визитов: она совпадает с тем, как ниже устроен chart
`Page Funnel`.
### Фильтр даты
В демо-данных события датированы `2022-11-28`. В текущей конфигурации dashboard фильтр даты
@@ -136,7 +152,7 @@ SELECT count() AS events
FROM dm.v_events_enriched;
```
И посмотри, откуда берётся график `Top Pages`:
И посмотри, откуда берётся график `Page Funnel`:
```sql
SELECT page_url_path, sum(pageviews) AS pageviews
@@ -233,18 +249,20 @@ Metadata Superset живёт в PostgreSQL, а сами данные остаю
```python
{
"slice_name": "📄 Top Pages",
"viz_type": "dist_bar",
"slice_name": "🪜 Page Funnel",
"viz_type": "funnel",
"dataset_name": "v_top_pages_daily",
"params": {
"groupby": ["page_url_path"],
"metrics": [
{"expressionType": "SQL", "sqlExpression": "SUM(pageviews)", "label": "Pageviews"}
],
"metric": {
"expressionType": "SQL",
"sqlExpression": "SUM(pageviews)",
"label": "Pageviews"
},
"row_limit": 20,
"time_range": "No filter",
"orientation": "vertical",
"show_legend": False
"sort_by_metric": True,
"percent_calculation_type": "first_step"
}
}
```
@@ -280,14 +298,16 @@ Native filters создаются в `build_dashboard_metadata`. Там есть
> **Что проверили по API.** Перед уроком Superset сверили через MCP Context7 (`/apache/superset`):
> в Superset есть отдельные сущности charts и dashboards, metadata хранится отдельно от
> подключаемых источников данных, а row limit — часть настройки запросов и конфигурации.
> Поэтому в уроке не лезем в REST API Superset, а работаем через уже существующий скрипт стенда.
> подключаемых источников данных. Для `funnel` Context7 не дал точную строку `viz_type`, поэтому
> дополнительно проверили установленный Superset 4.1.2: bundled example
> `Featured Charts/Funnel.yaml` использует `viz_type: funnel`. Поэтому в уроке не лезем в REST API
> Superset, а работаем через уже существующий скрипт стенда.
---
## 4. Управляемая правка: уменьшаем Top Pages
## 4. Управляемая правка: уменьшаем Page Funnel
Сейчас chart `Top Pages` показывает до 20 страниц:
Сейчас chart `Page Funnel` показывает до 20 страниц:
```python
"row_limit": 20,
@@ -296,7 +316,7 @@ Native filters создаются в `build_dashboard_metadata`. Там есть
Сделай маленькую видимую правку: временно покажи только топ-3 страницы.
Открой [`superset/create_dashboard.py`](../../../superset/create_dashboard.py), найди chart
`Top Pages` и поменяй:
`Page Funnel` и поменяй:
```python
"row_limit": 20,
@@ -314,7 +334,7 @@ Native filters создаются в `build_dashboard_metadata`. Там есть
make superset-dashboard
```
Вернись в Superset и обнови страницу dashboard. В chart `Top Pages` должно остаться не больше
Вернись в Superset и обнови страницу dashboard. В chart `Page Funnel` должно остаться не больше
трёх страниц. Если фильтр даты снова скрыл данные, поставь **Date Range → No filter** и нажми
**Apply filters**.
@@ -339,17 +359,17 @@ make superset-dashboard
make superset-dashboard
```
После обновления страницы chart `Top Pages` снова может показывать до 20 страниц.
После обновления страницы chart `Page Funnel` снова может показывать до 20 страниц.
Если после экспериментов Superset выглядит странно, самый простой учебный возврат dashboard
metadata к конфигурации из репозитория:
```bash
make superset-init
make superset-dashboard
```
Данные в ClickHouse эта команда не удаляет. Она повторно применяет подключение, datasets и
dashboard metadata Superset.
Данные в ClickHouse эта команда не удаляет. Она повторно применяет charts и dashboard
metadata Superset.
---
@@ -362,8 +382,8 @@ dashboard metadata Superset.
| открыть **Datasets** | Superset UI | есть datasets `v_events_enriched`, `v_top_pages_daily`, `dq_summary` |
| открыть dashboard | Superset UI | видны KPI, маркетинг, география и качество данных |
| поставить **Date Range → No filter** | dashboard filters | графики не скрываются из-за даты `2022-11-28` |
| поменять `row_limit` у `Top Pages` на `3` и запустить `make superset-dashboard` | chart `Top Pages` | не больше трёх страниц |
| вернуть `row_limit` на `20` и запустить `make superset-dashboard` | chart `Top Pages` | ограничение снова до 20 страниц |
| поменять `row_limit` у `Page Funnel` на `3` и запустить `make superset-dashboard` | chart `Page Funnel` | не больше трёх страниц |
| вернуть `row_limit` на `20` и запустить `make superset-dashboard` | chart `Page Funnel` | ограничение снова до 20 страниц |
Вопросы для созвона:
@@ -378,7 +398,7 @@ dashboard metadata Superset.
## 6. Что должно получиться
К концу урока у тебя должен быть открытый dashboard `E-commerce Analytics Dashboard` в Superset.
Сделай скриншот после временной правки `Top Pages`: на нём должно быть видно, что chart показывает
Сделай скриншот после временной правки `Page Funnel`: на нём должно быть видно, что chart показывает
не больше трёх страниц.
Второй артефакт — короткий абзац своими словами:
@@ -1,8 +1,8 @@
# Редизайн KPI-полосы и состава чартов дашборда «E-commerce Analytics»
Дата: 2026-06-06
Статус: Accepted (не реализовано — код `superset/create_dashboard.py` правится
отдельным заходом на реализацию)
Статус: Implemented (`superset/create_dashboard.py`, `docs/SUPERSET_DASHBOARD.md`,
`docs/course/lessons/06_superset_bi.md`)
Связано: [`CONTEXT.md`](../../CONTEXT.md), [ADR-0002](../adr/0002-specs-as-durable-design-docs.md),
урок [`docs/course/lessons/06_superset_bi.md`](../course/lessons/06_superset_bi.md)
@@ -141,11 +141,16 @@ KPI-полоса:
## Open questions
- **Точная формула Conversion:** доля визитов с ≥1 pageview `/confirmation`, или
просмотры `/confirmation` / просмотры `/home`? Влияет на число (~8%) и на то,
что именно учим (визит-конверсия vs page-to-page).
- **Events by Hour** — оставляем ли (зависит от проверки на пустоту на полных
данных: разброс `event_ts` по часам).
- **Resolved: точная формула Conversion.** Используем page-funnel conversion:
`countIf(page_url_path = '/confirmation') / countIf(page_url_path = '/home')`.
На полном датасете это `35 / 426 = 8.2%`. Визитовая формула даёт 25.3% и
отклонена, потому что KPI должен совпадать с логикой chart `Page Funnel`.
- **Resolved: Events by Hour.** Оставляем: на полном датасете есть два часовых
бакета (`20 → 256`, `21 → 744`), график не пустой.
- **Resolved: Funnel в Superset 4.1.2.** MCP Context7 по `/apache/superset` не
дал точной строки `viz_type`; установленный Superset 4.1.2 проверен по bundled
example `Featured Charts/Funnel.yaml` и frontend assets. Используем
`viz_type: funnel`.
- **Требования к будущему генератору**, вытекающие из упёртостей этих данных
(разнообразие `event_type`, возвраты пользователей → sessions>users,
реалистичная воронка) — при возврате к генератору перенести в его