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>
3.6 KiB
Opportunity Scoring Model
Overview
The scoring model assigns each prospect a score from 0-100 based on the opportunity potential for offering web services. Higher scores indicate better leads. The model supports two channels: digital (domain-based) and offline (in-person discovery).
Score Components — Digital Channel
Technical Health (Max 40 points)
Issues that indicate immediate opportunities:
| Issue | Points | Condition |
|---|---|---|
| No SSL | 15 | uses_https = false |
| Very Slow | 15 | performance_score < 30 |
| Slow | 10 | performance_score < 50 |
| Moderate Speed | 5 | performance_score < 70 |
| Not Mobile Friendly | 10 | is_mobile_friendly = false |
Modernity / Stack (Max 25 points)
Outdated technology stack:
| Issue | Points | Condition |
|---|---|---|
| Outdated CMS | 15 | CMS is Drupal, Joomla, or TYPO3 |
| Unknown CMS | 5 | No CMS detected but has website |
| Legacy JavaScript | 5 | Uses jQuery without modern framework |
| No Analytics | 5 | No Google Analytics or similar |
Business Value (Max 25 points)
Indicators of business potential:
| Factor | Points | Condition |
|---|---|---|
| Has Website | 10 | Active website exists |
| Has E-commerce | 10 | E-commerce platform detected |
| Short Domain | 5 | Domain name <= 15 characters |
Engagement Potential (Max 10 points)
Ability to contact the business:
| Factor | Points | Condition |
|---|---|---|
| Has Contacts | 5 | Any contact info found |
| Has Email | 3 | Email address found |
| Has Phone | 2 | Phone number found |
Score Components — Offline Channel
Offline leads have a simplified scoring model based on the information captured during in-person encounters:
| Scenario | Technical Health | Modernity | Business Value | Engagement | Total |
|---|---|---|---|---|---|
| No website at all | 30 | 20 | 20 | 0 | 70 (top_priority) |
| Uses gmail/free email | +0 | +10 | +0 | +0 | +10 |
| Met in person | +0 | +0 | +0 | +5 | +5 |
| Has email contact | +0 | +0 | +0 | +3 | +3 |
| Has phone contact | +0 | +0 | +0 | +2 | +2 |
A business with no website met in person with contact info scores: 70 + 5 + 3 + 2 = 80 (top_priority).
Lead Tiers
Based on the total score:
| Tier | Score Range | Description |
|---|---|---|
top_priority |
70-100 | Best leads, multiple issues or no website at all |
quick_win |
50-69 | Good leads, 1-2 easy fixes |
strategic |
30-49 | Moderate potential |
low_priority |
0-29 | Low opportunity |
Reason Flags
Each score includes reason_flags that explain why points were awarded:
{
"score": 78,
"reason_flags": ["no_ssl", "slow", "outdated_cms"],
"lead_tier": "top_priority"
}
Common flags (digital):
no_ssl— Missing HTTPSvery_slow— Performance score < 30slow— Performance score < 50not_mobile_friendly— Fails mobile testsoutdated_cms— Using old CMSlegacy_js— Using jQuery onlyno_analytics— No tracking installed
Offline-specific flags:
no_website— Business has no websiteuses_gmail— Uses free email providermet_in_person— Lead captured in person (warm lead)
Customizing the Model
The scoring logic is in app/modules/prospecting/services/scoring_service.py. You can adjust:
- Point values — Change weights for different issues
- Thresholds — Adjust performance score cutoffs
- Conditions — Add new scoring criteria
- Tier boundaries — Change score ranges for tiers