Import: parent folder, one subfolder per account, signs at the preview, quoted controls (#422) #439
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#439
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-422-import-per-account"
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?
Generated autonomously by /autopilot run of 2026-10-13 (milestone
planned-2026-10-12-retours-onboarding-v0171, link 2 of 8). Stacked on #438 (issue-424-budget-row-order).What
ImportFolderStructurecomponent, a nested<ul>(parent folder > two account folders > two CSV files under the first), lucideFolder/FileTexticons witharia-hidden, and the note that files at the root of the parent folder are ignored. Rendered above the bank CSV guide link.onboarding.card.import.noFolder,noSources,sourceListrewritten with the issue's texts (FR + EN, word for word).onboarding.card.import.filePreviewsays an expense must count among the outflows, as a negative amount, and names "Inverser les signes" before "Vérifier les doublons".WIZARD_ROWSrows now carry alabelsrecord; thefile-previewrow has{ button: "import.wizard.checkDuplicates", flip: "import.preview.flipSigns" }, andimportCardModelpasses the whole record.duplicateCheck,confirmandsourceConfig(see decisions).import.help.tips[0]rewritten, new tip at index 3 on the signs),import.empty.noSources.description,docs.import.steps[1],[5],[6]and the matching lines ofdocs/guide-utilisateur.md. The "Formats reconnus par banque" bullet is unchanged, as the issue says.No migration, no Rust, no network call, no Journal line.
Files
src/components/import/ImportFolderStructure.tsx(new),ImportFolderStructure.test.tsx(new)src/components/import/ImportEmptyState.tsx,ImportEmptyState.test.tsxsrc/utils/onboardingPath.ts,onboardingPath.test.ts,onboardingPath.locales.test.ts(new)src/pages/ImportPage.render.test.tsxsrc/i18n/locales/fr.json,en.jsondocs/guide-utilisateur.md,docs/qa-onboarding.html(new sectionretours-v0171, 4 cases),docs/architecture.mdCHANGELOG.md,CHANGELOG.fr.md(Changed / Modifié)Decisions
sourceConfiggets quotation marks around{{button}}too (only change to that sentence): the criterion covers every Import card sentence that names a control; #426 rewrites that sentence later.onboardingPath.locales.test.ts, not in the plan's file list: the shared faketnever reads the locale files, so the quoting criterion had no test. It requires each{{x}}ofonboarding.card.import.*to sit between « » / “ ”, and the preview sentence to carrybuttonandflip.guided-import-foldernow says "la carte d'un compte".Acceptance criteria
ImportEmptyState.test.tsx, both variants;ImportPage.render.test.tsx, both page states).grep -n -P 'sous-dossier par banque|banque/source|sub-?folder per bank(?! account)|bank/source' src/i18n/locales/*.json docs/guide-utilisateur.mdreturns nothing (rc=1).onboardingPath.locales.test.ts, 9 interpolations per language).npm run buildandnpm testgreen: 122 files, 2085 tests.Proofs (mutations, one at a time, restored from the index)
flipremoved from thefile-previewrowonboardingPath.test.ts(7.),ImportPage.render.test.tsx(file-preview)importCardModelpasses only{ button }<ImportFolderStructure />removed#422cases ofImportEmptyState.test.tsx, page render tests<ul>(div)ImportFolderStructure.test.tsxnesting testaria-hiddendropped on the file iconsaria-hidden="true"by default (checked by rendering<FileText/>alone); the explicit attribute staysrootNotenot renderedfilePreview:{{flip}}unquotedonboardingPath.locales.test.ts(fr)noSources:{{folder}}unquotedonboardingPath.locales.test.ts(en)filePreviewwithout the flipFor the reviewer
EmptyState's children container (text-left max-w-xl), above the guide link; worth a look in both themes (bg-[var(--muted)]).noSourcesquotes the folder name too (it is a value, not a label), as the issue's text does.🤖 Generated with Claude Code
Self-review (autopilot worker, not independent) — verdict: APPROVE
Generated autonomously by /autopilot run of 2026-10-13. Diff read against
issue-424-budget-row-order(15 files, all expected by the plan, plus one new locale test).Acceptance criteria
detailsfragment, pinned byImportEmptyState.test.tsx(both variants, box above the guide link) andImportPage.render.test.tsx(no folder, folder without sources). OK.grep -Pof the issue returns nothing. A wider scan of "par banque / per bank / votre banque" only finds texts that are right (formats per bank, CSV export guide, EN "per bank account"). OK.labels = { button: checkDuplicates, flip: flipSigns }, both quoted in FR and EN. OK.onboardingPath.locales.test.ts. OK.Regressions:
WIZARD_ROWSchanged shape (singlebutton→labelsrecord); the only reader isimportCardModel, and the other three rows keep exactly{ button }(test 7 and its "...but only at rest" sibling unchanged and green).i18n: every visible text goes through
t, including the sample file names (FRreleve-…, ENstatement-…). No hard-coded UI string.Security / privacy: static texts only; no Journal line, no path, no network, no migration, no Rust. The sample file names are fictitious.
Docs: guide lines found by their text (steps 2, 6, 7),
docs.import.steps[1],[5],[6]in sync with it; architecture.md count and empty-state row; QA list has 4 new cases; CHANGELOG under Changed / Modifié in both files.Known limit: mutation M6 (dropping
aria-hiddenon the icons) is an equivalent mutant, since lucide-react sets it by default. The explicit attribute stays.Nothing to fix.
CI lue par l'orchestrateur sur la tête
af884ca: PR Check — Frontend run 544 vert (build OK, vitest 122 fichiers / 2085 tests, comptes égaux à ceux du worker). Pas de job Rust attendu.Generated autonomously by /autopilot run of 2026-10-13
/pr-review — APPROVE
Résumé : la PR fait ce que #422 demande. Encadré « Structure attendue » dans les deux variantes de l'état vide, cartes « par compte », phrase de l'aperçu avec « Inverser les signes » puis « Vérifier les doublons », guillemets autour de chaque contrôle en FR et en EN. Tous les textes sont repris mot pour mot du corps de l'issue. Aucun bloquant.
Vérifications rejouées (tête
af884ca, worktree détaché +npm cipropre)npm run buildvert ;vitest run: 122 fichiers, 2085 tests verts.onFlipSignsest toujours passé parImportPage(ImportPage.tsx:220) : la carte ne cite jamais un bouton absent de l'aperçu.success(statut agrégé).pull_refde #439 enref_action: none. La fermeture passe parResolves #422dans le message du commit, ce que lit un merge ff.Mutations du relecteur (une à la fois, arbre restauré et vérifié propre après chacune)
confirm:{{button}}sans « »onboardingPath.locales.test.ts, fr)ImportEmptyState.test.tsx)filePreview: “ ” remplacés par des guillemets droits\"flippointé surimport.preview.flipSignsHintonboardingPath.test.ts7.,ImportPage.render.test.tsxfile-preview)import.empty.structure.account2retiré deen.jsonSuggestions (non bloquantes)
import.empty.structure.*manquante en anglais afficherait la clé brute (fallbackLng: "en"), et aucun test ne le verrait. Le trou existe dans tout le dépôt, pas seulement ici. Pour cette PR, un test de quelques lignes dansonboardingPath.locales.test.ts(mêmes clésstructuredans les deux fichiers, valeurs non vides) suffirait. Sinon, une issue de suivi pour une garde de parité globale.Resolves #422. Ça suffit pour le merge ff de la pile, mais un merge par commit de merge s'appuierait sur le même commit. AjouterResolves #422au corps, pour que la timeline soit cohérente avec les autres maillons.Actions faites
git worktree remove+prune), dépôt principal propre.status:review→status:approved.