# app/modules/prospecting/models/campaign.py """ Campaign templates and send tracking. Templates are tailored by lead type (no_website, bad_website, etc.) with support for multiple languages and delivery channels. """ import enum from sqlalchemy import ( Boolean, Column, DateTime, Enum, ForeignKey, Integer, String, Text, ) from app.core.database import Base from models.database.base import TimestampMixin class LeadType(str, enum.Enum): NO_WEBSITE = "no_website" BAD_WEBSITE = "bad_website" GMAIL_ONLY = "gmail_only" SECURITY_ISSUES = "security_issues" PERFORMANCE_ISSUES = "performance_issues" OUTDATED_CMS = "outdated_cms" GENERAL = "general" class CampaignChannel(str, enum.Enum): EMAIL = "email" LETTER = "letter" PHONE_SCRIPT = "phone_script" class CampaignSendStatus(str, enum.Enum): DRAFT = "draft" SENT = "sent" DELIVERED = "delivered" OPENED = "opened" BOUNCED = "bounced" REPLIED = "replied" class CampaignTemplate(Base, TimestampMixin): """A reusable marketing campaign template.""" __tablename__ = "campaign_templates" id = Column(Integer, primary_key=True, index=True) name = Column(String(255), nullable=False) lead_type = Column(Enum(LeadType), nullable=False) channel = Column(Enum(CampaignChannel), nullable=False, default=CampaignChannel.EMAIL) language = Column(String(5), nullable=False, default="fr") subject_template = Column(String(500), nullable=True) body_template = Column(Text, nullable=False) is_active = Column(Boolean, nullable=False, default=True) class CampaignSend(Base, TimestampMixin): """A record of a campaign sent to a specific prospect.""" __tablename__ = "campaign_sends" id = Column(Integer, primary_key=True, index=True) template_id = Column(Integer, ForeignKey("campaign_templates.id", ondelete="SET NULL"), nullable=True) prospect_id = Column(Integer, ForeignKey("prospects.id", ondelete="CASCADE"), nullable=False, index=True) channel = Column(Enum(CampaignChannel), nullable=False) rendered_subject = Column(String(500), nullable=True) rendered_body = Column(Text, nullable=True) status = Column(Enum(CampaignSendStatus), nullable=False, default=CampaignSendStatus.DRAFT) sent_at = Column(DateTime, nullable=True) sent_by_user_id = Column(Integer, nullable=True)