Files
portal/app/tests/Unit/Billing/GateResultTest.php
T
Дмитрий f78ab4af3d feat(биллинг): баланс блокирует запуск проекта, а не создание — единый гейт
Создавать проекты можно всегда; баланс проверяется в момент ЗАПУСКА
(создать-и-запустить / запустить / возобновить одиночно и пачкой / автоподбор)
под замком на клиента (без гонок). Не хватает — проект остаётся на паузе с
меткой preflight_blocked_at, клиенту сообщение в рублях (сколько пополнить).
Групповой запуск «сколько влезло». Нет активного тарифа на дату → запуск
запрещён (fail-closed). Гейт реквизитов первого проекта добавлен и в автоподбор.

- LaunchBalanceGate — единый гейт вместо 3 копий preflight (ProjectController
  store/update, AutopodborController), под DB::transaction + lockForUpdate(Tenant).
- ProjectService::create($launch) + новый setActive(); bulk resume «сколько влезло».
- AutopodborProjectCreator: пачка в транзакции через общий ProjectService::create.
- Идемпотентность box/phone_type миграций автоподбора (Schema::hasColumn guard).
- Тест-инфра: afterRefreshingDatabase восстанавливает месячные партиции.

Тесты фичи 40/40 зелёные. Спека и план — docs/superpowers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:07:22 +03:00

19 lines
600 B
PHP

<?php
use App\Services\Billing\GateResult;
it('exposes fields and builds balance payload', function () {
$r = new GateResult(passes: false, capacityLeads: 100, committedLeads: 80,
requiredLeads: 150, deficitLeads: 50, topupRub: '1000.00', balanceRub: '123.45');
expect($r->passes)->toBeFalse();
expect($r->deficitLeads)->toBe(50);
expect($r->toBalancePayload())->toBe([
'current_balance_rub' => '123.45',
'current_capacity_leads' => 100,
'would_be_required_leads' => 150,
'deficit_leads' => 50,
'topup_rub' => '1000.00',
]);
});