Context
A convenience-store chain was replacing its monolithic point-of-sale system with microservices.
The services talk over MQTT. I was a senior developer on a team of about 15, consulting through Momentum3, and I owned money orders end to end, from business rules to printing on real store hardware.
- Conductor
- Coordinates a sale across the other services.
- Transaction
- Totals the sale and records each money order.
- Hardware
- Drives the money-order printer at the counter.
- UI
- Shows the cashier what happened and what to do next.
Problem
Printing is slow and can fail partway, and the old flow had no clean way back.
Totaling the transaction waited on the printer, so the register sat blocked during every print. When a print failed, the failure tangled with the normal path. In payments, a failure can’t leave the customer charged for a document they never got.
Options
I weighed keeping printing inside the transaction against splitting the flow into steps that each recover on their own.
Decision
I redesigned the flow in the conductor service as a saga.
- Totaling continues while printing runs asynchronously.
- The print timeout scales with the number of documents, so a large order isn’t cut off early.
- Failed prints go down their own path and trigger an automatic refund transaction.
- A low-document alert warns the store before the printer runs out.
Outcome
A failed print now refunds the customer automatically, in the same flow.
Money orders shipped with configurable limits, no refunds after printing, employee-ID verification, and fees as sub-line items.
What I'd tell an interviewer
- 01
The design question was "what happens when step three fails?"
The saga answers that before anyone asks. Each step knows how to recover, so a failure never falls through to the happy path.
- 02
I started with the easiest test, not the hardest.
Writing out every branch first, then testing from the top down, got me unstuck when the hardest test kept stalling.