Files
outlay/docs/plans/2026-03-03-feature-batch-2-design.md
lashman 524672a42e Add feature batch 2 design doc (16 features)
Covers custom budget cycles, bulk operations, monthly recap,
natural language entry, Sankey diagram, what-if sandbox, tags UI,
splits UI, templates UI, auto-categorization rules UI, searchable
category picker, PDF import, spending streaks, goal projections,
credit card tracking, and anomaly alerts.
2026-03-03 16:24:55 +02:00

10 KiB

Feature Batch 2 Design - 16 Features

Date: 2026-03-03

Overview

16 features sourced from Reddit community research on personal finance app wishlists, filtered against Outlay's existing feature set.

Features

5. Custom Budget Cycle

Users can choose how budget periods are defined:

  • Calendar month (default, current behavior): 1st to last day of month
  • Payday offset: budget runs from day X to day X-1 of next month (e.g. 15th to 14th)
  • Rolling N-day: budget period is a fixed window of N days from a configurable start date

New settings: budget_cycle_mode (calendar/payday/rolling), budget_cycle_start_day (1-31), budget_cycle_days (e.g. 30).

Affects: Budgets view period labels ("Mar 15 - Apr 14"), navigation step size, all budget queries, safe-to-spend calculation, and budget threshold notifications. Charts and History remain calendar-month based to avoid confusion.

Cycle configuration accessible via a gear icon popover next to the month nav in Budgets view.

6. Bulk Transaction Operations

Selection mode in History view:

  • "Select" button in header bar activates selection mode
  • Checkboxes appear on each transaction row
  • Long-press also enters selection mode
  • Action bar: "Delete (N)", "Recategorize", "Tag", "Select All", "Cancel"
  • Delete shows confirmation dialog with count
  • Recategorize opens a category picker, applies to all selected
  • Tag opens a multi-select tag picker, applies to all selected

7. Monthly/Yearly Recap

Part of the new Insights view (see below). Toggle between "This Month" and "This Year".

Monthly recap: total income, expenses, net, transaction count. Per-category rows showing amount, percentage of total, and change vs previous month with directional arrows.

Yearly recap: month-by-month summary with sparklines, year-over-year comparison.

"Share as PDF" button reuses existing PDF export.

8. Natural Language Entry

Dedicated smart entry bar at the top of Log view and in Quick Add popup.

adw::EntryRow titled "Quick entry" with placeholder "e.g. Coffee 4.50 at Starbucks".

Parser (outlay-core/src/nlp.rs):

  • parse_transaction(input, categories) -> Option<ParsedTransaction>
  • Extracts amount (required), category (fuzzy match), note, payee (after "at"/"from"/"to")
  • Patterns: "Coffee 4.50", "Lunch 12.50 at Subway", "4.50 groceries milk", "$25 gas"

Preview row shows parsed result below the entry. Press Enter to save. Existing detailed form remains below for manual entry.

9. Sankey Diagram

New section in Charts view after existing charts. Title: "Money Flow".

Cairo-drawn Sankey layout:

  • Left nodes: income categories
  • Right nodes: expense categories
  • Center node: "Available" (net)
  • Flow widths proportional to amounts
  • Income flows colored green, expense flows use category colors
  • Hover shows amount labels

Layout computation in outlay-core/src/sankey.rs:

  • compute_sankey_layout(income_sources, expense_categories) -> SankeyLayout
  • Returns node positions and bezier curve control points

Month navigation synced with other charts.

10. What-If / Sandbox Mode

Toggle button in Budgets view header bar.

When active:

  • Header tinted amber, label shows "Sandbox Mode"
  • All budget amounts become inline-editable
  • Changes stored in temporary HashMap<i64, f64>, NOT written to DB
  • Progress bars and safe-to-spend recalculate live
  • Modified rows get a visual indicator
  • "Apply Changes" button writes sandbox values to DB
  • "Discard" button exits sandbox, reverts to real data

11. Tags UI

Database tables already exist (tags, transaction_tags). Need GTK surfaces:

  • History view: tag chips in FlowBox alongside category chips (different visual style - outlined vs filled). Clicking a tag chip filters to transactions with that tag.
  • Log view: tags already have an entry field. Ensure it works with get_or_create_tag() and set_transaction_tags().
  • Edit dialog: show and edit tags on existing transactions.
  • Bulk operations: "Tag" action in selection mode.

12. Transaction Splits UI

Database tables already exist (transaction_splits). Need GTK surfaces:

  • Log view / Edit dialog: "Split" toggle button next to category row
  • When enabled: category row replaced by split list
  • Each split row: category dropdown + amount entry + optional note
  • "Add Split" button for more rows
  • Validation: split total must equal transaction amount ("Remaining: X.XX" label)
  • On save: insert_splits() called after transaction insert
  • Edit dialog: if has_splits(), pre-fills split rows

13. Transaction Templates UI

Database tables already exist (transaction_templates). Need GTK surfaces:

  • Log view: "Templates" icon button in header opens a popover
  • Lists saved templates as adw::ActionRow items (name, amount, category icon, type badge)
  • Tapping a template fills the log form
  • "Save as Template" button at bottom of form when amount + category are filled
  • Opens dialog for template name, saves via insert_template()

14. Auto-Categorization Rules UI

Database tables already exist (categorization_rules). Need GTK surface in Settings:

  • New "Categorization Rules" adw::PreferencesGroup between Categories and Import/Export
  • Each rule: adw::ActionRow showing field (Note/Payee), pattern, target category
  • "Add Rule" button opens dialog: field dropdown, pattern entry, category dropdown, priority spinner
  • Delete button per row
  • Rules applied during import and optionally during manual entry

15. Searchable Category Picker

Replace all adw::ComboRow category dropdowns with a searchable version:

  • Custom gtk::FilterListModel backed by gtk::StringFilter
  • Search entry at top of dropdown popup
  • Typing filters category list in real-time
  • Shared utility: fn make_searchable_category_combo(...) -> adw::ComboRow
  • Used in: log view, edit dialog, budget dialog, quick add, split rows, rules dialog

16. PDF Bank Statement Import

New "PDF" import button in Settings alongside existing importers.

Two-phase extraction (outlay-core/src/import_pdf.rs):

  1. Text extraction via pdf-extract crate - look for tabular date/description/amount patterns
  2. If no extractable text found, fall back to existing Tesseract OCR pipeline

Preview dialog shows extracted transactions in an editable list. Each row: date, description, amount, category (auto-matched via categorization rules, fallback "Uncategorized"). Import All / Import Selected buttons. Merge/replace mode toggle.

New dependency: pdf-extract crate.

17. Spending Streaks / Gamification

Dedicated Insights view (new sidebar item) with three sections:

Streaks:

  • No-spend streak: consecutive days with zero expenses, flame icon, "Best: X days"
  • Under-budget streak: consecutive months staying under total budget cap
  • Savings streak: consecutive months with goal contributions

Achievements:

  • Grid of achievement badges, earned ones colored, unearned dimmed
  • Starter set: "First Transaction", "7-Day No-Spend", "30-Day No-Spend", "Month Under Budget", "3 Months Under Budget", "First Goal Completed", "100 Transactions", "Budget Streak 6mo"
  • Checked and awarded on app launch

New tables: streaks, achievements.

18. Financial Goal Projections

Enhance existing Goals view:

  • Each active goal row gets subtitle: "At current rate, reachable by [date]"
  • Based on average monthly contributions over last 3 months
  • States: "On track - X months ahead", "Behind schedule - need X.XX/month", "Start contributing to see projection"
  • Expandable section per goal: mini line chart showing saved amount over time with projected line to target

19. Credit Card Billing Cycle Tracking

Dedicated Credit Cards view (new sidebar item).

Summary card: total balance, total limit, utilization bar, next due date.

Card list: each card is adw::ExpanderRow:

  • Collapsed: name, balance, due countdown, utilization mini-bar
  • Expanded: statement close date, minimum payment, payment history (last 3 months)
  • Actions: "Record Payment" (creates expense transaction, reduces balance), Edit, Delete

New table: credit_cards (name, credit_limit, statement_close_day, due_day, min_payment_pct, current_balance, currency, color, active).

24. Spending Anomaly Alerts in UI

Surface existing detect_anomalies() in two places:

  • History view: adw::Banner at top when anomalies exist for the displayed month: "N spending insights for this month". Tapping navigates to Insights view.
  • Insights view: Anomaly Alerts section renders each anomaly as adw::ActionRow with warning/info icons. Clickable to navigate to category in History.
  • Startup: toast on first launch of the day if current month has insights.

Schema Migration (v8 -> v9)

New table: credit_cards - see feature #19 above. New table: streaks - see feature #17 above. New table: achievements - see feature #17 above. New settings: budget_cycle_mode, budget_cycle_start_day, budget_cycle_days.

New Files

  • outlay-core/src/nlp.rs - natural language transaction parser
  • outlay-core/src/import_pdf.rs - PDF statement import
  • outlay-core/src/sankey.rs - Sankey layout computation
  • outlay-gtk/src/insights_view.rs - Insights view (streaks, achievements, recap, anomalies)
  • outlay-gtk/src/credit_cards_view.rs - Credit Cards view

New Dependencies

  • pdf-extract crate for PDF text extraction

Modified Files

  • outlay-core/src/db.rs - migration v9, new CRUD methods for credit cards / streaks / achievements / recap queries / budget period computation
  • outlay-core/src/models.rs - new structs (CreditCard, Achievement, Streak, ParsedTransaction, SankeyLayout, etc.)
  • outlay-core/src/lib.rs - register new modules
  • outlay-gtk/src/main.rs - register new views, startup achievement checks
  • outlay-gtk/src/window.rs - add Insights and Credit Cards to sidebar navigation
  • outlay-gtk/src/history_view.rs - bulk operations, tag chips, anomaly banner
  • outlay-gtk/src/log_view.rs - NL entry bar, templates button, split toggle
  • outlay-gtk/src/edit_dialog.rs - splits editing, tags editing
  • outlay-gtk/src/budgets_view.rs - custom cycle, what-if sandbox
  • outlay-gtk/src/charts_view.rs - Sankey diagram section
  • outlay-gtk/src/goals_view.rs - projection subtitles and mini charts
  • outlay-gtk/src/settings_view.rs - categorization rules section, PDF import button
  • outlay-gtk/src/quick_add.rs - NL entry bar, searchable category
  • outlay-gtk/Cargo.toml - add pdf-extract dependency