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.