polycratia

The new service dropped a payment callback because it had never heard of the state the record was sitting in.

I was pulling a payment flow out of an inherited monolith. The data migrated clean. Both systems ran side by side, and traffic moved over in slices.

What I had not accounted for: the work that was already in motion at the moment of the switch.

The old code created records in an intermediate state while it waited for a provider callback. That state appeared in no schema doc and no ticket. It existed only between two steps, and the only thing that knew how to advance it was the old code path. The new service got the callback, saw a record it considered malformed, and did the responsible-looking thing: logged it and moved on.

Nothing errored. No alert fired. The record just sat there, pending, until a user asked why it had not moved.

The expensive part was not the rows I inherited: it was the verbs.

So now, before I start a rewrite, I ask five questions, and all five are about work in flight.

Which states exist only between two steps, and which code is responsible for advancing them?

What is mid-flight at cutover: queued jobs, scheduled retries, callbacks a provider has not sent yet?

Will external events arrive for records the old system minted, and will the new one recognise those identifiers?

When the new path meets a state it does not understand, does it reject, park it for a human, or hand it back to the old path? "Log and continue" is silent data loss with good manners.

How would I notice something stuck rather than failing? Error rates do not catch this. An oldest-record-per-state report does.

A migration photographs the system. Production is a movie, and at cutover half the frame is still moving.

I keep notes on the in-flight checks I run during a cutover on my blog: https://polycratia.com/c/295a8754

If you have cut over a payment or order flow, tell me what was still in flight that you only found out afterwards.

react

$ new-project --brief

or email hey@polycratia.com