from __future__ import annotations import datetime import sqlalchemy as sa from fansifter_common.adapters.db.types import ChoiceType, PydanticType from fansifter_common.auth.account import Account from fansifter_common.utils.uuid import uuid_string from sqlalchemy.orm import Mapped, mapped_column, relationship from email_campaigns.adapters.db import PgModel from email_campaigns.audiences.enums import AudienceTarget from email_campaigns.rosters.enums import FanDataListType class Audience(PgModel, kw_only=True): __tablename__ = "audience" id: Mapped[str] = mapped_column(primary_key=True, default_factory=uuid_string) name: Mapped[str] vendor_id: Mapped[int] subaccount_id: Mapped[int] target: Mapped[AudienceTarget] = mapped_column(ChoiceType(AudienceTarget)) fan_count: Mapped[int] = mapped_column(default=0) recipients_count_by_email_provider: Mapped[dict[str, int] | None] = mapped_column( PydanticType(dict[str, int] | None), default=None, ) archived_at: Mapped[datetime.datetime | None] = mapped_column(default=None) # relations fandata_lists: Mapped[list[AudienceFanDataList]] = relationship( lazy="raise", default_factory=list, repr=False, ) @property def is_archived(self) -> bool: return self.archived_at is not None @property def account(self) -> Account: return Account(vendor_id=self.vendor_id, subaccount_id=self.subaccount_id) @property def is_email(self) -> bool: return self.target == AudienceTarget.EMAIL @property def global_participant_ids(self) -> list[str]: return [ fandata_item.list_id for fandata_item in self.fandata_lists if fandata_item.type == FanDataListType.ARTIST ] @property def global_participant_id(self) -> str | None: try: return self.global_participant_ids[0] except IndexError: return None @property def custom_list_ids(self) -> list[str]: return [ fandata_item.list_id for fandata_item in self.fandata_lists if fandata_item.type == FanDataListType.CUSTOM_LIST ] @property def custom_list_id(self) -> str | None: try: return self.custom_list_ids[0] except IndexError: return None class AudienceFanDataList(PgModel, kw_only=True): __tablename__ = "audience_fandata_list" __table_args__ = (sa.UniqueConstraint("audience_id", "list_id", "type"),) id: Mapped[str] = mapped_column(primary_key=True, default_factory=uuid_string) audience_id: Mapped[str] = mapped_column(sa.ForeignKey("audience.id"), init=False) list_id: Mapped[str] type: Mapped[FanDataListType] = mapped_column(ChoiceType(FanDataListType))