-
v1.4.0 Stable
released this
2026-09-06 22:28:18 +02:00 | 48 commits to main since this releaseAjouté
- Modèle Transfem Science reconstruit sur la méta-analyse officielle
(https://transfemscience.org/articles/injectable-e2-meta-analysis/) :
la courbe TFS n'est plus dérivée des tables horaires du tableur — elle
est désormais la forme close exacte du modèle à 3 compartiments (V3C)
publié par le simulateur TFS, avec les paramètres D/k1/k2/k3 des 7 esters
(EV, EEn, EU, EB, EC huile, EC suspension, PEP). PICS DE RÉFÉRENCE
REPRODUITS À ~1 % (épinglés parTransfemScienceModelsTest) : EV 295
pg/mL @ 2,1 j ; EEn 160 @ 6,5 j ; EB 971 @ 0,65 j ; EC 155 @ 4,3 j ;
EC susp. 241 @ 1,2 j ; PEP 34 @ 32,5 mg @ 18 j ; AUC et état d'équilibre
EV 5 mg/7 j (Cmax 384 / Cmin 142 / Cavg 269) conformes à la Figure 11.
Avantages : plus de plancher d'arrondi 0,01 en queue de table, pas de
coupure à 8001 h (extrapolation exacte), coupure moteur à 10 demi-vies
terminales. - Nouveaux esters : benzoate (EB), cypionate huile (EC), cypionate
suspension aqueuse (ECS) et polyestradiol phosphate (PEP) — 4 presets
TFS, override d'ester par dose étendu (la liste suit le modèle du
traitement : TFS = les 7 esters, Estrannaise = EV/EU/EEn faute de tables
ODS). PEP = biodisponibilité réduite, doses ~6,5× (cf article). - Rappels qui suivent la Posologie (fix #52, Corrigé ci-dessous) :
la carte « Prochaine dose » de l'accueil passe par le même moteur que
les alarmes. - 12 nouveaux tests (102 au total / 84 sans les données locales) :
TransfemScienceModelsTest(pics, t½, AUC, équilibre de la Figure 11)
etReminderScheduleTest(grille Posologie, créneau manqué, fallback
quotidien).
Corrigé
- Les rappels se déclenchaient TOUS LES JOURS sans tenir compte de
l'intervalle entre prises (#52, remontée utilisateur : « je m'injecte
tous les samedis à 18 h, je dois recevoir le rappel uniquement le
samedi à 18 h ») : le calcul du prochain déclenchement ignorait doses et
Posologie. Désormais, un traitement avec Posologie + historique sonne
le jour du créneau à l'heure choisie (dernière dose + k × intervalle,
créneaux passés sautés comme la prévision) ; sans Posologie ou sans
historique → comportement quotidien inchangé. De plus, l'alarme suivante
est reprogrammée après chaque notification et après « Pris »
(les alarmes sont one-shot : la chaîne n'existait qu'au boot/au save).
Downloads
- Modèle Transfem Science reconstruit sur la méta-analyse officielle
-
v1.3.5 Stable
released this
2026-09-06 14:46:50 +02:00 | 49 commits to main since this releaseCorrigé
- Création du calendrier d'agenda impossible (remontée via les logs de
diagnostic — le mécanisme v1.3.1 a tout de suite nourri le diagnostic
à distance :Sync adapters must specify an account and account type) :
l'URI d'insertionCALLER_IS_SYNCADAPTER=truedu calendrier local
« HormoneTrack » n'embarquait pasACCOUNT_NAME+ACCOUNT_TYPE—
exigé par le CalendarProvider pour toute opération sync-adapter
(CalendarEvents.ensureCalendar, §14 #50). Ces mêmes logs prouvent aussi
que la permission agenda est désormais accordée (fix manifest v1.3.3 ✓)
et que l'export des logs fonctionne sur le téléphone (fix #48 ✓) —
la chaîne de diagnostic est opérationnelle. - Suppression d'événement d'agenda silencieusement manquée (#50 bis) :
l'URI de DELETE avait le même défaut (CALLER_IS_SYNCADAPTERsans params
account) → « switch OFF » + save loguait « supprimé » mais l'événement
restait dans le provider. Fix : mêmes paramètres sur l'URI de delete.
Validé émulateur : cycle complet ON→save→OFF→save = événement créé puis
réellement supprimé (content queryvide). - Événement d'agenda orphelin après tout re-save (#51) :
TreatmentEditorScreen.buildTreatment()ne transmettait pas
calendarEventId→ l'id revenait ànullà chaque sauvegarde : après le
premier save, l'événement devenait définitivement orphelin (plus jamais
supprimable/désactivable par l'app). L'id existant est désormais chargé à
l'ouverture et conservé par le save. - Log « événement agenda supprimé » mensonger : imprimé aussi quand rien
n'a été supprimé (switch désactivé, posologie absente, permission absente).
Désormais trois messages distincts : « créé/mis à jour (id=…) »,
« supprimé », « non activé (switch/posologie/permission) ».
Ajouté
- Validation émulateur de l'agenda end-to-end (recette §16.ter, permissions
accordées viapm grant) : calendrier + événement récurrent créés et
visibles dans le provider (content query).
Downloads
- Création du calendrier d'agenda impossible (remontée via les logs de
-
v1.3.4 Stable
released this
2026-09-06 12:38:57 +02:00 | 50 commits to main since this releaseCorrigé
- L'écran Doses faisait crasher l'app (remontée) :
MissingFormatArgumentException: Format specifier '%3$d'— la stringhrt_durationa TROIS placeholders
(%1$d mois, %2$d jours, %3$d total) mais l'appel transmettait 2 arguments.
Crash dès le premier affichage de l'écran Doses avec une donnée antérieure à
aujourd'hui. Le bug est né en v1.3.1 (string + appel dans le même commit,
jamais testés ensemble) et a survécu aux releases v1.3.1→v1.3.3. Fix : passer
totalDays en 3ᵉ argument (cf §14 #47). - L'export des logs de diagnostic faisait crasher l'app (remontée répétée ;
les « fixes » IO de v1.3.2 et v1.3.3 étaient corrects mais à côté du vrai
problème) : le nom de fichier était construit via
LocalDate.now().format(ofPattern("yyyyMMdd-HHmm"))— unLocalDaten'a pas
de champ horaire →UnsupportedTemporalTypeException: Unsupported field: HourOfDay, levée SYNCHRONEMENT dans le onClick (thread UI) au tap sur
« Exporter », avant même l'ouverture du gestionnaire de fichiers. L'export
JSON fonctionnait car son patternyyyyMMddest valide pour un LocalDate.
FIX : utilitaireExportFileNames(pur, testé) —diagnosticLogFileName()
utilise unLocalDateTime;backupFileName()reste surLocalDate.
Cf §14 #48. - Lint
StringFormatMatches(détecté en implantant le lint — nouveau filet
de la v1.3.4) : la notification de rappel passait un Double à une%s.
Fix :dose.toString()(comportement d'affichage inchangé, #49).
Ajouté
- Lint en filet bloquant :
./gradlew lintest désormais vert (it aurait
attrapé dès v1.3.1 les deux crashs ci-dessus viaStringFormatMatches).
Les deux checks Compose 1.12+ théoriques (NonObservableLocale,
LocalContextGetResourceValueCall) sont rétrogradés en warning via
app/lint.xml(staleness de config, refonte i18n plus tard, cf §19/§20). - Recette reproductible : test manuel sur émulateur (documentée §16.ter) :
émulateur + image ATD ou google_apis, seed de la DB du debug avec un backup
JSON via le nouveau scriptscripts/seed-emulator.py(générique, sans
aucune donnée embarquée), installation du APK release par-dessus (données
conservées, même signature), pilotage paruiautomator dump+input tap,
crashs viaadb logcat -b crash. C'est cette recette qui a reproduit et
confirmé les deux crashs ci-dessus ainsi que LEUR correction (flux SAF
complet : picker → SAVE → fichier écrit → message de confirmation, sur
l'APK release données réelles). - 3 nouveaux tests (
ExportFileNamesTest, 90 au total / 72 sans les
données locales) : épinglent le format des noms de fichiers d'export —
auraient attrapé le bug #48 le jour même.
Downloads
- L'écran Doses faisait crasher l'app (remontée) :
-
v1.3.3 Stable
released this
2026-09-06 11:24:22 +02:00 | 52 commits to main since this releaseCorrigé
- Export des logs plantait TOUJOURS l'app (remontée ; le « fix » v1.3.2
était insuffisant) : l'écriture était réimplémentée en inline au lieu de
réutiliser l'IO éprouvée de l'export JSON, et les appelsAppLog.logdu
callback étaient hors try/catch — une exception dans une coroutine à scope
racine (CoroutineScope standalone) remonte au handler de la thread =
crash du process. FIX : l'export passe désormais par
BackupManager.writeBackuptel quel (le même code path que l'export
JSON qui fonctionne sur le téléphone), tout le callback est gardé, et
AppLog.logne lève plus jamais d'exception (IO fichier avalée en interne,
on perd au pire une ligne de journal). Feedback visible succès/échec
(comme l'export JSON) + compteur de lignes rafraîchi après l'export. - Événements d'agenda inopérants depuis v1.3.0 : les permissions
WRITE_CALENDAR / READ_CALENDAR n'étaient pas déclarées dans le manifest
(jamais présentes dans tout l'historique git, bien que documentées §9) —
la demande à l'exécution était donc refusée d'office et
CalendarEventslève SecurityException. Cause racine manquante des bugs
« toggle agenda » « corrigés » en v1.3.1/v1.3.2 : la logique UI était
correcte, il ne venait à l'esprit de personne que la déclaration manquait. - Métadonnées de version fausses : le bump de version n'avait jamais
été commité — les tags v1.3.0, v1.3.1 et v1.3.2 contenaient tous
versionCode = 14 / versionName = "1.3.0", donc les APK publiés
affichaient « 1.3.0 » dans Paramètres et en titre du dialog « Nouveautés ».
Désormais bumpé + commité avant chaque tag (checklist §16 étape 1).
Technique
- Doc de développement mise à jour (DB v3, targetSdk 36, fichiers de
données de régression, bugs #43–#45) ; téléphone de test documenté :
Google Pixel 9 /e/OS (AOSP, DocumentsUI standard — l'export JSON y
fonctionne, l'export logs réutilise ce même path). - Compteur de tests inchangé : 87 (44 sans les données locales, gitignorées).
Downloads
- Export des logs plantait TOUJOURS l'app (remontée ; le « fix » v1.3.2
-
v1.3.2 Stable
released this
2026-09-06 10:41:34 +02:00 | 55 commits to main since this releaseCorrigé
- Toggle de l'agenda : le switch ne s'activait pas (le résultat de la
permission arrive ASYNCHRONE — le test synchrone juste aprèslaunch()
était toujours faux). FIX : le callback active le switch ; Posologie
désormais requise pour l'agenda (refus + message si absente) ;
permission vérifiée RÉELLEMENT viaContextCompatau save (le flag
remembered pouvait être faux après recomposition) ; journalisation
AppLog à chaque étape. - Export des logs plantait l'app : réécrit avec le pattern éprouvé de
l'export JSON (BackupManager) ; chaque étape journalisée dans AppLog. - Dialog « Nouveautés » réapparaissait à chaque réouverture : la version
vue est désormais mémorisée AVANT l'affichage (et non après) + AppLog
pour diagnostiquer si ça se reproduit. - Titre du dialog « Nouveautés » : affiche la version de l'APP
(BuildConfig.VERSION_NAME) — si l'APK installé est 1.3.0, le titre
montre 1.3.0 même si le contenu parle d'une version plus récente
(l'asset changelog.md peut contenir des sections plus récentes si
l'APK a été reconstruit après coup). Installer le dernier APK
(HormoneTrack-v1.3.2-release.apk) pour avoir la version correcte.
Downloads
- Toggle de l'agenda : le switch ne s'activait pas (le résultat de la
-
v1.3.1 Stable
released this
2026-09-06 10:16:51 +02:00 | 59 commits to main since this releaseAjouté
- En-tête « temps sous THS » sur la page Doses : depuis la 1re prise
enregistrée, en jours totaux et décomposition mois/jours (mois = 30 j,
estimation documentée). - Logs de diagnostic (v1.3.1) : journal horodaté des événements notables
(agenda, rappels, import/export, erreurs), buffer circulaire de 500 lignes,
persisté dansfilesDir/debug-log.txt; export (SAF) et effacement depuis
Paramètres. Objectif : debug à distance via les logs joints aux retours. - 9 nouveaux tests (87 au total) : AppLog (formatage, buffer circulaire) et
HrtDuration (jours, décomposition mois/jours).
Corrigé
- Toggle de l'agenda ne s'activait pas (bug remonté) : le résultat de la
permission arrive ASYNCHRONE — le test synchrone juste aprèslaunch()
était toujours faux → le switch rebondissait sans s'activer et sans
feedback. FIX : le callback active le switch ; feedback visible (hint) et
journalisation (AppLog).
Downloads
- En-tête « temps sous THS » sur la page Doses : depuis la 1re prise
-
v1.3.0 Stable
released this
2026-09-06 08:30:32 +02:00 | 65 commits to main since this releaseAjouté
- Dialog « Nouveautés » : après chaque mise à jour (et à la première
installation), l'app affiche le changelog des versions non vues dans une
fenêtre fermable — ne réapparaît pas avant la prochaine mise à jour
(version vue mémorisée). Contenu =docs/CHANGELOG.mdembarqué en asset,
synchronisé automatiquement à chaque build (tâche GradlecopyChangelog). - Événements d'agenda récurrents : dans l'éditeur de traitement, sous
« Rappels », un switch « Événement d'agenda récurrent » crée un événement
dans un calendrier local dédié « HormoneTrack » (visible dans l'agenda du
téléphone) avec répétition RRULE dérivée de la Posologie (tous les N
jours, arrondi demi-supérieur). Permission agenda demandée à l'activation ;
suppression/recréation automatique au save. - Paramètres : version installée + lien cliquable vers les releases Gitea
(télécharger les APK sans attendre le rappel de mise à jour). - 11 nouveaux tests (78 au total) : ChangelogHelper (8 : comparaison SemVer
numérique 1.2.9 < 1.2.10 — lexicographique aurait tort, extraction de
sections, première installation), CalendarRruleTest (3 : RRULE, arrondi
demi-supérieur — kotlin.math.round arrondit les ties vers l'entier PAIR
(6,5 → 6), piège documenté).
Downloads
- Dialog « Nouveautés » : après chaque mise à jour (et à la première
-
v1.2.10 Stable
released this
2026-09-05 23:36:32 +02:00 | 69 commits to main since this releaseCorrigé
- Sens des boutons de zoom inversé (retour utilisateur) : convention
carte — « + » = zoom avant (fenêtre plus courte, plus de détail) et
« − » = zoom arrière (fenêtre plus longue, plus de temps). Avant,
le « + » dézoomait (montrait plus de temps) — pas intuitif. Le pinch
(écarter = zoom avant) était déjà correct.
Downloads
- Sens des boutons de zoom inversé (retour utilisateur) : convention
-
v1.2.9 Stable
released this
2026-09-05 22:51:28 +02:00 | 71 commits to main since this releaseAjouté
- Zoom du graphique de simulation : pinch à 2 doigts et boutons − / +
(accessibilité), plage bornée 6 h → 300 j ; le point focal du pinch reste
fixe dans le temps ; échantillonnage adaptatif (15 min ≤ 12 h, 30 min ≤
24 h, sinon 1 h — courbes lisses à fort zoom) ; labels X adaptatifs
(1 h / 3 h). Un seul gestionnaire de gestes gère pan + zoom (pas de
conflit de consommation). - README : disclaimer IA en en-tête — projet développé avec l'IA,
contribution humaine essentielle (feedback, retours utilisateur, suggestions) ;
mention factuelle reprise en §1/§2 de la doc de développement. - 3 tests
stepForRange(67 au total).
Downloads
- Zoom du graphique de simulation : pinch à 2 doigts et boutons − / +
-
v1.2.8 Stable
released this
2026-09-05 22:24:25 +02:00 | 74 commits to main since this releaseModifié
- « Fréquence d'injection » renommé « Posologie » (section Traitements) :
le terme « fréquence d'injection » n'avait pas de sens pour les prises
d'hormones non injectables (gel, patch, oral). L'astuce d'intervalle est
inchangée ; les textes d'aide disent désormais « dernière prise
enregistrée » au lieu de « dernière injection » (EN : « Dosage »).
Downloads
- « Fréquence d'injection » renommé « Posologie » (section Traitements) :