Budget : sous-catégories en fin de groupe au dépli, et sous-totaux en bas rattachés aux mauvaises lignes (buildBudgetYearRows, reorderRows) #424
Labels
No labels
autopilot:pending-human
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-clarification
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/Simpl-Resultat#424
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
La grille Budget émet ses lignes par niveaux : une sous-catégorie dépliée s'affiche en fin de groupe au lieu de sous son parent. Avec les sous-totaux en bas,
reorderRowsrattache des lignes au mauvais sous-total, dans la grille comme dans les rapports Budget vs réel et Comparables. Cette issue émet la grille en profondeur et corrigereorderRows. Signalé par Max en testant la v0.17.1 (#422).Contexte
buildBudgetYearRows(src/hooks/useBudget.ts:106-383) émet chaque groupe de premier niveau par niveaux : son tri final (:360-380) range toutes les lignes de profondeur 1 avant toutes celles de profondeur 2, puis par nom ; avant lui, le tri alphabétique deallChildRows(:335-340) défait déjà l'ordre[sous-total, ...enfants]que rendbuildLevel2Group(:235). Les feuilles de profondeur 2 sortent donc après toutes les lignes de profondeur 1 du groupe, et celles de plusieurs parents intermédiaires se mêlent.Ordre rendu par la vraie fonction sur la taxonomie d'un profil neuf (
consolidated_schema.sql, 150 catégories), section Revenus tout dépliée, sous-totaux en haut :La taxonomie standard a des parents intermédiaires dans chaque groupe ; l'ancienne (profil par défaut) en a un, Dépenses récurrentes → Assurances → Assurance-auto, -habitation, -vie (migration v7).
Sous-totaux en bas.
reorderRows(src/utils/reorderRows.ts) range dans le bloc du sous-total courant toute ligne qui le suit, y compris une feuille de même profondeur. Sur l'ordre actuel, Emploi et Gouvernemental paraissent vides et « Revenus de placement » ferme un bloc de dix feuilles. Et même sur l'ordre en profondeur visé, une feuille qui suit un sous-groupe frère tombe dans son bloc (vérifié par sonde : « Retrait cash » au-dessus du sous-total « Impôts & taxes » ; même cas pour « Transferts internes » après « Remboursement de dette »). Le même utilitaire sertBudgetVsActualTableetComparePeriodTable, qui mêlent déjà feuilles et sous-groupes.Origine. Le tri date de l'ajout du 3ᵉ niveau (
a04813c, 2026-02-25). #289 l'a épinglé comme invariant :src/hooks/useBudget.test.ts:65-89affirme l'ordre défectueux (« Hydro after Rent »). Le repli ne dépend pas de l'ordre (marche des ancêtres,src/utils/collapsibleRows.ts). Le rapport Budget vs réel construit déjà l'arbre en profondeur (src/services/budgetService.ts:374-467) ; il n'est pas réutilisable tel quel (asynchrone, et il écarte les lignes à zéro que la grille doit montrer).Travail à faire
buildBudgetYearRowsémet en profondeur, par blocs :[sous-total, …ses enfants](ce que rend déjàbuildLevel2Group) ;localeComparedu nom de la feuille ou du sous-total, feuilles et sous-groupes mêlés (commebudgetService.ts:435), puis concaténés ;[parent, …]ou feuille seule) sont triés par type (TYPE_ORDER), puissort_order, puis nom, et concaténés. Plus aucun comparateur ne s'applique à des lignes à l'intérieur d'un groupe : le tri par profondeur disparaît.reorderRows: dansreorderGroup, une ligne dont la profondeur est inférieure ou égale àparentDepthet qui n'est pas un parent de ce niveau ferme le bloc en cours (le parent courant est vidé avec ses enfants) avant d'être émise. Corrige du même coup le mode « sous-totaux en bas » de Budget vs réel et Comparables.useBudget.ts:87-105), le commentaire decollapsibleRows.tsqui décrit la grille comme « level-ordered », et celui decollapsibleRows.test.ts(« the order the budget grid produces ») ; le casbfsTreereste, comme preuve que le repli ne dépend pas de l'ordre.BudgetTable.render.test.tsxetbudgetOnboardingTarget.test.tsne changent pas : leurs lignes sont construites à la main, à deux niveaux.Fichiers concernés
src/hooks/useBudget.ts,src/hooks/useBudget.test.tssrc/utils/reorderRows.ts,src/utils/reorderRows.test.ts(nouveau)src/utils/collapsibleRows.ts,src/utils/collapsibleRows.test.ts(commentaires)CHANGELOG.md,CHANGELOG.fr.mdDepends on
Aucune.
Tests
useBudget.test.ts:65-89) par l'invariant en profondeur : chaque ligne suit son parent, et toutes les lignes entre un parent et la fin de son sous-arbre sont ses descendantes.reorderRows.test.ts: sous-totaux en bas, une feuille qui suit un sous-groupe frère reste hors de son bloc, chaque sous-total suit ses propres feuilles, à deux et trois niveaux ; sous-totaux en haut : liste inchangée.useBudget.test.ts:101-108).reorderRows, rougissent chacune au moins un test.Critères d'acceptation
npm run buildetnpm testverts.Review caveats
reorderRowsplaçait encore une feuille qui suit un sous-groupe frère dans son bloc ; la correction est dans cette issue.getBudgetVsActualDatan'est pas retenu.Décisions prises en planification
reorderRowscorrigé ici, ce qui répare aussi les rapports (constat de revue, Max, 2026-10-12).Conventions
src/i18n/locales/fr.json,en.json) ; les textes de ce corps s'écrivent mot pour mot (FR validé par Max le 2026-10-12, EN rédigé sur le même contenu).StepCardText.labels(src/utils/onboardingPath.ts), traduit parStepCard; jamais recopié dans la phrase. Guillemets « » en FR et “ ” en EN autour de chaque libellé de contrôle interpolé ;{{filter, lowercase}}sans guillemets.## [Unreleased]dansCHANGELOG.mdetCHANGELOG.fr.md.renderToStaticMarkup(pas de jsdom) et le fauxtpartagé livré par #389.useImportWizard.ts:423-425: le Journal part avec un rapport de feedback).npm run build(il vérifie aussi les types des fichiers de test) etnpm testverts.docs/guide-utilisateur.md) : repérer une ligne par son texte cité, pas par son numéro.CHANGELOG
Fixed / Corrigé : FR « Budget : une sous-catégorie dépliée s'affiche sous sa catégorie parente, et non plus en fin de groupe. Avec les sous-totaux en bas, chaque sous-total suit ses propres lignes, dans la grille Budget comme dans les rapports Budget vs réel et Comparables. » EN "Budget: an expanded subcategory now shows under its parent category instead of at the end of the group. With subtotals at the bottom, each subtotal follows its own rows, in the Budget grid as in the Budget vs Actual and Compare reports."
Spec source
spec-plan-retours-onboarding-v0171.md(local, ignoré par git) ; décisions dansspec-decisions-retours-onboarding-v0171.md.Planification du 2026-10-12 (
/plan-run, jalonplanned-2026-10-12-retours-onboarding-v0171) : le corps est réécrit pour être autosuffisant (décisions de Max, constats de/review-specintégrés). Corps précédent ci-dessous.Corps précédent (titre : Budget : au dépli, les sous-catégories d'un parent intermédiaire s'affichent en fin de groupe (ordre par niveaux de buildBudgetYearRows))
Contexte
Signalé par Max en testant la v0.17.1 (#422, point 5) : « pour le budget, lorsqu'on déplie, les catégories ne sont pas sous le parent mais plutôt à la fin de la section ». Analysé le 2026-10-12 sur
mainà1954502; reproduit en appelant la vraie fonction sur la taxonomie d'un profil neuf.Cause.
buildBudgetYearRows(src/hooks/useBudget.ts:106-383) émet chaque groupe de premier niveau par niveaux (largeur d'abord). Son tri final (:360-380) range, dans un même groupe, toutes les lignes de profondeur 1 avant toutes celles de profondeur 2, puis par nom. Avant lui, le tri alphabétique deallChildRows(:335-340) défait déjà l'ordre[sous-total, ...enfants]que rendbuildLevel2Group(:235). Deux effets :Ordre rendu sur la taxonomie d'un profil neuf (
consolidated_schema.sql, 150 catégories), section Revenus tout dépliée, sous-totaux en haut (défaut) :Revenus est le seul groupe de sa section : déplier Emploi y affiche Paie régulière, Primes & bonus et Travail autonome tout en bas de la section, après Autres revenus. C'est le constat de Max. La taxonomie standard a des parents intermédiaires dans chaque groupe ; l'ancienne taxonomie (profil par défaut) en a un, Dépenses récurrentes → Assurances → Assurance-auto, -habitation, -vie (migration v7,
src-tauri/src/lib.rs).Sous-totaux en bas.
reorderRows(src/utils/reorderRows.ts) suppose un ordre en profondeur (un parent suivi de son sous-arbre). Sur l'ordre par niveaux, il rattache les lignes au mauvais sous-total. Même section :Origine. Le tri date de l'ajout du 3ᵉ niveau (
a04813c, 2026-02-25). #289 (repli multi-niveaux) l'a épinglé comme invariant :src/hooks/useBudget.test.ts:65-89affirme l'ordre défectueux (« Hydro after Rent »), et le commentaire deuseBudget.ts:91-100interdit de passer en profondeur sans revoirBudgetTable. Or le repli ne dépend pas de l'ordre (marche des ancêtres,src/utils/collapsibleRows.ts) : rien ne justifie plus l'ordre par niveaux.Modèle. Le rapport Budget vs réel construit déjà l'arbre en profondeur :
buildSubGrouprécursif, enfants par ordre alphabétique, « (direct) » en tête, puis un tri par type seul qui garde l'ordre de l'arbre (src/services/budgetService.ts:374-467).Travail à faire
buildBudgetYearRows: chaque parent suivi de son sous-arbre. Les groupes de premier niveau gardent leur ordre (type, puissort_order, puis nom). Les frères suivent la règle debudgetService.ts: « (direct) » en tête, puis par nom, feuilles et sous-groupes mêlés. C'est un changement visible à la profondeur 1, où la grille met aujourd'hui les parents avant les feuilles : il aligne la grille sur le rapport Budget vs réel.useBudget.ts:87-105, et celui decollapsibleRows.tsqui décrit la grille comme « level-ordered ».useBudget.test.ts:65-89) par l'invariant en profondeur, et recaler les ordres attendus qui en dépendent (useBudget.test.ts:101-108).budgetOnboardingTarget(première feuille visible, carte Budget du parcours) et ses tests restent justes.CHANGELOG.mdetCHANGELOG.fr.md.Fichiers concernés
src/hooks/useBudget.ts: tri deallChildRowset tri final, commentaire d'invariant.src/hooks/useBudget.test.ts: tests d'ordre.src/utils/collapsibleRows.ts: commentaire seulement.src/utils/collapsibleRows.test.ts: le casbfsTree(:56-124) reste une preuve valable que le repli ne dépend pas de l'ordre ; seul son commentaire « the order the budget grid produces » devient faux.src/components/budget/BudgetTable.render.test.tsx: fixture « in the orderbuildBudgetYearRowsemits them » (:68), à recaler si besoin.CHANGELOG.md,CHANGELOG.fr.md.Surface de test
src/hooks/useBudget.test.ts,src/utils/collapsibleRows.test.ts,src/components/budget/BudgetTable.render.test.tsx,src/components/budget/budgetOnboardingTarget.test.ts.reorderRows(…, false)sur la sortie du builder : chaque sous-total intermédiaire suit ses propres feuilles.Critères d'acceptation
npm testetnpm run buildverts.Complexité estimée
Simple à moyenne : une fonction pure et ses tests, avec un modèle existant dans
budgetService.ts.Questions ouvertes
Aucune. Indépendante des autres issues issues de #422 ; livrable seule, en correctif.
Budget : au dépli, les sous-catégories d'un parent intermédiaire s'affichent en fin de groupe (ordre par niveaux de buildBudgetYearRows)to Budget : sous-catégories en fin de groupe au dépli, et sous-totaux en bas rattachés aux mauvaises lignes (buildBudgetYearRows, reorderRows)