"""Thin data-access layer over SQLAlchemy. No business rules live here — the service layer owns those (and the privacy engine). The repository only knows how to fetch and stage rows, transparently excluding soft-deleted ones. """ from typing import Any from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession class BaseRepository: def __init__(self, session: AsyncSession, model: type) -> None: self.session = session self.model = model def _exclude_deleted(self, stmt): if hasattr(self.model, "deleted_at"): stmt = stmt.where(self.model.deleted_at.is_(None)) return stmt async def get(self, id_: Any, *, include_deleted: bool = False): stmt = select(self.model).where(self.model.id == id_) if not include_deleted: stmt = self._exclude_deleted(stmt) return (await self.session.execute(stmt)).scalar_one_or_none() async def list(self, *conditions, include_deleted: bool = False, order_by=None): stmt = select(self.model) for condition in conditions: stmt = stmt.where(condition) if not include_deleted: stmt = self._exclude_deleted(stmt) if order_by is not None: stmt = stmt.order_by(order_by) return list((await self.session.execute(stmt)).scalars().all()) def add(self, obj): self.session.add(obj) return obj