Buckets - Budget with Intent

Inspiration

POST apps, modern TUIs, and Ally’s clean banking UI. Most friends I talk to keep everything in 1–2 checking accounts and feel budgeting is “abstract.” Buckets is for them: a fast, no-friction way to visually allocate money even without opening more bank accounts.

What it does

  • Track multiple accounts and balances.
  • Add expenses and income quickly (keyboard-first).
  • Allocate money into Buckets (virtual envelopes) so every dollar has a job, even in one checking account.
  • Fire off recurring entries with Templates.
  • See quick Insights (period totals + daily averages) and navigate time via a compact calendar.

How I built it

  • Python + SQLAlchemy for models and persistence (Accounts, Categories, Buckets, Records, Templates).
  • Textual for a snappy TUI (components, modals, TCSS styling, keyboard UX).
  • A thin managers layer (CRUD + queries) to keep business logic out of the UI.
  • Form system (Pydantic) to render fields, validate input, and power modals.

Challenges I ran into

Mount vs. rebuild timing

  • Avoided calling mount() before parents were mounted.
  • Rendered static shells in compose(), then populated in on_mount()/rebuild().
  • Used call_after_refresh() for safe focus/scroll after rebuilds.

Rebuild safety

  • Defensive querying (check existence before updates).
  • Idempotent updates (update() + class toggles) instead of tearing down containers.
  • Preserved selection/cursor state across rebuilds.

API drift in Textual

  • DataTable.add_row(style_name=...) changed; switched to class-based styling and sentinel keys for “group header” rows.

Stateful navigation

  • Kept selected account, record cursor, and filter state in view-models; restored after refreshes.

Bucket-aware records

  • Added optional Bucket selector to expense records; disabled/hidden for income.
  • Threaded bucketId through validation, form build, and persistence without breaking quick-add.

Layout + TCSS grid

  • Evolved to a three-pane layout: Templates rail, Accounts/Insights stack, large Records view.
  • Converted templates list to a full-width vertical rail so items stack and stretch.

Why it matters

  • Built for people learning to budget, often with one checking account.
  • Buckets makes allocation visual and immediate: pick a bucket/category, hit enter, done.

Accomplishments I’m proud of

  • A clean, readable TUI that feels fast.
  • Clear separation of data, logic, and UI.
  • Smooth keyboard workflow for adding and navigating records.

What I learned

  • Textual components, TCSS, and focus management.
  • SQLAlchemy modeling and query composition for budgeting.
  • Designing a Pydantic-backed form system that’s ergonomic in a TUI.

What’s next for Buckets

  • Deeper insights: trends over time, top categories, bucket health.
  • Manager views: rollups by category/account/bucket for custom periods.
  • Rules & automations: pre-fill and auto-categorize by label/pattern.
  • Import pipeline: CSV/OFX import with matching and de-duplication.
  • Real time Bank Connection: Be able to connect through plaid with bank accounts to read real time data.

Why Buckets?

Most beginners don’t want to open 10 accounts they want to see where money should go. Buckets gives every dollar a job with virtual envelopes and zero-friction input, so you can budget with intent, not friction.

Built With

Share this project:

Updates