Alert System
Notifier Service
The bridge between the database and end-users. Stateless, idempotent, and designed for reliable WhatsApp delivery.
Notification Workflow
1
2
3
4
5
6
Lead Quality Classification
Gold
Private seller, low ad count, complete data, fresh listing
- active_ads ≤ 5
- total_ads ≤ 10
- Complete profile
Good
Likely private seller with reasonable ad activity
- active_ads ≤ 10
- total_ads ≤ 30
- Standard profile
Average
Ambiguous or high-volume private seller
- active_ads ≤ 20
- total_ads ≤ 100
- Mixed signals
Bad
Probable agent with high activity
- active_ads > 20
- OR total_ads > 100
- Agent patterns
Invalid
Commercial ad, holiday rental, or false positive
- Holiday rental detected
- Commercial keywords
- Price < R1000
Hard Filters
System-level filters applied to all notifications
- Exclude Holiday Rentals
- Exclude commercial ads
- Price minimum threshold
User Subscriptions
Database-driven filters from recipient_table_subscriptions
- table_name: 'gumtree_property_listings'
- min_lead_quality: 'good'
- Location filters via joins
Database-Driven Recipients
recipient_manager.py
# RecipientManager - Database-driven recipients
class RecipientManager:
"""Manages notification recipients from database"""
def get_active_recipients(self) -> list[Recipient]:
"""Fetch active, non-paused recipients"""
return self.db.query(whatsapp_recipients)
.filter(is_active=True, is_paused=False)
.all()
def check_quiet_hours(self, recipient_id: int) -> bool:
"""Check if current time falls within quiet hours"""
quiet_hours = self.db.query(recipient_quiet_hours)
.filter(recipient_id=recipient_id)
.first()
return self._is_within_quiet_period(quiet_hours)
# Twilio Content Template
CONTENT_SID = "HX57cf1aad109f3f5bca1593f250896c51"Recipients are managed via the whatsapp_recipients table with subscriptions and location filters stored in related tables. Twilio Content Templates ensure consistent message formatting.