Offline Ledger PWA
This walkthrough shows the shape of an offline-first ledger app for field teams, chamas, rent collection, or SME records.
Product Promise
- Users can open the app after first load.
- Users can create entries while offline.
- Entries show as pending until synced.
- Users can export local records if sync is blocked.
- The app does not promise background sync will always run.
Flow
flowchart TD
open[Open app] --> readLocal[Read IndexedDB]
readLocal --> render[Render ledger]
render --> create[Create entry]
create --> saveLocal[Save entry and outbox item]
saveLocal --> trySync{Online now?}
trySync -->|Yes| send[Send with idempotency key]
trySync -->|No| pending[Show pending state]
send --> result{Server accepted?}
result -->|Yes| markSynced[Mark synced]
result -->|No| pending
pending --> retry[Retry on reconnect or app open]
retry --> send
Implementation Shape
| Part | Design |
|---|---|
| Manifest | Stable id, standalone display, maskable icon |
| Service worker | Precache shell, navigation offline fallback, versioned caches |
| Data | IndexedDB object stores for entries, outbox, syncState |
| Writes | Client-generated IDs and idempotency keys |
| Sync | Foreground retry, optional Background Sync registration |
| Recovery | Export local JSON/CSV before clearing data |
| Tests | Offline create, reload, reopen, retry, duplicate replay |