Collapse the three Compare tabs (MoM / YoY / Budget) into two modes. The
new "Actual vs actual" mode exposes an explicit reference-month dropdown
in the header (defaults to the previous month, wraps around January) and
a MoM/YoY sub-toggle. The chart is rewritten to a grouped side-by-side
BarChart with two bars per category (reference period vs comparison
period) so both values are visible at a glance instead of just the
delta. The URL PeriodSelector stays in sync with the reference month.
- useCompare: state splits into { mode: "actual"|"budget", subMode:
"mom"|"yoy", year, month }. Pure helpers previousMonth(),
defaultReferencePeriod(), comparisonMeta() extracted for tests
- CompareModeTabs: 2 modes instead of 3
- New CompareSubModeToggle and CompareReferenceMonthPicker components
- ComparePeriodChart: grouped bars via two <Bar dataKey="..."/> on a
vertical BarChart
- i18n: modeActual / subModeMoM / subModeYoY / referenceMonth (FR+EN),
retire modeMoM / modeYoY
- 9 new vitest cases covering the pure helpers (January wrap-around for
both MoM and YoY, default reference period, month/year arithmetic)
Closes #96
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
18 KiB
18 KiB
Changelog
[Unreleased]
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 URLPeriodSelectorstays in sync with the reference month picker (#96)
[0.8.0] - 2026-04-14
Added
- Reports hub:
/reportsis 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
localStorageper report section
Changed
- The legacy monolithic
useReportshook 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
ContextMenushell 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
AddKeywordDialogenforces a 2–64 character length bound on user keywords to prevent ReDoS on large transaction sets (CWE-1333), uses parameterizedLIKEqueries 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) getCategoryZoomwalks the category tree through a bounded recursive CTE (WHERE depth < 5), protecting against malformedparent_idcycles (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_statustoaccount.jsonmanually 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.jsonand legacy unsignedaccount.jsoncaches 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_urlAPI, 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
errorparameter 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.ymlworkflow runscargo check/cargo testand 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
buildPrevYearTotalMapinline 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.jsonversion field no longer hasvprefix, 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_inputablemanagement 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
.debcompatibility
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
categoryIdsmap toCategoryOverTimeDatafor 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