fix(generator): исправлен расчёт скидки после складской дельты

- Зачем:
  - слепок D7 содержал отрицательный итог заказа и попадал в брак ODS.
- Что:
  - скидка пересчитана от корзины после удаления отсутствующей позиции.
  - сериализатор отклоняет отрицательные деньги через ValueError.
  - добавлены проверки восьми стартовых дней и обновлена опись мира.
- Проверка:
  - make lint, make typecheck и make test в generator/.
  - живой world_next_day: 1694 строки приняты, таблица ошибок пуста.
This commit is contained in:
2026-08-20 13:13:14 +03:00
parent 7b89ccb529
commit 64bcd3d596
8 changed files with 123 additions and 72 deletions
+9 -3
View File
@@ -32,11 +32,12 @@
позиций, посчитанная торговой половиной, то же число, что уехало клиентским
`purchaseRevenue`, но у заказа с вычеркнутой позицией он меньше на её полную
стоимость ([судьба заказа](fate.md)); `discount` — процент промокода от
исходной суммы клиентской покупки, округлённый вниз, и дельта его не
пересчитывает;
оставшегося `items_total`, округлённый вниз: склад сначала определяет, какие
позиции есть в заказе, затем бэкенд считает скидку от итоговой корзины;
`delivery` — бросок заказной стороны по таблице целых весов, единственные
деньги заказа, которых нет ни в одном событии; `total` = `items_total`
`discount` + `delivery`. Отсюда и правило витрин «деньги считаем по
`discount` + `delivery`. Скидка не превышает `items_total`, поэтому итог
неотрицателен по построению. Отсюда и правило витрин «деньги считаем по
бэкенду»: про скидку и доставку клиент не знает вовсе.
Отклонено: *выводить заказ разбором собственного вывода* (`purchaseID`, сырой
@@ -102,6 +103,11 @@
развилки
[«Форма записи слепка на проводе»](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/81)).
Отрицательные копейки канонический сериализатор отвергает через `ValueError`
до сборки записи: [контракт строгого
приёма](ingestion.md#граница-строгого-приёма) их не допускает, а появление
такого значения означает ошибку арифметики источника.
Сверх контракта здесь живёт одно правило: **порядок строк внутри слепка —
порядок рождения заказов, он же возрастание `order_id`**. Детерминизм даёт
его даром, а хешу слепка в описи нужен именно названный порядок.