from collections.abc import Iterator from dataclasses import dataclass, field from datetime import datetime from typing import NamedTuple from fansifter_common.adapters.sendgrid.models import Email, FanData from fansifter_common.core.enums import Brand from fansifter_common.utils import timezone class EmailSend(NamedTuple): campaign_id: str batch_id: int batch_offset: int provider: str is_first_send: bool current_hourly_quota: float brand: Brand vendor_id: int vendor_name: str subject: str html_content: str preview_text: str | None from_email: Email to_fans: Iterator[FanData] emails_to_send: int send_at: datetime category: str @dataclass(kw_only=True) class EmailSendResult: batch_id: int campaign_id: str sent_emails: int timestamp: datetime = field(default_factory=timezone.now) has_failed_sends: bool = False @dataclass(slots=True, frozen=True) class Recipient: fan_id: str fan_email: str fan_country_iso2: str | None profile_id: str fan_first_name: str | None