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
| Aggregate | Sync Policy | Rationale |
|---|---|---|
VirtualSession (live) | server_authoritative | Real-time session lifecycle managed by server; no client-side session state mutations |
VirtualSession (optimistic lock) | lww with version check | Client must pass current version; 409 on stale version; client reloads |
VirtualSessionParticipant | server_authoritative | Participant status driven by server-side events; clients observe only |
TenantVirtualCareConfig | server_authoritative | Admin-level writes; server is sole writer |
AsyncVisit | append_only + client_mutation_id idempotency | Patient 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:
- Offline draft: Patient/provider authors visit content locally (chief complaint, attachments).
- Queue: Local queue stores draft with
clientMutationId(stable UUID, set at creation time). - Submit: On connectivity,
POST /api/v1/virtual-care/async-visitswithclientMutationId. - Deduplication: Server's
UNIQUE (tenant_id, client_mutation_id)constraint makes duplicate submits safe. - 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.