"""Tenant-scoped repositories for Phase 11.9.""" from uuid import UUID from sqlalchemy import func, select from app.models.integrations import ( ExperienceConsumerConnectorDispatch, ExperienceConsumerConnectorRegistration, ExperienceNotifyDispatch, ExperienceWidgetDefinition, ExperienceWidgetInstance, ) from app.repositories.base import TenantBaseRepository class _FilteredRepository: async def list_filtered(self, tenant_id, *, offset, limit, spec=None): base = select(self.model).where( self.model.tenant_id == tenant_id, self.model.is_deleted.is_(False) ) count = select(func.count()).select_from(self.model).where( self.model.tenant_id == tenant_id, self.model.is_deleted.is_(False) ) if spec: base = spec.apply(base) count = count.where(*spec.filter_clauses()) else: base = base.order_by(self.model.created_at.desc()) total = int((await self.session.execute(count)).scalar_one()) items = (await self.session.execute(base.offset(offset).limit(limit))).scalars().all() return items, total class ConsumerConnectorRegistrationRepository( _FilteredRepository, TenantBaseRepository[ExperienceConsumerConnectorRegistration] ): model = ExperienceConsumerConnectorRegistration class ConsumerConnectorDispatchRepository( _FilteredRepository, TenantBaseRepository[ExperienceConsumerConnectorDispatch] ): model = ExperienceConsumerConnectorDispatch class WidgetDefinitionRepository( _FilteredRepository, TenantBaseRepository[ExperienceWidgetDefinition] ): model = ExperienceWidgetDefinition class WidgetInstanceRepository(_FilteredRepository, TenantBaseRepository[ExperienceWidgetInstance]): model = ExperienceWidgetInstance async def get_by_embed_ref(self, tenant_id: UUID, embed_ref: str): stmt = select(self.model).where( self.model.tenant_id == tenant_id, self.model.embed_ref == embed_ref, self.model.is_deleted.is_(False), ) result = await self.session.execute(stmt) return result.scalar_one_or_none() class NotifyDispatchRepository(_FilteredRepository, TenantBaseRepository[ExperienceNotifyDispatch]): model = ExperienceNotifyDispatch