Aller au contenu

ADR-0010 — Vocabulaire d'hypothèses partagé (frontend)

Statut : accepté (2026-06-15, arbitrages user). Contexte : la refonte de l'Atelier (ADR-0009) a laissé une dette. Le jeu d'hypothèses est rendu dans plusieurs écrans aux intentions distinctes — Composer (créer, formulaire), Labo / fork (dériver, sur-formulaire), Étude (justifier, grille de lecture), plus Éprouver et Studio. Chaque écran avait recopié sa propre vue : le type JeuDetail était redéfini dans 5 fichiers (chacun avec des champs manquants — dérive silencieuse), un même champ portait trois libellés (« Taux d'actualisation (%) » / « Taux actualisation (%) » / « Taux d'actualisation »), et le formatteur pct, les builders de grille et le preset K1 étaient copiés-collés. Pour un outil d'audit, un actuaire qui voit deux libellés du même champ selon l'écran est un défaut de correction.

🎯 À retenir

On partage le vocabulaire des hypothèses (types, libellés, unités, rendu) via une source unique frontend/lib/hypotheses.ts, pas le layout : chaque écran garde sa présentation mais la pilote depuis cette source. On n'extrait jamais un composant utilisé une seule fois.

La question

Faut-il un composant de grille unique (<HypothesisGrid mode=…>) consommé par les trois écrans ? Non. Les écrans divergent pour de bonnes raisons métier (créer ≠ dériver ≠ justifier) ; un composant à tout faire accumulerait les drapeaux (editable / override / justify / staff / héritage / upload) jusqu'à devenir illisible. Fondre les layouts remplacerait une dette par une pire.

La duplication réelle n'est pas le layout, c'est le vocabulaire : les types, les libellés, les unités, l'ordre, le rendu. C'est lui qu'on centralise.

Décisions

# Décision Arbitrage
D-VOC-1 On partage le vocabulaire, pas le layout. Chaque écran garde sa présentation mais la pilote depuis une source unique (frontend/lib/hypotheses.ts). Analogue frontend de la doctrine du moteur : le jeu définit les champs, les écrans les consomment différemment. user, 2026-06-15
D-VOC-2 Deux types canoniques, miroirs des contrats backend : JeuResume (léger, ↔ persistance.JeuHypothesesOut) et JeuDetail (complet, ↔ labo.JeuDetail). Tous les écrans les importent — fin des 5 redéfinitions locales. découle de D-VOC-1
D-VOC-3 CHAMPS_HYPOTHESES = source unique des libellés, unités, ordre et rendu (lignesChamps(d)). Libellé canonique sans unité ; l'unité (« % ») est une métadonnée de saisie affichée par les formulaires (Composer : « tape 4, pas 0,04 »), pas par les écrans de lecture (qui montrent la valeur formatée « 4 % »). user, 2026-06-15
D-VOC-4 Règle générale : ne pas extraire un composant utilisé une seule fois. L'éditeur de grille IFC n'existe qu'au Composer → pas de composant. On partage ce qui est vraiment dupliqué comme donnée : le formatteur grilleIfcTexte et le preset JEU_K1 (oracle K1, recopié verbatim au Labo et au Studio). user, 2026-06-15

Mécanique

frontend/lib/hypotheses.ts (créé) porte : les types JeuResume / JeuDetail, la table CHAMPS_HYPOTHESES (clé, libellé, unité, groupe, staffSeul, valeur(d)), les dérivés lignesChamps(d) / CLES_CHAMPS / libelleSaisie / libelleChamp, le formatteur grilleIfcTexte et le preset JEU_K1. Le formatteur pct rejoint lib/ui à côté de fcfa / num. Build Next vert.

Conséquences

  • + Cohérence garantie : un champ a un seul libellé, un seul rendu, un seul type. Ajouter un champ = une entrée dans CHAMPS_HYPOTHESES, reflétée partout.
  • + Dette supprimée : 5 types → 2, deux builders et le preset K1 dédupliqués.
  • Effets visibles assumés (harmonisations) : « Revalorisation salaire » → « Revalorisation des salaires » au Composer ; genre_mixte visible dans la Table de mortalité de la Doctrine (comme l'Étude) ; grille IFC d'Éprouver [0–5][0–5 ans] (dérive corrigée).
  • lib/hypotheses dépend de lib/ui (pour pct) — couplage assumé, sans cycle.

Voir mémoire projet « Vocabulaire partagé ActuaryLab ». Prolonge ADR-0009.