Skip to main content

Patient Chart Service — Sync Contract

Status: populated Owner: TBD Last updated: 2026-04-17 Companion: Service Template · 16 Offline & Sync

1. Conflict policy per aggregate

AggregatePolicyRationale
Problemserver_authoritative with lww+diff on non-status attributesClinical record ownership; status transitions serialized server-side
Allergyserver_authoritative with lww+diff on reactions / categoriesSafety-critical; duplicate guard must run at server
VitalsSetappend_only for new sets; corrections create a new versionHistorical integrity; never mutate the wire
Observationappend_onlyMeasurement immutability
ClinicalNote (draft)lww per section body with offline queue up to 48hOffline authoring is supported for field clinics
ClinicalNote (signed/amended)server_authoritative; no offline amendLegal record; server mediates cosign and amendment
NoteAddendumappend_only
ChartAccessappend_onlyAudit trail

2. Offline semantics

  • Vitals and draft notes are the primary offline-capture surfaces on tablet / POC devices.
  • Offline writes are queued with a client-generated ULID and a clientGeneratedAt timestamp. On sync, the server assigns the canonical ULID (or accepts the client ULID after cross-tenant and duplicate guards).
  • Idempotency: Idempotency-Key header required on POST replays; server returns the prior response if the key is known within the dedupe window (24 h).
  • NKA / NKDA assertions are never queued offline; they must be created while online to guarantee the active-set invariant.
  • Signing a note offline is not supported. Draft edits are queued; the clinician must be online to sign.

3. Conflict resolution examples

ScenarioResolution
Two clinicians edit different sections of the same draftBoth retained; merged per section (lww per section); server emits note.updated_draft.v1 once
Two clinicians edit same section offlineLater clientGeneratedAt wins; earlier edit retained as a non-authoritative backup with conflictPreservedId
Offline vitals set + online vitals set at same recordedAtBoth persisted as separate VitalsSet rows; chart timeline shows both with performer attribution
Offline problem add when server already has same code activeReject with CHART_DUPLICATE_PROBLEM; client surfaces merge action
Offline allergy add when NKA active server-sideReject with CHART_NKA_CONFLICT; client shows NKA present

4. Ordering guarantees

  • Intra-aggregate events preserve ordering per (aggregateId, version).
  • Cross-aggregate ordering is not guaranteed; consumers that need order (e.g., population-health rollups) key on (patientId, occurredAt).

5. Vector clocks

Not used. The service uses integer version per aggregate combined with a server-authoritative last-writer-wins tie-breaker for the specific fields marked lww+diff.

6. Backfill

When a previously offline device reconnects with a queued batch older than 30 days, the server marks resulting events with source=offline-backfill in the envelope metadata; downstream consumers MAY apply different rate-limits.

7. Open Questions

  • Should draft-note offline queue be 48 h or 7 days? Current policy: 48 h; extend if field-clinic trials demand.