Files
portal/app/tests/Feature/Integration
Дмитрий e8db184e99 feat(slepok): Task 2.5 — LeadRouter reads from project_routing_snapshots (R-01 closure)
LeadRouter SQL переписан на JOIN с project_routing_snapshots по active_slepok_date:
до 21:00 МСК = today, после 21:00 МСК = today+1. is_active / delivery_days_mask /
daily_limit / regions / signal_type / signal_identifier берутся из snapshot.
Из live projects — только delivered_today (счётчик остатка лимита). Из tenants —
balance_rub (live auto-pause при нулевом балансе).

Active snapshot date вычисляется в PHP (метод activeSnapshotDate()) и
передаётся в SQL как параметр — тестируемо через Carbon::setTestNow,
исключает дрейф между PHP- и DB-часами.

Fail-loud: Log::error('lead_router.no_snapshot_for_active_date', ...) если
по активной дате слепка вообще нет ни одной строки snapshot'а (cron не отработал).

Closes R-01, R-04, R-06, R-07, R-08, R-15.
Partial: R-02 (через шеринг), R-09 (race), R-10 (editable identifier) — закрываются Task 2.6+.

Plan: docs/superpowers/plans/2026-05-26-slepok-routing-protection.md §Task 2.5
Spec: docs/superpowers/specs/2026-05-26-slepok-routing-protection-design.md §4.2.3

Tests added:
- tests/Feature/LeadRouter/SnapshotRoutingTest.php (4 tests, all GREEN locally)

Tests patched (downstream — добавлен createRoutingSnapshotFromProject() helper):
- tests/Pest.php — global helper createRoutingSnapshotFromProject()
- tests/Feature/LeadRouter/BalanceFilterTest.php (2/2 GREEN)
- tests/Feature/Services/LeadRouterTest.php (10/10 GREEN)
- tests/Feature/Jobs/RouteSupplierLeadJobTest.php (14/14 GREEN)
- tests/Feature/Supplier/DirectPlatformTest.php (6/6 GREEN)
- tests/Feature/Supplier/RouteSupplierLeadJobBillingTest.php (3/3 GREEN)
- tests/Feature/Supplier/SupplierConnectionTest.php (5/5 GREEN)
- tests/Feature/Integration/SupplierLeadFlowTest.php (2/2 GREEN)
- tests/Feature/Pd/DealCreatePdLogTest.php (2/2 GREEN)

Each test file isolated regression: GREEN. Combined run 49/50 with 1 flake on
quirk #77 (Faker unique domainName + cross-connection pgsql/pgsql_supplier
DatabaseTransactions scope mismatch) — pre-existing, NOT regression от Task 2.5.

Patched via 7 parallel Sonnet subagents per Pravila §15.1; controller-verified
isolated + combined regression (latter caught 1 subagent over-application:
paused project in SupplierLeadFlowTest получил snapshot, что нарушило логику
теста — fixed inline, по semantic match with SnapshotBackfillCommand SQL
WHERE p.is_active = true).
2026-05-28 05:48:15 +03:00
..