78 lines
2.6 KiB
Python
78 lines
2.6 KiB
Python
"""Campaign application repositories — Phase 7.4."""
|
|
from __future__ import annotations
|
|
|
|
from uuid import UUID
|
|
|
|
from sqlalchemy import func, select
|
|
|
|
from app.models.campaigns import CampaignApplication
|
|
from app.repositories.base import TenantBaseRepository
|
|
|
|
|
|
class CampaignApplicationRepository(TenantBaseRepository[CampaignApplication]):
|
|
model = CampaignApplication
|
|
|
|
async def get_by_idempotency(
|
|
self, tenant_id: UUID, idempotency_key: str | None
|
|
) -> CampaignApplication | None:
|
|
if not idempotency_key:
|
|
return None
|
|
stmt = select(CampaignApplication).where(
|
|
CampaignApplication.tenant_id == tenant_id,
|
|
CampaignApplication.idempotency_key == idempotency_key,
|
|
)
|
|
result = await self.session.execute(stmt)
|
|
return result.scalar_one_or_none()
|
|
|
|
async def count_for_member(
|
|
self,
|
|
tenant_id: UUID,
|
|
campaign_id: UUID,
|
|
member_id: UUID,
|
|
*,
|
|
exclude_statuses: tuple = (),
|
|
) -> int:
|
|
clauses = [
|
|
CampaignApplication.tenant_id == tenant_id,
|
|
CampaignApplication.campaign_id == campaign_id,
|
|
CampaignApplication.member_id == member_id,
|
|
]
|
|
if exclude_statuses:
|
|
clauses.append(CampaignApplication.status.notin_(exclude_statuses))
|
|
stmt = select(func.count()).select_from(CampaignApplication).where(*clauses)
|
|
result = await self.session.execute(stmt)
|
|
return int(result.scalar_one())
|
|
|
|
async def list_for_campaign(
|
|
self,
|
|
tenant_id: UUID,
|
|
campaign_id: UUID,
|
|
*,
|
|
offset: int = 0,
|
|
limit: int = 50,
|
|
):
|
|
stmt = (
|
|
select(CampaignApplication)
|
|
.where(
|
|
CampaignApplication.tenant_id == tenant_id,
|
|
CampaignApplication.campaign_id == campaign_id,
|
|
)
|
|
.order_by(CampaignApplication.created_at.desc())
|
|
.offset(offset)
|
|
.limit(limit)
|
|
)
|
|
result = await self.session.execute(stmt)
|
|
return result.scalars().all()
|
|
|
|
async def count_for_campaign(self, tenant_id: UUID, campaign_id: UUID) -> int:
|
|
stmt = (
|
|
select(func.count())
|
|
.select_from(CampaignApplication)
|
|
.where(
|
|
CampaignApplication.tenant_id == tenant_id,
|
|
CampaignApplication.campaign_id == campaign_id,
|
|
)
|
|
)
|
|
result = await self.session.execute(stmt)
|
|
return int(result.scalar_one())
|