Simpl-Resultat/spec-decisions-refonte-seed-categories-ipc.md
le king fu 0e2078088a docs: add spec decisions and plan for categories IPC seed refactor
Source of truth for milestone spec-refonte-seed-categories-ipc
(issues #115-#123).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 15:35:15 -04:00

81 lines
8.1 KiB
Markdown

# Spec Decisions — Refonte du seed de catégories vers IPC Statistique Canada
> Date: 2026-04-19
> Projet: simpl-resultat
> Statut: Draft
> Slug: refonte-seed-categories-ipc
## Contexte
Le seed actuel (migration v2, `src-tauri/src/database/seed_categories.sql`) comprend 42 catégories sur 2 niveaux, structurées autour d'un axe cosmétique "récurrentes vs ponctuelles" sans logique métier derrière. Cette organisation :
- Ne reflète aucun référentiel comptable standard (pas d'alignement possible avec Statistique Canada, CPA, ou benchmarks internationaux).
- Exploite seulement 2 des 3 niveaux de hiérarchie supportés par le code (`src/services/categoryService.ts:55-60`).
- Contient des catégories "fourre-tout" (Amazon, Projets) qui cassent la cohérence comptable.
- Propose des mots-clés limités aux fournisseurs rencontrés dans un jeu de données historique personnel.
La refonte vise à s'aligner sur la **classification IPC de Statistique Canada (panier 2024)** qui regroupe les dépenses des ménages en 8 composantes principales officielles, étendues de granularité fine inspirée de Monarch Money (~60 catégories standard, 3 niveaux).
Le spike `seed-standard` (archivé sous `~/claude-code/.spikes/archived/seed-standard/`) a livré 4 documents préparatoires :
- `NOTES.md` — synthèse et décisions
- `code/seed-proposal-v1.sql` — taxonomie v1 (139 catégories, 150+ keywords)
- `code/mapping-old-to-new.md` — table de correspondance v2→v1
- `code/preview-page-mockup.md` — wireframes 3-étapes
**Bénéficiaires** : tous les utilisateurs actuels et futurs de Simpl'Résultat — en particulier les ménages québécois/canadiens qui pourront éventuellement comparer leurs dépenses aux moyennes Statistique Canada.
## Objectif
Remplacer le seed de catégories par une taxonomie alignée IPC/Monarch (3 niveaux, 9 racines IPC + Revenus/Finances/Transferts, ~140 catégories, 150+ keywords fournisseurs canadiens), livrer une page de prévisualisation read-only (Livraison 1), puis une page de migration interactive à 3 étapes avec backup obligatoire via SREF (Livraison 2). Les profils existants migrent en opt-in conscient ; les nouveaux profils reçoivent v1 automatiquement.
## Scope
### IN
- Nouveau fichier `consolidated_schema.sql` avec seed v1 IPC appliqué aux **nouveaux profils** automatiquement.
- Livraison 1 (Option E) : page read-only `/paramètres/catégories/standard` — arbre navigable de la taxonomie v1 avec descriptions, compteurs, export PDF. Aucune modification de données.
- Livraison 2 (Option B) : page de migration 3 étapes (Découvrir / Simuler / Consentir) pour les profils existants.
- Étape Simuler : dry-run complet, calcul des mappings automatiques avec badges de confiance, choix manuel pour cas ambigus.
- Étape Consentir : backup SREF obligatoire (format AES-256-GCM existant) + vérification d'intégrité AVANT toute écriture destructive + migration SQL atomique.
- Algorithme de ventillage en 4 passes (keyword → supplier → défaut → revue utilisateur) pour catégories splittées (Transport commun → Bus/Train, Assurances → 4 branches).
- Préservation des catégories custom utilisateur sous un parent "Catégories personnalisées (migration)" créé automatiquement.
- Bannière dashboard one-shot post-MAJ + entrée permanente dans Paramètres pour inviter à découvrir E et potentiellement B.
- Bouton "Rétablir la sauvegarde" accessible pendant 90 jours post-migration.
- i18n des noms de catégories seed via clés techniques (ex: `seed.categories.alimentation.epicerie`) avec fallback au nom brut pour les catégories custom.
- Couverture de tests complète : unitaires (algo mapping), intégration (flow backup→migrate→rollback), régression (transactions/budgets/keywords post-migration), QA manuelle.
### OUT (explicitement exclu)
- Attribut `transactions.frequency` (recurring/one_shot/unknown) et détection auto → issue séparée future.
- Attribut `categories.essentiality` (essential/discretionary/savings) et rapport 50/30/20 → issue séparée future.
- Peuplement de la colonne `categories.icon` (reste NULL, décision reportée à une future issue UI).
- Suppression de la colonne `categories.icon` (non nécessaire, hors scope).
- Comparaisons avec les moyennes Statistique Canada (infrastructure nécessaire pour télécharger des datasets IPC, analyser, afficher — hors scope v1).
- Migration automatique silencieuse des profils existants (principe : consentement explicite obligatoire).
- Suppression physique du fichier SREF backup (privacy-first : l'app ne gère pas les fichiers de l'utilisateur au-delà de la création).
- Traduction EN des catégories custom créées par l'utilisateur (restent dans la langue saisie).
- Version mobile / Simpl'Résultat Web (hors stack du projet aujourd'hui).
## Decisions prises
| Question | Décision | Raison |
|----------|----------|--------|
| Ordre de livraison (E read-only, B migration, ou fusion) | **E puis B en deux livraisons** | Permet de collecter du feedback sur la taxonomie via E avant d'investir dans l'UX migration B. Deux PRs testables indépendamment. |
| i18n des noms de catégories | **Clés i18n pour seed + noms libres pour custom** | Préserve l'expérience bilingue sans table de traduction BDD. Renderer : clé i18n si elle existe, sinon nom brut. |
| Nouveaux profils après MAJ | **v1 automatique** | Pas de friction pour un nouvel utilisateur sans historique. v1 devient le nouveau standard. |
| Rétention bannière "Rétablir la sauvegarde" | **90 jours** | Laisse le temps à plusieurs cycles mensuels pour détecter un problème. Le fichier SREF lui-même n'est jamais supprimé par l'app. |
| Granularité L3 (~90 feuilles) | **Toutes actives par défaut** | Simplicité, prévisibilité. L'utilisateur peut désactiver via `is_active=0` depuis les paramètres. Overhead négligeable (tree virtualisable). |
| Invitation des profils existants | **Bannière dashboard one-shot + entrée permanente dans Paramètres** | Équilibre entre découvrabilité et respect de l'utilisateur. Ni silent (adoption lente), ni modale bloquante (intrusif). |
| Catégories custom pendant la migration | **Préservées sous parent "Catégories personnalisées (migration)"** | Aucune perte de données ou de règles custom. L'utilisateur déplace à son rythme. Friction minimale à la migration. |
| Colonne `categories.icon` | **Garder NULL, décision reportée** | Ne pas élargir le scope. Issue UI séparée décidera du renderer (emojis / lucide-react / SVG). |
| Tests | **Unitaires + intégration + régression + QA manuelle** | Feature destructive sur données utilisateur → couverture complète justifiée. Algo ventillage = unitaires, migration end-to-end = intégration, non-régression = régression. |
## References
| Source | Pertinence |
|--------|------------|
| [IPC Statistique Canada — panier 2024](https://www150.statcan.gc.ca/n1/pub/62f0014m/62f0014m2025003-fra.htm) | Les 8 composantes principales officielles structurent les racines L1 v1. Référence "quasi-PCGR" pour les dépenses des ménages au Canada. |
| [Statistique Canada — Enquête sur les dépenses des ménages (EDM)](https://www23.statcan.gc.ca/imdb/p2SV_f.pl?Function=getSurvey&SDDS=3508) | Fournit la granularité L2/L3 avec >650 codes de classification détaillés. |
| [Monarch Money — Default Categories](https://help.monarch.com/hc/en-us/articles/360048883851-Default-Categories) | Benchmark 3 niveaux, ~60 catégories par défaut. Inspiration pour la granularité fine (ex: Food & Dining → Groceries, Restaurants, Coffee). |
| Spike `seed-standard` (archivé) | Analyse complète du modèle de données, taxonomie v1 draftée, mapping v2→v1 à 88% automatisable, wireframes 3-étapes. Input direct pour Phase 3b. |
| `src-tauri/src/commands/export_import_commands.rs:8-49` | Format SREF v0.1 + AES-256-GCM + Argon2id réutilisable tel quel pour le backup pre-migration. |
| `src/services/dataExportService.ts:7-10, 199` | Mode `transactions_with_categories` + `importCategoriesOnly()` pour le flow backup/restore. |
| `src/services/categoryService.ts:55-60, 68-74, 175-186` | Règles `is_inputable` auto-gérées + limite 3 niveaux enforced. Le nouveau seed doit respecter ces invariants. |