Skip to main content

Claims Service — Sync Contract

Status: populated Owner: TBD Last updated: 2026-04-18 Companion: SERVICE_OVERVIEW · Service Template · 02 DDD

Sync Policy Overview

AggregatePolicyConflict Resolution
ClaimRecordserver_authoritativeVersion-based optimistic concurrency
Coverageserver_authoritativeLast-write-wins with updatedAt
EligibilityTransactionappend_onlyImmutable once created; new inquiry creates new record
PriorAuthorizationserver_authoritativeVersion-based
RemittanceRecordappend_onlyImmutable once processed
DenialCaseserver_authoritativeLast-write-wins

server_authoritative Policy

The claims-service is the sole authority for all claim and coverage state. No offline client may mutate these records. All writes route through the claims-service REST API.

Rationale: Claims and coverage data carry financial and regulatory consequences. Concurrent offline edits could produce duplicate claim submissions or invalid coverage states.

Optimistic Concurrency (ClaimRecord)

ClaimRecord uses an integer version field for optimistic locking on state-transition operations.

Update flow:

1. Client fetches claim: { claimId, version: 3, status: "ready" }
2. Client submits: PATCH /api/v1/claims/:id with X-Version: 3
3. Server checks: claim.version == 3 → proceed
4. Server increments version to 4, saves
5. If version mismatch → 409 CONFLICT with current resource body

Clients must:

  • Store the version returned with each GET or mutation response
  • Include X-Version: <n> on any state-transition PATCH
  • On 409, re-fetch the resource, resolve locally, and retry

append_only Policy (EligibilityTransaction, RemittanceRecord)

Once created, these records are immutable:

  • EligibilityTransaction: A new inquiry always creates a new record. Old results are never updated in place; they expire via expiresAt.
  • RemittanceRecord: Once processedAt is set, no mutations are permitted. Corrections require a manual void+repost workflow via admin operations.

Downstream Consumer Guidance

Services consuming claims events (billing-service, patient-portal-service, population-health-service) should:

  1. Idempotency: Use the CloudEvents id (outbox record ID) as an idempotency key. Re-processing the same event must be a no-op.
  2. Event ordering: Events are produced in order within a single claim's lifecycle. Consumers that depend on ordering should use the time field for sorting within a given claimId.
  3. Stale reads: Query projections derived from events may lag the source of truth by the relay latency (typically < 1s). Consumers needing authoritative state must call the claims-service API directly.

FHIR Sync

FHIR R4 resources (Claim, Coverage, ExplanationOfBenefit, etc.) are generated views over the internal data model. They are read-only from external consumers. The canonical state is always the internal Postgres record. FHIR resource IDs are stored in the internal record (fhirClaimId, fhirCoverageId, fhirEobIds) for traceability.