TorbatYar/backend/services/experience/app/repositories/bundles.py
Mortezakoohjani 203671a7bf feat(experience): ship Experience Platform phases 11.0-11.10
Add the experience service with sites through analytics/AI hooks, migrations through 0011, and phase docs/manifests marking the track complete.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 11:43:10 +03:30

43 lines
1.6 KiB
Python

"""Tenant-scoped repositories for Phase 11.8."""
from sqlalchemy import func, select
from app.models.bundles import (
ExperienceBundleDefinition,
ExperienceFeatureToggle,
ExperienceLicenseBinding,
ExperienceTenantBundle,
)
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 BundleDefinitionRepository(_FilteredRepository, TenantBaseRepository[ExperienceBundleDefinition]):
model = ExperienceBundleDefinition
class TenantBundleRepository(_FilteredRepository, TenantBaseRepository[ExperienceTenantBundle]):
model = ExperienceTenantBundle
class LicenseBindingRepository(_FilteredRepository, TenantBaseRepository[ExperienceLicenseBinding]):
model = ExperienceLicenseBinding
class FeatureToggleRepository(_FilteredRepository, TenantBaseRepository[ExperienceFeatureToggle]):
model = ExperienceFeatureToggle