"""UserRepository PORT — the domain's contract; implemented in ``infrastructure``.

The application layer depends on this Protocol, never on SQLAlchemy. The concrete
``SqlAlchemyUserRepository`` lives in ``infrastructure/identity`` and maps the ORM
``User`` row to the domain ``User`` aggregate.
"""

from __future__ import annotations

import uuid
from typing import Protocol, runtime_checkable

from src.domain.identity.entities import User


@runtime_checkable
class UserRepository(Protocol):
    async def get_by_email(self, email: str) -> User | None:
        """Return the active user for ``email`` (already normalized) or None."""
        ...

    async def get_by_id(self, user_id: uuid.UUID) -> User | None:
        """Return the active user by id or None."""
        ...

    async def roles_after_reconcile(self, user: User) -> list[str]:
        """Apply the policy-admin reconcile, then return the user's sorted roles."""
        ...
