docs(specs): закрыты находки внешнего ревью спеки v2 (#17)
- Зачем:
- слепое ревью постановки нашло места, где исполнителю пришлось бы
молча изобретать решение.
- Что:
- зафиксированы: правило соединения purchaseID[1]=order_id, исключение
declared_* из правила «деньги по бэкенду», имена массивов позиций
dds.order, контракт присутствия всех 46 полей, класс awaiting_order
в сверке, счётчик дельт сумм в манифесте.
- шардирование в разделе 6 и dds.identity_map приведено к
cityHash64 — буквально тем же выражением, что в 1.3.
- Проверка:
- сверка правок с индексом находок ревью (SOL-1..SOL-8, кроме
отклонённого SOL-7).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -196,7 +196,9 @@ Ecommerce (заполнены только у торговых событий):
|
||||
|
||||
Пропущенный день ничего не ломает, следующий слепок самовосстанавливает.
|
||||
- Разбор JSON-позиций — **один раз**, в трансформации ODS → DDS; дальше
|
||||
витрины работают с плоскими массивами. Это единственный носитель навыка
|
||||
витрины работают с плоскими массивами `dds.order`: `item_sku`
|
||||
Array(String), `item_qty` Array(UInt64), `item_price` Array(Decimal(18,2))
|
||||
— одной длины, порядок как в JSON. Это единственный носитель навыка
|
||||
«вложенный JSON в ClickHouse» на стенде.
|
||||
- Статусы держим все три: смена `created` → `paid` и есть причина «дыхания»
|
||||
выручки внутри окна; сужение до двух — резервный срез 1.
|
||||
@@ -212,7 +214,10 @@ CSV в репозитории (`data/catalog/products.csv`: `sku`, `name`, `cate
|
||||
## 4. Сверка `purchase` против заказов
|
||||
|
||||
Ключ: клиентский `purchaseID` = `order_id` бэкенда (магазин знает номер
|
||||
заказа на `/confirmation`). Расхождения — перечислимый список,
|
||||
заказа на `/confirmation`). У события `purchase` массив `purchaseID` несёт
|
||||
ровно один элемент (одно подтверждение — один заказ), сверка соединяет по
|
||||
`purchaseID[1]`; правило зафиксировать комментарием в SQL сверки.
|
||||
Расхождения — перечислимый список,
|
||||
детерминированный от seed, не хаос:
|
||||
|
||||
| | Расхождение | Механика в генераторе | Ориентир доли |
|
||||
@@ -235,7 +240,10 @@ CSV в репозитории (`data/catalog/products.csv`: `sku`, `name`, `cate
|
||||
механически дублирует B.
|
||||
|
||||
Правило стенда: **поведение и атрибуцию считаем по трекеру, деньги — по
|
||||
бэкенду**. Оно выучивается на конфликте: суммы не сойдутся, менти сам
|
||||
бэкенду**. Единственное разрешённое исключение — клиентская оценка выручки
|
||||
под именем `declared_*` там, где атрибуция без трекера невозможна (UTM);
|
||||
слово `declared` в имени — сигнал «это заявка клиента, не деньги
|
||||
отчётности». Оно выучивается на конфликте: суммы не сойдутся, менти сам
|
||||
раскопает почему (Float64 против Decimal, промокод, доставка, отмены).
|
||||
|
||||
## 5. Анонимность и склейка идентичностей
|
||||
@@ -286,7 +294,10 @@ CSV в репозитории (`data/catalog/products.csv`: `sku`, `name`, `cate
|
||||
`cityHash64(сырой строки)`. Урок: «какая нода читала топик — меняется между
|
||||
прогонами, куда легли данные — нет».
|
||||
- **Приём строгий**: `input_format_skip_unknown_fields = 0`, обязательные
|
||||
поля — без значений по умолчанию. Несовпадение имени поля — громкая
|
||||
поля — без значений по умолчанию. Контракт присутствия: генератор выдаёт
|
||||
**все 46 полей в каждом событии**; «пусто» — пустой массив, пустая строка
|
||||
или 0, а не отсутствие ключа в JSON. Так строгий приём уживается с
|
||||
полями, пустыми по смыслу (ecommerce у `pageview`, UTM у прямого захода). Несовпадение имени поля — громкая
|
||||
ошибка в `*_errors`, а не молчаливые нули: имена CamelCase регистрозависимы,
|
||||
опечатка иначе не падает.
|
||||
- **Политика соединений**: по ключу ко-локации — обычное соединение с
|
||||
@@ -370,8 +381,11 @@ Kafka переобработка возможна только из эталон
|
||||
в порядке приоритета — классы пересекаются, побеждает более ранний).
|
||||
`match` — большинство строк; `amount_delta` — только необъяснённый остаток
|
||||
после приведения к сравнимой базе (округления Float64, ~1–2% заказов).
|
||||
Строка «`purchase` без заказа» внутри живого окна — это опоздание, ждущее
|
||||
слепка, а не отдельный класс расхождения.
|
||||
Строка «`purchase` без заказа» внутри живого окна — опоздание, ждущее
|
||||
слепка, а не расхождение: она получает служебный класс `awaiting_order`
|
||||
(шестое значение `mismatch_class`, вне приоритетов расхождений). После
|
||||
закрытия окна K таких строк не остаётся — сироты исключены построением
|
||||
(раздел 4).
|
||||
- **`v_utm_effectiveness`** — остаётся клиентской (атрибуция по трекеру);
|
||||
счётчики `purchases`/`add_to_carts` оживают из таксономии, добавляется
|
||||
`declared_revenue` по UTM.
|
||||
@@ -398,7 +412,7 @@ Kafka переобработка возможна только из эталон
|
||||
Манифест расширяется контрольными числами:
|
||||
|
||||
- заказная сторона: заказы и выручка по дням; манифест хранит точные
|
||||
счётчики по каждому классу расхождений (отмены, потери, дубли) —
|
||||
счётчики по каждому классу расхождений (отмены, потери, дубли, дельты сумм) —
|
||||
самопроверка лабы сверки;
|
||||
- идентичность: uniq кук, uniq известных пользователей, число двухкуковых
|
||||
покупателей — лаба склейки получает самопроверку.
|
||||
@@ -469,7 +483,8 @@ v2 стартует пустым, поэтому объём ниже — это
|
||||
9. Мониторинг и runbook «keeper упал / DDL повис в очереди».
|
||||
|
||||
Критерий приёмки этапа — честный: `make up` работает и проходят
|
||||
smoke-проверки, а не «дашборд зелёный». Документация правится в PR этапа
|
||||
smoke-проверки, а не «дашборд зелёный». Это минимальная планка; свои
|
||||
наблюдаемые критерии каждый этап получает при разбиении в /to-tickets. Документация правится в PR этапа
|
||||
(правило AGENTS.md).
|
||||
|
||||
## 10. Границы: чего не делаем
|
||||
|
||||
Reference in New Issue
Block a user