HormoneTrack-web/docs/CHANGELOG.md
Siphonight 524f122f15 v1.6.1 : fix — les options du graphique se réinitialisaient toutes seules
Cause (divergence de portage, bug remonté « options reset sans changer de
menu ») : renderRoute() re-crée l'écran ENTIER à chaque tick minute (60 s),
mutation du store ou resize — et l'état des options était une variable
LOCALE de renderChart, retombant aux défauts à chaque re-création.
L'Android est immunisé (remember { mutableStateOf } survit aux
recompositions).

Fix (miroir Compose) :
- chart.js : état d'interaction au NIVEAU MODULE (chartUiState) ;
  renderChart(container, ctx, { preserveState }) réutilise l'état quand
  preserveState=true, le recrée aux défauts sinon ;
- app.js : preserveChartState = (route === 'chart' && lastRoute === 'chart')
  comparé AVANT la mise à jour de lastRoute — tick/store/resize préservent
  l'état, la navigation le réinitialise (miroir du reset d'un remember
  Android quitté).

Épinglé par l'E2E : resize (même code path que le tick) → chip Tracé labs
+ légende restent en place ; navigation → retour aux défauts.

Docs : §4 « État d'interaction persistant », §8 scénario E2E, §11 leçon
#15 (tout état d'UI doit survivre au re-rendu global), CHANGELOG [1.6.1]
(fix web-only : parité fonctionnelle = Android 1.6.0), README.
2026-09-15 12:49:11 +02:00

8.5 KiB
Raw Blame History

CHANGELOG — HormoneTrack Web

Journal des versions de l'app web (séparé du CHANGELOG Android — docs/CHANGELOG.md à la racine du dépôt). Convention Keep a Changelog : section la plus récente EN PREMIER ; ce fichier est lu par le dialog « Nouveautés » de l'app web (fetch docs/CHANGELOG.md).

[1.6.1] — 2026-09-13

Corrigé — les options du graphique se réinitialisaient « toutes seules »

  • Bug remonté : sur l'écran Graphiques, les options sélectionnées (modèles affichés, Tracé labs, Prolonger, zoom, panoramique…) revenaient d'elles-mêmes aux défauts « alors qu'on n'a pas changé de menu ».
  • Cause (divergence de portage) : le shell web re-crée l'écran ENTIER à chaque tick minute (60 s), mutation du store ou resize — et l'état des options vivait dans une variable LOCALE de la fonction de rendu, donc retombait aux défauts à chaque re-crétion. Côté Android, l'équivalent vit dans des remember { mutableStateOf } qui survivent à toutes les recompositions : le bug est structurellement impossible côté APK — c'était un piège du portage, pas de la logique.
  • Fix : l'état d'interaction du graphique vit au niveau MODULE et le shell signale les re-rendus du même écran (preserveState: true) → options préservées pendant qu'on regarde le graphique ; à l'entrée depuis la navigation (quitter puis revenir), retour aux défauts — comportement identique à l'Android.
  • Épinglé par l'E2E : re-render déclenché (resize — même code path que le tick) → chip et légende toujours en place ; navigation → reset.

Note de parité : fix web-only (pas de changement Android) — les fonctionnalités portées restent celles de l'Android v1.6.0.

[1.6.0] — 2026-09-12

« Tracé labs » prolongé au-delà du dernier lab — portage de l'Android v1.6.0

  • Nouveau chip Prolonger (à côté de Tracé labs, off par défaut, désactivé tant que Tracé labs est off) : la courbe ancrée sur tes prises de sang se PROLONGE au-delà du dernier lab — la limite v1.5.0 rendait invisible justement la période la plus récente.
  • Recette : au-delà du dernier lab significatif, courbe(t) = M(t) × ρ_dernier lab — le modèle PK (dosages, esters injectés depuis, pics et descentes classiques) × le ratio mesuré au dernier lab, supposé constant. Les doses loguées APRÈS le dernier lab font repartir la courbe en pic (override d'ester compris).
  • Horizon honnête : la prolongation s'arrête quand le MODÈLE lui-même s'éteint (dernière dose + cutoff moteur : 10 t½ terminales V3C/WHS, fin de table ODS, 30 t½ Bateman) — jamais de ligne à zéro inventée.
  • Lisibilité : partie prolongée dessinée SÉPARÉMENT (même rose, atténué) avec sa légende dédiée + AVERTISSEMENT visible sous la légende : simple simulation sans garantie de correspondre au réel, extrapolée à partir de tes résultats de laboratoire — qui peuvent eux-mêmes être erronés. Fie-toi à ta prochaine prise de sang.
  • Garde anti-ratés inchangée (#61) : un lab hors fenêtre d'action ne prolonge pas la courbe et n'est jamais traversé.
  • Portage fidèle : extensionHorizonEndMs/lastAnchorMs (miroir du Kotlin), 8 nouveaux tests unitaires miroirs + scénario E2E navigateur (activation des chips, légende et avertissement rendus).

[1.5.0] — 2026-09-11

« Tracé labs » — portage de la version Android v1.5.0 (versions synchronisées)

  • Nouvelle courbe superposable (chip Tracé labs, off par défaut)
    courbe(t) = M(t) × ρ(t) — le modèle PK garde la forme biologique (Tmax, queues, accumulation), l'amplitude est recalée sur CHAQUE prise de sang — passage EXACT garanti sur chaque lab, transition log-linéaire d'un lab au suivant (jamais de saut vertical).
  • Garde anti-ratés (#61) : un lab hors fenêtre d'action n'est pas un ancrage ; E2 uniquement ; fenêtre bornée [1er ; dernier lab] — la courbe s'arrête au dernier lab (pas d'extrapolation).
  • Indépendante de la calibration (sa propre référence) ; hors pics/creux ; n'entre JAMAIS dans niveau accueil/alertes.
  • La rangée de chips du graphique défile horizontalement (4ᵉ chip — miroir du fix Android v1.5.0).
  • 11 tests miroirs de LabTrajectoryModelTest.kt (Android).

[1.4.10] — 2026-09-08

Version initiale de la version web — portage navigateur de l'app Android v1.4.10, 100 % locale (données dans le localStorage, aucun serveur applicatif, aucune télémétrie).

Moteur PK (fidèle à l'Android, testé)

  • Trois modèles superposables : Estrannaise (tables ODS de pk_profiles.json, même asset que l'app Android), Transfem Science (forme close V3C de la méta-analyse, 7 esters), WHSAH (fit license-free de Mona, 6 esters — PEP non couvert) + Bateman paramétrable (gel/patch/oral).
  • Pics de l'article TFS épinglés (±2 %) ; équilibre EV 5 mg/7 j = Figure 11 (Cmax 384 / Cmin 142 / Cavg 269) ; fidélité Mona WHSAH (EV 367,5 @ 1,69 j, EEn 187,9 @ 4,99 j, t½ 7,34 j).
  • Invariants Android préservés : bisection computeKa dans le bon sens (#19), modèle strict + extrapolation terminale ≥ 1 % du pic (#20/#21), lookup insensible à la casse (#22), conversion des labs T (#23/#26), garde de significativité de calibration (#61), créneaux de prévision passés sautés (#35), rappels sur la grille Posologie (#52).
  • Calibration par période d'ester et par modèle affiché (#60) : auto-calibration optionnelle (désactivée par défaut) + calibration manuelle par traitement ; k T par période d'ester.

Fonctionnalités

  • Accueil : niveau actuel estimé (E2 pg/mL + T ng/mL) avec delta « vs il y a 6 h » réel (fix #53), cartes d'alerte de seuil, carte prochaine dose (jours au-delà de 24 h, fix v1.4.1), log rapide, mini-graphique 24 h.
  • Graphiques : 24 h/7 j/30 j, zoom 6 h → 300 j (pinch, molette, boutons, focal du pinch conservée), panoramique avec cumul fractionnaire des deltas (fix #62), prévision avec extension de fenêtre sans saut (fix #54) et horizon borné 30 j–1 an, toggles 3 modèles alignés sur les traitements (fix #58), pics/creux avec valeurs, marqueurs de doses réelles et projetées (fix #55), labels X à minuit local dans le fuseau choisi (v1.4.5), labs T convertis en ng/mL au rendu.
  • Doses : historique groupé par jour, Δ jours depuis la dose précédente du même traitement, édition (override d'ester par injection selon le modèle), en-tête « temps sous THS » (3 placeholders, bug #47 épinglé).
  • Analyses : prise de sang E2 + T en une entrée, groupement par timestamp, suppression par prise entière, unités T multiples (ng/mL, ng/dL, ng/L, nmol/L).
  • Traitements : 22 presets, éditeur complet (ester/modèle/Bateman, calibration, Posologie, rappel), traitement inactif = drapeau administratif (la simulation reste, bug v1.2.4).
  • Rappels web : notifications navigateur tant que la page est ouverte (bannière in-app + actions « Loguer maintenant » / « Reporter 1 h »). Limite documentée : pas de notification onglet fermé.
  • Seuils d'alerte : évaluation du niveau estimé, notification web, anti-spam par état persisté (même codec que l'app Android).
  • Sauvegarde JSON compatible Android dans les deux sens (BackupData v2, rétrocompat v1, import en mode écrasement avec IDs conservés) ; paramètres utilisateur transportés (langue, auto-cal, seuils).
  • Logs de diagnostic exportables (buffer 500 lignes, même format que l'app Android).
  • FR + EN (langue par app, indépendante du système), dialog « Nouveautés » après mise à jour.

Processus

  • 121 tests Node (node --test) : profils ODS (pins ODS identiques à l'Android), fidélité TFS/WHSAH, moteur, calibration, backup (dont import des exports Android réels de local-test-data/ si présents), helpers du graphique, alertes, rappels, changelog, store.
  • scripts/check.sh : syntaxe de tous les modules + cohérence i18n FR/EN + tests + smoke HTTP optionnel.
  • Dépôt GIT SÉPARÉ de l'app Android (HormoneTrack-web) — historique 100 % propre (aucune dette de confidentialité), versions alignées sur l'Android, changelogs totalement indépendants.

Non porté (impossible ou hors périmètre navigateur)

  • Événements d'agenda récurrents (pas de CalendarProvider dans un navigateur) — l'éditeur affiche une note explicative.
  • Notifications quand l'onglet est fermé (aucun scheduler système côté web).
  • Verrou biométrique, widget — non implémentés non plus côté Android v1.