Skip to main content

Virtual Care Service — Sync Contract

Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 16 offline-first-and-sync

1. Per-Aggregate Conflict Policy​

AggregateSync PolicyRationale
VirtualSession (live)server_authoritativeReal-time session lifecycle managed by server; no client-side session state mutations
VirtualSession (optimistic lock)lww with version checkClient must pass current version; 409 on stale version; client reloads
VirtualSessionParticipantserver_authoritativeParticipant status driven by server-side events; clients observe only
TenantVirtualCareConfigserver_authoritativeAdmin-level writes; server is sole writer
AsyncVisitappend_only + client_mutation_id idempotencyPatient authors content offline; submits when connected; duplicate submits safe via client_mutation_id

2. Async Visit Offline Flow​

The async (store-and-forward) visit is the primary offline-capable pathway:

  1. Offline draft: Patient/provider authors visit content locally (chief complaint, attachments).
  2. Queue: Local queue stores draft with clientMutationId (stable UUID, set at creation time).
  3. Submit: On connectivity, POST /api/v1/virtual-care/async-visits with clientMutationId.
  4. Deduplication: Server's UNIQUE (tenant_id, client_mutation_id) constraint makes duplicate submits safe.
  5. Response: On duplicate submit, server returns the original persisted AsyncVisitDto (same semantics as first success).

Conflict rule: The first submission wins. Subsequent retries with the same clientMutationId are idempotent no-ops.

3. Session Optimistic Lock​

All session mutations (end, cancel, admit) require the caller to pass version in the request body (or as If-Match header). If the server-side version has been incremented by a concurrent operation, the client receives:

{ "statusCode": 409, "code": "OPTIMISTIC_LOCK_CONFLICT", "currentVersion": 3 }

The client must refetch the session and reapply the action if still applicable.

4. Live Session — No Offline Support​

Live video sessions (scheduled → waiting → active) are not designed for offline operation. If connectivity is lost during an active session, the grace-reconnect window (default 60s) applies. If reconnect fails, the session transitions to failed and the InitiateFallbackUseCase is available to open an async messaging thread.

5. Idempotency Headers​

All write endpoints accept Idempotency-Key header. Duplicate requests with the same key within 24 hours return the same response as the original success.