Commit graph

16 commits

Author SHA1 Message Date
le king fu
4a93c60ea7 feat(reports): plumb accountIds[] account filter into 7 report services
Give every report service an optional accountIds?: number[] filter that
narrows results to a subset of import sources (transactions.source_id),
matched via a parameterized IN (...) clause — one bound placeholder per
id, never a joined string (CWE-89). New shared inPlaceholders() helper
(src/utils/sqlFilters.ts) generates the placeholder list so the pattern
lives in exactly one place.

New accountIds param: getCompareMonthOverMonth, getCompareYearOverYear,
getBudgetVsActualData, getCartesSnapshot (forwarded to its
getCompareMonthOverMonth + getBudgetVsActualData sub-calls, so the
Cartes dashboard's top-movers and budget-adherence cards respect an
active filter instead of silently ignoring it).

Signature change scalar -> plural: getMonthlyTrends, getCategoryOverTime,
getExpensesByCategory (sourceId?: number -> accountIds?: number[]). No
scalar production caller of these three passed sourceId today, so only
the test call-sites needed updating to the array shape.

Omitted/empty accountIds adds no clause at all, so every service stays
byte-identical to its pre-#273 SQL/results — pinned by a regression test
per service (new budgetService.test.ts / dashboardService.test.ts files,
extended reportService.test.ts / reportService.cartes.test.ts).

This is backend plumbing only: no report page exposes an account filter
control yet (follow-up issues #274-#276 add the shared <FilterPanel> and
wire it into Trends/Compare/Budget).

Resolves #273

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 15:15:37 -04:00
le king fu
616cccec37 feat(reports): collapse/expand sub-categories in comparable reports (#254)
All checks were successful
PR Check / rust (pull_request) Successful in 22m52s
PR Check / frontend (pull_request) Successful in 2m24s
The two hierarchical comparable reports — real-vs-real Compare and
real-vs-budget — now let the user collapse or expand each top-level
category's sub-categories. Groups start collapsed by default (#260): only
the parent's subtotal row shows until the user expands it, and each expanded
group is remembered per report.

- New pure module utils/collapsibleRows.ts (visibility filter, group-key
  extraction, expanded-set (de)serialization) + useCollapsibleGroups hook
  wrapping the localStorage-persisted expanded set. Persisting the *expanded*
  set (not the collapsed one) makes "all collapsed" the zero/default state.
- A chevron toggles each top-level parent; an "Expand all / Collapse all"
  button toggles them together. Section subtotals and result lines keep
  summing every leaf, so collapsing never changes any total.
- Accessors mirror each table's own depth/parent logic so hidden rows are
  exactly a group's indented descendants.
- i18n keys reports.collapse.{expandAll,collapseAll} (FR/EN); CHANGELOG.

CategoryOverTimeTable (Trends -> by category) is intentionally left out: its
rows are a flat top-N category list with no parent/child hierarchy to fold.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 20:18:52 -04:00
le king fu
2a3cc07a0e Merge PR #251: feat(balance) CSV import of holdings in detailed snapshot (#245) 2026-07-05 17:03:00 -04:00
le king fu
c8c765e2f0 feat(balance): CSV import of holdings in detailed snapshot
All checks were successful
PR Check / rust (pull_request) Successful in 22m45s
PR Check / frontend (pull_request) Successful in 2m25s
A detailed (by-security) account can now import its positions from a CSV
instead of adding each security one by one. An "Import CSV" button next to
"Add a title" opens a native picker; the delimiter, encoding and columns
(symbol, quantity, optional price + book_cost) are auto-detected via new
csvAutoDetect helpers and adjustable in a small mapping editor. Rows sharing
a symbol are merged (SUM qty + book_cost, first price) and the batch is merged
into the basket by normalized symbol, so no UNIQUE(snapshot_line_id,
security_id) violation can occur at save. A CSV without a price column imports
quantities with an empty unit_price (fetch/type later) — the existing atomic
save path is unchanged (no SQL/Rust change).

- csvAutoDetect: autoDetectHoldingColumns + analyzeHoldingsCsv (+ tests)
- useSnapshotEditor: holdingsFromCsvRows + IMPORT_HOLDINGS action + importHoldings (+ tests)
- HoldingsCsvImportModal: file pick -> parse -> mapping editor + preview
- i18n FR/EN under balance.snapshot.detailed.importCsv.*
- CHANGELOG (Added / Ajouté)

Resolves #245

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 18:04:12 -04:00
le king fu
f3e8e94b16 feat(reports): hierarchical real-vs-real compare with subtotals
Render the real-vs-real comparable report as a parent/child category tree
with subtotal rows, mirroring the budget report — rows grouped into
expense/income/transfer sections with per-section and grand totals and a
subtotals-on-top/bottom toggle. The compare service now builds the tree on
top of the flat per-category deltas, so leaf-category figures are unchanged
and the #243 transfer netting is preserved (a balanced transfer group
subtotals to ~0, i.e. the group's net).

- reportService: buildCompareTree() synthesizes subtotal rows from the flat
  leaves + category metadata; getCompareMonthOverMonth/YoY return the tree
  (COMPARE_DELTA_SQL and rowsToDeltas untouched).
- CategoryDelta gains optional parent_id/is_parent/depth/category_type.
- ComparePeriodTable: sections, depth indentation, reorderRows toggle,
  section/grand net totals.
- Cartes top-movers and ComparePeriodChart filter to leaf rows only.
- reorderRows constraint loosened to the two fields it reads.
- i18n (FR+EN) section labels; CHANGELOG entries.

Resolves #247

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 17:32:38 -04:00
le king fu
344c27ee6d feat(balance): account form vehicle field + category rename via custom_label (#203)
All checks were successful
PR Check / rust (pull_request) Successful in 22m29s
PR Check / frontend (pull_request) Successful in 2m23s
- AccountForm: optional vehicle_type dropdown (account mode, 6 fiscal
  envelopes + none) wired into create/update; custom_label field (category
  mode) written to custom_label, never i18n_key.
- AccountsPage rename: writes custom_label, leaves i18n_key intact (fixes
  bug I where renaming clobbered the translation key).
- New shared renderCategoryLabel helper (+ shape adapters) applied at the 5
  sites: AccountsPage, AccountForm, SnapshotEditor, BalanceAccountsTable,
  BalancePage.
- Hide v13-deactivated seeds: useBalanceAccounts passes includeInactive=false
  (keeps #202 behavior-neutral default + tests green).
- BALANCE_VEHICLE_TYPES exported from shared/types as single source of truth
  (service reuses it).
- i18n FR+EN: vehicleType.*, category.form.customLabel*, errors.vehicle_type_invalid.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 20:50:40 -04:00
le king fu
8b90cb6489 feat(reports/highlights): default reference month to previous month + YTD current year, user-changeable (#106)
All checks were successful
PR Check / rust (push) Successful in 21m14s
PR Check / frontend (push) Successful in 2m16s
PR Check / rust (pull_request) Successful in 21m31s
PR Check / frontend (pull_request) Successful in 2m14s
- Extract shared defaultReferencePeriod helper (src/utils/referencePeriod.ts)
- useHighlights now reads ?refY=YYYY&refM=MM, defaults to previous month
- getHighlights signature: (referenceYear, referenceMonth, ytdYear, windowDays, ...)
- YTD tile pinned to Jan 1 of current civil year, independent of reference month
- CompareReferenceMonthPicker surfaced on /reports/highlights
- Hub highlights panel inherits the same default via useHighlights
- useCartes and useCompare now delegate their default-period helpers to the shared util
2026-04-19 08:28:30 -04:00
2a18d9be2d test: add unit tests for dateRange.ts utility
Add vitest and 17 tests covering computeDateRange (all periods
including January rollover) and buildMonthOptions (length, order,
rollover, label formatting). Add test/test:watch npm scripts.

Ref #33

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 23:05:32 -04:00
65815ef2e0 fix: address reviewer feedback (#31)
- Remove non-null assertions on bYear/bMonth in useDashboard fetchData
  by making parameters required
- Extract shared computeDateRange and buildMonthOptions into
  src/utils/dateRange.ts to eliminate duplication across useDashboard,
  useReports, DashboardPage and ReportsPage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:53:31 -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
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
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
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
bd6ff3deac feat: add CSV auto-detect configuration button
Analyzes imported CSV files to automatically detect delimiter, header,
date format, column mapping, amount mode, and sign convention. Excludes
running balance columns from amount mapping via consecutive-row math.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 18:09:35 +00:00
Le-King-Fu
88219e657f fix: reload column headers on config change and add YYYYMMDD date format
Headers now refresh live when delimiter, encoding, skipLines, or hasHeader
changes. Added YYYYMMDD compact date format to parser and dropdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 04:08:33 +00:00
Le-King-Fu
49e0bd2c94 feat: implement CSV import wizard with folder-based source detection
Full import pipeline: Rust backend (6 Tauri commands for folder scanning,
file reading, encoding detection, hashing, folder picker), TypeScript
services (DB, import sources, transactions, auto-categorization, user
preferences), utility parsers (French amounts, multi-format dates),
12 React components forming a 7-step wizard (source list, config,
column mapping, preview, duplicate detection, import, report), and
i18n support (FR/EN, ~60 keys each).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 03:38:46 +00:00