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.