Commit graph

14 commits

Author SHA1 Message Date
le king fu
5861346eb3 feat(balance): data layer — vehicle_type + custom_label migrations, starters, service (#202)
All checks were successful
PR Check / rust (pull_request) Successful in 22m31s
PR Check / frontend (pull_request) Successful in 2m26s
Bilan axe véhicule (Étape 1) data foundation: separate the fiscal envelope
(now balance_accounts.vehicle_type) from the asset class (the category).

- Migration v12 (additive): add vehicle_type (fiscal enum, nullable) to
  balance_accounts + custom_label to balance_categories; backfill the envelope
  onto ex-tfsa/rrsp accounts (cash stays NULL); defensive recovery of any seed
  i18n_key overwritten by free text (bug I).
- Migration v13 (reclass, conditional/idempotent): re-link ex-tfsa/rrsp accounts
  to the `other` asset class and deactivate the two envelope seeds.
- consolidated_schema.sql: 2 new columns, 5 asset-class seeds (no tfsa/rrsp),
  CELI/REER starters re-pointed to `other` + vehicle_type (avoids NULL FK).
- Types: BalanceVehicleType, custom_label / vehicle_type / category_custom_label.
- Service: normalizeVehicleType + vehicle_type_invalid; CRUD writes the new
  columns; SELECT/JOINs read them back; STARTER_ACCOUNTS + proposeStarterAccounts
  (is_active=1 + vehicle_type) + getStarterCollisions adjusted.
- Tests: Rust chain v9→v13 (snapshot_lines identical, transfers intact, archived
  ex-tfsa covered, seeds deactivated, v13 EXISTS guard, idempotence, CHECK reject)
  + consolidated complete (5 categories, 4 starters, 0 NULL FK); TS service +
  StarterAccountsModal specs. No diff to migrations <= v11.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 20:37:56 -04:00
le king fu
445822b792 fix(balance): pre-seed balance_starter_proposed pref for new profiles (S1)
Before this commit, a brand-new profile briefly showed the
StarterAccountsModal even though the 4 starter accounts were already
seeded — the modal rendered 4 collision rows with no actionable choice
before being dismissed. Pre-seeding the pref in consolidated_schema.sql
suppresses the modal on first /balance visit for new profiles entirely.

Existing profiles already running the app are unaffected: they handle
the modal once on their first /balance visit (the pref-write happens on
dismiss). No migration is needed for them.

Suggestion S1 from PR #185 review (#187).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 16:28:04 -04:00
le king fu
cd0a2b826f feat(balance): starter accounts + opt-in modal + ADR 0012
Part 1 — New profiles: seed 4 starter accounts in
consolidated_schema.sql (Compte chèque/CELI/REER/Compte
non-enregistré, currency CAD, is_active=1) right after the
balance_categories seeds. Categories resolved via SELECT subquery
on the seeded `key` values for robustness.

Part 2 — Existing profiles: StarterAccountsModal proposes the same
4 starters at first /balance visit. Default-checked checkboxes,
collision rule (case-insensitive trim name + matching category)
disables matches with a "Déjà présent" tooltip. The atomic helper
`proposeStarterAccounts` wraps the inserts in BEGIN/COMMIT (rolls
back on error). user_preferences.balance_starter_proposed records
{shown_at, accepted} so the modal never reappears, dismissed or
confirmed.

Part 3 — docs/adr/0012-balance-two-level-model.md (Proposed):
captures the future vehicles × compositions model for reflection,
no code change. Numbered 0012 because 0011 was already taken by
the providers-best-effort-yahoo ADR. Linked from architecture.md
ADR table and Bilan section.

Tests: StarterAccountsModal.test.tsx covers STARTER_ACCOUNTS shape,
getStarterCollisions (case-insensitive trim, category-scoped) and
proposeStarterAccounts (insert order, COMMIT, ROLLBACK on failure).
No render tests — mirrors the BalanceOnboardingCard pattern (no
jsdom configured).

Resolves #179
2026-05-02 11:59:45 -04:00
le king fu
3963f552ae feat(balance): add asset_type column to balance_categories
All checks were successful
PR Check / rust (push) Successful in 23m42s
PR Check / frontend (push) Successful in 2m26s
PR Check / rust (pull_request) Successful in 22m55s
PR Check / frontend (pull_request) Successful in 2m24s
Priced balance categories now carry an explicit `asset_type`
('stock' | 'crypto') so PriceFetchControl can route to the right
provider without symbol heuristics. ETH = Ethan Allen NYSE AND
Ethereum crypto are no longer ambiguous.

Migration v10 adds a nullable column and backfills the two seeded
priced categories (key='stock','crypto'). Legacy custom priced rows
stay NULL until the user edits the category — SnapshotLineRow hides
the price-fetch button when asset_type is NULL on a priced row, so
manual entry remains available.

Service-side validation rejects priced creation without asset_type
('asset_type_required') and rejects values outside ('stock','crypto')
('asset_type_invalid'). Simple kind coerces asset_type to NULL.

The CategoryVariant of AccountForm shows the selector only when
kind=priced, requires it on submit, and resets it on kind switch.
i18n keys added under balance.category.assetType.* (FR + EN).

Tests:
- 4 new Rust migration tests in lib.rs (column add, seed backfill,
  legacy row stays NULL, CHECK rejects 'gold')
- 6 new vitest cases on createBalanceCategory + listBalanceAccounts
  asserts c.asset_type AS category_asset_type in the join
- balance-flow integration test updated to pass asset_type='stock'

No new test for SnapshotLineRow render guard — project lacks
@testing-library/react + jsdom; the guard is one boolean expression
covered by manual QA per autopilot decisions in PR #167.

Fixes #169
2026-04-28 19:54:04 -04:00
le king fu
a6787adef0 feat(balance): add migration v9 schema (5 tables, 7 indexes, seed)
Adds the SQL foundation for the Bilan (balance sheet) feature:

- 5 new tables: balance_categories, balance_accounts, balance_snapshots,
  balance_snapshot_lines, balance_account_transfers
- 7 indexes (category, active partial, snapshot, accounts x2, transaction,
  snapshot_date)
- Seed of 7 standard categories (5 simple + 2 priced) marked is_seed=1
- CHECK(currency = 'CAD') on balance_accounts (MVP — v2 lifts the constraint
  with a multi-currency rate table)
- CHECK kind invariants on balance_snapshot_lines (quantity/unit_price both
  NULL OR both NOT NULL)
- FK transaction_id ON DELETE RESTRICT to preserve reproducibility of
  Modified Dietz returns calculated on past periods

Migration v9 is added inline to the lib.rs Vec<Migration> via a new
constant database::BALANCE_SCHEMA backed by balance_schema.sql. The
schema is mirrored in consolidated_schema.sql so brand-new profiles
get the feature preinstalled without replaying v9.

13 new co-located rusqlite tests validate the migration on a fresh
in-memory DB: schema applies cleanly, 7 categories seeded with correct
kinds, CHECK rejects invalid currency/kind/direction, UNIQUE rejects
duplicate snapshot_date / (snapshot_id,account_id) / (transaction_id,
account_id), FK CASCADE on snapshot delete, FK RESTRICT on transaction
delete and on category with linked accounts, seed idempotent on replay.

Refs #138

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 14:31:50 -04:00
le king fu
bd992f2f94 feat(categories): add v1 IPC seed, i18n keys, and migration v8 (#115)
All checks were successful
PR Check / rust (push) Successful in 22m29s
PR Check / frontend (push) Successful in 2m18s
PR Check / rust (pull_request) Successful in 22m39s
PR Check / frontend (pull_request) Successful in 2m18s
Livraison 1 du milestone spec-refonte-seed-categories-ipc. Applies the
new v1 IPC (Indice des prix à la consommation) taxonomy to freshly
created profiles while leaving existing v2 profiles untouched until the
migration wizard (upcoming issue #121) prompts them to move.

- Migration v8 (additive only):
    - ALTER TABLE categories ADD COLUMN i18n_key TEXT
    - INSERT OR IGNORE user_preferences.categories_schema_version=v2
      (existing profiles tagged as v2 for later migration)
- consolidated_schema.sql rewritten with the full v1 seed and
  categories_schema_version='v1' default for brand-new profiles
- src/data/categoryTaxonomyV1.json bundled as the TS-side source of
  truth (consumed by #116 categoryTaxonomyService next)
- categoriesSeed.* i18n namespace (FR/EN) — 150 entries each
- CategoryTree and CategoryCombobox fall back to the raw `name` when
  i18n_key is null (user-created categories stay literal)
- CategoryTreeNode and CategoryRow gain the i18n_key field end-to-end

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 16:41:55 -04:00
le king fu
d2a0ee65b3 Fix app stuck on spinner after v0.4.0 update (GH #9)
Restore seed_categories.sql to its original content so the migration 2
checksum matches existing databases. Move the level-3 insurance
subcategories (310-312) into a new migration 7 using INSERT OR IGNORE.
Add .catch() on connectActiveProfile() to surface DB errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:54:42 -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
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
c7f7bab98f fix: restore schema.sql to exact v0.2.4 bytes for migration checksum (v0.2.7)
Some checks failed
Release / build (windows-latest) (push) Has been cancelled
v0.2.6 still had comment lines in schema.sql that changed the SHA-384
checksum. sqlx requires byte-for-byte match with the originally applied
migration SQL. schema.sql is now identical to the v0.2.4 original.

Migrations 4 (is_inputable column) and 5 (import_config_templates table)
in lib.rs handle adding these to existing databases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 17:23:36 +00:00
Le-King-Fu
9ed79b4fa3 fix: revert schema.sql to match migration 1 checksum (v0.2.5.1)
schema.sql was modified in v0.2.5 to include is_inputable column and
import_config_templates table. Since schema.sql is include_str!'d into
migration 1, this changed its SHA-256 checksum in sqlx's migration
tracker, blocking migrations 4 and 5 from running.

Reverts schema.sql to its original v0.2.4 state so the checksum matches
and new migrations can apply. Fixes both "no such table:
import_config_templates" and is_inputable defaulting to false.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 16:47:07 +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
9ea8314149 feat: seed categories and keywords from SommaireDepense.csv
Add v2 migration with 6 parent categories, 36 child categories, and ~85
keywords extracted from the expense summary to enable auto-categorization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 01:40:47 +00:00
Le-King-Fu
801404ca21 Initial project scaffold: Tauri v2 + React + TypeScript + TailwindCSS v4
- Tauri v2 with SQLite plugin and full database schema
- React with react-router-dom, i18n (FR/EN), recharts, lucide-react
- TailwindCSS v4 with custom Bleu/Creme/Terracotta palette
- App shell with sidebar navigation (7 pages)
- Dashboard with summary cards, page stubs for all sections
- Default category configuration (10 top-level categories)
- TypeScript interfaces matching SQLite schema

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 11:05:11 +00:00