The previous lesson built the accounting model. This one covers the rule that makes it trustworthy — financial records are written once and never changed, and "fixing a mistake" means adding a new correcting entry, not editing the old one.
3 min read
A genuinely common pattern in production ledger schemas is a comment directly on the model definition: "IMMUTABLE — never UPDATE or DELETE." Not a suggestion, not a code-review preference — a constraint the schema itself is documented as depending on. Once a JournalEntry and its JournalLine rows are written and committed, nothing in the application is expected to ever run an UPDATE or DELETE against them again.
If a financial record can be edited after the fact, the ledger stops being able to answer "what did we believe was true at any point in the past" — which is the entire reason a ledger exists in the first place. An editable ledger:
Mistake discovered: a $200 charge was miscategorized as Revenue when
it should have been recorded as a deposit (a liability, since it's
owed back later)
WRONG: UPDATE the original JournalEntry's lines to fix the category
RIGHT: 1. Post a new entry reversing the original
(undoing exactly what the mistaken entry did)
2. Post a second new entry recording it correctly
Result: three entries exist in the ledger forever — the original
mistake, its reversal, and the correction. All three remain visible.
Nothing was erased; the ledger shows the full, honest history of
what actually happened, including the mistake.
This might look wasteful compared to "just fix the wrong number," but the honesty is the point: a ledger that only ever shows the currently-believed-correct state has thrown away the information needed to answer "was this ever wrong, and if so, how did we find out and fix it" — a question audits and investigations ask constantly.
All three entries stay in the ledger forever — nothing is erased.
A common, concrete way to model "this entry corrects that one" without ever mutating the original:
JournalEntry
id
reversedById -- points to the entry that later reversed THIS one,
if any (nullable — most entries are never reversed)
reversesEntryId -- points to the entry THIS one reverses, if this
entry is itself a reversal (nullable)
A correction is simply a brand-new JournalEntry, linked back to the one it corrects via this self-relation — never a mutation of the original row. Querying "what's the real, current picture" becomes "look at all entries, follow the reversal links, and net them out" rather than "trust whatever the single latest edit says."
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. A financial ledger schema is documented with the comment "IMMUTABLE — never UPDATE or DELETE" directly above the model. What does this actually mean in practice?
2. Why does an editable ledger fail to reliably support an audit?
3. A $200 charge was miscategorized in a posted JournalEntry. What's the correct fix?
4. How does a self-referencing reversedById/reversesEntryId pair on JournalEntry let a correction be modeled without mutating the original row?
Payments & Financial Systems