Bilan #1a — Schema migration + balance.service skeleton + AccountsPage comptes #138

Closed
opened 2026-04-25 16:07:52 +00:00 by maximus · 1 comment
Owner

Refs: spec-decisions-bilan.md + spec-plan-bilan.md (v2 + overnight-2026-04-26)

Issue mise à jour suite à /review-spec et /plan-overnight (2026-04-25). CRUD via TypeScript+getDb, migration inline lib.rs v9, currency hardcoded CAD pour MVP.

Tâches

  • Créer src-tauri/src/database/balance_schema.sql + déclaration dans database/mod.rs (pub const BALANCE_SCHEMA: &str = include_str!("balance_schema.sql"))
    • 5 tables (balance_categories, balance_accounts, balance_snapshots, balance_snapshot_lines, balance_account_transfers)
    • 7 indexes
    • Seed des 7 catégories standard avec is_seed = 1 :
      • cash (kind=simple), tfsa (simple), rrsp (simple), fund (simple), other (simple)
      • stock (kind=priced), crypto (priced)
    • balance_accounts.currency : NOT NULL DEFAULT 'CAD' CHECK(currency = 'CAD') — MVP hardcoded ; v2 lèvera le CHECK
    • balance_account_transfers.transaction_id : ON DELETE RESTRICT
    • balance_snapshot_lines : CHECK ((quantity IS NULL AND unit_price IS NULL) OR (quantity IS NOT NULL AND unit_price IS NOT NULL))
  • Vérifier en amont : grep version: src-tauri/src/lib.rs confirme que 8 = max actuel
  • Ajouter Migration { version: 9, description: "create balance schema", sql: BALANCE_SCHEMA, kind: MigrationKind::Up } au Vec dans src-tauri/src/lib.rs
  • Mirror dans src-tauri/src/database/consolidated_schema.sql (nouveaux profils)
  • Tests Rust unitaires migration (DB vierge) co-localisés dans lib.rs via #[cfg(test)] mod tests : application réussit, CHECK + UNIQUE + FK CASCADE/RESTRICT respectés, CHECK(currency = CAD) refuse autres devises
  • Créer src/services/balance.service.ts avec section CRUD initiale (catégories + comptes uniquement) via getDb() — pattern budgetService.ts
  • Tests vitest CRUD comptes/catégories (avec garde is_seed, FK RESTRICT sur catégorie avec comptes liés, refus création compte avec currency != CAD)
  • Créer src/hooks/useBalanceAccounts.ts (useReducer scoped)
  • Route /balance/accounts + page AccountsPage.tsx avec onglets Comptes et Catégories (CRUD simple-only)
  • Composant AccountForm.tsx (variant compte) :
    • Champ currency = grisé/locked à CAD (pas de select), label "CAD" affiché en read-only
    • Tooltip discret : "Multi-devises arrivera dans une version future"
    • Le variant catégorie viendra en #140
  • Clés i18n FR/EN sous balance.account.* et balance.category.*
  • Entrée CHANGELOG sous [Unreleased]

Hors scope (déplacé)

  • Pas dentrée sidebar Bilan (apparaît en #141 quand /balance existe vraiment)
  • Pas de SnapshotEditPage (#146)
  • Pas de catégories priced (#140)

Décisions prises ce soir

  • Currency hardcoded CAD pour MVP (CHECK SQL + UI lock). V2 lèvera la contrainte avec table de taux.
  • Tests Rust co-localisés via #[cfg(test)] mod tests (pas de dossier tests/ séparé).

Critères dacceptation

  • Un utilisateur peut créer un compte de bilan dans une catégorie seedée (currency=CAD verrouillé) et le visualiser
  • Tentative de créer un compte avec currency != CAD refusée côté service avec message clair
  • Suppression dune catégorie is_seed = 1 refusée côté service
  • cargo test passe (tests migration Rust + CHECK currency)
  • npm test passe (tests vitest service)
  • cargo check et npm run build passent
Refs: spec-decisions-bilan.md + spec-plan-bilan.md (v2 + overnight-2026-04-26) Issue mise à jour suite à /review-spec et /plan-overnight (2026-04-25). CRUD via TypeScript+getDb, migration inline lib.rs v9, currency hardcoded CAD pour MVP. ## Tâches - [ ] Créer src-tauri/src/database/balance_schema.sql + déclaration dans database/mod.rs (pub const BALANCE_SCHEMA: &str = include_str!("balance_schema.sql")) - 5 tables (balance_categories, balance_accounts, balance_snapshots, balance_snapshot_lines, balance_account_transfers) - 7 indexes - Seed des 7 catégories standard avec is_seed = 1 : - cash (kind=simple), tfsa (simple), rrsp (simple), fund (simple), other (simple) - stock (kind=priced), crypto (priced) - balance_accounts.currency : NOT NULL DEFAULT 'CAD' CHECK(currency = 'CAD') — MVP hardcoded ; v2 lèvera le CHECK - balance_account_transfers.transaction_id : ON DELETE RESTRICT - balance_snapshot_lines : CHECK ((quantity IS NULL AND unit_price IS NULL) OR (quantity IS NOT NULL AND unit_price IS NOT NULL)) - [ ] Vérifier en amont : grep version: src-tauri/src/lib.rs confirme que 8 = max actuel - [ ] Ajouter Migration { version: 9, description: "create balance schema", sql: BALANCE_SCHEMA, kind: MigrationKind::Up } au Vec<Migration> dans src-tauri/src/lib.rs - [ ] Mirror dans src-tauri/src/database/consolidated_schema.sql (nouveaux profils) - [ ] Tests Rust unitaires migration (DB vierge) co-localisés dans lib.rs via #[cfg(test)] mod tests : application réussit, CHECK + UNIQUE + FK CASCADE/RESTRICT respectés, CHECK(currency = CAD) refuse autres devises - [ ] Créer src/services/balance.service.ts avec section CRUD initiale (catégories + comptes uniquement) via getDb() — pattern budgetService.ts - [ ] Tests vitest CRUD comptes/catégories (avec garde is_seed, FK RESTRICT sur catégorie avec comptes liés, refus création compte avec currency != CAD) - [ ] Créer src/hooks/useBalanceAccounts.ts (useReducer scoped) - [ ] Route /balance/accounts + page AccountsPage.tsx avec onglets Comptes et Catégories (CRUD simple-only) - [ ] Composant AccountForm.tsx (variant compte) : - Champ currency = grisé/locked à CAD (pas de select), label "CAD" affiché en read-only - Tooltip discret : "Multi-devises arrivera dans une version future" - Le variant catégorie viendra en #140 - [ ] Clés i18n FR/EN sous balance.account.* et balance.category.* - [ ] Entrée CHANGELOG sous [Unreleased] ## Hors scope (déplacé) - Pas dentrée sidebar Bilan (apparaît en #141 quand /balance existe vraiment) - Pas de SnapshotEditPage (#146) - Pas de catégories priced (#140) ## Décisions prises ce soir - Currency hardcoded CAD pour MVP (CHECK SQL + UI lock). V2 lèvera la contrainte avec table de taux. - Tests Rust co-localisés via #[cfg(test)] mod tests (pas de dossier tests/ séparé). ## Critères dacceptation - Un utilisateur peut créer un compte de bilan dans une catégorie seedée (currency=CAD verrouillé) et le visualiser - Tentative de créer un compte avec currency != CAD refusée côté service avec message clair - Suppression dune catégorie is_seed = 1 refusée côté service - cargo test passe (tests migration Rust + CHECK currency) - npm test passe (tests vitest service) - cargo check et npm run build passent
maximus added this to the spec-price-fetching milestone 2026-04-25 16:07:52 +00:00
maximus added the
status:ready
type:feature
source:human
labels 2026-04-25 16:07:52 +00:00
Author
Owner

/review-spec — findings critiques + améliorations

Review adversariale du spec (3 agents : Sécurité / Architecture / Technique). Voir spec-plan-bilan.md (annotations inline + section "Revision — Synthese").

🔴 Critiques bloquants

1. CRUD via service TypeScript, pas via commandes Tauri (Architecture)
Les services existants utilisent getDb() + tauri-plugin-sql directement depuis TS (96 occurrences dans 15 services). Les commandes Tauri sont réservées au filesystem, OAuth, license, profils, feedback — pas au CRUD domaine. Les ~17 commandes balance proposées dupliquent la couche SQL en Rust pour rien.
Fix : Tout le CRUD passe dans balance.service.ts avec getDb(). Les commandes Rust se réduisent à 2 : fetch_price (Issue 5) et compute_account_return (Issue 4).

2. Migration inline dans lib.rs, pas de fichier séparé (Architecture+Technique)
Le path src-tauri/migrations/NNNN_balance_schema.sql est faux — ce dossier n'existe pas. Toutes les 8 migrations existantes sont inline via tauri_plugin_sql::Migration dans lib.rs. Contredit .claude/rules/sql-migrations.md.
Fix : Ajouter Migration { version: 9, description: "create balance schema", sql: BALANCE_SCHEMA, kind: MigrationKind::Up } dans le Vec<Migration> de lib.rs. Le SQL peut vivre comme constante dans database/mod.rs (mirror de SCHEMA + SEED_CATEGORIES).

🟡 Améliorations

  • Splitter cette issue en 1a / 1b : 1a = schema + service + AccountsPage comptes-only, 1b = SnapshotEditPage. Trop large telle quelle pour une seule PR.
  • Reporter l'entrée sidebar à Issue 3 : pointer /balance vers AccountsPage placeholder est une UX confuse en transition.
  • Préciser Migration { version: 9, ... } explicitement (pas "à déterminer") — éviter de modifier accidentellement une migration existante (checksums protégés).
  • Ajouter CHECK constraints kind invariants sur balance_snapshot_lines : CHECK ((quantity IS NULL AND unit_price IS NULL) OR (quantity IS NOT NULL AND unit_price IS NOT NULL)).
  • Ajouter les fichiers de tests dans la portée : balance.service.test.ts, useBalance.test.ts, #[cfg(test)] mod tests côté Rust.
## /review-spec — findings critiques + améliorations Review adversariale du spec (3 agents : Sécurité / Architecture / Technique). Voir spec-plan-bilan.md (annotations inline + section "Revision — Synthese"). ### 🔴 Critiques bloquants **1. CRUD via service TypeScript, pas via commandes Tauri** (Architecture) Les services existants utilisent `getDb()` + `tauri-plugin-sql` directement depuis TS (96 occurrences dans 15 services). Les commandes Tauri sont réservées au filesystem, OAuth, license, profils, feedback — pas au CRUD domaine. Les ~17 commandes balance proposées dupliquent la couche SQL en Rust pour rien. **Fix :** Tout le CRUD passe dans `balance.service.ts` avec `getDb()`. Les commandes Rust se réduisent à 2 : `fetch_price` (Issue 5) et `compute_account_return` (Issue 4). **2. Migration inline dans `lib.rs`, pas de fichier séparé** (Architecture+Technique) Le path `src-tauri/migrations/NNNN_balance_schema.sql` est faux — ce dossier n'existe pas. Toutes les 8 migrations existantes sont inline via `tauri_plugin_sql::Migration` dans `lib.rs`. Contredit `.claude/rules/sql-migrations.md`. **Fix :** Ajouter `Migration { version: 9, description: "create balance schema", sql: BALANCE_SCHEMA, kind: MigrationKind::Up }` dans le `Vec<Migration>` de `lib.rs`. Le SQL peut vivre comme constante dans `database/mod.rs` (mirror de `SCHEMA` + `SEED_CATEGORIES`). ### 🟡 Améliorations - **Splitter cette issue en 1a / 1b** : 1a = schema + service + AccountsPage comptes-only, 1b = SnapshotEditPage. Trop large telle quelle pour une seule PR. - **Reporter l'entrée sidebar à Issue 3** : pointer `/balance` vers AccountsPage placeholder est une UX confuse en transition. - **Préciser `Migration { version: 9, ... }`** explicitement (pas "à déterminer") — éviter de modifier accidentellement une migration existante (checksums protégés). - **Ajouter CHECK constraints kind invariants** sur `balance_snapshot_lines` : `CHECK ((quantity IS NULL AND unit_price IS NULL) OR (quantity IS NOT NULL AND unit_price IS NOT NULL))`. - **Ajouter les fichiers de tests** dans la portée : `balance.service.test.ts`, `useBalance.test.ts`, `#[cfg(test)] mod tests` côté Rust.
maximus changed title from Bilan #1 — Schéma SQL + saisie manuelle simple kind to Bilan #1a — Schema migration + balance.service skeleton + AccountsPage comptes 2026-04-25 18:07:11 +00:00
maximus modified the milestone from spec-price-fetching to overnight-2026-04-26-bilan 2026-04-25 18:17:51 +00:00
maximus added
status:in-progress
and removed
status:ready
labels 2026-04-25 18:26:29 +00:00
maximus added
status:approved
and removed
status:in-progress
labels 2026-04-25 18:39:15 +00:00
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#138
No description provided.