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.
This commit is contained in:
234
docs/plans/2026-03-03-feature-batch-2-design.md
Normal file
234
docs/plans/2026-03-03-feature-batch-2-design.md
Normal file
@@ -0,0 +1,234 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user