Designed an offline-first Kanban for vehicle repairs with ERP integration.
When the internet blips, work shouldn’t.
Browser DB + background sync made it boringly reliable.


Key2Key was the first project where I went all-in on the “offline-first, browser-native, server-light” philosophy. The mission was simple: give vehicle repair centres a real-time job board that didn’t collapse every time someone’s Wi-Fi hiccuped. In practice, that meant re-imagining what a web app could be — not as a website that needs a network, but as a local tool that occasionally syncs.


The problem I was solving

Most collision-repair management tools were server-bound. Every status update, quote upload, or parts request meant another round trip to a data centre. On a bad day, a repairer would change a job status to “in paint,” wait five seconds, refresh, get an error, then try again. Multiply that by 30 techs, and you’re staring at a workflow bottleneck disguised as “just latency.”

So the Key2Key PWA flipped that model: let the browser be the engine, not just the dashboard.

  • All job data lives in IndexedDB, mirrored with the backend when possible.

  • Service Workers queue updates for later if the connection drops.

  • Photos, notes and time records are captured offline, then synced in the background.

  • ERP sync (Dynamics 365 BC / NAV / Key2Key) happens in batches — not every click.

When it reconnects, the app quietly reconciles differences — users just keep working.


Why a PWA?

Because workshops are noisy, dusty, and often network-dead zones. Asking every technician to open Chrome tabs with login redirects and 30 MB dashboards was a non-starter.
PWAs solved that elegantly: installable on desktop or mobile, fast startup, full-screen, persistent storage, no App Store gatekeepers.

It follows what Google’s DevRel team has been saying for years: PWAs are no longer the fallback — they are the modern standard for enterprise apps. (web.dev)

In Key2Key’s case:

  • The average load time dropped from ~9 s to < 2 s after the Service Worker cache.

  • Offline edits (photo upload + job status) persisted for hours during network outages.

  • Sync conflicts were auto-merged or surfaced clearly in the UI.

It wasn’t glamorous, but it worked — boringly well, and that’s the goal.


Architecture snapshot

graph TD
A[Technician PWA] –>|local updates| B[IndexedDB]
B –>|background sync| C[Sync Queue]
C –>|WebSocket / REST| D[Coordination Server]
D –>|batch| E[(Dynamics 365 BC API)]
D –>|push| F[Other PWAs]

And a small code snippet for the sync logic:

// Service Worker background sync registration
self.addEventListener(‘sync’, event => {
if (event.tag === ‘sync-jobs’) {
event.waitUntil(uploadPendingJobs());
}
});

async function uploadPendingJobs() {
const jobs = await localDB.getAll(‘pendingJobs’);
for (const job of jobs) {
await fetch(‘/api/jobs’, { method: ‘POST’, body: JSON.stringify(job) });
await localDB.delete(‘pendingJobs’, job.id);
}
}

This pattern became the backbone for later apps (Snap App 2025, Scaffold, etc.): optimistic UI, local queue, quiet sync.


Real-world validation

  • Workshops running multiple repair bays reported zero downtime even during ISP outages.

  • Fleet clients saw job statuses update faster because sync batching reduced server contention.

  • Insurers could view job progress in near real-time via webhooks or scheduled syncs.

  • Most importantly, technicians actually liked using it — no more “I’ll update it later” excuses.

Other companies are discovering the same. A 2025 report on industrial PWAs noted that offline-first design “improves throughput by 20–30 % in field environments where connectivity is intermittent.” (forbes.com)


Lessons learned

  • Offline isn’t a feature — it’s architecture. Build for it from day one.

  • Sync needs design. CRDTs and delta queues are easier to maintain than custom diff merges.

  • Less backend = less fragility. The fewer central points of failure, the smoother the system.

  • Local UX > Global Latency. Instant feedback beats perfect data freshness every time.

I learned that “real-time” is relative: for a workshop, “now or in a few seconds” is real-time enough — as long as the system never blocks the job.


Looking ahead

The next evolution is coupling the PWA with WebRTC for lightweight peer updates: two techs on the same job seeing each other’s card changes instantly, even offline via LAN sync.
I’m also exploring WASM-powered background tasks for photo compression, OCR, and VIN recognition — all client-side, so the app stays fast and private.
And since Dynamics 365 BC APIs continue to evolve, I’ll integrate more event-driven patterns: the ERP as subscriber, not bottleneck.

Final thought

If the web app feels native, works offline, and syncs automatically, the user stops thinking about “the system” entirely. That’s the ultimate compliment.
Key2Key proved a truth I’ve carried into every project since: your app shouldn’t break when the Wi-Fi does.