Docs + process (web v1.6.0) : CHANGELOG, doc §4/§8/§11, garde de parité check.sh §3.bis

- check.sh : NOUVELLE étape 3.bis — garde de PARITÉ du portage
  Android↔web (si le dépôt Android voisin existe) : les symboles clés
  des features partagées (moteur prolongation, chip, avertissement)
  sont vérifiés des DEUX côtés — attrape un portage incomplet.
- Doc : arbre §4, suite lab-trajectory-model (§8), scénario E2E (§8),
  leçons #12 étendue (LABX) et #14 (parité) (§11).
- CHANGELOG web : entrée [1.6.0] (séparé du CHANGELOG Android).
- README : statut web v1.6.0, 140 tests verts.
This commit is contained in:
Siphonight 2026-09-12 23:51:20 +02:00
parent 551d8fa29e
commit ed623b786b
4 changed files with 92 additions and 7 deletions

View File

@ -17,7 +17,7 @@
> Fie-toi toujours à tes analyses de sang et aux consignes de ton
> endocrinologue.
- **Statut** : web v1.5.0 — portage de l'Android v1.5.0 · **132 tests verts** ·
- **Statut** : web v1.6.0 — portage de l'Android v1.6.0 · **140 tests verts** ·
E2E navigateur ✅ · conteneur testé en configuration durcie ✅ · lint/i18n ✅
- **Journal des versions web** : [docs/CHANGELOG.md](docs/CHANGELOG.md)
- **Releases** : [gitea.cloudyfy.fr/Siphonight/HormoneTrack-web/releases](https://gitea.cloudyfy.fr/Siphonight/HormoneTrack-web/releases)

View File

@ -5,6 +5,33 @@
> section la plus récente EN PREMIER ; ce fichier est lu par le dialog
> « Nouveautés » de l'app web (fetch `docs/CHANGELOG.md`).
## [1.6.0] — 2026-09-12
### « Tracé labs » prolongé au-delà du dernier lab — portage de l'Android v1.6.0
- **Nouveau chip `Prolonger`** (à côté de `Tracé labs`, **off par défaut**,
désactivé tant que Tracé labs est off) : la courbe ancrée sur tes
prises de sang se PROLONGE au-delà du dernier lab — la limite v1.5.0
rendait invisible justement la période la plus récente.
- **Recette** : au-delà du dernier lab significatif, `courbe(t) = M(t) ×
ρ_dernier lab` — le modèle PK (dosages, esters injectés depuis, pics et
descentes classiques) × le ratio mesuré au dernier lab, supposé constant.
Les doses loguées APRÈS le dernier lab font repartir la courbe en pic
(override d'ester compris).
- **Horizon honnête** : la prolongation s'arrête quand le MODÈLE lui-même
s'éteint (dernière dose + cutoff moteur : 10 t½ terminales V3C/WHS, fin
de table ODS, 30 t½ Bateman) — jamais de ligne à zéro inventée.
- **Lisibilité** : partie prolongée dessinée SÉPARÉMENT (même rose,
atténué) avec sa légende dédiée + **AVERTISSEMENT visible** sous la
légende : simple simulation sans garantie de correspondre au réel,
extrapolée à partir de tes résultats de laboratoire — qui peuvent
eux-mêmes être erronés. Fie-toi à ta prochaine prise de sang.
- Garde anti-ratés inchangée (#61) : un lab hors fenêtre d'action ne
prolonge pas la courbe et n'est jamais traversé.
- Portage fidèle : `extensionHorizonEndMs`/`lastAnchorMs` (miroir du
Kotlin), 8 nouveaux tests unitaires miroirs + **scénario E2E navigateur**
(activation des chips, légende et avertissement rendus).
## [1.5.0] — 2026-09-11
### « Tracé labs » — portage de la version Android v1.5.0 (versions synchronisées)

View File

@ -163,7 +163,8 @@ HormoneTrack-web/ (dépôt séparé)
│ │ ├── transfem-science-models.js V3C méta-analyse TFS (7 esters, params
│ │ │ copiés à l'identique du Kotlin)
│ │ ├── whsah-models.js fit WHSAH de Mona (6 esters, params identiques)
│ │ ├── lab-trajectory-model.js « Tracé labs » (v1.5.0) : courbe hybride
│ │ ├── lab-trajectory-model.js « Tracé labs » (v1.5.0 + PROLONGATION
│ │ v1.6.0) : courbe hybride + extension ρ const
│ │ M(t)×ρ(t) ancrée sur les labs (miroir strict
│ │ de pk/LabTrajectoryModel.kt — garde #61,
│ │ ρ log-linéaire, fenêtre labs)
@ -243,7 +244,8 @@ HormoneTrack-web/ (dépôt séparé)
│ ├── calibration.test.js ← CalibrationPerModel/ScaleFactorWhsahRepro/
│ │ V120Features (fixes #60/#61, périodes d'ester)
│ ├── lab-trajectory-model.test.js ← LabTrajectoryModelTest.kt (v1.5.0
│ │ « Tracé labs » — passage exact, garde #61)
│ │ « Tracé labs » + v1.6.0 prolongation —
│ │ passage exact, garde #61, horizon cutoff)
│ ├── backup.test.js ← BackupGsonTest.kt + exports Android RÉELS
│ │ (local-test-data/ si présent, sinon skip)
│ ├── chart-helpers.test.js ← ChartZoomTest.kt (#53/#54/#55/#58/#62)
@ -411,7 +413,13 @@ launch) — d'où le build dédié dans le cache Playwright, hors dépôt.
pipelines — jamais de médiane contaminée), k T contre l'E2 CALIBRÉE.
- **lab-trajectory-model** : v1.5.0 « Tracé labs » — miroir du Kotlin
(passage exact, ρ log-linéaire, garde #61, fenêtres, indépendance du
scaleFactor, modelOverride, doublons, bornes).
scaleFactor, modelOverride, doublons, bornes). v1.6.0 **prolongation**
(miroir §7.10.bis Android) : identité `M × ρ_last` exacte au-delà du
dernier lab, suture exacte, horizon = cutoff du traitement
(`extensionHorizonEndMs` — gardes : pas de dose / modèle déjà éteint →
null), dose EV loguée après le dernier lab → pic de prolongation,
garde #61 sur la prolongation, flag off = v1.5.0 bit-compatible,
`lastAnchorMs`.
- **backup** : round-trip v2, rétrocompat v1, écrasement + IDs conservés,
**imports des exports Android réels** (data-driven, hors dépôt).
- **chart-helpers** : cumul fractionnaire du pan (#62), minuit local (#55),
@ -441,6 +449,12 @@ launch) — d'où le build dédié dans le cache Playwright, hors dépôt.
- vérifie le **rendu réel** : cartes, valeurs, dialog « Nouveautés »
(markdown rendu), navigation des 5 onglets + Paramètres, **pixels du
canvas** (`getImageData` — le graphique PEINT vraiment) ;
- **v1.6.0 : scénario « Tracé labs prolongé »** — dézoome (dernier lab de
la démo à now − 7 j), vérifie que `Prolonger` est DÉSACTIVÉ tant que
`Tracé labs` est off, active les deux chips, asserting la légende
ancrée, la légende prolongée et l'**AVERTISSEMENT simulation** (sans
garantie, labs potentiellement erronés) — puis désactive et vérifie
qu'ils disparaissent ;
- vérifie l'**absence d'erreur console/page** sur toute la session ;
- captures dans `/tmp/hrt-web-shots/` (inspection visuelle).
- ⚠️ Course au screenshot évitée par le marqueur `body[data-ready="1"]`
@ -681,15 +695,21 @@ Trouvés pendant l'écriture (à ne pas réintroduire) :
11. **`getSettings()` fusionne les défauts** : un stockage partiel ne doit
jamais exposer des champs `undefined` (les gardes `!== null` deviennent
fausses autrement).
12. **Miroir du fix #63 Android** (v1.5.0) : la clé `'LAB'` (Tracé labs)
dans la liste `curves` est SKIPPÉE de la boucle de légende (légende
dédiée à part) — même bug qu'Android : le `else` (TFS) imprimerait la
12. **Miroir du fix #63 Android** (v1.5.0, étendu v1.6.0) : les clés
`'LAB'` ET `'LABX'` (Tracé labs ancré / prolongé) dans la liste
`curves` sont SKIPPÉES de la boucle de légende (légendes dédiées à
part) — même bug qu'Android : le catchall (TFS) imprimerait la
légende TFS en doublon. Quand une liste clé→série reçoit une clé,
grepper chaque consommateur de la liste (légende, stats, styles).
13. **Imports ESM = noms de modules EXACTS** (v1.5.0) : `labIsSignificant`
vit dans `pk-calibration.js` (pas `pk-engine.js`) — un import du
mauvais module = SyntaxError AU CHARGEMENT, l'app entière ne démarre
pas ; attrapé par `node --check` + l'E2E « aucune erreur console ».
14. **Parité du portage** (v1.6.0) : une feature Android portée à moitié
(moteur sans UI, clés i18n sans miroir) ne casse aucun test existant —
d'où la garde `check.sh` §3.bis : quand le dépôt Android voisin
existe, les symboles clés des features partagées sont vérifiés des
DEUX côtés (moteur + chip + avertissement).
## 12. Limites connues & non-portés

View File

@ -63,6 +63,44 @@ if ! node scripts/i18n-check.mjs; then
fail=1
fi
echo "── 3.bis Garde de PARITÉ du portage Android ↔ web (soft) ──"
# v1.6.0 (leçon de la session « Prolonger ») : le web est un PORTAGE fidèle
# de l'Android — quand les deux dépôts sont côte à côte (layout standard,
# cf docs/DEVELOPPEMENT.md §3), on vérifie que les symboles CLÉS des
# dernières features partagées existent des DEUX côtés. Attrape le portage
# incomplet (ex. modèle porté mais pas l'UI, ou clés i18n Android sans
# miroir web). Soft : si le dépôt Android voisin est absent (clone web
# isolé, CI), la garde est ignorée avec un message.
ANDROID_DIR="$(dirname "$PWD")/HormoneTrack"
if [[ -d "$ANDROID_DIR" ]]; then
parity=1
check_pair() { # <desc> <fichier-android:pattern> <fichier-web:pattern>
local desc="$1" andro="$2" web="$3"
local af="${andro%%:*}" ap="${andro#*:}"
local wf="${web%%:*}" wp="${web#*:}"
if grep -qE "$ap" "$ANDROID_DIR/$af" 2>/dev/null \
&& grep -qE "$wp" "$wf" 2>/dev/null; then
echo " ✓ $desc"
else
echo "✗ PARITÉ rompue : $desc (Android: $ANDROID_DIR/$af =~ $ap ; web: $wf =~ $wp)"
parity=0
fi
}
# Le modèle de prolongation doit exister des deux côtés (v1.6.0)
check_pair "prolongation tracé labs : moteur" \
"app/src/main/java/com/hormonetrack/pk/LabTrajectoryModel.kt:extensionHorizonEndMs" \
"js/pk/lab-trajectory-model.js:extensionHorizonEndMs"
check_pair "prolongation tracé labs : UI (chip)" \
"app/src/main/res/values/strings.xml:show_lab_track_extend" \
"js/util/i18n.js:show_lab_track_extend"
check_pair "prolongation tracé labs : avertissement" \
"app/src/main/res/values/strings.xml:lab_track_extend_warning" \
"js/util/i18n.js:lab_track_extend_warning"
[[ $parity -eq 1 ]] || fail=1
else
echo " (ignoré : dépôt Android voisin absent — $ANDROID_DIR)"
fi
echo "── 4. Tests unitaires ──"
if ! node --test tests/ 2>&1 | tail -6; then
fail=1