Stabilize calendar display by refining data caching and invalidation

Fix an issue where closing an order or delivery card caused all calendar entries to disappear by implementing selective cache invalidation and adjusting cache timings.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 7c468936-2a88-4686-ac0a-84921a45222d
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/7c468936-2a88-4686-ac0a-84921a45222d/B7k6m01
This commit is contained in:
michaelschal committed 2025-08-13 20:34:02 +00:00
1 parent e32f83de1f
commit 3b46f945a4
5 files changed
+80 -70

No files matched your search

+20 -16
View File
@@ -171,14 +171,16 @@ export default function CalendarGrid({
onDateClick,
onItemClick,
}: CalendarGridProps) {
console.log('🗓️ CalendarGrid rendered with:', {
currentDate: currentDate?.toISOString(),
ordersCount: orders?.length || 0,
deliveriesCount: deliveries?.length || 0,
publicitiesCount: publicities?.length || 0,
selectedStoreId,
userGroupsCount: userGroups?.length || 0
});
if (import.meta.env.DEV) {
console.log('🗓️ CalendarGrid rendered with:', {
currentDate: currentDate?.toISOString(),
ordersCount: orders?.length || 0,
deliveriesCount: deliveries?.length || 0,
publicitiesCount: publicities?.length || 0,
selectedStoreId,
userGroupsCount: userGroups?.length || 0
});
}
const monthStart = startOfMonth(currentDate);
const monthEnd = endOfMonth(currentDate);
@@ -192,12 +194,14 @@ export default function CalendarGrid({
return [];
}
console.log('🔍 CalendarGrid getPublicitiesForDate:', {
date: dateStr,
totalPublicities: publicities.length,
selectedStoreId,
userGroups: userGroups?.length || 0
});
if (import.meta.env.DEV) {
console.log('🔍 CalendarGrid getPublicitiesForDate:', {
date: dateStr,
totalPublicities: publicities.length,
selectedStoreId,
userGroups: userGroups?.length || 0
});
}
try {
return publicities.filter(pub => {
@@ -222,7 +226,7 @@ export default function CalendarGrid({
// If no store is selected and user has no assigned groups, show only publicities with participations
if (!selectedStoreId && (!userGroups || userGroups.length === 0)) {
const hasParticipations = pub.participations && Array.isArray(pub.participations) && pub.participations.length > 0;
if (hasParticipations) {
if (hasParticipations && import.meta.env.DEV) {
console.log('📋 Publicity has participations (no store selected):', { pubNumber: pub.pubNumber, participationCount: pub.participations.length });
}
return hasParticipations;
@@ -232,7 +236,7 @@ export default function CalendarGrid({
if (selectedStoreId) {
const matches = pub.participations && Array.isArray(pub.participations) &&
pub.participations.some((pg: any) => pg?.groupId === selectedStoreId);
if (matches) {
if (matches && import.meta.env.DEV) {
console.log('🎯 Publicity matches selected store:', { pubNumber: pub.pubNumber, selectedStoreId });
}
return matches;
@@ -43,8 +43,8 @@ export default function OrderDetailModal({
title: "Succès",
description: "Commande validée avec succès",
});
// Invalidation sélective pour éviter la disparition du calendrier
queryClient.invalidateQueries({ queryKey: ['/api/orders'] });
queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] });
onClose();
},
onError: (error) => {
@@ -76,8 +76,8 @@ export default function OrderDetailModal({
title: "Succès",
description: "Livraison validée avec succès",
});
// Invalidation sélective pour éviter la disparition du calendrier
queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] });
queryClient.invalidateQueries({ queryKey: ['/api/orders'] });
onClose();
},
onError: (error) => {
@@ -103,37 +103,26 @@ export default function OrderDetailModal({
const deleteMutation = useMutation({
mutationFn: async (id: number) => {
const endpoint = isOrder ? `/api/orders/${id}` : `/api/deliveries/${id}`;
console.log(`🗑️ Deleting ${isOrder ? 'order' : 'delivery'}:`, id);
if (import.meta.env.DEV) {
console.log(`🗑️ Deleting ${isOrder ? 'order' : 'delivery'}:`, id);
}
await apiRequest(endpoint, "DELETE");
},
onSuccess: () => {
console.log(`✅ ${isOrder ? 'Order' : 'Delivery'} deleted successfully, clearing cache...`);
if (import.meta.env.DEV) {
console.log(`✅ ${isOrder ? 'Order' : 'Delivery'} deleted successfully`);
}
toast({
title: "Succès",
description: `${isOrder ? 'Commande' : 'Livraison'} supprimée avec succès`,
});
// SOLUTION PRODUCTION : Cache clearing radical pour éviter incohérences storeId
console.log('🗑️ Cache cleared, forcing page reload to maintain storeId consistency...');
// SOLUTION HYBRIDE : Invalidation sélective pour éviter perte storeId
console.log('🧹 Using selective invalidation to preserve storeId context...');
// Invalidation ciblée sans clear() pour préserver le contexte
queryClient.invalidateQueries({
predicate: (query) => {
const key = query.queryKey[0]?.toString() || '';
return key.includes('/api/orders') || key.includes('/api/deliveries');
}
});
// Force refetch pour garantir synchronisation immédiate
queryClient.refetchQueries({
predicate: (query) => {
const key = query.queryKey[0]?.toString() || '';
return key.includes('/api/orders') || key.includes('/api/deliveries');
}
});
// Invalidation sélective uniquement pour l'API concernée
if (isOrder) {
queryClient.invalidateQueries({ queryKey: ['/api/orders'] });
} else {
queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] });
}
onClose();
},
+38 -27
View File
@@ -49,12 +49,14 @@ export default function Calendar() {
}
const url = `/api/orders?${params.toString()}`;
console.log('📅 Calendar fetching orders:', {
url,
selectedStoreId,
userRole: user?.role,
params: params.toString()
});
if (import.meta.env.DEV) {
console.log('📅 Calendar fetching orders:', {
url,
selectedStoreId,
userRole: user?.role,
params: params.toString()
});
}
const response = await fetch(url, {
credentials: 'include'
@@ -65,7 +67,9 @@ export default function Calendar() {
}
const data = await response.json();
console.log('📅 Calendar orders received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items');
if (import.meta.env.DEV) {
console.log('📅 Calendar orders received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items');
}
// Protection contre les données invalides en production
if (!Array.isArray(data)) {
@@ -74,6 +78,8 @@ export default function Calendar() {
}
return data;
},
staleTime: 5 * 60 * 1000, // 5 minutes de cache pour éviter la disparition des données
gcTime: 10 * 60 * 1000, // 10 minutes en cache
});
const { data: deliveries = [], isLoading: loadingDeliveries } = useQuery({
@@ -91,12 +97,14 @@ export default function Calendar() {
}
const url = `/api/deliveries?${params.toString()}`;
console.log('📅 Calendar fetching deliveries:', {
url,
selectedStoreId,
userRole: user?.role,
params: params.toString()
});
if (import.meta.env.DEV) {
console.log('📅 Calendar fetching deliveries:', {
url,
selectedStoreId,
userRole: user?.role,
params: params.toString()
});
}
const response = await fetch(url, {
credentials: 'include'
@@ -107,7 +115,9 @@ export default function Calendar() {
}
const data = await response.json();
console.log('📅 Calendar deliveries received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items');
if (import.meta.env.DEV) {
console.log('📅 Calendar deliveries received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items');
}
// Protection contre les données invalides en production
if (!Array.isArray(data)) {
@@ -116,6 +126,8 @@ export default function Calendar() {
}
return data;
},
staleTime: 5 * 60 * 1000, // 5 minutes de cache pour éviter la disparition des données
gcTime: 10 * 60 * 1000, // 10 minutes en cache
});
// Fetch publicities for the current year
@@ -129,12 +141,14 @@ export default function Calendar() {
}
const url = `/api/publicities?${params.toString()}`;
console.log('📅 Calendar fetching publicities:', {
url,
selectedStoreId,
userRole: user?.role,
year: currentDate.getFullYear()
});
if (import.meta.env.DEV) {
console.log('📅 Calendar fetching publicities:', {
url,
selectedStoreId,
userRole: user?.role,
year: currentDate.getFullYear()
});
}
const response = await fetch(url, {
credentials: 'include'
@@ -145,7 +159,9 @@ export default function Calendar() {
}
const data = await response.json();
console.log('📅 Calendar publicities received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items');
if (import.meta.env.DEV) {
console.log('📅 Calendar publicities received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items');
}
return Array.isArray(data) ? data : [];
},
});
@@ -166,12 +182,7 @@ export default function Calendar() {
};
const handleItemClick = (item: any, type: 'order' | 'delivery') => {
// Rafraîchir les données avant d'ouvrir le modal pour s'assurer d'avoir les liaisons à jour
queryClient.invalidateQueries({ queryKey: ['/api/orders'] });
queryClient.invalidateQueries({ queryKey: ['/api/orders', selectedStoreId] });
queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] });
queryClient.invalidateQueries({ queryKey: ['/api/deliveries', selectedStoreId] });
// Ne pas invalider le cache à l'ouverture pour éviter la disparition des données
setSelectedItem({ ...item, type });
setShowOrderDetail(true);
};
+1 -1
View File
@@ -2,4 +2,4 @@
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
#HttpOnly_localhost FALSE / FALSE 1755187696 connect.sid s%3AnEg7s3fD2sLyetJTCx-VYkzZFbBkPEcf.2BsOBC1UlFIC%2BpyKgdtocMX42YO%2FZLBn1cU6UeEnIYY
#HttpOnly_localhost FALSE / FALSE 1755203512 connect.sid s%3AGm18ttGO7m1DI7WtETfDd8gMojt-FqEw.%2BP3S4uZr6aX7vk2UAaEIow8kKQlZfWMzPcKLjUHAdNI
+7 -1
View File
@@ -19,13 +19,19 @@ La plateforme fournit une gestion robuste des flux de travail de livraison avec
## Recent Changes
### 2025-08-13 - Optimisation performance production + suppression fonctionnelle
### 2025-08-13 - Optimisation performance production + correction calendrier
✅ **Résolution latence production** :
- **Problème** : Console saturée par centaines de logs "API Response" causant latence
- **Solution** : Logging conditionnel - seulement en développement pour requêtes normales
- **Production** : Seules les erreurs API sont loggées pour debugging
- **Impact** : Réduction drastique de la charge console et amélioration performances
✅ **Problème calendrier résolu** :
- **Problème** : Fermeture carte commande/livraison faisait disparaître toutes les données
- **Cause** : Invalidation aggressive du cache React Query + invalidation à l'ouverture
- **Solution** : Cache timing optimisé (5min staleTime) + invalidation sélective seulement
- **Résultat** : Calendrier stable, plus de disparition des données au jour actuel
✅ **Fonctionnalité suppression complètement opérationnelle** :
- **Cache NocoDB** : Fonction `saveInvoiceVerificationCache` ajoutée aux deux systèmes stockage
- **MemStorage** : Implémentation CRUD complète pour ordres et livraisons