    __tablename__ = "campaign_recipients"
    id = Column(Integer, primary_key=True)
    campaign_id = Column(Integer, ForeignKey("campaigns.id", ondelete="CASCADE"), nullable=False, index=True)
    recipient_id = Column(Integer, ForeignKey("recipients.id", ondelete="CASCADE"), nullable=False)
    email = Column(String(320), nullable=False, index=True)
    status = Column(String(30), default="pending")  # pending|queued|processing|sent|temp_failed|perm_failed|suppressed|skipped
    generated_invoice_number = Column(String(100), default="")
    generated_amount = Column(Float)
    generated_shipping = Column(Float)
    generated_subject_id = Column(Integer, ForeignKey("subject_lines.id", ondelete="SET NULL"))
    generated_template_id = Column(Integer, ForeignKey("html_templates.id", ondelete="SET NULL"))
    generated_phone = Column(String(60), default="")
    assigned_account_id = Column(Integer, ForeignKey("gmail_accounts.id", ondelete="SET NULL"))
    attempt_count = Column(Integer, default=0)
    last_error = Column(Text, default="")
    msg_id = Column(String(200), default="")       # Gmail message id
    thread_id = Column(String(200), default="")    # Gmail thread id
    sent_at = Column(DateTime(timezone=True))
    seq = Column(Integer, default=0)               # ordering within campaign

    campaign = relationship("Campaign")
    recipient = relationship("Recipient")
    subject = relationship("SubjectLine")
    template = relationship("EmailTemplate")
    account = relationship("GmailAccount")

    __table_args__ = (UniqueConstraint("campaign_id", "recipient_id", name="uq_campaign_recipient"),
                      Index("ix_campaign_recipient_status", "campaign_id", "status"),)


class Attachment(Base, TimestampMixin):
    __tablename__ = "attachments"
    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True)
    name = Column(String(300), nullable=False)
    filename = Column(String(300), nullable=False)
    stored_path = Column(String(500), nullable=False)  # relative path under uploads/
    mime_type = Column(String(120), default="application/octet-stream")
    size_bytes = Column(Integer, default=0)
    kind = Column(String(30), default="file")  # text|html|pdf|image|file
    description = Column(Text, default="")
