HormoneTrack/docs/CHANGELOG.md
Siphonight 3f9b2bd8a0 v1.2.4 : traitement inactif = drapeau administratif, jamais un filtre de données
Bug remonté : passer un traitement à inactif effaçait sa simulation du graphique
(Home/Chart collectaient activeTreatments) et faussait la calibration, tout en
permettant d'y loger des doses.

- HomeScreen / ChartScreen : simulation + calibration avec ALLTreatments
  (actifs + inactifs) — l'historique EV d'un traitement archivé reste simulé
- Home : chips « Log rapide », dialog de création et carte « prochaine dose »
  sur les traitements ACTIFS uniquement
- DosesScreen : création → actifs uniquement ; édition d'une dose existante →
  tous les traitements (rattachement préservé)
- Rappels : annulés pour les inactifs (save, boot via getAllOnce, prochaine dose)
- RegressionUserCase3Test (6 tests, données réelles HORS dépôt gitignoré) :
  transition complète EV inactif (29 doses) → EEn actif (9 doses), 22 labs sur
  les deux périodes, calibration par période couvrant EV + EEN, k T par ester,
  continuité de courbe, niveau actuel — 62 tests verts
- docs : §6.bis (sémantique isActive), §14 bug #32, §8, §21, CHANGELOG,
  README, GUIDE ; versionCode 7, versionName 1.2.4
2026-09-05 20:05:07 +02:00

193 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Changelog — HormoneTrack
Format : [Keep a Changelog](https://keepachangelog.com/fr-FR/1.1.0/).
Versionnage : [SemVer](https://semver.org/). Releases taguées dans git (`v1.2.4`, …).
## [1.2.4] — 2026-09-05 (versionCode 7)
### Corrigé
- **Traitement inactif = drapeau administratif, pas filtre de données** (bug
remonté) : passer un traitement à inactif faisait disparaître sa simulation du
graphique **et** sa contribution à la calibration, tout en permettant encore
d'y loger des doses (incohérence). Désormais :
- Home et Graphiques simulent avec **TOUS les traitements** (actifs + inactifs)
→ l'historique EV d'un traitement passé à inactif reste simulé et calibré ;
- l'inactivation retire uniquement : les chips « Log rapide », le traitement
dans le dropdown des **nouvelles** doses (l'édition d'une dose existante
garde son traitement même inactif), et les **rappels** (alarme annulée au
save, au boot et dans le calcul de la prochaine dose) ;
- la suppression d'une dose reste possible depuis l'historique.
### Ajouté
- **Régression n°3** épinglée sur le 3ᵉ export réel (HORS dépôt, gitignoré) :
le scénario complet de transition — 1 traitement **EV inactif** (29 doses,
2–8 mg, janvier→juillet) + 1 traitement **EEn actif** (9 doses), 22 labs
couvrant les deux périodes. Vérifie : simulation de l'inactif, calibration
par période sur les DEUX esters (EV **et** EEN), k T par ester, continuité
de la courbe pendant la transition, niveau actuel. 6 nouveaux tests (62 au
total, tous verts).
## [1.2.3] — 2026-09-05 (versionCode 6)
### Ajouté
- **Pics et creux estimés sur le graphique** : chip « Pics / creux » (désactivé par
défaut) qui affiche des triangles ▲▼ aux extrema locaux de CHAQUE courbe
(E2 et T, pour les deux modèles), colorés comme leur série. Détection dans le
moteur (`detectExtrema`) : extrema locaux stricts, plateaux fusionnés,
alternance pic/creux imposée, oscillations d'amplitude < seuil ignorées
(2 pg/mL pour l'E2, 0,02 ng/mL pour la T — sémantique zigzag : une oscillation
sous le seuil produit un seul pivot).
- **Calibration T PAR PÉRIODE D'ESTER** : la suppression de la testostérone n'est
pas la même selon l'ester (valerate = pics hauts et courts, enanthate = plateau
doux) → le k du modèle T est désormais calibré **par période** comme le facteur
d'échelle E2 (`computeTKPerEster`) : labs T valerate → k des doses valerate,
labs T enanthate → k des doses enanthate. La courbe T utilise à chaque instant
le k de l'ester **actif** (dernière dose ≤ t, `activeEsterAt`), fallback = k stocké.
Le k T est calibré contre l'E2 **déjà calibrée** (scalePerEster appliqué).
- **Données de test hors dépôt (vie privée)** : les tests de régression épinglés
sur les exports réels chargent désormais leurs données depuis `local-test-data/`
(**gitignoré**) et s'ignorent proprement si le fichier est absent — **aucune
donnée de santé personnelle dans le dépôt ni dans son historique** (réécriture
d'historique effectuée avant le premier push).
- 14 nouveaux tests (56 au total) : détection d'extrema (6) + attribution du k T
par période et courbe T utilisant le k de l'ester actif (2), regroupement des
prises de sang (4), régression n°2 en version data-driven (6).
### Corrigé
- La calibration automatique de la T utilisait l'E2 **non calibrée** → les k
étaient faussés ; elle utilise maintenant l'E2 calibrée par période d'ester.
## [1.2.2] — 2026-09-05 (versionCode 5)
### Ajouté
- **Prise de sang E2 + T en UNE entrée** : le dialog d'ajout propose les deux
marqueurs (chacun **optionnel** — on peut ne saisir que E2 ou que T), avec
date/heure et notes partagées ; les entrées sont insérées au même timestamp et
s'affichent **côte à côte** dans l'écran Analyses (« E2 306 pg/mL · T 44 ng/dL »).
- **Tap sur une paire → sélecteur** (« Quelle entrée veux-tu modifier ? » E2 / T)
puis édition pré-remplie de l'entrée choisie.
- **Suppression par prise de sang** : la corbeille supprime la prise entière
(confirmation listant les valeurs).
- **Toggle T du graphique** : masque désormais aussi les **labs T** (avant : seule
la courbe T disparaissait, les points restaient).
- 4 tests de regroupement (48 au total).
## [1.2.1] — 2026-09-05 (versionCode 4)
### Corrigé
- **Calibration par PÉRIODE D'ESTER** (le fond du problème « courbes à 250–375 ») :
la calibration automatique calculait UN facteur par traitement, mélangeant les labs
de toutes les périodes — un lab valerate comparé à une prédiction enanthate donne un
ratio aberrant qui gonfle la courbe. Désormais chaque lab est **attribué à la période
d'injection dans laquelle il tombe** (dernière dose E2 ≤ lab → son ester) et le
facteur est la médiane des ratios de CETTE période : labs valerate → doses
valerate, labs enanthate → doses enanthate (`computeEsterScaleFactors` +
paramètre `scalePerEster` dans `e2At`/`computeCurve`).
Vérifié sur les données réelles : l'état d'équilibre EEn (t½ ≈ 6,7 j, doses tous
les 6–7 j → accumulation ×2) donne ~270 pg/mL calibré — cohérent avec les labs
300/250 ; les « 375 » rapportés = le même calcul **non calibré** (268/0,72 ≈ 367).
- **Lab T saisi en "pg/mL"** (38 "pg/mL" — faute de frappe) : renvoyé brut, il
écrasait l'axe T (~40) et **rendait la courbe T invisible** (écrasée en bas).
Conversion défensive ajoutée (`pg` → ÷1000, `µg/L` → ÷1000).
### Ajouté
- **Édition des résultats de labo** (comme les doses) : appuyer sur une ligne de
l'écran Analyses ouvre le dialog pré-rempli (marqueur, valeur, unité, date/heure,
notes). Nouveau formateur `formatLabValue` (préserve les décimales : 0,44 reste
0,44, contrairement à formatDose).
- **Tap sur le graphique de l'accueil → écran Graphiques** + mini-légende (E2 bleu /
T rose) + indication.
- **Calibration automatique fusionnée** : UNE seule option dans Paramètres qui couvre
**E2 (par période d'ester) ET T** — plus de réglage T isolé ; le bouton manuel
« Calibrer avec les analyses » (T) reste comme action ponctuelle.
- **8 nouveaux tests** (44 au total) dont `RegressionUserCase2Test` épinglé sur le
2ᵉ export réel (9 doses EEn/TFS, 8 labs, fréquence 6 j) — inclut la vérification
de l'état d'équilibre et du lab T en unité aberrante.
### Modifié
- `AutoCalibrated` : `treatments` inchangés (plus de copies avec SF modifié), nouveau
champ `esterScales: Map<String, Double>` + `calibratedEsters`.
## [1.2.0] — 2026-09-05 (versionCode 3)
### Ajouté
- **Panoramique du graphique** : fais glisser le graphique vers la droite pour
remonter dans le passé (fenêtre glissante sur tout l'historique) ; bouton
« Revenir à maintenant ».
- **Les deux modèles PK superposables** : Estrannaise (bleu) et Transfem Science
(turquoise) tracées simultanément sur le même graphique, avec toggles
indépendants (override de modèle dans le moteur, indépendant du modèle stocké
par traitement).
- **Simulation prévisionnelle** : nouvelle section « Fréquence d'injection » dans
l'éditeur de traitement (intervalle en jours) → chip « Prévision » du graphique
qui projette les doses à venir (2× l'intervalle, borné 7–30 j) à partir de la
dernière injection réelle ; les doses projetées ne sont jamais sauvegardées et
conservent l'ester override de la dernière injection.
- **Calibration automatique (optionnelle)** : dans les Paramètres, option
« Calibration automatique » — ajuste à la volée (affichage seul) les facteurs
d'échelle et le modèle T depuis les labs ; désactivée par défaut, les valeurs
stockées ne sont jamais modifiées.
- **Intervalle entre dosages** : l'écran Doses affiche Δ (jours) entre chaque dose
et la précédente du même traitement (colonne « Interval (d) » du `.ods`).
- 6 nouveaux tests (`V120FeaturesTest`) → **36 tests**.
### Modifié
- **Montée des toolchains** : Gradle 9.7.1, **AGP 9.4.0** (Kotlin intégré — plus de
plugin `org.jetbrains.kotlin.android`, `kotlinOptions` supprimé), Kotlin 2.3.21,
KSP 2.3.11, **Compose BOM 2026.08.00** (Compose 1.12), Room 2.8.4,
Navigation 2.10.0, Activity 1.13.0, AppCompat 1.8.0, DataStore 1.2.1, Gson 2.14.0,
compileSdk/targetSdk **37**.
- Note Material You / Expressive : la BOM récente apporte composants et comportements
Material You ; `MaterialExpressiveTheme` reste **internal** dans la ligne material3
pinnée (vérifié par compilation) → `MaterialTheme` standard conservé, à basculer
dès que l'API devient publique (commenté dans `ui/theme/Theme.kt`).
### Corrigé
- **Horloge du TimePicker décentrée** (partait vers la gauche dans les dialogs de
saisie) : centrage explicite (Box + Center) dans `DateTimeField` et l'éditeur de
traitement.
- Migration Room **v1 → v2** propre (colonne `forecastIntervalDays`) avec
suppression du `fallbackToDestructiveMigration()` — les données réelles sont
protégées : une migration manquante plante bruyamment au lieu d'effacer.
## [1.1.0] — 2026-09-05 (versionCode 2)
### Corrigé
- **Courbes EEn plates à zéro** (le bug rapporté : « les graphiques ne se génèrent pas »).
Cause : casse des clés de profils — l'asset JSON (verbatim du `.ods`) contient
`"EEn_ese"`/`"EEn_tfs"` (n minuscule) alors que la constante `Esters.EEN = "EEN"` ;
le lookup exact échouait silencieusement → `sample() = 0` pour **tous** les traitements
EEn (EV et EU marchaient, ce qui masquait le bug). Fix : lookup **insensible à la casse**
dans `PKProfileStore` (`lookup()`), test de régression épinglé sur les données réelles
de l'utilisatrice (`RegressionUserCaseTest`, export v1.0.0 fourni).
- **Unités de testostérone** : les labs T pouvaient être saisis en ng/dL (cas réel :
33 et 44 ng/dL). L'axe T du chart mélangeait alors des ng/dL avec des estimations en
ng/mL (erreur ×100, courbe T invisible) et la calibration T aurait été faussée d'un
facteur 100. Fix : `PharmacokineticEngine.convertTToNgMl()` (ng/dL → ×0,01 ;
ng/L → ×0,001 ; nmol/L → ×0,2884 ; ng/mL inchangé), appliqué à la calibration **et
au rendu du chart**.
### Ajouté
- **Édition des doses** (le bug rapporté : « on ne peut pas modifier les entrées
d'injection ») : appuyer sur une ligne de l'écran Doses ouvre le dialog en mode
édition (traitement, dose, date/heure, notes) → enregistre sans recréer.
- **Choix de l'ester par injection** dans le dialog de dose (comme dans le `.ods`) :
« Défaut (EEn) », EV, EU, EEn — override stocké par dose, utilisé par le moteur PK.
- 6 tests de régression sur les données réelles de l'utilisatrice (30 tests au total).
### Technique
- `versionCode 2`, `versionName 1.1.0` ; APK debug régénérée.
## [1.0.0] — 2026-09-05 (versionCode 1)
Première version fonctionnelle :
- Courbes estimées E2/T heure par heure (24 h / 7 j / 30 j), modèles **Estrannaise** et
**Transfem Science** (tables horaires extraites de `Estrogen.ods` : EV/EU/EEn)
- Modèle Bateman paramétrable (gel/patch/oral)
- Log des doses, analyses de sang, calibration (facteur d'échelle médian lab÷prédiction)
- Estimation T empirique calibrable
- Rappels quotidiens (alarmes exactes) avec actions « Pris » / « Reporter 1 h »,
notifications remontant sur Huawei Watch GT 3 (Gadgetbridge ou Huawei Health)
- Sauvegarde/Restauration JSON (SAF), FR/EN (langue par app), 100 % local
- 24 tests unitaires (moteur PK, profils ODS, round-trip backup)