Features:
- Add cloud sync retry service for failed report uploads
- Automatic retry loop that runs every 30 seconds
- Exponential backoff: 1 attempt per 30s with max 5 retries per report
- Reports always saved locally (IndexedDB) - cloud sync failures don't block user
- SyncInitializer component starts retry loop on app startup
Changes:
- frontend/lib/sync-retry.ts: New service for managing cloud sync retries
- retryPendingSyncs(): Attempt to sync all pending reports
- markForRetry(): Mark a report for retry
- startRetryLoop(): Start automatic retry background task
- stopRetryLoop(): Clean up retry loop on app shutdown
- getPendingSyncCount(): Get number of reports awaiting sync
- frontend/components/providers/SyncInitializer.tsx: Client component that:
- Initializes retry loop only when user is authenticated
- Cleans up on component unmount
- Logs retry service startup/shutdown
- frontend/app/layout.tsx: Add SyncInitializer to root layout
- Ensure retry loop starts automatically for authenticated users
- frontend/app/analysis/page.tsx: Improve error handling
- Log warning when cloud sync fails
- Report remains safely in IndexedDB even if cloud save fails
Impact:
- Reports never get lost even if cloud save fails temporarily
- Automatic retry ensures eventual consistency with cloud
- User experience improved: no more "report deleted" after 1 hour
- Network issues no longer result in data loss
- Addresses original issue: reports now persists locally indefinitely
Technical Design:
- Retry tracking uses in-memory Map (resets on page refresh)
- Future enhancement: could persist retry state to localStorage
- Cloud sync becomes eventual consistency rather than immediate
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>