- @capacitor/filesystem : téléchargement natif de l'APK (OkHttp) - @capawesome-team/capacitor-file-opener : ouverture de l'installateur Android - L'APK est écrit dans le cache de l'app puis ouvert via un Intent natif - Plus de passage par le navigateur — tout se passe dans l'app - file_paths.xml mis à jour pour couvrir le cache |
||
|---|---|---|
| design/prototype | ||
| scripts | ||
| server | ||
| shared | ||
| web | ||
| .gitignore | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
Météo Exam
Le calendrier des évaluations scolaires, traduit en bulletin météorologique interactif. Application Android (Capacitor) + PWA iOS + API Node.js.
Structure
meteo-exam/
├── 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
cd meteo-exam
npm install
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
| Rôle | Classe | Code | Pseudo |
|---|---|---|---|
| Admin | Terminale S2 | TERMS2 |
Thomas S. |
| Élève | Terminale S2 | TERMS2 |
n'importe quel |
Configuration admin
L'admin de la classe peut modifier tout le contenu affiché :
- É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)
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
# 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é)
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
sudo ufw allow 8787/tcp
Adresse : http://<IP-du-PC>: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 |
|---|---|---|---|
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 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 <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
- Flash info généré automatiquement