DEV Community

Son Do
Son Do

Posted on

For Review: Matching Plaid Bank Feeds Without Duplicate Ledger Entries

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

A bank feed line arrives from Plaid. Same amount, same day, same account as
a payment the firm already recorded in MyCase. If Accounting posts the feed
line as new activity, the ledger now has two entries for one real-world
movement of money.

That collision is the opening problem for bank sync in a practice-management
product. Firms are not starting from an empty book. Trust deposits,
operating payments, and invoice-linked transfers often exist in-system
before the bank feed catches up. Naive import is how you invent duplicates.
This post is about the For Review queue we built so feed lines could be
matched, categorized, split, or excluded -- and about the trust-side rule
that refuses to categorize at all.

For Review as the control plane

Unmatched bank transactions land in For Review. From there the firm can:

  • Categorize -- map the line to a GL account, including via firm-authored rules
  • Match -- link the line to an existing MyCase record
  • Split -- allocate across multiple accounts
  • Exclude -- leave it out of the books

When the action is done, the transaction moves to Reviewed. That queue is
the control plane for both Plaid feeds and the CSV import path for banks
Plaid does not cover. Same pipeline, different door: upload, preview,
column mapping, confirm, then For Review. The CSV path is a cameo here, not
a second product story. What mattered was not inventing a parallel matcher
for file imports.

On the operating side, user-defined categorization rules are firm-authored
mappings from feed attributes to GL accounts, applied when someone
categorizes (or when a rule can clear the obvious cases). They are
supporting machinery under Categorize, not the spine of the design.

The spine: trust skips categorization

The load-bearing decision is the trust exception.

The rejected alternative was symmetry: treat trust feed lines like
operating feed lines. Categorize them into GL accounts from the bank
description. It looks consistent in a UI mock. It is wrong under the model
in Parts 2 and
3.

Trust-side activity should already exist from firm-recorded deposits,
transfers, and billing-linked posts. The bank is confirming a movement the
firm should already know about. Categorizing trust lines from the feed
creates a second source of truth -- bank narrative inventing trust ledger
reality -- and fights three-way reconciliation and invoice-linked
safeguards.

So trust accounts skip categorization. Operating accounts get Categorize,
Match, Split, and Exclude. Trust gets Match or Exclude. If there is nothing
to match, that is a signal to investigate, not a prompt to invent a GL
category from a Plaid memo field.

For Review: trust path blocks Categorize; operating path allows Categorize, Match, Split, Exclude

Match without double-posting

Match is where the opening collision gets resolved. Linking a feed line to
an existing MyCase record is only allowed when the duplicate-prevention
checks agree: amount, payment method, and account. If they disagree, the
link does not go through. That contract blocks attaching a feed line to the
wrong record and blocks the "close enough" match that double-posts under a
different label.

Match contract: amount, payment method, and account must all agree

I am not going to invent a near-miss war story for this post. The checks
are the story: three fields, all must agree, or you do not attach.

Why this matters for reconciliation

Reviewed feed lines are what make monthly
three-way reconciliation
runnable without someone typing the bank statement by hand. The matching
pipeline auto-matched about 75% of Plaid bank-feed transactions to trust
and operating ledger entries for adopting firms. The remaining queue is the
work -- and because trust cannot be casually categorized from the feed, the
work stays pointed at real exceptions instead of invented books.

Part 5 is the other half
of "the firm already recorded this": posting billing and LawPay events into
the GL at event time so the records Match is looking for exist in the first
place.

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)