diff --git a/README.md b/README.md index ab10e91..bd13f1a 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,29 @@ # Météo Exam Le calendrier des évaluations scolaires, traduit en bulletin météorologique interactif. -Application Android (Capacitor) + API Node.js. +Application Android (Capacitor) + PWA iOS + API Node.js. ## Structure ``` meteo-exam/ -├── shared/ Types + correspondance type d'éval ↔ météo -├── server/ API Express + SQLite (classes, évaluations, SSE) +├── shared/ Types, métadonnées météo, APP_VERSION +├── server/ API Express + SQLite (classes, évaluations, config, SSE) +│ └── releases/ APK à distribuer (latest.apk) — non versionné ├── web/ Front Vite + TypeScript (compilé dans Capacitor) │ └── android/ Projet Capacitor Android +├── scripts/ Scripts utilitaires (gen-icons.mjs) └── design/prototype/meteo-exam-reference.html Prototype visuel d'origine ``` ## Démarrage rapide -### 1. Installer les dépendances - ```bash cd meteo-exam npm install -``` - -### 2. Lancer le serveur - -```bash -# Base de démonstration (Terminale S2, code d'invitation TERMS2) -npm run seed - -# Serveur API (port 8787) -npm run dev:server -``` - -### 3. Lancer le front en développement - -```bash -npm run dev:web -# → http://localhost:5173 -``` - -### 4. Builder l'APK Android - -```bash -cd web -npx cap sync android -cd android -./gradlew assembleDebug -# → android/app/build/outputs/apk/debug/app-debug.apk +npm run seed # Classe de démo Terminale S2 (code TERMS2) +npm run dev:server # API sur 8787 +npm run dev:web # Front dev sur 5173 (optionnel) ``` ## Comptes de démonstration @@ -57,37 +33,102 @@ cd android | Admin | Terminale S2 | `TERMS2` | `Thomas S.` | | Élève | Terminale S2 | `TERMS2` | n'importe quel | -L'admin peut ajouter / modifier / supprimer les évaluations. -Les élèves consultent et reçoivent les mises à jour en temps réel (SSE). +## Configuration admin -## Configuration +L'admin de la classe peut modifier **tout le contenu affiché** : -### Serveur +- **Évaluations** : ajouter / modifier / supprimer (onglet Météo) +- **Météo par jour** : forcer un statut (soleil, brouillard, vent, orage, tempête) — tapez un jour sur la frise +- **Flash info** : message quotidien visible par toute la classe (onglet Plus → Configuration admin) +- **Nom et niveau de la classe** (onglet Plus → Configuration admin) -| Variable | Défaut | Description | -|----------|--------|-------------| -| `PORT` | `8787` | Port d'écoute de l'API | -| `METEO_DB` | `server/data/meteo-exam.db` | Chemin du fichier SQLite | -| `METEO_ORIGINS` | `*` | Origines CORS autorisées (séparez par une virgule) | +Toutes les modifications se synchronisent instantanément sur les app des autres membres via SSE. -### App Android +## Mise à jour de l'app Android (in-app) -Dans l'onglet **Plus** de l'app, l'adresse du serveur est configurable. -Sur l'émulateur Android, utilisez `http://10.0.2.2:8787` (l'hôte de la machine). -Sur un téléphone physique, utilisez l'IP locale de la machine qui tourne le serveur. +Les utilisateurs n'ont **pas** à désinstaller l'app. Au démarrage, elle vérifie la version du serveur et propose la mise à jour si une version plus récente existe. L'APK s'installe par-dessus l'ancienne (données et session conservées). + +### Publier une mise à jour + +```bash +# 1. Incrémenter APP_VERSION dans shared/src/index.ts +# export const APP_VERSION = '0.4.0' + +# 2. Builder l'APK +cd meteo-exam/web +npx vite build +npx cap sync android +cd android && ./gradlew assembleDebug + +# 3. Copier l'APK sur le serveur +cp android/app/build/outputs/apk/debug/app-debug.apk \ + ../server/releases/latest.apk + +# 4. Redémarrer le serveur +cd ../server && npm run dev +``` + +Dès que le serveur tourne, les apps Android voient la nouvelle version au prochain démarrage. + +### Points clés + +| Élément | Où | +|---------|-----| +| Version de l'app | `shared/src/index.ts` → `APP_VERSION` | +| APK à distribuer | `server/releases/latest.apk` | +| Endpoint version | `GET /api/version` → `{ version, apkUrl, apkSize, notes }` | +| Téléchargement APK | `GET /download/latest.apk` | +| Vérification côté app | `web/src/update.ts` → `checkForUpdate()` | +| Modale de mise à jour | `web/src/update-modal.ts` | + +La mise à jour ne concerne que **Android natif**. Sur iOS/PWA, il suffit de recharger la page (Safari → actualiser). + +## Accès externe (depuis une autre ville) + +### Option 1 : Tailscale Funnel (recommandé) + +```bash +sudo tailscale set --operator=$USER # une seule fois +tailscale funnel --bg --https=443 http://127.0.0.1:8787 +``` + +URL publique : `https://gameurpro12-deputy-p60i.tail951d2f.ts.net` +(marche de n'importe où avec internet, HTTPS inclus) + +### Option 2 : Réseau local + +```bash +sudo ufw allow 8787/tcp +``` + +Adresse : `http://:8787` (ex. `http://192.168.1.28:8787`) +(même Wi-Fi uniquement) + +## PWA iOS + +Sur iPhone/iPad, Safari → ouvrir l'URL du serveur → **Partager** → **Sur l'écran d'accueil**. L'app s'installe avec icône, plein écran et fonctionne hors ligne (service worker). ## API | Méthode | Route | Accès | Description | |---------|-------|-------|-------------| -| `POST` | `/api/classes` | public | Créer une classe → `{ token, code, member, klass }` | +| `GET` | `/api/health` | public | Statut du serveur | +| `GET` | `/api/version` | public | Version + URL APK | +| `GET` | `/download/latest.apk` | public | Téléchargement de l'APK | +| `POST` | `/api/classes` | public | Créer une classe | | `POST` | `/api/classes/join` | public | Rejoindre via un code | | `GET` | `/api/classes/me` | membre | Session courante | | `GET` | `/api/exams?from&to` | membre | Liste des évaluations | | `POST` | `/api/exams` | admin | Ajouter une évaluation | | `PATCH` | `/api/exams/:id` | admin | Modifier | | `DELETE` | `/api/exams/:id` | admin | Supprimer | -| `GET` | `/api/stream` | membre | Flux SSE (ping + exam.created/updated/deleted) | +| `GET` | `/api/stream` | membre | Flux SSE temps réel | +| `GET` | `/api/config/day-weather` | membre | Overrides météo | +| `PUT` | `/api/config/day-weather` | admin | Forcer la météo d'un jour | +| `DELETE` | `/api/config/day-weather/:key` | admin | Retirer l'override | +| `GET` | `/api/config/flash` | membre | Flash info du jour | +| `PUT` | `/api/config/flash` | admin | Publier le flash info | +| `PATCH` | `/api/config/class` | admin | Renommer la classe | Authentification : `Authorization: Bearer ` ou `?token=` (SSE uniquement). @@ -105,5 +146,4 @@ Authentification : `Authorization: Bearer ` ou `?token=` (SSE uniquement) - Radar de rumeurs (vote communautaire, seuil de conversion 65 %) - Métriques : pression atmosphérique (coefficient) + indice de vigilance 1-5 -- Flash info du jour généré automatiquement -- PWA / service worker +- Flash info généré automatiquement