Series -- When the Aggregate Looks Right: 0: Overview · 1: Chart of Accounts · 2: Three-Way Reconciliation · 3: The Aggregate Can Lie · 4: Bank Sync · 5: GL Integration
The invoice already exists in MyCase. The LawPay settlement already hit the
payment ledger. Somewhere else -- a spreadsheet, a separate accounting tool,
a second set of books -- someone types the same numbers again.
That re-keying is not a one-off fat-finger story. It is the default
integration pattern when practice management and firm accounting are two
systems of truth. The concrete miss inside the pattern is familiar: a
payment shows as collected in billing, and the books disagree, or the books
never got the line at all. Someone forgot, or delayed, or rounded, or
posted to the wrong place on the second pass.
This post is about refusing that pattern. We integrated existing MyCase
billing, invoicing, and LawPay payment ledger events into MyCase Accounting
GL posting rules on Rails so time, invoices, and trust/operating payments
posted without re-keying.
The rejected alternative: export/import
The easy-sounding integration is a file. Export invoices and payments from
billing. Import them into Accounting on a schedule. Call it done.
Export/import keeps two systems of truth and reintroduces lag. Anything that
can lag can miss. Anything that can miss puts you back in the phone-call
failure mode from Part 0: the
aggregate looks fine until a human notices the gap.
What we shipped instead: auto-post at the billing and payment event. When
the billing layer records the fact, Accounting posting rules write the GL
entries into the
locked chart of accounts
under trust and operating rules. One event, one post, same Rails
transaction boundary where we could keep it honest.
The boundary: ledger-to-GL inside the monolith
There is no romantic microservice story here. Billing and Accounting lived
in the same Rails monolith. The seam was a ledger-to-GL bridge:
- Billing owns the payment and invoice facts.
- Accounting owns the posting rules onto the chart of accounts.
- The contract is prosaic: when billing records X, Accounting posts Y, routed trust versus operating correctly.
That boring boundary matters. It means the invoice identity
Part 3 matches against is the
same invoice billing just wrote -- not a copied row from last night's CSV
that drifted. It means
Part 4 Match has real in-system
twins to link bank feed lines to, instead of an empty ledger waiting on
manual entry.
Firms activate Accounting onto the pre-populated locked chart; posting
rules hang on those system accounts from the first event.
Closing the series
The failure mode at the start of this series was simple and ugly: an
aggregate that reconciled to the cent while a client's money was in the
wrong place.
The path through it was cumulative:
- Lock the chart so auto-post and matching have stable identity.
- Auto-generate client trust ledgers so three-way is real, not optional.
- Flag trust-to-operating movement with invoice-exact matching so reviewers trust every alert.
- Match bank feeds without categorizing trust into a second source of truth.
- Post billing and LawPay events into the GL at event time so the books and the practice stay one system of truth.
Watch closely without destroying the signal. Stop making a human retype the
signal into a second ledger. That is the work.
Series -- When the Aggregate Looks Right: 0: Overview · 1: Chart of Accounts · 2: Three-Way Reconciliation · 3: The Aggregate Can Lie · 4: Bank Sync · 5: GL Integration


Top comments (0)