Skip to content
Case dossier  /  Client win

Every bank balance on one screen, with a history that writes itself

One screen answers the cash question in a click, and a daily snapshot keeps the history nobody had time to keep.

20+bank accounts

Brought onto one screen instead of one portal login at a time.

180daily pulls

Of balance history read back into the cash-over-time chart, built automatically.

0false matches

In reconciliation testing against real logged transactions and a synthetic ledger.

$75a month saved

By using the standard accounts call instead of a paid real-time balance product.

01

The problem

The client's finance team ran money through 20 to 25 bank accounts spread across several banks. The question leadership asked most often was also the simplest one: how much cash do we have right now? Answering it meant logging into each bank portal, writing down each balance, and adding them up by hand.

The number was always available in theory. In practice it only got built when someone needed it badly enough to spend the time. Because nobody saved the results, any question about the past ("what did we have last Tuesday?") meant another round of logins. There was no trend line, no record of how cash moved from week to week, and no way to notice a broken bank connection except by spotting a number that looked off.

02

What we built

An internal treasury dashboard with one job: put total cash on a single screen and keep the history without anyone maintaining it.

Total cash across every connected account sits at the top, the account list underneath, and a cash-over-time chart beside it. Banks connect through Plaid, using the consent flow banks already expect. The data lives in a dedicated Postgres database, and the app is a Next.js build on Vercel.

The part that mattered most was the history. Every pull writes a snapshot of every account balance. A scheduled job runs that pull each morning on its own, and a Pull now button covers the days someone wants a fresh number before a meeting. The chart reads back up to 180 pulls, so the day-over-day trend fills in by itself.

Once the balances were reliable, the app took on two more jobs: logging every transaction from the connected accounts, and reconciling those transactions against the client's general ledger.

03

How it works

A handful of design choices do most of the work.

  • Cash means cash. The headline sums deposit accounts only. Credit cards, loans, and investment accounts are pulled and shown, but they never inflate the cash number.
  • Totals reflect what exists now. An early version read the headline from a stored roll-up, and after a bank was disconnected it kept showing money from accounts that were gone. The total is now computed from the latest snapshot of each account that still exists, so a disconnect corrects the headline immediately.
  • Broken connections are loud. When a bank connection fails (a changed password, an expired consent), that bank flips to "needs attention" instead of quietly showing a stale balance.
  • The API call matches the decision. Real-time balance checks are sold as a separate paid product. A once-a-day snapshot does not need them, because the standard accounts call returns the same balance fields. That one swap saves roughly $75 a month at this bank count.

Bank data raises the security bar, and the bank aggregator's production review makes you prove it. The app moved from a single shared password to per-person accounts with hashed passwords and an emailed one-time code as a second factor, plus an admin-only page to add people and reset access. Bank access tokens never reach the browser, and disconnecting a bank revokes it at the aggregator before deleting it locally.

Reconciliation is deliberately conservative. The ledger export is uploaded as a CSV and parsed in the browser, so the ledger never touches the server. The matcher pairs exact reference-and-amount matches first, then unique amounts within a date window, and hands everything else to a person. The report sorts into matched, needs review, bank activity with no ledger entry, and ledger entries that have not cleared.

04

The result

"How much cash do we have" is now one click, and the answer comes with its own history. Nobody logs into a stack of portals to build the number, and the trend exists because the system writes it every morning, not because someone remembered to.

The app was verified in production against a live bank connection. Real transactions were logged on the scheduled pull and displayed correctly, and the sign-in gates were tested from the outside: no session, a wrong password, and an unauthorized email were all refused. In reconciliation testing against real transactions and a synthetic ledger, the matcher produced zero false matches. That is the property that counts, because a reconciliation tool that confidently pairs the wrong items is worse than having none.

Every screen was also checked at phone width. Tables restack into cards on small screens, so balances and amounts stay visible without scrolling sideways.

Read the full build notes: One screen for every bank balance.

Your turn

Same problem? Different industry?

We work with one client per vertical at a time. If your shape matches one of our dossiers, we’ll tell you straight.