Appearance
Event Contracts
Versioned event contracts live in contracts/events/. They define cross-service handoffs; services must not read another service database.
Authoritative files:
contracts/events/README.mdcontracts/events/envelope.schema.jsoncontracts/events/search.projection.changed.v1.schema.json
Core Rules
- Every event uses the shared envelope schema.
- Consumers persist source event identity so replay is idempotent.
- Payment, billing, wallet, and usage remain separate owners:
payment-serviceemits payment outcomes,billing-serviceowns subscriptions and entitlements,wallet-serviceowns AZ Credit ledger mutations, andusage-servicematerializes quota/feature-gate snapshots. - IAM owns permission-bearing organization membership events; organization services keep read models only.
search.projection.changed.v1carries copied-index updates only. Its ownersourceVersionprevents out-of-order events from overwriting a newer index row or resurrecting a delete tombstone; it does not transfer canonical data ownership to search-service. Question Bank has an opt-in JetStream publisher and Search has a matching opt-in subscriber onSEARCH_PROJECTIONS/search.projection.changed.v1; both are disabled by default. Course, exam, and document still use pull rebuilds until their owner outbox and replay proof are added.
Monetization Chain
The current monetization handoff is:
payment.order.paid.v1frompayment-service.billing.subscription.activated.v1frombilling-service.billing.entitlements.updated.v1frombilling-service.- Wallet consumes top-up and subscription-credit events.
- Usage consumes entitlement snapshots.
Broker mode uses NATS JetStream stream MONETIZATION with subjects monetization.payment.order.paid.v1, monetization.billing.entitlements.updated.v1, and monetization.billing.subscription.activated.v1. Payment and billing publishers are opt-in; HTTP event endpoints remain fallback until wallet/usage subscribers and route rollback evidence exist.
Verification:
bash
make test-monetization-event-chain
make test-monetization-routesPublic wallet, payment hook, subscription, and quota routes stay legacy until a route rehearsal, browser/runtime proof, and rollback notes exist.