"""``mgf.common.providers`` — provider seam ABC + translation decorator.

Closes the strategic-review §4.3.C finding: every L2 consumer with
provider seams (telematics SDK, payment gateway, mapping service,
notification provider, ...) hand-rolls the same try/except shape:

  - Wrap each external call with ``try``.
  - Catch the provider SDK's exceptions.
  - Translate them to an ``AppError`` subclass at the seam.
  - Re-raise so the consumer's domain code only sees typed errors.

Without a primitive, every consumer ends up with N copies of the
same ladder; mistakes leak SDK-specific exceptions into domain
code, breaking the closed-box rule.

This module replaces that boilerplate with one ABC + one decorator:

.. code-block:: python

    from mgf.common.providers import ProviderABC, translate_at_seam
    from mgf.common.exceptions import (
        AppError,
        ProviderError,
        ResourceNotFoundError,
    )


    class TelematicsProvider(ProviderABC):
        def translate_exception(self, exc: Exception) -> AppError:
            if isinstance(exc, telematics_sdk.NotFound):
                return ResourceNotFoundError(name=str(exc))
            if isinstance(exc, telematics_sdk.RateLimited):
                return ProviderError(f"telematics rate limited: {exc}")
            return ProviderError(f"telematics call failed: {exc}")

        @translate_at_seam
        async def get_vehicle(self, vehicle_id: str) -> dict:
            # SDK exceptions become typed AppErrors at the boundary.
            return await self._client.vehicles.get(vehicle_id)

The decorator is import-free — it works on any class that has a
:meth:`translate_exception` method matching the
:class:`ProviderABC` shape. :class:`ProviderABC` is the recommended
base, but consumers using the duck-typed Protocol pattern can
adopt without subclassing.

No optional extras — the package is pure stdlib + ``mgf.common.exceptions``.
"""

from __future__ import annotations

from mgf.common.providers._provider import ProviderABC, translate_at_seam

__all__ = ["ProviderABC", "translate_at_seam"]
