Integration
1. Sister Services
Direction:→calls /←called by /↔bidir.
| Sister | Direction | Surface | Contract | Auth | Failure Mode | Idempotency |
|---|---|---|---|---|---|---|
@nx/sale | ← | HTTP POST /simulation/calculate (v1) | @nx/pricing/contracts types via PricingNetworkService.calculate() | BASIC (service-to-service) | sale propagates upstream 4xx (e.g. no active fare); throws on network/5xx | request side-effect-free, safe to retry |
@nx/sale | ← | HTTP POST /simulation-v2/calculate (v2) | @nx/pricing/contracts types via PricingNetworkService.calculateV2() | BASIC | same | same |
@nx/commerce | ← | Kafka CDCKafkaTopics.PRODUCT_VARIANT (Debezium) | @nx/core TProductVariantPgRow | — | at-least-once, manual commit | per (productVariantId) |
@nx/identity | → | HTTP — JWT verification via JWKS | JWT (ES256) | retry / Redis cache fallback | per request |
Commerce does not depend on pricing directly. The only commerce → pricing coupling is the
ProductVariantrow landing in the CDC stream that pricing's worker consumes.
2. The @nx/pricing/contracts Boundary
Sale consumes pricing through the dedicated ./contracts subpath export (src/contracts/index.ts), not the package root. The export is mostly export type declarations plus a small set of runtime const containers that sale needs at runtime for snapshot interpretation.
| Kind | Symbols (from contracts) |
|---|---|
| Request types | TSimulationCalculateRequest, TPricingContext, TPricingV2CalculateRequest, TPricingV2ContextRequest, TPricingV2ItemContext, TPricingV2ItemRequest |
| Response types | TSimulationCalculateResponse, TPricingV2CalculateResponse |
| Snapshot types | TAppliedPrice/Tax/Discount/Fee/Rule, TLineItemPricingSnapshot, TOrderPricingSnapshot, TByBearerTotals, TFareSource(Type), TPartyRole, TRuleBasis, TMoney, TCurrencyCode, TTransactionDirection, TSnapshot{Discount,Fee,Tax}Type, TFeeScope |
| Runtime const containers | AppliedRuleSourceTypes, FareSourceTypes, FeeScopes, PartyRoles, RuleBasises, SnapshotDiscountTypes, SnapshotFeeTypes, SnapshotTaxTypes, TransactionDirections |
Verified consumers:
sale/src/services/pricing-network.service.ts— imports the request/response types (import type { ... }) to type its Axios calls.sale/src/services/checkout.service.ts— importsTPricingV2CalculateResponse(type) andTransactionDirections(runtime value, to setdirection: TransactionDirections.SALEon the request and to narrow the snapshot'sbyBearerledger).
This keeps sale free of any runtime dependency on pricing's engine — it ships only erasable types plus a handful of frozen const tables. Sale never mounts pricing as an IGNIS component. See ADR-0001.
3. Critical Cross-Service Flows
3.1 Checkout Pricing Fan-out
Contract:
- Pricing is stateless — it returns the snapshot; sale persists it. Pricing keeps no order record.
- An upstream 4xx (e.g. variant with no ACTIVATED FareSet) is surfaced by sale with the upstream status, not masked as 500.
- v2 is canonical; sale persists the v2 snapshot as the audit/refund source-of-truth.
3.2 ProductVariant CDC → Fare Seeding
4. Contract Stability
| Surface | Stability | Versioning |
|---|---|---|
HTTP /simulation/calculate (v1) | stable, in maintenance | URL /v1/; v2 is canonical for new work |
HTTP /simulation-v2/calculate (v2) | stable | URL /v1/; snapshot envelopes carry their own v: 1 literal |
@nx/pricing/contracts snapshot types | stable | per-envelope v literal (Order / LineItem / per-applied-rule independently versioned) |
Kafka PRODUCT_VARIANT | stable | Debezium schema; field-additive |