Last-write-wins
Fits the six-week target and the expected single-phone writer pattern for a stock line. It keeps synchronization logic small enough to test deeply before expanding the model.
A local-first Flutter app and Go sync service designed to let small vendors record sales offline all day, then reconcile automatically when connectivity returns.
Small vendors using MTN and Airtel Mobile Money have no easy way to check mobile money transactions against actual stock and sales. Most tools assume the vendor has constant data. At the end of a market day, reconciliation can happen by memory, or not at all.
The core design starts from a harsher assumption: the connection may disappear for the entire period in which the user still needs to work.
The app has to be fully usable for an entire market day, recording sales, updating stock and calculating totals with zero connectivity, then sync cleanly whenever a signal appears for even a few seconds. Kampala's markets have patchy indoor coverage, so the design cannot make a sale wait for the network.
The local database handles the immediate write. The sync state is visible as system status, but it does not block the workflow. The mock interface below visualises that model rather than presenting an implemented product screenshot.
Every write lands on the device first. A local queue retries opportunistically. When connectivity returns, the Go API receives queued operations, checks for conflicts and reconciles them against the server-side PostgreSQL store.
The theoretically stronger conflict model is not automatically the correct product decision. For this first version, implementation cost and the expected writer pattern matter.
Fits the six-week target and the expected single-phone writer pattern for a stock line. It keeps synchronization logic small enough to test deeply before expanding the model.
A more theoretically complete concurrent-editing model, but one that would roughly triple the timeline for a conflict pattern expected to be uncommon in the initial use case.
Two staff phones editing the same item inside the synchronization window can still create real data loss. That scenario is scoped as the first thing to fix in v2, likely with per-field version vectors rather than a general-purpose CRDT.
The multi-device conflict path is the risk that can invalidate the simplistic synchronization model, so the build plan deliberately brings that case forward.