2026-10-02 19:51:13 +02:00
# Météo Exam
Le calendrier des évaluations scolaires, traduit en bulletin météorologique interactif.
2026-10-04 17:32:34 +02:00
Application Android (Capacitor) + PWA iOS + API Node.js.
2026-10-02 19:51:13 +02:00
## Structure
```
meteo-exam/
2026-10-04 17:32:34 +02:00
├── 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é
2026-10-02 19:51:13 +02:00
├── web/ Front Vite + TypeScript (compilé dans Capacitor)
│ └── android/ Projet Capacitor Android
2026-10-04 17:32:34 +02:00
├── scripts/ Scripts utilitaires (gen-icons.mjs)
2026-10-02 19:51:13 +02:00
└── design/prototype/meteo-exam-reference.html Prototype visuel d'origine
```
## Démarrage rapide
```bash
cd meteo-exam
npm install
2026-10-04 17:32:34 +02:00
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)
2026-10-02 19:51:13 +02:00
```
2026-10-04 17:32:34 +02:00
## Comptes de démonstration
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
| Rôle | Classe | Code | Pseudo |
|------|--------|------|--------|
| Admin | Terminale S2 | `TERMS2` | `Thomas S.` |
| Élève | Terminale S2 | `TERMS2` | n'importe quel |
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
## Configuration admin
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
L'admin de la classe peut modifier **tout le contenu affiché** :
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
- **É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)
Toutes les modifications se synchronisent instantanément sur les app des autres membres via SSE.
## Mise à jour de l'app Android (in-app)
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
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
2026-10-02 19:51:13 +02:00
```bash
2026-10-04 17:32:34 +02:00
# 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
2026-10-02 19:51:13 +02:00
npx cap sync android
2026-10-04 17:32:34 +02:00
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
2026-10-02 19:51:13 +02:00
```
2026-10-04 17:32:34 +02:00
Dès que le serveur tourne, les apps Android voient la nouvelle version au prochain démarrage.
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
### 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).
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
## Accès externe (depuis une autre ville)
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
### Option 1 : Tailscale Funnel (recommandé)
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
```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
```
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
Adresse : `http://<IP-du-PC>:8787` (ex. `http://192.168.1.28:8787` )
(même Wi-Fi uniquement)
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
## PWA iOS
2026-10-02 19:51:13 +02:00
2026-10-04 17:32:34 +02:00
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).
2026-10-02 19:51:13 +02:00
## API
| Méthode | Route | Accès | Description |
|---------|-------|-------|-------------|
2026-10-04 17:32:34 +02:00
| `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 |
2026-10-02 19:51:13 +02:00
| `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 |
2026-10-04 17:32:34 +02:00
| `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 |
2026-10-02 19:51:13 +02:00
Authentification : `Authorization: Bearer <token>` ou `?token=` (SSE uniquement).
## Statuts météo
| Icône | Nom | Coefficient | Signification |
|-------|-----|-------------|---------------|
| ☀️ | Grand Soleil | 0 | Aucune évaluation |
| 🌫️ | Brouillard | — | Rumeur non confirmée |
| 💨 | Coup de vent | 1 | Interro surprise, coeff faible |
| 🌩️ | Orage | 2– 3 | DS / contrôle continu |
| 🚨 | Alerte Rouge | 4+ | Examen blanc / épreuve commune |
## Phase 2 (prévu)
- Radar de rumeurs (vote communautaire, seuil de conversion 65 %)
- Métriques : pression atmosphérique (coefficient) + indice de vigilance 1-5
2026-10-04 17:32:34 +02:00
- Flash info généré automatiquement