# Journal des modifications

## [Non publié]

### Ajouté

- Migration des catégories : les catégories personnalisées sans correspondance standard peuvent désormais être **fusionnées** dans une catégorie standard, au lieu d'être seulement mises de côté. Chaque catégorie personnalisée du bloc « Catégories personnalisées » reçoit le même sélecteur de cible que les lignes du seed — choisissez une feuille standard et ses transactions, budgets, mots-clés et fournisseurs y sont réassignés, puis la catégorie personnalisée est retirée. Laisser une catégorie personnalisée non mappée conserve le comportement précédent (regroupée sous « Catégories personnalisées (migration) ») et ne bloque jamais la migration (#259).

### Modifié

- L'application déverrouille désormais ses modules par édition — **Gratuite**, **Base** ou **Premium**, résolue depuis votre clé de licence. La Gratuite conserve le Tableau de bord, l'Import CSV, les Transactions, les Catégories, le rapport Tendances (et le hub Rapports), l'export/import chiffré et le journal des modifications, avec un seul profil. La **Base** débloque en plus le Budget, les Ajustements, les quatre rapports avancés (Faits saillants, Comparables, Analyse par catégorie, Cartes), les profils multiples et les mises à jour automatiques. La **Premium** débloque en plus le module Bilan complet (patrimoine, détail par titre, cours du marché). Les modules verrouillés restent visibles — un cadenas apparaît dans la barre latérale et sur les tuiles de rapports — et les ouvrir affiche un écran de déverrouillage avec un raccourci « J'ai déjà une clé » vers la carte de licence ; le bouton d'achat en ligne « Obtenir Base / Premium » est affiché mais désactivé pour l'instant (« bientôt disponible »). Le verrouillage n'est jamais destructif : quelle que soit l'édition, vos données sont conservées intactes et tout réapparaît dès qu'une clé valide est entrée — en Gratuite votre profil actif reste toujours accessible, seuls la création d'un profil supplémentaire ou le passage à un autre profil sont verrouillés (#297, #298, #299, #300, #301).

### Sécurité

- Mise à jour de deux dépendances Rust situées sur le chemin de la mise à jour automatique, corrigeant six advisories RustSec : `rustls-webpki` 0.103.9 → 0.103.13 (traitement des contraintes de nom de certificat et analyse des listes de révocation, dont une panique atteignable) et `tar` 0.4.44 → 0.4.46 (`chmod` de répertoires arbitraires en suivant des liens symboliques pendant l'extraction, et en-têtes de taille PAX mal pris en compte). Les deux sont tirées par `tauri-plugin-updater`, qui télécharge et décompresse les mises à jour de l'application : ce sont donc de vrais chemins de code du produit livré. Aucun changement de comportement. Trois autres advisories restent signalées sur le fichier de verrouillage mais ne s'appliquent pas au produit livré — `quick-xml` n'est compilé que pour des cibles Apple que nous ne livrons pas, et `rsa` n'est jamais compilé — elles sont désormais consignées comme acceptées, avec leur justification et les conditions de leur retrait, plutôt que de laisser l'audit de sécurité quotidien rouge en permanence (#310).
- Mise à jour de la dépendance de build `postcss` (8.5.13 → 8.5.23), corrigeant GHSA-r28c-9q8g-f849 (traversée de chemin lors du chargement automatique d'une source map précédente depuis un commentaire `sourceMappingURL`, menant à la divulgation de fichiers `.map` arbitraires). Outillage de build uniquement, aucun changement runtime ni de comportement — le CSS généré est identique octet pour octet. Une advisory reste signalée sur `react-router` et est volontairement laissée en l'état : elle vise le mode React Server Components, qu'une application de bureau locale n'exécute jamais, et aucun correctif n'existe vers lequel avancer puisque `react-router-dom` est figé en 7.18.1 (sortir de la plage concernée demanderait une migration vers react-router v8, pas un changement de version) (#311).

## [0.14.0] - 2026-07-18

### Modifié

- Rapports : les trois tableaux de rapport hiérarchiques (Comparaison réel-vs-réel, réel-vs-budget, et Tendances par catégorie) permettent désormais de **replier ou déplier chaque niveau de la hiérarchie de catégories**, plus seulement le premier. Chaque catégorie parente — y compris les intermédiaires — porte son propre chevron ; en déplier une révèle ses enfants directs (eux-mêmes repliés), pour descendre un niveau à la fois. Les tableaux s'ouvrent entièrement repliés (seules les catégories de premier niveau visibles), « Tout déplier » ouvre tous les niveaux d'un coup, et vos choix de repli sont désormais enregistrés **par profil** — dans la base de données du profil, donc détruits avec lui — au lieu du navigateur. Les sous-totaux et les lignes de résultat restent rigoureusement inchangés quel que soit ce que vous repliez (#288).
- Budget : la grille budget se **replie et se déplie elle aussi à chaque niveau de catégorie**, à l'image des rapports. Chaque catégorie parente porte un chevron, la grille **s'ouvre entièrement repliée** (seules les catégories de premier niveau visibles) pour un aperçu compact, et « Tout déplier » ouvre tous les niveaux en un clic. Replier une catégorie est purement visuel — les totaux de section et les lignes de résultat sont inchangés, et aucune valeur de budget que vous avez saisie n'est jamais perdue. Vos choix de repli sont enregistrés par profil (#289).

### Corrigé

- Arbre des catégories standard (le guide autonome comme l'étape d'aperçu de l'assistant de migration des catégories) : le bouton « Tout déplier / Tout replier » reflète désormais l'état réel de l'arbre — il reste sur « Tout déplier » tant que tous les groupes ne sont pas ouverts, au lieu de basculer sur « Tout replier » dès qu'une seule catégorie était dépliée (#290).

## [0.13.0] - 2026-07-12

### Ajouté

- Rapports → Comparaison : les deux rapports comparables hiérarchiques (réel vs réel et réel vs budget) permettent désormais de **replier ou déplier les sous-catégories de chaque catégorie parente**. Un chevron sur chaque catégorie de premier niveau masque son détail tout en gardant sa ligne de sous-total visible, et un bouton « Tout déplier / Tout replier » les bascule ensemble. Les groupes s'ouvrent **repliés** pour un aperçu compact au niveau des sous-totaux ; ce que vous dépliez est mémorisé par rapport (#254).
- Rapports → Tendances → par catégorie (vue tableau) : le tableau d'analyse de résultat est désormais **hiérarchique et repliable**, à l'image du rapport de comparaison. Les catégories parentes apparaissent en groupes indentés au-dessus de leurs sous-catégories, chacune avec son propre sous-total, et un chevron (plus un bouton « Tout déplier / Tout replier ») replie un groupe jusqu'à ce seul sous-total. Les groupes s'ouvrent **repliés**, et vos choix sont mémorisés séparément des tableaux comparables. La ligne **Résultat avant transferts** se place maintenant entre les sections de dépenses et la section des transferts au lieu du bas, et replier un groupe ne déplace aucun sous-total ni résultat — les chiffres sont toujours calculés sur l'ensemble des données (#265).
- Rapports : pose les fondations d'un futur filtre de comptes pour les rapports — le hook de période partagé suit désormais aussi une sélection multi-comptes via l'URL (mémorisable comme la plage de dates, et validée contre les URL malformées ou modifiées à la main). Purement interne pour l'instant : aucun contrôle de filtre visible encore, le sélecteur de comptes et le branchement par rapport arrivent dans des issues de suivi (#272).
- Rapports : les sept services de rapports (tendances, catégories dans le temps, comparaison réel-vs-réel, budget-vs-réel, dépenses par catégorie, et le tableau de bord Cartes) acceptent désormais un filtre multi-comptes optionnel, comparé à une liste paramétrée de sources d'import. Plomberie interne seulement — omettre le filtre partout donne des résultats identiques au byte près, et aucune page de rapport n'expose encore de contrôle de filtre ; cela arrive dans des issues de suivi (#273).
- Rapports : pose les fondations de l'interface du filtre de comptes — un panneau de filtre partagé affiche le contrôle de période propre à chaque rapport à côté d'une sélection multiple (cases à cocher) de vos sources d'import. Purement interne pour l'instant : aucune page de rapport n'affiche encore ce panneau, cela arrive dans des issues de suivi (#274).
- Rapports → Tendances : le panneau de filtre partagé apparaît désormais sur ce rapport, à côté du sélecteur de période. Cocher une ou plusieurs sources d'import restreint à la fois la vue mensuelle globale et le tableau de résultat par catégorie à ces sources ; ne rien cocher garde l'affichage de toutes les sources, inchangé (#275).
- Rapports → Comparaison et Budget : le panneau de filtre partagé apparaît désormais aussi sur ces deux rapports, à côté de leur contrôle de période existant (la comparaison garde son sélecteur de mois de référence, la grille budget garde son navigateur d'année — inchangés). Cocher une ou plusieurs sources d'import restreint le rapport de comparaison — y compris son onglet budget-vs-réel — et la colonne de référence de l'année précédente de la grille budget à ces sources ; ne rien cocher garde l'affichage de toutes les sources, inchangé (#276).

### Corrigé

- Rapports → Tendances → par catégorie (vue tableau) : le tableau d'analyse de résultat couvre désormais **toutes** les catégories au lieu des 50 plus grosses, et ses lignes de Résultat sont exactes. Deux catégories différentes portant le même nom ne sont plus fusionnées, et un petit revenu ou transfert n'est plus comptabilisé comme une dépense — les revenus et le résultat net s'additionnent donc correctement (#264).

### Modifié

- Rapports → Tendances : le rapport **s'ouvre désormais sur la vue « Par catégorie » en tableau** par défaut, au lieu du graphique mensuel global. Le tableau par catégorie comporte une section revenus, donc une catégorie de revenu (ex. votre paie) apparaît d'emblée — sans changer de vue au préalable. La vue que vous choisissez vous-même reste mémorisée (#262).
- Rapports → Comparaison (réel vs budget) : le tableau budget-vs-réel se lit désormais comme les autres rapports comparables — une **analyse de résultat**. Les catégories sont regroupées Revenus → Dépenses → Transferts (au lieu de Dépenses → Revenus → Transferts), et l'ancienne ligne « Total » plate est remplacée par une ligne **Résultat avant transferts** (affichée lorsque des transferts existent) et une ligne **Résultat net**, toutes deux colorées en vert pour un surplus, en rouge pour un déficit. Les montants de catégorie et de section sont inchangés (#277).
- Budget : la grille budget se lit désormais comme une analyse de résultat — les catégories sont regroupées **Revenus → Dépenses → Transferts** (auparavant dépenses en premier), et l'ancienne ligne « Total » brute est remplacée par deux lignes de résultat : **Résultat avant transferts** (revenus − dépenses) et **Résultat net** (après transferts), calculées sur les colonnes année précédente, annuelle et mensuelles. Toutes les catégories restent affichées sur la grille — elle demeure une surface d'édition, sans ligne masquée ni repliable (#278).
- Tableau de bord (`/`) : la page d'accueil adopte désormais le modèle du rapport Cartes. Les cartes d'indicateurs (revenus, dépenses, résultat net, taux d'épargne) affichent leur variation vs le mois précédent et vs l'an dernier (sélecteur de mois de référence, par défaut le dernier mois complet) ; les catégories en hausse/en baisse et le respect du budget sont présentés de la même façon que sur Cartes. Une nouvelle tuile **valeur nette** affiche le dernier total du Bilan — une métrique différente de toutes les autres cartes de la page, donc masquée (jamais un « 0 $ » trompeur) tant qu'aucun compte de bilan n'a de snapshot enregistré, et jamais affectée par le filtre de comptes ci-dessous. Le camembert des dépenses est remplacé par des **barres classées** des catégories de dépense les plus importantes, et le filtre de comptes (sources d'import) — introduit sur Tendances/Comparaison/Budget — s'applique désormais aussi aux widgets transactionnels du tableau de bord (#279).

## [0.12.0] - 2026-07-05

### Modifié

- Rapports → Comparaison (réel vs réel) : le rapport est désormais une **analyse de résultat**. Les catégories de revenu apparaissent aux côtés des dépenses, avec deux lignes de résultat — **résultat avant transferts** (revenus − dépenses) et **résultat net** (après annulation des transferts) — pour voir d'un coup d'œil si la période dégage un surplus ou un déficit. Les catégories sont regroupées Revenus → Dépenses → Transferts, les couleurs suivent le sens (plus de revenu = vert, plus de dépense = rouge), et un montant de résultat passe au vert pour un surplus, au rouge pour un déficit (#253).
- Rapports : les rapports comparables s'ouvrent désormais par défaut sur le **mois précédent (dernier mois complet)** au lieu de décembre de l'année civile courante (#253).
- Rapports → Tendances → Par catégorie (vue tableau) : le tableau des catégories dans le temps se lit désormais comme une analyse de résultat, à l'image du rapport de comparaison. Les catégories sont regroupées en sections **Revenus → Dépenses → Transferts** avec des sous-totaux par mois et un total, et l'ancienne ligne « Total » mélangée — qui additionnait revenus, dépenses et transferts en valeurs absolues pour un chiffre sans signification — est remplacée par une ligne **Résultat net** par mois (revenus − dépenses + transferts), colorée en vert pour un surplus et en rouge pour un déficit, plus une ligne **Résultat avant transferts** affichée lorsque des transferts existent. Les cellules de catégorie restent des niveaux neutres ; seules les lignes de résultat portent une couleur de signe (#256).

## [0.11.0] - 2026-07-05

### Ajouté

- Rapports → Comparaison (réel vs réel) : le rapport comparable s'affiche désormais en **hiérarchie de catégories avec sous-totaux**, comme le rapport de budget. Les catégories parentes regroupent leurs enfants dans une ligne de sous-total — sa valeur est le net du groupe, donc un groupe de transferts équilibrés s'annule à ~0 — avec les lignes réparties en sections Dépenses / Revenus / Transferts portant des totaux par section et un total général, plus un choix sous-totaux en haut/en bas. Les montants des catégories feuilles sont inchangés, et l'annulation des transferts du correctif précédent est préservée (#247).
- Bilan : un compte détaillé (par titre) peut désormais **importer ses positions depuis un CSV** au lieu d'ajouter chaque titre un à un. Depuis un snapshot, un bouton « Importer un CSV » à côté de « Ajouter un titre » ouvre un sélecteur de fichier ; le séparateur, l'encodage et les colonnes (symbole, quantité et — au besoin — cours et coût d'acquisition) sont détectés automatiquement et ajustables avant l'import. Les lignes partageant un symbole sont fusionnées en une seule position, et un CSV sans colonne de cours importe tout de même les quantités pour récupérer ou saisir le prix ensuite (#245).

### Modifié

- Bilan : la page d'accueil du bilan est désormais un hub de tuiles. Avoir des comptes mais aucun snapshot ne vous bloque plus sur une invite « créer un snapshot » — la page affiche maintenant des tuiles de navigation, et **Gérer les comptes** est accessible en tout temps, y compris depuis le tableau de bord peuplé. La page de gestion des comptes (créer/modifier/archiver les comptes et les types d'actif) n'était auparavant accessible qu'en tapant son URL (#244).
- Migration des catégories (Paramètres → Catégories → migrer vers le jeu standard) : la catégorie cible de l'étape d'aperçu est désormais modifiable sur **chaque** ligne, et non plus seulement celles « à réviser ». Chaque ligne offre un champ de recherche avec autocomplétion (insensible aux accents), pour corriger une cible détectée automatiquement aussi facilement que résoudre une ligne sans correspondance (#246).

### Sécurité

- Mise à jour de dépendances pour corriger quatre advisories signalés par `npm audit` : `react-router-dom` 7.13 → 7.18.1 (ce qui tire `react-router` au-delà des advisories RCE turbo-stream, DoS `__manifest`/single-fetch et XSS de redirection RSC), plus l'outillage de développement `vite` 6.4.2 → 6.4.3 et `vitest` 4.0.18 → 4.1.9. Aucun changement de comportement. L'app est livrée comme un client de bureau local : les advisories runtime (qui nécessitent un serveur SSR/RSC react-router) ne s'appliquaient pas au produit livré ; ce sont des mises à jour de durcissement (#235, #236, #237, #238).
- Épinglé la dépendance transitive de build `@babel/core` en 7.29.7 via une entrée `overrides` scopée (sous `@vitejs/plugin-react`), corrigeant le dernier advisory `npm audit` (GHSA-4x5r-pxfx-6jf8, lecture de fichier arbitraire via un commentaire `sourceMappingURL`, sévérité faible). Outillage de build uniquement — aucun changement runtime ni de comportement — et `npm audit` est désormais propre (#241).

### Corrigé

- Rapports → Comparaison (réel vs réel) : les catégories de type transfert (ex. « Paiement CC ») s'annulent maintenant à ~0 au lieu d'afficher seulement leurs sorties. Un transfert est un mouvement d'argent, pas une dépense — son débit et son crédit correspondant sur la même période se compensent. Les catégories de dépense et de revenu conservent exactement leurs montants précédents (#243).

## [0.10.1] - 2026-06-30

### Corrigé

- Bilan : correction d'une erreur **« database is locked »** qui pouvait apparaître après avoir commencé un snapshot puis quitté la page avant d'enregistrer, bloquant ensuite toute écriture jusqu'au redémarrage de l'app. Tout l'accès à la base est désormais sérialisé, et une transaction tient une seule connexion sur toute sa durée — une transaction d'écriture ne peut donc plus rester bloquée entre deux connexions SQLite (la cause racine). Aucune donnée enregistrée n'a été menacée ; seul le snapshot en cours était perdu (#230).
- La console de journaux intégrée (Paramètres → Systèmes → Journaux) se met maintenant à jour **en direct** à mesure que les événements surviennent, au lieu de n'afficher que les entrées présentes avant l'ouverture de la page. Les enregistrements de snapshot et leurs échecs sont désormais journalisés, donc les problèmes de base de données y apparaissent (#230).

## [0.10.0] - 2026-06-29

### Ajouté

- Bilan : **saisie de snapshot par titre**. Un compte *détaillé* se saisit désormais titre par titre — chaque position a sa propre ligne avec un sélecteur de titre (autocomplétion sur vos titres existants, avec création inline d'un nouveau symbole), quantité, cours (avec la récupération automatique de prix optionnelle), coût d'acquisition, et un gain latent calculé en direct. La valeur du compte est la somme affichée de ses positions. Les comptes simples sont inchangés. Le sélecteur de titre accepte n'importe quel symbole normalisé (MAJUSCULES/sans espaces) — pas de validation en direct du symbole, puisque la récupération du prix est une étape séparée et au mieux ; vous choisissez la classe d'actif (Action / Crypto) à la création d'un nouveau symbole (#214).
- Bilan : **détailler un compte agrégé en titres** (assistant). Un compte *simple* peut être basculé en *détaillé* via l'action « Détailler en titres » dans le tableau des comptes. La bascule est à sens unique : elle passe le compte en détaillé et fixe la date du jour comme date de bascule (pivot, `detailed_since`) — l'historique agrégé passé reste figé en lecture seule, et les titres se saisissent au prochain snapshot normal (l'assistant ne capture pas de portefeuille initial). Une fois un titre saisi, le compte ne peut plus revenir en saisie simple (verrouillé à la fois dans l'interface et dans le service) (#215).
- Bilan : **drill-down par titre et gain latent dans le tableau des comptes et l'aperçu**. Un compte détaillé peut être déplié pour afficher ses titres (valeur + gain latent %), et le gain latent (valeur − coût d'acquisition) est agrégé par compte, par classe d'actif et par enveloppe fiscale dans le tableau des comptes et la carte d'aperçu du bilan. Les positions sans coût d'acquisition sont signalées « N/A » et exclues du pourcentage (pas de division par zéro) ; le rendement Modified Dietz par compte est inchangé (#216).
- Bilan : la date d'un snapshot existant peut maintenant être déplacée. Le champ date devient modifiable en mode édition — changez-la puis enregistrez, et le snapshot (avec toutes ses lignes) est déplacé à la nouvelle date dans une seule transaction atomique. Si un autre snapshot occupe déjà la date cible, le déplacement est refusé avec un message clair et rien n'est modifié (#200).
- Bilan : **enveloppe fiscale sur les comptes**. Un compte peut désormais porter une enveloppe fiscale optionnelle (Non-enregistré, CELI, REER, FERR, CELIAPP, REEE — ou aucune), choisie via un menu déroulant dans le formulaire de compte. C'est un axe distinct du type du compte (la classe d'actif) : un compte d'actions logé dans un CELI est enfin exprimable — type *Actions* + enveloppe *CELI*. La migration v12 ajoute la colonne nullable `balance_accounts.vehicle_type` avec un CHECK sur l'enum et backfille les anciens comptes CELI/REER (#202, #203).
- Bilan : **axe enveloppe du graphique empilé**. Le graphique d'évolution empilé gagne un sous-choix d'axe — **Par classe d'actif** (défaut, comportement inchangé) ou **Par enveloppe** (regroupe par enveloppe fiscale, avec un bucket « Aucune » pour les comptes sans enveloppe). Lisez votre patrimoine par ce que vous détenez *ou* par l'abri fiscal où il se trouve (#204).
- Bilan : **colonnes de rendement repliables**. Les quatre colonnes de rendement Modified Dietz du tableau des comptes (3M / 1A / depuis création / non-ajusté) sont maintenant repliées par défaut derrière un bouton afficher/masquer ; le choix est mémorisé d'une session à l'autre (`user_preferences.balance_show_returns`) pour réduire le bruit visuel chez les utilisateurs qui ne suivent que des valeurs (#204).

### Modifié

- Bilan : terminologie clarifiée. Les regroupements de comptes (Liquidités, CELI, REER, etc.) sont désormais appelés **types** de façon cohérente dans l'interface du bilan et le guide utilisateur, pour éviter la confusion avec les *catégories* de transactions (un autre module). Le type « Encaisse » devient **Liquidités** et « Fonds commun » devient **Fonds / FNB**. Le terme *snapshot* est conservé mais glosé à son premier usage (#198).
- Bilan : **un type est désormais une pure classe d'actif**. Les types standard sont les cinq classes d'actif — Liquidités, Fonds / FNB, Actions, Crypto, Autres. Les enveloppes fiscales qui étaient des types (CELI, REER) ne sont plus des types : elles ont migré vers le nouvel attribut d'enveloppe fiscale, porté par le compte. À la migration, les comptes CELI/REER existants sont reclassés dans la classe d'actif **Autres** tout en conservant leur enveloppe (`tfsa`/`rrsp`) ; les types seedés `tfsa`/`rrsp` sont désactivés et disparaissent des menus de types (migrations v12 + v13). Les nouveaux profils seedent cinq classes d'actif ; les comptes de départ CELI/REER passent sous *Autres* avec leur enveloppe renseignée. Vos montants et votre historique ne changent pas — seul le regroupement change (#202).
- Bilan : **note sur les bilans historiques**. L'axe « par classe d'actif » du graphique est recalculé sur le type *actuel* de chaque compte ; un snapshot saisi *avant* cette migration pour un ancien compte CELI/REER apparaît donc désormais sous **Autres** sur cet axe (il ne s'affiche plus sous « CELI »/« REER »). C'est attendu — le nouvel axe **par enveloppe** retrouve bien ces CELI/REER, et aucune valeur ni aucun historique n'est modifié (#204).
- Bilan : **renommer un type ne casse plus la traduction** (correction de bug). Renommer un type écrasait auparavant sa clé i18n avec le texte libre, cassant la traduction FR/EN. Le nom personnalisé est désormais stocké à part dans `balance_categories.custom_label`, et la clé de traduction d'origine n'est jamais touchée (et réapparaît si vous videz le nom personnalisé). La migration v12 récupère aussi, en défense, tout type seedé dont la clé de traduction aurait déjà été écrasée par un renommage antérieur (#202, #203).
- Bilan : **les comptes cotés existants sont convertis automatiquement en comptes détaillés**. À la migration, chaque compte coté existant (doté d'une classe d'actif et d'un symbole) devient un compte *détaillé* à une seule position — ses lignes historiques quantité/cours sont reflétées en positions par titre, sans perte de valeur ni d'historique, et la ligne agrégée conserve le total. Les comptes cotés sans classe d'actif ou sans symbole restent intacts. La valeur du compte et toutes les agrégations sont inchangées ; vous pouvez désormais ajouter d'autres titres au même compte (migrations v14/v15/v16) (#211).

### Corrigé

- Bilan : le symbole (ticker) est maintenant optionnel pour les comptes d'un type coté. Un compte coté peut être créé ou modifié sans symbole — la valorisation manuelle (quantité × prix unitaire) n'en a jamais eu besoin ; un symbole n'est requis que pour utiliser le bouton de récupération automatique des prix (#199).

## [0.9.1] - 2026-05-10

### Ajouté

- Bilan : 4 comptes de départ (Compte chèque, CELI, REER, Compte non-enregistré) seedés pour les nouveaux profils, plus un modal d'opt-in unique pour les profils existants à leur première visite de /balance. Cases cochées par défaut ; les comptes existants avec le même nom + catégorie désactivent la ligne correspondante avec un tooltip « Déjà présent ». Confirmation ou ignorance enregistrée dans `user_preferences.balance_starter_proposed` pour que le modal ne réapparaisse jamais. ADR 0012 (Proposed) capture le futur modèle à deux niveaux véhicule × composition (#179).

### Modifié

- **Récupération de prix activée** — `/v1/prices` de `maximus-api` est en production depuis le 2026-05-05. La fonctionnalité premium de récupération de prix livrée en 0.9.0 (#160) est désormais fonctionnellement disponible de bout en bout (#161).
- **Paramètres réorganisés en 3 sous-pages** — la page unique de 12 cartes est éclatée en un hub (`/settings`) qui pointe vers trois sous-pages thématiques : `/settings/users` (comptes, licences, guide d'utilisation), `/settings/data` (catégories, sauvegarde, confidentialité de la récupération de prix) et `/settings/systems` (version, mise à jour, historique des versions, journaux + commentaires). Le guide d'utilisation et l'historique des versions, qui occupaient leurs propres pages, sont maintenant intégrés dans leur sous-page parente ; les anciennes URL `/docs` et `/changelog` redirigent automatiquement pour préserver les marque-pages externes et les liens des notes de version. Le bandeau de sécurité du fallback token-store est maintenant rendu une seule fois en haut du layout des paramètres, visible depuis chaque sous-page principale (#190).
- **Icône de l'application** — remplacement de l'icône par défaut de Tauri par un design sur mesure : une calculatrice au visage de robot souriant avec un cadenas de confidentialité sur la touche Entrée / `=`. Reflète les quatre valeurs du produit — robot (assistant), simplicité (formes géométriques), comptabilité (calculatrice), confidentialité (cadenas). Le SVG source est conservé dans `src-tauri/icons/icon.svg` pour les futures itérations ; les 16 fichiers raster spécifiques aux plateformes ont été régénérés via `tauri icon`. Le favicon web et le `<title>` de la fenêtre sont mis à jour aussi (auparavant *« Tauri + React + Typescript »* hérité du scaffolding par défaut).
- Bilan : remplacement de l'état vide de /balance par une carte d'onboarding à 2 étapes (Créer un compte → Saisir un snapshot) pour éviter l'écran « aucun snapshot » déroutant avant qu'un compte n'existe. Le bouton « + Nouveau snapshot » est masqué tant qu'aucun compte n'existe. La copie de l'état vide de /balance/snapshot clarifie la différence entre un compte et un snapshot (#178).

### Corrigé

- Bilan : correction de l'erreur SQLite « misuse of aggregate function MIN() » au chargement de /balance avec des snapshots existants ; remplacement du pattern aggregate-in-WHERE par une window function ROW_NUMBER() dans getAccountsPeriodAnchor (#175).
- Bilan : la sauvegarde d'un snapshot utilise désormais une transaction atomique BEGIN/COMMIT et valide toutes les lignes avant toute écriture en BDD, empêchant les snapshots orphelins lorsque la validation échoue. La migration v11 nettoie les orphelins existants (#176).
- Bilan : le sélecteur de date sur `/balance/snapshot` se ferme maintenant après la sélection sur Linux (WebKitGTK) au lieu de rester ouvert jusqu'à ce que l'utilisateur appuie sur Échap. Le contournement appelle `blur()` sur le champ après chaque changement — sans effet sur Windows WebView2 / macOS WKWebView, où le sélecteur se ferme déjà automatiquement (#177).
- Mise à jour de la dépendance `postcss` (8.5.6 → 8.5.13) pour corriger l'avis de sécurité de sévérité modérée GHSA-qx2v-qp2m-jg93 (XSS via `</style>` non échappé dans le stringifier CSS). Transitive via vite, build-time uniquement — aucun impact runtime sur le binaire Tauri livré (#180).
- Contournement du sélecteur de date WebKitGTK étendu aux 7 autres champs `<input type="date">` natifs répartis sur 4 composants (barre de filtres Transactions, formulaire Ajustements, modal de Liaison de transferts, sélecteur de période). Chaque handler onChange appelle désormais `e.currentTarget.blur()` pour fermer le popup natif sur Linux Tauri WebView — sans effet sur Windows WebView2 / macOS WKWebView. Même approche que #177 (#188).
- Bilan : nettoyage post-merge des suggestions issues des reviews des PR #182-#185. Six corrections groupées : (1) `getStarterCollisions` filtre désormais `archived_at IS NULL`, donc recréer un compte starter volontairement archivé n'est plus bloqué ; (2) `proposeStarterAccounts` re-vérifie chaque collision (nom, catégorie) en transaction avant l'INSERT en défense-in-depth (saut silencieux si déjà présent, aucune contrainte UNIQUE ajoutée) ; (3) les nouveaux profils reçoivent désormais `balance_starter_proposed` pré-seedé dans `consolidated_schema.sql` pour que le StarterAccountsModal ne s'ouvre jamais brièvement avec uniquement des collisions à la première visite de /balance ; (4) `/balance` cache maintenant le sélecteur de période, le graphique d'évolution et le tableau des comptes tant que la carte d'onboarding vide est affichée (évite trois messages vides empilés) ; (5) `BalanceOnboardingCard.Step` appelle directement `useTranslation()` au lieu de recevoir `t` en prop ; (6) le bloc de doc de la formule Modified Dietz dans `return_calculator.rs` est maintenant entouré d'une fence `text` pour que `cargo test --doc` n'essaie plus de compiler la pseudo-math comme du Rust (#187).

## [0.9.0] - 2026-04-29

### Ajouté
- **Bilan — colonne `asset_type` sur les catégories cotées** (route `/balance/accounts`) : les catégories cotées portent maintenant un `asset_type` explicite (`stock` ou `crypto`) qui pilote le routage de PriceFetchControl vers le bon fournisseur, sans heuristique sur le symbole (ex : ETH = Ethan Allen NYSE *et* Ethereum crypto, deux symboles homonymes). La migration v10 ajoute une colonne nullable et backfille les deux catégories cotées seedées (`stock`, `crypto`) avec leur valeur respective ; les lignes cotées custom existantes restent NULL en attendant un futur écran d'édition pour qu'on les renseigne. Le formulaire de création de catégorie (onglet Catégories) affiche désormais un sélecteur de type d'actif quand `kind = priced` et refuse l'enregistrement tant qu'aucune valeur n'est choisie. L'éditeur de snapshot masque le bouton de récupération de prix sur les lignes cotées dont l'`asset_type` est encore NULL — la saisie manuelle reste l'unique chemin sur ces lignes legacy. (#169)
- **Bilan — documentation et ADRs** (`docs/`) : finalise le milestone Bilan avec la passe documentaire. `docs/architecture.md` répertorie désormais les 5 nouvelles tables (`balance_categories`, `balance_accounts`, `balance_snapshots`, `balance_snapshot_lines`, `balance_account_transfers`), les 7 nouveaux index, les invariants CHECK et FK (CAD seulement, invariants de type, `RESTRICT` sur `transaction_id` pour la reproductibilité Modified Dietz), le découpage 4 sections de `balance.service.ts` (CRUD / snapshots+lignes / rendements+transferts / prix), les 3 hooks scoped par page (`useBalanceAccounts`, `useSnapshotEditor`, `useBalanceOverview`), la commande Tauri `compute_account_return` (avec mention de la future commande `fetch_price` Phase 5), et les 3 nouvelles routes `/balance*`. Trois nouveaux ADRs accompagnent : **0008 — Modified Dietz** (justifie le choix vs ROI / TWR / IRR avec référence à `return_calculator.rs`) ; **0009 — Proxy price-fetching via maximus-api** (architecture documentée maintenant, implémentation BLOQUÉE en attendant la Phase 2 de maximus-api — couvre les considérations privacy comme le strip de headers, l'absence de corrélation `(symbole, licence)` dans les logs et le User-Agent fixe `simpl-resultat`, l'abstraction adapter Yahoo + CoinGecko, la stratégie d'auth Bearer, le rate-limiting client + serveur et le double gating premium UI + serveur) ; **0010 — FK RESTRICT sur `balance_account_transfers.transaction_id`** (justifie l'arbitrage intégrité vs friction pour la reproductibilité Modified Dietz). Le guide utilisateur gagne une nouvelle section *Bilan* qui détaille la saisie de snapshot (simple + coté), la liaison de transferts, la lecture des rendements multi-horizons (3M / 1A / depuis création avec colonne non-ajustée côte à côte), avec la mention « à venir Phase 5 » pour le price-fetching premium. Clés i18n `docs.balance.*` (FR + EN) ajoutées pour que le guide in-app reflète la nouvelle section (#145)
- **Bilan — suite de tests d'intégration cross-cutting** (infrastructure de tests) : clôt la feature *Bilan* avec une couche de tests d'intégration qui exerce toute la surface TypeScript en un seul flux de bout en bout (compte → catégorie cotée → snapshot coté → transfert lié → rendement) et des assertions dédiées sur le verrou de devise (CAD seulement au MVP, refusé à la fois côté service et côté CHECK SQL), la sécurité de tolérance pour le type coté (un mauvais enregistrement ne doit PAS supprimer les lignes existantes), le câblage de `computeAccountReturn` (résolution du profil actif, transmission des dates ISO, conservation telle quelle d'une réponse de période partielle). Trois nouveaux tests Rust d'intégration appliquent la migration v9 par-dessus un schéma v1 seedé contenant déjà des transactions pour vérifier (1) aucune perte ni mutation de données, (2) le round-trip lier / délier sur de vraies `transaction_id`, (3) la chaîne FK RESTRICT (suppression d'une transaction liée bloquée, autorisée après détachement), (4) la cohabitation indépendante des espaces d'identifiants `categories.id` (v1) et `balance_categories.id` (v9). Un test de non-régression au niveau source sur `TransactionTable.tsx` verrouille le contrat de l'icône de transfert inlinée : prop optionnelle, court-circuit en chaînage optionnel, clés i18n, aria-label, layout partagé de la cellule description — pour que la page reste rendue à l'identique en l'absence de transferts liés. (#144)
- **Bilan — rendements Modified Dietz et liaison de transferts** (route `/balance`) : le rendement par compte arrive enfin. Nouveau module Rust `commands/return_calculator.rs` qui implémente la formule Modified Dietz `R = (V_fin − V_début − ΣCF_i) / (V_début + ΣW_i × CF_i)` avec pondération des apports à la précision du jour `W_i = (T − t_i) / T`, et annualisation `(1 + R)^(365/T) − 1`. Les cas limites — snapshot d'extrémité manquant, aucun flux taggé sur la période, compte créé en cours de période, vidé puis rechargé, période de durée nulle — sont surfacés via les flags explicites `is_partial` / `has_no_transfers_warning` pour que l'UI affiche un tiret + tooltip clair plutôt qu'un nombre incompréhensible. Nouvelle commande Tauri `compute_account_return(account_id, period_start, period_end)` qui exécute trois lectures SQL courtes contre la BD du profil actif (dernier snapshot ≤ début de période, dernier snapshot ≤ fin de période, transferts joints aux transactions filtrés sur la période) puis alimente le calculateur. Sept tests Rust co-localisés en TDD couvrent chaque cas avant l'implémentation. Le tableau des comptes sur `/balance` affiche désormais quatre colonnes supplémentaires côte à côte : 3M / 1A / Depuis création (Modified Dietz) plus une colonne *Non ajusté* qui calcule simplement `(V_fin − V_début) / V_début` pour qu'on voie d'un coup d'œil quelle part du rendement vient de la pondération des apports. Le menu d'actions de chaque ligne reçoit l'item *Lier transferts* qui ouvre une modal de sélection multiple avec filtres période / catégorie / recherche texte ; la modal propose automatiquement le sens (`in` pour les montants bancaires négatifs, `out` pour les positifs) et l'utilisateur peut inverser ligne par ligne avant de soumettre. Les transactions liées à un ou plusieurs comptes de bilan affichent maintenant une petite icône `Link2` à côté de la description dans la page *Transactions*, avec un tooltip listant les noms et sens des comptes. Les chemins de suppression en lot (par fichier importé et tout effacer) pré-vérifient l'existence d'un lien dans `balance_account_transfers` et surfacent l'erreur typée `TransactionLinkedToBalanceError` (« Cette transaction est liée au compte de bilan X — déliez-la avant de supprimer ») au lieu de laisser fuiter l'erreur SQLite brute. Le graphique d'évolution sur `/balance` superpose désormais des lignes verticales de référence à chaque date de transfert lié (vert pour `in`, rouge pour `out`). Nouvelles clés i18n sous `balance.returns.*`, `balance.accountsTable.*`, `balance.transfers.*`, `balance.evolution.*`, `transactions.transferIcon.*` (FR + EN) (#142)
- **Bilan — page `/balance` avec graphique d'évolution et entrée sidebar** (route `/balance`) : quatrième tranche de la feature *Bilan*, qui la rend enfin accessible depuis la navigation. La nouvelle page compose (1) une carte d'aperçu avec la valeur nette agrégée du dernier snapshot, le Δ% par rapport au snapshot chronologiquement précédent (affiché « — » quand il n'existe qu'un seul snapshot), un avertissement de fraîcheur quand le dernier snapshot date de plus de 60 jours, et un CTA *Nouveau snapshot* qui pointe vers `/balance/snapshot` ; (2) un sélecteur de période (3 mois / 6 mois / 1 an / 3 ans / Tout) qui recharge toutes les séries en parallèle ; (3) un graphique d'évolution avec deux modes — *Ligne* (une seule série `SUM(value) GROUP BY snapshot_date`) et *Empilé par catégorie* (une `<Area stackId>` Recharts par `balance_categories.key`) ; (4) un tableau des comptes listant chaque compte actif avec sa dernière valeur snapshot, le Δ% par compte sur la période active (valeur la plus récente vs valeur du premier snapshot dans la fenêtre — null si pas d'ancrage, affiché « — »), et un menu d'actions (Détail désactivé en attendant la #142, Archiver). Les colonnes de rendement (3M / 1A / depuis création / non ajusté) sont réservées pour une version ultérieure avec un commentaire `TODO`. La sidebar expose désormais l'entrée *Bilan* (icône `Wallet`) entre *Rapports* et *Paramètres*. Le service gagne trois helpers de série temporelle : `getSnapshotTotalsByDate(range?)`, `getSnapshotTotalsByCategoryAndDate(range?)`, `getAccountsLatestSnapshot()` ainsi qu'un calcul d'ancrage par compte `getAccountsPeriodAnchor(range)` — tous couverts par des tests unitaires. Nouveau hook `useBalanceOverview` (`useReducer` scoped) qui pilote l'état de la page. Nouvelles clés i18n sous `balance.overview.*`, `balance.period.*`, `balance.chart.*` plus `nav.balance` (FR + EN) (#141)
- **Bilan — type coté (quantité × prix unitaire)** (routes `/balance/accounts` et `/balance/snapshot`) : troisième tranche de la feature *Bilan*. Les catégories exposent désormais un sélecteur de *type* à la création : `simple` (saisie d'un montant direct) ou `coté` (`quantité × prix_unitaire`). Les comptes liés à une catégorie cotée exigent un symbole. L'éditeur de snapshot bascule selon le type de la catégorie du compte : les comptes simples conservent leur unique champ de valeur ; les comptes cotés affichent trois champs — `quantité`, `prix unitaire` (les deux obligatoires) et un champ `valeur` en lecture seule calculé en temps réel à partir de `quantité × prix unitaire` (arrondi à 2 décimales). Une étiquette d'attribution `[Manuel]` apparaît sur chaque ligne cotée ; la future étiquette `[via Maximus le AAAA-MM-JJ]` arrivera avec la récupération automatique des prix. Le bouton *Pré-remplir depuis le précédent* copie maintenant les quantités pour les comptes cotés mais laisse les prix unitaires vides (un prix frais doit être saisi à chaque fois). Le service valide les lignes cotées avant la CHECK SQL : invariants de type (les lignes cotées doivent porter à la fois quantité et prix unitaire ; les lignes simples ne doivent porter ni l'un ni l'autre) et invariant de valeur `|valeur − quantité × prix unitaire| ≤ 0,01` (un centime de tolérance pour absorber les arrondis flottants). La suppression d'une catégorie est désormais mieux guardée : une catégorie liée à un ou plusieurs comptes affiche un bandeau d'erreur listant le nombre et jusqu'à trois noms de comptes pour que l'utilisateur sache exactement lesquels archiver d'abord ; les catégories standard restent protégées côté service avec leur bouton désactivé dans l'interface. Nouvelles clés i18n `balance.category.kind.*`, `balance.category.form.kindLabel/kindHint*`, `balance.category.error.has_accounts`, `balance.snapshot.priced.*` (FR + EN) (#140)
- **Bilan — éditeur de snapshot (type simple)** (route `/balance/snapshot`) : deuxième tranche de la feature *Bilan*. La nouvelle page permet de créer ou modifier un snapshot daté de votre patrimoine : choisissez une date (par défaut aujourd'hui), saisissez la valeur de chaque compte actif groupé par catégorie, puis enregistrez. Le mode est piloté par le paramètre `?date=` de l'URL — si un snapshot existe déjà à cette date, la page bascule automatiquement en mode édition (la contrainte UNIQUE sur `balance_snapshots.snapshot_date` garantit un snapshot par jour). La date d'un snapshot existant est immuable : pour la changer, supprimez puis recréez. Un bouton *Pré-remplir depuis le précédent* copie les valeurs du snapshot antérieur le plus récent (comptes simples uniquement — les comptes cotés seront pris en charge quand l'éditeur coté arrivera). Un bouton *Supprimer* affiche une modal de double confirmation qui exige de retaper la date du snapshot avant d'activer l'action destructive. Seules les valeurs de type simple sont acceptées à ce stade (`quantity` et `unit_price` sont laissés `NULL`) ; l'éditeur coté (quantité × prix unitaire + récupération de prix) arrivera dans une prochaine version. Nouveau hook `useSnapshotEditor` (`useReducer` couvrant tout le cycle de vie) et deux nouveaux composants `SnapshotEditor` + `SnapshotLineRow`. i18n FR/EN sous `balance.snapshot.*` (#146)
- **Bilan — fondations du schéma et page Comptes** (route `/balance/accounts`) : première tranche de la nouvelle feature *Bilan*. La migration SQL v9 introduit 5 tables (`balance_categories`, `balance_accounts`, `balance_snapshots`, `balance_snapshot_lines`, `balance_account_transfers`) avec 7 index et seede 7 catégories standard — Encaisse, CELI, REER, Fonds commun, Autre (type simple) + Action et Cryptomonnaie (type coté). La colonne `currency` est verrouillée à `CAD` via une contrainte CHECK au MVP — le support multi-devises arrivera plus tard. La nouvelle page expose deux onglets : *Comptes* (CRUD complet sur les comptes de l'utilisateur, archivage soft plutôt que suppression dure pour préserver les snapshots historiques) et *Catégories* (renommer une catégorie, créer des catégories de type simple, supprimer celles créées par l'utilisateur — les catégories standard sont protégées). Couverture i18n FR/EN complète sous `balance.*`. Snapshots, transferts, rendements et price-fetching premium arriveront dans les prochaines issues ; pour l'instant la route est accessible directement par URL (pas encore d'entrée sidebar) (#138)

- **Récupération de prix premium pour actions (best-effort) et crypto (exchanges directs)** — vie privée préservée via proxy maximus-api. Toggle dans les Paramètres pour révoquer le consentement (activation serveur en attente — fonctionnalité dormante jusqu'à la mise en ligne de `/v1/prices` de maximus-api). (#160)

### Modifié
- **Clé publique Ed25519 de licence** : la clé embarquée a été rotée pour correspondre au serveur de licences `maximus-api` qui vient d'être déployé en production (live à `https://api.lacompagniemaximus.com`). Aucune licence n'avait été émise en production avec l'ancienne clé, donc ce changement est invisible pour les utilisateurs existants — mais `/licenses/activate` répond désormais, donc l'activation par machine (issue #53) sera débloquée dès la sortie de cette version. La clé privée correspondante vit uniquement sur le serveur (#49)

### Corrigé
- **Rapport Zoom catégorie** (`/reports/category`) : la liste déroulante du combobox des catégories affiche désormais la liste complète dans un ordre hiérarchique DFS correct — chaque racine est émise avant ses descendants, et les frères et sœurs sont triés par `sort_order` puis nom affiché. Auparavant la liste était triée globalement par `sort_order` (via un `ORDER BY sort_order, name` SQL), ce qui entrelaçait des parents et enfants de sous-arbres différents partageant le même `sort_order`, d'où l'indentation incohérente et l'impression d'arbre cassé. La recherche filtrée (insensible aux accents) conserve le même comportement (#126)

## [0.8.4] - 2026-04-21

### Ajouté
- **Bannière (90 jours) et entrée permanente *Rétablir une sauvegarde* pour annuler une migration de catégories à partir de la sauvegarde automatique** (Paramètres → *Catégories*) : après une migration v2→v1, une bannière fermable (icône `ShieldCheck`) s'affiche désormais en haut de la carte Catégories pendant 90 jours et pointe vers la sauvegarde SREF automatique écrite par `categoryBackupService`. Une entrée dédiée *Rétablir une sauvegarde* reste accessible sous le lien de migration tant qu'une migration est enregistrée — même après les 90 jours — afin que le rétablissement ne soit jamais perdu. La fenêtre de confirmation lit le journal `last_categories_migration` pour récupérer son horodatage et son chemin de sauvegarde, impose une confirmation en deux étapes avec un bouton rouge *Rétablir*, bascule sur un sélecteur de fichier lorsque le chemin enregistré n'est plus sur disque, demande le NIP du profil lorsque le fichier SREF est chiffré, puis en cas de succès remet `categories_schema_version=v2`, inscrit `reverted_at` dans le journal et recharge l'application. La bannière se masque d'elle-même une fois la migration rétablie. Ajout de la commande Tauri `file_exists` pour la vérification préalable, nouveau service `categoryRestoreService` qui emballe `read_import_file` + `importTransactionsWithCategories` avec des codes d'erreur stables (#122)
- **Page de migration des catégories en 3 étapes** (route `/settings/categories/migrate`, Paramètres → *Migrer vers la structure standard*) : les profils v2 peuvent désormais choisir de migrer vers la nouvelle taxonomie v1 IPC via un parcours guidé — *Découvrir* (arbre en lecture seule, réutilisé de la page Guide), *Simuler* (table 3 colonnes en dry-run avec badges de confiance haute / moyenne / basse / à réviser, panneau latéral cliquable montrant les 50 premières transactions impactées par ligne, sélecteur de cible en ligne pour les lignes non résolues, bouton *Suivant* bloqué tant qu'une ligne n'est pas résolue) et *Consentir* (case à cocher + champ NIP pour les profils protégés + loader 4 étapes). Au clic de confirmation, la page crée une sauvegarde SREF vérifiée via `categoryBackupService` (obligatoire, abort sur échec sans écriture BD) puis lance une transaction SQL atomique via le nouveau service `categoryMigrationService.applyMigration(plan, backup)` — BEGIN → INSERT de la taxonomie v1 → UPDATE des transactions / budgets / budget_templates / keywords / suppliers vers les nouveaux id v1 → replacement des catégories personnalisées sous un nouveau parent *Catégories personnalisées (migration)* → désactivation des catégories v2 → pose de `categories_schema_version='v1'` et journalisation dans `user_preferences.last_categories_migration` → COMMIT. Toute erreur déclenche un ROLLBACK, laissant le profil dans son état pré-migration. Les écrans de succès et d'échec affichent le chemin de la sauvegarde et, pour le succès, le nombre de lignes insérées / transactions, mots-clés et budgets migrés (#121)
- **Bannière du tableau de bord invitant les profils v2 à découvrir la nouvelle taxonomie v1 IPC** : les profils existants (marqués `categories_schema_version='v2'`) voient désormais une bannière fermable en haut du tableau de bord qui pointe vers la nouvelle page Guide des catégories standard. La bannière est non destructive (CTA en lecture seule, aucun changement de catégories), ne s'affiche qu'aux profils v2 (les nouveaux profils semés en v1 ne la voient jamais), et sa fermeture est persistée dans `user_preferences` sous la clé `categories_v1_banner_dismissed` pour ne plus réapparaître (#118)
- **Page Guide des catégories standard** (Paramètres → *Structure standard des catégories*, route `/settings/categories/standard`) : nouvelle page en lecture seule qui expose la taxonomie v1 IPC complète sous forme d'arbre navigable avec repli/expansion par racine, un compteur global en direct (racines · sous-catégories · feuilles · total), une recherche plein texte insensible aux accents sur les noms traduits, des info-bulles au survol affichant la clé `i18n_key`, le type et l'identifiant de chaque nœud, et un bouton *Exporter en PDF* qui ouvre la boîte d'impression du navigateur. Une règle `@media print` dédiée force l'affichage complet de toutes les branches à l'impression, peu importe l'état de repli à l'écran. Tous les libellés passent par `categoriesSeed.*` avec `name` en repli pour les futures lignes personnalisées. Aucune écriture en base, aucune action destructive (#117)
- **Seed de catégories IPC pour les nouveaux profils** : les nouveaux profils sont désormais créés avec la taxonomie v1 IPC (Indice des prix à la consommation) — une hiérarchie alignée sur les catégories de Statistique Canada. Les noms des catégories du seed sont traduits dynamiquement depuis la clé i18n `categoriesSeed.*` (FR/EN), donc affichés dans la langue de l'utilisateur. Les profils existants gardent l'ancien seed v2, marqués via une nouvelle préférence `categories_schema_version` (une page de migration ultérieure offrira le passage v2→v1). Côté interne : colonne `categories.i18n_key` (nullable) ajoutée par la migration v8 (strictement additive), `src/data/categoryTaxonomyV1.json` livré comme source de vérité côté TS, les renderers `CategoryTree` et `CategoryCombobox` utilisent `name` en repli quand aucune clé de traduction n'est présente (catégories créées par l'utilisateur) (#115)

## [0.8.3] - 2026-04-19

### Ajouté
- **Rapport Cartes — Toggle Mensuel / Cumul annuel (YTD)** (`/reports/cartes`) : nouveau toggle segmenté à côté du sélecteur de mois de référence bascule les quatre cartes KPI (revenus, dépenses, solde net, taux d'épargne) entre la valeur du mois de référence (défaut inchangé) et une vue cumul annuel. En mode YTD, la valeur courante somme janvier → mois de référence, le delta MoM la compare à la fenêtre Jan → (mois − 1) de la même année (null en janvier), le delta YoY la compare à Jan → mois de référence de l'année précédente, et le taux d'épargne utilise les revenus/dépenses YTD. La sparkline 13 mois, les top mouvements, la saisonnalité et l'adhésion budgétaire restent mensuels peu importe le toggle. L'info-bulle du taux d'épargne reflète maintenant le mode actif. Choix persisté dans `localStorage` (`reports-cartes-period-mode`) (#102)
- **Guide utilisateur — Section Cartes** : nouvelle section dédiée documentant les formules des quatre KPI, le toggle Mensuel/YTD, la sparkline, les top mouvements, les règles de saisonnalité et d'adhésion budgétaire, ainsi que le cas limite du taux d'épargne (« — » quand les revenus sont à zéro) (#102)
- **Rapport Cartes** : info-bulle d'aide sur le KPI taux d'épargne expliquant la formule — `(revenus − dépenses) ÷ revenus × 100`, calculée sur le mois de référence (#101)
- **Rapport Tendances — Par catégorie** (`/reports/trends`) : nouveau toggle segmenté pour basculer le graphique d'évolution par catégorie entre les barres empilées (par défaut, inchangé) et une vue surface empilée Recharts (`<AreaChart stackId="1">`) qui montre la composition totale dans le temps. Les deux modes partagent la même palette de catégories et les mêmes patterns SVG en niveaux de gris. Le type choisi est mémorisé dans `localStorage` (`reports-trends-category-charttype`) (#105)

### Modifié
- **Rapport Zoom catégorie** (`/reports/category`) : le sélecteur de catégorie est désormais un combobox saisissable et filtrable avec recherche insensible aux accents, navigation clavier (↑/↓/Entrée/Échap) et indentation hiérarchique, en remplacement du `<select>` natif (#103)
- **Rapport Comparables — Réel vs réel** (`/reports/compare`) : le tableau reprend maintenant la structure riche à 8 colonnes du tableau Réel vs budget, en scindant chaque comparaison en un bloc *Mensuel* (mois de référence vs mois de comparaison) et un bloc *Cumulatif YTD* (progression jusqu'au mois de référence vs progression jusqu'à la fenêtre précédente). En mode MoM, le cumulatif précédent couvre janvier → fin du mois précédent de la même année ; en mode YoY, il couvre janvier → même mois de l'année précédente. Le graphique reste uniquement mensuel (#104)
- **Rapport Faits saillants** (`/reports/highlights`) : les tuiles mensuelles (solde du mois courant, top mouvements vs mois précédent) s'ouvrent désormais sur le **mois précédent** au lieu du mois courant, en cohérence avec les rapports Cartes et Comparables. La tuile Cumul annuel reste ancrée au 1er janvier de l'année civile en cours. Un nouveau sélecteur de mois de référence permet de faire pivoter le solde mensuel et la comparaison des top mouvements vers n'importe quel mois passé ; le choix est mémorisé dans l'URL via `?refY=YYYY&refM=MM` pour que la vue soit bookmarkable. Le panneau de faits saillants du hub suit la même valeur par défaut (#106)

### Corrigé
- **Rapport Cartes** : retrait du sélecteur de période non fonctionnel — le rapport Cartes est un instantané « mois X vs X-1 vs X-12 », seul le sélecteur de mois de référence est nécessaire (#101)
- **Rapport Cartes** : le KPI taux d'épargne affiche maintenant « — » au lieu de « 0 % » lorsque le mois de référence n'a aucun revenu (une division par zéro est indéfinie, pas zéro) (#101)
- **Rapport Cartes — adhésion budgétaire** : la carte affichait systématiquement « aucune catégorie avec budget ce mois-ci » même lorsque des budgets étaient définis sur les catégories de dépenses. Cause racine : les budgets de dépenses sont stockés signés négatifs et le filtre/la comparaison utilisaient les valeurs brutes au lieu des absolus. Le nombre de catégories, les catégories dans la cible et les montants de dépassement sont maintenant tous calculés sur les valeurs absolues (#112)

## [0.8.2] - 2026-04-17

### Ajouté
- **Widget Feedback Hub** (Paramètres → Journaux) : un bouton *Envoyer un feedback* dans la carte Journaux ouvre un dialogue pour soumettre suggestions, commentaires ou rapports de bogue vers le Feedback Hub central. Un dialogue de consentement (affiché une seule fois) explique que l'envoi atteint `feedback.lacompagniemaximus.com` — une exception explicite au fonctionnement 100 % local de l'app. Trois cases à cocher opt-in (toutes décochées par défaut) : inclure le contexte de navigation (page, thème, écran, version, OS), inclure les derniers logs d'erreur, m'identifier avec mon compte Maximus. L'envoi passe par une commande Rust côté backend, donc rien ne quitte la machine tant que l'utilisateur n'a pas cliqué *Envoyer* (#67)
- **Rapport Cartes** (`/reports/cartes`) : nouveau sous-rapport de type tableau de bord dans le hub Rapports. Combine quatre cartes KPI (Revenus, Dépenses, Solde net, Taux d'épargne) affichant les deltas MoM et YoY simultanément avec une sparkline 13 mois dont le mois de référence est mis en évidence, un graphique overlay revenus vs dépenses sur 12 mois (barres + ligne de solde net), le top 5 des catégories en hausse et en baisse par rapport au mois précédent, une carte d'adhérence au budget (N/M dans la cible plus les 3 pires dépassements avec barres de progression) et une carte de saisonnalité qui compare le mois de référence à la moyenne du même mois sur les deux années précédentes. Toutes les données proviennent d'un seul appel `getCartesSnapshot()` qui exécute ses requêtes en parallèle (#97)

### Modifié
- **Rapport Comparables** (`/reports/compare`) : passage de trois onglets (MoM / YoY / Budget) à deux modes (Réel vs réel / Réel vs budget). La vue « Réel vs réel » affiche désormais un sélecteur de mois de référence en en-tête (défaut : mois précédent), un sous-toggle MoM ↔ YoY, et un graphique en barres groupées côte-à-côte (deux barres par catégorie : période de référence vs période comparée). Le `PeriodSelector` d'URL reste synchronisé avec le sélecteur de mois (#96)

## [0.8.0] - 2026-04-14

### Ajouté
- **Hub des rapports** : `/reports` devient un hub affichant un panneau de faits saillants (solde mois courant + cumul annuel avec sparklines, top mouvements vs mois précédent, plus grosses transactions récentes) et quatre cartes de navigation vers des sous-rapports dédiés (#69–#76)
- **Rapport Faits saillants** (`/reports/highlights`) : tuiles de solde avec sparklines 12 mois, tableau triable des top mouvements, graphique en barres divergentes, liste des grosses transactions avec fenêtre 30/60/90 jours (#71)
- **Rapport Tendances** (`/reports/trends`) : bascule interne entre flux global (revenus vs dépenses) et évolution par catégorie, toggle graphique/tableau sur les deux (#72)
- **Rapport Comparables** (`/reports/compare`) : barre d'onglets pour Mois vs Mois précédent, Année vs Année précédente, et Réel vs Budget ; graphique en barres divergentes centré sur zéro pour les deux premiers modes (#73)
- **Zoom catégorie** (`/reports/category`) : analyse ciblée avec donut chart de la répartition par sous-catégorie, graphique d'évolution mensuelle en aires, et tableau filtrable des transactions (#74)
- **Édition contextuelle des mots-clés** : clic droit sur n'importe quelle ligne de transaction pour ajouter sa description comme mot-clé de catégorisation ; un dialog de prévisualisation montre toutes les transactions qui seraient recatégorisées (limitées à 50, avec checkbox explicite pour les suivantes) avant validation. Disponible sur le zoom catégorie, la liste des faits saillants, et la page Transactions principale (#74, #75)
- **Période bookmarkable** : la période des rapports vit maintenant dans l'URL (`?from=YYYY-MM-DD&to=YYYY-MM-DD`), vous pouvez copier, coller et partager le lien en conservant l'état (#70)
- **Préférence chart/table** mémorisée dans `localStorage` par section de rapport

### Modifié
- Le hook monolithique `useReports` a été splitté en hooks par domaine (`useReportsPeriod`, `useHighlights`, `useTrends`, `useCompare`, `useCategoryZoom`) pour que chaque sous-rapport ne possède que l'état qu'il utilise (#70)
- Le menu contextuel (clic droit) des rapports est désormais un composant générique `ContextMenu` réutilisé par le menu des graphiques existant et le nouveau dialog d'ajout de mot-clé (#69)

### Supprimé
- Le tableau croisé dynamique a été retiré. Plus de 90 % de son usage réel consistait à zoomer sur une catégorie, ce que le nouveau rapport Zoom catégorie traite mieux. L'historique git préserve l'ancienne implémentation si jamais elle doit revenir (#69)

### Sécurité
- Le nouveau `AddKeywordDialog` impose une longueur de 2 à 64 caractères sur les mots-clés utilisateurs pour empêcher les attaques ReDoS sur de grands ensembles de transactions (CWE-1333), utilise des requêtes `LIKE` paramétrées pour la prévisualisation (CWE-89), encapsule l'INSERT + les UPDATE par transaction dans une transaction SQL BEGIN/COMMIT/ROLLBACK explicite (CWE-662), affiche toutes les descriptions non-sûres via rendu React enfants (CWE-79), et ne recatégorise que les lignes explicitement cochées par l'utilisateur — jamais rétroactivement. Le remplacement d'un mot-clé existant sur une autre catégorie nécessite une confirmation explicite (#74)
- `getCategoryZoom` parcourt l'arbre des catégories via une CTE récursive **bornée** (`WHERE depth < 5`), protégeant contre les cycles `parent_id` malformés (CWE-835) (#74)

## [0.7.4] - 2026-04-14

### Modifié
- Les tokens OAuth sont maintenant stockés dans le trousseau du système d'exploitation (Credential Manager sous Windows, Secret Service sous Linux) au lieu d'un fichier JSON en clair. Les utilisateurs existants sont migrés de façon transparente au prochain rafraîchissement de session ; l'ancien fichier est écrasé avec des zéros puis supprimé. Une bannière « tokens en stockage local » apparaît dans les Paramètres si le trousseau est indisponible (#66, #78, #79, #81)
- Le cache d'informations de compte est désormais signé par HMAC avec une clé stockée dans le trousseau : modifier manuellement le champ `subscription_status` dans `account.json` ne permet plus de contourner le gating Premium (#80)
- Hachage du PIN migré de SHA-256 vers Argon2id pour résistance au brute-force (CWE-916). Les PINs SHA-256 existants sont vérifiés de façon transparente et rehachés au prochain déverrouillage réussi ; les nouveaux PINs utilisent Argon2id (#54)

### Sécurité
- Correction de CWE-312 (stockage en clair des tokens OAuth), CWE-345 (absence de vérification d'intégrité du cache d'abonnement) et CWE-916 (hachage faible du PIN). Les anciens fichiers `tokens.json` et les caches `account.json` non signés sont rejetés par le chemin de gating jusqu'à ce que le prochain rafraîchissement rétablisse un anchor de confiance dans le trousseau (#66, #54)

## [0.7.3] - 2026-04-13

### Corrigé
- Connexion Compte Maximus : le callback deep-link utilise maintenant l'API canonique Tauri v2 `on_open_url`, donc le code d'autorisation parvient bien à l'app en cours d'exécution au lieu de laisser l'interface bloquée en « chargement » (#51, #65)
- Les callbacks OAuth contenant un paramètre `error` remontent maintenant l'erreur à l'interface au lieu d'être ignorés silencieusement (#51)

## [0.7.2] - 2026-04-13

### Modifié
- Les mises à jour automatiques sont temporairement ouvertes à l'édition Gratuite en attendant que le serveur de licences (issue #49) soit en ligne. Le gating sera restauré une fois l'activation payante fonctionnelle de bout en bout (#48)

## [0.7.1] - 2026-04-13

### Corrigé
- Connexion Compte Maximus : le callback OAuth2 revient maintenant correctement dans l'instance en cours au lieu de lancer une deuxième instance et de laisser l'app d'origine bloquée en « chargement » (#51, #65)

## [0.7.0] - 2026-04-11

### Ajouté
- CI : nouveau workflow `check.yml` qui exécute `cargo check`/`cargo test` et le build frontend sur chaque push de branche et PR, détectant les erreurs avant le merge plutôt qu'au moment de la release (#60)
- Carte de licence dans les Paramètres : affiche l'édition actuelle (Gratuite/Base/Premium), accepte une clé de licence et redirige vers la page d'achat (#47)
- Carte Compte Maximus dans les Paramètres : connexion optionnelle via OAuth2 PKCE pour les fonctionnalités Premium (#51)
- Activation de machines : activer/désactiver des machines via le serveur de licences, voir les machines activées dans la carte licence (#53)
- Vérification quotidienne de l'abonnement : rafraîchit automatiquement les infos du compte une fois par jour au lancement (#51)

### Modifié
- Les mises à jour automatiques sont maintenant réservées à l'édition Base ; l'édition Gratuite affiche un message invitant à activer une licence (#48)
- La détection d'édition prend maintenant en compte l'abonnement Compte Maximus : Premium remplace Base quand l'abonnement est actif (#51)

## [0.6.7] - 2026-03-29

### Modifié
- Rapport Catégorie dans le temps : suppression du filtre codé en dur sur les dépenses, ajout d'un sélecteur de type avec dépense par défaut (#41)
- Rapport Catégorie dans le temps : ajout d'un filtre par type (dépense/revenu/transfert) dans le panneau de filtre à droite (#41)

### Corrigé
- Mise à jour de la dépendance picomatch (4.0.3 → 4.0.4) pour corriger des vulnérabilités de sévérité HIGH (#43)

## [0.6.6]

### Modifié
- Tableau de budget : la colonne année précédente affiche maintenant le réel (transactions) au lieu du budget planifié (#34)
- Refactorisation de `buildPrevYearTotalMap` en inline et simplification des tests (#39)

### Corrigé
- Fichiers changelog synchronisés automatiquement via plugin Vite, copies obsolètes dans public/ supprimées (#37)

## [0.6.5]

### Ajouté
- Tableau de bord : menu déroulant de sélection du mois pour la section Budget vs Réel avec le dernier mois complété par défaut (#31)

### Modifié
- Rapports et tableau de bord : police réduite dans le menu déroulant de mois pour un meilleur équilibre visuel (#31)

## [0.6.4]

### Ajouté
- Tableau de budget : colonne du total de l'année précédente affichée comme première colonne de données pour servir de référence (#16)

### Corrigé
- Tableau de bord : les catégories de niveau 4+ apparaissent maintenant sous leur parent au lieu du bas de la section (#23)
- Tableau de bord : la hiérarchie de catégories supporte maintenant une profondeur de niveaux arbitraire (#23)

### Modifié
- Tableau de bord : le graphique circulaire prend 1/3 de la largeur au lieu de 1/2, donnant plus d'espace au tableau budget (#23)
- Tableau de bord : les étiquettes du graphique circulaire s'affichent uniquement au survol via le tooltip (#23)
- Budget vs Réel : la colonne des catégories reste désormais fixe lors du défilement horizontal (#29)
- Budget vs Réel : titre changé pour « Budget vs Réel pour le mois de [mois] » avec un menu déroulant pour sélectionner le mois (#29)
- Budget vs Réel : le mois par défaut est maintenant le dernier mois complété au lieu du mois courant (#29)

## [0.6.3]

### Ajouté
- Tableau de bord : histogramme empilé des dépenses par catégorie et par mois (#15)
- Tableau de bord : tableau budget vs réel du mois courant avec écart en $ et % (#15)
- Tableau de budget et rapport Budget vs Réel : formatage des sous-totaux de section avec poids visuel croissant (#14)

### Modifié
- Tableau de bord : période par défaut changée de « mois » à « année à ce jour » (#15)
- Tableau de bord : section des transactions récentes supprimée (#15)
- Tous les rapports tabulaires : les lignes de grand total utilisent maintenant une police plus grande (text-sm), gras et bordure supérieure plus épaisse pour une meilleure hiérarchie visuelle (#14)

### Corrigé
- Rapport catégories dans le temps : toutes les catégories sont maintenant affichées (limite passée de 8 à 50) (#13)
- Graphique par catégorie : les noms sur l'axe Y utilisent maintenant la couleur du texte principal au lieu du gris (#13)
- Graphique catégories dans le temps : le texte de la légende utilise maintenant la couleur du texte principal au lieu d'hériter la couleur de la catégorie (#13)

## [0.6.2]

### Ajouté
- Tableau de budget : sous-totaux par section (dépenses, revenus, transferts) affichés après chaque groupe (#11)
- Rapport Budget vs Réel : sous-totaux par section avec réel, prévu, écart ($) et écart (%) par type (#11)

### Corrigé
- Page catégories : le panneau de détail reste maintenant visible lors du défilement d'une longue liste de catégories (#12)

## [0.6.1]

### Ajouté
- Page historique des versions : historique complet accessible depuis les Paramètres à tout moment
- Changelog bilingue : les notes de version s'affichent dans la langue choisie par l'utilisateur (FR/EN)

### Corrigé
- Visibilité des labels de graphiques : les montants sur les barres empilées utilisent maintenant du texte noir avec contour blanc pour un meilleur contraste (#8)
- Tableau de budget : les cellules éditables affichent maintenant un fond au survol, un curseur pointeur et une info-bulle pour clarifier l'interaction (#9)

## [0.6.0]

### Ajouté
- Rapports : bascule entre vue tableau et graphique pour les onglets Tendances, Par catégorie et Évolution
- Rapports : option « Afficher les montants » pour afficher les valeurs directement sur les barres et courbes
- Rapports : panneau de filtres avec cases à cocher par catégorie (recherche, tout sélectionner/désélectionner) et filtre par source
- Rapports : le filtre source s'applique au niveau SQL pour des totaux filtrés précis
- Rapports : en-têtes de tableau fixes sur tous les tableaux de rapports (Rapport dynamique, Budget vs Réel)
- Rapports : survol interactif — barres non survolées estompées, info-bulle filtrée sur la catégorie survolée
- Rapports : le survol de la légende met en évidence la catégorie sur tous les mois (graphique Évolution)

### Corrigé
- Tableau des transactions : l'icône de commentaire devient orange (comme l'icône de ventilation) quand une note est présente (#7)

## [0.5.0]

### Ajouté
- Gestion d'erreurs : intercepte les plantages React et affiche une page d'erreur au lieu d'un écran blanc
- Délai de démarrage (10 s) sur la connexion à la base de données — affiche une page d'erreur au lieu d'un indicateur de chargement infini
- Page d'erreur avec « Rafraîchir », « Vérifier les mises à jour » et liens de contact
- Visionneuse de journaux dans les paramètres — capture la sortie console, filtrable par niveau, copiable, persiste entre les rafraîchissements
- Licence GPL-3.0 — le projet est maintenant open source

### Modifié
- Modale détail de rapport : colonnes triables — cliquez sur les en-têtes pour trier par date, description ou montant (#1)
- Modale détail de rapport : bascule pour afficher/masquer la colonne des montants (#3)
- Tableau de budget : les en-têtes de colonnes restent fixes lors du défilement vertical (#2)

### Corrigé
- Mise à jour automatique sur Linux : le champ version de `latest.json` n'a plus le préfixe `v`, téléversement au registre de paquets plus robuste
- Nouvelle tentative au démarrage : la connexion BD réessaie jusqu'à 3 fois avant d'afficher la page d'erreur (corrige l'échec au premier lancement sur Windows)
- Somme de contrôle de migration : répare automatiquement la somme de contrôle obsolète de la migration 1 au démarrage

## [0.4.4]

### Corrigé
- Le binaire Linux est maintenant compatible avec glibc 2.35+ (Ubuntu 22.04 / Pop!_OS) — le CI compile dans un conteneur Ubuntu 22.04

## [0.4.3]

### Corrigé
- Le point de terminaison de mise à jour automatique utilise maintenant le registre de paquets Forgejo pour une URL stable
- Les signatures Linux (.AppImage.sig) sont maintenant correctement collectées dans le CI
- Toutes les signatures de plateforme (.deb.sig, .rpm.sig) sont maintenant incluses dans les assets de la release

## [0.4.2]

### Modifié
- La mise à jour automatique pointe maintenant vers l'instance Forgejo auto-hébergée
- Les builds Windows sont maintenant compilés en croisé via cargo-xwin

## [0.4.1]

### Corrigé
- Application bloquée sur un indicateur de chargement infini après mise à jour depuis v0.3.x (somme de contrôle de migration incompatible sur seed_categories.sql)
- Les erreurs de connexion BD sont maintenant journalisées dans la console au lieu d'échouer silencieusement

## [0.4.0]

### Ajouté
- Catégories : support de 3 niveaux de hiérarchie (ex : Dépenses récurrentes → Assurances → Assurance-auto)
- Rapport dynamique : nouveau champ « Catégorie (Niveau 3) »
- Budget : sous-totaux intermédiaires et indentation 3 niveaux pour les catégories imbriquées
- Catégories : gestion automatique de `is_inputable` à la création/suppression de sous-catégories
- Catégories : la validation de profondeur empêche la création d'un 4e niveau
- Données initiales : Assurances divisées en Assurance-auto, Assurance-habitation, Assurance-vie

### Corrigé
- Auto-catégorisation : les mots-clés commençant/finissant par des caractères spéciaux (`[`, `]`, `(`, `)`, `-`, etc.) sont maintenant reconnus
- Auto-catégorisation : pré-compilation des regex pour de meilleures performances en lot

## [0.3.11]

### Ajouté
- Rapport dynamique : support de plusieurs dimensions en colonnes (clés composites)

### Corrigé
- Rapport dynamique : n'est plus affecté par les filtres de date globaux — utilise uniquement ses propres filtres du panneau

## [0.3.10]

### Ajouté
- Rapport dynamique : les champs peuvent maintenant être utilisés dans plusieurs zones simultanément (lignes + filtres, colonnes + filtres)
- Rapport dynamique : clic-droit sur une valeur de filtre pour l'exclure (affiché barré en rouge)
- Option de période « Cette année » dans les rapports et le tableau de bord (du 1er janvier à aujourd'hui)

## [0.3.9]

### Ajouté
- Rapport dynamique (tableau croisé) : composez des rapports personnalisés en assignant des dimensions aux lignes, colonnes, filtres et mesures aux valeurs
- Suppression de mots-clés depuis la vue « Tous les mots-clés »

## [0.3.8]

### Ajouté
- Sélecteur de plage de dates personnalisée pour les rapports et le tableau de bord
- Bascule pour positionner les sous-totaux au-dessus ou en dessous des lignes de détail
- Affichage des notes de version du CHANGELOG dans les releases et le système de mise à jour

## [0.3.7]

### Corrigé
- Suppression du bundle MSI pour éviter le conflit de chemin d'installation du système de mise à jour
- Changement du mode d'installation Windows à basicUi
- Amélioration de la visibilité de l'indicateur de ventilation et de la mise en page des ajustements

## 0.3.2

### Nouvelles fonctionnalités
- **Support Linux** : ajout des builds Linux (`.deb`, `.rpm`, `.AppImage`) au workflow de release
- **Ventilations sur la page Ajustements** : visualisez les ajustements de ventilation des transactions dans une section dédiée

### Corrigé
- Correction de cas limites de détection automatique CSV
- Suppression de l'accent dans productName pour la compatibilité `.deb` Linux

## 0.3.1

### Corrigé
- Toujours afficher le sélecteur de profil dans la barre latérale (#2)

## 0.3.0

### Nouvelles fonctionnalités
- **Profils multiples** : créez plusieurs profils avec des bases de données séparées, des noms et couleurs personnalisés
- **Protection par NIP** : protégez les profils avec un NIP numérique optionnel
- **Sélecteur de profil** : changement rapide de profil depuis la barre latérale
- **Glisser-déposer les catégories** : réordonnez les catégories ou changez le parent par glisser-déposer dans l'arborescence
- **Ventilation des transactions** : ventilez une transaction sur plusieurs catégories avec des montants ajustables

## 0.2.10

### Nouvelles fonctionnalités
- **Sélection rapide de période** : boutons de filtre rapide (Ce mois, Mois dernier, etc.) sur la page Transactions
- **Rapport Budget vs Réel** : tableau comparatif mensuel et cumulatif annuel dans les Rapports
- **Sous-totaux de catégories parentes** : la page Budget affiche les sous-totaux agrégés pour les catégories parentes
- **Guide utilisateur** : documentation complète accessible depuis les Paramètres, imprimable en PDF

### Améliorations
- Persistance de la sélection de modèle et ajout du bouton Mettre à jour le modèle
- Ne plus pré-sélectionner les fichiers déjà importés à l'entrée de la configuration source
- Rendre les imports de données de paramètres visibles dans l'historique d'import
- Remplacer les boutons de suppression par modèle par un seul bouton sur la sélection
- Remplacer l'icône de rafraîchissement par une icône de sauvegarde sur le bouton de mise à jour du modèle
- Ajout de la convention de signe à la page budget

## 0.2.9

### Corrigé
- Permettre les fichiers à contenu identique avec des noms différents (#1)

## 0.2.8

### Nouvelles fonctionnalités
- **Export/import de données** : exportez et importez vos données (transactions, catégories, ou les deux) avec chiffrement AES-256-GCM optionnel (#3)

### Corrigé
- Détection de doublons inter-fichiers et suivi d'import par fichier

## 0.2.5

### Nouvelles fonctionnalités
- **Modèles de configuration d'import** : sauvegardez et chargez les configurations de source d'import comme modèles réutilisables
- **Grille de budget 12 mois** : vue budgétaire annuelle complète avec cellules mensuelles et totaux annuels

### Corrigé
- Corrections du budget et des catégories
- Problème de somme de contrôle de migration (schema.sql ne doit pas être modifié après la release initiale)

## 0.2.3

### Nouvelles fonctionnalités
- **Motifs de graphiques** : ajout de motifs de remplissage SVG (lignes diagonales, points, hachures, etc.) pour différencier les catégories dans les graphiques au-delà de la couleur
- **Menu contextuel des graphiques** : clic-droit sur une catégorie dans un graphique pour la masquer ou voir ses transactions dans une fenêtre de détail
- **Catégories masquées** : les catégories masquées apparaissent comme des puces au-dessus des graphiques avec un bouton « Tout afficher »
- **Modale de détail des transactions** : visualisez toutes les transactions composant le total d'une catégorie directement depuis n'importe quel graphique
- **Aperçu d'import en popup** : l'aperçu des données est maintenant une modale popup au lieu d'une étape séparée de l'assistant
- **Vérification directe des doublons** : nouveau bouton « Vérifier les doublons » sur la page de configuration d'import

### Améliorations
- Flux de l'assistant d'import simplifié : configuration source → vérification des doublons (l'aperçu est optionnel via popup)
- Le bouton retour de la vérification des doublons retourne maintenant à la configuration source

## 0.2.2

- Mise à jour de version

## 0.2.1

- Ajout de la vue « Tous les mots-clés » sur la page Catégories
- Ajout du mode sombre avec palette de gris chauds
- Correction des catégories orphelines, persistance de has_header pour les imports, ajout de la réinitialisation
- Ajout des pages Budget et Ajustements
