Commit Graph

2 Commits

Author SHA1 Message Date
Дмитрий 08605cf640 fix(tests): Bus::fake partial + session mock — close quirk #72
CsvReconcileJobTest used Bus::fake() (all jobs), silencing dispatch_sync of
RefreshSupplierSessionJob when a parallel afterEach wiped supplier:session.
Now: Bus::fake([RouteSupplierLeadJob::class]) + anonymous mock that re-puts
the session in handle(), making race-window recovery deterministic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 05:35:06 +03:00
Дмитрий deca81c2d7 feat(supplier): Plan 4 Task 8 — CsvReconcileJob hourly + drift>5% email + supplier_csv_reconcile_log
CsvReconcileJob — hourly резерв-канал приёма лидов через CSV-экспорт поставщика:
- Cache::lock 600s (overlap protection).
- Окно [now-25h, now] (запас 1ч над hourly cron).
- INSERT supplier_csv_reconcile_log status='running' → 'ok' | 'drift_alert' | 'failed'.
- Missing vids → INSERT supplier_leads (platform extracted из project, source='csv_recovery',
  recovered_from_csv_at=now) + dispatch RouteSupplierLeadJob.
- Drift > 5% → CsvDriftAlertMail на services.supplier.alert_email.
- UNIQUE-vid conflict → log + skip (idempotency).
- На SupplierTransientException/любой Throwable → status='failed', error_message, rethrow.

CsvDriftAlertMail + blade-template emails/csv_drift_alert.

routes/console.php — Schedule::job(new CsvReconcileJob)->hourly().
config/services.php — supplier.alert_email default 'ops@liderra.ru'.

6 integration tests (CsvReconcileJobTest) + Schedule registration test (через
Http::fake + Bus::fake + Mail::fake + SharesSupplierPdo trait для cross-connection).

Parallel-test race fix: putSupplierSession() вызывается прямо перед SUT, потому
что Sync/Cleanup tests'ы в afterEach делают forget('supplier:session'), а в
--parallel режиме воркеры делят Redis DB+prefix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 11:04:49 +03:00