Some checks failed
Migrates scanning pipeline from marketing-.lu-domains app into Orion module. Supports digital (domain scan) and offline (manual capture) lead channels with enrichment, scoring, campaign management, and interaction tracking. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
# app/modules/prospecting/models/prospect_contact.py
|
|
"""
|
|
Contact information for a prospect.
|
|
|
|
Supports both auto-scraped (digital) and manually entered (offline) contacts.
|
|
"""
|
|
|
|
import enum
|
|
|
|
from sqlalchemy import Boolean, Column, Enum, ForeignKey, Integer, String, Text
|
|
from sqlalchemy.orm import relationship
|
|
|
|
from app.core.database import Base
|
|
from models.database.base import TimestampMixin
|
|
|
|
|
|
class ContactType(str, enum.Enum):
|
|
EMAIL = "email"
|
|
PHONE = "phone"
|
|
ADDRESS = "address"
|
|
SOCIAL = "social"
|
|
FORM = "form"
|
|
|
|
|
|
class ProspectContact(Base, TimestampMixin):
|
|
"""Contact information associated with a prospect."""
|
|
|
|
__tablename__ = "prospect_contacts"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
prospect_id = Column(Integer, ForeignKey("prospects.id", ondelete="CASCADE"), nullable=False, index=True)
|
|
|
|
contact_type = Column(Enum(ContactType), nullable=False)
|
|
value = Column(String(500), nullable=False)
|
|
label = Column(String(100), nullable=True) # e.g., "info", "sales", "main"
|
|
source_url = Column(Text, nullable=True) # Page where contact was found
|
|
source_element = Column(String(100), nullable=True) # e.g., "mailto", "tel", "contact-form"
|
|
|
|
is_validated = Column(Boolean, nullable=False, default=False)
|
|
validation_error = Column(Text, nullable=True)
|
|
is_primary = Column(Boolean, nullable=False, default=False)
|
|
|
|
# Relationships
|
|
prospect = relationship("Prospect", back_populates="contacts")
|