- 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
- strings EN « Dosage » / FR « Posologie » ; hint « dernière prise » (au lieu
de « dernière injection ») — adapté aux voies non injectables
- quirk Gitea découvert : le nom d'asset passé à l'upload peut être normalisé
(observé : -release.apk → .apk générique) → le script renomme l'asset via
l'API d'édition (PATCH …/assets/{id}) après chaque upload
- release v1.2.8 publiée avec les 2 APK (release 2,5 Mo + debug 21 Mo)
- docs : §16.bis quirk, §8 (64 tests), historique, footer, README
- versionCode 11, versionName 1.2.8
- generateForecastDoses : les créneaux déjà passés (oubli d'injection) ne sont
plus simulés — avant, dernier+intervalle tombait dans le passé → faux pic
dans l'historique + rythme décalé ; la prévision démarre au premier créneau
strictement futur, au rythme configuré
- un retard décale toute la prévision (part de la dernière prise réelle) —
comportement voulu, épinglé par 2 tests
- doc §7.3b corrigée (mismatch doc-code détecté par l'utilisatrice)
- docs : §13 écrasement, §19/§20 import, §14 #34/#35, §21, historique
(lignes v1.2.2/6/7), footer — vérification intégrée dans le script de patch
- versionCode 10, versionName 1.2.7 ; 64 tests verts
- build release signé avec la CLÉ DEBUG (même signature → mise à jour
par-dessus l'app installée sans perte de données) mais avec R8 full mode
+ isShrinkResources : 20 Mo → 2,4 Mo, démarrage et fluidité améliorés
- proguard-rules.pro : -keep explicites pour la réflexion Gson (data.model,
BackupData, TConfig) — sinon export/import JSON cassé en release uniquement
- release v1.2.5 : deux APK publiés (release recommandé 2,4 Mo + debug 20 Mo)
- docs : §16.bis (deux APK par release, garde-fous R8), CHANGELOG
- scripts/gitea-release.py : argument d'instance (URL/owner/trousseau par hôte),
usage inchangé sinon ; tokens par instance dans le trousseau macOS
- remotes : origin (cloudyfy, HTTPS) + farewell (SSH, alias giteassh:2222)
- docs §16/§16.bis : deux remotes, scopes des tokens, commande d'ajout au
trousseau pour farewell
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
- §8 : 56 tests, V120FeaturesTest (10) incluant calibration T par ester
- §14 : bugs 25-31 (calibration par période, lab T en unité aberrante,
commentaires imbriqués dans les KDoc, XML de test périmés, idempotence
du scrub d'historique, préfixe « v » des releases) + leçons (f)(g)(h)
- §20 : état des faits / reste à faire mis à jour
- §21 : checklist des features v1.2.x
- README : arbre (scripts/, CHANGELOG, local-test-data gitignoré)
- le corps de chaque release Gitea est extrait de docs/CHANGELOG.md (la section
[X.Y.Z] de la version) — les 5 releases existantes ont été mises à jour (le
1er script cherchait [vX.Y.Z] et était tombé sur le fallback)
- crée ou met à jour la release (PATCH), remplace l'asset APK du même nom
- token Gitea lu dans le trousseau macOS, scope write:repository suffisant
- §16.bis documente le script + le piège du préfixe « v »
- §8.bis : les données de santé de test vivent dans local-test-data/ (gitignoré),
tests Assume-skippés si absentes, historique nettoyé avant premier push
(filter-branch) — aucune donnée de santé dans le dépôt ni l'historique
- §16.bis : procédure de release Gitea (API + upload APK par tag)
- README : statut v1.2.3, section Vie privée (dépôt sans données), Git à jour
- RegressionUserCase{,2}Test chargent le backup réel depuis local-test-data/
(gitignoré) et sont IGNORÉS proprement (Assume) si le fichier est absent —
plus aucune donnée de santé personnelle embarquée dans le dépôt
- KDoc LabDialog : exemple 300.0 (au lieu d'une valeur réelle)
- script d'anonymisation /tmp/scrub.py prêt pour filter-branch (historique)
- 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
- concentrationOfDose/e2At/computeCurve : paramètre modelOverride (dessiner
Estrannaise et Transfem Science simultanément, indépendamment du pkModel stocké)
- generateForecastDoses : projette les doses à venir depuis la dernière injection
réelle + forecastIntervalDays (jamais persistées, ester override conservé)
- autoCalibrated : recalcul à la volée des scale factors et du modèle T depuis les
labs (copies uniquement — les valeurs stockées ne changent jamais)
- Treatment.forecastIntervalDays + migration Room v1→v2 (ALTER TABLE), sans
fallbackToDestructiveMigration (données réelles de l'utilisatrice protégées)
- AppSettings.autoCalibrate (DataStore, désactivé par défaut)
- V120FeaturesTest : 6 tests (rythme des prévisions, override d'ester projeté,
divergence des deux modèles, auto-cal appliquée et préservation des originaux)