A Banking API Is Not Just CRUD: What Building a Money-Movement Ledger Taught Me

I thought a banking API would be mostly CRUD. Make an account. Read a balance. Update a row. I had built dozens of APIs before this one. The pattern felt familiar.

Then I moved real money, and everything I thought I knew started breaking.

The Moment CRUD Thinking Collapses

The first sign of trouble was a race condition I could not reproduce consistently. Two requests hitting the same account at nearly the same time, both reading the same balance, both deciding there were sufficient funds, both completing. The account went negative. No error was thrown. The database was in a perfectly consistent state that was also completely wrong.