diff --git a/docs/plans/2026-03-03-feature-batch-2-design.md b/docs/plans/2026-03-03-feature-batch-2-design.md new file mode 100644 index 0000000..2ae78d0 --- /dev/null +++ b/docs/plans/2026-03-03-feature-batch-2-design.md @@ -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` +- 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`, 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