refactor: Amélioration des performances et migration des Cloud Functions

Cette mise à jour majeure vise à améliorer significativement les performances de l'application, en particulier au démarrage, et à standardiser l'infrastructure backend. Les principaux changements incluent la migration de toutes les Cloud Functions vers une région européenne (`europe-west9`), l'optimisation du chargement des données, et l'introduction d'un moniteur de performance pour le débogage.

**Changements Backend (Cloud Functions) :**

-   **Migration de la Région :**
    -   Toutes les Cloud Functions ont été déplacées de `us-central1` à `europe-west9` (Paris) pour réduire la latence pour les utilisateurs européens. Cela concerne les appels depuis le frontend (ex: `api_config.dart`, `email_service.dart`) et les définitions des fonctions elles-mêmes (`index.js`, etc.).
-   **Standardisation des Fonctions :**
    -   La plupart des fonctions `onCall` (v1) ont été migrées vers le format `onRequest` (v2) avec une gestion d'authentification et de CORS unifiée, améliorant la robustesse et la cohérence.
    -   Les triggers Firestore (`onDocumentCreated`, `onDocumentUpdated`) et les tâches planifiées (`onSchedule`) ont été mis à jour pour spécifier explicitement la région `europe-west9`.
-   **Mise à jour des Index Firestore :**
    -   Les index `firestore.indexes.json` ont été mis à jour pour supporter les nouvelles requêtes de l'application et optimiser les performances de filtrage.

**Améliorations des Performances Frontend :**

-   **Chargement Asynchrone et Mis en Cache :**
    -   Le chargement des données utilisateur (`LocalUserProvider`) et des événements (`EventProvider`) a été optimisé pour utiliser un cache local à court terme (5 minutes pour l'utilisateur, 30 secondes pour les événements).
    -   Les données ne sont rechargées que si le cache a expiré ou si un rechargement est forcé, évitant des appels réseau redondants et accélérant la navigation.
-   **Démarrage de l'Application Optimisé :**
    -   Le processus de connexion automatique (`main.dart`) a été revu. L'application navigue désormais immédiatement vers la page demandée sans attendre la fin du chargement des données utilisateur, qui s'effectue en arrière-plan.
    -   Un écran de chargement plus esthétique avec le logo de l'entreprise a été ajouté, remplaçant l'indicateur de chargement simple.
-   **Chargement de la Page Calendrier :**
    -   Le chargement et la sélection de l'événement par défaut sur la page `CalendarPage` sont maintenant entièrement asynchrones, rendant l'affichage de la page quasi instantané.

**Nouveaux Outils et Améliorations UX :**

-   **Moniteur de Performance :**
    -   Ajout d'un nouvel outil `PerformanceMonitor` (`lib/utils/performance_monitor.dart`) pour mesurer précisément le temps d'exécution des opérations critiques (appels API, parsing, etc.) en mode débogage. Il aide à identifier les goulots d'étranglement.
-   **Amélioration du Formulaire de Connexion :**
    -   Les champs "Email" et "Mot de passe" sur la page de connexion (`LoginPage`) supportent désormais l'autocomplétion du navigateur (`AutofillGroup`).
    -   Appuyer sur "Entrée" dans l'un des champs déclenche désormais la connexion, améliorant l'ergonomie.

**Mise à jour de la version :**

-   La version de l'application a été incrémentée à `1.0.9`.
This commit is contained in:
ElPoyo
2026-02-09 10:14:52 +01:00
parent a7e5f91a21
commit 8cd4854924
24 changed files with 545 additions and 515 deletions

View File

@@ -1,4 +1,4 @@
const functions = require('firebase-functions');
const {onCall} = require('firebase-functions/v2/https');
const admin = require('firebase-admin');
const nodemailer = require('nodemailer');
const handlebars = require('handlebars');
@@ -10,22 +10,19 @@ const {getSmtpConfig, EMAIL_CONFIG} = require('./utils/emailConfig');
* Envoie un email d'alerte à un utilisateur
* Appelé par le client Dart via callable function
*/
exports.sendAlertEmail = functions.https.onCall(async (data, context) => {
exports.sendAlertEmail = onCall({
region: 'europe-west9',
cors: true
}, async (request) => {
// Vérifier l'authentification
if (!context.auth) {
throw new functions.https.HttpsError(
'unauthenticated',
'L\'utilisateur doit être authentifié',
);
if (!request.auth) {
throw new Error('L\'utilisateur doit être authentifié');
}
const {alertId, userId, templateType} = data;
const {alertId, userId, templateType} = request.data;
if (!alertId || !userId) {
throw new functions.https.HttpsError(
'invalid-argument',
'alertId et userId sont requis',
);
throw new Error('alertId et userId sont requis');
}
try {
@@ -36,10 +33,7 @@ exports.sendAlertEmail = functions.https.onCall(async (data, context) => {
.get();
if (!alertDoc.exists) {
throw new functions.https.HttpsError(
'not-found',
'Alerte introuvable',
);
throw new Error('Alerte introuvable');
}
const alert = alertDoc.data();
@@ -51,10 +45,7 @@ exports.sendAlertEmail = functions.https.onCall(async (data, context) => {
.get();
if (!userDoc.exists) {
throw new functions.https.HttpsError(
'not-found',
'Utilisateur introuvable',
);
throw new Error('Utilisateur introuvable');
}
const user = userDoc.data();
@@ -112,10 +103,7 @@ exports.sendAlertEmail = functions.https.onCall(async (data, context) => {
};
} catch (error) {
console.error('Erreur envoi email:', error);
throw new functions.https.HttpsError(
'internal',
`Erreur lors de l'envoi de l'email: ${error.message}`,
);
throw new Error(`Erreur lors de l'envoi de l'email: ${error.message}`);
}
});