Cette mise à jour améliore la génération de QR codes pour les équipements et les containers en ajoutant un retour visuel à l'utilisateur et une gestion des erreurs plus robuste. **Changements :** - **Ajout d'un indicateur de chargement :** Un `CircularProgressIndicator` est désormais affiché pendant que les données des équipements ou des containers sélectionnés sont récupérées, informant l'utilisateur qu'une opération est en cours. - **Gestion des erreurs :** Un bloc `try...catch` a été ajouté autour de la logique de génération dans les pages de gestion des équipements (`EquipmentManagementPage`) et des containers (`ContainerManagementPage`). - **Affichage des erreurs :** En cas d'échec, le chargement est stoppé et une `SnackBar` rouge apparaît pour notifier l'utilisateur de l'erreur, améliorant ainsi la robustesse de la fonctionnalité.
9.2 KiB
Système de Gestion des Mises à Jour - EM2RP
📋 Vue d'ensemble
Ce système permet de gérer automatiquement les mises à jour de l'application web Flutter, en notifiant les utilisateurs et en forçant le rechargement du cache si nécessaire.
🔧 Architecture
Fichiers impliqués
Configuration
lib/config/app_version.dart: Fichier source de vérité pour la versionweb/version.json: Fichier déployé avec l'app pour vérification côté serveur
Services
lib/services/update_service.dart: Service de vérification des mises à jourlib/views/widgets/common/update_dialog.dart: Widget d'affichage du dialog de mise à jour
Scripts
scripts/increment_version.js: Incrémente automatiquement la versionscripts/update_version_json.js: Génère version.json depuis app_version.dartdeploy.bat: Script de déploiement complet
Documentation
CHANGELOG.md: Notes de version (utilisées dans le dialog)
🚀 Workflow de déploiement
1. Développement normal
Travaillez normalement sur votre code en mode développement.
2. Déploiement d'une nouvelle version
deploy.bat
Ce script exécute automatiquement :
- ✅ Bascule en mode PRODUCTION
- ✅ Incrémente la version (0.3.8 → 0.3.9)
- ✅ Incrémente le buildNumber (1 → 2)
- ✅ Génère version.json depuis app_version.dart
- ✅ Build Flutter Web
- ✅ Déploie sur Firebase Hosting
- ✅ Retour en mode DÉVELOPPEMENT
3. Mise à jour côté utilisateur
Au prochain chargement de l'app (ou après 2 secondes) :
- L'app vérifie
https://em2rp.web.app/version.json - Compare avec la version locale dans
app_version.dart - Si
buildNumber serveur > buildNumber local→ Affiche le dialog
📝 Format de version
app_version.dart
class AppVersion {
static const String version = '0.3.8'; // Version sémantique
static const int buildNumber = 1; // Numéro de build (incrémenté automatiquement)
static String get fullVersion => 'v$version';
static String get fullVersionWithBuild => 'v$version+$buildNumber';
}
version.json (déployé)
{
"version": "0.3.8",
"buildNumber": 1,
"updateUrl": "https://em2rp.web.app",
"forceUpdate": false,
"releaseNotes": "• Scanner QR Code\n• Génération QR conteneurs\n• Performance améliorée"
}
🔄 Comparaison des versions
Le système compare uniquement le buildNumber :
buildNumber serveur > buildNumber local→ Mise à jour disponible- Ignore les versions identiques même si la version sémantique change
Exemple :
- Local :
0.3.8+1 - Serveur :
0.3.9+2 - Résultat : Mise à jour proposée (2 > 1) ✅
🎨 Expérience utilisateur
Mise à jour normale (forceUpdate: false)
┌────────────────────────────────────┐
│ 🔄 Mise à jour disponible │
├────────────────────────────────────┤
│ Version actuelle : 0.3.8 (1) │
│ Nouvelle version : 0.3.9 (2) │
│ │
│ Nouveautés : │
│ • Scanner QR Code │
│ • Performance améliorée │
│ │
│ [Plus tard] [Mettre à jour] 🔄 │
└────────────────────────────────────┘
Mise à jour forcée (forceUpdate: true)
┌────────────────────────────────────┐
│ ⚠️ Mise à jour requise │
├────────────────────────────────────┤
│ Version actuelle : 0.3.8 (1) │
│ Nouvelle version : 0.3.9 (2) │
│ │
│ ⚠️ Cette mise à jour est │
│ obligatoire pour continuer │
│ │
│ [Mettre à jour] 🔄 │
└────────────────────────────────────┘
🛠️ Utilisation avancée
Forcer une mise à jour critique
Si vous déployez un correctif critique :
- Modifiez
web/version.jsonaprès le déploiement :
{
"version": "0.3.9",
"buildNumber": 2,
"forceUpdate": true, // ← Changer à true
"releaseNotes": "🔴 Correctif de sécurité important"
}
- Les utilisateurs ne pourront plus fermer le dialog jusqu'à la mise à jour
Personnaliser les notes de version
Éditez CHANGELOG.md avant le déploiement :
## [0.3.9] - 2026-01-16
### Ajouté
- Scanner QR Code pour équipements
- Génération QR pour conteneurs
### Amélioré
- Performance du dialog de sélection
- Gestion du cache
### Corrigé
- Bug de cache des équipements
Les 5 premières lignes de la section seront utilisées dans le dialog.
🧪 Tests
Test 1 : Vérification de version locale
// Dans n'importe quel fichier
import 'package:em2rp/config/app_version.dart';
print('Version: ${AppVersion.version}');
print('Build: ${AppVersion.buildNumber}');
print('Full: ${AppVersion.fullVersionWithBuild}');
Test 2 : Forcer l'affichage du dialog
Modifiez temporairement web/version.json :
{
"buildNumber": 999 // Très grand nombre
}
Rechargez l'app → Le dialog s'affiche immédiatement
Test 3 : Tester le rechargement
- Cliquez sur "Mettre à jour"
- Vérifiez que la page se recharge
- Vérifiez que le cache est vidé (nouvelles ressources chargées)
📊 Logs de debug
En mode debug, des logs sont affichés dans la console :
[UpdateService] Current version: 0.3.8+1
[UpdateService] Server version: 0.3.9+2
Si pas de mise à jour disponible, rien ne s'affiche.
🔐 Sécurité
Headers HTTP pour forcer le non-cache
Le fichier web/index.html contient :
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
Cache-busting sur version.json
Chaque requête ajoute un timestamp :
final timestamp = DateTime.now().millisecondsSinceEpoch;
Uri.parse('$versionUrl?t=$timestamp')
Garantit que la version la plus récente est toujours récupérée.
🚨 Résolution de problèmes
Problème : Le dialog ne s'affiche pas
Causes possibles :
- Le
buildNumberserveur n'est pas supérieur au local - Erreur réseau (timeout 10s)
- Le fichier
version.jsonn'existe pas sur le serveur
Solution :
# Vérifier la version déployée
curl https://em2rp.web.app/version.json
# Forcer un nouveau déploiement
deploy.bat
Problème : Le cache ne se vide pas
Causes possibles :
- Service Worker actif (ancienne version)
- Cache navigateur très persistant
Solution :
// Dans les DevTools du navigateur
navigator.serviceWorker.getRegistrations().then(registrations => {
registrations.forEach(r => r.unregister());
});
// Puis CTRL+SHIFT+R (rechargement forcé)
Problème : Le script increment_version.js échoue
Solution :
# Vérifier la syntaxe du fichier app_version.dart
# Doit contenir exactement :
static const String version = '0.3.8';
static const int buildNumber = 1;
📈 Évolution future
Fonctionnalités possibles
- Afficher un changelog complet dans le dialog
- Permettre de sauter une version (skip this version)
- Notifications push pour les mises à jour critiques
- Analytics sur le taux d'adoption des mises à jour
- Support des mises à jour en arrière-plan
Améliorations techniques
- Utiliser un CDN pour version.json
- Implémenter un rollback automatique si erreur
- Ajouter une vérification de santé post-déploiement
🎯 Commandes rapides
# Déployer une nouvelle version
deploy.bat
# Incrémenter manuellement la version
node scripts\increment_version.js
# Générer version.json manuellement
node scripts\update_version_json.js
# Vérifier la version actuelle
type lib\config\app_version.dart
# Vérifier la version déployée
curl https://em2rp.web.app/version.json
✅ Checklist de déploiement
Avant chaque déploiement :
- Tester l'application en local
- Mettre à jour
CHANGELOG.mdavec les nouveautés - Vérifier que tous les tests passent
- Exécuter
deploy.bat - Vérifier le déploiement sur https://em2rp.web.app
- Tester la mise à jour sur un navigateur propre
- Informer l'équipe de la nouvelle version
📞 Support
En cas de problème avec le système de mise à jour, vérifier :
- Les logs dans la console du navigateur
- Le fichier
version.jsondéployé - Le fichier
app_version.dartlocal - La connexion réseau de l'utilisateur
Le système est conçu pour échouer silencieusement : Si une erreur se produit, l'utilisateur peut continuer à utiliser l'app normalement sans être bloqué.