feat(rapports) : repli/depliage a chaque niveau de la hierarchie (socle + 3 rapports) #292
No reviewers
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#292
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-288-collapse-socle"
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?
Resolves #288
Generated autonomously by /autopilot run of 2026-07-15
Summary
localStoragetouser_preferences(per-profile, destroyed with the profile — privacy-first); the hook gainsstorageKey: null+options.defaultExpanded+ async hydration, and a pure testedisCollapsedForpolarity helper.isTopParent->isParent) so intermediate parents get a truthful chevron +aria-expanded;aria-leveladded on parent rows; deadCategoryTable.tsxremoved. Collapse stays purely visual (subtotals/results from raw rows). 823 vitest green, build + cargo clean.Revue /pr-review — APPROVE
Verdict : APPROVE (4 suggestions non bloquantes)
La generalisation du repli a chaque niveau est correcte et remarquablement testee. Le coeur du changement — passer d'une detection par adjacence (dependante de l'ordre DFS) a une remontee d'ancetres
hiddenByAncestorindependante de l'ordre — est le vrai fix du cas grille budget (emise en ordre BFS). Verifie en profondeur :p:<id>+ feuille « (direct) » :reportService.ts:642-645parente la feuille directe surcat.idavecis_parent:false. Elle partage donc la clep:<catId>du sous-total, mais seul le sous-total (isParent) est indexe dans la mapparents; la feuille porte la cle du parent viaparentKeyOfet se cache/revele avec lui. Exactement le modele des tests.sumLeaves(section.rows),computeResults(data)), jamais surgroups.visible(). Aucune atteinte a l'exactitude financiere. Les tests l'ancrent (« collapse is purely visual »).switchProfiledispatchINCREMENT_REFRESH→App.tsx:108<BrowserRouter key={refreshKey}>remonte tout le sous-arbre → l'effet d'hydratation rejouegetPreferencesur la DB du nouveau profil. Aucune fuite d'etat entre profils, ecritures toujours sur le profil actif. La promesse « detruit avec le profil » tient.reports-{compare,bva,trends}-expandedbien namespacees — aucune collision avec les clesuser_preferencesexistantes.CategoryTable.tsx: reellement mort, aucun import ailleurs.MAX_TREE_DEPTH, ancetre absent → visible (feuille orpheline preservee), polariteisCollapsedFordans les deux sens — tous couverts. Le test « BFS masque a l'identique de DFS » est le regression test du bug corrige.setPreferenceen SQL parametre ($1/$2) ; pas de secret, pas de nouvelle migration.Suggestions (non bloquantes)
Course d'hydratation (
useCollapsibleGroups.ts) — si l'utilisateur toggle un groupe dans la fenetre (~ms) entre le mount et la resolution degetPreference, le.thend'hydratation ecrase son toggle (setFlipped(parseStoredExpanded(raw))). Fenetre minuscule et auto-corrigee au clic suivant, mais un garde « l'utilisateur a deja interagi » (ou n'hydrater que siflippedest encore intact) fermerait le trou proprement.Generalite speculative (YAGNI) —
defaultExpanded: trueetstorageKey: nullsont ajoutes + testes, mais aucun consommateur en production dans cette PR : les 3 tables passent le defaut (defaultExpanded: false) et une vraie cle. Infrastructure construite « pour les arbres de categories » qui n'existent pas encore. Non nuisible, mais a defaut d'un consommateur, elle pourrait attendre.Scope creep — les modifs de
.claude/skills/release/SKILL.md(etapes pre-vol/post-CI, « confirmer avec Max avant de tagger ») sont sans lien avec #288 ; elles proviennent d'une autre session (release v0.13.0). Idealement un commit/PR separe.aria-levelinerte (a11y mineur) — sur un<tr>d'une<table>ordinaire, sansrole="treegrid"/row/treeitem,aria-levelest ignore par les lecteurs d'ecran, et seuls les parents le portent.aria-expandedsur le bouton, lui, est effectif — les chevrons sont bien annonces, donc l'essentiel de l'a11y est la.Aucun blocage : correction correcte, purement visuelle sur les chiffres, tests solides (incl. regression BFS/DFS). Bon a merger.
Mergé en fast-forward dans
main(pile #292→#295), commit48adb3d. Forgejo ne détecte pas le merge local → fermeture manuelle. L'issue liée s'est auto-fermée viaResolves #N.Pull request closed