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>
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
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
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>
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>
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>
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>
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>
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>
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>
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>
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>