# EXIF Scanner β€” Feature Roadmap > Living feature specification document. Covers all proposed features for the photo > upload / OCR / GPS-push app at `~/projects/exif-test/`. **Legend:** βœ… done Β· πŸ’‘ proposed --- ## 1. βœ… Offline Queue β€” Service Worker + IndexedDB ### Use Case Facility audits happen in warehouses, basements, parking lots, and rural sites β€” all places with unreliable or zero cellular signal. Currently if the server is unreachable the app shows nothing useful and queued photos are lost on page refresh. The user needs to "fire and forget": snap photos, move to the next machine, and have the uploads drain silently when signal returns. ### User Experience 1. Open the app β€” service worker installs, page loads from cache instantly 2. If online: everything works as today (live upload via fetch to `/api/analyze`) 3. If offline (navigator.onLine === false or fetch fails): - Photo thumbnails still generate (client-side EXIF via exifr.js works offline) - The gallery, summary, filter chips all work from IndexedDB-local - "Bulk Process" button changes to "πŸ“‘ Queue for Upload (N pending)" - A small banner at the top: "πŸ“‘ Offline β€” N photos queued" 4. When signal returns (online event or periodic background sync): - Queue drains FIFO, one at a time, with retry (3 attempts, exponential backoff) - Banner updates: "πŸ“‘ Syncing… (3/12 remaining)" - On completion: banner disappears, results load from server `/api/photos` 5. Page refresh mid-queue: IndexedDB persists the queue, resumes on next load ### Spec ``` IndexedDB schema β€” "photos-queue" store: { id: auto_inc, file_blob: Blob, filename: string, timestamp: number, retries: number, status: 'queued'|'uploading'|'done'|'failed' } Service worker: - Cache-first strategy for static assets (/, /static/*) - Network-first for /api/* (falls back to cached error page) - Listen for 'sync' events from periodicSync API if available ``` ### Tech - **Service Worker registration** in `