Skip to main content

Billing Service — Sync Contract

Status: populated Owner: Platform Engineering Last updated: 2026-04-18

1. Per-Aggregate Policy

AggregatePolicyRationale
BillingEventserver_authoritativeImmutable after insert; clients read via usage query API
PricingTableserver_authoritativeAdmin-managed; versioned history maintained server-side
OperatorCostserver_authoritativeAdmin-managed
Invoiceserver_authoritativeCron-generated; download via presigned S3 URL
UsageSummaryserver_authoritativeInternal; not exposed as a resource

2. Offline Behavior

No offline client path exists for billing. All reads require a live HTTP request to the REST API.

3. Event Consumption Ordering

billing.events messages for the same accountId may be delivered out of DLR timestamp order (NATS does not guarantee per-account ordering). Usage summaries are UPSERT-based and commutative — ordering does not affect correctness of aggregation. billing_events rows are independent (no inter-row ordering dependency).

4. Replay Tolerance

  • billing.events redelivery: ON CONFLICT (message_id) DO NOTHING ensures idempotent ingestion.
  • billing.invoice.generated publication: if cron crashes after PDF upload but before NATS publish, re-running the cron detects status=DRAFT and re-publishes.
  • Usage summary idempotency: NATS dedup window (5 min default) + ON CONFLICT DO UPDATE SET ... = ... + EXCLUDED... is NOT idempotent by default — guarded by billing_events unique constraint ensuring each messageId produces exactly one usage summary update.