Skip to content

feat(treasury): policy layer for tax transfers and Amex paydowns (W3) - #401

Open
adme-dev wants to merge 1 commit into
mainfrom
feat/treasury-policy-layer
Open

feat(treasury): policy layer for tax transfers and Amex paydowns (W3)#401
adme-dev wants to merge 1 commit into
mainfrom
feat/treasury-policy-layer

Conversation

@adme-dev

Copy link
Copy Markdown
Owner

Why

Workstream W3 of the spreadsheet retirement (.paul/PLAN-2026-08-13-spreadsheet-retirement-platform-work.md, Monday board C-12). Kellie's cash-management judgment — weekly NAB Business → NAB Tax transfers with month-varying amounts and a skip-first-Monday rule, plus Amex statement paydown tranches — can't be represented in Xero (its own cashflow tools exclude transfers and card paydowns). Hand-keying them as commitment rows recreated the spreadsheet's maintenance burden, and modelling an internal transfer as a commitment wrongly depressed the org-level 13-week forecast (cash moving between our own accounts isn't an outflow).

What

  • treasury_policies (migration 377, already applied to prod — additive): one JSONB config row per policy type per tenant.
  • server/utils/treasuryPolicy.ts — pure derivation of dated lines: tax_transfer (per-month weekly amounts, 1-based skip-Monday rules) tagged internal_transfer and excluded from org-level outflow; amex_paydown tranches join weekly outflows as real cash events.
  • cashflow-13w — policy lines wired in; policyLines and totalPolicyOutflow exposed for the UI / per-account views.
  • GET/PUT /api/cashflow/policies — zod-validated per policy type.
  • Seeded from Kellie's 12 Aug sheet: transfers Aug-26 $16k/wk through May-27 $15.5k/wk (skip 1st Monday), Amex $50k (13/8) + $35,327.37 (21/8). The wrong transfer commitment row is closed; deriving months without config (Jun-27+) intentionally produce nothing — mirrors her "review for next BAS" note.

Cutover step on deploy

The two Amex — statement payment commitment rows are still expected so the live forecast keeps that outflow until this ships. Close them when this deploys (their notes field says exactly this); otherwise the week of 17 Aug double-counts ~$35k.

Tests

  • test/server/utils/treasuryPolicy.test.ts — skip rules, per-month amounts, horizon bounds, default fallback, past-tranche exclusion (validated against Kellie's actual Aug/Sep/Oct/Nov Monday patterns).
  • Full test/server/ suite: 4,811 passed.

Follow-ups

  • Settings UI for Kellie (frontend-design pass) — separate PR.
  • W2 (RepeatingInvoices push) gated on the C-12 decisions, target 27 Aug.

🤖 Generated with Claude Code

Kellie's cash-management judgment — weekly NAB Business → NAB Tax
transfers with month-varying amounts and a skip-first-Monday rule, and
Amex statement paydown tranches — cannot live in Xero (its cashflow
tools exclude transfers and card paydowns) and proved unmaintainable as
hand-keyed commitment rows. Worse, an internal transfer modelled as a
commitment depressed the org-level 13-week forecast: cash moving
between our own accounts is not an outflow.

- treasury_policies table (migration 377): one config row per policy
  type per tenant, applied to prod (additive, IF NOT EXISTS).
- server/utils/treasuryPolicy.ts: pure derivation of dated lines from
  config; internal transfers tagged and excluded from org-level outflow,
  Amex paydowns join weekly outflows.
- cashflow-13w: policy lines wired in; policyLines + totalPolicyOutflow
  exposed for the UI.
- GET/PUT /api/cashflow/policies with zod validation per policy type.
- Policies seeded from Kellie's 12 Aug sheet (Aug-26 $16k/wk … May-27
  $15.5k/wk, skip 1st Monday; Amex $50k 13/8 + $35,327.37 21/8).

CUTOVER on deploy: close the two 'Amex — statement payment' commitment
rows (notes on the rows say so) — they stay 'expected' so the live
forecast keeps the outflow until this code ships.

Workstream W3 of .paul/PLAN-2026-08-13-spreadsheet-retirement-platform-work.md.
Settings UI for Kellie follows separately (frontend-design pass).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant