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>
78 lines
2.3 KiB
Python
78 lines
2.3 KiB
Python
# app/modules/prospecting/services/interaction_service.py
|
|
"""
|
|
Interaction tracking service.
|
|
|
|
Manages logging of all touchpoints with prospects:
|
|
calls, emails, meetings, visits, notes, etc.
|
|
"""
|
|
|
|
import logging
|
|
from datetime import date
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.modules.prospecting.models import ProspectInteraction
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class InteractionService:
|
|
"""Service for prospect interaction management."""
|
|
|
|
def create(
|
|
self,
|
|
db: Session,
|
|
prospect_id: int,
|
|
user_id: int,
|
|
data: dict,
|
|
) -> ProspectInteraction:
|
|
"""Log a new interaction."""
|
|
interaction = ProspectInteraction(
|
|
prospect_id=prospect_id,
|
|
interaction_type=data["interaction_type"],
|
|
subject=data.get("subject"),
|
|
notes=data.get("notes"),
|
|
outcome=data.get("outcome"),
|
|
next_action=data.get("next_action"),
|
|
next_action_date=data.get("next_action_date"),
|
|
created_by_user_id=user_id,
|
|
)
|
|
db.add(interaction)
|
|
db.commit()
|
|
db.refresh(interaction)
|
|
logger.info("Interaction logged for prospect %d: %s", prospect_id, data["interaction_type"])
|
|
return interaction
|
|
|
|
def get_for_prospect(
|
|
self,
|
|
db: Session,
|
|
prospect_id: int,
|
|
) -> list[ProspectInteraction]:
|
|
"""Get all interactions for a prospect, newest first."""
|
|
return (
|
|
db.query(ProspectInteraction)
|
|
.filter(ProspectInteraction.prospect_id == prospect_id)
|
|
.order_by(ProspectInteraction.created_at.desc())
|
|
.all()
|
|
)
|
|
|
|
def get_upcoming_actions(
|
|
self,
|
|
db: Session,
|
|
*,
|
|
before_date: date | None = None,
|
|
) -> list[ProspectInteraction]:
|
|
"""Get interactions with upcoming follow-up actions."""
|
|
query = db.query(ProspectInteraction).filter(
|
|
ProspectInteraction.next_action.isnot(None),
|
|
ProspectInteraction.next_action_date.isnot(None),
|
|
)
|
|
|
|
if before_date:
|
|
query = query.filter(ProspectInteraction.next_action_date <= before_date)
|
|
|
|
return query.order_by(ProspectInteraction.next_action_date.asc()).all()
|
|
|
|
|
|
interaction_service = InteractionService()
|