Docs : audit de complétude pour reprise par session sans contexte

- §8 : 56 tests, V120FeaturesTest (10) incluant calibration T par ester
- §14 : bugs 25-31 (calibration par période, lab T en unité aberrante,
  commentaires imbriqués dans les KDoc, XML de test périmés, idempotence
  du scrub d'historique, préfixe « v » des releases) + leçons (f)(g)(h)
- §20 : état des faits / reste à faire mis à jour
- §21 : checklist des features v1.2.x
- README : arbre (scripts/, CHANGELOG, local-test-data gitignoré)
This commit is contained in:
Siphonight 2026-09-05 19:49:44 +02:00
parent 80d49244d5
commit 54bd236506

View File

@ -309,7 +309,7 @@ Type de retour : `LevelPoint(timestamp, e2, t)`.
## 8. Tests unitaires
**54 tests JVM, tous verts** (`./gradlew testDebugUnitTest`). Dépendance : JUnit 4.13.2.
**56 tests JVM, tous verts** (`./gradlew testDebugUnitTest`). Dépendance : JUnit 4.13.2.
Emplacement : `app/src/test/java/com/hormonetrack/`. Répertoire de travail d'exécution =
`app/` → l'asset est lu via `src/main/assets/pk_profiles.json` (fallback `app/src/…`).
@ -331,7 +331,7 @@ Emplacement : `app/src/test/java/com/hormonetrack/`. Répertoire de travail d'ex
labs antérieurs à la 1ʳᵉ dose ignorés par la calibration SF, conversion ng/dL→ng/mL,
calibration T avec labs en ng/dL. **En cas de nouveau bug remonté par l'utilisatrice :
exporter le JSON, l'épingler ici, reproduire, corriger.**
- **`V120FeaturesTest`** (8) : v1.2.0/v1.2.1 — doses prévisionnelles (rythme 7 j depuis la
- **`V120FeaturesTest`** (10) : v1.2.0→v1.2.3 — doses prévisionnelles (rythme 7 j depuis la
dernière dose réelle, liste exacte J+4/J+11/J+18/J+25 ; vide sans intervalle ou sans
doses ; ester override projeté), override de modèle (ESE ≠ TFS à 45 h pour EV ;
sans override = modèle du traitement), auto-calibration v1.2.1 (facteur **par ester**
@ -559,10 +559,48 @@ Historique complet — **à ne pas réintroduire** (utile pour diff/revert) :
`LogDoseDialog` supprimé (attention : `formatDose` vivait dedans → déplacée
top-level dans `DoseDialog.kt`).
**Session v1.2.1/v1.2.2 (remontées utilisateur) :**
25. **Calibration mélangeant les périodes d'ester** — le fond du « 250–375 » :
un facteur unique par traitement comparait des labs valerate à des prédictions
enanthate → ratios aberrants → courbes gonflées. → calibration **par période**
(`computeEsterScaleFactors` + `scalePerEster`, cf §7.6) ; vérifié que l'état
d'équilibre EEn (accumulation ×2) est CORRECT — le « 375 » = calcul non calibré.
26. **Lab T en unité aberrante (« 38 pg/mL », faute de frappe)** : renvoyé brut il
écrasait l'axe T et rendait la courbe T invisible. → `convertTToNgMl` avec
branche défensive pg/mL ÷1000 (et µg/L).
27. **Pas d'édition des labs** → LabDialog create/edit + tap sur la ligne ;
formatLabValue (préserve les décimales, contrairement à formatDose).
**Session v1.2.3/push Gitea :**
28. **Commentaires Kotlin imbriqués** : `/**TFS**` dans un KDoc ouvre un bloc
`/**` JAMAIS fermé (Kotlin les imbrique !) → « Unclosed comment » → NE PAS
mettre `/**` dans un texte de doc ; écrire « EEn + TFS ».
29. **XML de test périmés après échec de compilation** : quand compile échoue,
les anciens XML test-results restent → on « corrige » des échecs fantômes.
Toujours vérifier que la COMPILATION passe (grep `^e:` du log) avant
d'analyser les résultats de tests.
30. **filter-branch non idempotent** : le scrub (45.0→44.0) a corrompu une
constante d'un test PUR écrit après coup (assert 0.45 vs 44/100). Règle :
les remplacements d'anonymisation doivent être idempotents (les valeurs de
remplacement ne re-matchent jamais les motifs) et les tests purs doivent
utiliser des constantes hors des motifs de scrub.
31. **Release script : préfixe « v »** — le tag git = `v1.2.3`, la CHANGELOG
titre `[1.2.3]` : l'extraction cherchait `[vX.Y.Z]` → fallback silencieux.
→ `scripts/gitea-release.py` (corps = section CHANGELOG, APK attaché).
**Leçons** : (a) ne jamais croire un build « probablement bon » sans l'avoir lancé ;
(b) les tests sémantiques attrapent ce que la compilation ne voit pas ; (c) se méfier des
constantes stdlib « de mémoire » (`ln2`), des mélanges Float/Double, et des APIs M3
expérimentales sans `@OptIn` ; (d) **un test de régression sur les VRAIES données
utilisateur** attrape les bugs de convention (casse, unités) que les tests
synthétiques ratent — mais garde ces données **hors du dépôt** (§8.bis) ;
(e) attention aux identifiants « presque pareils » entre sources (constantes app
vs clés d'asset) ; (f) après un échec de COMPILATION, jeter les résultats de tests
de la même passe (XML périmés) ; (g) tout script de réécriture d'historique doit
être idempotent ; (h) dans un KDoc, `/**` imbrique. (a) ne jamais croire un build « probablement bon » sans l'avoir lancé ;
(b) les tests sémantiques attrapent ce que la compilation ne voit pas ; (c) se méfier des
constantes stdlib « de mémoire » (`ln2`), des mélanges Float/Double, et des APIs M3
expérimentales sans `@OptIn` ; (d) **un test de régression sur les VRAIES données
utilisateur** (`RegressionUserCaseTest` = export JSON réel) attrape les bugs de
convention (casse, unités) que les tests synthétiques ratent ; (e) attention aux
identifiants « presque pareils » entre sources (constantes app vs clés d'asset).
@ -700,9 +738,16 @@ Volontaires (v1) :
2. **Émulateur local** pour smoke-tests UI (sur demande, ~2–3 Go)
3. Mode « planifier les injections » (schedule récurrent → pré-remplir le log)
4. Import JSON : mode **replace** (wipe + insert) + détection de doublons
5. Migration Room v2 (retirer fallbackToDestructiveMigration)
6. Verrou biométrique (BiometricPrompt), widget, export CSV
7. Charts : zoom/pan + tooltip au toucher
5. Verrou biométrique (BiometricPrompt), widget, export CSV
6. Charts : **zoom** + tooltip au toucher (le pan est fait, v1.2.0) ;
MaterialExpressiveTheme quand l'API passera publique (cf §3)
7. Release workflow : version signée (release build) au lieu de debug APK
Fait (à ne pas refaire) : pan du chart (v1.2.0), pics/creux (v1.2.3),
prévision par fréquence (v1.2.0), calibration par période d'ester E2 **et** T
(v1.2.1/v1.2.3), édition doses (v1.1.0) et labs (v1.2.2), E2+T en une entrée
(v1.2.2), migration Room v1→v2 sans fallback destructif (v1.2.0), dépôt Gitea
+ releases APK (push session).
8. Phase 2 montre : watchface `.hwt` custom, puis mini-app Lite Wearable (cf §17)
9. Retirer WorkManager ou l'utiliser (reschedule de sécurité quotidien)
@ -724,6 +769,16 @@ Sur le téléphone de test (à compléter par l'utilisatrice) :
- [ ] Redémarrer le téléphone → rappel reprogrammé (BootReceiver)
- [ ] Désactiver un rappel → plus de notif (cancel — cf §14.3)
- [ ] Tester l'installation d'une watchface `.hwt` via Gadgetbridge (pour la Phase 2)
- [ ] **v1.2.x** : graphique panoramique (glisser → passé, bouton « Revenir à maintenant »)
- [ ] **v1.2.x** : toggles Estrannaise/TFS indépendants (les deux courbes superposées)
- [ ] **v1.2.x** : chip « Prévision » (configurer la Fréquence d'un traitement d'abord)
- [ ] **v1.2.x** : chip « Pics / creux » (triangles ▲▼ aux extrema E2 et T)
- [ ] **v1.2.x** : Calibration automatique ON → courbes ajustées depuis les labs
(par période d'ester si changement d'ester), OFF → valeurs stockées
- [ ] **v1.2.x** : tap sur le mini-chart de l'accueil → écran Graphiques
- [ ] **v1.2.x** : édition d'une dose (tap ligne Doses) et d'un lab (tap ligne
Analyses → sélecteur E2/T si paire) ; suppression par prise entière
- [ ] **v1.2.x** : prise de sang E2 + T en une entrée (champs optionnels)
---
*Doc mise à jour le 5 sept. 2026 (v1.2.3) — build OK, 56/56 tests verts (44 sans les données locales), dépôt Gitea privé + releases APK, aucune donnée de santé dans le dépôt ni l'historique.*