AUTO-BACKUP JOURNALIER (en plus de l'export manuel, inchangé) : - AppSettings : enabled / treeUri (SAF persisté) / keep (1..30, défaut 7) / lastRun ; BackupManager.writeAutoBackup : tree URI → createDocument d'un fichier horodaté (ExportFileNames.autoBackupFileName — signature LocalDateTime, règle anti-#48) → écriture via writeBackup TEL QUEL (leçon #45) → purge par AutoBackupRetention (PURE, testée : ne touche JAMAIS exports manuels/logs/étrangers, keep clampé ≥ 1). - AutoBackupWorker + AutoBackupScheduler (pattern AlertWorker) : périodique 24 h (KEEP au démarrage, no-op si désactivé), runNow à l'activation (premier backup immédiat), statut dernier run persisté + AppLog ; proguard : -keep explicite du worker (réflexion WorkManager, leçon #64). - Paramètres : carte « Sauvegarde automatique quotidienne » — switch (ON sans dossier → picker SAF), dossier persisté (takePersistableUriPermission), nom lisible (folderDisplayName), copies conservées, statut OK/ÉCHEC. - Validé émulateur §16.ter (APK release + données réelles seedées) : dossier Download/HormoneTrack choisi via le picker SAF, premier backup v2 écrit immédiatement (3 traitements/52 doses/26 labs, importable), rétention keep=2 vérifiée (3 vieux autos supprimés, export manuel intact), statut « OK (date) », 0 crash. UNITÉS DES AXES (remontée « jamais ajoutées depuis v1.0 ») : pg/mL (E2, gauche) / ng/mL (T, droite) au sommet des colonnes de labels (padTop 12→26 dp) — validé émulateur (screencap). Portées web (v1.7.0 web sync). 9 nouveaux tests (200 verts / 177 sans données locales) + lint vert. versionCode 33 / versionName 1.7.0.
16 KiB
HormoneTrack
🤖 Développé avec l'IA : ce projet a été conçu et codé avec un assistant IA. La contribution humaine a été essentielle : feedback continu, retours utilisateur (tests sur vrai téléphone, rapports de bugs accompagnés d'exports réels), suggestions d'améliorations et validation de chaque release. Le détail session par session est documenté dans docs/DEVELOPPEMENT.md §2.
Suivi de thérapie hormonale (THS) sur Android, avec courbes estimées heure par heure d'estradiol (E2) et de testostérone (T), calibration sur les prises de sang, rappels affichés sur smartwatch (Huawei Watch GT 3 via Gadgetbridge ou Huawei Health) et sauvegarde JSON. 100 % local, aucun compte, aucun serveur.
⚠️ Avertissement médical : les courbes sont des estimations pharmacocinétiques à titre informatif — ce ne sont pas des mesures. Fie-toi toujours à tes analyses de sang et aux consignes de ton endocrinologue.
- Statut : v1.7.0 — build Android ✅, lint vert ✅, 200 tests unitaires ✅ (177 sans les données de test locales ; régressions épinglées sur données réelles non versionnées), intégration montre = notifications ✅, dépôt Gitea privé + releases avec APK ✅
- Journal des versions : docs/CHANGELOG.md
- Guide utilisateur : docs/GUIDE_INSTALLATION.md
- Doc de développement (architecture, maths, décisions, bugs) : docs/DEVELOPPEMENT.md
- Montre / Gadgetbridge : docs/MONTRE-GADGETBRIDGE.md
Fonctionnalités
- Courbes estimées heure par heure : E2 (pg/mL) et T (ng/mL), vue 24 h / 7 j / 30 j, doses marquées (prévisionnelles et réelles), fuseau horaire du graphique configurable (v1.4.5), panoramique (glisser pour remonter dans le passé), zoom (pinch ou boutons − / +, 6 h → 300 j, échantillonnage adaptatif), pics & creux affichables avec leurs valeurs estimées (triangles ▲▼ aux extrema locaux, toggle)
- Deux modèles PK au choix, superposables : Estrannaise (EstraNase) (tables
horaires du
.ods) et Transfem Science — depuis v1.4.0, le modèle TFS est la méta-analyse officielle à 3 compartiments (forme close exacte, params du simulateur TFS, article), avec les 7 esters (EV, EU, EEn, EB, EC huile, EC suspension, PEP) — et WHSAH en couvre 6 (sans PEP). Affichés côte à côte avec toggles indépendants (3 couleurs) — pré-cochés selon les modèles de tes traitements (v1.4.7) et chaque modèle calibré séparément par tes labs (v1.4.8 — les facteurs s'adaptent à chaque profil) - « Tracé labs » (v1.5.0, prolongé en v1.6.0) : la courbe ancrée sur tes
prises de sang (chip
Tracé labs, off par défaut) — la forme du modèle PK entre les labs, mais l'amplitude recalée pour passer EXACTEMENT sur chaque lab E2 ; transition log-linéaire d'un lab au suivant, garde des labs hors fenêtre d'action (#61) ; chipProlonger(v1.6.0) : la courbe se prolonge au-delà du dernier lab (modèle × ratio du dernier lab, horizon = extinction du modèle, partie estimée dessinée atténuée + légende dédiée) — la courbe est une référence de COMPARAISON, jamais une estimation d'action (elle n'entre jamais dans l'accueil/les alertes) - Modèle Bateman paramétrable (temps au pic, demi-vie, biodisponibilité) pour gel, patch et voie orale
- Simulation prévisionnelle : configurer la posologie (intervalle en jours) sur un traitement → projection des doses à venir sur le graphique (jamais sauvegardées) ; l'activation ne déplace pas le début du graphique mais ÉTEND la fenêtre jusqu'à la prochaine dose (v1.4.4) et la projection se parcourt en tirant vers la gauche, jusqu'à 1 an
- Log des doses avec date/heure exacte, dose en mg, ester par injection (switch EV↔EU↔EEn comme dans le tableur), éditable (tap sur une ligne dans Doses), intervalle en jours entre dosages affiché
- Traitements inactifs : un traitement archivé n'apparaît plus dans la saisie ni dans les rappels, mais tout son historique reste simulé et calibré — utile pour une transition valerate → enanthate
- Analyses de sang : E2 + T en une seule entrée (chacune optionnelle), affichées côte à côte quand elles partagent la même date/heure, éditables (tap → choix de l'entrée) ; unités T : ng/mL, ng/dL, ng/L, nmol/L
- Calibration : facteur d'échelle par traitement = médiane(lab ÷ prédiction du modèle),
calculé automatiquement (« Scale factor » du
.ods, automatisé) — ou calibration automatique permanente (option, désactivée par défaut) qui calibre chaque ester avec les labs de sa période (labs valerate → doses valerate, labs enanthate → doses enanthate) et recalibre le modèle T - Estimation T empirique
T = plancher + (base − plancher) ÷ (1 + k·E2), avec k calibré par période d'ester (la suppression T diffère valerate vs enanthate), contre l'E2 déjà calibrée — unités T acceptées : ng/mL, ng/dL, ng/L, nmol/L - Rappels quotidiens avec actions « Pris » / « Reporter 1 h » dans la notification ; les notifications remontent sur la Watch GT 3 (Gadgetbridge ou Huawei Health) ; les rappels suivent la Posologie (v1.4.0) : un traitement injecté tous les 7 jours ne sonne que le jour d'injection, pas tous les jours
- Seuils d'alerte configurables (v1.4.2) : limites hautes/basses E2 (pg/mL) et T (ng/mL) dans Paramètres → carte d'avertissement sur l'accueil + notification toutes les 15 min même app fermée (WorkManager, anti-spam, canal dédié) — évaluées sur le taux estimé, opt-in
- Sauvegarde JSON complète : traitements + doses + analyses + réglages T + paramètres (langue, auto-calibration, seuils d'alerte) (v1.4.2)
- Sauvegarde automatique quotidienne (v1.7.0, opt-in) : en PLUS de l'export manuel — chaque jour, un backup JSON complet (même format, importable tel quel) est écrit dans le dossier que tu choisis (ex. dossier Owncloud synchronisé). Aucune permission de stockage (SAF, dossier choisi une fois, permission persistante révocable), rétention configurable (1–30 copies, défaut 7 — fichier horodaté par run, jamais d'écrasement ; exports manuels et fichiers étrangers jamais touchés), statut du dernier run dans Paramètres, premier backup immédiat à l'activation
- Nouveautés à chaque mise à jour : dialog de changelog automatique (fermé = ne réapparaît pas avant la prochaine version)
- Temps sous THS affiché en haut de la page Doses (depuis la 1re prise) ; prochaine dose en jours sur l'accueil quand elle est à plus de 24 h (v1.4.1)
- Logs de diagnostic exportables (Paramètres) — utile pour le support
- Événements d'agenda : les rappels de prises peuvent créer un événement récurrent (posologie) dans un calendrier « HormoneTrack » de ton téléphone
- Sauvegarde/Restauration JSON complète (traitements + doses + analyses + réglages T + paramètres, v1.4.2)
- FR + EN (langue par app, indépendante du système)
- UI Jetpack Compose récente (BOM 2026.08, Material You) ; 100 % local, aucun compte
Démarrage rapide (build depuis les sources)
Prérequis : JDK 17+ (Java 21 OK), Android SDK (la plateforme 37 sera auto-téléchargée par AGP si les licences sont signées). Le wrapper télécharge Gradle 9.7.1.
git clone <repo> && cd HormoneTrack
echo "sdk.dir=/chemin/vers/android-sdk" > local.properties # ou ANDROID_HOME
./gradlew assembleDebug # APK : app/build/outputs/apk/debug/app-debug.apk
./gradlew testDebugUnitTest # 200 tests (177 sans les données locales)
./gradlew lint # lint vert obligatoire avant release
Installation sur un téléphone : mode développeur + Débogage USB, puis Android Studio
(Run ▶️) ou adb install -r app/build/outputs/apk/debug/app-debug.apk.
Pas de Play Store : l'app est sideloadée. Détails pas-à-pas : docs/GUIDE_INSTALLATION.md.
Git
Dépôts : gitea.cloudyfy.fr et gitea.farewell.dev (miroir) —
Siphonight/HormoneTrack sur les deux (privé), avec
releases taguées (v1.1.0 → v1.4.10) et deux APK par release (depuis v1.2.5)
(téléchargeables sans compiler, cf docs/DEVELOPPEMENT.md §16.bis) :
-release.apk (recommandé, optimisé R8, 2,4 Mo) et -debug.apk (20 Mo) :
git tag # lister les releases
git log --oneline # historique par couches (toolchain / moteur / UI / docs)
git push -u origin main --tags
Portage web : depuis v1.4.10, la version navigateur vit dans son propre
dépôt Siphonight/HormoneTrack-web (mêmes instances) — versions alignées
(web v1.4.10 = portage de l'Android v1.4.10), releases sync (checklist
§16 étape 4.bis), changelogs séparés.
Chaque commit de release passe ./gradlew testDebugUnitTest (vert obligatoire) et est
taggué annoté. Voir docs/DEVELOPPEMENT.md §16.
Les modèles en bref
Chaque injection contribue dose_mg × profil(dt) où profil est la réponse normalisée
(pg/mL par mg) ; les contributions se superposent. Trois modèles superposables :
- Estrannaise = tables horaires du
.ods(8001 h), EV/EU/EEn - Transfem Science = méta-analyse à 3 compartiments (V3C, forme close, article), 7 esters (EV, EU, EEn, EB, EC, EC suspension, PEP)
- WHSAH (v1.4.6) = fit « license-free » du WHSAH Collective via Mona — même famille mathématique mais paramètres indépendants avec biodisponibilité explicite F < 1 : montée plus rapide à J+1 (EEn ~70 pg/mL à J+1 pour 5 mg vs ~22 chez TFS) et décroissance plus longue (t½ EEn 7,3 j vs 4,5 j). 6 esters (sans PEP)
Pics de référence (pg/mL par mg) :
| Profil | Modèle | Pic (pg/mL/mg) | Tmax | t½ term. |
|---|---|---|---|---|
| EV | Estrannaise | 61,1 | ~45 h | — |
| EU | Estrannaise | 3,4 | ~55 h (plateau long) | — |
| EEn | Estrannaise | 31,4 | ~152 h | — |
| EV | Transfem Science | 59,0 | ~51 h | 3,0 j |
| EU | Transfem Science | 10,1 | ~198 h | — |
| EEn | Transfem Science | 32,0 | ~156 h | 4,5 j |
| EB | Transfem Science | 194,2 | ~16 h | 1,2 j |
| EC (huile) | Transfem Science | 31,1 | ~103 h | 6,7 j |
| EC (susp.) | Transfem Science | 48,2 | ~29 h | 5,1 j |
| PEP | Transfem Science | 1,03 (dose ~6,5×) | ~18 j | 28,4 j |
| EV | WHSAH | 73,5 | ~41 h | 3,1 j |
| EEn | WHSAH | 37,6 | ~120 h | 7,3 j |
| EB | WHSAH | 260,1 | ~12 h | 1,3 j |
| EC (huile) | WHSAH | 25,0 | ~81 h | 7,9 j |
| EC (susp.) | WHSAH | 53,5 | ~16 h | 7,1 j |
| EU | WHSAH | 4,9 | ~67 h | 31,7 j |
Calibration (v1.4.8) : le facteur d'échelle s'applique par ESTER et par PÉRIODE d'injection (médiane des ratios lab ÷ prédiction, comme la colonne « Scale factor » de la feuille d'origine) — et par MODÈLE : chaque courbe affichée (Estrannaise / Transfem Science / WHSAH) est calibrée avec la prédiction de SON modèle → toutes collent à tes labs, quelle que soit leur forme. L'auto-calibration est optionnelle (désactivée par défaut).
Vie privée
- L'app est 100 % locale : base de données Room sur le téléphone, aucun serveur, aucune télémétrie ; compat Gadgetbridge (FOSS) sans dépendance à Huawei Health
- Le dépôt ne contient aucune donnée de santé : le code et la doc sont génériques ;
les tests de régression qui utilisent des exports réels chargent leurs données
depuis
local-test-data/(gitignoré, hors dépôt — et l'historique a été nettoyé avant le premier push, cf docs/DEVELOPPEMENT.md §8.bis) - Sauvegarde = fichier JSON que tu stockes où tu veux (Owncloud, etc.)
- L'auto-backup quotidien (v1.7.0) n'écrit QUE dans le dossier que tu as toi-même choisi (sélecteur système SAF, permission révocable) — rien ne part ailleurs, aucun serveur
allowBackup=false(données sensibles) ; verrou biométrique prévu en Phase 2- Le dépôt est privé : les releases APK se téléchargent en étant connecté ; passer le dépôt en public rend les APK téléchargeables sans compte (sans risque de données, cf ci-dessus)
Structure du dépôt
HormoneTrack/
├── README.md ← ce fichier
├── docs/
│ ├── GUIDE_INSTALLATION.md guide utilisateur (téléphone + montre)
│ ├── DEVELOPPEMENT.md doc de dev complète (architecture, maths, bugs, tests)
│ ├── CHANGELOG.md journal détaillé des versions
│ └── MONTRE-GADGETBRIDGE.md montre Huawei GT 3 : options + limites
├── scripts/
│ ├── gitea-release.py publie le corps d'une release (CHANGELOG + APK)
│ ├── publish-release.py publie les 2 APK d'un tag (vérification par téléchargement)
│ └── seed-emulator.py injecte un backup JSON dans la DB d'un émulateur (cf §16.ter)
├── local-test-data/ ← gitignoré : backups réels pour les tests
│ de régression (JAMAIS dans le dépôt, cf §8.bis)
├── build.gradle.kts config Gradle racine (AGP/Kotlin/KSP épinglés)
├── settings.gradle.kts
├── gradle.properties
├── gradle/wrapper/ wrapper Gradle 9.7.1 (jar + properties)
├── gradlew / gradlew.bat
└── app/
├── build.gradle.kts dépendances (Compose, Room, DataStore, Gson…)
├── proguard-rules.pro
└── src/
├── main/
│ ├── AndroidManifest.xml
│ ├── assets/pk_profiles.json ← tables horaires (Estrannaise/TFS)
│ ├── java/com/hormonetrack/
│ │ ├── data/ (Room : models, DAOs, repository, backup)
│ │ ├── pk/ (moteur PK + profils : Estrannaise/TFS/WHSAH, alertes, export)
│ │ ├── reminder/ (alarmes exactes, notifs + actions, boot, worker alertes)
│ │ ├── settings/ (DataStore : TConfig, langue)
│ │ ├── ui/ (Compose : screens, components, theme)
│ │ ├── HormoneTrackApp.kt
│ │ └── MainActivity.kt
│ └── res/ (strings FR/EN, thème, icônes)
└── test/java/com/hormonetrack/ ← tests unitaires JVM
├── pk/ (moteur, profils ESE/TFS/WHSAH, calibration
│ par modèle, rappels, régressions data-driven)
├── data/backup/ (round-trip Gson + paramètres)
├── ui/ (fenêtre graphique, garde de source)
├── util/ (noms de fichiers d'export, durées)
├── reminder/ + settings/ (RRULE agenda, changelog)
Feuille de route
- v1 : courbes E2/T, log doses, labs + calibration, rappels, backup JSON, FR/EN
- Tests UI Compose + compilation release signée
- Verrou biométrique, widget, export CSV
- Phase 2 montre : watchface personnalisée et/ou mini-app Lite Wearable (voir docs/MONTRE-GADGETBRIDGE.md)
Licence
GPL-3.0 — voir LICENSE. Cohérent avec l'écosystème Gadgetbridge. Les modèles PK appartiennent à leurs autrices respectives (Estrannaise, Transfem Science).