An offline draft can be submitted later, but the server may have changed in the meantime. A sync request should include the version the editor saw and an idempotency key. The server checks permission at sync time, compares versions, and either commits or returns a conflict with enough safe context for reconciliation. Automatically taking the last arriving value can erase another person's work. Some fields can be merged mechanically; a free-text inspection note usually needs a user decision or an append-only model. Preserve the local draft until the result is known.
Offline Sync and Conflict Policy
Working case
Reviewer 29 edits case 47 from version 12 while disconnected. Reviewer 31 approves the case on the server, producing version 13. When reviewer 29 reconnects, the old draft arrives with expected version 12. The server returns 409 and the current version, and the UI shows both the draft and the new status. The reviewer may append the note as a new inspection if policy allows, or discard it. The code models the version check only; a real service must perform comparison and write atomically with authorization.
Implementation
function acceptDraft({ expectedVersion, currentVersion, note }) {
if (expectedVersion !== currentVersion) {
return { status: 409, currentVersion };
}
if (!note.trim()) return { status: 422 };
return { status: 201, version: currentVersion + 1 };
}
console.log(acceptDraft({ expectedVersion: 12, currentVersion: 13, note: "seal checked" }).status);
console.log(acceptDraft({ expectedVersion: 13, currentVersion: 13, note: "seal checked" }).version);Observed output
409
14Cost and boundaries
Version comparison is O(1), but a conflict can require an extra read and a human decision. Keeping local drafts consumes storage until confirmation or discard. Automatic merge logic adds complexity proportional to the data model; do not build a general merge engine for a small append-only workflow. Repeated retries should carry one stable idempotency key so a delayed response cannot create duplicates. Monitor conflict frequency to find workflows that need better collaboration design.
Common Mistakes
- Do not let last arrival silently overwrite a newer edit.
- Do not drop a local draft after a 409 response.
- Do not bypass current server permission because a draft was once allowed.
Connected lessons
Offline and Device Capabilities; Service Worker Offline Fallback; IndexedDB for Local Drafts; Web App Manifest and Optional Installation; Browser storage: save convenience data without storing credentials; Fetch requests: separate HTTP failure, transport failure, and cancellation; HTTP caching: validate a changed representation with an ETag.
Failure trace
Two reviewers edit the same case note from version 12. One saves online; the other reconnects with an offline draft and overwrites the newer text because the server accepted a blind update. Send the draft's base version with the write. On mismatch, preserve both versions and ask for a deliberate merge or choose a field-specific rule; never silently discard the unsynced work.
Verification
- Create two drafts from one base version, commit one, then replay the other and expect a conflict.
- Verify the conflict response contains enough safe context to compare the two versions.
- Retry an unchanged queued request and ensure it cannot apply twice after a timeout.
Decision note
Last-write-wins can be reasonable for replaceable preferences. It is a poor default for substantive notes or records with audit requirements; the conflict rule should follow the value of the data.
Apply and check
Build Project: offline inspection draft and photo intake; then check the boundary with Web Development: offline and delivery contracts quiz.
Further connections
Cross-Tab and Offline Data Coordination; Offline Outbox, Idempotency, and Replay.
