Le « creux » était le minimum de la fenêtre entière (créneau N−1 → N) :
pour un ester à montée lente (EEn, pic ~J+5 ≈ intervalle 7 j) il tombait
juste après l'injection PRÉCÉDENTE — date antérieure à la stabilisation
affichée sur la même carte, et « juste avant ton injection du … » faux de
plusieurs jours. Le creux est désormais le niveau PRÉ-INJECTION du créneau
(principe v1.8.0 restauré ; EV inchangé — le point pré-injection EST son
minimum de fenêtre). WEB_VERSION alignée sur 1.10.0.
180 tests + E2E verts (check.sh) ; suite lab-timing inchangée (sa
sémantique épinglée était celle du fix).
La règle de stabilisation comparait l'écart inter-doses EXACTEMENT à
l'écart précédent : un log 30 min plus tard cassait le régime et
repoussait la stabilisation de 5 × t½ à chaque injection (creux fuyant).
Fix : chaque écart doit rester dans l'intervalle de Posologie ± 24 h
(GAP_TOLERANCE_MS, fenêtre vs l'intervalle THÉORIQUE) — des logs à 6,8 j
puis 7,2 j ne se déstabilisent plus en cascade ; un vrai changement de
créneau reste hors fenêtre.
Tests : « interval change » ré-épinglé (+21 j) + 2 tests de tolérance
miroirs (12 verts lab-timing). WEB_VERSION 1.9.7 + CHANGELOG/README.
Corrigé (audit) :
- cutoffHours : garde hasModel pour ESE (parité Kotlin) — un backup
importé ESE + ester non couvert levait TypeError → écran vide
- min/max en une passe : les spreads Math.min(...allPoints) levaient
RangeError au-delà de ~1e5 arguments (Nuage × zoom max) et allouaient
par frame
- init MCMC non bloquante : data-ready garantit désormais « asset chargé »
Perf (portage v1.8.2 Android, fin de la dérive de miroir) :
- prepareE2Context/e2AtCtx : doses groupées, cutoffs précalculés, Bateman
paresseux ; computeCurve ne recalcule plus cutoffHours par point
- résultat identique (175 tests verts)
E2E : version lue via data-version (anti-bug v1.9.3)
Docs/commentaires : pk-engine (ESE analytique), pk-calibration (JSDoc
arrondi), dialogs (ESE=6), lab-timing (import mort, JSDoc orpheline),
home (COLORS), pk-profile-store (test-only), pk_profiles.json exclu du
zip (export-ignore, −548 Ko)
Le modèle ESE analytique (v1.9.0) couvre 6 esters injectables : presets
ajoutés pour EC (huile), EB et EUCS (undécylate suspension cristalline,
exclusif à ce fit) — les champs Bateman reflètent les t½ terminales des
fits (informatifs). Miroir de PKPresets.kt Android.
- estrannaise-cloud.js : le filtre des doses ne teste PLUS le pkModel
STOCKÉ du traitement — le nuage couvre toutes les doses E2 à profil
injectable dont l'ESTER EFFECTIF (override compris) est couvert par le
fit Estrannaise (identique à l'ensemble redessiné par
computeCurve(modelOverride = "ESE")). L'exclusivité ESE reste portée
par le chip ; l'oral Bateman reste hors nuage ; les traitements
inactifs sont inclus (§6.bis).
- Test réécrit : « les doses d'un traitement TFS sont couvertes quand ESE
est affiché » (épinglé des deux plateformes) ; oral seul → vide.
- WEB_VERSION 1.9.2. CHANGELOG [1.9.2], README statut.
- estrannaise-cloud.js : paramètre scalePerEster — le nuage reçoit la
MÊME calibration que la courbe ESE (autoByModel ESE). Avant : courbe ESE
calibrée mais nuage BRUT → échelles différentes (remontée v1.9.1 :
« le nuage ne s'active que autour du tracé, pas autour du modèle
Estrannaise »).
- chart.js : autoByModel.get('ESE')?.esterScales passé au nuage ;
DEFAULT_NB_CURVES importé.
- +1 test : nuage calibré ×2 = nuage brut ×2 (167 verts au total).
- CHANGELOG [1.9.1] : fix nuage calibré + HARMONISATION de l'arrondi de
la médiane de calibration (le web avait la troncature historique — les
niveaux web/android convergent ; le niveau correct = l'ARRONDI).
- WEB_VERSION 1.9.1.
- lab-timing.js : computeRegimeStartMs — le régime courant = séquence
terminale de doses à (ester effectif, dose, écart inter-doses) constants
(écart comparé EXACTEMENT) : tout changement récent de dose/ester/
posologie réinitialise la stabilisation. L'ancien proxy (1ʳᵉ dose du
traitement) disait « stabilisée depuis février » malgré des changements
récents (remontée v1.8.0). L'encart porte l'ESTER EFFECTIF de la
dernière dose (override compris).
- home.js : encart « Prochaine prise de sang (suggestion) » sur l'ACCUEIL
(demande) — creux daté + créneau associé + mention de stabilisation
seulement si le régime n'était pas déjà stable.
- 3 nouveaux tests miroirs (155 verts) : dose/intervalle/ester → reset
épinglé. WEB_VERSION 1.8.1. CHANGELOG [1.8.1], README.
- js/pk/lab-timing.js : miroir fidèle de pk/LabTiming.kt — creux prévisionnel
(minimum de la courbe E2 entre 2 injections), saut au premier creux
STABILISÉ (5 × t½ terminale : TFS/WHS analytiques, Estrannaise lue dans
la table via le nouveau pkProfileStore.terminalHalfLifeDays — refactor
de la pente d'extrapolation de sample(), zéro duplication), filtres
honnêtes (injectable actif + Posologie requis, creux ≥ now+6 h et jamais
déjà mesuré, horizon borné → null), shouldSuggestPosology (invite quand
un injectable actif est sans Posologie — demande v1.8.0).
- labs.js : encart « Prochaine prise de sang (suggestion) » ou invite,
mutuellement exclusifs (miroir carte Android).
- i18n FR/EN (labrec_*), WEB_VERSION 1.8.0, assertions E2E.
- tests/lab-timing.test.js : 7 tests miroirs (152 verts au total) + E2E
(encart rendu : titre, creux daté, créneau, stabilisation).
- Doc : §4 arbre, §8 suite + E2E, CHANGELOG [1.8.0], README.
Miroir fidèle du Kotlin (doc Android §7.10.bis) :
- extendBeyondLastLab (ρ_last constant au-delà du dernier ancre),
lastAnchorMs, extensionHorizonEndMs (dernière dose E2 + cutoff du
moteur — même sémantique d'extinction, une seule source de vérité).
- 8 nouveaux tests unitaires miroirs (140 verts au total) : identité
M×ρ_last, suture exacte, horizon cutoff, dose EV après le dernier lab,
garde #61, flag off = v1.5.0 bit-compatible, gardes du helper,
lastAnchorMs.
Miroir strict de pk/LabTrajectoryModel.kt (Android v1.5.0) :
- js/pk/lab-trajectory-model.js : courbe hybride M(t)×ρ(t) ancrée sur les
labs — passage EXACT garanti, ρ log-linéaire, garde #61 (lab hors
fenêtre d'action pas un ancrage), E2 seul, fenêtre [1er ; dernier lab],
< 2 labs → vide, indépendante de la calibration (sinon double
correction). JAMAIS dans levelAt/alertes.
- UI : chip 'Tracé labs' (off par défaut) dans la rangée modèles +
scroll horizontal CONFINÉ à la rangée (miroir du fix Android) ;
couleur #c2185b dashed ; leçon #63 Android-miroir — clé 'LAB' SKIPPÉE
de la boucle légende (sinon légende TFS dupliquée).
- 11 tests miroirs de LabTrajectoryModelTest.kt (132 verts total).
- WEB_VERSION = 1.5.0 + CHANGELOG [1.5.0] + docs (§4/§8, README).
Détail d'exécution épingle: les deux problèmes du portage ont été
attrapés par node --check/E2E avant release (imports ESM faux —
labIsSignificant vit dans pk-calibration.js, pas pk-engine.js).