import datetime from typing import Any from fansifter_common.legal_info.types import LegalEntity, PrivacyLink from pydantic import BaseModel, ConfigDict, EmailStr, Field, field_validator from preference_center.profile.enums import Gender from preference_center.profile.types import ( BirthdayStr, CountryCode, EmailMaskedStr, PhoneNumberMaskedStr, PhoneNumberStr, ) # Override BaseModel defaults BaseModel.model_config["populate_by_name"] = True # Infra class HelloResponse(BaseModel): status: str = "ok" # Profiles class Settings(BaseModel): is_date_of_birth_allowed: bool = Field(alias="isDateOfBirthAllowed") privacy_links: dict[str, list[PrivacyLink]] = Field(alias="privacyLinks") legal_entity: LegalEntity = Field(alias="legalEntity") class Profile(BaseModel): email: EmailMaskedStr phone_number: PhoneNumberMaskedStr | None = Field(alias="phoneNumber") first_name: str | None = Field(alias="firstName") last_name: str | None = Field(alias="lastName") date_of_birth: datetime.date | None = Field(alias="dateOfBirth") birthday: str | None gender: Gender | None country_code: str | None = Field(alias="countryCode") city: str | None address: str | None zip_code: str | None = Field(alias="zipCode") model_config = ConfigDict(from_attributes=True) class UpdateProfileInput(BaseModel): email: EmailStr | None = None phone_number: PhoneNumberStr | None = Field(None, alias="phoneNumber") first_name: str | None = Field(None, alias="firstName", max_length=110) last_name: str | None = Field(None, alias="lastName", max_length=110) date_of_birth: datetime.date | None = Field(None, alias="dateOfBirth") birthday: BirthdayStr | None = None gender: Gender | None = None country_code: CountryCode | None = Field(None, alias="countryCode") city: str | None = Field(None, max_length=75) address: str | None = Field(None, max_length=255) zip_code: str | None = Field(None, alias="zipCode", max_length=20) model_config = ConfigDict(str_strip_whitespace=True) @field_validator("*", mode="before") @classmethod def empty_to_none(cls, v: Any) -> Any: if not v: return None return v class Subscription(BaseModel): id: str name: str is_active: bool = Field(alias="isActive") model_config = ConfigDict(from_attributes=True) class SubscriptionChange(BaseModel): id: str is_active: bool = Field(alias="isActive") model_config = ConfigDict(frozen=True) class UpdateSubscriptionsInput(BaseModel): data: set[SubscriptionChange] class UnsubscribeAllByEmailInput(BaseModel): email: EmailStr email_campaign_id: str | None = Field(None, alias="emailCampaignId") origin_id: str | None = Field(None, alias="originId") origin_type: str | None = Field(None, alias="originType") automated_email_trigger_id: str | None = Field( None, alias="automatedEmailTriggerId" ) class EncryptSongwhipFanConsentIdInput(BaseModel): fan_consent_id: bytes = Field(alias="fanConsentId") class EncryptSongwhipFanConsentIdOutput(BaseModel): encrypted: str