Files
clickstream-data-platform/docs/architecture/orders/snapshot.md
T
ddadminandClaude Fable 5 0d9a83d6af docs(orders): устройство заказов переехало в живой набор architecture/orders
Зачем: собранная спека заказов стала базовой документацией сервиса, а
жанр спеки-события ей мал: дата в имени врёт, целиком в контекст агента
она не влезает, а трекер с резолюциями долговечным хранилищем не
считается. Решение владельца — держать детальное устройство компонента
связным набором живых документов (ADR 0011) и совместить переезд с
проходом на вычитание (#84).

Что: docs/architecture/orders/ — индекс README и файлы по частям
устройства: проекция, слепок и доставка, судьба, классы расхождений,
опись, мост к склейке, стартовый мир, правила кода; спека приёма
переехала в ingestion.md без содержательных правок. Резы вычитания по
итогам двух слепых линий: тела разделов о проводе и приёме сведены к
указателям на мастер-спеку, исследование формата и ADR (порядок строк
слепка — единственное правило, оставшееся на месте); замеры канонического
зерна и повторы-пояснения срезаны; списки отклонённых вариантов сохранены
как долговечная запись. Датированные файлы удалены, ссылки из мастер-спеки,
спеки генератора, ADR 0008/0010, исследования формата и storage.md
перенацелены; раздел «Структура» AGENTS.md дополнен правилом подпапки.

Проверка: grep по репозиторию не находит ссылок на удалённые файлы;
все относительные ссылки внутри набора разрешаются в существующие файлы;
впереди холодная сверка «ни одно решение не потеряно» и приёмка #88.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 23:50:13 +03:00

5.8 KiB

Слепок и его доставка

Резолюция развилки «Генератор слепков: где живёт и чем связан с событиями».

Запуск. Третья команда того же пакета — snapshot --day D [--days N], свой приёмник, топик orders. Два источника — два запуска: трекер и бэкенд видны глазами как два производителя, каждый со своим топиком. Один прогон с двумя выходами отклонён: экономии он не даёт (со сдвигом отправки окно слепка и сыгранный день не пересекаются вовсе), а правило «приёмник выбирается тем, что для него назвали» ломает. Отклонены также: отдельный пакет и образ — библиотека на двоих ради одной команды; генератор пишет слепок файлом, в топик льёт даг — второй путь доставки и второй сериализатор; слепок едет топиком hits — убивает два режима приёма.

Сборка окна. Слепок дня D несёт заказы, рождённые в дни D−6…D, и собирается переигровкой этих семи дней: заказы дня — производная всей воронки дня, дешёвого пути к ним нет. Цена — семь проигрышей дня (~14 с) на слепок; у начала оси окно усекается само. Отклонено: кэш заказов на томе — состояние между прогонами; окно держит хранилище — топик перестаёт нести слепок; K = 1 — это страховочный срез 1 мастер-спеки, он в резерве.

Отправка. Слепок снимается на границе суток, а отправляется следующим прогоном: даг, играющий день D, отправляет слепок дня D−1 — ночная выгрузка бэкенда за вчера, как в бою. Содержимое слепка — чистая функция (зерно, D), от момента отправки не зависит. Следствия:

  • живой день перестаёт быть особым случаем: своего дага у него нет, слепок живого дня отправит следующий прогон;
  • пропущенный день лечится окном: слепок переснимается и даёт те же байты, отдельного механизма самовосстановления нет;
  • покупки текущего дня в сверке всегда awaiting_order — сюжет «вчера не сходилось, сегодня сошлось», ради которого мастер-спека этот класс завела;
  • цена — один лишний проигрыш дня на прогон (окно и сыгранный день не пересекаются, проигрышей всегда восемь).

На старте оси дня −1 нет, поэтому прогон дня 0 не отправляет ничего; первый слепок — дня 0 — уезжает прогоном дня 1 (исследование формата).

Случайность. Судьбу заказов бросает свой подпоток, ветвящийся по дню рождения заказа: слепок несёт семь дней рождения сразу, и судьбу каждого заказа обязан читать из его собственного дня. Вся судьба решается при рождении, поэтому слепок любого дня — чтение готовой судьбы, а не накопление состояния. Отклонено: дописывать броски в конец COMMERCE — правка заказа и правка торгового поведения стали бы одним рычагом; бросать состояние в подпотоке дня слепка — траектория заказа зависела бы от того, какие слепки снимали.

Запись на проводе

Контракт провода — на заказ один JSON-документ: деньги строками с двумя знаками, времена RFC 3339 в UTC с миллисекундами, items обычным массивом — целиком описан мастер-спекой (раздел 2); основания, отклонённые варианты и проверка разбора — в исследовании формата (резолюция развилки «Форма записи слепка на проводе»).

Сверх контракта здесь живёт одно правило: порядок строк внутри слепка — порядок рождения заказов, он же возрастание order_id. Детерминизм даёт его даром, а хешу слепка в описи нужен именно названный порядок.