# 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` (уроки 0–6) и **калибровочный эталон** генератора (профиль ниже — опорные цифры). По мере появления «стартовой истории стенда» его учебная роль смещается на **dev-фикстуру и эталон** (быстрый повторяемый вход для пайплайна STG→DM, не зависящий от генератора); смещение зафиксировано как будущее направление в ADR-0005, на время разработки сид и поток сосуществуют. - **стартовая история стенда** — сгенерированное прошлое (заливка `K → ∞` + заморозка состояния), с которого живой стенд стартует непрерывно. Ещё не строим; см. ADR-0005. ### Модельное время и масштаб (×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 строятся на статическом сиде, не на потоке.