From b0db1d31023135bf223c5ea87aa79d88f16ff78a Mon Sep 17 00:00:00 2001 From: le king fu Date: Thu, 8 Oct 2026 09:53:47 -0400 Subject: [PATCH 01/11] docs(guide): describe the guided getting-started path in the user guide The "Getting Started" section, which "Open the guide" opens at the end of the path, gains a "The getting-started path" sub-section in both locales and in docs/guide-utilisateur.md: the banner and its list, the step cards and their outline, "Skip this step" and "Resume", the end of the path, the profiles that find it hidden from the start, and how to show it again from Settings -> Users. It uses the sub-section shape DocsSubsections already reads for the Import section. The Dashboard and Settings sections no longer describe the compact bar the banner replaced, and the Profiles section says the path belongs to each profile. Co-Authored-By: Claude Opus 5.5 --- docs/guide-utilisateur.md | 28 ++++++++++++++++++++++------ src/i18n/locales/en.json | 34 +++++++++++++++++++++++++++------- src/i18n/locales/fr.json | 34 +++++++++++++++++++++++++++------- 3 files changed, 76 insertions(+), 20 deletions(-) diff --git a/docs/guide-utilisateur.md b/docs/guide-utilisateur.md index 8ac96ab..c042df6 100644 --- a/docs/guide-utilisateur.md +++ b/docs/guide-utilisateur.md @@ -16,10 +16,11 @@ Simpl'Résultat vous aide à suivre vos finances personnelles en important des r - Profils multiples avec bases de données séparées et NIP optionnel - Mode sombre avec palette gris chaud - Export et import de données avec chiffrement AES-256 optionnel +- Parcours de démarrage guidé : un bandeau en haut de chaque page et, sur la page de l'étape en cours, une carte qui dit quoi faire ### Démarrage rapide -Les six étapes ci-dessous sont celles de la liste de démarrage affichée sur le tableau de bord d'un profil neuf ; chaque case se coche d'elle-même quand l'étape est faite. +Les six étapes ci-dessous sont celles du parcours de démarrage. La carte d'accueil du tableau de bord d'un profil neuf les liste, puis le bandeau en haut de chaque page mène de l'une à la suivante (voir « Le parcours de démarrage », plus bas) ; chaque étape se coche d'elle-même quand elle est faite. 1. Créer un profil — chaque profil a sa propre base de données 2. Choisir un dossier d'import — le dossier où vous déposerez vos relevés, un sous-dossier par compte bancaire @@ -28,6 +29,20 @@ Les six étapes ci-dessous sont celles de la liste de démarrage affichée sur l 5. Classer une transaction à la main — le seed de mots-clés fait le gros du travail, une correction manuelle affine le reste 6. Saisir un premier budget — édition Base et plus ; suivez ensuite votre progression via les Rapports +### Le parcours de démarrage + +1. Le bandeau de démarrage s'affiche en haut de chaque page tant que le parcours n'est pas masqué. Il indique votre progression, par exemple « Démarrage 3/6 », et l'étape suivante, avec un lien vers la page où la faire. Il n'apparaît pas sur le tableau de bord d'un profil sans transaction, dont la carte d'accueil contient déjà la liste +2. « Voir la liste » déplie les six étapes sous le bandeau et « Fermer la liste » les replie ; la liste se replie aussi quand vous changez de page. Chaque étape à faire mène à la page où la faire +3. Sur les pages Import, Transactions et Budget, quand l'étape suivante s'y fait, une carte de démarrage remplace le bandeau. Elle indique « Étape n sur N », dit quoi faire et entoure d'un contour le contrôle à utiliser. Le contour pulse trois fois, et pas du tout si votre système demande de réduire les animations. Si vous arrivez par un lien « Étape suivante », le focus du clavier se place sur le titre de la carte +4. La carte suit l'étape sans que vous changiez de page. Sur la page Import, elle accompagne l'assistant écran par écran. Le lien de l'étape « Classer une transaction à la main » ouvre la page Transactions sur les transactions non catégorisées, toutes dates confondues, ou sur toutes les transactions s'il n'en reste aucune à classer. Sur la page Budget, la carte désigne d'abord « Tout déplier », puis la cellule du mois courant de la première catégorie à remplir ; elle ne déplie jamais la grille à votre place +5. Dès que l'étape est faite, la carte reste affichée, annonce « Fait. » et propose l'étape suivante, avec un lien vers sa page. Elle n'annonce pas « Fait. » pour un import qui n'a ajouté aucune transaction : le rapport d'import dit pourquoi +6. « Passer cette étape », sur la carte, marque l'étape comme passée : elle compte dans la progression, et la liste l'affiche avec le badge « Passée » et un lien « Reprendre ». « Reprendre » remet l'étape à faire et ouvre sa page +7. Quand toutes les étapes sont faites ou passées, le bandeau, ou la carte de la dernière étape, annonce « Démarrage terminé. Le guide d'utilisation vous accompagne pour la suite. » « Ouvrir le guide » mène à cette section Premiers pas, et « Fermer » masque le parcours +8. « Masquer », dans le bandeau ou dans la liste, masque le bandeau et la liste pour ce profil seulement. Pour les retrouver, ouvrez Paramètres → Utilisateurs et cliquez sur « Afficher la liste de démarrage » : le parcours réapparaît en haut des pages. Ce bouton est visible dès que le parcours est masqué +9. Un profil qui contenait déjà des transactions avant l'arrivée du parcours guidé le voit masqué d'office à sa première ouverture, comme après « Masquer » ; Paramètres → Utilisateurs le réaffiche. Un profil vide ou neuf le garde + +Les étapes se cochent d'elles-mêmes, sur vos données et sans changer de page : « Classer une transaction à la main » attend une transaction dont vous avez choisi la catégorie vous-même, et la catégorisation automatique de l'import ne la coche pas. En édition Gratuite, l'étape Budget est verrouillée et ne compte pas : le parcours se termine à 5/5. + ### Astuces - Vous pouvez basculer entre le français et l'anglais via le sélecteur de langue dans la barre latérale @@ -63,6 +78,7 @@ Gérez plusieurs profils indépendants, chacun avec sa propre base de données. - La suppression d'un profil supprime définitivement toutes ses données — cette action est irréversible - À l'ouverture d'un profil créé par une version antérieure, l'application met sa base à jour après en avoir gardé une copie dans le dossier `migration-backups`, à côté des bases (sous Linux `~/.config/com.simpl.resultat/`, sous Windows `%APPDATA%\com.simpl.resultat\`). La copie est supprimée avec le profil - Sous Linux, les versions jusqu'à la 0.17.0 laissaient sur le disque la base d'un profil supprimé (`~/.config/com.simpl.resultat/profile_….db`) ; vous pouvez supprimer ce fichier à la main +- Le parcours de démarrage est propre à chaque profil : ses étapes se cochent sur les données du profil, et le masquer dans un profil ne le masque pas dans les autres --- @@ -78,13 +94,13 @@ Le tableau de bord vous donne un aperçu rapide de votre situation financière p - Histogramme empilé des dépenses par catégorie et par mois - Sélecteur de période ajustable (par défaut : année à ce jour) - Menu contextuel (clic droit) pour masquer une catégorie ou voir ses transactions -- Liste de démarrage pour un profil neuf : six cases qui se cochent d'elles-mêmes selon vos données, avec un bouton « Masquer » +- Carte d'accueil d'un profil sans transaction, avec la liste de démarrage : six étapes qui se cochent d'elles-mêmes selon vos données, et un bouton « Masquer » ### Comment faire 1. Dans un profil sans transaction, le tableau de bord affiche une carte d'accueil et la liste de démarrage : créer un profil (déjà cochée), choisir un dossier d'import, configurer une source d'import, importer un premier fichier, classer une transaction à la main, saisir un premier budget. Chaque ligne non cochée mène à la page où la faire ; la case Budget est marquée « Base et plus » en édition Gratuite et ne compte pas dans le total -2. Après votre premier import, la liste se réduit à une barre compacte au-dessus des filtres, avec son compteur (par exemple 4 / 6), et disparaît d'elle-même quand toutes les cases sont cochées -3. « Masquer » retire la liste de ce profil seulement ; vous pouvez la réafficher depuis Paramètres → Utilisateurs +2. Dès que le profil a des transactions, la liste quitte le tableau de bord : le bandeau de démarrage, en haut de chaque page, la remplace jusqu'à la fin du parcours (voir Premiers pas → Le parcours de démarrage) +3. « Masquer » retire la liste de la carte d'accueil, et le bandeau de toutes les pages, pour ce profil seulement ; Paramètres → Utilisateurs les réaffiche 4. Utilisez le sélecteur de période en haut à droite pour choisir une plage de temps (mois, 3 mois, année, etc.) 5. Consultez les cartes résumées pour votre solde, revenus totaux et dépenses totales 6. Vérifiez le graphique circulaire pour voir comment vos dépenses sont réparties par catégorie @@ -567,7 +583,7 @@ Configurez les préférences de l'application, vérifiez les mises à jour, acc - Export des données (transactions, catégories, ou les deux) en format JSON ou CSV - Import des données depuis un fichier exporté précédemment - Chiffrement AES-256-GCM optionnel pour les fichiers exportés -- Réaffichage de la liste de démarrage du tableau de bord (Paramètres → Utilisateurs) quand elle a été masquée +- Réaffichage du parcours de démarrage (Paramètres → Utilisateurs) quand il a été masqué ### Comment faire @@ -578,7 +594,7 @@ Configurez les préférences de l'application, vérifiez les mises à jour, acc 5. Utilisez la section Gestion des données pour exporter ou importer vos données 6. Lors de l'export, choisissez ce qu'il faut inclure et définissez optionnellement un mot de passe pour le chiffrement 7. Lors de l'import, sélectionnez un fichier exporté précédemment — les fichiers chiffrés demanderont le mot de passe -8. Pour revoir la liste de démarrage après l'avoir masquée, ouvrez Paramètres → Utilisateurs et cliquez sur « Afficher la liste de démarrage » ; elle réapparaît sur le tableau de bord de ce profil. Le bouton n'est visible que si la liste a été masquée +8. Pour revoir le parcours de démarrage après l'avoir masqué, ouvrez Paramètres → Utilisateurs et cliquez sur « Afficher la liste de démarrage » : le parcours réapparaît en haut des pages de ce profil, et un message le confirme. Le bouton est visible dès que le parcours est masqué, même depuis le bandeau de cette page ### Astuces diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 12333e2..b738fbd 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -880,7 +880,8 @@ "Visual reports and interactive charts with context menu", "Multiple profiles with separate databases and optional PIN", "Dark mode with warm gray palette", - "Data export and import with optional AES-256 encryption" + "Data export and import with optional AES-256 encryption", + "Guided getting-started path: a banner at the top of every page and, on the page of the step in progress, a card that says what to do" ], "steps": [ "Create a profile — each profile has its own database", @@ -890,6 +891,24 @@ "Categorize a transaction by hand — the keyword seed does most of the work, a manual correction refines the rest", "Enter a first budget — Base edition and up; then track your progress through Reports" ], + "subsections": [ + { + "id": "getting-started-path", + "title": "The getting-started path", + "steps": [ + "The getting-started banner shows at the top of every page while the path is not hidden. It shows your progress, for instance \"Getting started 3/6\", and the next step, with a link to the page where it is done. It does not show on the dashboard of a profile without transactions, whose welcome card already holds the list", + "\"Show the list\" unfolds the six steps under the banner and \"Close the list\" folds them; the list also folds when you change pages. Each step still to do leads to the page where it is done", + "On the Import, Transactions and Budget pages, while the next step is done there, a getting-started card takes the place of the banner. It shows \"Step n of N\", says what to do and puts an outline around the control to use. The outline pulses three times, and not at all if your system asks for reduced motion. When you arrive by a \"Next step\" link, the keyboard focus goes to the card's title", + "The card follows the step without you changing pages. On the Import page, it goes along with the wizard screen by screen. The link of the \"Categorize a transaction by hand\" step opens the Transactions page on the uncategorized transactions whatever their date, or on every transaction when none is left uncategorized. On the Budget page, the card first points at \"Expand all\", then at the current month's cell of the first category you can fill in; it never unfolds the grid for you", + "As soon as the step is done, the card stays, says \"Done.\" and offers the next step, with a link to its page. It does not say \"Done.\" for an import that added no transaction: the import report says why", + "\"Skip this step\", on the card, marks the step as skipped: it counts towards your progress, and the list shows it with the \"Skipped\" badge and a \"Resume\" link. \"Resume\" puts the step back to do and opens its page", + "Once every step is done or skipped, the banner, or the card of the last step, says \"Getting started complete. The user guide takes it from here.\" \"Open the guide\" leads to this Getting Started section, and \"Close\" hides the path", + "\"Hide\", in the banner or in the list, hides the banner and the list for this profile only. To bring them back, open Settings → Users and click \"Show the getting-started checklist\": the path reappears at the top of the pages. The button shows as soon as the path is hidden", + "A profile that already had transactions before the guided path arrived has it hidden from its first opening, as if you had clicked \"Hide\"; Settings → Users shows it again. An empty or new profile keeps it" + ], + "note": "Steps tick on their own, from your data and without changing pages: \"Categorize a transaction by hand\" expects a transaction whose category you picked yourself, and the automatic categorization of the import does not tick it. In the Free edition, the Budget step is locked and does not count: the path ends at 5/5." + } + ], "tips": [ "You can switch between English and French using the language selector in the sidebar", "Toggle dark mode using the button in the sidebar", @@ -918,7 +937,8 @@ "The PIN is requested each time you access a protected profile", "Deleting a profile permanently removes all its data — this action cannot be undone", "When you open a profile created by an earlier version, the app updates its database after keeping a copy in the migration-backups folder, next to the databases (on Linux ~/.config/com.simpl.resultat/, on Windows %APPDATA%\\com.simpl.resultat\\). The copy is deleted with the profile", - "On Linux, versions up to 0.17.0 left a deleted profile's database on disk (~/.config/com.simpl.resultat/profile_….db); you can delete that file by hand" + "On Linux, versions up to 0.17.0 left a deleted profile's database on disk (~/.config/com.simpl.resultat/profile_….db); you can delete that file by hand", + "The getting-started path belongs to each profile: its steps tick from the profile's data, and hiding it in one profile does not hide it in the others" ] }, "dashboard": { @@ -931,12 +951,12 @@ "Stacked bar chart of expenses by category and month", "Adjustable time period selector (default: year to date)", "Context menu (right-click) to hide a category or view its transactions", - "Getting-started checklist for a new profile: six boxes that tick themselves from your data, with a \"Hide\" button" + "Welcome card for a profile without transactions, with the getting-started checklist: six steps that tick themselves from your data, and a \"Hide\" button" ], "steps": [ "In a profile without transactions, the dashboard shows a welcome card and the getting-started checklist: create a profile (already ticked), choose an import folder, set up an import source, import a first file, categorize a transaction by hand, enter a first budget. Each unticked row leads to the page where it is done; the Budget box is marked \"Base and up\" in the Free edition and does not count towards the total", - "After your first import, the list shrinks to a compact bar above the filters, with its counter (for instance 4 / 6), and disappears on its own once every box is ticked", - "\"Hide\" removes the list from this profile only; you can show it again from Settings → Users", + "Once the profile has transactions, the checklist leaves the dashboard: the getting-started banner, at the top of every page, takes over until the end of the path (see Getting Started → The getting-started path)", + "\"Hide\" removes the checklist from the welcome card, and the banner from every page, for this profile only; Settings → Users shows them again", "Use the period selector in the top-right to choose a time range (month, 3 months, year, etc.)", "Review the summary cards for your balance, total income, and total expenses", "Check the pie chart to see how your spending is distributed across categories", @@ -1256,7 +1276,7 @@ "Data import from a previously exported file", "Optional AES-256-GCM encryption for exported files", "Optional feedback submission to feedback.lacompagniemaximus.com (explicit exception to the 100% local operation — prompts for consent)", - "Show the dashboard's getting-started checklist again (Settings → Users) once it was hidden" + "Show the getting-started path again (Settings → Users) once it was hidden" ], "steps": [ "Click User Guide to access the full documentation", @@ -1266,7 +1286,7 @@ "When exporting, choose what to include and optionally set a password for encryption", "When importing, select a previously exported file — encrypted files will prompt for the password", "Click Send feedback in the Logs section to share a suggestion, comment, or issue — the identify and context/logs checkboxes are unchecked by default", - "To see the getting-started checklist again after hiding it, open Settings → Users and click \"Show the getting-started checklist\"; it reappears on this profile's dashboard. The button is only visible once the list was hidden" + "To see the getting-started path again after hiding it, open Settings → Users and click \"Show the getting-started checklist\": the path reappears at the top of this profile's pages, and a message confirms it. The button shows as soon as the path is hidden, even from the banner of that same page" ], "tips": [ "Updates only replace the app binary — your database is never modified", diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 43a2030..aca96d6 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -880,7 +880,8 @@ "Rapports visuels et graphiques interactifs avec menu contextuel", "Profils multiples avec bases de données séparées et NIP optionnel", "Mode sombre avec palette gris chaud", - "Export et import de données avec chiffrement AES-256 optionnel" + "Export et import de données avec chiffrement AES-256 optionnel", + "Parcours de démarrage guidé : un bandeau en haut de chaque page et, sur la page de l'étape en cours, une carte qui dit quoi faire" ], "steps": [ "Créer un profil — chaque profil a sa propre base de données", @@ -890,6 +891,24 @@ "Classer une transaction à la main — le seed de mots-clés fait le gros du travail, une correction manuelle affine le reste", "Saisir un premier budget — édition Base et plus ; suivez ensuite votre progression via les Rapports" ], + "subsections": [ + { + "id": "getting-started-path", + "title": "Le parcours de démarrage", + "steps": [ + "Le bandeau de démarrage s'affiche en haut de chaque page tant que le parcours n'est pas masqué. Il indique votre progression, par exemple « Démarrage 3/6 », et l'étape suivante, avec un lien vers la page où la faire. Il n'apparaît pas sur le tableau de bord d'un profil sans transaction, dont la carte d'accueil contient déjà la liste", + "« Voir la liste » déplie les six étapes sous le bandeau et « Fermer la liste » les replie ; la liste se replie aussi quand vous changez de page. Chaque étape à faire mène à la page où la faire", + "Sur les pages Import, Transactions et Budget, quand l'étape suivante s'y fait, une carte de démarrage remplace le bandeau. Elle indique « Étape n sur N », dit quoi faire et entoure d'un contour le contrôle à utiliser. Le contour pulse trois fois, et pas du tout si votre système demande de réduire les animations. Si vous arrivez par un lien « Étape suivante », le focus du clavier se place sur le titre de la carte", + "La carte suit l'étape sans que vous changiez de page. Sur la page Import, elle accompagne l'assistant écran par écran. Le lien de l'étape « Classer une transaction à la main » ouvre la page Transactions sur les transactions non catégorisées, toutes dates confondues, ou sur toutes les transactions s'il n'en reste aucune à classer. Sur la page Budget, la carte désigne d'abord « Tout déplier », puis la cellule du mois courant de la première catégorie à remplir ; elle ne déplie jamais la grille à votre place", + "Dès que l'étape est faite, la carte reste affichée, annonce « Fait. » et propose l'étape suivante, avec un lien vers sa page. Elle n'annonce pas « Fait. » pour un import qui n'a ajouté aucune transaction : le rapport d'import dit pourquoi", + "« Passer cette étape », sur la carte, marque l'étape comme passée : elle compte dans la progression, et la liste l'affiche avec le badge « Passée » et un lien « Reprendre ». « Reprendre » remet l'étape à faire et ouvre sa page", + "Quand toutes les étapes sont faites ou passées, le bandeau, ou la carte de la dernière étape, annonce « Démarrage terminé. Le guide d'utilisation vous accompagne pour la suite. » « Ouvrir le guide » mène à cette section Premiers pas, et « Fermer » masque le parcours", + "« Masquer », dans le bandeau ou dans la liste, masque le bandeau et la liste pour ce profil seulement. Pour les retrouver, ouvrez Paramètres → Utilisateurs et cliquez sur « Afficher la liste de démarrage » : le parcours réapparaît en haut des pages. Ce bouton est visible dès que le parcours est masqué", + "Un profil qui contenait déjà des transactions avant l'arrivée du parcours guidé le voit masqué d'office à sa première ouverture, comme après « Masquer » ; Paramètres → Utilisateurs le réaffiche. Un profil vide ou neuf le garde" + ], + "note": "Les étapes se cochent d'elles-mêmes, sur vos données et sans changer de page : « Classer une transaction à la main » attend une transaction dont vous avez choisi la catégorie vous-même, et la catégorisation automatique de l'import ne la coche pas. En édition Gratuite, l'étape Budget est verrouillée et ne compte pas : le parcours se termine à 5/5." + } + ], "tips": [ "Vous pouvez basculer entre le français et l'anglais via le sélecteur de langue dans la barre latérale", "Activez le mode sombre via le bouton dans la barre latérale", @@ -918,7 +937,8 @@ "Le NIP est demandé à chaque fois que vous accédez à un profil protégé", "La suppression d'un profil supprime définitivement toutes ses données — cette action est irréversible", "À l'ouverture d'un profil créé par une version antérieure, l'application met sa base à jour après en avoir gardé une copie dans le dossier migration-backups, à côté des bases (sous Linux ~/.config/com.simpl.resultat/, sous Windows %APPDATA%\\com.simpl.resultat\\). La copie est supprimée avec le profil", - "Sous Linux, les versions jusqu'à la 0.17.0 laissaient sur le disque la base d'un profil supprimé (~/.config/com.simpl.resultat/profile_….db) ; vous pouvez supprimer ce fichier à la main" + "Sous Linux, les versions jusqu'à la 0.17.0 laissaient sur le disque la base d'un profil supprimé (~/.config/com.simpl.resultat/profile_….db) ; vous pouvez supprimer ce fichier à la main", + "Le parcours de démarrage est propre à chaque profil : ses étapes se cochent sur les données du profil, et le masquer dans un profil ne le masque pas dans les autres" ] }, "dashboard": { @@ -931,12 +951,12 @@ "Histogramme empilé des dépenses par catégorie et par mois", "Sélecteur de période ajustable (par défaut : année à ce jour)", "Menu contextuel (clic droit) pour masquer une catégorie ou voir ses transactions", - "Liste de démarrage pour un profil neuf : six cases qui se cochent d'elles-mêmes selon vos données, avec un bouton « Masquer »" + "Carte d'accueil d'un profil sans transaction, avec la liste de démarrage : six étapes qui se cochent d'elles-mêmes selon vos données, et un bouton « Masquer »" ], "steps": [ "Dans un profil sans transaction, le tableau de bord affiche une carte d'accueil et la liste de démarrage : créer un profil (déjà cochée), choisir un dossier d'import, configurer une source d'import, importer un premier fichier, classer une transaction à la main, saisir un premier budget. Chaque ligne non cochée mène à la page où la faire ; la case Budget est marquée « Base et plus » en édition Gratuite et ne compte pas dans le total", - "Après votre premier import, la liste se réduit à une barre compacte au-dessus des filtres, avec son compteur (par exemple 4 / 6), et disparaît d'elle-même quand toutes les cases sont cochées", - "« Masquer » retire la liste de ce profil seulement ; vous pouvez la réafficher depuis Paramètres → Utilisateurs", + "Dès que le profil a des transactions, la liste quitte le tableau de bord : le bandeau de démarrage, en haut de chaque page, la remplace jusqu'à la fin du parcours (voir Premiers pas → Le parcours de démarrage)", + "« Masquer » retire la liste de la carte d'accueil, et le bandeau de toutes les pages, pour ce profil seulement ; Paramètres → Utilisateurs les réaffiche", "Utilisez le sélecteur de période en haut à droite pour choisir une plage de temps (mois, 3 mois, année, etc.)", "Consultez les cartes résumées pour votre solde, revenus totaux et dépenses totales", "Vérifiez le graphique circulaire pour voir comment vos dépenses sont réparties par catégorie", @@ -1256,7 +1276,7 @@ "Import des données depuis un fichier exporté précédemment", "Chiffrement AES-256-GCM optionnel pour les fichiers exportés", "Envoi de feedback optionnel vers feedback.lacompagniemaximus.com (exception explicite au fonctionnement 100% local — déclenche une demande de consentement)", - "Réaffichage de la liste de démarrage du tableau de bord (Paramètres → Utilisateurs) quand elle a été masquée" + "Réaffichage du parcours de démarrage (Paramètres → Utilisateurs) quand il a été masqué" ], "steps": [ "Cliquez sur Guide d'utilisation pour accéder à la documentation complète", @@ -1266,7 +1286,7 @@ "Lors de l'export, choisissez ce qu'il faut inclure et définissez optionnellement un mot de passe pour le chiffrement", "Lors de l'import, sélectionnez un fichier exporté précédemment — les fichiers chiffrés demanderont le mot de passe", "Cliquez sur Envoyer un feedback dans la section Journaux pour partager une suggestion, un commentaire ou un problème — la case d'identification et d'envoi du contexte/logs sont décochées par défaut", - "Pour revoir la liste de démarrage après l'avoir masquée, ouvrez Paramètres → Utilisateurs et cliquez sur « Afficher la liste de démarrage » ; elle réapparaît sur le tableau de bord de ce profil. Le bouton n'est visible que si la liste a été masquée" + "Pour revoir le parcours de démarrage après l'avoir masqué, ouvrez Paramètres → Utilisateurs et cliquez sur « Afficher la liste de démarrage » : le parcours réapparaît en haut des pages de ce profil, et un message le confirme. Le bouton est visible dès que le parcours est masqué, même depuis le bandeau de cette page" ], "tips": [ "Les mises à jour ne remplacent que le programme — votre base de données n'est jamais modifiée", -- 2.45.2 From 7ce5816bb289a32ab448e9420f8cdf3b8825d953 Mon Sep 17 00:00:00 2001 From: le king fu Date: Thu, 8 Oct 2026 09:53:52 -0400 Subject: [PATCH 02/11] test(docs): hold both locales to the shape the user guide reads DocsContent and DocsSubsections read the guide straight from fr.json and en.json, but their tests run on fixtures: a string where an array is expected, a sub-section without its steps or a French list longer than its English one only showed in the app. DocsContent.locales.test.ts reads the real files: every section DocsContent renders and no other, the strings and string arrays it reads, sub-sections that readSubsections keeps whole, anchors of their own, French and English item for item, and the path's sub-section in the section "Open the guide" opens. DocsContent exports SECTIONS for it. Co-Authored-By: Claude Opus 5.5 --- .../settings/DocsContent.locales.test.ts | 148 ++++++++++++++++++ src/components/settings/DocsContent.tsx | 3 +- 2 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 src/components/settings/DocsContent.locales.test.ts diff --git a/src/components/settings/DocsContent.locales.test.ts b/src/components/settings/DocsContent.locales.test.ts new file mode 100644 index 0000000..3915ef5 --- /dev/null +++ b/src/components/settings/DocsContent.locales.test.ts @@ -0,0 +1,148 @@ +// The user guide's docs.* keys, as DocsContent and DocsSubsections read them (#401). +// +// Both components read the guide straight from the locale files: `title` and +// `overview` as strings, `features`, `steps` and `tips` as string arrays +// (`returnObjects: true`), and the optional `subsections` through +// `readSubsections`, which drops a malformed entry without a word. Their own +// tests run on fixtures, so these tests hold the real files to that shape: a +// string where an array is expected, a sub-section without its steps, or a +// French list longer than its English one would otherwise only show in the app. + +import { describe, it, expect } from "vitest"; +import fr from "../../i18n/locales/fr.json"; +import en from "../../i18n/locales/en.json"; +import { SECTIONS } from "./DocsContent"; +import { readSubsections } from "./DocsSubsections"; +import { GETTING_STARTED_GUIDE } from "../onboarding/OnboardingBanner"; + +type Docs = Record; + +const LOCALES: Record = { + fr: (fr as { docs: Docs }).docs, + en: (en as { docs: Docs }).docs, +}; + +const SECTION_KEYS: string[] = SECTIONS.map((section) => section.key); + +/** The labels DocsContent reads besides the sections. */ +const SHARED_LABELS = ["title", "print", "features", "howTo", "quickStart", "tipsHeader"]; + +const LISTS = ["features", "steps", "tips"] as const; + +function isText(value: unknown): value is string { + return typeof value === "string" && value.trim().length > 0; +} + +function section(docs: Docs, key: string): Record { + const value = docs[key]; + expect(value, `docs.${key}`).toBeTypeOf("object"); + return value as Record; +} + +/** The section's sub-sections as declared, or an empty array when it has none. */ +function declaredSubsections(docs: Docs, key: string): Array> { + const value = section(docs, key).subsections; + return value === undefined ? [] : (value as Array>); +} + +describe("docs.* keys of the user guide", () => { + it("declare, in both locales, every section DocsContent renders and no other", () => { + for (const [lng, docs] of Object.entries(LOCALES)) { + const sectionsInFile = Object.keys(docs).filter( + (key) => typeof docs[key] === "object" && docs[key] !== null, + ); + expect(sectionsInFile, lng).toEqual(SECTION_KEYS); + } + }); + + it("give every section the strings and the string arrays DocsContent reads", () => { + for (const [lng, docs] of Object.entries(LOCALES)) { + for (const key of SECTION_KEYS) { + const value = section(docs, key); + expect(isText(value.title), `${lng} docs.${key}.title`).toBe(true); + expect(isText(value.overview), `${lng} docs.${key}.overview`).toBe(true); + for (const list of LISTS) { + const items = value[list]; + expect(Array.isArray(items), `${lng} docs.${key}.${list} is an array`).toBe(true); + expect((items as unknown[]).length, `${lng} docs.${key}.${list}`).toBeGreaterThan(0); + for (const item of items as unknown[]) { + expect(isText(item), `${lng} docs.${key}.${list}: ${JSON.stringify(item)}`).toBe(true); + } + } + } + for (const label of SHARED_LABELS) { + expect(isText(docs[label]), `${lng} docs.${label}`).toBe(true); + } + } + }); + + it("keep every declared sub-section whole: readSubsections drops none", () => { + for (const [lng, docs] of Object.entries(LOCALES)) { + for (const key of SECTION_KEYS) { + const declared = section(docs, key).subsections; + if (declared === undefined) continue; + expect(Array.isArray(declared), `${lng} docs.${key}.subsections is an array`).toBe(true); + const kept = readSubsections(declared); + expect(kept, `${lng} docs.${key}.subsections`).toHaveLength((declared as unknown[]).length); + for (const sub of kept) { + const where = `${lng} docs.${key}.subsections[${sub.id}]`; + expect(isText(sub.id), `${where}.id`).toBe(true); + expect(isText(sub.title), `${where}.title`).toBe(true); + expect(sub.steps.length, `${where}.steps`).toBeGreaterThan(0); + for (const step of sub.steps) expect(isText(step), `${where}.steps`).toBe(true); + if (sub.status !== undefined) expect(isText(sub.status), `${where}.status`).toBe(true); + if (sub.note !== undefined) expect(isText(sub.note), `${where}.note`).toBe(true); + } + } + } + }); + + it("give each sub-section an anchor of its own, apart from the section keys", () => { + // DocsContent keeps sections and sub-sections in one table of anchors + // (`/settings/users#import-export`): a shared id would hijack the scroll. + for (const [lng, docs] of Object.entries(LOCALES)) { + const ids = SECTION_KEYS.flatMap((key) => + declaredSubsections(docs, key).map((sub) => String(sub.id)), + ); + expect(new Set(ids).size, `${lng}: ${ids.join(", ")}`).toBe(ids.length); + for (const id of ids) expect(SECTION_KEYS, `${lng}: ${id}`).not.toContain(id); + } + }); + + it("match French and English item for item", () => { + for (const key of SECTION_KEYS) { + const frSection = section(LOCALES.fr, key); + const enSection = section(LOCALES.en, key); + for (const list of LISTS) { + expect((enSection[list] as unknown[]).length, `docs.${key}.${list}`).toBe( + (frSection[list] as unknown[]).length, + ); + } + const frSubs = declaredSubsections(LOCALES.fr, key); + const enSubs = declaredSubsections(LOCALES.en, key); + expect(enSubs.map((sub) => sub.id), `docs.${key}.subsections`).toEqual( + frSubs.map((sub) => sub.id), + ); + frSubs.forEach((frSub, i) => { + const enSub = enSubs[i]; + const where = `docs.${key}.subsections[${String(frSub.id)}]`; + expect((enSub.steps as unknown[]).length, `${where}.steps`).toBe( + (frSub.steps as unknown[]).length, + ); + expect("status" in enSub, `${where}.status`).toBe("status" in frSub); + expect("note" in enSub, `${where}.note`).toBe("note" in frSub); + }); + } + }); + + it("describe the getting-started path in the section that \"Open the guide\" opens", () => { + // The end of the path links to the guide by its hash (#397); the section it + // opens carries the path's own sub-section (#401). + const target = GETTING_STARTED_GUIDE.split("#")[1]; + expect(SECTION_KEYS).toContain(target); + for (const [lng, docs] of Object.entries(LOCALES)) { + const ids = readSubsections(section(docs, target).subsections).map((sub) => sub.id); + expect(ids, lng).toContain("getting-started-path"); + } + }); +}); diff --git a/src/components/settings/DocsContent.tsx b/src/components/settings/DocsContent.tsx index e48eed8..c5bb6bb 100644 --- a/src/components/settings/DocsContent.tsx +++ b/src/components/settings/DocsContent.tsx @@ -21,7 +21,8 @@ import { } from "lucide-react"; import DocsSubsections from "./DocsSubsections"; -const SECTIONS = [ +/** The guide's sections, in order; `DocsContent.locales.test.ts` holds both locales to them. */ +export const SECTIONS = [ { key: "gettingStarted", icon: Rocket }, { key: "profiles", icon: Users }, { key: "dashboard", icon: LayoutDashboard }, -- 2.45.2 From d6f42dbe325d8cf632786a929342103eab2f843e Mon Sep 17 00:00:00 2001 From: le king fu Date: Thu, 8 Oct 2026 09:53:58 -0400 Subject: [PATCH 03/11] docs: architecture, QA checklist and changelog for the guided path - architecture.md: the Onboarding section describes the guided path as delivered (provider and useOnboarding(), the data-change channel of ADR 0022, the three onboarding preferences, rule D9, the pure models of onboardingPath.ts, the banner, the card latch and CARD_PAGES, the step cards, the highlight by props and CSS); the utils count and the user_preferences row follow the stack. - qa-onboarding.html: the phase 1 cases that still hold, without the compact bar ones, and four guided-path groups, including the manual checks the five links left for a release build (WebKitGTK and WebView2, Orca and NVDA, reduced motion, keyboard, Free edition, rule D9). - CHANGELOG (EN and FR): one entry for what every step card does, one per page, the path hidden on active profiles covers the banner too, the skipped state, and the guide's new sub-section. - STATE.md: manual checks due on the next release. Resolves #401 Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.fr.md | 14 +- CHANGELOG.md | 14 +- STATE.md | 1 + docs/architecture.md | 53 ++++++- docs/qa-onboarding.html | 337 +++++++++++++++++++++++++++------------- 5 files changed, 295 insertions(+), 124 deletions(-) diff --git a/CHANGELOG.fr.md b/CHANGELOG.fr.md index 7a79449..71f2e5e 100644 --- a/CHANGELOG.fr.md +++ b/CHANGELOG.fr.md @@ -4,15 +4,17 @@ ### Ajouté -- Un bandeau de démarrage en haut de chaque page tant que le parcours de démarrage est affiché : « Démarrage 3/6 », l'étape suivante avec un lien vers la page où la faire, « Voir la liste », qui déplie les six étapes en place, et « Masquer », qui masque le bandeau et la liste pour le profil courant. Il n'apparaît pas sur le tableau de bord d'un profil sans transaction, dont la carte d'accueil contient déjà la liste. Une fois toutes les étapes faites, il l'annonce et propose « Ouvrir le guide », qui mène à la section « Premiers pas » du guide d'utilisation, et « Fermer », qui le retire jusqu'à un réaffichage depuis Paramètres → Utilisateurs (#397). -- Une carte de démarrage sur la page Import, à la place du bandeau, tant que l'étape suivante du parcours s'y fait (choisir un dossier d'import, configurer une source d'import, importer un premier fichier). Elle indique « Étape n sur N », dit quoi faire à chaque écran de l'assistant d'import et désigne le contrôle à utiliser par un contour qui pulse trois fois, et pas du tout quand le système demande de réduire les animations. Elle suit l'assistant pas à pas, annonce « Fait. » une fois le fichier importé et propose « Étape suivante », qui mène à la page de l'étape d'après ; elle n'annonce pas « Fait. » pour un import qui n'a ajouté aucune transaction. Arriver sur la page Import par un lien « Étape suivante » place le focus du clavier sur le titre de la carte. « Passer cette étape » marque l'étape comme passée dans la liste de démarrage, où « Reprendre » l'annule (#398). -- Une carte de démarrage sur la page Transactions, à la place du bandeau, tant que l'étape suivante du parcours est de classer une transaction à la main. Le lien de cette étape ouvre la page sur les transactions non catégorisées, toutes dates confondues, ou sur toutes les transactions s'il n'en reste aucune à classer. La carte dit quoi faire et désigne la catégorie de la première transaction affichée. Choisir une catégorie coche l'étape : la carte annonce « Fait. » et propose « Saisir un premier budget », ou la fin du parcours en édition Gratuite (#399). -- Une carte de démarrage sur la page Budget, à la place du bandeau, tant que l'étape suivante du parcours est de saisir un premier budget. La grille du budget s'ouvre catégories repliées : la carte désigne d'abord « Tout déplier », puis la cellule du mois courant de la première catégorie à remplir, et ne déplie jamais la grille à votre place. Elle rappelle qu'Entrée enregistre, et que Tab enregistre et passe au mois suivant. Enregistrer un montant coche l'étape : la carte annonce « Fait. » et termine le parcours, avec « Ouvrir le guide » et « Fermer » (#400). +- Un bandeau de démarrage en haut de chaque page tant que le parcours de démarrage est affiché : « Démarrage 3/6 », l'étape suivante avec un lien vers la page où la faire, « Voir la liste », qui déplie les six étapes en place, et « Masquer », qui masque le bandeau et la liste pour le profil courant. Il n'apparaît pas sur le tableau de bord d'un profil sans transaction, dont la carte d'accueil contient déjà la liste. Une fois toutes les étapes faites ou passées, il l'annonce et propose « Ouvrir le guide », qui mène à la section « Premiers pas » du guide d'utilisation, et « Fermer », qui le retire jusqu'à un réaffichage depuis Paramètres → Utilisateurs (#397). +- Des cartes de démarrage sur les pages Import, Transactions et Budget. Tant que l'étape suivante du parcours se fait sur l'une de ces pages, une carte y prend la place du bandeau : elle indique « Étape n sur N », dit quoi faire et désigne le contrôle à utiliser par un contour qui pulse trois fois, et pas du tout quand le système demande de réduire les animations. Quand l'étape est faite, la carte reste, annonce « Fait. » et propose « Étape suivante », qui mène à la page de l'étape d'après, ou la fin du parcours. Arriver sur une page par un lien « Étape suivante » place le focus du clavier sur le titre de la carte. « Passer cette étape » marque l'étape comme passée dans la liste de démarrage, où « Reprendre » l'annule (#398, #399, #400). +- Sur la page Import, la carte de démarrage suit l'assistant d'import écran par écran, à travers ses trois étapes (choisir un dossier d'import, configurer une source d'import, importer un premier fichier), et n'annonce pas « Fait. » pour un import qui n'a ajouté aucune transaction (#398). +- Sur la page Transactions, le lien de l'étape « Classer une transaction à la main » ouvre la page sur les transactions non catégorisées, toutes dates confondues, ou sur toutes les transactions s'il n'en reste aucune à classer, et la carte désigne la catégorie de la première transaction affichée. En édition Gratuite, qui n'a pas d'étape Budget, classer une transaction termine le parcours (#399). +- Sur la page Budget, dont la grille s'ouvre catégories repliées, la carte de démarrage désigne d'abord « Tout déplier », puis la cellule du mois courant de la première catégorie à remplir, et ne déplie jamais la grille à votre place. Elle rappelle qu'Entrée enregistre, et que Tab enregistre et passe au mois suivant. Enregistrer un montant termine le parcours (#400). +- Une sous-section « Le parcours de démarrage » dans la section « Premiers pas » du guide d'utilisation, celle qu'ouvre « Ouvrir le guide » à la fin du parcours : le bandeau et sa liste, les cartes d'étape et leur contour, « Passer cette étape » et « Reprendre », la fin du parcours, les profils qui le trouvent masqué d'office, et son réaffichage depuis Paramètres → Utilisateurs. Les sections Tableau de bord, Profils et Paramètres du guide décrivent le parcours tel qu'il fonctionne désormais (#401). ### Modifié -- La liste de démarrage ne s'affiche plus dans un profil qui avait déjà des transactions avant cette version : à la première ouverture d'un tel profil, la liste est masquée, comme après un clic sur « Masquer », et « Afficher la liste de démarrage », dans Paramètres → Utilisateurs, la fait revenir. Un profil sans transaction la garde (#396). -- Le tableau de bord n'affiche plus la barre compacte de démarrage une fois que le profil a des transactions : le bandeau la remplace sur chaque page. Dans la liste détaillée, les lecteurs d'écran annoncent désormais si chaque étape est faite, verrouillée ou en attente (#397). +- Le parcours de démarrage ne s'affiche plus dans un profil qui avait déjà des transactions avant cette version : à la première ouverture d'un tel profil, le bandeau et sa liste sont masqués, comme après un clic sur « Masquer », et « Afficher la liste de démarrage », dans Paramètres → Utilisateurs, les fait revenir. Un profil sans transaction les garde (#396). +- Le tableau de bord n'affiche plus la barre compacte de démarrage une fois que le profil a des transactions : le bandeau la remplace sur chaque page. Dans la liste détaillée, les lecteurs d'écran annoncent désormais si chaque étape est faite, passée, verrouillée ou en attente (#397). - Paramètres → Utilisateurs propose « Afficher la liste de démarrage » dès que le parcours est masqué, y compris depuis le bandeau de cette même page, et confirme désormais que le parcours réapparaît en haut des pages (#397). ### Corrigé diff --git a/CHANGELOG.md b/CHANGELOG.md index dfda285..2e87b50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,15 +4,17 @@ ### Added -- A getting-started banner at the top of every page while the getting-started path is shown: "Getting started 3/6", the next step with a link to the page where it is done, "Show the list", which unfolds the six steps in place, and "Hide", which hides the banner and the list for the current profile. It does not show on the dashboard of a profile without transactions, whose welcome card already holds the list. Once every step is done, it says so and offers "Open the guide", which leads to the "Getting Started" section of the user guide, and "Close", which removes it until it is shown again from Settings → Users (#397). -- A getting-started card on the Import page, in place of the banner, while the next step of the path is done there (choose an import folder, set up an import source, import a first file). It shows "Step n of N", says what to do on each screen of the import wizard and points at the control to use with an outline that pulses three times, not at all when the system asks for reduced motion. It follows the wizard as you go, says "Done." once the file is imported and offers "Next step", which leads to the page of the following step; it does not say "Done." for an import that added no transaction. Arriving on the Import page by a "Next step" link puts the keyboard focus on the card's title. "Skip this step" marks the step as skipped in the getting-started list, where "Resume" takes it back (#398). -- A getting-started card on the Transactions page, in place of the banner, while the next step of the path is to categorize a transaction by hand. The link of that step opens the page on the uncategorized transactions whatever their date, or on every transaction when none is left uncategorized. The card says what to do and points at the category of the first transaction shown. Choosing a category ticks the step: the card says "Done." and offers "Enter a first budget", or the end of the path in the Free edition (#399). -- A getting-started card on the Budget page, in place of the banner, while the next step of the path is to enter a first budget. The budget grid opens with its categories folded: the card first points at "Expand all", then at the current month's cell of the first category you can fill in, and never unfolds the grid for you. It reminds you that Enter saves, and that Tab saves and moves to the next month. Saving an amount ticks the step: the card says "Done." and ends the path, with "Open the guide" and "Close" (#400). +- A getting-started banner at the top of every page while the getting-started path is shown: "Getting started 3/6", the next step with a link to the page where it is done, "Show the list", which unfolds the six steps in place, and "Hide", which hides the banner and the list for the current profile. It does not show on the dashboard of a profile without transactions, whose welcome card already holds the list. Once every step is done or skipped, it says so and offers "Open the guide", which leads to the "Getting Started" section of the user guide, and "Close", which removes it until it is shown again from Settings → Users (#397). +- Getting-started cards on the Import, Transactions and Budget pages. While the next step of the path is done on one of these pages, a card takes the place of the banner there: it shows "Step n of N", says what to do and points at the control to use with an outline that pulses three times, not at all when the system asks for reduced motion. When the step gets done, the card stays, says "Done." and offers "Next step", which leads to the page of the following step, or the end of the path. Arriving on a page by a "Next step" link puts the keyboard focus on the card's title. "Skip this step" marks the step as skipped in the getting-started list, where "Resume" takes it back (#398, #399, #400). +- On the Import page, the getting-started card follows the import wizard screen by screen through its three steps (choose an import folder, set up an import source, import a first file), and does not say "Done." for an import that added no transaction (#398). +- On the Transactions page, the link of the "Categorize a transaction by hand" step opens the page on the uncategorized transactions whatever their date, or on every transaction when none is left uncategorized, and the card points at the category of the first transaction shown. In the Free edition, which has no Budget step, categorizing a transaction ends the path (#399). +- On the Budget page, whose grid opens with its categories folded, the getting-started card first points at "Expand all", then at the current month's cell of the first category you can fill in, and never unfolds the grid for you. It reminds you that Enter saves, and that Tab saves and moves to the next month. Saving an amount ends the path (#400). +- A sub-section, "The getting-started path", in the "Getting Started" section of the user guide, the one "Open the guide" opens at the end of the path: the banner and its list, the step cards and their outline, "Skip this step" and "Resume", the end of the path, the profiles that find it hidden from the start, and how to show it again from Settings → Users. The Dashboard, Profiles and Settings sections of the guide describe the path as it now works (#401). ### Changed -- The getting-started checklist no longer shows in a profile that already had transactions before this version: the first time such a profile is opened, the checklist is hidden, as if you had clicked "Hide", and "Show the getting-started checklist" in Settings → Users brings it back. A profile without transactions keeps it (#396). -- The dashboard no longer shows the compact getting-started bar once the profile has transactions: the banner replaces it on every page. In the detailed list, screen readers now hear whether each step is done, locked or pending (#397). +- The getting-started path no longer shows in a profile that already had transactions before this version: the first time such a profile is opened, the banner and its checklist are hidden, as if you had clicked "Hide", and "Show the getting-started checklist" in Settings → Users brings them back. A profile without transactions keeps them (#396). +- The dashboard no longer shows the compact getting-started bar once the profile has transactions: the banner replaces it on every page. In the detailed list, screen readers now hear whether each step is done, skipped, locked or pending (#397). - Settings → Users offers "Show the getting-started checklist" as soon as the path is hidden, also when it was hidden from the banner of that same page, and now confirms that the path reappears at the top of the pages (#397). ### Fixed diff --git a/STATE.md b/STATE.md index 900b287..3e12dbf 100644 --- a/STATE.md +++ b/STATE.md @@ -65,6 +65,7 @@ Audit critique de la page Bilan livré (`docs/audit-bilan-2026-05.md`, revue CPA - **Le paiement est live : « aucun tag avant le go-live » n'a plus de raison d'être, et la release desktop qu'attendait le go-live est publiée (v0.16.0, 2026-10-03).** Bascule live le 2026-09-29 (Product et Price live à 19 $ CAD, webhook, variables Stripe de production, redeploy `3673d09` de maximus-api, URL `cs_live_` vérifiée), puis achat réel de contrôle le 2026-09-30 : clé sur `/merci` et par courriel, activation dans l'app, remboursement complet et licence révoquée par `charge.refunded`. **Volet serveur clos le 2026-10-03** (derniers commentaires relus le 2026-10-04) : maximus-api#62 fermée, tous critères cochés (maximus-api 0.4.2 en prod, secrets en runtime seul), avec la milestone `spec-paiements` de maximus-api (12/12) ; la-compagnie-maximus#150 (Link dans les textes légaux) livrée et fermée le 2026-10-01. **Clôture du go-live = la-compagnie-maximus#141** (`status:blocked`), qui n'attend plus que ce dépôt : l'updater vérifié (Free refuse et invite à acheter, Base accepte), #350 étant fermée depuis le 2026-10-04. la-compagnie-maximus#184 (politique de confidentialité : données d'activation, contrôle au démarrage) est en `status:review` ; sa PR reste en brouillon jusqu'au déploiement de maximus-api#85 (commentaire du 2026-10-03). Les deux textes des suites de licence (contrôle à la saisie, retrait de la clé) y sont postés depuis le 2026-10-05 (commentaire 19724). **Vérifications manuelles sur la release publiée, toutes faites** : #365 le 2026-10-03, #346 et #350 le 2026-10-04 (voir Décisions). Reste l'étape 10 de `/release` sous Windows (Michel). - **Vérifications post-merge de #390** (PR #394, sur le prochain build) : la case 5 se coche après un classement manuel ; sous Linux, un vrai profil secondaire ancien affiche « database updated with versions … » au Journal, sa copie est dans `~/.config/com.simpl.resultat/migration-backups/` et l'import y fonctionne ; supprimer un profil retire son `.db` ; les rendements du Bilan s'affichent. #390 reste en `status:blocked` jusque-là. - **Vérifications manuelles dues sur la v0.17.0 publiée** (onboarding + suites de licence ; Linux puis Windows), dans un ordre qui ne détruit le jeton d'activation qu'à la fin de ce qui en dépend : (1) #370, machine activée hors ligne → « Retirer la clé » : seconde confirmation qui donne la raison, Annuler ne change rien, sauts de ligne des fenêtres ; (2) #367, s'il existe un second poste avec la même clé : y désactiver ce poste, puis ouvrir ici la liste des machines → « Activer » revient sans recharger, ligne au Journal ; (3) #370 en ligne → place libérée, carte en Gratuite ; (4) #373 et #370 avec la clé révoquée du 2026-09-30 : Base une à deux secondes puis Gratuite, ligne « License check: the license server says the key was revoked » ; retirée → aucune désactivation envoyée, puis au redémarrage « no valid key stored, nothing sent » ; ressaisie → reste en Gratuite ; (5) clé testeur Premium ressaisie, « Activer », `verif-350.py` rend `64 brut: False dérivé: True` ; (6) #367, dossier v0.15.0 (clé A à côté du jeton d'une licence B révoquée) : couvert par un test de bout en bout, à faire seulement si un tel dossier existe encore. Plus la liste QA de l'onboarding (`docs/qa-onboarding.html`). +- **Vérifications manuelles dues sur la prochaine release : parcours de démarrage guidé** (#396 à #401, milestone `planned-2026-10-06-onboarding-parcours-guide`), d'abord sous Linux avec Orca, puis sous Windows avec NVDA : les sections « Parcours guidé » de `docs/qa-onboarding.html` (profil neuf de bout en bout, bandeau et liste, « Passer » et « Reprendre », règle D9 sur un vrai profil ancien, édition Gratuite à 5/5, contour dans WebKitGTK et WebView2, mouvement réduit, clavier, annonces). #401 se ferme au merge ; la liste de la phase 1 pour la v0.17.0 reste lisible par `git show v0.17.0:docs/qa-onboarding.html`. - Backlog ouvert : **vague `planned-2026-09-24-paiements` close 3/3** (milestone fermée le 2026-09-30) : #270 (PR #359) et #346 (PR #362) mergées le 2026-09-27, #347 (PR #364, ferme aussi #360) mergée le 2026-09-30 ; volet site **clos** (maximus/la-compagnie-maximus#153, redirection de `/simpl-resultat` en prod). **#365 fermée le 2026-10-03** après sa vérification manuelle. **Milestone `planned-2026-10-03-suites-licence` fermée 3/3 le 2026-10-05** (#373, #370, #367 mergées, voir Décisions ; suivi #389 en `status:triage`). Hors milestone, en `status:ready` : **#369** (réserver le fractionnement de transactions à l'édition Base) et **#372** (la liste complète des versions repousse le Journal en bas de Paramètres → Systèmes). **#350 fermée le 2026-10-04** (étape 3 vérifiée en production, voir Décisions) ; reste de #363 (plafond de `/issue-license` à 36525 jours et essai d'une vraie clé de 100 ans, débloqués par le déploiement de maximus-api#63) ; réglés côté serveur et site : maximus-api#63 (clés de 100 ans) et maximus-api#70 (réactivation d'une machine désactivée), fermées et contenues dans `3673d09`, le commit déployé à la bascule du 2026-09-29, et la-compagnie-maximus#157, fermée, dont les CGV sont publiées en tronc commun plus annexe Simpl-Résultat (annexe relue en production le 2026-09-30, plus aucune durée de 10 ans) ; côté serveur, `/v1/prices` ne vérifie pas qu'une machine est encore active (une machine désactivée garde les cours jusqu'à l'expiration de son jeton), issue maximus-api à ouvrir ; suites de #350 ouvertes le 2026-10-01 : maximus-api#82 (`status:triage` : identifiants machine bruts déjà stockés, lignes désactivées comprises ; à rehacher avant l'expiration des premiers jetons bruts, sinon une réactivation crée une seconde ligne) et la-compagnie-maximus#184 (`status:review`, voir ci-dessus) ; clôture du go-live = la-compagnie-maximus#141 seule, maximus-api#62 étant fermée ; `spec-paiements` reste le parapluie des trois dépôts (ici 4/5, reste #363) ; onboarding phase 1 **livrée** : milestone `planned-2026-10-03-onboarding-phase1` fermée 7/7 le 2026-10-04 (#351 à #357, mergées en avance rapide, `667e058`) ; suivis ouverts : **#384** (`status:ready`, suivis non bloquants des revues) et **#371** (`status:blocked`, hors `/autopilot` : en-têtes CSV BMO à fournir par Max depuis un compte réel, un par type de compte, chèques/épargne et Mastercard, avec des valeurs fictives) ; analyse d'origine dans `docs/analyse-onboarding-2026-09.md`, plan détaillé dans les `spec-*-onboarding-phase1.md` locaux, ignorés par git ; #271 absorbé par #301, livré ; `spec-ci-build-optimization` **fermée 4/4** le 2026-10-05 (#232 livrée le 2026-07-27 ; #234 close le 2026-10-05 avec ses quatre preuves : dispatch run 464, PR #386 run 480, run planifié 488, `actcache` à 999 Mo) ; **#376** (`status:triage` : Node 20, en fin de vie depuis le 2026-04-30, encore installé par `check-frontend.yml` et `audit.yml`, et commentaire `concurrency` de `check-rust.yml` démenti par `forgejo-ops.md` pour les runs de PR). Le suivi « glob `src-tauri/**` non prouvé » ouvert avec #232 est **levé** : la PR #344 est le cas test isolé attendu (`Cargo.lock` + 2 `.md` seulement) — `check-rust` a bien tourné, `check-frontend` a bien été sauté par sa denylist. - Suivis des advisories : **#312, #313 et #315 fermées le 2026-08-15** (PRs #321/#322 mergées). **#314 fermée le 2026-08-15, prémisse infirmée** — elle affirmait « zéro run `schedule` », or `audit.yml` tire tous les jours à 06:00 UTC (**19 runs `schedule` verts** du 07-28 au 08-15, sans trou) ; elle a été écrite le 07-27 vers 23:56Z, ~6 h avant le premier tir programmé possible, et décrivait donc une fenêtre trop courte, pas un scheduler en panne. Ces 19 runs confirment au passage que `.cargo/audit.toml` est bien lu en conteneur **sur `main`** — l'ADR 0018 ne l'avait vérifié que par un `workflow_dispatch` sur une branche. **#343 fermée le 2026-09-04** (PR #344) — RUSTSEC-2026-0258 sur `h2`, la seule vulnérabilité qui rougissait l'audit depuis le 08-19 ; l'audit est de nouveau vert sur `main`, prouvé par `workflow_dispatch` (run 393) et non déduit du run de PR. **#348 fermée le 2026-09-21** (PR #349) — RUSTSEC-2026-0285 sur `rustls`, seule vulnérabilité rougissant l'audit depuis le 09-15 (7 runs, 405→411) ; vert reprouvé par `workflow_dispatch` sur `main` (run 414 : 666 paquets, zéro vulnérabilité, 12 warnings autorisés). Deux advisories en cinq semaines sur le même chemin, celui de la mise à jour automatique. Restent **#317** (prémisse caduque depuis le 2026-09-26 : `react-router-dom` 7.18.2 et suivantes corrigent l'advisory par un bump de patch dans `^7.18.1`, sans migration v8 ; absorbée par #358, dont la PR la fermera), **#319** (déclencheur de retrait pour `rsa`, désormais **seule** entrée de `.cargo/audit.toml` — le garde-fou est passé à 2 vérifications) et **#345** (domicilier la contrainte `windows-sys 0.61.2` — analysée le 09-04 : le corps d'origine, écrit de mémoire en fin de revue, se trompait sur trois points. Le déclencheur n'est pas « n'importe quel `cargo update` » mais tout bump atteignant le sous-arbre réseau/TLS — mesuré : `-p anyhow` ne bouge rien, `-p hyper` fait descendre les 7 — soit précisément là où tombent les advisories. **Prémisse restreinte le 2026-09-21 par #348** : `-p rustls`, au cœur de ce même sous-arbre, n'en déplace **aucun** — le déclencheur tient à `hyper` et à ce qu'il tire, pas à la couche TLS en général, donc « sous-arbre réseau/TLS » prédit une dérive là où il n'y en a pas et ferait écrire une strophe à la main sans nécessité. D'où la suggestion portée en commentaire sur l'issue : formuler le garde-fou sur la **version résolue de `windows-sys`** plutôt que sur une liste de crates déclencheurs — la liste est ce qui vient d'être trouvé faux, la version est ce qui est protégé. #310 avait **bien** vu la dérive et l'avait jugée inoffensive *sur Linux*, où elle l'est ; son coût tombe sur le build Windows que personne ne mesurait : **3 versions de `windows-sys` compilées contre 5**. Aucun risque de correction — les 7 crates déclarent des bornes larges couvrant les deux états. Et cargo annonce « Locking 1 package » en écrivant 8 changements, donc le silence est le sien. Décision : garde-fou CI sur la version + ADR portant la condition de sortie. Le check croisé Windows depuis Linux a été **testé et écarté** — `cc-rs` s'arrête sur `lib.exe`, il faudrait `cargo-xwin`). Côté npm, **#358** ouverte le 2026-09-26 par `/analyse-vulnerabilite` : `npm audit` remonte 7 findings (4 high, 3 moderate) sur 4 dépendances racines, contre les 2 acceptés au 07-27, et chaque correctif tient dans la borne déjà déclarée ; le lock se régénère avec `npx npm@11` (npm 10 plante sur un bump de vitest 4.1.x). - Nouveau bug ouvert : **#320** — les installations `.rpm` ne reçoivent aucune mise à jour (`latest.json` ne porte qu'une entrée `linux-x86_64` construite depuis le `.deb`, `release.yml:104-122`), alors que les `.rpm` continuent d'être publiés en assets. Documenté en §3 de `docs/qa-update-cycle.md` (« ne pas tester : cassé, pas seulement non vérifié »). diff --git a/docs/architecture.md b/docs/architecture.md index fe19751..f0d77f6 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -45,7 +45,7 @@ simpl-resultat/ │ ├── pages/ # 14 pages (dont 4 sous-pages rapports) │ ├── services/ # 26 services métier (20 détaillés dans la section « Services TypeScript ») │ ├── shared/ # Types, constantes, matrice d'entitlements (entitlements.ts), gate profils (profileGate.ts), CTA d'upsell (upsellCta.ts), URL d'achat (purchaseUrl.ts), échéance de licence (licenseExpiry.ts) -│ ├── utils/ # 14 utilitaires purs (parsing montants/dates, détection CSV, codec de format d'import, dictionnaire lexical, signatures de banques, charts, drapeaux SQL 0/1) +│ ├── utils/ # 16 utilitaires purs (parsing montants/dates, détection CSV, codec de format d'import, dictionnaire lexical, signatures de banques, charts, drapeaux SQL 0/1, liste et parcours de démarrage) │ ├── i18n/ # Config i18next + locales FR/EN │ ├── __fixtures__/ # csv/ : corpus de détection (15 cas figés) ; samples/ : gabarits du dossier d'exemple embarqués par Rust │ ├── App.tsx # Router principal @@ -97,7 +97,7 @@ simpl-resultat/ | `budget_templates` | Modèles de budget réutilisables | | `budget_template_entries` | Catégories et montants dans les modèles | | `import_config_templates` | Modèles prédéfinis de config d'import | -| `user_preferences` | Préférences applicatives (clé-valeur) — `import_folder`, `balance_show_returns`, `balance_starter_proposed`, `onboarding_checklist_hidden` (« 1 » quand la liste de démarrage a été masquée ; la clé est supprimée par « Afficher la liste de démarrage », #351-#352)… **et l'état de repli des catégories** (clés `reports-compare-expanded`, `reports-bva-expanded`, `reports-trends-expanded`, `budget-grid-expanded`) : persisté ici **par profil** plutôt qu'en `localStorage`, pour être détruit avec le profil (pas de résidu machine-global survivant à la suppression) — voir [ADR 0016](adr/0016-persistance-etat-ui-par-profil.md) | +| `user_preferences` | Préférences applicatives (clé-valeur) — `import_folder`, `balance_show_returns`, `balance_starter_proposed`, `onboarding_checklist_hidden` (« 1 » quand le parcours de démarrage est masqué ; la clé est supprimée par « Afficher la liste de démarrage », #351-#352, #397), `onboarding_skipped_` (« 1 » par étape passée, #396), `onboarding_guided_initialized` (« 1 » une fois la règle D9 appliquée au profil, #396) — voir la section « Onboarding »… **et l'état de repli des catégories** (clés `reports-compare-expanded`, `reports-bva-expanded`, `reports-trends-expanded`, `budget-grid-expanded`) : persisté ici **par profil** plutôt qu'en `localStorage`, pour être détruit avec le profil (pas de résidu machine-global survivant à la suppression) — voir [ADR 0016](adr/0016-persistance-etat-ui-par-profil.md) | | `balance_categories` | Taxonomie des **classes d'actif** (Liquidités, Fonds/FNB, Actions, Crypto, Autres) — `kind ∈ {simple, priced}` (défaut suggéré pour les nouveaux comptes), `custom_label` pour le renommage bilingue-safe (v12). Les ex-types véhicules (TFSA/RRSP) ont migré vers `balance_accounts.vehicle_type` (Étape 1, v12/v13, [ADR 0014](adr/0014-balance-vehicule-attribut.md)) | | `balance_accounts` | Comptes de bilan (rattachés à une catégorie). `currency` hardcodée à `CAD` au MVP via CHECK. `archived_at` pour soft-delete. `vehicle_type` (enveloppe fiscale nullable, v12, [ADR 0014](adr/0014-balance-vehicule-attribut.md)). `kind ∈ {simple, detailed}` + `detailed_since` (pivot faisant autorité, v15, [ADR 0015](adr/0015-balance-detail-par-titre.md)) — porte désormais l'axe simple/détaillé (auparavant dérivé de `category.kind`). **Issue #179** : 4 comptes de départ seedés (`consolidated_schema.sql`) + proposés aux profils existants via `StarterAccountsModal` | | `balance_snapshots` | Snapshots datés (`snapshot_date` UNIQUE) — éditer = mettre à jour les lignes, pas dupliquer | @@ -306,9 +306,9 @@ L'étape `file-preview`, déclarée depuis l'origine dans `ImportWizardStep` san Deux relevés **inventés** (`exemple-desjardins.csv` : compte chèque Desjardins ; `exemple-tangerine.csv` : carte de crédit Tangerine ; 41 lignes chacun), avec les jetons `{{M1}}` / `{{M2}}` que la commande Rust `create_sample_import_folders` remplace par les deux mois complets précédant le clic (`MM/YYYY`). Les fichiers sont embarqués dans le binaire par `include_str!` : le dépôt est la seule source, il n'y a rien à copier au build. Le module est **séparé** de `csv/index.ts` à dessein — ce corpus est figé à quinze cas par `csvAutoDetect.test.ts` et six boucles y passent chaque fixture ; y ajouter les gabarits élargirait le contrat figé en silence. `src/__integration__/onboarding-samples.test.ts` lit les **mêmes** fichiers et fige ce que l'assistant en fera : chaque fichier reconnu par la signature de la banque qu'il imite, toutes les lignes lues, aucune ligne en erreur, totaux signés attendus, et la part catégorisée par les 180 mots-clés du seed — en laissant exprès des lignes à classer à la main (dont « GARDERIE LES PETITS PAS »), pour que la cinquième case de la liste de démarrage ait quelque chose à cocher (#354). -## Onboarding — états vides et liste de démarrage +## Onboarding — états vides et parcours de démarrage -Phase 1 de l'accueil des nouveaux profils (#351-#357 ; analyse d'origine dans `docs/analyse-onboarding-2026-09.md`). Aucune migration ni table : tout se lit dans les données existantes, et une seule préférence est écrite. +Phase 1 de l'accueil des nouveaux profils (#351-#357 ; analyse d'origine dans `docs/analyse-onboarding-2026-09.md`) : les états vides, la liste de démarrage et le dossier d'exemple. Phase 2 (#396-#401) : le parcours guidé, un bandeau en haut de chaque page et une carte d'étape sur la page de l'étape en cours (voir « Parcours guidé », plus bas). Aucune migration ni table : tout se lit dans les données existantes, et le parcours n'écrit que des préférences par profil. **Les quatre états vides** rendent le composant partagé `EmptyState` (`src/components/shared/` : icône, titre, description, action primaire en `` ou `