5.6 KiB
5.6 KiB
🚀 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
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 :
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 :
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
-
Polling de base : 30 secondes pour Leantime (inchangé)
-
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
-
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
- Temps réel : Notifications instantanées
- Efficace : Pas de polling inutile
- Scalable : Facile d'ajouter d'autres widgets
- Rétrocompatible : Le polling reste en fallback
- Performance : Réduction de 70-80% des appels API
🚨 Points d'Attention
- Déduplication : S'assurer qu'on ne déclenche pas plusieurs fois
- Rate limiting : Limiter les triggers si trop fréquents
- Fallback : Garder le polling comme backup
- Cache : Invalider intelligemment