"""Pydantic models representing inbound/outbound preference messages.""" from datetime import datetime from typing import Literal from typing import Optional from uuid import UUID from pydantic import BaseModel from pydantic import ConfigDict from pydantic import Field class UpdatedSubscription(BaseModel): """Single subscription preference change element inside an envelope.""" model_config = ConfigDict(populate_by_name=True) id: str crm_id: Optional[str] = Field(default=None, alias='crmId') mailing_list_id: Optional[UUID] = Field(default=None, alias='mailingListId') mailing_list_crm_id: Optional[str] = Field(default=None, alias='mailingListCrmId') email_campaign_id: Optional[UUID] = Field(default=None, alias='emailCampaignId') old_value: Optional[bool] = Field(default=None, alias='oldValue') new_value: bool = Field(alias='newValue') updated_at: Optional[datetime] = None class PreferenceChangeEnvelope(BaseModel): """Top-level payload produced by the preference center.""" model_config = ConfigDict(populate_by_name=True, frozen=True) id: UUID crm_id: Optional[str] = Field(default=None, alias='crmId') updated_subscriptions: list[UpdatedSubscription] = Field(alias='updatedSubscriptions') updated_at: datetime = Field(alias='updatedAt') class SalesforcePreferenceMessage(BaseModel): """Outbound Salesforce message schema.""" model_config = ConfigDict(populate_by_name=True, frozen=True) Action__c: Literal['Sub', 'Unsub'] Mailing_List_ID__c: str Source__c: Literal['New Preference Center'] Fan_ID__c: str Subscription_ID__c: str class InvalidPreferenceMessage(BaseModel): """Invalid source message captured for DLQ publishing.""" model_config = ConfigDict(populate_by_name=True, frozen=True) message_key: Optional[str] = None message_value: str error_type: str error_message: str