The Offline Queue That Lost Three Inspections
A field-inspection mobile app lets technicians capture photos and notes in areas with no signal. The app uses a local storage entity for drafts and a client action that saves to the server when connectivity returns. Technicians report that after a full day offline, roughly 3 of 20 inspections vanish. The app was built with a SaveOnDevice-style pattern where each draft is written to local storage, and an OnApplicationResume event triggers a sync loop that uploads everything and then clears the local table. One technician's phone was at 4% battery when the app was killed by the OS. Another closed the app from the task switcher mid-sync. The team cannot reproduce it in the office on Wi-Fi.
1. Explain the most likely cause of the lost inspections and why office testing cannot catch it.
Read the worked answer
The sync loop clears local storage after uploading, but the clear is not transactional with the upload. If the process is interrupted - OS kill on low battery, task-switcher close mid-loop - some records are uploaded and some are not, yet the clear step may still run for the batch that was in flight, or the app may restart with a partially cleared table. The design also assumes OnApplicationResume fires reliably; a hard kill does not guarantee it. Office testing on Wi-Fi completes the loop in under a second, so the interruption window is effectively zero and the bug is invisible. The failure needs an interruption during the upload to manifest, which is exactly what a long offline batch plus a dying battery produces.
2. Redesign the sync so an interrupted upload cannot lose data. Describe the states and the order of operations.
Read the worked answer
Give every draft an explicit status: Pending, Uploading, Synced. Sync loop: (1) select Pending records; (2) mark one record Uploading and persist that mark locally before the network call; (3) call the server; (4) on success, mark it Synced locally, then delete or archive it; (5) on failure or timeout, revert to Pending. Never delete a record until the server has confirmed with a durable identifier. On app start and on resume, run a recovery pass that resets any record stuck in Uploading back to Pending - the server call is idempotent because each draft carries a client-generated GUID, so a duplicate upload is rejected or merged rather than creating a second inspection. This makes every interruption point safe: the worst case is a retry, not a loss.
3. What would you change about how sync is triggered?
Read the worked answer
Do not rely on a single lifecycle event. Trigger sync on: network availability change (connectivity listener), app foreground, explicit user action, and a periodic timer while the app is open. Each trigger calls the same idempotent loop, so overlapping triggers are harmless. Also surface queue depth to the technician - a visible count of pending items with a manual retry button - so a failure is noticed the same day rather than discovered at the end of the week. The 3-in-20 loss rate is partly a visibility failure: nothing told the user the sync had not finished.