Commit Graph
178 Commits
Author SHA1 Message Date
ddadmin 48bec014cf fix(monitoring): доводы приведены к замерам, пары нод больше не расходятся
- Зачем:
  - второй круг ревью нашёл, что текст спорит с собственной приёмкой: окно
    держалось доводом «слияния за минуту-две», а замер даёт двадцать секунд;
    довод панели ошибок опирался на отказ по памяти, которого ADR 0004 на этом
    стенде не обещает.
- Что:
  - «Части» сортируются по таблице: сортировка по числу частей разводила две
    ноды одной таблицы, как только между ними вставала чужая.
  - у «Слияний» столбик шириной в минуту, иначе редкие события выходили
    волосяной линией; из заголовка убран «слой» — фильтр отсекает журналы
    сервера, а не выбирает слои.
  - в cluster.md исправлены довод за окно, ложное «времени в system.parts нет»,
    счёт панелей без нод (их две, не одна) и разрешение, в котором снят замер
    процессора.
  - панель ошибок и её запись в ADR 0002 переписаны под проверенное: отказ на
    шарде воспроизведён принудительным пределом памяти.
  - из queries.md убран абзац про SELECT 1 — он объяснял пол удалённой панели.
- Проверка:
  - make config-test; make smoke 21/21; make check-clickhouse 10/10.
  - все десять панелей отвечают через /api/ds/query в окнах на полчаса, час и
    шесть часов; шаг столбика слияний проверен отдельным запросом.
2026-08-21 15:28:03 -04:00
ddadmin 42075ff9fb fix(monitoring): панели уточнены по ревью, приёмка снята под нагрузкой
- Зачем:
  - слияния в верхних строках показывали только журналы самого сервера, а
    предел в 15 строк рвал пару нод пополам: панели отвечали не на свой вопрос.
- Что:
  - «Слияния» стали столбиками по слоям: журналы сервера отделены, ряды ods и
    stg видны своими.
  - «Части» показывают все таблицы слоёв целиком, без предела и без обрезанных
    пар.
  - у «Запросов» убран «Поток запросов» — его пол составляли пробники
    состояния; у «Кто спрашивает» убрана лишняя колонка.
  - ряд «коробка» назван «отведено» — как в заголовке панели.
  - доводы дописаны в cluster.md и queries.md, отступления от ADR 0002
    записаны в сам ADR.
- Проверка:
  - make config-test; make smoke 21/21; make check-clickhouse 10/10.
  - все десять панелей отвечают через /api/ds/query в окнах на полчаса, час и
    шесть часов.
2026-08-21 15:11:21 -04:00
ddadmin 7ffb4606f1 feat(monitoring): собраны дашборды «Кластер» и «Запросы»
- Зачем:
  - ADR 0002 обещает три дашборда; собран был один, а симптом инфраструктуры
    как следствие решения человека показать было негде.
- Что:
  - cluster.json — семь панелей: процессор, память с пределом коробки, диски,
    части по таблицам, слияния, keeper, очередь распределённых DDL.
  - queries.json — четыре панели поверх system.query_log: тяжёлые запросы,
    поток запросов, аппетит по пользователям, ошибки.
  - системные таблицы читаются через clusterAllReplicas; очередь DDL — без
    обёртки, она живёт в keeper и у обеих нод одна.
  - устройство обоих дашбордов записано в docs/architecture/monitoring/,
    правило про пороги поднято из data.md в README набора.
- Проверка:
  - make config-test; make smoke 21/21; make check-clickhouse 10/10.
  - все одиннадцать панелей отвечают через /api/ds/query.
2026-08-21 14:52:58 -04:00
ddmitry 272660ff66 Merge pull request 'Мониторинг: справочник зоны — в набор документов' (#122) from feat/121-monitoring-docs into main
Reviewed-on: #122
2026-08-21 21:19:03 +03:00
ddadmin 06c77c5ed2 docs(monitoring): «скребёт» заменено, поправлены падеж и тяжёлые фразы
- Зачем:
  - «что скребёт Prometheus» — калька со scrape, по-русски звучит коряво;
    рядом нашлись ошибка падежа и пара фраз, которые читаются с запинкой.
- Что:
  - заголовок набора и раздел названы по-русски: «за чем следит» и «кого
    опрашивает Prometheus».
  - «Единицы общие — сообщений за интервал» исправлено на именительный падеж.
  - разбиты две перегруженные фразы: про место диагностики версий и про то,
    что читать на панели сходимости.
- Проверка:
  - make config-test.
2026-08-21 14:15:57 -04:00
ddadmin 28177cff92 docs(monitoring): вводный абзац не повторяет каталог дашбордов
- Зачем:
  - проход на вычитание: каталог дашбордов появился в этом же PR, и абзац
    «что здесь есть» стал называть «Данные» второй раз.
- Что:
  - вводный абзац отсылает к каталогу, а имя дашборда и состав панелей
    остались только в самом каталоге.
- Проверка:
  - make config-test.
2026-08-21 14:07:35 -04:00
ddadmin ee0306d19e docs(monitoring): убраны повтор заголовков, запрет и двойной довод
- Зачем:
  - таблица панелей дублировала заголовки из data.json и уже правилась
    дважды; заголовок раздела называл запрещённое действие вместо нужного;
    довод про отвергнутые способы счёта сходимости стоял в двух местах.
- Что:
  - в таблице панелей остались только источники, вопрос панели читается с её
    заголовка на экране.
  - раздел про чтецов Kafka назван по тому, что панели делают, опасность
    kafka_commit_on_select осталась внутри как причина.
  - из записи о приёмке убран пересказ довода, замер оставлен.
- Проверка:
  - make config-test; make lint.
2026-08-21 14:01:32 -04:00
ddadmin 61eb2680ff docs(monitoring): приёмка дашборда переехала к дашборду
- Зачем:
  - в общем разделе «Что проверено» лежали два разных прогона, пола и
    дашборда; следующие дашборды копили бы там осадок.
- Что:
  - запись о приёмке дашборда «Данные» перенесена в data.md, в README.md
    осталась приёмка самой зоны.
- Проверка:
  - make config-test.
2026-08-21 14:00:33 -04:00
ddadmin 91e281fd32 docs(monitoring): справочник зоны разрезан на набор документов
- Зачем:
  - половина справочника была про один дашборд «Данные», а этап приносит ещё
    два дашборда и правила оповещения: описание самой зоны утонуло бы.
- Что:
  - заведён набор docs/architecture/monitoring/ по ADR 0011: README.md — зона
    и каталог дашбордов, data.md — устройство дашборда «Данные».
  - обе входящие ссылки перенацелены: README.md репозитория и ADR 0002.
- Проверка:
  - make config-test; ссылки из README.md и ADR 0002 открываются.
2026-08-21 14:00:05 -04:00
ddmitry d43a9b348b Merge pull request 'Дашборд «Данные»: свежесть, поток, брак, сходимость' (#120) from feat/115-data-dashboard into main
Reviewed-on: #120
2026-08-21 20:52:52 +03:00
ddadmin f7123f2ad7 fix(monitoring): ряды панелей подписаны своими именами, а не буквой запроса
- Зачем:
  - на живом дашборде видно то, чего не показывает API: при нескольких
    запросах в панели Grafana ставит перед именем ряда его букву — «A события»,
    «B приземлилось в ClickHouse». Читателю панели это шум.
- Что:
  - свежесть и поток собраны одним запросом на панель: два столбца вместо двух
    запросов. У потока это заодно вернуло ряд заказов, который пропадал, когда
    в окне не было ни одного слепка.
  - у сходимости ряды из разных источников слить нельзя, поэтому ряду
    ClickHouse имя задано переопределением поля.
- Проверка:
  - make config-test; на живом стенде подписи прочитаны прямо со страницы
    дашборда: «события», «заказы», «произведено в Kafka», «приземлилось в
    ClickHouse»; все шесть панелей отвечают через /api/ds/query.
2026-08-21 13:28:22 -04:00
ddadmin e5c573bb25 fix(monitoring): панели уточнены по ревью, приёмка снята на стенде
- Зачем:
  - две линии ревью нашли, что колонки панели брака читаются как
    непересекающиеся кучи, «вовремя ли» из ADR 0002 не считается вовсе, а
    отказ от ряда «против вчерашнего» нигде не записан рядом с решением.
- Что:
  - в панели брака столбец назван «Из них в брак»: брак — часть приехавшего,
    а не соседняя куча.
  - панель слепка считает паузу после прошлого слепка — это и есть «вовремя
    ли» из ADR 0002; пустая пауза у самого раннего слепка держится
    обнуляемым типом.
  - отказ от ряда «против вчерашнего» записан в ADR 0002 и в monitoring.md с
    доводом: сдвиг на модельные сутки прописал бы ускорение мира в JSON.
  - в monitoring.md сказано, почему свежесть читает физическую _dist, а не
    ods.*_v, и почему панель слепка не знает окна; довод про сломанный JSON
    оставлен у кода, а не задвоен в доке.
  - README больше не утверждает, что панелей нет.
  - у разбора дашбордов убран флаг -e: он обещал утверждение, которого нет.
- Проверка:
  - make config-test (краснеет на нарочно сломанном JSON дашборда), make lint,
    make smoke 21/21, make check-clickhouse 10/10; все шесть панелей отвечают
    через /api/ds/query. Опыты приёмки и их следы — monitoring.md,
    «Что проверено».
2026-08-21 11:23:05 -04:00
ddadmin 180ef5b94f feat(monitoring): собран дашборд «Данные» из шести панелей
- Зачем:
  - главный дашборд ADR 0002 отвечает на вопрос «с потоком всё в порядке?»;
    три его вопроса — свежесть, брак и сходимость — у предшественника не
    заданы вовсе, и в этом весь смысл экрана.
- Что:
  - добавлен infra/grafana/provisioning/dashboards/data.json: свежесть, поток,
    брак, сходимость, отставание чтения из Kafka и дневной слепок заказов;
    порогов и цветовых вердиктов на панелях нет.
  - в monitoring.md записано устройство дашборда: почему слои у панелей разные
    и как считается сходимость — с доводом и двумя отвергнутыми способами.
  - make config-test разбирает JSON дашбордов тем же доводом, что и файлы
    дагов: сломанный файл Grafana молча оставляет прежнюю версию.
- Проверка:
  - make config-test; на живом стенде make smoke 21/21 и make check-clickhouse
    10/10; все шесть панелей отвечают через /api/ds/query.
2026-08-21 11:06:43 -04:00
ddmitry 2ccb8ff72c Merge pull request 'Пол мониторинга: источник ClickHouse в Grafana и экспортёр Kafka' (#118) from feat/114-monitoring-floor into main
Reviewed-on: #118
2026-08-21 17:34:02 +03:00
ddadmin c5dd9c2d34 feat(monitoring): подготовлена основа мониторинга Kafka и ClickHouse
- Зачем:
  - подготовлен пол мониторинга для SQL-панелей и метрик отставания Kafka.
- Что:
  - добавлены отдельная роль ClickHouse, источник Grafana и Kafka exporter.
  - образ Grafana собирается с закреплённым плагином вне тома данных.
  - Prometheus, смоук и документация обновлены под четыре цели.
- Проверка:
  - make config-test; make lint.
  - make smoke; make check-clickhouse; make check-services.
  - make -C generator lint typecheck test.
2026-08-21 09:56:56 -04:00
ddadmin 0bb07fd91d docs(spec): мониторинг перенесён из хвоста в параллельный трек
- Зачем:
  - дашборды нужны точками наблюдения на приёмке этапов 4-8, а зависимость
    у них формально только от этапа 1: «в хвосте» было выбором, не
    необходимостью.
- Что:
  - раздел 9: дашборды строятся параллельно этапам 4-8, состав не меняется.
  - назван хвост этапа: runbook keeper/DDL, system.text_log, правила
    оповещения, урок «посмотрели - сломали - вернули».
  - записано правило: панели порогов и цветовых вердиктов не несут, красное
    и зелёное живёт в проверках.
- Проверка:
  - тикеты этапа нарезаны по этому раскрою: #114-#117 под #11.
2026-08-21 08:06:10 -04:00
ddadmin 67313bf997 chore(main): объединены локальные и удалённые изменения
- Зачем:
  - локальные уточнения документации нужно опубликовать без потери слитых изменений #96 и #109.
- Что:
  - актуальный `origin/main` объединён с двумя локальными коммитами документации.
  - сохранены уточнения применения настроек ClickHouse и границ проектирования заказов.
- Проверка:
  - `make config-test`.
  - `make lint`.
2026-08-21 11:09:49 +03:00
ddmitry fd988babdf Merge pull request 'Упростить имена таблиц заказов в ODS' (#113) from feat/109-simplify-order-table-names into main
Reviewed-on: #113
2026-08-21 11:02:14 +03:00
ddadmin 2a94ee9bde refactor(ods): упрощены имена таблиц заказов
- Зачем:
  - ODS должен показывать сущность заказа, а не способ её доставки слепком.
- Что:
  - физические таблицы и представление переведены на имена `order_*`.
  - SQL загрузки, DAG и документация приведены к тому же словарю.
- Проверка:
  - `make config-test`, `make lint`.
  - `make clean && make up`, `make smoke`, `make check-clickhouse`, `make check-services`.
2026-08-21 10:49:02 +03:00
ddmitry a24dfc4510 Merge pull request 'feat(stand): добавлены стартовые слепки заказов' (#112) from feat/96-start-world-snapshots into main
Reviewed-on: #112
2026-08-21 10:47:45 +03:00
ddadmin ba4743ed52 feat(stand): добавлены стартовые слепки заказов
- Зачем:
  - свежий стенд должен показывать отставание ночной выгрузки заказов от кликстрима.
- Что:
  - после событий генератор отправляет семь слепков дней 0…6 в общий топик orders.
  - make up запускает orders_ingest, ограниченно ждёт его завершения и оставляет день 7 первому ходу мира.
  - README и карта проверок описывают второй источник и измеренную цену подъёма.
- Проверка:
  - make clean && make up; make smoke; make check-clickhouse; make check-services.
  - cd generator && make lint && make typecheck && make test.
2026-08-20 19:12:01 +03:00
ddadmin 9bb044e1ce docs(orders): убран преждевременный вопрос о _load_id
- Зачем:
  - состав полей DDS определяется вместе с моделью, поэтому отдельная задача заранее не нужна.
- Что:
  - удалена задача #85 из списка открытых решений по заказам.
  - убран устаревший указатель на неё из описания приёма.
- Проверка:
  - выполнен `git diff --cached --check`.
2026-08-20 15:57:37 +03:00
ddadmin 0dcc874419 docs(clickhouse): уточнено применение настроек нод
- Зачем:
  - перезапуск мог оставить прежнее окружение и старый inode файла, а документы обещали неподдерживаемое живое применение.
- Что:
  - в README записано пересоздание нод с ожиданием их здоровья.
  - ADR 0007 отделяет решение от процедуры и очищен от устаревших обещаний.
- Проверка:
  - make config-test.
  - git diff --cached --check.
2026-08-20 15:10:13 +03:00
ddmitry 664abf0160 Merge pull request 'Исправить отрицательный total после складской дельты' (#108) from fix/102-negative-order-total into main
Reviewed-on: #108
2026-08-20 13:17:36 +03:00
ddadmin 64bcd3d596 fix(generator): исправлен расчёт скидки после складской дельты
- Зачем:
  - слепок D7 содержал отрицательный итог заказа и попадал в брак ODS.
- Что:
  - скидка пересчитана от корзины после удаления отсутствующей позиции.
  - сериализатор отклоняет отрицательные деньги через ValueError.
  - добавлены проверки восьми стартовых дней и обновлена опись мира.
- Проверка:
  - make lint, make typecheck и make test в generator/.
  - живой world_next_day: 1694 строки приняты, таблица ошибок пуста.
2026-08-20 13:13:14 +03:00
ddmitry 7b89ccb529 Merge pull request 'feat(clickhouse): справочники вынесены в зону dic, словарь читает подложку' (#107) from feat/105-dictionary-home into main
Reviewed-on: #107
2026-08-20 12:26:39 +03:00
ddadminandClaude Opus 5 5cc0ede75a fix(clickhouse): починена проверка словаря, выметены хвосты переноса
Зачем: ревью в три линии нашло настоящий дефект. Девятая проверка кластера
звала dictGet('dds.products', …) — объекта после переноса не существует, и
make check-clickhouse падал. Промах вырос из недосчёта: упоминания dds.products
я искал с фильтром по расширениям, .sh туда не попал, и в ADR уехало «четыре
упоминания» вместо семи.

Что: проверка переведена на dic.products и сверяет цену, умножив её обратно на
сто, — так утверждается ещё и точность приведения к Decimal. Раздел 3
мастер-спеки и список пользователей README догнали перенос: оба описывали
отменённое устройство. В ADR 0012 добавлено условие пересмотра для дома — для
него его не было, хотя ради дома тикет и заводился; недосчёт записан в
«Что проверено» как урок. Разнобой обозначений сведён: карта таблиц в доке
хранилища перешла на имена баз строчными, таблица мастер-спеки — на заголовок
«Где», зону всюду зовут зоной, а не слоем. Термин «Справочник» переписан без
метафоры и уложен в формат глоссария. Вычтено лишнее: комментарии DDL
сократились вдвое, из ADR 0006 и 0007 убраны самооправдание и дублирующие
абзацы, отраслевой образец получил честную оговорку о непроверяемости.

Проверка: make config-test, make lint, make smoke и make check-clickhouse —
все зелёные, десять проверок кластера из десяти.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 12:10:03 +03:00
ddadminandClaude Opus 5 d77acfdf6c fix(docs): расхождение нод при обновлении словаря названо верно
Зачем: горячее ревью поймало ошибку в трёх местах сразу. Было записано, что
после правки каталога ноды расходятся до тридцати секунд — число взято из
ширины окна LIFETIME(MIN 60 MAX 90). Ширина тут ни при чём: каждая нода ждёт
правки от нуля до верхней границы окна, фазы у них независимы, поэтому
расходиться они могут почти на все полторы минуты.

Что: исправлены ADR 0012, опорная точка мастер-спеки и комментарий DDL. Заодно
уточнено, что LIFETIME(0) неатомарность не предотвращал, а сжимал до разброса
исполнения SYSTEM RELOAD DICTIONARY ON CLUSTER, и что витрина выручки пока
спроектирована, а не построена.

Проверка: рассуждением, замером не подтверждалось — прежнее число тоже было
выведено, а не измерено. Замер в ADR (116 секунд на окне MIN 60 MAX 120)
относится к другому утверждению: что словарь обновляется сам.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 11:47:23 +03:00
ddadminandClaude Opus 5 b3e66034fc docs(storage): устройство справочников оставлено в одном месте
Зачем: каждое утверждение о словаре было записано трижды — в доке хранилища, в
комментариях DDL и в ADR 0012. Правка поведения стоила бы трёх согласованных
правок, а расхождение между копиями обнаружилось бы не сразу. Дока хранилища —
карта, а не пересказ реализации.

Что: раздел «Справочники» сведён к своему уровню — правило принадлежности зоны,
топология на кластере, единицы денег и указатели. Механика (движок, форма пути,
пользователь, окно обновления) осталась только в sql/ddl/05-dic-catalog.sql,
рядом с кодом, который она объясняет. Блок «Что проверено» отправлен к замерам
ADR 0012 вместо их пересказа — так же, как он уже поступает с ADR 0005.

Проверка: минус 30 строк; ссылок на убранный подзаголовок в репозитории нет,
три относительные ссылки нового текста разрешаются в существующие файлы.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 11:42:26 +03:00
ddadminandClaude Opus 5 abc94ba406 feat(clickhouse): справочники вынесены в зону dic, словарь читает подложку
Зачем: место словаря в dds было унаследовано от первого объекта, а не решено.
Справочник читают несколько слоёв, а производит его в хранилище ни один —
прописка внутри одного из потребителей приписывала DDS владение, которого у
него нет.

Что: заведена база dic вне цепочки STG → ODS → DDS → DM, dds.products переехал
в dic.products. Под словарём появилась подложка dic.products_file на движке
File — намеренное усложнение ради урока: в бою источник словаря приезжает
процессом, а не лежит файлом у сервера. Источник объявлен формой query и
приводит цену из целых копеек каталога в Decimal(18, 2), как у денег бэкенда.
Обновление — окном LIFETIME(MIN 60 MAX 90) вместо ручной перезагрузки, ценой
заявленной неатомарности между нодами. У словаря свой беспарольный
пользователь dict с единственным правом на чтение dic. Суффикс _file добавлен
в конвенцию имён ADR 0006. Решение, отвергнутые варианты и условия пересмотра
— ADR 0012.

Проверка: make clean && make up на собранном заново стенде — зелено, make smoke
20 проверок и 0 ошибок, make lint чисто. Словарь LOADED со 180 строками, цена
Decimal(18, 2) и точна на копейках: 188990 → 1889.90. Пользователь bi читает
словарь dictGet-ом со второй ноды, analyst — подложку соединением, база dds
пуста. Минимальное право на движок замерено тремя пользователями: достаточно
GRANT FILE ON *.*, хотя отказ называет TABLE ENGINE ON File.

Closes #105

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 11:37:26 +03:00
ddmitry 862dde9fa4 Merge pull request 'feat(clickhouse): добавлен словарь товаров из каталога' (#104) from feat/95-product-dictionary into main
Reviewed-on: #104
2026-08-19 07:38:16 +03:00
ddadmin 13abc58d98 feat(clickhouse): добавлен словарь товаров из каталога
- Зачем:
  - витринам нужен общий с генератором каталог, а менти — пример штатного обновления словаря.
- Что:
  - каталог смонтирован read-only в обе ноды и создан как dds.products ON CLUSTER.
  - роли получили dictGet, а check-clickhouse сверяет ответ под etl с исходным CSV.
  - источник, раскладка и явная политика обновления записаны в документации.
- Проверка:
  - make up с чистыми томами; make lint; make config-test; make smoke; make check-clickhouse.
  - в generator: make lint typecheck test — 427 тестов прошли.
2026-08-19 00:50:14 +03:00
ddmitry 62b275ef94 Merge pull request 'feat(orders): добавлен версионный ODS заказов' (#103) from feat/94-versioned-order-ods into main
Reviewed-on: #103
2026-08-18 23:58:54 +03:00
ddadmin a5508bd9ec refactor(orders): SQL приёма вынесен из DAG
- Зачем:
  - преобразования хранилища должны читаться рядом с целевым слоем, а DAG должен показывать оркестрацию.
- Что:
  - запросы забора и разбора заказов разложены по каталогам STG и ODS.
  - общий контракт провода подключён в обе ветви штатным шаблонизатором Airflow.
  - SQL смонтирован во все службы Airflow, а правило раскладки записано в архитектуре.
- Проверка:
  - make lint config-test smoke check-services.
  - airflow tasks render для pull_batch и parse_batch; airflow tasks test для parse_batch.
2026-08-18 23:55:04 +03:00
ddadmin bdcbe48b59 feat(orders): добавлен версионный ODS заказов
- Зачем:
  - менти должен различать версию заказа, наблюдение источника и запуск загрузки.
- Что:
  - добавлены таблицы версий и брака заказов, а также представление ods.order_v.
  - даг orders_ingest дополнен строгим переходом одного среза STG в две цели ODS.
  - результаты опытов записаны в документации, дефект генератора вынесен в #102.
- Проверка:
  - make lint config-test smoke check-clickhouse check-services.
2026-08-18 23:10:01 +03:00
ddmitry 11a494f550 Merge pull request 'feat(orders): добавить приём слепков в STG' (#101) from feat/93-orders-ingestion into main
Reviewed-on: #101
2026-08-18 21:49:08 +03:00
ddadmin 6bd9190142 feat(orders): добавить приём слепков в STG
Зачем:
- связать проигрывание модельных дней с пакетным приёмом заказов
- показать на одном стенде различие потокового push и пакетного pull

Что:
- добавлен топик, Kafka-чтец и реплицированное сырьё заказов
- добавлен даг orders_ingest с одним прямым чтением и идентификатором загрузки
- работники мира отправляют слепок, ждут приём и только затем двигают позицию
- решения, границы отказа и проверки отражены в ADR и архитектурных документах

Проверка:
- make lint
- make config-test
- make smoke
- make check-clickhouse
- make check-services
2026-08-18 21:33:13 +03:00
ddmitry e67ee27a17 Merge pull request 'feat(generator): добавлена команда слепков заказов' (#100) from feat/92-order-snapshot into main
Reviewed-on: #100
2026-08-18 17:17:16 +03:00
ddadmin 8e21381e13 feat(generator): добавлена команда слепков заказов
- Зачем:
  - задача #92 добавляет второй источник и показывает слепок как чистую функцию зерна и дня.
- Что:
  - добавлены окно, состояние на границе суток и канонические байты с настоящими миллисекундами.
  - добавлены команда snapshot, сдвиг D → D−1 и переиспользование проигранных дней.
  - опись дополнена хешами слепков и поведенческими тестами.
- Проверка:
  - в generator выполнены make lint, make typecheck и make test: 427 тестов.
2026-08-18 17:12:49 +03:00
ddmitry c11da3b252 Merge pull request 'feat(generator): добавлена судьба заказов' (#99) from feat/91-order-fate into main
Reviewed-on: #99
2026-08-18 16:06:32 +03:00
ddadmin 0d90bd566b feat(generator): добавлена судьба заказов
- Зачем:
  - issue #91 требует решать исход и расхождение заказа в день его рождения.
- Что:
  - добавлены три исхода, моменты оплаты и отмены и дельта одной позиции.
  - обновлены проверки повторяемости и архитектурное описание заказов.
- Проверка:
  - cd generator && make lint && make typecheck && make test (418 passed).
2026-08-18 16:02:12 +03:00
ddmitry 62941d2ee5 Merge pull request 'feat(generator): заказы дня — проекция покупок с деньгами магазина' (#98) from feat/90-order-projection into main
Reviewed-on: #98
2026-08-18 15:19:14 +03:00
ddadminandClaude Opus 5 db632c2558 test(generator): анонимность события проверяется и текстом, не только числом
- Зачем:
  - холодное ревью Кодексом (линия дефектов) показало дыру в проверке
    анонимности: личность, уехавшая строкой в сыром `ecommerce`, проходила
    мимо сравнения числовых колонок, и тест оставался зелёным. Дыра
    воспроизведена: user_id, дописанный в блок покупки, тест не замечал.
- Что:
  - тест анонимности спрашивает двумя способами: числовые колонки дня — со
    всеми личностями аудитории, строки покупок целиком — с личностями
    покупателей. Сырой блок собирается руками, и лишнее поле в нём теперь
    красит проверку.
- Проверка:
  - из `generator/`: make lint, make typecheck, make test (417 тестов).
  - мутация «дописать user_id в ecommerce покупки»: до правки тест зелёный,
    после — красный.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 12:46:16 +03:00
ddadminandClaude Opus 5 b2fcc7e593 feat(generator): заказы дня — проекция покупок с деньгами магазина
- Зачем:
  - тикет #90: второй источник должен смотреть на торговую половину дня
    глазами бэкенда — заказ есть проекция покупки, а не второе порождение;
    учебный результат — два источника согласованы по построению, а не
    сверкой.
- Что:
  - `commerce` отдаёт вторым выходом покупки дня: номер заказа, корзину,
    выручку клиента, промокод и человека за кукой; новых бросков в
    подпоток `COMMERCE` не добавилось, события дня не сдвинулись.
  - заведена заказная сторона: подпоток `ORDERS` на позиции 2 дерева зерна
    (прежнее мёртвое имя `DISCREPANCIES`), ветвление — по дню рождения
    заказа; `LATECOMERS` не тронут, его наполнит этап 6.
  - новый модуль `orders.py`: деньги заказа целыми копейками —
    `items_total` из корзины, `discount` по таблице «код → скидка»
    (округление вниз), `delivery` броском по таблице весов на полную длину
    дня, `total` = `items_total` − `discount` + `delivery`.
  - план состава завёл `person_id` — последним броском когорты, после
    паспортов: вторая кука пары повторяет ID своего человека, заказ
    показывает его как `user_id`, в событие Метрики он не попадает.
  - `world`: окно изменяемости `ORDER_WINDOW_DAYS` = 7 рядом с D0 и поясом,
    черновая таблица стоимости доставки.
  - слепок дня в тестах сторожит обе половины: заказы сравниваются наравне
    с потоком событий.
  - доки: имя подпотока заказной стороны и состав денег заказа записаны в
    `docs/architecture/orders`, README генератора знает про новый модуль.
- Проверка:
  - из `generator/`: make lint, make typecheck, make test (417 тестов);
    в корне — make lint.
  - опись мира не покраснела: байты восьми дней те же, заказная сторона
    события не сдвинула.

Closes #90

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 12:30:13 +03:00
ddmitry 716eafe865 Merge pull request 'Добавить каноническое чтение актуальных событий через ods.event_v' (#97) from feat/86-event-v into main
Reviewed-on: #97
2026-08-18 11:46:30 +03:00
ddadmin ded0dac5e2 feat(ods): добавлено представление актуальных событий
- Зачем:
  - потребителю ODS нужна точная актуальная версия события без знания о FINAL.
- Что:
  - создано ods.event_v над распределённой таблицей событий с FINAL.
  - сверка стартового мира переведена на новое представление.
  - документация различает физические версии ODS и бизнес-представление DDS.
- Проверка:
  - make config-test.
  - make check-clickhouse.
2026-08-18 11:33:59 +03:00
ddadminandClaude Fable 5 5f72e63b14 docs(specs): модель DDS заказа перенесена из этапа 3 в этап 4
Зачем: черновик этапов держал DDS заказа в этапе 3, а принятый набор
docs/architecture/orders/ оставляет модель DDS проектированию этапа 4
(ingestion.md «Не входит», тикет #85 перевешен на #6) — расхождение
всплыло на холодном ревью нарезки этапа (#89).

Что: в разделе 9 этап 3 сужен до STG/ODS и дага приёма, модель DDS
заказа названа работой этапа 4.

Проверка: чтение; нарезка этапа 3 (#90–#96) согласована с этой строкой.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 22:57:20 +03:00
ddadminandClaude Fable 5 cf1c6c4636 docs(orders): спека превращена в принятый живой набор architecture/orders
Зачем: датированная спека — событие истории, а устройство компонента — живой
документ; большое полотно плохо грузится и агентом, и человеком (ADR 0011).

Что: вычитание #84 слито с переустройством формы: набор
docs/architecture/orders/ — индекс README и семь файлов по частям устройства
(нарезка по правилу «семь плюс-минус два»); датированные файлы удалены,
ссылки перенацелены, AGENTS.md дополнен правилом подпапки. Приёмка
владельцем #88 пройдена, черновой статус снят из README.

Проверка: холодная сверка миграции свежим тредом — потерь решений нет;
обход относительных ссылок набора — битых нет.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 22:05:52 +03:00
ddadmin 3b4827d819 chore(git): каталог .scratch добавлен в игнор
Зачем: локальные рабочие файлы агентов (хэндоффы, обменные артефакты ревью)
живут в репозитории, чтобы переживать перезагрузку, но в git им не место.

Что: .scratch/ в .gitignore.

Проверка: git status не показывает .scratch/.
2026-08-17 22:05:52 +03:00
ddadminandClaude Fable 5 905ca5bbaf docs(orders): спека второго источника собрана из решений развилок
Зачем: решения развилок #70–#74, #80, #81 карты #69 разошлись по резолюциям
тикетов — цельная картина второго источника нужна в одном месте.

Что: черновик спеки заказов docs/specs/2026-08-16-orders.md и спека приёма
docs/specs/2026-08-16-order-ingestion.md; согласующие правки соседних
документов; правки горячего ревью и двух слепых холодных линий — дефекты
сборки закрыты, назван порядок строк внутри слепка.

Проверка: перепроверка находок теми же ревьюерами — ALL_CLOSED.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 22:05:23 +03:00