"""Protocol клиента CRM — позволяет подменять реализацию в тестах (`StubCrmClient`).""" from __future__ import annotations from functools import lru_cache from typing import Protocol from app.core.config import settings from app.schemas.orders import OrderOut class CrmError(Exception): """CRM ответила `status: ERROR` (см. поле `errors` в ответе API).""" class CrmClient(Protocol): async def get_orders(self, *, status: str) -> list[OrderOut]: ... async def set_status(self, *, order_id: str, status: str) -> None: ... @lru_cache def get_crm_client() -> CrmClient: """Один экземпляр на процесс: стаб копит выставленные статусы в памяти.""" if settings.crm_use_stub: if settings.is_production: raise RuntimeError("CRM_USE_STUB=true заборонено в production") from app.services.crm.stub_client import StubCrmClient return StubCrmClient() from app.services.crm.exo_client import ExoCrmClient return ExoCrmClient(settings)