HormoneTrack-web/README.md
Siphonight 96e0627741 Docs : première release web publiée (v1.4.10, cloudyfy) + statut conteneur réel
- §10 : v1.4.10 = première release Gitea web (zip vérifié par
  téléchargement via scripts/publish-release.py, construit par git archive
  AU TAG) ; farewell en attente de la création du repo
- §10 : statut conteneur = build + run réels validés localement (colima) ;
  container-test en configuration durcie vert ; deux problèmes du premier
  test documentés (tmpfs /tmp requis en read-only, case header_json curl)
- README : lien releases + statut conteneur
2026-09-08 21:09:34 +02:00

184 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# HormoneTrack Web
> **La version navigateur d'HormoneTrack** — suivi de thérapie hormonale (THS)
> avec courbes estimées heure par heure, 100 % locale : **l'app tourne
> entièrement dans ton navigateur et tes données ne quittent jamais ta
> machine** (localStorage). Aucun compte, aucun serveur applicatif, aucune
> télémétrie.
>
> C'est le portage fidèle de l'**app Android** — les sauvegardes JSON sont
> **interchangeables dans les deux sens**. L'app Android vit dans son propre
> dépôt : [gitea.cloudyfy.fr/Siphonight/HormoneTrack](https://gitea.cloudyfy.fr/Siphonight/HormoneTrack)
> (README, docs et releases APK).
> La doc de développement : [docs/DEVELOPPEMENT.md](docs/DEVELOPPEMENT.md).
> **⚠️ 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** : web v1.4.10 — portage de l'Android v1.4.10 · **121 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)
(zip de déploiement statique vérifié par téléchargement)
- **Versionnage** : les versions web sont **alignées sur l'Android porté**
(web v1.4.10 = toutes les fonctionnalités de l'Android v1.4.10, sauf les
impossibilités structurelles du navigateur) — cf
[docs/DEVELOPPEMENT.md §3](docs/DEVELOPPEMENT.md).
---
## Démarrage rapide
### Avec le serveur de développement intégré
```bash
cd web
python3 scripts/serve.py # → http://127.0.0.1:8970/
```
Ouvre **http://127.0.0.1:8970/** dans ton navigateur. C'est tout.
- **Mode démo** (données de test, hook documenté) :
<http://127.0.0.1:8970/?demo=1> — charge 12 injections + 6 prises de sang
fictives si le stockage est vide, avec une bannière explicite.
- ⚠️ L'app doit être servie en HTTP : l'ouverture directe du `index.html`
en `file://` est bloquée par les navigateurs (modules ES).
### Avec n'importe quel serveur statique
Le dépôt est un site statique autonome — déploie-le tel quel
(nginx, caddy, Pages Gitea/GitLab, un NAS…) :
```bash
# nginx (extrait)
server {
root /var/www/hormonetrack; # = le contenu de ce dépôt
index index.html;
}
```
### Avec Docker (self-host NAS/VPS)
L'image ne fait **que servir les fichiers** : aucune donnée dedans, la vie
privée est identique (les données vivent dans les navigateurs). Build et
exécution :
```bash
docker compose up -d # build + run → http://<hôte>:8080/
docker compose up -d --build # rebuild après mise à jour du dépôt
```
- Image **non privilégiée** (`nginx-unprivileged`, utilisateur 101, port
8080), filesystem en **lecture seule** (composé prêt pour le NAS),
healthcheck intégré, gzip sur l'asset PK (550 Ko → ~150 Ko).
- Headers `no-cache` : une mise à jour d'image est prise en compte au
rechargement suivant, sans code périmé chez les clients.
- Validation en 3 commandes sur l'hôte qui a Docker (cf
[docs/DEVELOPPEMENT.md §10](docs/DEVELOPPEMENT.md)) : build, run, puis
`HRT_E2E_BASE=http://127.0.0.1:8080 node scripts/e2e.mjs` — le même test
E2E que le CI pilote le site SERVI PAR LE CONTENEUR.
Aucun build, aucune variable d'environnement, aucun composant serveur : les
données de chaque personne vivent **dans SON navigateur**, jamais sur la
machine qui sert les fichiers.
## Fonctionnalités (à l'image de l'app Android)
- **Courbes estimées heure par heure** : E2 (pg/mL) et T (ng/mL), vues
24 h / 7 j / 30 j, **zoom** (pinch, molette, boutons − / +, 6 h → 300 j,
échantillonnage adaptatif), **panoramique** (glisser droite = passé,
gauche = futur avec la prévision), **pics & creux** avec valeurs estimées.
- **Trois modèles PK superposables** : **Estrannaise** (tables du `.ods`),
**Transfem Science** (méta-analyse V3C, 7 esters), **WHSAH** (fit Mona,
6 esters) — toggles indépendants, calibrés séparément.
- **Modèle Bateman** paramétrable pour gel, patch et voie orale.
- **Simulation prévisionnelle** (Posologie) : projection des doses à venir,
extension de fenêtre sans saut, horizon jusqu'à 1 an, marqueurs de doses.
- **Log des doses** avec override d'ester par injection, édition, Δ jours
entre doses, temps sous THS.
- **Analyses de sang** E2 + T en une entrée, unités T multiples
(ng/mL, ng/dL, ng/L, nmol/L).
- **Calibration** par période d'ester et **par modèle affiché**
(auto-calibration optionnelle, désactivée par défaut + bouton manuel).
- **Seuils d'alerte** configurables (E2/T haut/bas) avec notification
navigateur et anti-spam.
- **Rappels** via les notifications du navigateur (actions « Loguer
maintenant » / « Reporter 1 h ») — tant que la page est ouverte, cf
[limites](#limites-vs-lapp-android).
- **Sauvegarde/Restauration JSON** compatible Android (import en mode
écrasement, réglages transportés).
- **Logs de diagnostic** exportables (Paramètres) pour le debug à distance.
- **FR + EN** (langue par app, indépendante du système), dialog
« Nouveautés » après mise à jour.
## Vie privée
- **100 % local** : les données (traitements, doses, analyses, réglages)
vivent dans le **localStorage de ton navigateur**, sur TA machine. Le
serveur qui sert l'app ne voit rien, ne stocke rien.
- Les seules requêtes réseau sont des **lectures** de fichiers statiques
(l'asset des profils PK, le changelog) — aucune donnée personnelle
n'est jamais envoyée.
- Sauvegarde = un fichier JSON que tu stockes où tu veux.
- `?demo=1` charge des données FICTIVES clairement banniérées, jamais
automatiquement.
## Compatibilité avec l'app Android
| Flux | Support |
|---|---|
| Export Android → import web | ✅ (backups v1 et v2 — testés sur de vrais exports) |
| Export web → import Android | ✅ (même schéma BackupData v2, champs Gson identiques) |
| Modèles PK / courbes | ✅ mêmes maths, mêmes paramètres, mêmes pins de tests |
| Calibrations (facteurs, k) | ✅ recalculées identiquement depuis les labs |
Le schéma de backup est verrouillé par des tests des deux côtés
(`tests/backup.test.js` ↔ `BackupGsonTest.kt` Android) — toute divergence
métadonnée↔code ferait échouer la CI.
## Limites vs l'app Android
| Fonctionnalité | Android | Web |
|---|---|---|
| Rappels app fermée | ✅ (AlarmManager) | ❌ page ouverte uniquement (pas de scheduler système) |
| Événements d'agenda récurrents | ✅ | ❌ impossible dans un navigateur (pas de CalendarProvider) |
| Montre (Gadgetbridge) | ✅ notifications miroir | ❌ |
| Verrou biométrique / widget | roadmap | ❌ |
Ces limites sont structurelles (plateforme navigateur), pas des choix de
design — elles sont listées dans le dialog « Nouveautés » et la doc de dev.
## FAQ
**Mes données sont-elles visibles par le serveur qui héberge l'app ?**
Non. Le serveur ne fait que distribuer des fichiers statiques (comme des
images). Tes données vivent dans ton navigateur et n'en sortent jamais.
**Je change de navigateur / d'ordinateur, je fais quoi ?**
Paramètres → « Exporter JSON » sur la première machine, « Importer JSON »
sur la seconde. Le backup transporte tout (données + réglages).
**Puis-je utiliser Android et web en parallèle ?**
Oui — exporte/importe entre les deux. Attention : l'import est un
écrasement (comme sur Android), pas une fusion.
**Pourquoi l'app me demande-t-elle la permission « Notifications » ?**
Pour les rappels de dose. Refuser n'empêche rien d'autre (la bannière
in-app s'affiche quand même à l'heure du rappel, page ouverte).
## Doc de développement
Architecture, portage fichier par fichier, format du backup, processus de
test (121 tests Node + E2E navigateur), processus de push et pièges connus :
**[docs/DEVELOPPEMENT.md](docs/DEVELOPPEMENT.md)**.
## Licence
**GPL-3.0** — voir [LICENSE](LICENSE), cohérente avec l'app Android
et l'écosystème Gadgetbridge. Les modèles PK appartiennent à leurs autrices
respectives ([Estrannaise](https://estrannaise.github.io/),
[Transfem Science](https://transfemscience.org),
[WHSAH Collective via Mona](https://github.com/mona-hrt/mona)).