Skip to content

Phase 4: Extract Orders

Status: Planned
Prerequisite: Phase 3 (Inventory) stable for 30 days.
Risk: High — event sourcing is a significant departure from the monolith's CRUD model; saga coordination with Inventory and Payment requires both services to be healthy.
Rollback cost: High — EventStoreDB rollback requires replaying to a known checkpoint; saga compensation must be manually verified.


Goal

Extract the Orders domain using event sourcing (EventStoreDB) and saga orchestration. This is the most complex extraction because: 1. The data model changes fundamentally (CRUD rows → event streams). 2. The saga coordinates across two already-extracted services (Inventory) and an external system (Payment Gateway). 3. Historical orders must be backfilled as synthetic events, not rows.


What Changes

Concern Before After
Orders data store Oracle (mutable rows) EventStoreDB (append-only event streams)
Order lifecycle Monolith Java EE Orders Service (TypeScript/Fastify)
Distributed transaction Implicit DB transaction Saga orchestration (reserve → pay → confirm)
/v1/orders/* handler Monolith Java EE Orders Service
Order events None OrderPlaced, OrderConfirmed, OrderCancelled on Kafka

Extraction Sequence

  1. Backfill EventStoreDB: tooling/backfill-orders-eventstore.py reconstructs historical order events from Oracle audit tables.
  2. Projection validation: Verify that reconstructed projections match Oracle order totals to the cent.
  3. Dual-write enabled: Orders Service appends events to EventStoreDB; relay writes to Oracle orders table.
  4. Canary start: Kong routes 1% of /v1/orders/* to Orders Service.
  5. Saga verification: Confirm that stock reservation and payment capture work end-to-end at canary weight.
  6. Canary ramp: 1% → 10% → 50% → 100%.
  7. Dual-write disabled: Oracle orders table becomes stale at 100%.
  8. 30-day stability window: Orders must be stable before Phase 5 (decommission) begins.

Saga Validation at Each Canary Weight

At each weight increase, run the saga integration test suite: - Happy path: place → reserve → pay → confirm - Compensation path: place → reserve → payment failure → release → cancel - Idempotency: duplicate PlaceOrder commands produce one OrderPlaced event (optimistic concurrency)


Go / No-Go Criteria

  • Financial reconciliation: EventStoreDB projections match Oracle to the cent
  • Saga happy path success rate ≥ 99.95% over 24 hours
  • Saga compensation triggers correctly on payment failure (verified by load test)
  • OrderPlaced, OrderConfirmed, OrderCancelled events appearing in Kafka
  • Fulfillment Gateway picking up OrderConfirmed and dispatching to WMS

Rollback

  1. Kong: set /v1/orders/* weight to 0 (monolith receives 100%).
  2. If EventStoreDB has new events not in Oracle: run tooling/sync-eventstore-to-oracle.py to forward-sync.
  3. Trigger: Financial reconciliation divergence > 0, saga compensation failure, or SLA burn rate > 2× for 15 minutes.