There is a category of enterprise software that works perfectly in the demo and fails completely on site. It is usually the same failure: the application assumed a network.
At 1 200 metres below surface there is no signal. On the N4 between Rustenburg and the border there are long stretches with none. In a peri-urban service area a field advisor has one bar and a data bundle they are paying for personally. Software designed in an office with fibre does not survive any of these.
Offline cannot be added later
This is the part teams get wrong most often. Offline support is treated as a feature to add in phase two, and phase two turns into a rewrite.
The reason is that offline changes the shape of everything. Identifiers must be generated on the device, not by the server. Validation must run locally with the rules cached. Every write must be an idempotent operation that can be replayed. Conflict resolution rules must exist for every entity. References between records must survive one of them not having synced yet.
An application built on the assumption that the server is authoritative and reachable has these assumptions distributed through every layer. Removing them is not a refactor.
Last-write-wins is almost always wrong
The default conflict strategy is to take whichever record synced most recently. For a safety inspection this is dangerous: a supervisor's later correction should override a technician's earlier entry, but a technician's later entry should not silently overwrite a supervisor's sign-off.
Conflict rules have to be domain-specific, agreed with the people who own the process, and written down. Anything the rules cannot resolve should surface to a human as an explicit conflict rather than be resolved silently in either direction. Silent resolution is how inspection records quietly lose data for six months before anyone notices.
Sync must be delta, and it must be resumable
A full sync on a metered connection is a real cost to a worker who may be paying for the data. We send changes only, compressed, with a resumable cursor so a sync interrupted at 80% resumes rather than restarts.
On one distribution deployment this took mobile data consumption per driver from roughly 340MB per month to under 90MB. That is a material amount of money to somebody earning a driver's wage, and it changed adoption more than any feature we shipped.
Design for the device people actually carry
The specification says Android 12. The workforce carries a mix going back to Android 9, several with 2GB of RAM, and about a fifth with cracked screens and degraded touch response.
We test on the actual device mix. It changes decisions: smaller image capture, aggressive memory management, larger touch targets, and interfaces that work with a gloved hand in direct sunlight. Contrast ratios that pass WCAG in an office are not always readable on a scratched screen at midday on a highwall.
The test that matters
Before any field application ships, we do the same test: put the device in aeroplane mode, complete a full day's realistic workflow, then turn the network back on and verify that everything arrives correctly and nothing was lost.
It is a simple test. It fails far more often than it should.