Simpl-Resultat/CLAUDE.md
le king fu e2b8eb8b22
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m38s
docs: architecture, ADR 0019, user guide and changelog for the import format
Last link of the ten-link import-format stack. Links 1-9 deliberately wrote
no changelog and no documentation, to avoid a conflict at every level of a
linear pile; this link owes all of it.

- ADR 0019 records the structuring decision: the import format is a fully
  persisted value, never re-inferred. It documents the three independent paths
  by which it used to be lost (hardcoded restore, header drift, data export),
  and why a single codec with a completeness test closes the class rather than
  a composed type -- the two carriers are structurally incompatible
  (`has_header` is boolean on one and number on the other). `template_id` is
  recorded as a provenance label, never re-read as format.
- `docs/architecture.md` gains a dedicated "Import CSV" section covering the
  codec, the lexical detection layer and its separate dictionary module, the
  bank signatures, the now-mandatory preview step, and sources/templates in
  the SREF envelope. Migration v17 and its four CHECK-guarded columns are
  listed in the migrations table.
- Stale counts corrected against the tree, not by arithmetic: 16 -> 17
  migrations (both files), `src/components/import/` 13 -> 14, `src/utils/`
  4 -> 13. Tables (20) and indexes (24) were re-measured and are NOT stale --
  v17 is an ALTER TABLE only -- so they are left as they are, with the reason
  written down. ADR 0018, missing from the ADR table, is added.
- The user guide and the `docs.*` keys in both locales carry the same new
  import journey: automatic detection, confidence score, mandatory preview
  with its signed recap, sign inversion, recognised bank formats, drift panel,
  and the safe repair path.
- Both changelogs carry the same entries, translated, verified section by
  section including issue references. The `public/` copies sync automatically
  via `syncChangelogs()`.

1176 vitest green, build clean, cargo check clean. No DB migration.

Resolves #332

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 11:13:25 -04:00

11 KiB

CLAUDE.md — Simpl'Résultat

@STATE.md

Contexte du projet

Simpl'Résultat est une application de bureau desktop privacy-first pour la gestion des finances personnelles. Elle traite localement les fichiers CSV bancaires sans aucune dépendance cloud. Projet solo entrepreneurial, en développement par Max.

Stack technique : Tauri v2 + React 19 + TypeScript + Tailwind CSS v4 Backend : Rust (commandes Tauri) Stockage : SQLite local (tauri-plugin-sql) Langues supportées : Français (FR) et Anglais (EN) Plateformes : Windows, Linux Version actuelle : 0.6.3 Licence : GPL-3.0-only


Principes fondamentaux

Privacy-first — NON NÉGOCIABLE

  • Zéro donnée envoyée vers un serveur tiers
  • Tout le traitement CSV et toutes les données financières restent en local
  • Aucune télémétrie, aucun analytics cloud

Précision financière

  • Toujours valider les montants selon les règles de parsing configurables (gestion des virgules/points, espaces, symboles monétaires)
  • Gérer l'encodage des fichiers CSV (UTF-8, Windows-1252, ISO-8859-15)

Internationalisation (i18n)

  • Toute chaîne affichée à l'utilisateur doit passer par le système i18n (i18next + react-i18next)
  • Jamais de texte en dur dans les composants React
  • Fichiers de traduction : src/i18n/locales/fr.json et src/i18n/locales/en.json

Architecture & structure du code

src/
├── components/          # 53 composants React organisés par domaine
│   ├── adjustments/     # Ajustements
│   ├── budget/          # Budget
│   ├── categories/      # Catégories hiérarchiques
│   ├── dashboard/       # Tableau de bord
│   ├── import/          # Wizard d'import (14 composants)
│   ├── layout/          # AppShell, Sidebar
│   ├── profile/         # Profils (PIN, formulaire, switcher)
│   ├── reports/         # Graphiques et rapports
│   ├── settings/        # Paramètres
│   ├── shared/          # Composants réutilisables
│   └── transactions/    # Transactions
├── contexts/            # ProfileContext (état global profil)
├── hooks/               # 13 hooks custom (useReducer)
├── pages/               # 11 pages
├── services/            # 14 services métier
├── shared/              # Types et constantes partagés
├── utils/               # Utilitaires (parsing, CSV, charts)
├── i18n/                # Config i18next + locales FR/EN
├── App.tsx              # Router principal (react-router-dom)
└── main.tsx             # Point d'entrée

src-tauri/
├── src/
│   ├── commands/        # 3 modules, 17 commandes Tauri
│   │   ├── fs_commands.rs           # Système de fichiers (6 commandes)
│   │   ├── export_import_commands.rs # Export/import chiffré (5 commandes)
│   │   └── profile_commands.rs      # Gestion des profils (6 commandes)
│   ├── database/        # Schémas SQL et migrations
│   │   ├── schema.sql               # Schéma initial (v1)
│   │   ├── seed_categories.sql      # Seed catégories (v2)
│   │   └── consolidated_schema.sql  # Schéma complet (nouveaux profils)
│   ├── lib.rs           # Point d'entrée, 17 migrations inline, plugins
│   └── main.rs
└── Cargo.toml

Règles d'architecture :

  • La logique métier va dans services/, jamais directement dans les composants
  • L'état de chaque domaine est géré par un hook useReducer dédié dans hooks/
  • Les composants React sont responsables de l'affichage uniquement
  • Toute opération sur les fichiers système passe par les commandes Tauri (Rust)
  • Les requêtes SQL passent par les services TypeScript via tauri-plugin-sql

Fonctionnalités principales

  • Import CSV : wizard multi-étapes, détection auto (encodage, délimiteur, colonnes par libellé FR/EN, formats de banques connus) avec score de confiance, aperçu obligatoire à récap signé avant tout import, templates de config, déduplication par fichier. Le format d'import est persisté en entier sur la source et jamais re-devinéADR 0019
  • Catégorisation : automatique (mots-clés avec priorité) et manuelle, drag-and-drop pour réorganiser
  • Transactions : filtrage, tri, split sur plusieurs catégories, notes
  • Budget : grille 12 mois, templates réutilisables, budget vs réel
  • Rapports : tendances mensuelles, répartition par catégorie, évolution dans le temps, graphiques interactifs (SVG patterns, menu contextuel)
  • Multi-profils : bases de données séparées, protection par PIN (Argon2), switching rapide
  • Export/Import : JSON/CSV avec chiffrement AES-256-GCM optionnel (format SREF)
  • Mises à jour : auto-updater intégré (tauri-plugin-updater)
  • Changelog bilingue : page /changelog avec historique complet, notes de version dynamiques FR/EN depuis CHANGELOG.md / CHANGELOG.fr.md (bundlés dans public/)

Conventions de code

React / TypeScript

  • Un composant = un fichier .tsx, nommé en PascalCase
  • Hooks custom dans hooks/, services dans services/
  • État local via useReducer dans les hooks de domaine

Rust / Tauri

  • Toutes les commandes Tauri retournent Result<T, String> pour la gestion d'erreurs
  • Documenter chaque commande avec un commentaire sur son rôle

Général

  • Commits en anglais, commentaires de code en anglais
  • Messages d'interface en français ET anglais (via i18n)
  • Tester les cas limites de parsing CSV (montants négatifs, cellules vides, formats inattendus)

Base de données

  • 20 tables SQLite, 24 index (voir docs/architecture.md pour le détail). Le module Bilan en représente 7 tables (balance_categories, balance_accounts, balance_snapshots, balance_snapshot_lines, balance_account_transfers, puis balance_securities + balance_snapshot_holdings ajoutées en Étape 2 — détail par titre) et 9 index. Ces deux comptes sont inchangés depuis v13 : v14-v16 ajoutent 2 tables + 2 index (déjà comptés), v17 est un ALTER TABLE pur
  • 17 migrations inline dans lib.rs (v1→v17, via tauri_plugin_sql::Migration). Étape 2 du Bilan (détail par titre) : v14 (balance_securities + balance_snapshot_holdings + 2 index), v15 (balance_accounts.kind + detailed_since + backfill), v16 (conversion des comptes cotés existants en détaillés 1-position) — voir ADR 0015. Import : v17 (import_sources.amount_mode + sign_convention, les deux avec CHECK, + header_signature + template_id) — voir ADR 0019
  • Schéma consolidé (consolidated_schema.sql) pour l'initialisation des nouveaux profils
  • Les migrations appliquées sont protégées par checksum — ne jamais modifier une migration existante, toujours en créer une nouvelle

Documentation technique

La documentation technique est centralisée dans docs/ :

  • docs/architecture.md — Architecture technique complète (stack, BDD, services, hooks, commandes Tauri, routing, i18n, CI/CD)
  • docs/adr/ — Architecture Decision Records (décisions techniques structurantes)
  • docs/guide-utilisateur.md — Guide utilisateur
  • docs/archive/ — Anciennes spécifications archivées

Règle : quand un changement touche l'architecture, mettre à jour la documentation :

  • Nouveau service, hook, commande Tauri, page/route, ou table SQL → mettre à jour docs/architecture.md
  • Décision technique structurante (choix de librairie, pattern architectural, changement de stratégie) → créer un nouvel ADR dans docs/adr/
  • Changement affectant l'utilisation de l'app → mettre à jour docs/guide-utilisateur.md et les traductions i18n correspondantes (src/i18n/locales/fr.json, src/i18n/locales/en.json, clés sous docs.*)

Règle CHANGELOG : tout changement affectant le comportement utilisateur → ajouter une entrée sous ## [Unreleased] dans les deux fichiers :

  • CHANGELOG.md (anglais) — source principale
  • CHANGELOG.fr.md (français) — traduction
  • Catégories : Added/Ajouté, Changed/Modifié, Fixed/Corrigé, Removed/Supprimé
  • Format Keep a Changelog. Le contenu est extrait automatiquement par le CI pour les release notes et affiché dans l'app selon la langue de l'utilisateur.
  • The public/ copies are synced automatically: Vite copies them on dev/build start via syncChangelogs() in vite.config.ts. No manual sync needed.

Points d'attention RS&DE / CRIC

Pour maintenir l'éligibilité aux crédits d'impôt R&D (RS&DE fédéral + CRIC Québec) :

  • Documenter les incertitudes technologiques rencontrées pendant le développement
  • Noter les expérimentations et les approches alternatives testées
  • Garder un journal des avancées techniques (dans /docs/rnd-journal/)
  • Les algorithmes de catégorisation automatique et le parsing multi-format sont des activités R&D éligibles

CI/CD

Workflows Forgejo Actions dans .forgejo/workflows/. Le runner est à capacité 1 — les jobs se suivent, ils ne tournent pas en parallèle.

  • check-rust.yml — déclenché sur les PR touchant src-tauri/** ou .cargo/**. Lance cargo check, une vérification bloquante que les advisories acceptées restent non atteignables, cargo test et un cargo audit informatif. Doit être vert avant tout merge.
  • check-frontend.yml — déclenché sur les PR, sauf si tous les fichiers modifiés sont du Rust, de la doc ou du markdown. Lance npm run build (tsc + vite) et npm test (vitest). Doit être vert avant tout merge. Aucune étape npm audit : les advisories npm ne sont pas un gate de CI. npm audit remonte 2 high en permanence — une seule advisory react-router (mode RSC, inatteignable dans une app de bureau sans serveur), acceptée et suivie en #317.
  • audit.yml — audit RustSec quotidien (06:00 UTC) + workflow_dispatch, pour couvrir les avis de sécurité entre deux PR Rust. Échec bloquant. Un run vert signifie « zéro advisory hors de la liste acceptée », pas « zéro advisory » : cette liste est dans .cargo/audit.toml (preuve de non-atteignabilité et condition de retrait par entrée), encadrée par l'ADR 0018. Ne jamais y ajouter une advisory atteignable ni élargir une entrée à un crate entier.
  • release.yml — déclenché par les tags v*. Build Windows (NSIS .exe) + Linux (.deb, .rpm), signe les binaires et publie le JSON d'updater pour les mises à jour automatiques.

Aucun workflow check-* ne filtre sur branches: : une PR stackée sur une autre branche de feature déclenche donc bien la CI. Le cache Actions est retiré partout tant que #234 (connectivité du serveur de cache) n'est pas réglé — restore et save échouent tous les deux. Le miroir .github/workflows/ est dormant (aucune PR côté GitHub).


Ressources clés