feat(reports): shared account filter state in useReportsPeriod (#272) #280
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#280
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-272-report-filters-hook"
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 #272
Generated autonomously by /autopilot run of 2026-07-11
Extends the shared
useReportsPeriodhook additively withaccountIds: number[](URL-backed via a newsourcesquery param, comma-separated, default[]= no filter) and adds theReportFilters { period, accountIds }type inshared/types. URL parsing validates each token as a finite integer (strict regex +Number.isSafeInteger), dropping invalid tokens individually rather than discarding the whole selection.Foundation only (issue I1 of milestone
overnight-2026-07-08-filtres-fondation): no UI exposes the filter yet and no service readsaccountIdsyet — both land in follow-up issues (#273+). The hook shape is purely extended (no rename, no removed fields), so all 6 existing consumers (useTrends,useCompare,useCategoryZoom,ReportsCategoryPage,ReportsPage,ReportsComparePage) compile unchanged, confirmed by a greennpm run build.Tests: 728 -> 745 (17 added, 0 regressions). Build (tsc+vite) green. No DB migration.
Reviewer caveat: none blocking. One judgment call worth a second look: invalid tokens in the
sourcesparam are dropped individually (e.g.sources=3,abc,7->[3,7]) rather than invalidating the whole list — seeparseAccountIds's docstring/tests insrc/hooks/useReportsPeriod.ts/.test.tsif you want to confirm that matches your intent for a hand-edited/corrupted URL.Add accountIds: number[] to the shared useReportsPeriod hook, URL-backed via a dedicated `sources` query param (comma-separated, bookmarkable like the existing period/from/to). Purely additive: the hook's existing shape is unchanged, so all 6 consumers (useTrends, useCompare, useCategoryZoom, ReportsCategoryPage, ReportsPage, ReportsComparePage) keep compiling as-is. Also adds the shared ReportFilters { period, accountIds } type for follow-up issues to consume, and exports pure parseAccountIds/ serializeAccountIds helpers (same hookless-testability pattern as resolveReportsPeriod). URL parsing validates each token as a finite integer via a strict regex + Number.isSafeInteger, dropping invalid tokens individually rather than discarding the whole selection. This is foundation only: no UI control exposes the filter yet, and no service reads accountIds yet (both land in follow-up issues of the "rapports uniformes" epic). Resolves #272 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>/pr-review — APPROVE
Résumé : fondation propre et purement additive. Le hook
useReportsPeriodgagneaccountIds(adossé au param d'URLsources) plus deux fonctions puresparseAccountIds/serializeAccountIds, validées de façon défensive et bien testées (17 tests). Changement rétrocompatible : les 7 consommateurs existants ne déstructurent que des champs préexistants → aucune régression possible. Aucune migration DB.Points vérifiés
^-?\d+$puisNumber.isSafeInteger) — c'est bien la 2e passe qui rejette99999999999999999999(tous chiffres → passe la regex mais débordeisSafeInteger). Notation hex/exponentielle, décimales, tokens vides et espaces sont tous couverts. Aucun chemin d'exception (toutes les opérations sont totales sur des strings).UseReportsPeriodResultest étendu, jamais réduit. Les 4 pages +useCompare/useTrends/useCategoryZoomne lisent queperiod/setPeriod/from/to/setCustomDates→ build vert crédible.setAccountIdssuit à l'identique le patternsetPeriod/setCustomDates(updater fonctionnelnew URLSearchParams(prev),{ replace: true }), et supprimesourcesquand la sélection est vide — miroir de la suppression defrom/topour une période non-custom.ReportFilters.accountIds= liste deImportSource.id(biennumber), distinct debalance_accounts— le docstring le note explicitement. Bon réflexe.architecture.md(table des hooks) +CHANGELOG.md/.fr.mdsous[Unreleased]mis à jour. Conforme.Suggestions (non bloquantes, pour les follow-ups #273+)
ReportFiltersdéfini mais non consommé — normal pour une slice « fondation ». À surveiller : le hook exposeperiod+accountIdsà plat alors queReportFiltersles regroupe ; décider au moment du câblage services quelle forme fait foi, pour éviter deux modèles parallèles.import_sources.idest un autoincrement ≥ 1, donc^-?\d+$laisse passer-3/0qui ne matcheront jamais un compte réel (inoffensif : no-op enIN (...)SQL comme dans un picker). Resserrer en^\d+$(+n > 0) serait plus fidèle au domaine.parseAccountIds("3,3")→[3,3]. Sans effet en SQLIN, mais si la valeur alimente un état de cases à cocher, unSet/dedup au parse éviterait un double-comptage.Aucun de ces points ne bloque le merge.
Merged into
mainvia local fast-forward (commitfe9ae01) as a linear stack. Forgejo doesn't flag non-API merges as merged; closing manually.Pull request closed