Commit graph

55 commits

Author SHA1 Message Date
le king fu
4c58b8bab8 feat(reports/cartes): new KPI dashboard sub-report with sparklines, top movers, budget adherence and seasonality (#97)
All checks were successful
PR Check / rust (push) Successful in 23m21s
PR Check / frontend (push) Successful in 2m24s
PR Check / rust (pull_request) Successful in 23m12s
PR Check / frontend (pull_request) Successful in 2m20s
New /reports/cartes page surfaces a dashboard-style snapshot of the
reference month:

- 4 KPI cards (income / expenses / net / savings rate) showing MoM and
  YoY deltas simultaneously, each with a 13-month sparkline highlighting
  the reference month
- 12-month income vs expenses overlay chart (bars + net balance line)
- Top 5 category increases + top 5 decreases MoM, clickable through to
  the category zoom report
- Budget adherence card: on-target count + 3 worst overruns with
  progress bars
- Seasonality card: reference month vs same calendar month averaged
  over the two previous years, with deviation indicator

All data is fetched in a single getCartesSnapshot() service call that
runs four queries concurrently (25-month flow, MoM category deltas,
budget-vs-actual, seasonality). Missing months are filled with zeroes
in the sparklines but preserved as null in the MoM/YoY deltas so the UI
can distinguish "no data" from "zero spend".

- Exported pure helpers: shiftMonth, defaultCartesReferencePeriod
- 13 vitest cases covering zero data, MoM/YoY computation, January
  wrap-around, missing-month handling, division by zero for the
  savings rate, seasonality with and without history, top mover sign
  splitting and 5-cap

Note: src/components/reports/CompareReferenceMonthPicker.tsx is a
temporary duplicate — the canonical copy lives on the issue-96 branch
(refactor: compare report). Once both branches merge the content is
identical and git will dedupe. Keeping the local copy here means the
Cartes branch builds cleanly on main without depending on #96.

Closes #97

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 19:44:58 -04:00
le king fu
62430c63dc feat: category zoom + secure AddKeywordDialog with context menu (#74)
Some checks failed
PR Check / rust (push) Has been cancelled
PR Check / frontend (push) Has been cancelled
PR Check / rust (pull_request) Has been cancelled
PR Check / frontend (pull_request) Has been cancelled
Service layer
- New reportService.getCategoryZoom(categoryId, from, to, includeChildren) —
  bounded recursive CTE (WHERE ct.depth < 5) protects against parent_id cycles;
  direct-only path skips the CTE; every binding is parameterised
- Export categorizationService helpers normalizeDescription / buildKeywordRegex /
  compileKeywords so the dialog can reuse them
- New validateKeyword() enforces 2–64 char length (anti-ReDoS), whitespace-only
  rejection, returns discriminated result
- New previewKeywordMatches(keyword, limit=50) uses parameterised LIKE + regex
  filter in memory; caps candidate scan at 1000 rows to protect against
  catastrophic backtracking
- New applyKeywordWithReassignment wraps INSERT (or UPDATE-reassign) +
  per-transaction UPDATEs in an explicit BEGIN/COMMIT/ROLLBACK; rejects
  existing keyword reassignment unless allowReplaceExisting is set; never
  recategorises historical transactions beyond the ids the caller supplied

Hook
- Flesh out useCategoryZoom with reducer + fetch + refetch hook

Components (flat under src/components/reports/)
- CategoryZoomHeader — category combobox + include/direct toggle
- CategoryDonutChart — template'd from dashboard/CategoryPieChart with
  innerRadius=55 and ChartPatternDefs for SVG patterns
- CategoryEvolutionChart — AreaChart with Intl-formatted axes
- CategoryTransactionsTable — sortable table with per-row onContextMenu
  → ContextMenu → "Add as keyword" action

AddKeywordDialog — src/components/categories/AddKeywordDialog.tsx
- Lives in categories/ (not reports/) because it is a keyword-editing widget
  consumed from multiple sections
- Renders transaction descriptions as React children only (no
  dangerouslySetInnerHTML); CSS truncation (CWE-79 safe)
- Per-row checkboxes for applying recategorisation; cap visible rows at 50;
  explicit opt-in checkbox to extend to N-50 non-displayed matches
- Surfaces apply errors + "keyword already exists" replace prompt
- Re-runs category zoom fetch on success so the zoomed view updates

Page
- ReportsCategoryPage composes header + donut + evolution + transactions
  + AddKeywordDialog, fetches from useCategoryZoom, preserves query string
  for back navigation

i18n
- New keys reports.category.* and reports.keyword.* in FR + EN
- Plural forms use i18next v25 _one / _other suffixes (nMatches)

Tests
- 3 reportService tests cover bounded CTE, cycle-guard depth check, direct-only fallthrough
- New categorizationService.test.ts: 13 tests covering validation boundaries,
  parameterised LIKE preview, regex word-boundary filter, explicit BEGIN/COMMIT
  wrapping, rollback on failure, existing keyword reassignment policy
- 62 total tests passing

Fixes #74

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:09:17 -04:00
le king fu
ff350d75e7 feat: compare report — MoM / YoY / budget with view toggle (#73)
Some checks failed
PR Check / rust (push) Successful in 23m24s
PR Check / frontend (push) Successful in 2m17s
PR Check / frontend (pull_request) Has been cancelled
PR Check / rust (pull_request) Has been cancelled
- Services: getCompareMonthOverMonth(year, month) and getCompareYearOverYear(year)
  return CategoryDelta[] (expense-side, ABS aggregates, parameterised SQL only)
- Shared CategoryDelta type with HighlightMover now aliased to it
- Flesh out useCompare hook: reducer + fetch + automatic year/month inference
  from the shared useReportsPeriod `to` date; budget mode skips fetch and
  delegates to CompareBudgetView which wraps the existing BudgetVsActualTable
- Components: CompareModeTabs (MoM/YoY/Budget tabs), ComparePeriodTable (sortable
  table with signed delta coloring), ComparePeriodChart (diverging horizontal
  bar chart with ChartPatternDefs for SVG patterns), CompareBudgetView
  (fetches budget rows for the current target year/month)
- ReportsComparePage wires everything with PeriodSelector + ViewModeToggle
  (storage key reports-viewmode-compare); chart/table toggle is hidden in budget
  mode since the budget table has its own presentation
- i18n keys: reports.compare.modeMoM / modeYoY / modeBudget in FR + EN
- 4 new vitest cases for the compare services: parameterised boundaries,
  January wrap-around to December previous year, delta conversion with
  previous=0 fallback to null pct, year-over-year spans

Fixes #73

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 14:57:13 -04:00
le king fu
ac9c8afc4a feat: reports hub with highlights panel and detailed highlights page (#71)
All checks were successful
PR Check / rust (pull_request) Successful in 24m54s
PR Check / frontend (pull_request) Successful in 2m32s
PR Check / rust (push) Successful in 24m14s
PR Check / frontend (push) Successful in 2m26s
- Transform /reports into a hub: highlights panel + 4 nav cards
- New service: reportService.getHighlights (parameterised SQL, deterministic
  via referenceDate argument for tests, computes current-month balance, YTD,
  12-month sparkline series, top expense movers vs previous month, top recent
  transactions within configurable 30/60/90 day window)
- Extended types: HighlightsData, HighlightMover, MonthBalance
- Wired useHighlights hook with reducer + window-days state
- Hub tiles (flat naming under src/components/reports):
  HubNetBalanceTile, HubTopMoversTile, HubTopTransactionsTile,
  HubHighlightsPanel, HubReportNavCard
- Detailed ReportsHighlightsPage: balance tiles, sortable top movers table,
  diverging bar chart (Recharts + patterns SVG), top transactions list with
  30/60/90 window toggle; ViewModeToggle persistence keyed as
  reports-viewmode-highlights
- New i18n keys: reports.hub.*, reports.highlights.*
- 5 new vitest cases: empty profile, parameterised queries, window sizing,
  delta computation, zero-previous divisor handling

Fixes #71

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 14:47:55 -04:00
le king fu
91430e994a refactor: remove pivot report, add sub-route skeletons and shared components (#69)
All checks were successful
PR Check / rust (push) Successful in 24m21s
PR Check / frontend (push) Successful in 2m12s
PR Check / rust (pull_request) Successful in 23m5s
PR Check / frontend (pull_request) Successful in 2m16s
- Delete DynamicReport* components and pivot types (PivotConfig, PivotResult, PivotFieldId, etc.)
- Remove getDynamicReportData/getDynamicFilterValues from reportService
- Strip pivotConfig/pivotResult from useReports hook and ReportsPage
- Drop "dynamic" from ReportTab union
- Remove reports.pivot.* and reports.dynamic i18n keys in FR and EN
- Add skeletons for /reports/highlights, /trends, /compare, /category pages
- Register the 4 new sub-routes in App.tsx
- Add reports.hub, reports.viewMode, reports.empty, common.underConstruction keys
- New shared ContextMenu component with click-outside + Escape handling
- Refactor ChartContextMenu to compose generic ContextMenu
- New ViewModeToggle with localStorage persistence via storageKey
- New Sparkline (Recharts LineChart) for compact trends
- Unit tests for readViewMode helper

Fixes #69

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 14:25:38 -04:00
ba5257791f Merge pull request 'fix: migrate PIN hashing from SHA-256 to Argon2id (#54)' (#55) from fix/simpl-resultat-54-argon2id-pin into main 2026-04-14 12:49:05 +00:00
le king fu
3b1c41c48e feat: settings banner when OAuth tokens fall back to file store (#81)
Some checks are pending
PR Check / rust (push) Waiting to run
PR Check / frontend (push) Waiting to run
PR Check / rust (pull_request) Successful in 22m28s
PR Check / frontend (pull_request) Successful in 2m19s
Adds a visible warning in the Settings page when `token_store` has
landed in the file fallback instead of the OS keychain. Without this,
a user on a keychain-less system would silently lose the security
benefit introduced in #78 and never know.

- New `get_token_store_mode` service wrapper in authService.ts.
- New `TokenStoreFallbackBanner` component: fetches the mode on mount,
  renders nothing when mode is `keychain` or null, renders an
  amber warning card when mode is `file`.
- Mounted in SettingsPage right after AccountCard so it sits next to
  the account state the user can fix (log out + log back in once the
  keychain is available).
- i18n keys under `account.tokenStore.fallback.*` in fr/en.

Refs #66

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 08:18:41 -04:00
le king fu
e314bbe1e3 fix: remove handle_auth_callback from invoke_handler
All checks were successful
PR Check / rust (push) Successful in 17m12s
PR Check / frontend (push) Successful in 2m12s
PR Check / rust (pull_request) Successful in 16m56s
PR Check / frontend (pull_request) Successful in 2m14s
The auth callback is handled exclusively via the deep-link handler in
lib.rs — exposing it as a JS-invocable command is unnecessary attack
surface. The frontend listens for auth-callback-success/error events
instead.

Plaintext token storage documented as known limitation (see #66).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:35:10 -04:00
le king fu
b53a902f11 feat: Maximus Account OAuth2 PKCE + machine activation + subscription check (#51, #53)
All checks were successful
PR Check / rust (push) Successful in 16m34s
PR Check / frontend (push) Successful in 2m14s
PR Check / rust (pull_request) Successful in 16m31s
PR Check / frontend (pull_request) Successful in 2m13s
- Add auth_commands.rs: OAuth2 PKCE flow (start_oauth, handle_auth_callback,
  refresh_auth_token, get_account_info, check_subscription_status, logout)
- Add deep-link handler in lib.rs for simpl-resultat://auth/callback
- Add AccountCard.tsx + useAuth hook + authService.ts
- Add machine activation commands (activate, deactivate, list, get_activation_status)
- Extend LicenseCard with machine management UI
- get_edition() now checks account subscription for Premium detection
- Daily subscription status check (refresh token if last check > 24h)
- Configure CSP for API/auth endpoints
- Configure tauri-plugin-deep-link for desktop
- Update i18n (FR/EN), changelogs, and architecture docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 14:18:51 -04:00
le king fu
2da2de183a feat: license card in settings (#47)
All checks were successful
PR Check / rust (push) Successful in 16m19s
PR Check / frontend (push) Successful in 2m14s
Adds the user-facing layer on top of the Rust license commands shipped
in #46.

- `licenseService.ts` thin wrapper around the new Tauri commands
- `useLicense` hook follows the project's useReducer pattern (idle,
  loading, ready, validating, error) and exposes `submitKey`,
  `refresh`, and `checkEntitlement` for cross-component use
- `LicenseCard` shows the current edition, the expiry date when set,
  accepts a license key with inline validation feedback, and links to
  the purchase page via `openUrl` from `@tauri-apps/plugin-opener`
- Card is inserted at the top of `SettingsPage` so the edition is the
  first thing users see when looking for license-related actions
- i18n: new `license.*` keys in both `fr.json` and `en.json`
- Bilingual CHANGELOG entries
2026-04-09 15:47:04 -04:00
escouade-bot
34626711eb fix: address reviewer feedback (#54)
- Add automatic re-hashing of legacy SHA-256 PINs to Argon2id on
  successful verification, returning new hash to frontend for persistence
- Use constant-time comparison (subtle::ConstantTimeEq) for both
  Argon2id and legacy SHA-256 hash verification
- Add unit tests for hash_pin, verify_pin (Argon2id and legacy paths),
  re-hashing flow, error cases, and hex encoding roundtrip
- Update frontend to handle VerifyPinResult struct and save rehashed
  PIN hash via profile update

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:46:27 -04:00
escouade-bot
d099678ddf fix: address reviewer feedback (#41)
- Default categoryType filter to "expense" so top-N ranking is not
  skewed by mixing income and expense amounts
- Remove redundant showFilterPanel condition (hasCategories already
  covers the overTime tab)
- Add unit tests for getCategoryOverTime query construction and output

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 02:02:41 -04:00
escouade-bot
56b46f1dfa Remove hard-coded expense filter from Category Over Time report
The Category Over Time report previously only showed expenses (t.amount < 0).
This removes that filter so all transaction types are shown by default,
and adds a type filter (expense/income/transfer) in the right filter panel.

Ref: simpl-resultat#41

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:05:27 -04:00
4e70eee0a8 feat: show actual transactions in budget previous year column
Replace planned budget data with actual transaction totals for the
previous year column in the budget table. Add getActualTotalsForYear
helper to budgetService.

Ref #34

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 23:03:26 -04:00
66d0cd85ff fix: address reviewer feedback (#23)
- Extract reorderRows into shared utility (src/utils/reorderRows.ts) to
  deduplicate identical function in BudgetTable and BudgetVsActualTable
- Restore alphabetical sorting of children in budgetService.ts
- Fix styling for intermediate parent rows at depth 2+ (was only handling
  depth 0-1)
- Reduce pie chart size (height 220->180, radii reduced) and padding to
  give more space to the table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 21:02:24 -04:00
dbe249783e fix: display level 4+ categories under their parent in dashboard budget table (#23)
- Replace flat alphabetical sort with tree-order traversal so child
  categories appear directly under their parent subtotal row
- Make category hierarchy recursive (supports arbitrary depth)
- Reduce pie chart width from 1/2 to 1/3 of the dashboard
- Show pie chart labels only on hover via tooltip

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 01:10:46 -04:00
le king fu
e1192beca3 Fix missing categories and gray text in category reports
Increase category over time limit from 8 to 50 so all categories appear.
Fix category name visibility: use foreground color for bar chart Y-axis
labels and chart legend text instead of muted/inherited colors.

Closes #13

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 09:06:40 -05:00
le king fu
0a5b7bce10 Bump version to 0.6.0 — Reports enhancements and comment visibility fix
All checks were successful
Release / build-and-release (push) Successful in 26m12s
- Add table/chart toggle for Trends, By Category, and Over Time reports
- Add "Show amounts" toggle to display values on chart elements
- Add filter panel with category checkboxes and source dropdown
- Add source filter at SQL level for all chart report queries
- Add sticky headers on Dynamic Report and Budget vs Actual tables
- Add interactive hover: dimmed non-hovered bars, filtered tooltip, legend hover
- Fix comment icon color to match split indicator (orange) (#7)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:01:13 -05:00
le king fu
15d626cbbb Fix migration checksum mismatch on startup
Add repair_migrations Tauri command that deletes stale migration 1
checksum from _sqlx_migrations before Database.load(). Migration 1
is idempotent (CREATE IF NOT EXISTS) so re-applying is safe.
Fixes "migration 1 was previously applied but has been modified".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 09:17:35 -05:00
le king fu
fb92cfc12c Add startup retry logic and persist logs across refresh
All checks were successful
Release / build-and-release (push) Successful in 25m5s
Retry connectActiveProfile up to 3 times with 1s delay before showing
the error page. Persist log buffer to sessionStorage so logs survive
page refresh and are visible in the settings log viewer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 22:12:41 -05:00
le king fu
d604d5ae63 Fix updater latest.json and add log viewer in settings
Some checks failed
Release / build-and-release (push) Has been cancelled
Fix updater: strip v-prefix from version in latest.json, and delete
old package before re-uploading to avoid 409 conflicts.
Add frontend log capture (console intercept) with a log viewer card
in the settings page (filterable, copyable, clearable).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:09:10 -05:00
le king fu
4938bba3f3 fix: keyword matching with non-word boundary characters
Keywords starting/ending with non-word characters (brackets, parens,
dashes) never matched because \b requires a word↔non-word transition.
Now uses smart boundaries: \b for word-char edges, (?<=\s|^)/(?=\s|$)
for non-word edges. Also pre-compiles regex patterns once per batch
instead of recreating them for every description × keyword combination.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 20:03:04 -05:00
le king fu
a04813ced2 feat: add 3rd level of category hierarchy
Support up to 3 levels of categories (e.g., Dépenses récurrentes →
Assurances → Assurance-auto) while keeping SQL JOINs bounded and
existing 2-level branches fully compatible.

Changes across 14 files:
- Types: add "level3" pivot field, depth property on budget row types
- Reports: grandparent JOIN for 3-level resolution in dynamic reports
- Categories: depth validation (max 3), auto is_inputable management,
  recursive tree operations, 3-level drag-drop with subtree validation
- Budget: 3-level grouping with intermediate subtotals, leaf-only
  aggregation, depth-based indentation (pl-8/pl-14)
- Seed data: Assurances split into Assurance-auto/habitation/vie
- i18n: level3 translations for FR and EN

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 19:54:05 -05:00
le king fu
2ae7fb301c fix: decouple dynamic report from global page date filters
The dynamic report now relies exclusively on its own panel filters
instead of inheriting the global period selector date range.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 10:09:14 -05:00
le king fu
04ec221808 feat: support multiple column dimensions in dynamic reports
Combine column dimensions into composite keys instead of using only the
first column dimension, enabling richer pivot tables and charts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 10:00:42 -05:00
le king fu
d06153f472 feat: allow reusable pivot fields across zones and right-click filter exclusion
Fields can now be assigned to multiple zones simultaneously (e.g. rows + filters).
Right-clicking a filter value excludes it (NOT IN), shown with strikethrough in red.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 09:10:15 -05:00
le king fu
20b3a54ec7 feat: add Dynamic Report (pivot table) tab to Reports page
Implement a pivot table feature allowing users to compose custom reports
by assigning dimensions (Year, Month, Type, Level 1/2) to rows, columns,
and filters, with periodic and YTD measures as values. Includes a side
panel for configuration, a dynamic table with subtotals, and a stacked
bar chart visualization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 08:26:50 -05:00
Le-King-Fu
b190df4eae feat: show transaction splits on Adjustments page + fix CSV auto-detect
Some checks failed
Release / build (ubuntu-22.04) (push) Has been cancelled
Release / build (windows-latest) (push) Has been cancelled
Add a "Répartitions" section below manual adjustments listing all
split transactions. Clicking a split opens the existing modal to
view, edit, or delete it.

Fix CSV auto-detect failing on files with preamble lines (e.g.
Mastercard CSVs with metadata header). Three fixes:
- Delimiter detection uses mode of column counts instead of first-line
- Detect and skip preamble rows before header/data detection
- Exclude date-like columns from amount candidates and prefer columns
  with decimal values when picking the amount column

Bumps version to 0.3.4.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 01:41:08 +00:00
Le-King-Fu
142c240a00 feat: add transaction split adjustments across multiple categories
Allow users to split a transaction across multiple categories directly
from the transactions table. Split children are hidden from the list
and automatically included in dashboard, report, and budget aggregates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 23:51:36 +00:00
Le-King-Fu
732302cb44 feat: add drag-and-drop reorder for categories and fix duplicate sort_order
Auto-fix duplicate sort_order values on load, auto-assign sort_order on
category creation, and add drag-and-drop via @dnd-kit to reorder and
reparent categories in the tree (with 2-level nesting constraint).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 23:25:45 +00:00
Le-King-Fu
20cae64f60 feat: add multiple profiles with separate databases and optional PIN (v0.3.0)
Some checks failed
Release / build (windows-latest) (push) Has been cancelled
Each profile gets its own SQLite database file for complete data isolation.
Profile selection screen at launch, sidebar switcher for quick switching,
and optional 4-6 digit PIN for privacy. Existing database becomes the
default profile with seamless upgrade.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:54:09 +00:00
Le-King-Fu
5e7c7e6609 feat: add Budget vs Actual report tab with monthly and YTD comparison
Some checks failed
Release / build (windows-latest) (push) Has been cancelled
New tabular report showing actual vs budgeted amounts per category,
with dollar and percentage variations for both the selected month
and year-to-date. Includes parent/child hierarchy, type grouping,
variation coloring, and month navigation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 18:01:10 +00:00
Le-King-Fu
32dae2b7b2 feat: add parent category subtotals and sign convention to budget page
Parent categories now display as bold read-only subtotal rows with their
children indented below. Expenses show as negative (red), income as
positive (green). Inputable parents get a "(direct)" child row for their
own budget entries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 17:44:32 +00:00
Le-King-Fu
e23e559ee3 feat: make settings data imports visible in Import History
Create import_sources + imported_files tracking records when importing
transactions from Settings > Data Management, so imports appear in the
Import History panel and can be deleted like CSV imports.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 13:38:51 +00:00
Le-King-Fu
ac295d9048 feat: persist template selection and add update template button
The template dropdown now stays on the selected value after applying,
and a new update button lets users save config changes back to the
selected template.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 13:16:55 +00:00
Le-King-Fu
db1d47ea94 fix: allow duplicate-content files with different names (#1)
Change imported_files UNIQUE constraint from (source_id, file_hash) to
(source_id, filename) so files with identical content but different names
each get their own record. Update createImportedFile to look up existing
records by filename instead of hash.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 12:40:01 +00:00
Le-King-Fu
87e8f26754 feat: add data export/import with optional AES-256-GCM encryption (#3)
Add export (JSON/CSV) and import (full replace) to the Settings page.
Export supports 3 modes (transactions+categories, transactions only,
categories only) with optional password encryption using Argon2id key
derivation. Import detects encrypted .sref files, prompts for password,
and shows a destructive confirmation modal before replacing data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:40:28 +00:00
Le-King-Fu
ccdab1f06a feat: add import config templates, budget/category fixes (v0.2.5)
Add reusable import config templates so users can save and apply CSV
parsing configurations across different import sources. Includes
database table, service, hook integration, and template UI in the
source config panel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 15:06:44 +00:00
Le-King-Fu
720f52bad6 feat: 12-month budget grid, import UX improvements, confirmation dialogs (v0.2.4)
Some checks failed
Release / build (windows-latest) (push) Has been cancelled
- Budget page: replace single-month view with 12-month annual grid
  with inline editing, split-evenly button, and year navigation
- Import: pre-select only new files and sort them first, show
  "already imported" badge on previously imported files
- Add confirmation modals for category re-initialization and
  import deletion (single and bulk), replacing native confirm()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 12:59:11 +00:00
Le-King-Fu
29a1a15120 feat: add chart patterns, context menu, and import preview popup (v0.2.3)
Some checks failed
Release / build (windows-latest) (push) Has been cancelled
- Add SVG fill patterns to differentiate chart categories beyond color
- Add right-click context menu on charts to hide categories or view transactions
- Add transaction detail modal showing all transactions for a category
- Change import preview from wizard step to popup modal
- Add direct "Check Duplicates" button skipping preview step
- Bump version to 0.2.3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 23:55:19 +00:00
Le-King-Fu
5648f79424 feat: add "All Keywords" view on Categories page
Adds a toggle button to view all keywords across categories in a
searchable table with accent-insensitive filtering. Clicking a category
name navigates back to the normal view with that category selected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 12:37:46 +00:00
Le-King-Fu
c73f466429 fix: persist has_header for imports, fix orphan categories, add re-initialize
Some checks failed
Release / build (windows-latest) (push) Has been cancelled
- Import: persist `has_header` flag to DB (migration v3) so headerless
  CSVs like Desjardins don't lose their first data row on re-import.
- Categories: promote children to root on parent deletion instead of
  cascading deactivation, preventing invisible orphans.
- Categories: add re-initialize button to reset all categories and
  keywords to seed defaults.
- Bump version to 0.2.1 across tauri.conf.json, package.json, Cargo.toml.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 11:54:33 +00:00
Le-King-Fu
5f5696c29a feat: add Budget and Adjustments pages with full functionality
Some checks failed
Release / build (windows-latest) (push) Has been cancelled
Budget: monthly data grid with inline-editable planned amounts per
category, actuals from transactions, difference coloring, month
navigation, and save/apply/delete budget templates.

Adjustments: split-panel CRUD for manual adjustment entries.

Both features include FR/EN translations and follow existing
service/hook/component patterns.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 00:58:43 +00:00
Le-King-Fu
474c7b947a fix: CSV import bugs and dashboard category filtering
Some checks failed
Release / build (windows-latest) (push) Has been cancelled
- Fix column display for Desjardins-style quoted CSVs (apply preprocessQuotedCSV in header loading)
- Fix column mapping disappearing on back-navigation (generate synthetic headers when hasHeader is false)
- Fix auto-detect picking account number as amount (exclude constant-value columns, treat 0 as empty in debit/credit detection)
- Use category type instead of amount sign for dashboard pie chart and recent transactions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 00:09:10 +00:00
Le-King-Fu
41398f0f34 fix: CAD currency, real-time import progress, per-row duplicate control, orphaned sources cleanup, dashboard expenses-only
- Change all currency formatters from EUR/fr-FR to CAD/en-CA
- Add onProgress callback to insertBatch for real-time progress bar updates
- Replace binary skip/include duplicates with per-row checkboxes and type badges (DB/batch)
- Clean up orphaned import_sources when deleting imports with no remaining files
- Filter dashboard recent transactions to show expenses only

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 12:36:12 +00:00
Le-King-Fu
9ff410e9f9 fix: searchable category combobox, import source upsert, and intra-batch duplicate detection
Replace native <select> with a type-to-search CategoryCombobox in both
the filter bar and inline table cells. Fix re-import UNIQUE constraint
error by using INSERT ... ON CONFLICT upsert in createSource(). Detect
duplicate rows within the same import batch using a Set key check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 12:02:23 +00:00
Le-King-Fu
d6000e191f feat: implement reports page with trends, category, and over-time charts
Add three chart tabs sharing a period selector: monthly income/expenses
area chart, horizontal category bar chart, and stacked category-over-time
bar chart with top 8 + Other grouping.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 01:47:18 +00:00
Le-King-Fu
3506c2c87e feat: add import history panel with delete and cross-source duplicate detection
Make duplicate file detection cross-source by removing sourceId from
existsByHash query. Add import history table below source list with
per-import and delete-all functionality.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 01:29:23 +00:00
Le-King-Fu
ca531262f7 feat: add auto-categorize button and fix keyword word-boundary matching
Replace substring matching (.includes) with \b word-boundary regex so
keywords like "Pay" no longer match "Payment". Add an auto-categorize
button on the transactions page that re-runs keyword matching on
uncategorized transactions and displays the result count.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 00:02:51 +00:00
Le-King-Fu
84eca47afd feat: implement dashboard with KPI cards, category pie chart, and recent transactions
Wire dashboard to real DB data with period selector (month/3m/6m/12m/all),
expense breakdown donut chart by category, and last 10 transactions list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 23:49:16 +00:00