npm update postcss moves it 8.5.13 -> 8.5.23, clearing GHSA-r28c-9q8g-f849 (path traversal in previous-source-map auto-loading via a sourceMappingURL comment, arbitrary .map disclosure, 7.5 high). No overrides entry needed, unlike #241: vite declares postcss ^8.5.3 and 8.5.23 is published, so the existing range already permitted the fix and only the lockfile carried a stale resolution. nanoid 3.3.11 -> 3.3.16 comes along as postcss's own dependency, within its declared range. postcss IS the CSS pipeline, so a green build only proves compilation. The emitted stylesheet was diffed across the bump and is byte-for-byte identical (same content hash, same asset filename). The remaining react-router advisory (GHSA-qwww-vcr4-c8h2, RSC Mode CSRF bypass) is accepted rather than fixed. It targets React Server Components, which a Tauri desktop app never runs — App.tsx mounts a client-only BrowserRouter and src/ has no createStaticHandler, StaticRouter or server rendering. There is also nothing to move forward to: react-router-dom is frozen at 7.18.1 since v8 merged the package into react-router, so npm's proposed "fix" is a downgrade to 7.11.0, and leaving the affected range means migrating to react-router v8. Re-evaluation trigger tracked in #317. Unlike the Rust side, no CI gate is involved: check-frontend.yml runs no npm audit step, so nothing turns red. That expectation is now written down in docs/architecture.md and CLAUDE.md so the two permanent high findings do not read as a regression. npm audit: 3 findings -> 2 (high 3 -> 2), postcss cleared. npm ci + npm run build + 871 vitest green. Resolves #311 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.jsonetsrc/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 (13 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, 7 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
useReducerdédié danshooks/ - 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 de l'encodage/délimiteur, templates de config, déduplication par fichier
- 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
/changelogavec historique complet, notes de version dynamiques FR/EN depuisCHANGELOG.md/CHANGELOG.fr.md(bundlés danspublic/)
Conventions de code
React / TypeScript
- Un composant = un fichier
.tsx, nommé en PascalCase - Hooks custom dans
hooks/, services dansservices/ - État local via
useReducerdans 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.mdpour le détail). Le module Bilan en représente 7 tables (balance_categories,balance_accounts,balance_snapshots,balance_snapshot_lines,balance_account_transfers, puisbalance_securities+balance_snapshot_holdingsajoutées en Étape 2 — détail par titre) et 9 index - 16 migrations inline dans
lib.rs(v1→v16, viatauri_plugin_sql::Migration). Étape 2 (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 - 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 utilisateurdocs/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.mdet les traductions i18n correspondantes (src/i18n/locales/fr.json,src/i18n/locales/en.json, clés sousdocs.*)
Règle CHANGELOG : tout changement affectant le comportement utilisateur → ajouter une entrée sous ## [Unreleased] dans les deux fichiers :
CHANGELOG.md(anglais) — source principaleCHANGELOG.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 ondev/buildstart viasyncChangelogs()invite.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 touchantsrc-tauri/**ou.cargo/**. Lancecargo check, une vérification bloquante que les advisories acceptées restent non atteignables,cargo testet uncargo auditinformatif. 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. Lancenpm run build(tsc + vite) etnpm test(vitest). Doit être vert avant tout merge. Aucune étapenpm audit: les advisories npm ne sont pas un gate de CI.npm auditremonte 2 high en permanence — une seule advisoryreact-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 tagsv*. 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
- Tauri v2 Docs
- React Docs
- SQLite via Tauri
- Architecture détaillée :
docs/architecture.md - Décisions techniques :
docs/adr/