Local first
Catalogue, carts, sales and shifts live in the browser’s IndexedDB, so a refresh never loses a sale.
Exactly once
Each operation has an idempotency key. Re-sending it can’t create a second sale.
Visible conflicts
If stock changed elsewhere, you choose how to reconcile. Nothing is overwritten silently.
Honest limits
Cash works offline. Card authorisation, online orders and remote search need a connection.
States you’ll see
Always clear what’s happening.
- OnlineSales sync in the background within seconds.
- OfflineA banner shows; sales queue locally with their own receipt numbers.
- ReconnectingThe register checks the connection before sending anything.
- SyncingA progress bar shows the queue draining.
- ConflictA stock mismatch waits for a person to decide.
- Sync errorA failed batch stays queued and can be retried.
- SyncedEverything acknowledged; last sync time shown.
In this prototype
What’s simulated.
There is no server. The “remote” is a ledger table in your own browser, and a Demo Network Control lets you cut the connection, inject a stock conflict or force a sync error. The service worker caches the app shell in production builds; your data is separate and lives in IndexedDB.
Clearing your browser’s site data deletes demo data. No browser app can promise otherwise.
- Not by default. Real card authorisation requires the network; in this demo a feature flag can allow simulated card tenders offline for testing.