feat(prospecting): add complete prospecting module for lead discovery and scoring
Some checks failed
CI / pytest (push) Failing after 48m31s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
CI / ruff (push) Successful in 11s
CI / validate (push) Successful in 23s
CI / dependency-scanning (push) Successful in 28s

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>
This commit is contained in:
2026-02-28 00:59:47 +01:00
parent a709adaee8
commit 6d6eba75bf
79 changed files with 7551 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
# 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")