# Changelog ## [Unreleased] ### Added - **Cartes report** (`/reports/cartes`): new dashboard-style sub-report in the Reports hub. Combines four KPI cards (income, expenses, net balance, savings rate) showing MoM and YoY deltas simultaneously with a 13-month sparkline highlighting the reference month, a 12-month income vs. expenses overlay chart (bars + net balance line), top 5 category increases and top 5 decreases vs. the previous month, a budget-adherence card (N/M on-target plus the three worst overruns with progress bars), and a seasonality card that compares the reference month against the same calendar month from the two previous years. All data comes from a single `getCartesSnapshot()` service call that runs its queries concurrently (#97) ### Changed - **Compare report** (`/reports/compare`): reduced from three tabs (MoM / YoY / Budget) to two modes (Actual vs. actual / Actual vs. budget). The actual-vs-actual view now has an explicit reference-month dropdown in the header (defaults to the previous month), a MoM ↔ YoY sub-toggle, and a grouped side-by-side bar chart (two bars per category: reference period vs. comparison period). The URL `PeriodSelector` stays in sync with the reference month picker (#96) ## [0.8.0] - 2026-04-14 ### Added - **Reports hub**: `/reports` is now a hub surfacing a live highlights panel (current month + YTD net balance with sparklines, top movers vs. last month, top recent transactions) and four navigation cards to dedicated sub-reports (#69–#76) - **Highlights report** (`/reports/highlights`): balance tiles with 12-month sparklines, sortable top movers table, diverging bar chart, recent transactions list with 30/60/90 day window toggle (#71) - **Trends report** (`/reports/trends`): internal sub-view toggle between global flow (income vs. expenses) and by-category evolution, chart/table toggle on both (#72) - **Compare report** (`/reports/compare`): tab bar for Month vs. Previous Month, Year vs. Previous Year, and Actual vs. Budget; diverging bar chart centered on zero for the first two modes (#73) - **Category zoom** (`/reports/category`): single-category drill-down with donut chart of subcategory breakdown, monthly evolution area chart, and filterable transactions table (#74) - **Contextual keyword editing**: right-click any transaction row to add its description as a categorization keyword; a preview dialog shows every transaction that would be recategorized (capped at 50, with an opt-in checkbox for N+) before you confirm. Available on the category zoom, the highlights list, and the main transactions page (#74, #75) - **Bookmarkable period**: the reports period now lives in the URL (`?from=YYYY-MM-DD&to=YYYY-MM-DD`), so you can copy, paste, and share the link and keep the same state (#70) - **View mode preference** (chart vs. table) is now persisted in `localStorage` per report section ### Changed - The legacy monolithic `useReports` hook has been split into per-domain hooks (`useReportsPeriod`, `useHighlights`, `useTrends`, `useCompare`, `useCategoryZoom`) so every sub-report owns only the state it needs (#70) - Context menu on reports (right-click) is now a generic `ContextMenu` shell reused by the existing chart menu and the new keyword dialog (#69) ### Removed - The dynamic pivot table report was removed. Over 90% of its real usage was zooming into a single category, which is better served by the new Category Zoom report. Git history preserves the old implementation if it ever needs to come back (#69) ### Security - New `AddKeywordDialog` enforces a 2–64 character length bound on user keywords to prevent ReDoS on large transaction sets (CWE-1333), uses parameterized `LIKE` queries for the preview (CWE-89), wraps its INSERT + per-transaction UPDATEs in an explicit BEGIN/COMMIT/ROLLBACK transaction (CWE-662), renders all untrusted descriptions as React children (CWE-79), and recategorizes only the rows the user explicitly checked — never retroactively. Keyword reassignment across categories requires an explicit confirmation step (#74) - `getCategoryZoom` walks the category tree through a **bounded** recursive CTE (`WHERE depth < 5`), protecting against malformed `parent_id` cycles (CWE-835) (#74) ## [0.7.4] - 2026-04-14 ### Changed - OAuth tokens are now stored in the OS keychain (Credential Manager on Windows, Secret Service on Linux) instead of a plaintext JSON file. Existing users are migrated transparently on the next sign-in refresh; the old file is zeroed and removed. A "tokens stored in plaintext fallback" banner appears in Settings if the keychain is unavailable (#66, #78, #79, #81) - Cached account info is now HMAC-signed with a keychain-stored key: writing `subscription_status` to `account.json` manually can no longer bypass the Premium gate (#80) - PIN hashing migrated from SHA-256 to Argon2id for brute-force resistance (CWE-916). Existing SHA-256 PINs are verified transparently and rehashed on next successful unlock; new PINs use Argon2id (#54) ### Security - Closed CWE-312 (cleartext storage of OAuth tokens), CWE-345 (missing integrity check on the subscription cache), and CWE-916 (weak PIN hashing). Legacy `tokens.json` and legacy unsigned `account.json` caches are rejected by the gating path until the next token refresh re-establishes a keychain-anchored trust (#66, #54) ## [0.7.3] - 2026-04-13 ### Fixed - Maximus Account sign-in: the deep-link callback now uses the canonical Tauri v2 `on_open_url` API, so the auth code is properly received by the running app instead of leaving the UI stuck in "loading" (#51, #65) - OAuth callbacks containing an `error` parameter now surface the error to the UI instead of being silently ignored (#51) ## [0.7.2] - 2026-04-13 ### Changed - Auto-updates are temporarily open to the Free edition until the license server (issue #49) is live. Gating will be restored once paid activation works end-to-end (#48) ## [0.7.1] - 2026-04-13 ### Fixed - Maximus Account sign-in: the OAuth2 callback now correctly returns to the running app instead of launching a second instance and leaving the original one stuck in "loading" (#51, #65) ## [0.7.0] - 2026-04-11 ### Added - CI: new `check.yml` workflow runs `cargo check`/`cargo test` and the frontend build on every branch push and PR, catching errors before merge instead of waiting for the release tag (#60) - License card in Settings page: shows the current edition (Free/Base/Premium), accepts a license key, and links to the purchase page (#47) - Maximus Account card in Settings: optional sign-in via OAuth2 PKCE for Premium features (#51) - Machine activation: activate/deactivate machines against the license server, view activated machines in the license card (#53) - Daily subscription status check: automatically refreshes account info once per day at launch (#51) ### Changed - Automatic updates are now gated behind the Base edition entitlement; the Free edition shows an upgrade hint instead of fetching updates (#48) - Edition detection now considers Maximus Account subscription: Premium overrides Base when subscription is active (#51) ## [0.6.7] - 2026-03-29 ### Changed - Category Over Time report: removed hard-coded expense-only filter, added type selector defaulting to expense (#41) - Category Over Time report: added type filter (expense/income/transfer) in the right filter panel (#41) ### Fixed - Updated picomatch dependency (4.0.3 → 4.0.4) to fix HIGH severity vulnerabilities (#43) ## [0.6.6] ### Changed - Budget table: previous year column now shows actual transactions instead of planned budget (#34) - Refactored `buildPrevYearTotalMap` inline and simplified tests (#39) ### Fixed - Changelog files synced automatically via Vite plugin, removed stale public/ copies (#37) ## [0.6.5] ### Added - Dashboard: month dropdown selector for the Budget vs Actual section with last completed month as default (#31) ### Changed - Reports & Dashboard: reduced font size of month dropdown for better visual balance (#31) ## [0.6.4] ### Added - Budget table: previous year total column displayed as first data column for baseline reference (#16) ### Fixed - Dashboard: level 4+ categories now appear under their parent instead of at the bottom of the section (#23) - Dashboard: category hierarchy now supports arbitrary nesting depth (#23) ### Changed - Dashboard: pie chart takes 1/3 width instead of 1/2, giving more space to the budget table (#23) - Dashboard: pie chart labels now shown only on hover via tooltip instead of permanent legend (#23) - Budget vs Actual: category column now stays fixed when scrolling horizontally (#29) - Budget vs Actual: title changed to "Budget vs Réel pour le mois de [month]" with a dropdown month selector (#29) - Budget vs Actual: default month is now the last completed month instead of current month (#29) ## [0.6.3] ### Added - Dashboard: expenses over time stacked bar chart by category and month (#15) - Dashboard: budget vs actual table for current month with variance in $ and % (#15) - Budget table and Budget vs Actual report: section subtotal formatting with increasing visual weight (#14) ### Changed - Dashboard: default period changed from "month" to "year to date" (#15) - Dashboard: removed recent transactions section (#15) - All report tables: grand total rows now use larger font (text-sm), bold weight, and thicker top border for better visual hierarchy (#14) ### Fixed - Category over time report: all categories now displayed (limit increased from 8 to 50) (#13) - Category bar chart: Y-axis labels now use foreground color instead of muted gray (#13) - Category over time chart: legend text now uses foreground color instead of inheriting category color (#13) ## [0.6.2] ### Added - Budget table: section subtotals for expenses, income, and transfers displayed after each group (#11) - Budget vs Actual report: section subtotals with actual, planned, variation ($) and variation (%) per type (#11) ### Fixed - Category page: detail panel now stays visible when scrolling through a long category list (#12) ## [0.6.1] ### Added - Changelog page: full version history accessible from Settings at any time - Bilingual changelog: release notes displayed in the user's selected language (EN/FR) ### Fixed - Chart label visibility: amount labels on stacked bar charts now use black text with white outline for better contrast (#8) - Budget table: editable cells now show hover background, pointer cursor, and tooltip hint for clearer affordance (#9) ## [0.6.0] ### Added - Reports: toggle between table and chart view for Trends, By Category, and Over Time tabs - Reports: "Show amounts" toggle displays values directly on chart bars and area curves - Reports: filter panel with category checkboxes (search, select all/none) and source dropdown - Reports: source filter applies at SQL level for accurate filtered totals - Reports: sticky table headers on all report tables (Dynamic Report, Budget vs Actual) - Reports: interactive hover — dimmed non-hovered bars, tooltip filtered to hovered category - Reports: legend hover highlights category across all months (Over Time chart) ### Fixed - Transaction table: comment icon now turns orange (like split icon) when a note is present (#7) ## [0.5.0] ### Added - Error boundary catches React crashes and displays an error page instead of a white screen - Startup timeout (10s) on database connection — shows error page instead of infinite spinner - Error page with "Refresh", "Check for updates", and contact/issue links - Log viewer in settings page — captures console output, filterable by level, copyable, persists across refresh - GPL-3.0 license — project is now open source ### Changed - Report detail modal: sortable columns — click headers to sort by date, description, or amount (#1) - Report detail modal: toggle to show/hide amounts column (#3) - Budget table: column headers stay fixed when scrolling vertically (#2) ### Fixed - Auto-updater on Linux: `latest.json` version field no longer has `v` prefix, package registry upload is more robust - Startup retry: DB connection retries up to 3 times before showing error page (fixes first-launch failure on Windows) - Migration checksum mismatch: automatically repairs stale migration 1 checksum on startup ## [0.4.4] ### Fixed - Linux binary now compatible with glibc 2.35+ (Ubuntu 22.04 / Pop!_OS) — CI builds in Ubuntu 22.04 container ## [0.4.3] ### Fixed - Auto-updater endpoint now uses Forgejo package registry for stable URL - Linux updater signatures (.AppImage.sig) now correctly collected in CI - All platform signatures (.deb.sig, .rpm.sig) now included in release assets ## [0.4.2] ### Changed - Auto-updater now points to self-hosted Forgejo instance - Windows builds now cross-compiled via cargo-xwin ## [0.4.1] ### Fixed - App stuck on infinite spinner after updating from v0.3.x (migration checksum mismatch on seed_categories.sql) - DB connection errors now logged to console instead of silently failing ## [0.4.0] ### Added - Categories: support for 3 levels of hierarchy (e.g., Dépenses récurrentes → Assurances → Assurance-auto) - Dynamic Report: new "Category (Level 3)" pivot field - Budget: intermediate subtotals and 3-level indentation for nested categories - Categories: automatic `is_inputable` management when creating/deleting subcategories - Categories: depth validation prevents creating a 4th level - Seed data: Assurances split into Assurance-auto, Assurance-habitation, Assurance-vie ### Fixed - Auto-categorization: keywords starting/ending with special characters (`[`, `]`, `(`, `)`, `-`, etc.) now match correctly - Auto-categorization: pre-compile regex patterns for better batch performance ## [0.3.11] ### Added - Dynamic Report: support multiple column dimensions (composite column keys) ### Fixed - Dynamic Report: no longer affected by global page date filters — uses only its own panel filters ## [0.3.10] ### Added - Dynamic Report: fields can now be used in multiple zones simultaneously (rows + filters, columns + filters) - Dynamic Report: right-click on a filter value to exclude it (shown with strikethrough in red) - "This year" period option in reports and dashboard (Jan 1 to today) ## [0.3.9] ### Added - Dynamic Report (pivot table): compose custom reports by assigning dimensions to rows, columns, filters and measures to values - Delete keywords from the "All Keywords" view ## [0.3.8] ### Added - Custom date range picker for reports and dashboard - Toggle to position subtotals above or below detail rows - Display release notes from CHANGELOG in GitHub releases and in-app updater ## [0.3.7] ### Fixes - Remove MSI bundle to prevent updater install path conflict - Change Windows updater installMode to basicUi - Improve split indicator visibility and adjustments layout ## 0.3.2 ### New Features - **Linux support**: Add Linux build (`.deb`, `.rpm`, `.AppImage`) to release workflow - **Transaction splits on Adjustments page**: View transaction split adjustments in a dedicated section on the Adjustments page ### Fixes - Fix CSV auto-detect edge cases - Remove accent from productName for Linux `.deb` compatibility ## 0.3.1 ### Fixes - Always show profile switcher in sidebar (#2) ## 0.3.0 ### New Features - **Multiple profiles**: Create multiple profiles with separate databases, custom names, and colors - **PIN protection**: Protect profiles with an optional numeric PIN - **Profile switcher**: Quick profile switching from the sidebar - **Drag-and-drop categories**: Reorder categories or change parent via drag-and-drop in the category tree - **Transaction splits**: Split a transaction across multiple categories with adjustable amounts ## 0.2.10 ### New Features - **Period quick-select**: Add quick period filter buttons (This month, Last month, etc.) on the Transactions page - **Budget vs Actual report**: Monthly and year-to-date comparison table in Reports - **Parent category subtotals**: Budget page shows aggregated subtotals for parent categories - **User guide**: Complete documentation page accessible from Settings, printable to PDF ### Improvements - Persist template selection and add Update template button - Don't pre-select already-imported files when entering source config - Make settings data imports visible in Import History - Replace per-template delete buttons with single delete on selection - Replace refresh icon with save icon on update template button - Add sign convention to budget page ## 0.2.9 ### Fixes - Allow duplicate-content files with different names (#1) ## 0.2.8 ### New Features - **Data export/import**: Export and import your data (transactions, categories, or both) with optional AES-256-GCM encryption (#3) ### Fixes - Cross-file duplicate detection and per-file import tracking ## 0.2.5 ### New Features - **Import config templates**: Save and load import source configurations as reusable templates - **12-month budget grid**: Full year budget view with monthly cells and annual totals ### Fixes - Budget and category fixes - Migration checksum issue (schema.sql must not be modified after initial release) ## 0.2.3 ### New Features - **Chart patterns**: Added SVG fill patterns (diagonal lines, dots, crosshatch, etc.) to differentiate categories in bar charts, pie chart, and stacked bar charts beyond just color - **Chart context menu**: Right-click any category in a chart to hide it or view its transactions in a detail popup - **Hidden categories**: Hidden categories appear as dismissible chips above charts with a "Show all" button to restore them - **Transaction detail modal**: View all transactions composing a category's total directly from any chart - **Import preview popup**: The data preview is now a popup modal instead of a separate wizard step, allowing quick inspection without leaving the configuration page - **Direct duplicate check**: New "Check Duplicates" button on the import configuration page skips directly to duplicate validation without requiring a preview first ### Improvements - Import wizard flow simplified: source-config → duplicate-check (preview is optional via popup) - Duplicate-check back button now returns to source configuration instead of the removed preview step - Added `categoryIds` map to `CategoryOverTimeData` for proper category resolution in the over-time chart ## 0.2.2 - Bump version ## 0.2.1 - Add "All Keywords" view on Categories page - Add dark mode with warm gray palette - Fix orphan categories, persist has_header for imports, add re-initialize - Add Budget and Adjustments pages