from __future__ import annotations import json from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.models.entities import Backend, PlacementPolicy class BackendRepository: def __init__(self, session: AsyncSession) -> None: self.session = session async def get_by_name(self, name: str) -> Backend | None: result = await self.session.execute(select(Backend).where(Backend.name == name)) return result.scalar_one_or_none() async def get_by_id(self, backend_id: str) -> Backend | None: return await self.session.get(Backend, backend_id) async def create(self, backend: Backend) -> Backend: self.session.add(backend) await self.session.flush() await self.session.refresh(backend) return backend async def list_all(self) -> list[Backend]: result = await self.session.execute(select(Backend).order_by(Backend.write_priority.desc(), Backend.name.asc())) return list(result.scalars().all()) async def list_enabled(self) -> list[Backend]: result = await self.session.execute( select(Backend) .where(Backend.is_enabled.is_(True)) .order_by(Backend.write_priority.desc(), Backend.read_priority.desc(), Backend.name.asc()) ) return list(result.scalars().all()) async def save(self, backend: Backend) -> Backend: await self.session.flush() await self.session.refresh(backend) return backend async def delete(self, backend: Backend) -> None: await self.session.delete(backend) await self.session.flush() async def is_referenced_by_policy(self, backend_id: str) -> bool: result = await self.session.execute(select(PlacementPolicy)) for policy in result.scalars().all(): preferred = json.loads(policy.preferred_backend_ids_json or "[]") excluded = json.loads(policy.excluded_backend_ids_json or "[]") if backend_id in preferred or backend_id in excluded: return True return False async def list_enabled_by_type(self, backend_type: str) -> list[Backend]: result = await self.session.execute( select(Backend) .where(Backend.is_enabled.is_(True), Backend.type == backend_type) .order_by(Backend.write_priority.desc(), Backend.read_priority.desc(), Backend.name.asc()) ) return list(result.scalars().all())