Bank reconciliation
Read-only Plaid sync, 5-rule auto-matcher, categorization rules, QuickBooks IIF export.
transactions and balance Plaid products are enabled at the integration layer (defense-in-depth enforcement before any Plaid API call, not just config).Connecting a bank
Super_admin only. Settings → Bank Sync → "Connect Bank Account" launches Plaid Link. User signs in through Plaid's hosted modal; we receive an access token which we encrypt at rest (AES-256-GCM with tenant-derived key) + store under bank_connections. Token never leaves the service layer in plaintext.
5 auto-match rules
Evaluated in priority order; first match ≥ 0.70 confidence auto-applies.
R1 · 0.98
R2 · 0.85
R3 · 0.75
R4 · 0.80
R5 · 0.70
Admin can confirm, reject, or manually rebind any auto-matched row. Manual matches always win over rule-based labels.
Match kinds — 6 entity bindings + 2 special
- ✓ar_payment — inflow → invoices (auto + manual)
- ✓retainer_deposit — inflow → active retainers (manual only in v1)
- ✓ap_payment — outflow → vendor payments (auto + manual)
- ✓expense_reimbursement — outflow → approved expenses (manual only)
- ✓retainer_refund — outflow → closed retainers with refund disposition
- ✓direct_user_payment — outflow → users (employee / vendor_member); foundation for year-end 1099-NEC reporting via GROUP BY targetEntityId
- ✓transfer — paired internal transfer via R5 (detection only, no auto-apply)
- ✓manual_category — free-text, no entity (categorize path for bank-only flows like payroll / fees)
Categorization rules
For recurring transactions the auto-matcher can't bind (payroll, Stripe deposits, bank fees, tax payments), define pattern-based rules in Banking → Categorization rules. Each rule matches merchant name or description against a substring or regex pattern and stamps a category. Rules fire DURING sync AND via the "Auto-categorize" sweep button on the transactions list.
ttp_category IS NULL rows. Once a category is set by hand, only an admin can change it.Reconciliation + QuickBooks export
Reconciliation
IIF export
ttp_category per line.Security posture
- ✓Read-only Plaid products only — enforced before any API call
- ✓AES-256-GCM tenant-scoped encryption on access tokens
- ✓Tampered ciphertext rejected by GCM auth tag
- ✓Webhook signature verification via Plaid's ES256-signed JWT
- ✓Atomic disconnect — Plaid /item/remove BEFORE local wipe
- ✓Audit log on every state change