-
v1.13.0 Stable
released this
2026-10-07 09:59:19 +02:00 | 1 commits to main since this releaseAjouté — la reco de prise de sang devient prédictive (3 niveaux clairs)
- Valeur E2 attendue au creux recommandé : la carte (Accueil + Analyses)
affiche désormais « ≈ X pg/mL » quand l'auto-calibration fournit ses
facteurs — sinon rien (une valeur brute non calibrée serait trompeuse).
Tu sais AVANT de piquer si le creux tombera dans ta cible. - Régime POOLÉ entre traitements identiques :
pooledRegimeDoses— les
doses de tous les traitements partageant (ester effectif, mg) forment UNE
séquence. Un re-parenting d'historique (créer un « … - old » et y
déplacer des doses) ne fait plus redémarrer la stabilisation. Garde-fous
épinglés : ester ≠ → jamais poolé (transition EV→EEn) ; dose ≠ → exclue
(le 8 mg casse le régime, trou conservateur). - Cible de creux E2 (opt-in, Paramètres) : référence personnelle « je
veux être dans [basse, haute] au creux recommandé » — la prédiction est
colorée dans/hors cible sur la carte. ⚠️ DISTINCT des seuils d'alerte
(§9.bis) : les seuils surveillent le niveau en continu et notifient ; la
cible est une référence de lab, elle ne notifie JAMAIS. Voyage dans le
backup (champs optionnels rétrocompatibles — un backup ancien n'efface
pas la cible locale). - Régression n°7 épinglée sur données réelles (
backup-v1.12.0.json,
gitigné — l'export avec le re-parenting « 6d-old ») : le régime poolé
traverse la frontière de re-parenting et reste arrêté par le 8 mg.
Vérifié : 284 tests JVM (250 sans données locales) + 14 tests UI +
lint verts ; web 199 tests + E2E verts (check.sh).Downloads
- Valeur E2 attendue au creux recommandé : la carte (Accueil + Analyses)
-
v1.12.0 Stable
released this
2026-09-29 23:24:35 +02:00 | 4 commits to main since this releaseCorrigé — un traitement inactif à Posologie projetait encore ses injections (#70)
- Remontée : « une injection qui n'est plus active est toujours prise en
compte dans le graphique de simulations si elle contient une posologie et
qu'elle a déjà été utilisée — un traitement mis en inactif ne devrait
plus être pris en compte pour les futures prédictions ». - Cause :
generateForecastDoses(source unique des créneaux
prévisionnels) ne vérifiait pas l'archivage ; de plus l'horizon du chip
Prévision du graphique incluait les Posologies INACTIVES. - Fix : garde
!isActivedans le moteur (l'historique reste simulé —
§6.bis inchangé — seul le FUTUR s'arrête, comme les rappels depuis
v1.4.0) + horizon/chip Prévision calculés sur les ACTIFS uniquement.
Miroir web appliqué (js/pk/pk-engine.js+js/ui/chart.js). - Tests : 3 tests JVM (
ForecastDosesGuardTest) + 3 miroirs web ;
émulateur avec données modifiées (2 inactifs à Posologie 7 j) :
Prévision on/off sans crash.
Ajouté — icônes de forme de prise dans la page Doses
- Chaque ligne de dose porte désormais l'icône de sa forme : 💊-icône pilule
(oral), seringue (injection IM et SC — teinte distincte pour la SC),
goutte (gel), sparadrap (patch), compte-gouttes (autre). Miroir web :
émojis (routeGlyph, même mapping).
Ajouté — marqueurs « prise de sang le même jour » sur les lignes de doses
- Une analyse de sang effectuée LE MÊME JOUR qu'une dose affiche un petit
encart latéral 🧪↑ (avant la dose) et/ou 🧪↓ (après) — pour visualiser
les prises de sang dans le tableau de dosages (demande utilisatrice).
Fenêtre = jour calendaire LOCAL (au-delà le lien clinique devient ténu).
Helper purlabMarkersForDose(Kotlin + miroir web) — 7 tests JVM
(DosesExtrasTest: mapping icônes + marqueurs, frontière minuit,
convention « à l'heure de la dose = après ») + 10 miroirs web. - Vérifié émulateur avec données réelles : glyphes en tête de liste,
marqueur « Blood test later the same day » sur la dose du 10 sept
(analyse 35 min après).
Vérifié : 274 tests JVM (240 sans données locales) + 14 tests UI +
lint verts ; web 194 tests + E2E verts (check.sh).Downloads
- Remontée : « une injection qui n'est plus active est toujours prise en
-
v1.11.0 Stable
released this
2026-09-29 07:31:25 +02:00 | 6 commits to main since this releaseAjouté — les traitements inactifs regroupés en bas de la page Traitements
- Demande : « les traitements inactifs sont peu discernables par rapport
aux traitements actifs — les placer à la fin (tout en bas) de la liste
pour éviter les confusions ». - Tri : les ACTIFS d'abord, les INACTIFS regroupés tout en bas, sous
un en-tête de section « Traitements inactifs » (n'apparaît que s'il
existe des inactifs). Tri STABLE : l'ordre relatif à l'intérieur de
chaque groupe est conservé — le tri ne réordonne jamais les actifs entre
eux, ni les inactifs entre eux. - Distinction visuelle renforcée : les cartes inactives sont ATTÉNUÉES
(alpha 0,55) en plus du badge « inactif » — second signal demandé
(« peut-être les rendre plus distincts ») ; elles restent lisibles et
tappables (l'édition d'un traitement archivé doit rester possible). - Helper pur
treatmentsForDisplay(Kotlin + miroir web en
js/data/models.js) — 5 tests JVM (TreatmentsDisplayTest) + 4 tests
web (tests/treatments-display.test.js). - Vérifié émulateur avec données réelles seedées : les 5 actifs en haut,
en-tête puis les 2 inactifs (EV-old, EEn-old) tout en bas.
Vérifié : 264 tests JVM (230 sans données locales) + 14 tests UI +
lint verts ; web 184 tests + E2E verts (check.sh).Downloads
- Demande : « les traitements inactifs sont peu discernables par rapport
-
v1.10.1 Stable
released this
2026-09-28 21:49:06 +02:00 | 8 commits to main since this releaseAmélioré — durcissement du système de rappels (revue de code post-v1.10.0)
launchMode="singleTop"sur MainActivity : un tap sur la notification
quand l'app est DÉJÀ ouverte délivre désormaisonNewIntent(dialog de
saisie ouvert, extras traités) sans détruire/recréer l'activité —
l'ancien combostandard+CLEAR_TOPrecréait tout et rendait le chemin
onNewIntentde la v1.10.0 inopérant (code mort).- Instant PLANIFIÉ dans l'alarme (
EXTRA_PLANNED_AT) : le garde
« créneau déjà honoré » (v1.10.0) évaluait le jour au moment du FEU — une
alarme inexacte (setWindow) ou retardée (Doze) glissant après minuit
évaluait le mauvais jour (23:58 → 00:02). L'instant planifié voyage
désormais dans l'intent de l'alarme, le snooze le FORWARDE tel quel, et
le garde évalue toujours le jour du CRÉNEAU. Vérifié sur émulateur par
broadcast avecplanned_atdaté d'hier → notification correctement
sautée. BootReceiverconsolidé (dette §20.bis #2) :goAsync+ coroutine IO
(pattern ReminderReceiver) — remplace leThread+ doublerunBlocking
de la v1.0 ; une seule lecture séquentielle des DAO,finish()garanti.- Audit doc : comptes de tests périmés corrigés (§14 note #64, §16.ter).
Vérifié : 259 tests JVM + 14 tests UI + lint verts ; scénarios émulateur
(singleTop + planned_at). Web non concerné (aucune logique miroir touchée).Downloads
-
v1.10.0 Stable
released this
2026-09-27 23:11:04 +02:00 | 11 commits to main since this releaseCorrigé — la recommandation de prise de sang précédait la stabilisation (#68)
- Remontée : « la recommandation suggère une date antérieure à la
stabilisation des taux » (données réelles de la remontée → 6ᵉ régression
épingléelocal-test-data/backup-v1.9.8.json, gitigné). - Cause (double) : le « creux » était le minimum de la fenêtre entière
(créneau N−1 → créneau N). Pour un ester à montée lente (EEn : pic ~J+5 ≈
intervalle 7 j), ce minimum tombe juste après l'injection PRÉCÉDENTE
(creux d'absorption, ~3 h) — pas juste avant la suivante : la date proposée
était gouvernée par l'injection N−1, elle-même antérieure à la
stabilisation, et le texte « juste avant ton injection du … » était faux de
plusieurs jours. Balayage sur ±60 jours denow(test) : creux 5 oct 02:32
vs stabilisation 7 oct 04:03. - Fix : le creux = niveau PRÉ-INJECTION du créneau (dernier point de
courbe avant l'injection) — restaure le principe v1.8.0 documenté (« juste
avant l'injection suivante, le moment le plus comparable »), rend la carte
cohérente (creux 46 min avant le créneau étiqueté) et le garde de
stabilisation s'exprime sur l'instant réellement proposé. Pour les esters à
t½ courte (EV), le point pré-injection EST le minimum de fenêtre :
comportement inchangé. Miroir web appliqué (js/pk/lab-timing.js). - Tests : régression n°6 data-driven (4 tests dont un balayage de
nowsur
±60 j — l'invariant « creux ≥ stabilisation » doit tenir À TOUT INSTANT) ;
les 17 LabTimingTest passent inchangés (leur sémantique était celle du fix).
Corrigé — le dialog de dose se rouvrait à chaque retour sur l'accueil (#69)
- Remontée : tap sur la notification de rappel → le dialog de saisie
s'ouvre ; le fermer puis changer d'onglet et revenir sur l'accueil le
ROUVRAIT à chaque fois (reproduit et revérifié sur émulateur). - Cause : la demande vivait au niveau ACTIVITÉ (paramètre d'intent) mais
la consommation vivait dans unLaunchedEffectde Home — quitter l'onglet
détruit lesrememberlocaux, le paramètre survivait → à chaque
ré-entrée en composition, le dialog se rouvrait. - Fix : la demande est un état
MutableState<Long?>détenu par
MainActivity (survit aux onglets), consommé UNE fois par HomeScreen ;
les extras sont retirés de l'intent après lecture (un recreate ne doit
jamais rouvrir une notification traitée) ; et un tap notification quand
l'app est déjà ouverte ouvre désormais aussi le dialog (avant :
silencieusement perdu). - Tests : nouveau test UI instrumenté
LogDoseRequestTest(ouverture 1× +
plus jamais après aller-retour d'onglets) + vérification émulateur.
Ajouté — la notification de rappel saute un créneau déjà honoré
- Demande : si la dose prévue du jour est saisie AVANT l'heure de
rappel, la notification ne doit pas sonner pour une prise déjà faite ; le
rappel suivant repart au créneau suivant (idem pour le quotidien des
oraux sans Posologie). - Implémentation : garde au moment du déclenchement —
PharmacokineticEngine.hasDoseLoggedOnDay(pur, jour calendaire LOCAL,
testable) consultée parReminderReceiver: dose loguée aujourd'hui →
notification sautée (AppLog) + re-programmation du créneau suivant dans
tous les cas. Robuste quel que soit le moment de la saisie. - Tests : 6 tests JVM (
ReminderLoggedDayTest: même jour, veille,
frontière minuit, autre traitement, liste vide, mélange) + vérification
A/B sur émulateur (EEn dose-loguée-ce-jour → 0 notif ; Fluoxetine sans
dose → 1 notif).
Vérifié : 259 tests unitaires (dont régression n°6 sur données réelles)
- 14 tests UI + lint vert ; web miroir : 180 tests + E2E verts
(check.sh). Version web alignée au moment de la release (checklist 4.bis).
Downloads
- Remontée : « la recommandation suggère une date antérieure à la
-
v1.9.8 Stable
released this
2026-09-22 22:39:46 +02:00 | 14 commits to main since this releaseAjouté — tests UI Compose, signature release dédiée, README anglais
- 13 tests UI instrumentés (navigation 5 onglets, dialog « Nouveautés »
— épinglage du fix v1.3.2 « ne réapparaît pas après dismiss » —, sections
Paramètres, version installée = BuildConfig : le bug #46 « versions jamais
bumpées » ne peut plus revenir silencieusement). Déterministes : permission
de notifications pré-grantée, zéro dépendance aux données, indépendants de
la langue FR/EN. Exécution :./gradlew connectedDebugAndroidTest. - Signature release dédiée, prête à l'emploi :
scripts/make-release-keystore.sh
crée le keystore +keystore.properties(gitignorés) ;assembleRelease
l'utilise dès qu'il existe (sinon clé debug inchangée). Migration
téléphone documentée (export JSON → désinstallation → réinstallation →
réimport). Aucun changement pour l'utilisatrice tant que la bascule n'est
pas faite. - README anglais (README.en.md) — lien FR/EN en tête de
chaque fichier ; la doc de développement reste en français.
Modifié — écran Paramètres découpé (maintenance)
SettingsScreen.kt(840 lignes) devient un orchestrateur de 377 lignes +
11 cartes thématiques dansui/screens/settings/(langue, calibration,
modèle T, seuils, fuseau, rappels, sauvegarde, auto-backup, logs, à propos).
Comportement et rendu strictement identiques (déplacement pur) ;
validé par les tests UI + smoke test RELEASE sur émulateur (toutes les
sections, version 1.9.8, 0 crash — anti-bug #64).ChartScreenreste volontairement entier : sa garde de source (#54)
exige le bloc de gestes dans ce fichier.
Vérifié : 249 tests unitaires + 13 tests UI verts, lint vert, APK debug +
release (2,7 Mo) buildés, smoke test release complet (accueil, 5 onglets,
Paramètres, éditeur de traitement, dialog de dose — 0 crash).Downloads
- 13 tests UI instrumentés (navigation 5 onglets, dialog « Nouveautés »
-
v1.9.7 Stable
released this
2026-09-21 22:19:46 +02:00 | 15 commits to main since this releaseCorrigé — la suggestion de prise de sang « change tout le temps » à chaque injection
- Remontée : « la suggestion de prochain test sanguin change tout le
temps à chaque injection si l'injection n'est pas faite pile à la même
heure ou si elle est faite 30 minutes plus tard que la précédente ». - Cause : la règle de stabilisation v1.8.1 comparait l'écart inter-doses
EXACTEMENT à l'écart précédent (au ms près) — un log à 12:30 au lieu
de 12:00 cassait le régime, repoussant la stabilisation de 5 × t½ à
CHAQUE injection : le creux recommandé fuyait vers l'avant sans jamais
se fixer. - Fix (tolérance) : chaque écart doit rester dans l'intervalle de
Posologie ± 24 h (GAP_TOLERANCE_MS— « je m'injecte le même jour, à
l'heure près »). La fenêtre se réfère à l'INTERVALLE THÉORIQUE, pas à
l'écart précédent : des logs à 6,8 j puis 7,2 j ne se déstabilisent plus
en cascade. Un vrai changement de créneau (2 j au lieu de 7 j) reste
hors fenêtre et réinitialise, comme avant. Le créneau affiché se cale
toujours sur la dernière dose réelle (voulu). - Tests : le test v1.8.1 « interval change » ré-épinglé (NOW+21 j) + 2
nouveaux (flou d'heure ± 23 h → PAS de reset ; écart 25 h → reset).
249 tests verts + lint. Web miroir v1.9.7 (12 tests lab-timing).
Downloads
- Remontée : « la suggestion de prochain test sanguin change tout le
-
v1.9.6 Stable
released this
2026-09-21 21:56:32 +02:00 | 16 commits to main since this releaseModifié — la carte de l'Accueil liste TOUTES les prochaines prises
- Remontée : « si une injection et une prise d'un autre médicament ont
lieu en même temps… le rappel ne montre que la prise qui vient, non
toutes les prises du jour » — avec une prise quotidienne (CPA), le
rappel de l'injection hebdomadaire (EEn) « n'arrive qu'après celui de la
CPA, du coup je ne le vois quasiment pas ». - Fix : la carte « Prochaine dose » devient « Prochaines doses »
(titre pluriel dès 2 lignes) — une ligne par traitement, TRIÉES par
prochaine prise ; la 1ʳᵉ ligne (la plus proche) reste mise en avant.
Format de ligne inchangé (Xj Yh · ven. 25 10:00 (nom),XhMM · HH:mm,
N min). Le CPA se lit désormais AU-DESSUS de l'EEn du samedi, jamais à
sa place. - Les NOTIFICATIONS de rappel sont inchangées (une alarme par traitement
— le problème était purement l'affichage de l'Accueil). - Moteur : helper PUR
nextDoseLine(HomeScreen.kt, locale/zone
paramétrables, template jours localisé) — 3 tests (NextDoseLineTest).
247 tests verts + lint.
Downloads
- Remontée : « si une injection et une prise d'un autre médicament ont
-
v1.9.5 Stable
released this
2026-09-20 12:56:15 +02:00 | 17 commits to main since this releaseCorrigé — revue de code post-v1.9.4 (audit lecture-seule des deux dépôts)
- #67 — les ticks X ignoraient le fuseau choisi :
drawXLabelsformatait
les labels DANS le fuseau choisi mais appelaitxLabelTicksSANS le
passer — les ticks étaient alignés sur le fuseau de l'appareil (heures
décalées dès que les deux divergent, contredisant le fix #55). Fix :
zone passée + pas avancé par Calendar (un+24 hfixe dérivait d'1 h
aux transitions DST) ; test DST épinglé (Europe/Paris, 29/03/2026). EstrannaiseCloud.compute: paramètrenowMsmort supprimé (jamais
lu — le KDoc prétendait une sémantique que le code n'avait pas) ;
appelants + tests mis à jour.
Amélioré — perf (suite de l'optimisation v1.8.2)
- Contexte moteur pré-calculé (
E2Context+prepareE2Context) : le
tracé labs appellee2Atpar point de grille (720 pts) — chaque appel
reconstruisait les maps internes (groupBy/cutoffs/Bateman), diluant
l'optimisation v1.8.2. Préparé UNE fois par courbe labs ET par
calibration par ester ; résultat bit-identique (244 tests verts). - Canvas : Paints texte MÉMOÏSÉS par (couleur, taille, align, gras)
(une alloc par extremum/label × frame → une par clé) ;detectExtrema
mémoïsé par série (scan O(n) par frame → par changement de séries) ;
formatters X/marqueurs mémoïsés (SimpleDateFormat par frame → par
fuseau).
Documenté — commentaires et docs rattrapés après les refontes
- Commentaires à jour avec le code :
PKPresets.kt(l'ODS n'existe plus
au runtime),Treatment.kt(ESE analytique 6 esters),
LabTimingTest.kt(t½ analytique), doc §7.2/§7.3 (asset historique,
cutoff = 10 × t½ depuis v1.9.0). - Règle anti-#59 ré-appliquée : labels de modèle via
modelLabelRes(le
wheninline de l'éditeur violait la règle) ; literals « ESE »/« TFS »/
« WHS » remplacés parPKModels.*(ChartScreen/CurveChart) ;
scheduler2supprimé (le scheduler de l'écran existe déjà).
Downloads
- #67 — les ticks X ignoraient le fuseau choisi :
-
v1.9.4 Stable
released this
2026-09-19 23:30:23 +02:00 | 18 commits to main since this releaseAjouté — les presets du modèle ESE couvrent ses 6 esters injectables
- Remontée : depuis l'ajout du modèle source Estrannaise (v1.9.0), les
presets de création n'offraient toujours que EV/EU/EEn — « les presets
n'ont pas été mis à jour lors de l'ajout du modèle source pour ESE ». - Presets (
PKPresets.kt, 25 entrées) : 3 presets ESE ajoutés au
même niveau que les autres — EC huile (5 mg IM), EB (1 mg IM), EUCS
undécylate suspension cristalline (10 mg SC, ester exclusif à ce fit).
Champs Bateman informatifs = t½ terminales des fits (pas utilisés au
calcul — le dispatch passe par la forme close). - Éditeur (
TreatmentEditorScreen.kt) : la liste des esters suit la
couverture RÉELLE du modèle choisi (Esters.choicesForModel— même
liste que l'override du DoseDialog) : ESE liste ses 6 esters
injectables directement à la création. Au changement de modèle, si
l'ester courant sort de la couverture (ex. EUCS + TFS), il rebascule
sur EV — garde anti « 0 pg/mL ». - Tests :
PKPresetsTest(nouveau, 6 tests — miroir
tests/presets.test.jsweb) : couverture des 6 esters ESE, unicité,
TFS (7) / WHSAH (6) inchangés, garde « aucun preset injectable hors
couverture de son modèle », plausibilité des t½ informatives.
243 tests verts + lint. - Doc : doublon de la section §7.12 supprimé (collé deux fois).
Downloads
- Remontée : depuis l'ajout du modèle source Estrannaise (v1.9.0), les