Дмитрий
|
8fc9d3ec8a
|
feat(supplier): Plan 3 Task 4 — SupplierPortalClient HTTP-обёртка над rt-*
Компоненты:
- SupplierProjectDto (readonly DTO, fromModel + equals)
- SupplierException иерархия (Auth/Transient/Client + abstract base)
- SupplierAuthException: 401/403 sticky после refresh-retry
- SupplierTransientException: 5xx/network/timeout (retryable)
- SupplierClientException: 4xx 400/404/422 (наша ошибка payload)
- SupplierPortalClient: list/save/update/delete projects через Http facade
+ Redis cache cookie/CSRF (key 'supplier:session', TTL 6h)
+ auto-retry на 401/403 через dispatch_sync(RefreshSupplierSessionJob)
+ classification HTTP errors → 3 exception types
- RefreshSupplierSessionJob stub (handle() пустой; full impl в Task 5)
- config/services.supplier (login/password/portal_url/alert_email)
+9 тестов через Http::fake() в Unit/Supplier/SupplierPortalClientTest.php:
- cookie/CSRF attach
- 401 retry flow (single retry, sticky 401 → SupplierAuthException)
- 5xx → SupplierTransientException
- 4xx → SupplierClientException
- network error → SupplierTransientException
- save/update/delete payload shapes + responses
NOTE: toPayload() shape — placeholder; точные поля адаптируются
после Task 1 discovery + Task 2 spec §4.4 (отдельный fixup commit
перед Task 6 при расхождении наблюдаемого формата с предполагаемым).
|
2026-05-11 06:46:13 +03:00 |
|