Onboarding : compteur de transactions, compteurs d'onboarding et reducer de la liste (socle) #351
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#351
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?
Vague
planned-2026-10-03-onboarding-phase1(séance/plan-rundu 2026-10-03, spec +/review-specdu 2026-09-25, verdict APPROUVÉ après intégration). Les fichiersspec-decisions-onboarding-phase1.md/spec-plan-onboarding-phase1.mdsont ignorés par git : ce corps est auto-suffisant, ne pas chercher le spec. Analyse d'origine :docs/analyse-onboarding-2026-09.md.Règles de la vague : pile linéaire (chaque PR part de la précédente) ; ne pas toucher
CHANGELOG.md/CHANGELOG.fr.mdavant #357 qui les centralise ; FR + EN pour toute clé i18n (.claude/rules/i18n.md) ; aucune migration DB ; aucune chaîne en dur dans les composants.Objectif
Poser le socle sans UI : un compteur global de transactions, un service de compteurs d'onboarding en une requête, la fonction pure qui calcule les six cases de la liste de démarrage, et le hook à reducer exporté.
Tâches
transactionService.getTransactionCount(): Promise<number>—SELECT COUNT(*) FROM transactions, sans filtresrc/services/onboardingService.ts:getOnboardingCounters()qui lit en unPromise.all(a) la requête agrégée ci-dessous, (b)getImportFolder(), (c)getPreference("onboarding_checklist_hidden");hideChecklist()→setPreference("onboarding_checklist_hidden", "1");showChecklist()→deletePreference(...);logInfoau masquage et au réaffichage (logService)src/utils/onboardingChecklist.ts:computeChecklist(counters, { importFolderSet, budgetAllowed })pur →{ items: ChecklistItem[], done, total, complete },ChecklistItem = { key, done, locked, to }; six cases dans cet ordre :profile(toujours cochée),importFolder(importFolderSet),source(sources ≥ 1),import(imports ≥ 1),manualCategory(manualCategorized ≥ 1),budget(budgetEntries ≥ 1,lockedquandbudgetAllowedest faux) ;total= 6, ou 5 quand la case budget est verrouillée ;complete= toutes les cases non verrouillées cochées ;to=/import,/import,/import,/transactions,/budget(/settings/userspour budget verrouillé)src/hooks/useOnboardingChecklist.ts:onboardingChecklistReduceretinitialOnboardingChecklistStateexportés (nommage préfixé commelicenseReducer,feedbackReducer,migrationReducer) ; état{ status: "loading" | "ready" | "error", counters, hidden, error }; actionsrefresh(),hide(),show(); composition avecuseEntitlement("budget")(allowed→budgetAllowed,ready→budgetReady) ; rend{ status, checklist, hidden, budgetReady, refresh, hide, show }; une erreur de chargement posestatus: "error"sans toucherhiddenOnboardingCountersetChecklistItemdanssrc/shared/types/index.tsRequête des compteurs :
Fichiers concernés
src/services/transactionService.ts(+ test danssrc/services/transactionService.test.tssi existant, sinon créer)src/services/onboardingService.ts(nouveau) +src/services/onboardingService.test.ts(nouveau,vi.mock("./db")commecategorizationService.test.ts:9)src/utils/onboardingChecklist.ts(nouveau) +src/utils/onboardingChecklist.test.ts(nouveau)src/hooks/useOnboardingChecklist.ts(nouveau) +src/hooks/useOnboardingChecklist.test.ts(nouveau, patternsrc/hooks/useSnapshotEditor.test.ts: reducer testé sansrenderHook)src/shared/types/index.tsDepends on
(aucune)
Critères d'acceptation
computeChecklist: tests pour chaque case isolée,budgetAllowed=false→total=5et casebudget.locked=true,completevrai à 5/5 verrouillé et 6/6 ouvert, dossier choisi sans source →done=2, compteurs à zéro →done=1hiddenet posestatus="error";refreshaprèserrorrepasse enloadingpuisreadygetTransactionCounttesté avecdbmocké (0 et N)npm testetnpm run buildverts ; aucune UI touchée dans cette PRReview caveats
Décisions prises en planification
is_manually_categorized = 1) et non « règle créée » ni « transactions catégorisées » : le seed IPC met 180 mots-clés dans tout profil neuf et le wizard catégorise pendant l'import (useImportWizard.ts:1016).planned-2026-09-24-paiementss'exécute avant celle-ci (fichiers partagés :fr.json,en.json, CHANGELOG,architecture.md,guide-utilisateur.md) ; partir d'unmainqui contient déjà ses clés.onboarding_checklist_hidden, valeur"1",snake_casecommecategories_v1_banner_dismissed.Spec source
spec-plan-onboarding-phase1.md (local, ignoré par git)
Onboarding: transaction count, onboarding counters and checklist reducer (socle)to Onboarding : compteur de transactions, compteurs d'onboarding et reducer de la liste (socle)