Команда snapshot: окно, граница суток, байты и опись #92

Closed
opened 2026-08-17 22:54:55 +03:00 by ddmitry · 0 comments
Owner

Part of #5.

Цель

Третья команда пакета: snapshot собирает слепок дня переигровкой окна,
снимает состояние заказов на границе суток, сериализует одной функцией и
отправляет со сдвигом «ночная выгрузка за вчера». Побайтовая
воспроизводимость слепка встаёт под охрану описи. Учебный результат: слепок —
чистая функция (зерно, D), у живого дня нет особого случая.

Что войдёт

  • Команда snapshot --day D [--days N] со своим Kafka-приёмником (топик
    orders; сам топик заводит #93) и файловым приёмником для проверок.
    Семантика --dayдень прогона: прогон дня D отправляет слепок дня
    D−1, прогон дня 0 не отправляет ничего; закрепить в --help и доке.
    Правило сдвига живёт в одном месте — в проигрывателе.
  • Окно: слепок дня D несёт заказы, рождённые в дни D−6…D, и собирается
    переигровкой этих дней; у начала оси окно усекается само. Внутри одного
    прогона --days N проигрыши дней переиспользуются между слепками
    (стартовый диапазон — 8 проигрышей, не 49); байты слепков не зависят от
    разбиения диапазона на прогоны. Кэша между прогонами нет. Замер цены — в
    тело PR.
  • Состояние на границе суток D|D+1 — чтение готовой судьбы: учитываются
    моменты, не позже границы; status — по учтённым моментам, updated_at
    поздний учтённый момент, а без единого — created_at. Если это правило
    разойдётся с принятыми документами — вопрос владельцу, не починка на
    месте.
  • Сериализация: явная функция в serialize.py — один словарь с вложенным
    списком и один orjson.dumps; прямых json.dumps по коду нет. Контракт
    провода — мастер-спека, раздел 2: деньги строками с ровно двумя знаками,
    времена RFC 3339 в UTC с миллисекундами, snapshot_date строкой
    YYYY-MM-DD, items обычным массивом, порядок ключей — порядок полей
    контракта.
  • Порядок строк внутри слепка — порядок рождения заказов, он же возрастание
    order_id.
  • Печать числа отправленных заказов — как у batch: по ней тикеты приёма
    сверяют счёт.
  • Опись мира получает строку на каждый отправленный слепок с хешем байтов.

Границы

  • Топик, DDL и приём — #93/#94; проверки здесь идут файловым приёмником.
  • Описание выгрузки слепка из кода (docs/formats/) не заводится: контракт
    уже записан мастер-спекой и исследованием формата, второй сторож без
    читателя не нужен (рез вычитания при нарезке).
  • Счётчики заказов, выручки и классов в опись — не этап 3: их заводит этап,
    приносящий читателя (сверка — этап 4, B+D — этап 6). Счёта строк слепка в
    описи нет — опись описывает мир, а не доставку.
  • Работа генератора кончается на Kafka; доезд байтов — вопрос стенда.

Кому что

serialize.py, правило сдвига и CLI — Opus: сериализатор — учебный код с одним местом правды. Кодексу — прогоны пересъёмки и хешей, разбор объёмного вывода при отладке. В брифе: проверять свойство, не текст вывода; POSIX-инструменты.

Сначала прочитать

  • docs/architecture/orders/snapshot.md — целиком, это спека тикета;
  • docs/architecture/orders/fate.md — моменты судьбы;
  • docs/architecture/orders/inventory.md — что хранит опись;
  • docs/research/2026-08-16-order-snapshot-wire-format.md — контракт и
    проверка разбора;
  • docs/architecture/orders/code-rules.md;
  • docs/specs/2026-08-01-generator.md — приёмники, режимы, опись.

Проверка

В generator/: make lint, make typecheck, make test.

  • Пересъёмка слепка даёт те же байты; хеш сходится со строкой описи;
    make test следит за свежестью описи, как уже делает для дней.
  • Слепок дня 6 несёт заказы дней 0…6, слепок дня 3 — дней 0…3
    (усечение у начала оси).
  • «Дыхание»: заказ, оплаченный в день D+1, в слепке дня D — created,
    в слепке дня D+1 — paid.
  • В файловом приёмнике строки идут в порядке order_id, каждая
    проходит разбор по контракту (приём разбора — из исследования
    формата).
  • Прогон дня 0 не отправляет ничего; прогон дня D отправляет слепок
    дня D−1.
Part of #5. ## Цель Третья команда пакета: `snapshot` собирает слепок дня переигровкой окна, снимает состояние заказов на границе суток, сериализует одной функцией и отправляет со сдвигом «ночная выгрузка за вчера». Побайтовая воспроизводимость слепка встаёт под охрану описи. Учебный результат: слепок — чистая функция (зерно, D), у живого дня нет особого случая. ## Что войдёт - Команда `snapshot --day D [--days N]` со своим Kafka-приёмником (топик `orders`; сам топик заводит #93) и файловым приёмником для проверок. Семантика `--day` — **день прогона**: прогон дня D отправляет слепок дня D−1, прогон дня 0 не отправляет ничего; закрепить в `--help` и доке. Правило сдвига живёт в одном месте — в проигрывателе. - Окно: слепок дня D несёт заказы, рождённые в дни D−6…D, и собирается переигровкой этих дней; у начала оси окно усекается само. Внутри одного прогона `--days N` проигрыши дней переиспользуются между слепками (стартовый диапазон — 8 проигрышей, не 49); байты слепков не зависят от разбиения диапазона на прогоны. Кэша между прогонами нет. Замер цены — в тело PR. - Состояние на границе суток D|D+1 — чтение готовой судьбы: учитываются моменты, не позже границы; `status` — по учтённым моментам, `updated_at` — поздний учтённый момент, а без единого — `created_at`. Если это правило разойдётся с принятыми документами — вопрос владельцу, не починка на месте. - Сериализация: явная функция в `serialize.py` — один словарь с вложенным списком и один `orjson.dumps`; прямых `json.dumps` по коду нет. Контракт провода — мастер-спека, раздел 2: деньги строками с ровно двумя знаками, времена RFC 3339 в UTC с миллисекундами, `snapshot_date` строкой `YYYY-MM-DD`, `items` обычным массивом, порядок ключей — порядок полей контракта. - Порядок строк внутри слепка — порядок рождения заказов, он же возрастание `order_id`. - Печать числа отправленных заказов — как у `batch`: по ней тикеты приёма сверяют счёт. - Опись мира получает строку на каждый отправленный слепок с хешем байтов. ## Границы - Топик, DDL и приём — #93/#94; проверки здесь идут файловым приёмником. - Описание выгрузки слепка из кода (`docs/formats/`) не заводится: контракт уже записан мастер-спекой и исследованием формата, второй сторож без читателя не нужен (рез вычитания при нарезке). - Счётчики заказов, выручки и классов в опись — не этап 3: их заводит этап, приносящий читателя (сверка — этап 4, B+D — этап 6). Счёта строк слепка в описи нет — опись описывает мир, а не доставку. - Работа генератора кончается на Kafka; доезд байтов — вопрос стенда. ## Кому что `serialize.py`, правило сдвига и CLI — Opus: сериализатор — учебный код с одним местом правды. Кодексу — прогоны пересъёмки и хешей, разбор объёмного вывода при отладке. В брифе: проверять свойство, не текст вывода; POSIX-инструменты. ## Сначала прочитать - `docs/architecture/orders/snapshot.md` — целиком, это спека тикета; - `docs/architecture/orders/fate.md` — моменты судьбы; - `docs/architecture/orders/inventory.md` — что хранит опись; - `docs/research/2026-08-16-order-snapshot-wire-format.md` — контракт и проверка разбора; - `docs/architecture/orders/code-rules.md`; - `docs/specs/2026-08-01-generator.md` — приёмники, режимы, опись. ## Проверка В `generator/`: `make lint`, `make typecheck`, `make test`. - [ ] Пересъёмка слепка даёт те же байты; хеш сходится со строкой описи; `make test` следит за свежестью описи, как уже делает для дней. - [ ] Слепок дня 6 несёт заказы дней 0…6, слепок дня 3 — дней 0…3 (усечение у начала оси). - [ ] «Дыхание»: заказ, оплаченный в день D+1, в слепке дня D — `created`, в слепке дня D+1 — `paid`. - [ ] В файловом приёмнике строки идут в порядке `order_id`, каждая проходит разбор по контракту (приём разбора — из исследования формата). - [ ] Прогон дня 0 не отправляет ничего; прогон дня D отправляет слепок дня D−1.
ddmitry added the ready-for-agent label 2026-08-17 22:56:06 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: ddmitry/clickstream-data-platform#92