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>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# Слепок и его доставка
|
||||
|
||||
Резолюция развилки [«Генератор слепков: где живёт и чем связан с
|
||||
событиями»](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/71).
|
||||
|
||||
**Запуск.** Третья команда того же пакета — `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 ([исследование
|
||||
формата](../../research/2026-08-16-order-snapshot-wire-format.md)).
|
||||
|
||||
**Случайность.** Судьбу заказов бросает свой подпоток, ветвящийся по дню
|
||||
рождения заказа: слепок несёт семь дней рождения сразу, и судьбу каждого
|
||||
заказа обязан читать из его собственного дня. Вся судьба решается при
|
||||
рождении, поэтому слепок любого дня — чтение готовой судьбы, а не накопление
|
||||
состояния. Отклонено: *дописывать броски в конец `COMMERCE`* — правка заказа
|
||||
и правка торгового поведения стали бы одним рычагом; *бросать состояние в
|
||||
подпотоке дня слепка* — траектория заказа зависела бы от того, какие слепки
|
||||
снимали.
|
||||
|
||||
## Запись на проводе
|
||||
|
||||
Контракт провода — на заказ один JSON-документ: деньги строками с двумя
|
||||
знаками, времена RFC 3339 в UTC с миллисекундами, `items` обычным массивом —
|
||||
целиком описан мастер-спекой (раздел 2); основания, отклонённые варианты и
|
||||
проверка разбора — в [исследовании
|
||||
формата](../../research/2026-08-16-order-snapshot-wire-format.md) (резолюция
|
||||
развилки
|
||||
[«Форма записи слепка на проводе»](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/81)).
|
||||
|
||||
Сверх контракта здесь живёт одно правило: **порядок строк внутри слепка —
|
||||
порядок рождения заказов, он же возрастание `order_id`**. Детерминизм даёт
|
||||
его даром, а хешу слепка в описи нужен именно названный порядок.
|
||||
Reference in New Issue
Block a user