Image Upload and Processing Flow
This document explains the complete end-to-end flow of how test strip images are captured, uploaded, and processed in the Eli Health platform.
Overview
The image upload process involves multiple services working together to capture, upload, analyze, and provide results for hormone test strips. The flow utilizes Firebase for temporary storage, Google Cloud Storage for permanent storage, PubSub for asynchronous processing, and the Health Analysis Engine (HAE) for image analysis.
Architecture Components
Mobile App (React Native)
- Captures test strip images using the device camera
- Detects and validates QR codes on test strips
- Uploads images to Firebase Storage
- Monitors processing status and displays results
Backend API (NestJS)
- Receives upload notifications from mobile app
- Copies images from Firebase to GCS
- Publishes messages to PubSub for processing
- Manages reading records in PostgreSQL
PubSub Messaging
- Asynchronous message queue for background processing
- Topics:
reading-analysis-caandreading-error-ca - Ensures reliable processing with retry mechanisms
Health Analysis Engine (HAE)
- External service for image analysis
- Processes test strip images to extract hormone values
- Returns quantitative results and recommendations
Detailed Flow
Step 1: Image Capture (Mobile App)
Key aspects of image capture:
- QR Code Detection: Validates hormone type (Cortisol/Progesterone)
- Quality Checks: Ensures proper lighting, distance, and angle
- Auto-rotation: Ensures images are in portrait orientation
- Firebase Upload: Temporary storage in
tempImages/{userId}/{date}/path
Step 2: Backend Processing Initiation
Request payload structure:
{
"epochDate": 1758759730,
"storagePath": "tempImages/userId/2025-09-25/cortisol_1758759728419_sud0asz.jpg",
"qrCodeString": "C8",
"qrCodeCoordinates": {
"x1": 1414, "y1": 2505,
"x2": 1628, "y2": 2511,
"x3": 1411, "y3": 2295,
"x4": 1631, "y4": 2299
},
"wakeupTime": "2025-09-24T08:00:00-04:00",
"timeZone": "2025-09-24T20:22:10-04:00",
"hormone": "cortisol",
"tags": "tag1,tag2"
}
Step 3: Asynchronous Analysis
HAE Request includes:
- Image URL from GCS
- Historical readings for context
- QR code coordinates
- Wake-up time for cortisol circadian rhythm
- Period history for progesterone
Step 4: Client Polling and Result Display
Error Handling
Error Recovery Mechanisms
- Dead Letter Queue: Failed messages after 5 retries
- Retry Policy: Exponential backoff (1s to 600s)
- Fallback Values: Hardcoded results for demo accounts
- Cleanup: Automatic deletion of temporary Firebase files
Complete System Flow Diagram
Performance Optimizations
Mobile App
- Smart Capture Mode: QR detection with quality validation
- Auto-rotation: Ensures correct image orientation
- Retry Mechanism: Handles camera connection errors on newer iPhones
- Device-specific Settings: Optimal camera configuration per device model
Backend
- Server-side Copy: Efficient GCS-to-GCS transfer
- Parallel Processing: Async PubSub handling
- Connection Pooling: Optimized database connections
- Trace Context: End-to-end request tracking
Infrastructure
- CDN: CloudFlare for static assets
- Regional Buckets: northamerica-northeast1 for low latency
- Auto-scaling: Cloud Run scales based on load
- Caching: 15-minute cache for frequently accessed data
Monitoring and Observability
Trace IDs
Every request is tracked with a unique trace ID that flows through all services:
x-cloud-trace-context: Google Cloud trace formatx-eli-trace-id: Custom trace ID for internal trackingx-eli-span-id: Span ID for distributed tracing
Key Metrics
- Upload Success Rate: Target >95%
- QR Detection Rate: Target >95%
- Processing Time: P95 Less than 15 seconds
- Error Rate: Target Less than 1%
Log Correlation
All logs include:
traceId: For request correlationreadingId: For reading-specific trackinguserId: For user-specific debuggingtype: For categorizing log events
Security Considerations
- Authentication: Firebase Auth + JWT validation
- File Access: Signed URLs with 15-minute expiration
- Data Isolation: User-specific paths in storage
- Cleanup: Automatic deletion of temporary files
- Encryption: TLS for all API calls
- RBAC: Role-based access control for resources
Troubleshooting Guide
Common Issues
-
"No active video connection" error
- Occurs on iPhone 16/17 with iOS 18+
- Solution: Retry with connection stabilization delay
-
QR not detected
- Check lighting conditions
- Ensure QR code is flat and unobstructed
- Verify QR format matches expected pattern
-
Upload failures
- Check network connectivity
- Verify Firebase Storage permissions
- Ensure storage quota not exceeded
-
Processing timeouts
- Check HAE service health
- Verify PubSub subscription active
- Review dead letter queue for failed messages
Future Improvements
- WebSocket Updates: Real-time status updates instead of polling
- Edge Processing: On-device ML for faster QR detection
- Batch Processing: Multiple test strips in one session
- Offline Mode: Queue uploads when offline
- Progressive Upload: Stream image while capturing