Blog ·
A cheque is a state machine
Most systems model a cheque as a row with a status field. That works until someone needs to reverse a state — and then you discover the model was never the field.

Most systems model a cheque as a row with a status field. That works until someone needs to reverse a state — and then you discover the model was never the field.
A cheque received from a customer moves through states: received, deposited, cleared, bounced, endorsed to a supplier, cancelled. Each transition has preconditions, side effects on someone’s balance, and a reverse that isn’t always allowed.
What the status column can’t express
Which transitions are legal. From cleared you don’t go back to received. From endorsed you can’t deposit. A free-text status lets any code write any value, so the rules live scattered across whoever remembered them.
What each transition does to money. Depositing moves an amount into an account. Bouncing reverses that and usually adds a fee. Endorsing transfers the instrument to a supplier’s account. The transition is the operation, not a metadata update.
What happened before. “Cancelled” tells you nothing about whether it was cleared first. You need the history, with dates and who did it — because someone will ask months later.
Modelling transitions changes the shape of the code
Instead of a setStatus called from fifteen places, there are named operations — deposit, bounce, endorse — each validating its own preconditions and writing its own movements and history entry. The invalid transition becomes impossible, rather than merely unlikely.
The general principle
If the field is called status and the object has a lifecycle, the field is a symptom. Model the transitions, and the states fall out of them.
That’s how cheques are modelled in YSY Empresa: every step of the instruments flow is an audited operation, not an update.