Files
clickstream-ch-kafka-supers…/CONTEXT.md
T
ddadminandClaude Opus 4.8 fa93aef150 docs(context): глоссарий и спеки приведены в соответствие с ADR-0006
- Зачем:
  - ADR-0006 сделал генерацию единственным источником аналитики, а статический
    сид — архивным; глоссарий и спеки это ещё не отражали.
- Что:
  - CONTEXT.md: «статический сид» переименован в «архивный статический сид»
    (короткое имя сохранено), описан как временная кладовка значений с целью
    полного вывода; «стартовая история» получила синонимы «стартовый сид» и
    «новый сид»; раздел «Слои данных» отмечает переход аналитики на генерацию.
  - мат-спека: разделы «Персистентность через рестарты» и «Воспроизводимость»
    помечены как переописанные в спеке модельного времени (ссылкой, без повтора).
  - спека модельного времени: синоним «стартовый сид» добавлен в определение и
    в заметку о влиянии на документацию.
- Проверка:
  - git diff: термины и перекрёстные ссылки читаются непротиворечиво; ADR не
    правились (статус «архивный» не переносится в документы до ADR-0006).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 15:31:11 +03:00

147 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CONTEXT.md — глоссарий домена
Доменный язык стенда: как мы называем сущности кликстрима и что под ними
понимаем. Один термин — одно имя. Ведётся вместе с `docs/adr/` (см.
[ADR-0001](./docs/adr/0001-spec-adr-issue-layout.md)).
## Сущности
### Пользователь (user)
`user_domain_id` (`UUID`) — постоянный идентификатор пользователя (cookie-уровень),
переживает отдельные визиты. Источник — `device_events`, привязан к `click_id`.
В витринах: `uniqExact(user_domain_id)`.
### Визит / сессия (visit / session)
`click_id` (`UUID`) — **визит**: envelope из одного и более событий с общим
контекстом device/geo. В DDL `dds.click` описана как «контекст сессии
пользователя» (см. [`sql/ddl/dds/30_dds.sql`](./sql/ddl/dds/30_dds.sql)).
Важно: в источнике **нет отдельного session-таймаута** (как Snowplow
`domain_sessionid`). Поэтому в этой модели **сессия ≡ визит ≡ `click_id`**
группа событий под одним идентификатором, а не окно активности по тайм-ауту.
Если в будущем понадобится «настоящая» сессия по 30-минутному окну неактивности —
это отдельная производная над `user_domain_id` + `event_ts`, и на сиде она дала
бы **другие** группы: в полном сиде 11 внутрисессионных пауз превышают 30 минут,
а разброс времени внутри `click_id` доходит до 49 минут (см. профиль
сид-датасета ниже; ранее здесь ошибочно значилось «разброс ≤ 1 мин» — это был
замер по малому срезу файла).
«Сессию» и «визит» используем как синонимы; в UI предпочитаем «визит», когда важно
подчеркнуть, что это не сессия-по-тайм-ауту.
### Событие (event)
`event_id` (`UUID`) — отдельное действие пользователя в рамках визита: `pageview`,
`click`, `purchase`, `add_to_cart` и т.п. (поле `event_type`). Источник —
`browser_events` + `location_events`. В витринах: `count()`.
## Иерархия
```
user_domain_id (пользователь, постоянный)
└── click_id (визит/сессия — 1..N событий с общим device/geo)
└── event_id (событие: pageview / click / purchase ...)
```
Здоровые данные дают пирамиду `users ≤ sessions ≤ events`.
## Термины потоковой генерации (steady-stream)
Относятся к синтетическому потоку из генератора (режим `steady-stream`), не к
статическому сиду. Решение и контекст — [ADR-0004](./docs/adr/0004-steady-stream-synthetic-generator.md),
форма доработки — [спека генератора](./docs/specs/2026-06-09-generator-rework-hierarchical.md).
### Популяция пользователей (user population)
Множество пользователей с **постоянными** `user_domain_id`, которые генератор
держит во времени и из которых разыгрывает активность. В отличие от сида (где
пул `user_domain_id` плоский и 1:1 с визитами), популяция — это источник
возвратов: один и тот же пользователь порождает несколько визитов.
### Возвращающийся пользователь (returning user)
Пользователь, открывающий **более одного** визита (`click_id`) во времени, с
межсессионными паузами. Именно возвраты дают расхождение `users < sessions`
то, чего нет на сиде (`users == sessions`) и что отличает поток от статики.
### Три значения слова «сид»
Слово перегружено — в разговоре про генератор это **три разные сущности**, их
нельзя путать (см. [ADR-0005](./docs/adr/0005-generator-model-clock.md)):
- **`GEN_SEED`** — зерно ГПСЧ генератора (детерминизм случайных решений). Не
данные, а число.
- **архивный статический сид** (короткое имя — «статический сид», файлы
`data/*.jsonl`) — учебный демо-датасет режима `bootstrap` (уроки 06). По
[ADR-0006](./docs/adr/0006-generation-as-sole-analytics-source.md)
он **выведен из аналитики и стал архивным**: витрины и дашборды переводятся на
генерацию. У сида осталась одна временная роль — **кладовка готовых значений**
(браузеры, страны, устройства, метки кампаний), откуда генератор берёт «фактуру»
для событий. Цель — **совсем убрать файл**, когда генератор научится придумывать
фактуру сам (отдельная спека). Профиль ниже — теперь опорные цифры и список
известных расхождений, а не эталон для подгонки (подгонять генерацию под сид
число-в-число в ADR-0006 отклонено).
- **стартовая история стенда** (синонимы — **«стартовый сид»** и **«новый сид»**;
это не новые значения слова, а та же сущность) — сгенерированное прошлое (заливка `K → ∞` +
заморозка состояния), с которого живой стенд стартует непрерывно. По ADR-0006
она **несущая**: именно с неё свежий стенд получает историю с первой минуты.
Механизм проектируется — спека
[модельного времени](./docs/specs/2026-06-14-generator-model-time-and-startup-history.md);
решение про часы — [ADR-0005](./docs/adr/0005-generator-model-clock.md).
### Модельное время и масштаб (×K)
**Модельное время стенда** отвязано от настенных часов: генератор крутит
внутренние часы, а драйвер задаёт скорость — ×1 (как реальное время), ×K
(ускоренно, учебная «ручка» урока 7) или `K → ∞` (мгновенная заливка прошлого).
При ускорении «сейчас» стенда уходит вперёд настенного времени — это свойство, не
баг (ключ аналитики — `event_timestamp`). Решение и режимы —
[ADR-0005](./docs/adr/0005-generator-model-clock.md).
## Почему на демо `Unique Users == Unique Sessions`
В демо-датасете (`data/*.jsonl`) каждый пользователь имеет **ровно один**
`click_id` — связь user↔визит строго 1:1 (проверено: 99 пользователей =
99 `click_id` в полном файле). Поэтому `uniqExact(user_domain_id)` и
`uniqExact(click_id)` дают одинаковое число.
Это **свойство конкретного датасета, а не закон модели и не баг расчёта.** В
реальных данных пользователь возвращается несколькими визитами, и числа
расходятся. Поэтому на дашборде мы **не** показываем две одинаковые KPI-плитки
(это читалось бы как ошибка) — вместо дубля идут производные метрики
(события на визит, доля визитов с одним событием), а различие «пользователь vs
сессия» объясняется текстом урока.
Синтетический генератор (ветка `feature/data-generator`) проблему не решает, а
усугубляет: он штампует свежий `click_id` на каждое событие, и `click_id`
вырождается в «событие». См. `generator/KNOWN_ISSUES.md` на той ветке.
## Профиль сид-датасета (измерено 2026-06-10, полные файлы)
Опорные цифры о статическом сиде (`data/*.jsonl`) — для калибровки генератора
и проверки гипотез. Измерено по **полным** файлам (1000 событий); внимание:
ранние оценки «1..7 событий на визит» делались по малому срезу и неверны.
- **Объём:** 1000 событий, 99 визитов (`click_id`), 99 пользователей (1:1).
- **Длина визита:** 1..27 событий, медиана 10, среднее 10.1.
- **Паузы между событиями визита:** медиана ~20 с, p95 ≈ 17 мин,
максимум ≈ 40 мин; пауз длиннее 30 минут — 11 штук. Разброс времени внутри
одного `click_id` — до 49 минут.
- **Воронка:** 25% визитов достигают `/confirmation`. Пути — с петлями:
возвраты на `/home`, просмотр обоих товаров; у 21 из 25 «купивших» визитов
есть события **после** `/confirmation`, у 9 — `/confirmation` встречается
дважды. То есть `/confirmation` — последний *шаг воронки*, но не обязательно
последнее *событие визита*.
- **Страницы (по событиям):** `/home` 426, `/product_a` 236, `/product_b` 157,
`/cart` 93, `/payment` 53, `/confirmation` 35. `event_type` — 100% `pageview`.
## Слои данных
`STG → ODS → DDS → DM` — см. [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md).
Сейчас витрины (`dm.*`) и дашборд Superset строятся на статическом сиде. По
[ADR-0006](./docs/adr/0006-generation-as-sole-analytics-source.md) целевой источник
аналитики — генерация (стартовая история и живой поток); перевод загрузки, витрин
и дашбордов на неё входит в текущую работу, детальный план — отдельной спекой.