from collections.abc import Sequence from dataclasses import dataclass from typing import ClassVar from anydi import singleton from fansifter_common.auth.requests import AuthAccountFilterRequest from fansifter_common.auth.services import AuthService from fansifter_common.auth.types import Permission from ows_text_campaigns.campaigns.enums import CampaignStatus from ows_text_campaigns.campaigns.models import Campaign from ows_text_campaigns.campaigns.repositories import CampaignRepository from ows_text_campaigns.campaigns.services import CampaignService from ows_text_campaigns.campaigns.types import CampaignCriteria, CampaignOrderBy @dataclass(kw_only=True) class GetCampaignsRequest(AuthAccountFilterRequest): DEFAULT_LIMIT: ClassVar[int] = 50 DEFAULT_OFFSET: ClassVar[int] = 0 DEFAULT_ORDER_BY: ClassVar[list[CampaignOrderBy]] = ["updatedAt.desc"] search: str | None global_participant_ids: set[str] | None statuses: list[CampaignStatus] | None order_by: list[CampaignOrderBy] limit: int offset: int @dataclass class GetCampaignsResponse: items: Sequence[Campaign] total: int @singleton class GetCampaignsHandler: permission = Permission("text_campaign", "view") def __init__( self, auth_service: AuthService, campaign_repository: CampaignRepository, campaign_service: CampaignService, ) -> None: self.auth_service = auth_service self.campaign_repository = campaign_repository self.campaign_service = campaign_service def handle(self, request: GetCampaignsRequest) -> GetCampaignsResponse: account_access = self.auth_service.authorize_for_permission( request.identity_id, permission=self.permission ) vendor_ids = account_access.filter_vendor_ids(request.vendor_id) subaccount_ids = account_access.filter_subaccount_ids(request.subaccount_id) criteria = CampaignCriteria( vendor_ids=set(vendor_ids), subaccount_ids=set(subaccount_ids), global_participant_ids=request.global_participant_ids, search=request.search, statuses=request.statuses, ) total = self.campaign_repository.count_by_criteria(criteria) if total == 0: return GetCampaignsResponse(total=0, items=[]) items = self.campaign_repository.find_by_criteria( criteria, order_by=request.order_by, limit=request.limit, offset=request.offset, ) # Prefetch audience self.campaign_service.prefetch_audience(items) self.campaign_service.prefetch_analytics(items) return GetCampaignsResponse(total=total, items=items)