Onboarding phase 1 : suivis restants des revues #377-#383 (épingles, carte Transactions, messages d’Import, dérives de docs) #384

Open
opened 2026-10-04 12:52:55 +00:00 by maximus · 2 comments
Owner

Contexte

Constats non bloquants des sept /pr-review de l'onboarding phase 1 (PRs #377 à #383, mergées le 2026-10-04, 667e058). Ce corps est réécrit par /analyze le 2026-10-16, lu sur main 065f580. L'ancien corps et la liste de ce qui a changé sont archivés dans le commentaire 24043. Les items réglés depuis (#377, #378, le label de process, le flash d'Import, le câblage de Budget, le compte des hooks de l'arborescence, block.props.ref sous React 19) sont retirés.

Décisions (Max, 2026-10-16)

  • D1 — Carte « importez d'abord » de Transactions alignée sur Budget : showsEmptyState (src/hooks/useTransactions.ts:213) ne regarde plus que totalInDb === 0. totalInDb vaut null tant que le compte n'est pas chargé, donc rien ne s'affiche avant. Le test « keeps the regular layout while a page is loading, even at 0 » (useTransactions.test.ts:70) est réécrit pour la nouvelle règle.
  • D2 — Messages de create_sample_import_folders traduits par des codes : la commande Rust rend des codes stables au lieu de phrases anglaises, et le front les traduit. Un message inconnu reste affiché brut, comme aujourd'hui (t(state.error, { defaultValue: state.error }), ImportPage.tsx:109).

Travail à faire

1. Épingles (code correct, propriété non prouvée)

  • src-tauri/src/commands/fs_commands.rs, module de tests : cas « Exemple Tangerine existe → Exemple Desjardins non créé, rien n'est écrit ». Le test existant (refuses_when_desjardins_folder_exists_and_writes_nothing) ne couvre que le premier dossier de la boucle. Mutation : retirer la boucle de vérification préalable (for (folder_name, _) in &samples { if root.join(folder_name).exists() ... }) doit rougir ce nouveau test.
  • Même module : épingler « {{M1}} = mois le plus récent ». assert_dates_in accepte les deux mois sans les distinguer. Asserter qu'une ligne précise du gabarit (la première ligne de données de chaque fichier, ou toute ligne connue pour porter {{M1}}) porte 08/2026 pour today = 2026-09-25. Mutation : échanger m1_token et m2_token dans les deux .replace doit rougir. Côté vitest, onboarding-samples.test.ts (M1 = "08/2026", l. 53) : même épingle si le test lit une ligne précise ; sinon le noter dans la PR.
  • src/__integration__/onboarding-samples.test.ts:229 : corriger le commentaire « the seed is all priority 0 ». C'est faux : COSTCO et WALMART sont à 50, COUCHE-TARD ESSENCE à 10. Le commentaire doit dire pourquoi le tri du mock reste juste.
  • src/pages/TransactionsPage.render.test.tsx : un cas « profil sans transaction » (totalInDb: 0) qui asserte la carte transactions.empty.* (clé exacte à lire dans TransactionsPage.tsx, l. 119 et suivantes) et l'absence du tableau, sur le modèle de BudgetPage.render.test.tsx (« a profile without transactions »). Mutation : isEmptyProfile forcé à false doit rougir.

2. Transactions et Budget

  • D1 : showsEmptyState de Transactions = state.totalInDb === 0, signature réduite à Pick<TransactionsState, "totalInDb">. Réécrire le test de la ligne 70 : à 0 avec une page en chargement, l'état vide est affiché. Vérifier à la lecture qu'après un import, totalInDb est rechargé (canal d'événements de données, ADR 0022), sinon la carte resterait affichée. Si ce n'est pas le cas, le noter dans la PR comme limite, sans corriger.
  • useTransactions.ts:232 et useBudget.ts:431 : Promise.all couple l'échec de getTransactionCount() à celui des autres chargements, si bien qu'un compte en échec vide aussi les catégories et les sources. Passer à Promise.allSettled : chaque résultat réussi est dispatché, le premier échec part en SET_ERROR, et un compte en échec laisse totalInDb à null (mise en page normale, jamais la carte). Test du chargement si le harnais de hook le permet (src/test/hookHarness.ts), sinon une fonction pure extraite qui transforme les résultats en actions.

3. Import (#382)

  • D2 : create_sample_import_folders (fs_commands.rs, l. 240 et suivantes) rend des codes stables :
    • sample_folder_exists:<nom> pour « Folder already exists » ;
    • import_folder_missing pour « Folder does not exist » ;
    • invalid_date pour « Invalid date ».
      Les erreurs d'écriture (Cannot create folder, Cannot write) gardent leur texte : ce sont des erreurs du système, rares, utiles brutes dans le Journal. Côté front, createSampleFolders (useImportWizard.ts:443) traduit chaque code en clé import.empty.sampleErrors.* (FR et EN, nom du dossier interpolé) et garde le message brut pour tout autre texte. Le message brut part aussi en logWarn. Tests Rust des trois codes (adapter les err.contains(...) existants) et test du mapping côté front (fonction pure).
  • Bandeaux réussite et erreur : scanFolderInternal attrape son erreur et ne la relance pas, donc SET_SAMPLE_CREATED part même après un rescan en échec. Ne poser SET_SAMPLE_CREATED que si le rescan a réussi : scanFolderInternal rend un booléen, ou une valeur équivalente lisible par l'appelant. Test : rescan en échec → sampleCreated reste null et l'erreur est posée.
  • ImportEmptyState : hasFolder et folderName sont redondants (folderName !== null ⇔ hasFolder aux deux sites d'appel, ImportPage.tsx:77-78 et 153-155). Garder folderName: string | null seul et mettre à jour les deux appels et les tests de rendu existants.

4. Documentation

  • docs/architecture.md, section « Commandes Tauri » :
    • recompter depuis generate_handler! (src-tauri/src/lib.rs, 45 commandes au 2026-10-16) ;
    • documenter les cinq absentes (send_feedback, get_feedback_user_agent, ensure_backup_dir, get_file_size, file_exists) dans la section de leur module ;
    • remplacer le paragraphe « À venir Phase 5 » de fetch_price par sa description réelle (balance_commands.rs, fetch_price_in, refus LicenseRevoked, voir la section licence l. 464) ;
    • remettre les compteurs de section d'accord avec les listes.
  • docs/architecture.md : titre « Hooks (25+) » → compte réel (29 au 2026-10-16, fichiers .ts hors tests de src/hooks/). CLAUDE.md, arborescence : « 13 hooks custom » → même compte. Pour éviter un conflit avec #446 (compte des composants dans la même arborescence de CLAUDE.md), recompter au moment du maillon, pas recopier ces chiffres.
  • docs/guide-utilisateur.md:30 et la clé docs.* correspondante (FR et EN) : « le seed de mots-clés » → « les mots-clés fournis avec l'application » (EN : « the keywords that come with the app »).

Fichiers concernés

  • src-tauri/src/commands/fs_commands.rs : codes d'erreur, deux épingles
  • src/__integration__/onboarding-samples.test.ts
  • src/hooks/useTransactions.ts, src/hooks/useTransactions.test.ts, src/hooks/useBudget.ts, src/hooks/useBudget.test.ts
  • src/pages/TransactionsPage.render.test.tsx
  • src/hooks/useImportWizard.ts, src/hooks/useImportWizard.test.ts, src/pages/ImportPage.tsx, src/components/import/ImportEmptyState.tsx et ses tests de rendu
  • src/i18n/locales/fr.json, src/i18n/locales/en.json
  • docs/architecture.md, docs/guide-utilisateur.md, CLAUDE.md
  • CHANGELOG.md, CHANGELOG.fr.md

Surface de test

  • Existants : fs_commands.rs (5 tests du dossier d'exemple), onboarding-samples.test.ts, useTransactions.test.ts (showsEmptyState, l. 39-77), useBudget.test.ts (l. 371-401), TransactionsPage.render.test.tsx, BudgetPage.render.test.tsx, ImportPage.render.test.tsx, useImportWizard.test.ts.
  • À ajouter : listés à chaque tâche.
  • Test de régression : oui pour D1, D2 et les bandeaux (changements de comportement).

Critères d'acceptation

  • Les deux épingles Rust et l'épingle TransactionsPage rougissent sous leur mutation, citée dans la PR.
  • Sur un profil vide, la carte de Transactions s'affiche dès que le compte est chargé, sans attendre la première page ; test réécrit.
  • Un compte de transactions en échec n'empêche plus le chargement des catégories et des sources (Transactions) ni des comptes (Budget).
  • « Exemple … existe déjà », dossier manquant et date invalide s'affichent en français ou en anglais selon la langue ; un autre message reste brut.
  • Après un rescan en échec, seul le bandeau d'erreur est affiché.
  • ImportEmptyState n'a plus que folderName.
  • architecture.md : compteurs de commandes et de hooks justes, les cinq commandes documentées, fetch_price décrite au présent ; CLAUDE.md à jour ; guide sans « seed ».
  • CHANGELOG FR et EN : Modifié (carte Transactions), Corrigé (messages d'Import traduits, bandeaux).
  • npm test, cargo test et la CI verts.

Hors portée

  • Vérification visuelle du flash sur un profil vide : à faire dans l'app lancée, dans la liste manuelle de la prochaine release (docs/qa-onboarding.html).

Complexité

Medium : volume, une modification Rust bornée, aucune migration.


Plan d'exécution — milestone lot-v018 (planifié le 2026-10-16)

Les sections ci-dessous viennent de la séance /plan-run du 2026-10-16 (revue /review-spec Sécurité, Architecture, Technique comprise). En cas de conflit avec le corps au-dessus, elles priment.

Consignes communes

  • Préflight : #369, #419 et #421 sont fermées et le tag v0.17.2 existe (git ls-remote --tags origin v0.17.2). Sinon, arrêt sans rien écrire.
  • Les numéros de ligne du corps ont été lus sur main 065f580 ; #369, #419 et #421 les ont déplacés depuis. Repérer chaque site par son contenu (symbole, chaîne), jamais par son numéro.
  • Toute clé i18n ajoutée l'est en FR et en EN (garde de #453, en tête de pile).
  • Les vérifications manuelles (app lancée) vont dans le corps de la PR et le DAILY-REPORT, pas dans STATE.md : le report dans STATE.md se fait au /merge-stack.

Depends on

Note : dépendance d'ordre de la pile, pas de dépendance de code.

Décisions prises en planification

  • Corps réécrit par /analyze le 2026-10-16 (D1, D2 ci-dessus, décisions de Max). Ajoutée à la milestone par Max le même jour, juste avant #446 : les deux touchent docs/architecture.md et l'arborescence de CLAUDE.md. Chacune recompte sur le tip de son maillon.
  • La vérification visuelle du flash sur un profil vide va dans le corps de la PR et le DAILY-REPORT.

Spec source

spec-plan-lot-v018.md

## Contexte Constats non bloquants des sept `/pr-review` de l'onboarding phase 1 (PRs #377 à #383, mergées le 2026-10-04, `667e058`). Ce corps est réécrit par `/analyze` le 2026-10-16, lu sur `main` `065f580`. L'ancien corps et la liste de ce qui a changé sont archivés dans le commentaire 24043. Les items réglés depuis (#377, #378, le label de process, le flash d'Import, le câblage de Budget, le compte des hooks de l'arborescence, `block.props.ref` sous React 19) sont retirés. ## Décisions (Max, 2026-10-16) - **D1 — Carte « importez d'abord » de Transactions alignée sur Budget** : `showsEmptyState` (`src/hooks/useTransactions.ts:213`) ne regarde plus que `totalInDb === 0`. `totalInDb` vaut `null` tant que le compte n'est pas chargé, donc rien ne s'affiche avant. Le test « keeps the regular layout while a page is loading, even at 0 » (`useTransactions.test.ts:70`) est réécrit pour la nouvelle règle. - **D2 — Messages de `create_sample_import_folders` traduits par des codes** : la commande Rust rend des codes stables au lieu de phrases anglaises, et le front les traduit. Un message inconnu reste affiché brut, comme aujourd'hui (`t(state.error, { defaultValue: state.error })`, `ImportPage.tsx:109`). ## Travail à faire ### 1. Épingles (code correct, propriété non prouvée) - [ ] `src-tauri/src/commands/fs_commands.rs`, module de tests : cas « Exemple Tangerine existe → Exemple Desjardins non créé, rien n'est écrit ». Le test existant (`refuses_when_desjardins_folder_exists_and_writes_nothing`) ne couvre que le premier dossier de la boucle. Mutation : retirer la boucle de vérification préalable (`for (folder_name, _) in &samples { if root.join(folder_name).exists() ... }`) doit rougir ce nouveau test. - [ ] Même module : épingler « `{{M1}}` = mois le plus récent ». `assert_dates_in` accepte les deux mois sans les distinguer. Asserter qu'une ligne précise du gabarit (la première ligne de données de chaque fichier, ou toute ligne connue pour porter `{{M1}}`) porte `08/2026` pour `today = 2026-09-25`. Mutation : échanger `m1_token` et `m2_token` dans les deux `.replace` doit rougir. Côté vitest, `onboarding-samples.test.ts` (`M1 = "08/2026"`, l. 53) : même épingle si le test lit une ligne précise ; sinon le noter dans la PR. - [ ] `src/__integration__/onboarding-samples.test.ts:229` : corriger le commentaire « the seed is all priority 0 ». C'est faux : COSTCO et WALMART sont à 50, COUCHE-TARD ESSENCE à 10. Le commentaire doit dire pourquoi le tri du mock reste juste. - [ ] `src/pages/TransactionsPage.render.test.tsx` : un cas « profil sans transaction » (`totalInDb: 0`) qui asserte la carte `transactions.empty.*` (clé exacte à lire dans `TransactionsPage.tsx`, l. 119 et suivantes) et l'absence du tableau, sur le modèle de `BudgetPage.render.test.tsx` (« a profile without transactions »). Mutation : `isEmptyProfile` forcé à `false` doit rougir. ### 2. Transactions et Budget - [ ] **D1** : `showsEmptyState` de Transactions = `state.totalInDb === 0`, signature réduite à `Pick<TransactionsState, "totalInDb">`. Réécrire le test de la ligne 70 : à 0 avec une page en chargement, l'état vide est affiché. Vérifier à la lecture qu'après un import, `totalInDb` est rechargé (canal d'événements de données, ADR 0022), sinon la carte resterait affichée. Si ce n'est pas le cas, le noter dans la PR comme limite, sans corriger. - [ ] `useTransactions.ts:232` et `useBudget.ts:431` : `Promise.all` couple l'échec de `getTransactionCount()` à celui des autres chargements, si bien qu'un compte en échec vide aussi les catégories et les sources. Passer à `Promise.allSettled` : chaque résultat réussi est dispatché, le premier échec part en `SET_ERROR`, et un compte en échec laisse `totalInDb` à `null` (mise en page normale, jamais la carte). Test du chargement si le harnais de hook le permet (`src/test/hookHarness.ts`), sinon une fonction pure extraite qui transforme les résultats en actions. ### 3. Import (#382) - [ ] **D2** : `create_sample_import_folders` (`fs_commands.rs`, l. 240 et suivantes) rend des codes stables : - `sample_folder_exists:<nom>` pour « Folder already exists » ; - `import_folder_missing` pour « Folder does not exist » ; - `invalid_date` pour « Invalid date ». Les erreurs d'écriture (`Cannot create folder`, `Cannot write`) gardent leur texte : ce sont des erreurs du système, rares, utiles brutes dans le Journal. Côté front, `createSampleFolders` (`useImportWizard.ts:443`) traduit chaque code en clé `import.empty.sampleErrors.*` (FR et EN, nom du dossier interpolé) et garde le message brut pour tout autre texte. Le message brut part aussi en `logWarn`. Tests Rust des trois codes (adapter les `err.contains(...)` existants) et test du mapping côté front (fonction pure). - [ ] Bandeaux réussite et erreur : `scanFolderInternal` attrape son erreur et ne la relance pas, donc `SET_SAMPLE_CREATED` part même après un rescan en échec. Ne poser `SET_SAMPLE_CREATED` que si le rescan a réussi : `scanFolderInternal` rend un booléen, ou une valeur équivalente lisible par l'appelant. Test : rescan en échec → `sampleCreated` reste `null` et l'erreur est posée. - [ ] `ImportEmptyState` : `hasFolder` et `folderName` sont redondants (`folderName !== null` ⇔ `hasFolder` aux deux sites d'appel, `ImportPage.tsx:77-78` et `153-155`). Garder `folderName: string | null` seul et mettre à jour les deux appels et les tests de rendu existants. ### 4. Documentation - [ ] `docs/architecture.md`, section « Commandes Tauri » : - recompter depuis `generate_handler!` (`src-tauri/src/lib.rs`, 45 commandes au 2026-10-16) ; - documenter les cinq absentes (`send_feedback`, `get_feedback_user_agent`, `ensure_backup_dir`, `get_file_size`, `file_exists`) dans la section de leur module ; - remplacer le paragraphe « À venir Phase 5 » de `fetch_price` par sa description réelle (`balance_commands.rs`, `fetch_price_in`, refus `LicenseRevoked`, voir la section licence l. 464) ; - remettre les compteurs de section d'accord avec les listes. - [ ] `docs/architecture.md` : titre « Hooks (25+) » → compte réel (29 au 2026-10-16, fichiers `.ts` hors tests de `src/hooks/`). `CLAUDE.md`, arborescence : « 13 hooks custom » → même compte. Pour éviter un conflit avec #446 (compte des composants dans la même arborescence de `CLAUDE.md`), recompter au moment du maillon, pas recopier ces chiffres. - [ ] `docs/guide-utilisateur.md:30` et la clé `docs.*` correspondante (FR et EN) : « le seed de mots-clés » → « les mots-clés fournis avec l'application » (EN : « the keywords that come with the app »). ## Fichiers concernés - `src-tauri/src/commands/fs_commands.rs` : codes d'erreur, deux épingles - `src/__integration__/onboarding-samples.test.ts` - `src/hooks/useTransactions.ts`, `src/hooks/useTransactions.test.ts`, `src/hooks/useBudget.ts`, `src/hooks/useBudget.test.ts` - `src/pages/TransactionsPage.render.test.tsx` - `src/hooks/useImportWizard.ts`, `src/hooks/useImportWizard.test.ts`, `src/pages/ImportPage.tsx`, `src/components/import/ImportEmptyState.tsx` et ses tests de rendu - `src/i18n/locales/fr.json`, `src/i18n/locales/en.json` - `docs/architecture.md`, `docs/guide-utilisateur.md`, `CLAUDE.md` - `CHANGELOG.md`, `CHANGELOG.fr.md` ## Surface de test - Existants : `fs_commands.rs` (5 tests du dossier d'exemple), `onboarding-samples.test.ts`, `useTransactions.test.ts` (`showsEmptyState`, l. 39-77), `useBudget.test.ts` (l. 371-401), `TransactionsPage.render.test.tsx`, `BudgetPage.render.test.tsx`, `ImportPage.render.test.tsx`, `useImportWizard.test.ts`. - À ajouter : listés à chaque tâche. - Test de régression : oui pour D1, D2 et les bandeaux (changements de comportement). ## Critères d'acceptation - [ ] Les deux épingles Rust et l'épingle `TransactionsPage` rougissent sous leur mutation, citée dans la PR. - [ ] Sur un profil vide, la carte de Transactions s'affiche dès que le compte est chargé, sans attendre la première page ; test réécrit. - [ ] Un compte de transactions en échec n'empêche plus le chargement des catégories et des sources (Transactions) ni des comptes (Budget). - [ ] « Exemple … existe déjà », dossier manquant et date invalide s'affichent en français ou en anglais selon la langue ; un autre message reste brut. - [ ] Après un rescan en échec, seul le bandeau d'erreur est affiché. - [ ] `ImportEmptyState` n'a plus que `folderName`. - [ ] `architecture.md` : compteurs de commandes et de hooks justes, les cinq commandes documentées, `fetch_price` décrite au présent ; `CLAUDE.md` à jour ; guide sans « seed ». - [ ] CHANGELOG FR et EN : Modifié (carte Transactions), Corrigé (messages d'Import traduits, bandeaux). - [ ] `npm test`, `cargo test` et la CI verts. ## Hors portée - Vérification visuelle du flash sur un profil vide : à faire dans l'app lancée, dans la liste manuelle de la prochaine release (`docs/qa-onboarding.html`). ## Complexité Medium : volume, une modification Rust bornée, aucune migration. --- # Plan d'exécution — milestone lot-v018 (planifié le 2026-10-16) Les sections ci-dessous viennent de la séance `/plan-run` du 2026-10-16 (revue `/review-spec` Sécurité, Architecture, Technique comprise). **En cas de conflit avec le corps au-dessus, elles priment.** ## Consignes communes - Préflight : #369, #419 et #421 sont fermées et le tag `v0.17.2` existe (`git ls-remote --tags origin v0.17.2`). Sinon, arrêt sans rien écrire. - Les numéros de ligne du corps ont été lus sur `main` `065f580` ; #369, #419 et #421 les ont déplacés depuis. Repérer chaque site par son contenu (symbole, chaîne), jamais par son numéro. - Toute clé i18n ajoutée l'est en FR et en EN (garde de #453, en tête de pile). - Les vérifications manuelles (app lancée) vont dans le corps de la PR et le DAILY-REPORT, pas dans `STATE.md` : le report dans `STATE.md` se fait au `/merge-stack`. ## Depends on - #437 Note : dépendance d'ordre de la pile, pas de dépendance de code. ## Décisions prises en planification - Corps réécrit par `/analyze` le 2026-10-16 (D1, D2 ci-dessus, décisions de Max). Ajoutée à la milestone par Max le même jour, juste avant #446 : les deux touchent `docs/architecture.md` et l'arborescence de `CLAUDE.md`. Chacune recompte sur le tip de son maillon. - La vérification visuelle du flash sur un profil vide va dans le corps de la PR et le DAILY-REPORT. ## Spec source spec-plan-lot-v018.md
maximus added the
status:ready
type:feature
source:human
labels 2026-10-04 12:52:55 +00:00
Author
Owner

La pile du parcours guidé (#402 → #407, mergée le 2026-10-08, main ee17f31) règle trois items de cette liste, cochés dans le corps :

  • #377, hide() pendant un refresh() en vol : #396 (PR #402) fait primer une action locale sur le snapshot d'un chargement parti avant elle (hiddenSetAt dans le reducer de useOnboardingChecklist, ADR 0022 §4).
  • #378, état fait/verrouillé non annoncé : #397 (PR #403) ajoute un texte masqué visuellement par état (onboarding.state.*) dans OnboardingChecklist.
  • Process, status:approved posé par les workers : le skill autopilot laisse désormais status:review ; le run du 2026-10-08 a laissé ses six issues en status:review.

En partie seulement, donc non coché : #382. Le flash de la variante « sans dossier » est réglé par d024f5a (#398, PR #404) : la page attend la lecture du dossier d'import. Restent les bannières succès et erreur qui peuvent coexister si le rescan échoue après l'écriture, et le message de refus Rust affiché en anglais brut. Un micro-flash de la ligne « Aucun dossier configuré » d'ImportFolderConfig est noté comme limite connue dans la liste QA (guided-import-flash).

La pile du parcours guidé (#402 → #407, mergée le 2026-10-08, `main` `ee17f31`) règle trois items de cette liste, cochés dans le corps : - **#377, `hide()` pendant un `refresh()` en vol** : #396 (PR #402) fait primer une action locale sur le snapshot d'un chargement parti avant elle (`hiddenSetAt` dans le reducer de `useOnboardingChecklist`, ADR 0022 §4). - **#378, état fait/verrouillé non annoncé** : #397 (PR #403) ajoute un texte masqué visuellement par état (`onboarding.state.*`) dans `OnboardingChecklist`. - **Process, `status:approved` posé par les workers** : le skill `autopilot` laisse désormais `status:review` ; le run du 2026-10-08 a laissé ses six issues en `status:review`. En partie seulement, donc non coché : **#382**. Le flash de la variante « sans dossier » est réglé par `d024f5a` (#398, PR #404) : la page attend la lecture du dossier d'import. Restent les bannières succès et erreur qui peuvent coexister si le rescan échoue après l'écriture, et le message de refus Rust affiché en anglais brut. Un micro-flash de la ligne « Aucun dossier configuré » d'`ImportFolderConfig` est noté comme limite connue dans la liste QA (`guided-import-flash`).
Author
Owner

Archive avant réécriture par /analyze (2026-10-16, lu sur main 065f580). Corps rédigé le 2026-10-04, jamais relu contre le code depuis. Entre-temps, les piles du parcours guidé (#396-#401), de la fiabilité des tests (#408, #409, #389, #395) et des retours de la v0.17.1 (#422-#432) ont touché Import, Transactions, Budget et docs/architecture.md.

Ce qui a changé :

  • Flash de la variante « sans dossier » d’Import : réglé par d024f5a (#398), déjà noté dans le commentaire 20845.
  • Câblage isEmptyProfile des pages : Budget est maintenant couvert (BudgetPage.render.test.tsx, « a profile without transactions »). Transactions ne l’est pas : TransactionsPage.render.test.tsx ne rend jamais totalInDb: 0.
  • Commentaire « priority 0 » : passé de la ligne 239 à la ligne 229 de src/__integration__/onboarding-samples.test.ts.
  • Commandes Tauri : docs/architecture.md dit maintenant « (39) » ; generate_handler! en enregistre 45. Cinq ne sont jamais nommées (send_feedback, get_feedback_user_agent, ensure_backup_dir, get_file_size, file_exists). compute_account_return est documentée, mais fetch_price est encore décrite « à venir Phase 5 » alors qu’elle est enregistrée.
  • Hooks : l’arborescence de architecture.md dit 29, juste (29 fichiers hors tests). Restent le titre « Hooks (25+) » et CLAUDE.md (« 13 hooks custom »).
  • block.props.ref : le projet est sur React ^19.1.0, donc le test est valide ; plus rien à faire tant que React reste en 19.
  • Inchangés : les deux épingles Rust de #380, Promise.all (useTransactions.ts:232, useBudget.ts:431), le garde !isLoading de showsEmptyState (useTransactions.ts:213), les bandeaux réussite et erreur qui coexistent (scanFolderInternal attrape son erreur et ne la relance pas, SET_SAMPLE_CREATED part quand même), le message Rust brut, la redondance hasFolder/folderName, le jargon du guide (l. 30).
Corps du 2026-10-04 (avec les coches du 2026-10-09)

Constats non bloquants des sept /pr-review indépendantes de la vague planned-2026-10-03-onboarding-phase1 (PRs #377 → #383, mergées ff sur main à 667e058 le 2026-10-04). Les trois correctifs déjà appliqués en tête de pile (statut BMO sans provenance interne, garde budgetReady sur la liste compacte, test formatLocalDate épinglé hors UTC) n'y figurent pas.

Tests à épingler (code correct, propriété non prouvée)

  • #380 fs_commands.rs : ajouter le cas discriminant « Exemple Tangerine existe → Exemple Desjardins non créé » (retirer la boucle d'existence laisse les 5 tests verts aujourd'hui)
  • #380 : épingler « {{M1}} = mois le plus récent » (l'inversion des jetons laisse Rust 5/5 et vitest 9/9 verts)
  • #380 onboarding-samples.test.ts:239 : le commentaire « the seed is all priority 0 » est faux (COSTCO/WALMART = 50, COUCHE-TARD ESSENCE = 10) ; le tri du mock est juste
  • #379 : le câblage des pages (isEmptyProfile ?) n'est couvert par aucun test (convention du dépôt sans renderer) — à documenter ou couvrir si un renderer arrive

UX / robustesse

  • #377 useOnboardingChecklist.ts:92-113 : un hide() pendant un refresh() en vol peut être annulé par le snapshot hidden de ce chargement (sans effet tant que le dashboard ne rafraîchit qu'au montage)
  • #378 OnboardingChecklist : l'état fait/verrouillé n'est pas annoncé aux lecteurs d'écran (icône aria-hidden, line-through muet)
  • #379 useTransactions.ts:171-180, useBudget.ts:435-441 : Promise.all couple l'échec de getTransactionCount() à celui des catégories/sources ; allSettled garderait l'ancien comportement
  • #379 : le garde !isLoading sur Transactions allonge le flash au lieu de l'éviter (mise en page régulière jusqu'à la fin de la première page sur un profil vide) ; incohérent avec Budget
  • #382 : flash de la variante « sans dossier » au premier rendu d'Import avant le chargement de la préférence (drapeau loaded) ; bannières succès et erreur peuvent coexister si le rescan échoue après l'écriture ; message de refus Rust affiché en anglais brut
  • #382 : hasFolder / folderName redondants dans ImportEmptyState

Documentation

  • #383 docs/architecture.md : « Commandes Tauri (37) » = somme des sections, mais generate_handler! en enregistre 43 ; 7 commandes jamais listées (send_feedback, get_feedback_user_agent, ensure_backup_dir, get_file_size, file_exists, compute_account_return, fetch_price) — dérive préexistante
  • #383 : hooks/ # 29 vs « Hooks (25+) » ; #381 : « le seed de mots-clés » est du jargon dans le guide (chapitre 1)
  • #381 : le test DocsSubsections lit block.props.ref, valide seulement sous React 19

Process

  • Skills autopilot / sprint : les workers posent status:approved après leur auto-revue, avant toute revue indépendante — laisser status:review, réserver approved au relecteur (mémoire feedback_autopilot_self_review_label)
Archive avant réécriture par `/analyze` (2026-10-16, lu sur `main` `065f580`). Corps rédigé le 2026-10-04, jamais relu contre le code depuis. Entre-temps, les piles du parcours guidé (#396-#401), de la fiabilité des tests (#408, #409, #389, #395) et des retours de la v0.17.1 (#422-#432) ont touché Import, Transactions, Budget et `docs/architecture.md`. Ce qui a changé : - **Flash de la variante « sans dossier » d’Import** : réglé par `d024f5a` (#398), déjà noté dans le commentaire 20845. - **Câblage `isEmptyProfile` des pages** : Budget est maintenant couvert (`BudgetPage.render.test.tsx`, « a profile without transactions »). Transactions ne l’est pas : `TransactionsPage.render.test.tsx` ne rend jamais `totalInDb: 0`. - **Commentaire « priority 0 »** : passé de la ligne 239 à la ligne 229 de `src/__integration__/onboarding-samples.test.ts`. - **Commandes Tauri** : `docs/architecture.md` dit maintenant « (39) » ; `generate_handler!` en enregistre 45. Cinq ne sont jamais nommées (`send_feedback`, `get_feedback_user_agent`, `ensure_backup_dir`, `get_file_size`, `file_exists`). `compute_account_return` est documentée, mais `fetch_price` est encore décrite « à venir Phase 5 » alors qu’elle est enregistrée. - **Hooks** : l’arborescence de `architecture.md` dit 29, juste (29 fichiers hors tests). Restent le titre « Hooks (25+) » et `CLAUDE.md` (« 13 hooks custom »). - **`block.props.ref`** : le projet est sur React `^19.1.0`, donc le test est valide ; plus rien à faire tant que React reste en 19. - **Inchangés** : les deux épingles Rust de #380, `Promise.all` (`useTransactions.ts:232`, `useBudget.ts:431`), le garde `!isLoading` de `showsEmptyState` (`useTransactions.ts:213`), les bandeaux réussite et erreur qui coexistent (`scanFolderInternal` attrape son erreur et ne la relance pas, `SET_SAMPLE_CREATED` part quand même), le message Rust brut, la redondance `hasFolder`/`folderName`, le jargon du guide (l. 30). <details><summary>Corps du 2026-10-04 (avec les coches du 2026-10-09)</summary> Constats **non bloquants** des sept `/pr-review` indépendantes de la vague `planned-2026-10-03-onboarding-phase1` (PRs #377 → #383, mergées ff sur `main` à `667e058` le 2026-10-04). Les trois correctifs déjà appliqués en tête de pile (statut BMO sans provenance interne, garde `budgetReady` sur la liste compacte, test `formatLocalDate` épinglé hors UTC) n'y figurent pas. ## Tests à épingler (code correct, propriété non prouvée) - [ ] #380 `fs_commands.rs` : ajouter le cas discriminant « Exemple Tangerine existe → Exemple Desjardins non créé » (retirer la boucle d'existence laisse les 5 tests verts aujourd'hui) - [ ] #380 : épingler « `{{M1}}` = mois le plus récent » (l'inversion des jetons laisse Rust 5/5 et vitest 9/9 verts) - [ ] #380 `onboarding-samples.test.ts:239` : le commentaire « the seed is all priority 0 » est faux (COSTCO/WALMART = 50, COUCHE-TARD ESSENCE = 10) ; le tri du mock est juste - [ ] #379 : le câblage des pages (`isEmptyProfile ?`) n'est couvert par aucun test (convention du dépôt sans renderer) — à documenter ou couvrir si un renderer arrive ## UX / robustesse - [x] #377 `useOnboardingChecklist.ts:92-113` : un `hide()` pendant un `refresh()` en vol peut être annulé par le snapshot `hidden` de ce chargement (sans effet tant que le dashboard ne rafraîchit qu'au montage) - [x] #378 `OnboardingChecklist` : l'état fait/verrouillé n'est pas annoncé aux lecteurs d'écran (icône `aria-hidden`, `line-through` muet) - [ ] #379 `useTransactions.ts:171-180`, `useBudget.ts:435-441` : `Promise.all` couple l'échec de `getTransactionCount()` à celui des catégories/sources ; `allSettled` garderait l'ancien comportement - [ ] #379 : le garde `!isLoading` sur Transactions allonge le flash au lieu de l'éviter (mise en page régulière jusqu'à la fin de la première page sur un profil vide) ; incohérent avec Budget - [ ] #382 : flash de la variante « sans dossier » au premier rendu d'Import avant le chargement de la préférence (drapeau `loaded`) ; bannières succès et erreur peuvent coexister si le rescan échoue après l'écriture ; message de refus Rust affiché en anglais brut - [ ] #382 : `hasFolder` / `folderName` redondants dans `ImportEmptyState` ## Documentation - [ ] #383 `docs/architecture.md` : « Commandes Tauri (37) » = somme des sections, mais `generate_handler!` en enregistre 43 ; 7 commandes jamais listées (`send_feedback`, `get_feedback_user_agent`, `ensure_backup_dir`, `get_file_size`, `file_exists`, `compute_account_return`, `fetch_price`) — dérive préexistante - [ ] #383 : `hooks/ # 29` vs « Hooks (25+) » ; #381 : « le seed de mots-clés » est du jargon dans le guide (chapitre 1) - [ ] #381 : le test `DocsSubsections` lit `block.props.ref`, valide seulement sous React 19 ## Process - [x] Skills `autopilot` / `sprint` : les workers posent `status:approved` après leur auto-revue, avant toute revue indépendante — laisser `status:review`, réserver `approved` au relecteur (mémoire `feedback_autopilot_self_review_label`) </details>
maximus changed title from Onboarding phase 1 : suivis non bloquants des revues #377-#383 to Onboarding phase 1 : suivis restants des revues #377-#383 (épingles, carte Transactions, messages d’Import, dérives de docs) 2026-10-17 00:09:46 +00:00
maximus added this to the planned-2026-10-16-lot-v018 milestone 2026-10-17 00:14:26 +00:00
maximus added
status:in-progress
and removed
status:ready
labels 2026-10-19 00:08:25 +00:00
maximus added
status:review
and removed
status:in-progress
labels 2026-10-19 00:45:34 +00:00
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#384
No description provided.