# Золотые векторы расчёта чека

Каждый файл — чек с вручную проверенным результатом (ADR-0007). Векторы фиксируют поведение
движка вплоть до округлений и объяснения расчёта; любой порт движка (другой язык, офлайн-режим
кассы) обязан проходить их без изменений. Прогон: `GoldenVectorsTest` в `tests/Unit`.

## Формат

| Поле | Содержание |
|---|---|
| `description` | что проверяет вектор |
| `calculation` | ход ручного расчёта ожидаемого результата |
| `rules` | набор правил целиком, с определениями акций в `campaigns`, уровнями в `tiers` (или `null`), бонусами в `bonuses` и картами штампов в `stamp_cards` (`RuleSet::definition()`, `schema: 1`) |
| `basket` | чек: `purchased_at` (ISO 8601), `redeem_points`, `redeem_maximum`, `lines[]`; необязательно `channel`, `location_id` |
| `member` | `member_id` (или `null` для анонимного покупателя), `spendable_points`, `can_redeem`, `can_accrue`; необязательно `tier` (без него действует начальный уровень программы), `segments`, `purchases`, `birth_date`, `stamps` (штампы по коду карты) |
| `campaign_state` | необязательно: `codes` (промокод по id акции), `rejected_codes` (`code`, `reason`), `member_uses` и `budget_left` по id акции |
| `expected` | результат `CalculationResult` без `snapshot_id` и `snapshot_version` |

Строка чека: `id`, `sku`, `quantity` (в тысячных долях: 1 шт. = 1000, 0,567 кг = 567), `amount`
(копейки, после скидок кассы) и необязательные флаги каталога: `categories`, `restricted`,
`excluded_from_accrual`, `excluded_from_redemption`, `excluded_from_promotions`,
`min_unit_price_minor`.

Единицы: деньги — копейки, баллы — минимальные единицы типа баллов (`points.precision` знаков),
проценты и доли — базисные пункты (1 % = 100). Все значения целые.

## Правила добавления

Ожидаемый результат считается вручную и записывается в `calculation`, а не копируется из вывода
движка. Изменение ожидаемого результата существующего вектора — изменение поведения, которое
требует записи в CHANGELOG.
