- Зачем:
- ADR-0006 сделал генерацию единственным источником аналитики, а статический
сид — архивным; глоссарий и спеки это ещё не отражали.
- Что:
- CONTEXT.md: «статический сид» переименован в «архивный статический сид»
(короткое имя сохранено), описан как временная кладовка значений с целью
полного вывода; «стартовая история» получила синонимы «стартовый сид» и
«новый сид»; раздел «Слои данных» отмечает переход аналитики на генерацию.
- мат-спека: разделы «Персистентность через рестарты» и «Воспроизводимость»
помечены как переописанные в спеке модельного времени (ссылкой, без повтора).
- спека модельного времени: синоним «стартовый сид» добавлен в определение и
в заметку о влиянии на документацию.
- Проверка:
- git diff: термины и перекрёстные ссылки читаются непротиворечиво; ADR не
правились (статус «архивный» не переносится в документы до ADR-0006).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
147 lines
11 KiB
Markdown
147 lines
11 KiB
Markdown
# 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). По
|
||
[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) целевой источник
|
||
аналитики — генерация (стартовая история и живой поток); перевод загрузки, витрин
|
||
и дашбордов на неё входит в текущую работу, детальный план — отдельной спекой.
|