SPKPPSU Field Reporting
The setting
Village field officers record infrastructure and sanitation inspections on paper, then retype them at the office days later. By then the data is stale and the handwritten originals are often lost. A plain web form fails immediately in the field, because the areas being inspected frequently have no usable signal.
Sync contract
The design assumes the network is absent, not just slow. Every write lands in local storage first and counts as successful the moment it is durably on the device. Upload is a separate concern that retries on its own.
Three rules shaped the sync layer. Writes never block on the network. Conflicts resolve toward the most recent field entry, because a retyped office version is less accurate than what the officer saw on site. The officer can see what has and has not reached the server.
Records queue in IndexedDB and a service worker handles background sync when connectivity returns. Each record carries a client-generated UUID and a monotonic local revision, so replays are idempotent. A flaky connection that fires three sync attempts does not create three inspections.
What held up
The app runs in airplane mode with no visible difference in responsiveness. Queued records survive a page reload and, because the service worker keeps the queue, a device restart as well. On the admin side, a monitoring view shows submissions as they arrive, flags officers holding records older than a configurable threshold, and filters by village sector.
Two lessons came out of it. Retrofitting a sync queue onto a form built around a live server means rewriting the whole data layer. The first version put optimistic UI on request-based state, which fails exactly where this app is supposed to work. Writing the sync contract down before implementing it also mattered more than expected, because most integration bugs came from ambiguous assumptions about ordering, not from code defects.