Phase 3: Real-time Geofence Detection Implementation
Overview
Phase 3 implements Real-Time Geofence Detection that processes individual location reports immediately after fetching from Apple FindMy to detect geofence entry/exit events before data aggregation. This addresses the critical issue of missing delivery events that occur between hourly aggregation intervals.
Problem Statement
The current system has a fundamental timing mismatch:
- 6-hour fetch interval with hourly aggregation creates gaps
- Devices entering and exiting geofences between fetches are missed entirely
- Geofence detection runs on aggregated data (averaged positions)
- Actual entry/exit points are lost in aggregation
- Results in false negatives for geofence events
Solution Architecture
Real-Time Processing Pipeline
Apple FindMy → Tracker Fetcher → Real-Time Geofence Detection → Event Storage
↓ ↓ ↓
Location Reports Geofence Events Audit Trail
↓ ↓ ↓
Data Aggregation Status Updates Notifications
Key Components
1. Real-Time Geofence Service (services/realtime_geofence/)
Core Service (service.py):
- Processes individual location reports for geofence events
- Detects entry/exit events by comparing previous and current geofences
- Determines status changes based on geofence priority
- Filters location reports based on accuracy and recency
Detection Utilities (detection_utils.py):
- Geospatial queries for delivery and storage locations
- Point-in-geofence calculations using PostGIS
- Distance calculations to geofence centers
- Location accuracy validation
Event Storage (event_storage.py):
- Persists geofence events with complete audit trail
- Maintains tracker geofence state for exit detection
- Provides event retrieval for analysis and debugging
Integration Layer (integration.py):
- Connects real-time detection to tracker fetching pipeline
- Processes location reports immediately after fetch
- Triggers immediate status updates based on events
2. Data Models (models.py)
GeofenceEvent: Complete event record with location data LocationPoint: Precise location with accuracy information GeofenceDetectionResult: Processing result with events and status changes
Implementation Benefits
Immediate Improvements
- Real-time detection: Events detected within seconds of location fetch
- Complete audit trail: All geofence interactions stored with full location data
- Accurate timing: Uses actual location timestamps, not aggregation times
- No missed events: Processes every location report before aggregation
Long-term Advantages
- Debugging capability: Raw location data available for investigating missed events
- Flexible aggregation: Multiple aggregation strategies possible
- Event-driven architecture: Foundation for real-time notifications
- Scalable processing: Efficient batch processing for multiple trackers
Technical Implementation
Geofence Detection Logic
def process_location_report(tracker_id, location, location_report_id):
# 1. Validate location accuracy and recency
if not should_process_location_for_geofence(location):
return empty_result
# 2. Get current geofences for location
current_geofences = get_current_geofences_for_location(db, tracker_id, location)
# 3. Get previous geofences from state
previous_geofences = get_tracker_last_known_geofences(db, tracker_id)
# 4. Detect entry/exit events
events = detect_geofence_events(previous_geofences, current_geofences)
# 5. Determine status change
status_changed, new_status = determine_status_change(current_geofences)
return GeofenceDetectionResult(events, current_geofences, status_changed)
Status Priority Logic
- DELIVERED (highest priority) - if in delivery location geofence
- IN_STORAGE (medium priority) - if in storage location geofence
- IN_TRANSIT (default) - if not in any geofence
Location Accuracy Filtering
- Minimum accuracy: 100 meters horizontal accuracy
- Minimum confidence: 50% confidence level
- Recency requirement: Within last hour
- Purpose: Prevent false positive events from poor GPS signals
Integration with Tracker Fetcher
# In tracker fetcher after successful Apple FindMy fetch
def process_fetched_reports(tracker_id, location_reports):
# 1. Store raw location reports
stored_reports = store_location_reports(location_reports)
# 2. Process for real-time geofence detection
geofence_service = GeofenceIntegrationService(db)
detection_results = geofence_service.process_fetched_location_reports(
tracker_id, location_reports
)
# 3. Trigger immediate status updates if needed
if detection_results["total_events_generated"] > 0:
geofence_service.trigger_immediate_status_update(tracker_id)
# 4. Continue with normal aggregation pipeline
return detection_results
Database Schema Requirements
Geofence Events Table
CREATE TABLE geofence_events (
id SERIAL PRIMARY KEY,
tracker_id INTEGER NOT NULL,
event_type VARCHAR(20) NOT NULL, -- 'entry', 'exit', 'dwell'
geofence_type VARCHAR(30) NOT NULL, -- 'delivery_location', 'storage_location'
geofence_id INTEGER NOT NULL,
latitude DECIMAL(10, 8) NOT NULL,
longitude DECIMAL(11, 8) NOT NULL,
horizontal_accuracy REAL NOT NULL,
confidence INTEGER NOT NULL,
event_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
location_report_id INTEGER,
previous_status VARCHAR(20),
new_status VARCHAR(20),
dwell_duration_seconds INTEGER,
distance_to_center REAL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
FOREIGN KEY (tracker_id) REFERENCES trackers(id),
INDEX idx_geofence_events_tracker_timestamp (tracker_id, event_timestamp),
INDEX idx_geofence_events_type_timestamp (event_type, event_timestamp)
);
Tracker Geofence State Table
CREATE TABLE tracker_geofence_state (
tracker_id INTEGER NOT NULL,
geofence_type VARCHAR(30) NOT NULL,
geofence_id INTEGER NOT NULL,
entered_at TIMESTAMP WITH TIME ZONE NOT NULL,
PRIMARY KEY (tracker_id, geofence_type, geofence_id),
FOREIGN KEY (tracker_id) REFERENCES trackers(id)
);
Testing Strategy
Behavioral Tests (tests/behaviors/realtime_geofence/)
Test Coverage:
- Geofence entry/exit event detection
- Location accuracy filtering
- Event storage with complete audit trail
- Integration with tracker fetching pipeline
- Complete end-to-end delivery detection workflow
Test Scenarios:
- Tracker entering delivery location triggers entry event
- Tracker exiting delivery location triggers exit event
- Tracker moving between storage and delivery locations
- Low accuracy locations skipped for detection
- Stale locations skipped for real-time processing
- Events stored with complete location and timing data
- Batch processing of multiple trackers
Quality Metrics
- Test Coverage: >80% for all real-time geofence components
- Function Complexity: ≤10 cyclomatic complexity per function
- Function Length: ≤15 lines per function (following Cline standards)
- No SQL Injection: All queries use parameterized statements
- No Hardcoded Values: All configuration externalized
Performance Considerations
Efficient Processing
- Batch geofence checks: Process multiple trackers efficiently
- Minimal database queries: Reuse location queries where possible
- Accuracy filtering: Skip processing for poor quality locations
- State caching: Maintain tracker geofence state for quick exit detection
Scalability
- Asynchronous processing: Can be moved to background tasks if needed
- Database indexing: Optimized indexes for geofence queries
- Memory efficiency: Process locations individually, not in large batches
- Error isolation: Failed processing doesn't affect other trackers
Monitoring and Observability
Key Metrics
- Events per hour: Number of geofence events detected
- Processing latency: Time from location fetch to event detection
- Accuracy filtering rate: Percentage of locations skipped due to poor accuracy
- Status change rate: Percentage of events that trigger status changes
Logging
- Event detection: Log all entry/exit events with context
- Accuracy filtering: Log skipped locations with reasons
- Processing errors: Log failures with tracker and location details
- Performance metrics: Log processing times for optimization
Future Enhancements
Phase 4 Considerations
- Real-time notifications: Immediate alerts for delivery events
- Dwell time detection: Events for trackers staying in geofences
- Geofence analytics: Patterns and insights from event data
- Machine learning: Predictive delivery timing based on movement patterns
Integration Opportunities
- Webhook notifications: Real-time delivery notifications to external systems
- Dashboard updates: Live status updates in admin panel
- Customer notifications: Automated delivery confirmation messages
- Analytics pipeline: Feed events into business intelligence systems
Deployment Notes
Prerequisites
- PostGIS extension enabled in PostgreSQL
- Database schema updates applied
- Real-time geofence service integrated with tracker fetcher
Configuration
- Accuracy thresholds configurable per environment
- Geofence detection can be enabled/disabled per tracker
- Event storage retention policies configurable
- Processing timeouts and error handling configurable
Rollback Plan
- Real-time detection can be disabled without affecting existing functionality
- Fallback to existing aggregation-based geofence detection
- Event data preserved for analysis and debugging
- No impact on core tracker fetching functionality