A rewrite is not a code project. It's a stretch of time where two systems both believe they own the same state.
So the questions worth asking first are rarely about the code.
-
What writes money state today, and will both systems write it during the cutover? If that's yes even for an hour, idempotency keys and version-checked writes come before line one of the new service.
-
What runs with no user in front of it? Cron jobs, retry sweepers, reconciliation batches. The parts with no click path are the parts that get forgotten in the port, and in payment systems those are usually the parts quietly correcting errors.
-
Who consumes your side effects? Webhooks, notification fan-outs, exported files, signed documents. Downstream consumers are a public API you did not write down, and they won't upgrade on your schedule.
-
What is the rollback, concretely? If going back means replaying writes the old system did not see, you don't have one. You have a one-way door you haven't labelled yet.
-
How do you prove equivalence while both are alive? Shadow the reads, compare outputs, reconcile balances daily. Equivalence gets measured, not asserted in a design doc.
My take: the only rewrite you can do safely is the one you can stop halfway. Each question above is really asking whether halfway is a state you survive.
Most rewrites I've seen go wrong didn't fail at writing the new code. They failed in the weeks when both systems were real.
If you're planning one, I'd start by listing what writes to your core tables without being an HTTP request.