Решение заказчика 03.07.2026: два вида тарифа вместо трёх — суточный
оклад daily_salary и процент от пополнений topup_step. Убраны
percent_oborot и fix_per_client.
Миграция 2026_07_03_120000 меняет CHECK sales_tariffs.kind, освобождает
FK sales_users.current_tariff_id и sales_client_assignments.tariff_id,
удаляет тарифы уходящих видов. SalesEarningsService для уходящих видов
возвращает 0 по default-ветке. Снимки привязок не трогаются.
Обновлены контроллеры тарифов и дохода, сервисы Earnings и Metrics,
фронт SalesTariffsView и api/sales.ts, демо-сид, тесты бэка и фронта,
CHANGELOG схемы v8.61 и спека портала.
Не на проде: ветка feat/sales-portal-demo.
Проверка: Sales Feature 169/169, Vitest SalesTariffs 10/10, Larastan 0.
Co-Authored-By: Claude Opus 4.8 1M context <noreply@anthropic.com>
Task 6.3 — период уже проброшен во всех контроллерах (SalesPeriodResolver)
и экранах (salesPeriod store + watch). Добавлен проверочный тест на
/api/sales/overview: period=this даёт оборот 3000/лид, period=prev — 5000/лид,
а balance_sum_rub одинаков (1000) — баланс не зависит от периода.
Фаза 6 завершена: начальник видит весь отдел; период переключается везде.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 3.3a — SalesClientsController наполняет earned_rub через
SalesEarningsService (был null-заглушкой):
- index: доход по каждому клиенту за период по снимку тарифа привязки;
клиент без привязки (начальник видит незакреплённых) → null.
- show (kpi): доход по одному клиенту.
- overview (totals): сумма комиссии по всем привязкам в scope (без оклада).
Тесты Фазы 1 обновлены под реальные значения (percent_oborot 10/20% от
засеянного оборота → 500/5/10000 ₽; привязка без тарифа → 0.0; без
привязки → null). Попутно исправлен ключ params тест-тарифа
(percent→rate, движок читает rate). Sales-набор 132/132, Larastan 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 1.5a: GET /api/sales/overview — агрегаты по своим клиентам (начальник — по всем) за период: счётчики (клиентов/активных/триал/просрочка), Σ баланс, лиды/оборот, earned=null до Фазы 3; «требуют внимания» (overdue/suspended/запас=0, worst-first, до 10); «топ клиентов по лидам» (top-4). deriveTenantStatus вынесен в приватный helper (общий с index). Тест 10/10, stan 0. Один эскейп на сессию.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>