from typing import TypeVar, Generic, Type from uuid import UUID from sqlalchemy import select, func from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import Base ModelT = TypeVar("ModelT", bound=Base) class BaseRepository(Generic[ModelT]): def __init__(self, model: Type[ModelT], session: AsyncSession): self.model = model self.session = session async def get(self, id: UUID) -> ModelT | None: return await self.session.get(self.model, id) async def list(self, offset: int = 0, limit: int = 50, **filters) -> tuple[list[ModelT], int]: query = select(self.model) count_query = select(func.count()).select_from(self.model) for attr, value in filters.items(): if value is not None and hasattr(self.model, attr): query = query.where(getattr(self.model, attr) == value) count_query = count_query.where(getattr(self.model, attr) == value) total = (await self.session.execute(count_query)).scalar() or 0 query = query.offset(offset).limit(limit) result = await self.session.execute(query) return list(result.scalars().all()), total async def create(self, obj: ModelT) -> ModelT: self.session.add(obj) await self.session.flush() await self.session.refresh(obj) return obj async def update(self, obj: ModelT, data: dict) -> ModelT: for key, value in data.items(): if value is not None: setattr(obj, key, value) await self.session.flush() await self.session.refresh(obj) return obj async def delete(self, obj: ModelT) -> None: await self.session.delete(obj) await self.session.flush()