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 email_campaigns.campaigns.enums import EmailCampaignStatus from email_campaigns.campaigns.models import EmailCampaign from email_campaigns.campaigns.repositories import EmailCampaignRepository from email_campaigns.campaigns.types import ( CampaignSearchContext, EmailCampaignCriteria, EmailCampaignOrderBy, ) from email_campaigns.rosters.types import FanDataListId @dataclass(kw_only=True) class SearchCampaignsRequest(AuthAccountFilterRequest): DEFAULT_LIMIT: ClassVar[int] = 50 DEFAULT_ORDER_BY: ClassVar[list[EmailCampaignOrderBy]] = ["createdAt.desc"] search: str | None search_context: CampaignSearchContext | None campaign_ids: set[str] | None fandata_list_ids: set[FanDataListId] | None statuses: list[EmailCampaignStatus] | None audience_id: str | None = None order_by: list[EmailCampaignOrderBy] | None limit: int @singleton class SearchCampaignsHandler: default_permission = Permission("email_campaign", "view") audience_view_permission = Permission("audience", "access") def __init__( self, auth_service: AuthService, campaign_repository: EmailCampaignRepository, ) -> None: self.auth_service = auth_service self.campaign_repository = campaign_repository def handle(self, request: SearchCampaignsRequest) -> Sequence[EmailCampaign]: account_access = self.auth_service.authorize_for_permission( request.identity_id, permission=self._get_permission(request) ) vendor_ids = account_access.filter_vendor_ids(request.vendor_id) subaccount_ids = account_access.filter_subaccount_ids(request.subaccount_id) criteria = EmailCampaignCriteria( campaign_ids=request.campaign_ids, vendor_ids=set(vendor_ids), subaccount_ids=set(subaccount_ids), fandata_list_ids=request.fandata_list_ids, search=request.search, statuses=request.statuses, audience_id=request.audience_id, ) return self.campaign_repository.search_by_criteria( criteria, order_by=request.order_by or SearchCampaignsRequest.DEFAULT_ORDER_BY, limit=request.limit, ) def _get_permission(self, request: SearchCampaignsRequest) -> Permission: if request.search_context == "AUDIENCE": return self.audience_view_permission return self.default_permission