Insights23 March 2026Updated 26 October 20264 min read

Offline-First State Management: Building Data Continuity for Compliance

A glowing digital tree with roots on a hexagonal base, displaying the text 'DATA ROOTS: OFFLINE & RESILIENT CONTINUITY ASSURED' in blue tones.

For offline compliance records, we recommend treating a local save, server acceptance and approval as different events. Design the application so that someone reviewing an inspection can tell which event has happened, what remains outstanding and who needs to act. This is an engineering recommendation, not an assessment that a particular workflow meets its legal obligations.

The storage boundary matters even before synchronisation starts. The Indexed Database API 2.0 specification requires a committed transaction's changes to be written atomically, with none written if an error prevents completion. For a browser implementation, we recommend using that transaction boundary to save an inspection alongside its pending submission, rather than updating them independently.

Define what each state proves

Start with a hypothetical inspection that a worker records without a connection. We would distinguish an editable draft from a locally saved observation, then record whether the server accepted it and whether an authorised reviewer approved it. Give each transition an explicit trigger and a visible description, rather than making a single green icon represent the whole process.

For example, show “saved on this device” only after the local transaction reports completion. Show “accepted by the server” only after the application receives and records the corresponding acknowledgement. Keep approval separate, with its own decision and reviewer, rather than deriving it from successful transmission. These labels are proposed product rules, which the team should agree with the people responsible for the workflow.

Our earlier article on Redux and MobX for field apps covers the choice of interface state model. Here the question is narrower: what evidence should support each change in the inspection's status?

Save the record and the outstanding work together

A bright record cube and a small queued packet sealed together in one glass capsule on a device

Use a stable inspection identifier and record the revision being submitted. In our proposed design, the local transaction stores both the observation and a durable entry describing the outstanding submission. On restart, reconstruct the submission list from those stored entries rather than from an in-memory counter. Keep a failed save distinct from a saved record waiting for a connection.

This distinction needs a failure path, not only a success banner. IndexedDB explicitly allows transaction failure because of storage quota limits or input/output errors. We recommend showing the failure and retaining the user's editable work where possible, without labelling it as durably saved. Test the chosen storage implementation on the devices and browsers the organisation actually supports.

Agree a separate response for device loss before synchronisation. For records held only on that device, our recommendation is to document the exposure and the recovery procedure rather than describe local saving as a backup strategy.

Make server acceptance conditional

A packet of light reaches a server gate that checks it before a confirmation ring lights up

We recommend checking an inspection submission against the server’s current record, rather than accepting the device’s status as authoritative.

For concurrent edits, HTTP's If-Match precondition supports checking an entity tag before applying a change and is intended to prevent accidental overwrites. We recommend retaining the version the worker edited and using the API's agreed precondition mechanism when submitting it. If another accepted change makes the request stale, preserve the submitted observation and present a resolution task rather than silently replacing either account. Define who can resolve that task and what explanation they must record.

Also test a submission whose server response disappears after processing. Keep the request identity and the unresolved acknowledgement state available for reconciliation. Specify how the server recognises a repeated submission and returns its recorded outcome, then test that behaviour rather than assuming retries are harmless.

Keep corrections and decisions traceable

NIST SP 800-53 Revision 5, control AU-3, identifies audit record content including event type, time, source, outcome and associated identities. Use those categories as a technical checklist when deciding which events to record for an inspection. For this workflow, we recommend recording local capture, server acceptance, rejection, correction and approval as distinct event types.

Keep the reported observation time separate from the server receipt time, with labels that explain each field. Where a correction changes an accepted record, retain a link to the earlier revision and the reason for the change. Do not make the reviewer reconstruct that relationship from whichever values happen to be on the current screen.

NIST control AU-9 calls for protecting audit information against unauthorised access, modification and deletion. We recommend reviewing who can amend records, who can manage their history and how those actions are recorded. Treat these controls as design inputs, not as a declaration of UK regulatory compliance.

Test the evidence a reviewer receives

Build an acceptance test around one inspection moving through the proposed states. Interrupt its local save, close the app while submission is pending, and simulate a missing server response. Then introduce a conflicting revision and require an explicit resolution before approval.

For each scenario, inspect the stored record, the outstanding submission and the history presented to a reviewer. Require the interface to distinguish an unresolved outcome from a rejection and from confirmed acceptance. Record the expected result before running the test, including who owns any recovery work. We would use that evidence to decide whether the workflow is ready, rather than treating a successful reconnect as the acceptance criterion.

Update, October 2026

For teams using agents to change this workflow, we recommend supplying the transition rules and failure cases before implementation starts. Our engineering article on grounding packs describes giving agents dated context, explicit gaps and a duty to check load-bearing claims against code. Apply that approach here by giving the implementer and reviewer the same definitions of local saving, server acceptance and approval.

Sources

Want this in your team?

Tell us what you're building and where you want to get to, and we'll think it through with you.

Let's have a chat Follow by RSS →

All insights →