Analytics Service — Event Schemas
Status: populated Owner: Platform Engineering Last updated: 2026-04-18 Companion: APPLICATION_LOGIC · DATA_MODEL
1. Consumed Events
This service publishes no events. It is a pure subscriber.
| Subject | Stream | Producer | Durable Consumer | Purpose |
|---|---|---|---|---|
billing.events | BILLING_EVENTS | billing-service | anlyt-billing-consumer | Cost + volume aggregation |
sms.dlr.inbound | SMS_DLR | dlr-processor | anlyt-dlr-consumer | Delivery status + latency aggregation |
billing.events — sms.billed.v1 (consumed)
interface SmsBilledEvent {
schemaVersion: '1';
eventId: string; // UUIDv4 — used for dedup
messageId: string;
accountId: string;
tenantId: string;
operatorId: string;
segmentCount: number;
costPerSegment: string; // decimal string
totalCost: string; // decimal string
currency: string; // ISO 4217
status: 'BILLED' | 'REFUNDED';
billedAt: string; // ISO 8601
}
Fields used by analytics: eventId, accountId, operatorId, segmentCount, totalCost, status, billedAt.
sms.dlr.inbound.v1 (consumed)
interface DlrInboundEvent {
schemaVersion: '1';
eventId: string;
messageId: string;
operatorId: string;
accountId: string;
deliveryStatus: 'DELIVERED' | 'FAILED' | 'UNDELIVERABLE' | 'PENDING';
errorCode: string | null;
latencyMs: number; // ms between message submission and DLR receipt
tpsSnapshot: number; // operator TPS at time of DLR
receivedAt: string; // ISO 8601
}
Fields used: eventId, operatorId, accountId, deliveryStatus, latencyMs, tpsSnapshot, receivedAt.
2. Idempotency Guarantee
Both consumers use the eventId field (UUIDv4 from producer) to deduplicate in anlyt.processed_events. NATS Nats-Msg-Id header is also asserted equal to eventId in validation.
3. Backfill
If analytics data is lost (e.g. PG partition dropped) and source events are still within NATS stream retention (7 d for BILLING_EVENTS, 3 d for SMS_DLR), a backfill by seeking the durable consumer to a prior sequence number is possible. Backfill idempotency is guaranteed by processed_events — already-processed events are silently skipped.
4. Schema Evolution
- Analytics service is a pure consumer — it must tolerate additive changes to upstream schemas without deployment.
- Destructive changes (field removal, type change) require coordination: analytics updates first (ignores new field), then producer changes, then analytics deploys to use new field.