- predictedE2 : valeur brute au creux × facteur du ester actif — fournie
par Home/Labs quand l'auto-calibration est ON (sinon null : la carte
n'affiche rien, une valeur brute serait trompeuse). Miroir web.
- Régime POOLÉ (pooledRegimeDoses) : les doses de tous les traitements
partageant (ester effectif, mg) forment UNE séquence — le re-parenting
d'historique (« 6d-old », v1.12.0) ne fait plus redémarrer la
stabilisation. Garde-fous : ester ≠ jamais poolé (régression n°3) ;
dose ≠ exclue (le 8 mg casse via le trou). Régression n°7 data-driven
sur le nouvel export (backup-v1.12.0.json).
- Cible de creux E2 (opt-in) : DataStore + carte settings (hint croisé
« distinct des seuils d'alerte — jamais de notification ») + coloration
carte reco (primaire/hors cible tertiary) + backup rétrocompatible (un
backup ancien n'efface pas la cible locale). Système à 3 niveaux
documenté §7.11. Miroir web complet.
284 tests JVM (250 sans données locales) + 14 UI + lint verts ; web 199
tests + E2E verts (check.sh). Validé émulateur sur données réelles :
« Expected at this trough: ≈ 208 pg/mL — outside your target », régime
poolé = stable depuis le 12 août, 0 crash.
- FIX#70 : generateForecastDoses garde !isActive — un injectable archivé
avec Posologie et de l'historique projetait encore ses injections
(graphique Prévision, extension de fenêtre, horizon LabTiming) ; le chip
Prévision s'activait sur des Posologies inactives. FIX : garde moteur +
horizon/chip sur les ACTIFS. §6.bis inchangé : l'historique reste simulé,
seul le FUTUR s'arrête (comme les rappels v1.4.0). Miroir web. 3 tests
ForecastDosesGuardTest + 3 miroirs web.
- Icônes de forme de prise dans Doses : routeIcon pur (pilule/seringue
IM+SC teinte tertiary pour la SC/goutte/sparadrap/compte-gouttes ;
⚠️ MedicationLiquid absent d'icons-extended 1.7.8 → Colorize).
- Marqueurs « prise de sang le même jour » : labMarkersForDose pur (jour
calendaire LOCAL, lab à l'heure exacte = APRÈS) → encart 🧪↑/🧪↓ en bout
de ligne. 7 tests DosesExtrasTest + 10 miroirs web.
274 tests JVM + 14 UI + lint verts ; web 194 tests + E2E verts (check.sh).
Validé émulateur sur APK RELEASE avec données réelles seedées + scénario du
bug (2 inactifs à Posologie 7 j) : Prévision on/off 0 crash, glyphes et
marqueurs en place.
- Demande : « les traitements inactifs sont peu discernables — les placer
à la fin (tout en bas), et peut-être les rendre plus distincts ».
- Helper pur treatmentsForDisplay (tri STABLE : actifs d'abord, inactifs
après, ordre relatif conservé dans chaque groupe).
- LazyColumn en 3 sections : actifs / en-tête inactive_section (seulement
si des inactifs existent) / inactifs — cartes alpha 0.55 en plus du
badge, lisibles et tappables (l'édition d'un archivé reste possible).
- Miroir web : treatmentsForDisplay dans js/data/models.js + rendu
sections + opacity 0.55 + i18n inactive_section FR/EN (web v1.11.0 sync).
- 5 tests JVM TreatmentsDisplayTest + 4 tests web (miroir).
264 tests JVM + 14 UI + lint verts ; web 184 tests + E2E verts (check.sh).
Validé émulateur sur APK RELEASE avec données réelles seedées (5 actifs en
haut, en-tête + EV-old/EEn-old tout en bas, 0 crash).
Remontée : le rappel quotidien (CPA) masquait le rappel hebdomadaire
(EEn) — « je ne le vois quasiment pas ».
- NextDoseCard : UNE ligne par traitement, TRIÉES par prochaine prise ;
1ʳᵉ ligne (la plus proche) en avant, suivantes en style secondaire ;
titre pluriel « Prochaines doses » dès 2 lignes (next_doses FR/EN)
- Helper PUR nextDoseLine (locale/zone paramétrables, template jours
localisé next_dose_days) + 3 tests NextDoseLineTest
- Notifications inchangées (une alarme par traitement)
- versionCode 43 / 1.9.6 + CHANGELOG/§2/README/GUIDE
- LabTrajectoryModel : extendBeyondLastLab (ρ_last constant au-delà du
dernier lab significatif), lastAnchorMs, extensionHorizonEndMs
(horizon = dernière dose E2 + cutoff du traitement — cutoffHours rendu
public, une seule source de vérité) ; boucle de calcul inchangée.
- ChartScreen : chip « Prolonger » (5ᵉ, off par défaut, désactivé tant
que Tracé labs est off), split série "LAB" (ancrée) / "LABX"
(prolongée, rose atténué α 0,55), légendes dédiées (branche explicite
avant le else — leçon #63), AVERTISSEMENT « simple simulation, sans
garantie de correspondre au réel, labs potentiellement erronés » sous
la légende quand la prolongation est visible.
- 8 nouveaux tests (191 verts / 168 sans données locales) + lint vert.
- Bump versionCode 32 / versionName 1.6.0.
- DosesScreen : carte « Sous THS depuis le … » (HrtDuration, mois = 30 j estimés)
- AppLog : journal horodaté buffer circulaire 500 lignes persisté
filesDir/debug-log.txt ; export SAF + effacement dans Paramètres ;
alimenté par agenda/permissions/import/export/erreurs
- FIX toggle agenda (bug remonté) : le résultat de permission arrive
ASYNCHRONE — le test synchrone post-launch() était toujours faux → le
callback active le switch + journalisation
- AppLogTest (4) + HrtDurationTest (5) → 87 tests verts
- versionCode 15, versionName 1.3.1
- Dialog « Nouveautés » (v1.3.0) : au démarrage, si la version installée est
plus récente que la dernière vue (DataStore changelog_seen_version), un
AlertDialog affiche les sections CHANGELOG non vues (ChangelogHelper
sectionsSince + comparaison SemVer NUMÉRIQUE — 1.2.9 < 1.2.10, lexicographique
aurait tort) ; asset changelog.md synchronisé à chaque build par la tâche
Gradle copyChangelog (gitignoré) ; fermable, ne réapparaît pas avant la
prochaine mise à jour
- Événements d'agenda récurrents (CalendarEvents.kt) : calendrier LOCAL dédié
« HormoneTrack » (CalendarContract, ACCOUNT_TYPE_LOCAL), événement avec
RRULE FREQ=DAILY;INTERVAL=N dérivé de la Posologie (arrondi demi-supérieur
EXPLICITE floor(x+0.5) — kotlin.math.round arrondit les ties vers l'entier
PAIR : 6,5 → 6, piège épinglé), début = prochaine occurrence à l'heure de
rappel (ou 12:00) ; switch dans l'éditeur sous « Rappels », permissions
WRITE_CALENDAR + READ_CALENDAR demandées à l'activation ; suppression/
recréation au save ; id stocké sur Treatment (Room v3, MIGRATION_2_3)
- Paramètres : version installée (BuildConfig.VERSION_NAME, buildConfig=true)
+ lien cliquable vers les releases Gitea
- Tests : ChangelogHelperTest (8) + CalendarRruleTest (3) → 78 tests verts
- versionCode 14, versionName 1.3.0
- detectExtrema : extrema locaux stricts (plateaux fusionnés), alternance
pic/creux imposée, filtre d'amplitude (2 pg/mL E2, 0,02 ng/mL T) — sémantique
zigzag documentée (oscillation sous le seuil = un seul pivot)
- CurveChart : triangles ▲▼ aux extrema de chaque série (couleur de la série),
chip « Pics / creux » + légende (désactivé par défaut)
- computeTKPerEster : le k du modèle T est calibré PAR PÉRIODE D'ESTER (labs T
attribués à la période de la dernière dose ≤ lab, médiane) — la suppression T
diffère valerate vs enanthate ; la courbe T utilise le k de l'ester ACTIF à
chaque instant (activeEsterAt + curseur de doses triées dans computeCurve)
- Fix : la calibration T automatique utilise désormais l'E2 CALIBRÉE
(scalePerEster) — calibrer contre l'E2 brute faussait les k
- levelAt/currentLevel : paramètre tKPerEster (fallback = tConfig.k stocké)
- ExtremaTest : 6 tests (alternance, monotone, plat, court, filtre d'amplitude,
anti-corrélation E2/T) — 56 tests verts
- versionCode 6, versionName 1.2.3 ; docs mises à jour (§7.5/§7.6, §11, README, guide)
- LabDialog : mode création avec deux sections (E2 et T, chacune optionnelle,
au moins une valeur requise) → insère 1 ou 2 LabResult au même timestamp ;
mode édition inchangé (un seul marqueur, pré-rempli)
- LabsScreen : regroupement par timestamp (groupLabsForDisplay : E2 avant T,
autres ensuite, tri desc) → affichage « E2 306 pg/mL · T 45 ng/dL » côte à
côte ; tap sur une paire → sélecteur « Quelle entrée modifier ? » puis
édition pré-remplie ; suppression = la prise entière (confirm nommant les
valeurs) ; formatLabValue préserve les décimales
- ChartScreen : le toggle T masque désormais aussi les labs T (avant : seuls
les points restaient visibles)
- LabsGroupingTest : 4 tests de regroupement (48 tests verts au total)
- versionCode 5, versionName 1.2.2 ; docs mises à jour
- computeEsterScaleFactors : chaque lab est attribué à la période d'injection
dans laquelle il tombe (dernière dose E2 <= lab → son ester) ; facteur final
par ester = médiane des ratios de cette période. Corrige le mélange des
périodes valerate/enanthate qui gonflait les courbes (250-375 pg/mL)
- e2At/computeCurve : paramètre scalePerEster (chaque dose scalée par le facteur
de SON ester, fallback = scaleFactor stocké du traitement)
- autoCalibrated : renvoie esterScales + tConfig recalibré, traitements inchangés
- convertTToNgMl : conversion défensive pg/mL et µg/L (un lab T « 38 pg/mL »
écrasait l'axe T et rendait la courbe T invisible — remonté utilisateur)
- LabDialog create/edit : tap sur une ligne de l'écran Analyses → édition
pré-remplie (formatLabValue préserve les décimales)
- Home : tap sur le mini-graphique → écran Graphiques + mini-légende E2/T
- Settings : UNE seule option « Calibration automatique (E2 + T) » (E2 par
période d'ester + modèle T), placée au-dessus des réglages T manuels
- RegressionUserCase2Test : 2e export réel épinglé (9 doses EEn/TFS, 8 labs,
fréquence 6 j) — vérifie l'état d'équilibre EEn (~270 pg/mL calibré, cohérent
labs 306/248 ; non calibré ≈ 367 = les « 375 » rapportés)
- V120FeaturesTest : attribution des labs par période d'ester + scalePerEster
- 44 tests verts ; versionCode 4, versionName 1.2.1
- Docs : CHANGELOG, DEVELOPPEMENT (§7.6 réécrit), GUIDE, README
- CurveChart : API ChartSeries/CurveStyle (superposition de plusieurs modèles,
styles plein/pointillé), labs T normalisés en ng/mL au rendu
- ChartScreen : panoramique horizontal (remonter dans le passé, bouton
« Revenir à maintenant »), toggles Estrannaise/TFS indépendants, chip Prévision
(horizon = 2× l'intervalle configuré, borné 7-30 j), auto-calibration intégrée,
légende dynamique
- HomeScreen : données auto-calibrées pour la courbe 24 h
- DosesScreen : intervalle en jours entre chaque dose et la précédente du même
traitement (colonne « Interval (d) » du .ods)
- TreatmentEditorScreen : section « Fréquence » (switch + intervalle en jours)
- SettingsScreen : option Calibration automatique
- TimePicker : centré dans ses dialogs (bug d'alignement à gauche signalé)
- strings FR/EN complètes pour toutes les nouveautés