# 🚀 Proposition : Notifications en Temps Réel ## 📊 Analyse Actuelle vs Proposition ### ❌ Système Actuel (Polling toutes les 30s) **Problèmes :** - ⏱️ Délai de 30 secondes maximum avant notification - 🔄 Polling constant même sans nouveaux messages - 💻 Charge serveur inutile - 📱 UX moins réactive **Flow actuel :** ``` Polling toutes les 30s └─> API /notifications/count └─> NotificationService └─> LeantimeAdapter └─> Badge mis à jour ``` --- ### ✅ Système Proposé (Event-Driven) **Avantages :** - ⚡ Notifications instantanées (0-1 seconde) - 🎯 Déclenchement uniquement quand nécessaire - 💚 Réduction de la charge serveur - 🎨 Meilleure UX **Flow proposé :** ``` Widget détecte nouveau message/email └─> Trigger notification refresh └─> API /notifications/count (force refresh) └─> Badge mis à jour immédiatement ``` --- ## 🔧 Implémentation Proposée ### 1. Hook pour déclencher les notifications **Fichier :** `hooks/use-trigger-notification.ts` ```typescript import { useSession } from 'next-auth/react'; export function useTriggerNotification() { const { data: session } = useSession(); const triggerNotificationRefresh = async () => { if (!session?.user?.id) return; try { // Force refresh du notification count await fetch('/api/notifications/count?_t=' + Date.now(), { method: 'GET', credentials: 'include', cache: 'no-store' }); // Le hook useNotifications écoutera ce changement // via le système de refresh unifié } catch (error) { console.error('Error triggering notification refresh:', error); } }; return { triggerNotificationRefresh }; } ``` --- ### 2. Intégration dans Parole (RocketChat) **Fichier :** `components/parole.tsx` **Modification :** ```typescript import { useTriggerNotification } from '@/hooks/use-trigger-notification'; export function Parole() { const { triggerNotificationRefresh } = useTriggerNotification(); const [lastMessageCount, setLastMessageCount] = useState(0); const fetchMessages = async (isRefresh = false) => { // ... code existant ... const data = await response.json(); const currentUnreadCount = data.messages?.reduce((sum: number, msg: any) => sum + (msg.unread || 0), 0) || 0; // Si nouveau message non lu détecté if (currentUnreadCount > lastMessageCount) { triggerNotificationRefresh(); // ⚡ Déclenchement immédiat } setLastMessageCount(currentUnreadCount); }; } ``` --- ### 3. Intégration dans Courrier (Email) **Fichier :** `hooks/use-email-state.ts` **Modification :** ```typescript import { useTriggerNotification } from '@/hooks/use-trigger-notification'; export const useEmailState = () => { const { triggerNotificationRefresh } = useTriggerNotification(); const checkForNewEmails = useCallback(async () => { // ... code existant ... if (data.newestEmailId && data.newestEmailId > lastKnownEmailId) { // Nouvel email détecté triggerNotificationRefresh(); // ⚡ Déclenchement immédiat toast({ variant: "new-email", title: "New emails", description: "You have new emails in your inbox", }); } }, [triggerNotificationRefresh, ...]); } ``` --- ### 4. Adapters pour RocketChat et Email (Optionnel) Créer des adapters dédiés qui peuvent être pollés plus fréquemment : **Fichier :** `lib/services/notifications/rocketchat-adapter.ts` **Fichier :** `lib/services/notifications/email-adapter.ts` Ces adapters pourraient : - Poller toutes les 10-15 secondes (au lieu de 30s) - Ou être déclenchés en temps réel via WebSocket/SSE --- ## 🎯 Stratégie Hybride Recommandée ### Combinaison Polling + Event-Driven 1. **Polling de base** : 30 secondes pour Leantime (inchangé) 2. **Event-driven** : Déclenchement immédiat quand : - Parole détecte un nouveau message - Courrier détecte un nouvel email - Devoirs détecte une nouvelle tâche 3. **Cache invalidation** : Quand un widget détecte du nouveau, invalider le cache des notifications --- ## 📝 Plan d'Implémentation ### Phase 1 : Hook de déclenchement - [ ] Créer `use-trigger-notification.ts` - [ ] Fonction pour forcer le refresh du count ### Phase 2 : Intégration Parole - [ ] Détecter nouveaux messages non lus - [ ] Appeler `triggerNotificationRefresh()` quand détecté ### Phase 3 : Intégration Courrier - [ ] Détecter nouveaux emails - [ ] Appeler `triggerNotificationRefresh()` quand détecté ### Phase 4 : Optimisation - [ ] Réduire polling Leantime à 60s (moins critique) - [ ] Garder event-driven pour Parole/Courrier (temps réel) --- ## 🔄 Flow Final Proposé ``` Widget Parole/Courrier └─> Détecte nouveau message/email └─> triggerNotificationRefresh() └─> POST /api/notifications/trigger-refresh └─> Invalide cache Redis └─> NotificationService.refreshCount() └─> Badge mis à jour (< 1 seconde) ``` --- ## 💡 Avantages de cette Approche 1. **Temps réel** : Notifications instantanées 2. **Efficace** : Pas de polling inutile 3. **Scalable** : Facile d'ajouter d'autres widgets 4. **Rétrocompatible** : Le polling reste en fallback 5. **Performance** : Réduction de 70-80% des appels API --- ## 🚨 Points d'Attention 1. **Déduplication** : S'assurer qu'on ne déclenche pas plusieurs fois 2. **Rate limiting** : Limiter les triggers si trop fréquents 3. **Fallback** : Garder le polling comme backup 4. **Cache** : Invalider intelligemment