|
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m44s
Three ways an imported amount could be silently wrong, all of them passing validation, all of them fixed here. The two-column rule was `isNaN(credit) ? -debit : credit`, so the credit always won. Many banks write `0,00` in the unused column rather than leaving it empty, and `isNaN(0)` is false -- every debit of such a file imported as 0,00 and the expense simply vanished, with no error anywhere. The rule is `credit - debit` on magnitudes now, which needs no special case for a `0,00` cell (zero is the identity of the subtraction) and implements the documented convention even when an export negates its debits. A row unreadable in BOTH columns is an error instead of a free 0,00 transaction. `parseFrenchAmount` ended on `parseFloat`, which returns the longest valid PREFIX instead of rejecting. Measured before the fix: `"50,00-"` -> 5000, `"1 234,56 CR"` -> 123456, `"100,00 CAD"` -> 10000. A factor-100 error, and it passes `isNaN`, so those rows counted as VALID everywhere downstream -- which would have defeated the signed preview (#329), the safety net of the whole chantier. Validation is anchored over the whole normalized string now and any residual character yields NaN. NaN, not a rescued magnitude, for a trailing `CR`/`DB` or currency code. Two reasons: `CR`/`DB` carry a DIRECTION, so returning a magnitude for both would trade a loud failure for a silent SIGN error (the D/C-indicator shape is refused upstream by design, #328); and `"100,00 CAD"` is structurally identical to `"2025 Montant"`, so whitelisting a trailing word to rescue the first re-blinds `detectHeader` on the second. Two accounting forms ARE legitimate and supported: parentheses `(50,00)` and a trailing sign `50,00-`. The `?? 0` fallbacks read column 0 -- usually the date -- when the mapping was incomplete. An unmapped amount column is an explicit row error now, reported ahead of any per-row problem since it is a format error affecting every row. `1.234` is 1234 in a French column and 1.234 in an English one, and no rule applied to that cell ALONE can tell. `detectDecimalSeparator` arbitrates from the decisive siblings of the column and `parseFrenchAmount` takes the verdict as an option. Detection deliberately stays out of it: it runs before a column is known to be an amount column at all, so the verdict is applied where the value actually becomes a transaction. The rule itself moves out of the hook as a pure `mapRow(raw, format)` in `importFormat.ts`. That is what lets the corpus tests run the REAL rule -- the hand-written mirror in `csvAutoDetect.test.ts` and the static guard pinning five `parseFilesInternal` expressions are both deleted -- and what stops the detection score (#328) and the signed preview (#329) each re-implementing it. Hardening is global: the parser is shared by 11 call sites, 8 in `csvAutoDetect.ts` and 3 in the holdings CSV import (#245), where a price cell `150,25 CAD` used to store 15025. It is refused now and `buildDetailedLines` raises on the empty price. An unreadable QUANTITY was worse -- coerced to 0, so a zero-value position saved in silence; the draft keeps the offending text instead and the existing `snapshot_priced_quantity_required` fires. Row errors become i18n keys (`import.rowErrors.*`) rather than the raw English literals rendered straight into the preview table, since this adds a user-visible string. The report table also carries raw exception messages, so both render sites resolve through `isRowErrorKey` and never feed `t()` anything that is not ours. Test churn, per link 1's handoff (update the expectation, drop the marker, never delete the test): the three `#325` KNOWN DEFECT blocks in `amountParser.test.ts` flip, plus `unused-column-zero` in `csvAutoDetect.test.ts`. One block tagged `#328` flips too -- `header-numeric-label`, whose own comment reads "#328 adds a lexical signal to detectHeader, and #325 anchors the parser [...] either fix closes this". The anchored parser landed first. The other `#328` blocks (`debit-credit-reversed`, `absolute-indicator`) and the `#329` block are verified unchanged. CHANGELOG and docs stay centralized in the last link of the stack, as the plan specifies. 989 vitest (963 before), tsc + vite build clean, cargo check clean. No DB migration. Resolves #325 |
||
|---|---|---|
| .cargo | ||
| .claude | ||
| .forgejo/workflows | ||
| .github/workflows | ||
| config | ||
| docs | ||
| public | ||
| src | ||
| src-tauri | ||
| tasks | ||
| tests/smoke | ||
| .gitignore | ||
| CHANGELOG.fr.md | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| index.html | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| spec-decisions-collapse-multi-niveaux.md | ||
| spec-decisions-feature-gating.md | ||
| spec-decisions-import-csv-format.md | ||
| spec-decisions-refonte-seed-categories-ipc.md | ||
| spec-issue-66-oauth-keychain.md | ||
| spec-monetisation.md | ||
| spec-plan-collapse-multi-niveaux.md | ||
| spec-plan-feature-gating.md | ||
| spec-plan-import-csv-format.md | ||
| spec-plan-refonte-seed-categories-ipc.md | ||
| spec-refonte-rapports.md | ||
| spec-simpl-resultat-web.md | ||
| STATE.md | ||
| tsconfig.json | ||
| tsconfig.node.json | ||
| vite.config.ts | ||
Simpl'Résultat
Application de bureau 100 % locale pour importer, catégoriser et analyser vos transactions financières personnelles ou d'entreprise. Aucune donnée ne quitte votre ordinateur.
Fonctionnalités
- Import CSV — Importez vos relevés bancaires depuis plusieurs sources avec auto-détection des colonnes et modèles d'import réutilisables
- Tableau de bord — Vue d'ensemble avec KPIs, répartition par catégorie et dernières transactions
- Transactions — Parcourez, recherchez et filtrez avec sélection rapide de période
- Catégorisation automatique — Attribution automatique par mots-clés, avec ajustement manuel
- Split de transactions — Répartissez une transaction sur plusieurs catégories
- Budgets — Grille budgétaire 12 mois par catégorie avec modèles et rapport Budget vs Réel
- Ajustements — Ajustements ponctuels ou récurrents par catégorie
- Rapports — Tendances mensuelles, répartition par catégorie, évolution dans le temps, budget vs réel
- Graphiques interactifs — Motifs SVG, menu contextuel (clic droit), détail des transactions par catégorie
- Profils multiples — Bases de données séparées avec protection PIN optionnelle
- Export / Import de données — Sauvegarde complète avec chiffrement AES-256-GCM optionnel
- Mode sombre — Thème sombre avec palette gris chaud
- Bilingue — Interface disponible en français et en anglais
- Guide utilisateur intégré — Documentation complète accessible depuis les paramètres, imprimable en PDF
- Mise à jour automatique — Notifications et installation des nouvelles versions depuis l'application
Installation
Windows
- Rendez-vous sur la page Releases
- Téléchargez le fichier
.exe(installateur NSIS) - Lancez le fichier téléchargé
Note : Windows SmartScreen peut afficher un avertissement car l'application n'est pas signée numériquement. Cliquez sur « Informations complémentaires » puis « Exécuter quand même » pour continuer.
Linux
- Rendez-vous sur la page Releases
- Téléchargez le format adapté à votre distribution :
.debpour Debian / Ubuntu.rpmpour Fedora / openSUSE.AppImagepour toute distribution (exécutable universel)
- Installez le paquet ou lancez l'AppImage directement
Démarrage rapide
1. Choisir ou créer un profil
Au premier lancement, un profil par défaut est créé. Vous pouvez ajouter d'autres profils (chacun avec sa propre base de données) et les protéger par un PIN.
2. Configurer le dossier d'import
Organisez vos fichiers CSV dans un dossier avec un sous-dossier par source :
Documents/
Comptabilité/
Desjardins/
releve-2024-01.csv
releve-2024-02.csv
Autre banque/
export.csv
3. Importer des transactions
- Allez dans Import
- Sélectionnez le dossier source et les fichiers CSV
- Configurez le mappage des colonnes (ou utilisez un modèle d'import sauvegardé)
- Vérifiez les doublons puis lancez l'import
4. Consulter le tableau de bord
Le tableau de bord affiche automatiquement :
- Les KPIs du mois (revenus, dépenses, solde)
- La répartition des dépenses par catégorie
- Les dernières transactions
5. Parcourir et catégoriser les transactions
- Utilisez la recherche et les filtres (date, catégorie, source, période rapide)
- Modifiez la catégorie d'une transaction en cliquant dessus
- Ajoutez des mots-clés pour automatiser les futures catégorisations
- Scindez une transaction sur plusieurs catégories si nécessaire
6. Gérer les budgets
- Définissez un budget mensuel par catégorie sur une grille 12 mois
- Créez des modèles budgétaires réutilisables
- Consultez le rapport Budget vs Réel pour suivre vos écarts
7. Analyser les rapports
- Tendances — Évolution mensuelle des revenus et dépenses
- Catégories — Répartition détaillée par catégorie (clic droit pour masquer ou voir le détail)
- Évolution — Suivi dans le temps par catégorie
- Budget vs Réel — Comparaison mensuelle et cumul annuel
8. Guide utilisateur
Un guide complet est accessible via Paramètres → Guide utilisateur. Il couvre toutes les fonctionnalités et peut être imprimé ou exporté en PDF.
Développement
Prérequis
Lancer en mode développement
npm install
npm run tauri dev
Compiler l'application
npm run tauri build
Les installateurs sont générés dans src-tauri/target/release/bundle/.
Publier une nouvelle version
- Mettez à jour la version dans
src-tauri/tauri.conf.jsonetpackage.json - Committez les changements
- Créez et poussez un tag :
git tag v0.3.7
git push origin v0.3.7
Le workflow GitHub Actions compile automatiquement l'application pour Windows et Linux, puis publie les installateurs dans une nouvelle Release.
Technologies
| Technologie | Rôle |
|---|---|
| Tauri v2 | Framework desktop (Rust backend) |
| React 19 | Interface utilisateur |
| SQLite | Base de données locale |
| Tailwind CSS v4 | Styles |
| Recharts | Graphiques |
| react-i18next | Internationalisation |
| PapaParse | Parsing CSV |