"""
FastAPI dependency providers for shared resources.

Centralising dependencies here means:
  - Routers stay clean — one line per dependency, no config duplication.
  - Tests can override any dependency via app.dependency_overrides.
  - The database session is always committed on success, rolled back on error.

Usage in route handlers:
    async def my_endpoint(db: AsyncSession = Depends(get_db)):
        ...
"""

from collections.abc import AsyncGenerator

from sqlalchemy.ext.asyncio import AsyncSession

from app.database import AsyncSessionLocal


async def get_db() -> AsyncGenerator[AsyncSession, None]:
    """
    Yield an async database session for the duration of a single request.

    Commits on success, rolls back on any unhandled exception.
    The session is always closed in the finally block.

    Override in tests via:
        app.dependency_overrides[get_db] = override_get_db
    """
    async with AsyncSessionLocal() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise
        finally:
            await session.close()
