Cash & treasury
Cash is the only balance sheet account with an independent third party asserting what it should be. That makes it both the most verifiable account and the one where a break matters most.
1. Balances are plural
A single "cash balance" is almost always wrong. There are at least four, and they differ.
| Balance | Meaning | Source |
|---|---|---|
| Book (GL) | What we've recorded | GL |
| Bank current | What the bank has posted | Bank feed |
| Bank available | Posted, minus holds, plus same-day credit | Bank feed |
| Projected | Available, minus scheduled payments, plus expected receipts | Derived |
UI rules:
BalanceCardshows available as the figure and current as a secondary line when they differ. Conflating them is the most consequential copy error in banking UI.- The ledger balance and the bank balance differ legitimately — deposits in transit, outstanding checks. That difference is the reconciliation, not an error.
- Projected balance is a forecast and is rendered as such — dashed on charts, labeled, with the assumptions reachable.
- Every balance carries its "as of" and its source. A cached bank balance shown as current is the most dangerous state in the product;
StaleIndicatorexists for it.
2. Transaction states
pending → posted → reconciled
│ │
│ └─ settled on the bank's books; reaches the GL once coded or matched
└─ visible on the feed, may still change amount or vanish entirely
A pending card authorization is not a transaction. It can settle for a different amount (tips, fuel, hotels) or disappear. UI rules:
- Pending transactions render at
opacity: 0.6with a--warningleft border, and are excluded from the ledger balance. - When a pending transaction settles at a different amount, the change is shown, not silently overwritten.
- Never reconcile a pending transaction.
3. Bank reconciliation
The full model is in periods & close. What matters at the component level:
Matching ladder
- Exact — amount, date, and reference all agree. Auto-matched, no review.
- Near — amount agrees, date within tolerance. Auto-suggested, one-click accept.
- Rule-based — a saved rule (this description pattern → this account). Suggested with the rule named.
- Many-to-one — a bank deposit covering several invoices, or one payment covering several bills. Common, and the case most tools handle worst.
- One-to-many — one book entry split across several bank lines.
- Unmatched — the actual exception.
UI rules:
- Confidence is shown with its basis, not as a bare percentage. "Matched on amount and reference" is actionable; "94%" is not.
- Many-to-one selection shows a running sum against the target, so the user can see when the selection is exact.
- Auto-matched items are reviewable and reversible. An automation you cannot inspect is an automation you cannot trust at audit.
- The difference is always on screen. It is the number being driven to zero.
- The match animation is one of the four sanctioned delight moments — see motion catalog.
Categorization rules
type CategorizationRule = {
conditions: { field: "description" | "amount" | "counterparty" | "account"; op: Op; value: string }[];
actions: { account: string; dimensions?: Dimensions; memo?: string };
autoPost: boolean; // suggest vs. post automatically
priority: number;
};
- Rule creation happens inline from a transaction — categorize one, offer to categorize the other 40 like it. The highest-leverage interaction in bookkeeping.
- Preview the match count before applying. "This rule matches 47 existing transactions."
autoPostis off by default. A rule that posts to the GL without review is a control decision, and it should be a deliberate one.
4. Cash forecasting
Opening available balance 412,880
Add: expected receipts (AR due, by date) 184,200
Less: scheduled payments (AP due + payroll) (241,600)
Less: committed (approved POs to invoice) (48,000)
─────────────────────────────────────────────────────
Projected closing balance 307,480
UI rules:
- Certainty tiers are visually distinct. Contracted (scheduled payments), expected (AR by due date, with a collection-probability haircut), and forecast (modelled) are three different qualities of number and must not render identically.
- Show the minimum balance in the horizon, not just the endpoint. A forecast ending at $300k that dips to −$40k in week three is the important fact, and an endpoint-only view hides it.
- Payroll is a separate, prominent line. It is the payment that cannot be delayed.
- Scenario comparison (base / downside / upside) uses distinct line styles as well as color, never color alone.
5. Multi-account treasury
- Sweeps and internal transfers are not income or expense. They net to zero at the group level and must be eliminated from any cash-flow presentation. A dashboard that counts an internal transfer as a receipt is double-counting.
InternalTransferMatchpairs the two sides of a transfer and marks both as eliminated.- Restricted cash is disclosed separately and excluded from available cash. It is on the balance sheet but it is not spendable.
- Concentration risk: cash by institution against insured limits (FDIC $250,000 per depositor, per insured bank, per ownership category — sweep and reciprocal-deposit networks can extend it).
CashConcentrationrenders exposure by bank with the limit line.
6. Payment rails
Different rails have different timing, reversibility, and cost, and the UI must state all three at the moment of choosing.
| Rail | Settlement | Reversible? | Cutoff |
|---|---|---|---|
| ACH | Next or second business day; Same Day ACH up to $1M per payment | Limited — returns and reversals within Nacha windows (generally 2 banking days; 60 days for unauthorized consumer debits) | Three Same Day ACH windows; the last closes at 4:45 p.m. ET |
| Wire (domestic) | Same day | No | Bank-specific, typically mid-afternoon |
| Wire (international) | 1–5 days | No | Plus correspondent-bank delays |
| RTP / FedNow | Seconds | No | 24/7 |
| Check | 5–10 days + float | Stop-payment possible | |
| Card | 1–3 days | Chargeback window |
UI rules:
- Irreversible rails get
HoldToConfirm. Wires, RTP, FedNow. - The cutoff is shown as a live countdown where it matters. "Submit within 2h 14m for same-day settlement."
- Business days, not calendar days. Weekends and bank holidays are respected in every arrival estimate, and the holiday calendar is per-country.
- The arrival estimate is always shown before confirming, and it's the sentence users read most: "Arrives Tue 8 Sep".
7. Cash component set
| Component | Purpose |
|---|---|
BalanceCard |
Available as the figure, current as the secondary line, with source and as-of |
AccountCard |
Per-account, with connection health — connected / stale / reauth-required, prominent |
TransactionTable |
Pending and posted, with settlement changes visible |
ReconciliationView |
The two-pane matcher; suggestions carry their confidence basis, not a bare score |
CategoryPicker |
Rule creation inline from a transaction, with match-count preview |
CashRequirements |
Due in 7/14/30 vs. available |
CashForecast* |
Certainty-tiered, showing the minimum in the horizon |
InternalTransferMatch* |
Pairs and eliminates both sides |
CashConcentration* |
Exposure by institution against insured limits |
PaymentRailSelector* |
Timing, reversibility, and cost at the point of choice |
* Specified here, not yet in the catalog.