## Ответ Сумма заказа живёт **на обеих сторонах**, и стороны законно расходятся: клиентское событие несёт объявленную сумму (то, что сайт продиктовал трекеру через dataLayer — до пересчёта на бэкенде), заказ бэкенда — итоговую правду со статусами. Правило стенда: **поведение и атрибуцию считаем по трекеру, деньги — по бэкенду**. Правило выучивается на конфликте: суммы у менти не сойдутся, и он сам раскопает почему. ### Клиентская сторона (широкое событие, рамка #18) - Таксономия торговых событий: `pageview` + `add_to_cart` + `purchase`. Полный словарь Метрики (`detail`, `remove`, `impressions`) не берём: механика та же, объём массивов большой, новых идей нет — остаётся теорией в документе о реализме. - `purchase` несёт `purchaseID/Revenue/Currency/Coupon` + массивы `product*` состава заказа + сырую строку `ecommerce` (по образцу выгрузки Метрики, фактура — #27). - `add_to_cart` — массивы `product*` с одним товаром. Оживают мёртвые счётчики `purchases`/`add_to_carts` в `v_utm_effectiveness` без правки витрины. ### Сторона бэкенда (второй источник, рамка #18) - **Формат выгрузки: полный ежедневный слепок заказов в пределах окна изменяемости K дней.** Запись = снапшот заказа: `order_id`, `user_id`, времена, `status` (`created`/`paid`/`cancelled`), `updated_at`, итоговые суммы (товары / скидка / доставка / итого) + **позиции вложенным JSON** (`items: [{sku, qty, price}]`) — «родной» экспорт бэкенда, а не диалект Метрики. - Обоснование слепка (а не инкремента): очень частый боевой формат; идемпотентный приём и самовосстановление (пропущенный день ничего не ломает); дедуп до последней версии становится обязательным с первого дня. Окно K делает объём защитимым (за окном заказ неизменяем — возить незачем) и даёт границу пересчёта: выручка дня D «дышит» K дней, потом замерзает. - Приём: дедуп через `ReplacingMergeTree`/`argMax`; разбор JSON-позиций — **один раз** в трансформации ODS → DDS, дальше витрины работают с плоскими массивами. Это единственный носитель навыка «вложенный JSON в ClickHouse» в стенде. - В `docs/generator-realism.md` — честный абзац trade-off «инкремент экономнее, слепок надёжнее» и сноска про compacted topic как родной Kafka-паттерн для состояния сущности. ### Сверка - **Ключ: клиентский `purchaseID` = `order_id` бэкенда** (магазин знает номер заказа на `/confirmation` — как `actionField.id` у Метрики). - Конструируемые расхождения — перечислимый список из четырёх причин, детерминированных от seed: - **A. Отмена** — `purchase` есть, заказ дошёл до `status='cancelled'` (бесплатно из статусов); - **B. Потерянное событие** — заказ есть, `purchase` не доехал (вероятность в генераторе); - **C. Дельта суммы** — систематическая, по построению: клиент объявляет сумму товаров до промокода и доставки, бэкенд — итог; менти может вывести формулу связи; - **D. Дубль события** — повторный `purchase` от обновления `/confirmation` (вероятность). - Пятый эффект бесплатно даёт формат доставки: **опоздание** (заказ впервые появляется в слепке D+1/D+2) — «вчера не сходилось, сегодня сошлось». - Не берём: сироту-фрод (дублирует B механически) и расхождение часов клиент/сервер — это жители тумана «Грязь в данных», придут своим тикетом. ### Слои и витрины - DDS: одна новая сущность `dds.order` (последняя версия заказа, позиции разобраны в массивы). `purchase` отдельной сущности не получает — это строка широкого события. - DM, три роли: **выручка** (`v_revenue_daily`, по категориям через `dictGet` каталога) — строится только от заказов; **сверка** (`v_purchase_vs_orders`) — FULL OUTER JOIN по ключу с классификатором расхождения; **атрибуция** (`v_utm_effectiveness`) — остаётся клиентской, плюс объявленная выручка по UTM. Точный состав колонок — в спеку (#17). ### Эталонный мир Пересборка артефакта неизбежна и уже оплачена решением #18; этот тикет нагружает её смыслом: манифест расширяется контрольными числами заказной стороны — заказы и выручка по дням, и ровно N потерянных / M дублей / K отмен для самопроверки лабы сверки. Политика версионирования артефакта здесь не решается (пункт тумана карты). ### Ограничения исполнения и страховочные срезы Аудитория — джун после базовой программы: расхождения — перечислимый список, не хаос. Если при сборке спеки (#17) суммарный объём испугает, резать в порядке: (1) статусы сузить до `created`/`cancelled` — урок дедупа держится на самом слепке; (2) расхождения вводить поэтапно — сначала A+C, потом B+D; (3) окно K сделать константой мира, а не параметром. ### Отклонено по дороге Событийный лог заказов (сборка автомата — дальше от типовой работы DE), CDC-формат (имитация Debezium без Debezium), шапка+строки (воскрешает склейку по ключам), отдельный поток возвратов, полный словарь торговых событий Метрики, механика Sign/CollapsingMergeTree (остаётся кандидатом на потом, её дом — клиентская сторона, поток визитов Метрики Про, не заказы). Фактура: `docs/research/2026-07-26-yandex-clickstream-format.md` (#27), резолюция «Модель данных» (#18).