Зачем: помочь начинающему инженеру проследить событие и версию заказа от генератора до хранилища, включая ошибки и повторные поступления. Что: обновлены вводная генератора, справочники приема и модели заказа, разделы хранилища и комментарии SQL и дага. Сохранены технические условия; исполняемый код, схемы и поведение стенда не изменены. Проверка: make lint, git diff --check, 142 локальные ссылки и справка CLI. SQL без комментариев и Python AST без строк документации совпали с исходными. Генерация данных и сброс состояния не выполнялись. Refs #250
96 lines
7.6 KiB
Markdown
96 lines
7.6 KiB
Markdown
# Генератор событий и заказов
|
||
|
||
Генератор создает данные двух источников интернет-магазина. Счетчик сайта
|
||
отправляет в топик Kafka `hits` события: просмотр страницы, добавление товара
|
||
в корзину и покупку. Серверная часть магазина выгружает в `orders` дневной
|
||
слепок — состояние заказов, оформленных за последние семь модельных дней.
|
||
Оба источника работают; хранилище принимает события непрерывно, заказы —
|
||
по команде Airflow.
|
||
|
||
Событие описывает отдельное действие посетителя. Заказ после оформления
|
||
может измениться, например перейти в статус `paid` или `cancelled`.
|
||
Поэтому один `order_id` встречается в нескольких слепках. Часть заказов
|
||
впервые появляется с задержкой в один или два дня; конец семидневного окна
|
||
от этого не сдвигается. Правила изменений и задержек — в
|
||
[описании судьбы заказа](../docs/architecture/orders/fate.md).
|
||
|
||
Слепок снимается на конец модельного дня и отправляется на следующий день.
|
||
Команда `snapshot --day 1` отправляет слепок дня 0, а `snapshot --day 0`
|
||
не отправляет ничего: до начала модели заказов нет. События и слепки
|
||
отправляются отдельными запусками генератора.
|
||
|
||
## Как это работает
|
||
|
||
Зерно генерации задает случайные выборы: какие посетители придут,
|
||
какие страницы откроют и что купят. При неизменных коде, каталоге
|
||
и настройках одинаковые зерно и номер дня дают одинаковые данные.
|
||
День можно рассчитать без генерации всех предыдущих дней.
|
||
|
||
Сначала рассчитываются посещения и покупки. Из покупки получаются событие
|
||
`purchase` со стороны сайта и заказ со стороны магазина. Номер связывает
|
||
их: `purchaseID` в событии соответствует `order_id` заказа. Суммы могут
|
||
различаться: магазин учитывает скидку, доставку и удаленные позиции.
|
||
Деньги генератор считает целыми копейками; в JSON заказа это строки
|
||
в рублях с двумя знаками после точки, например `"1289.99"`.
|
||
|
||
Готовые записи превращаются в JSON и отправляются в файл или Kafka:
|
||
одна запись занимает одну строку файла или одно сообщение. Событие содержит
|
||
47 полей по [описанию выгрузки](../docs/formats/clickstream-event.md),
|
||
запись заказа — поля [формата слепка](../docs/architecture/orders/snapshot.md#запись-на-проводе).
|
||
Подробное устройство генератора разобрано в
|
||
[техническом справочнике](../docs/architecture/generator/README.md).
|
||
|
||
## Что где лежит
|
||
|
||
Все перечисленные модули находятся в `src/clickstream_generator/`.
|
||
|
||
| Модули | Назначение |
|
||
|---|---|
|
||
| `world.py`, `seeds.py`, `plan.py` | Настройки мира, случайные выборы и план посещений |
|
||
| `reference.py`, `catalog.py` | Устройства, города, источники трафика и каталог товаров |
|
||
| `day.py`, `commerce.py` | Визиты, события сайта и покупки |
|
||
| `orders.py` | Состояние заказов на дату слепка, изменения и задержки |
|
||
| `serialize.py`, `player.py`, `sinks.py` | Запись JSON и отправка в файл или Kafka |
|
||
| `cli.py` | Команды и параметры запуска |
|
||
| `schema.py`, `schema_doc.py` | Описания колонок события и сборка документа выгрузки |
|
||
| `inventory.py` | Сборка паспорта мира с контрольными суммами и счетчиками |
|
||
|
||
Тесты в `tests/` проверяют формат, правила модели и повторяемость данных.
|
||
Описание выгрузки и [паспорт мира](../data/world-inventory.json) собираются
|
||
из кода; вручную их не редактируют.
|
||
|
||
## Команды
|
||
|
||
Для запуска из каталога `generator/` используйте
|
||
`uv run python -m clickstream_generator <команда>`. Справку можно открыть
|
||
через `--help`, в том числе после имени команды.
|
||
|
||
| Команда | Что отправляет | Особые параметры |
|
||
|---|---|---|
|
||
| `batch` | События дня без пауз | `--limit N` ограничивает число событий за весь запуск |
|
||
| `live` | События постепенно, с ускорением | `--speed X`, по умолчанию 60: сутки занимают около 24 минут |
|
||
| `snapshot` | Слепок заказов предыдущего дня | `--day D` задает день отправки |
|
||
|
||
Для всех команд нужны номер дня `--day` и приемник: `--file` либо
|
||
`--brokers` вместе с `--topic`. Общие параметры `--seed` и `--days`
|
||
задают зерно и число последовательных дней. Параметры можно передать
|
||
и через окружение; имена и примеры собраны в
|
||
[справочнике запуска](../docs/architecture/world.md#как-запустить-генератор).
|
||
Прямой запуск генератора не продвигает сохраненную позицию времени стенда —
|
||
ей управляют [даги модельного времени](../docs/handbook/airflow-dags.md#даги-мира).
|
||
|
||
Из каталога `generator/` доступны:
|
||
|
||
- `make test` — тесты генератора;
|
||
- `make lint` — проверка кода и форматирования через ruff;
|
||
- `make typecheck` — проверка типов через ty;
|
||
- `make demo` — показать стадии расчета первого дня, D0;
|
||
- `make docs` — пересобрать описание выгрузки;
|
||
- `make inventory` — пересобрать паспорт мира.
|
||
|
||
В корне `make lint` проверяет даги, код Superset и сборку карты архитектуры.
|
||
Корневые `make generate-batch` и `make generate-live` запускают события
|
||
через контейнер генератора. Состав проверок — в
|
||
[карте проверок](../docs/architecture/testing.md).
|
||
Python и зависимости запускаются через `uv`; версии закреплены в `uv.lock`.
|