Files
orion/app/modules/prospecting/schemas/prospect.py
Samir Boulahtit 6d6eba75bf
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
feat(prospecting): add complete prospecting module for lead discovery and scoring
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>
2026-02-28 00:59:47 +01:00

123 lines
3.4 KiB
Python

# app/modules/prospecting/schemas/prospect.py
"""Pydantic schemas for prospect management."""
from datetime import datetime
from pydantic import BaseModel, Field
class ProspectCreate(BaseModel):
"""Schema for creating a prospect."""
channel: str = Field("digital", pattern="^(digital|offline)$")
business_name: str | None = Field(None, max_length=255)
domain_name: str | None = Field(None, max_length=255)
source: str | None = Field(None, max_length=100)
address: str | None = Field(None, max_length=500)
city: str | None = Field(None, max_length=100)
postal_code: str | None = Field(None, max_length=10)
country: str = Field("LU", max_length=2)
notes: str | None = None
tags: list[str] | None = None
location_lat: float | None = None
location_lng: float | None = None
contacts: list["ProspectContactCreate"] | None = None
class ProspectUpdate(BaseModel):
"""Schema for updating a prospect."""
business_name: str | None = Field(None, max_length=255)
status: str | None = None
source: str | None = Field(None, max_length=100)
address: str | None = Field(None, max_length=500)
city: str | None = Field(None, max_length=100)
postal_code: str | None = Field(None, max_length=10)
notes: str | None = None
tags: list[str] | None = None
class ProspectResponse(BaseModel):
"""Schema for prospect response."""
id: int
channel: str
business_name: str | None = None
domain_name: str | None = None
status: str
source: str | None = None
has_website: bool | None = None
uses_https: bool | None = None
http_status_code: int | None = None
address: str | None = None
city: str | None = None
postal_code: str | None = None
country: str = "LU"
notes: str | None = None
tags: list[str] | None = None
location_lat: float | None = None
location_lng: float | None = None
created_at: datetime
updated_at: datetime
# Nested (optional, included in detail view)
score: "ProspectScoreResponse | None" = None
primary_email: str | None = None
primary_phone: str | None = None
class Config:
from_attributes = True
class ProspectDetailResponse(ProspectResponse):
"""Full prospect detail with all related data."""
tech_profile: "TechProfileResponse | None" = None
performance_profile: "PerformanceProfileResponse | None" = None
contacts: list["ProspectContactResponse"] = []
class Config:
from_attributes = True
class ProspectListResponse(BaseModel):
"""Paginated prospect list response."""
items: list[ProspectResponse]
total: int
page: int
per_page: int
pages: int
class ProspectDeleteResponse(BaseModel):
"""Response for prospect deletion."""
message: str
class ProspectImportResponse(BaseModel):
"""Response for domain import."""
created: int
skipped: int
total: int
# Forward references resolved at module level
from app.modules.prospecting.schemas.contact import ( # noqa: E402
ProspectContactCreate,
ProspectContactResponse,
)
from app.modules.prospecting.schemas.performance_profile import (
PerformanceProfileResponse, # noqa: E402
)
from app.modules.prospecting.schemas.score import ProspectScoreResponse # noqa: E402
from app.modules.prospecting.schemas.tech_profile import (
TechProfileResponse, # noqa: E402
)
ProspectCreate.model_rebuild()
ProspectResponse.model_rebuild()
ProspectDetailResponse.model_rebuild()