notifications
This commit is contained in:
parent
a1e4e14b30
commit
2602773980
@ -2,6 +2,7 @@ import { NextResponse } from 'next/server';
|
|||||||
import { getServerSession } from 'next-auth';
|
import { getServerSession } from 'next-auth';
|
||||||
import { authOptions } from "@/app/api/auth/options";
|
import { authOptions } from "@/app/api/auth/options";
|
||||||
import { NotificationService } from '@/lib/services/notifications/notification-service';
|
import { NotificationService } from '@/lib/services/notifications/notification-service';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
// GET /api/notifications/count
|
// GET /api/notifications/count
|
||||||
export async function GET(request: Request) {
|
export async function GET(request: Request) {
|
||||||
@ -24,9 +25,11 @@ export async function GET(request: Request) {
|
|||||||
// If force refresh, invalidate cache first
|
// If force refresh, invalidate cache first
|
||||||
if (forceRefresh) {
|
if (forceRefresh) {
|
||||||
await notificationService.invalidateCache(userId);
|
await notificationService.invalidateCache(userId);
|
||||||
|
logger.debug('[NOTIFICATIONS_COUNT_API] Cache invalidated for force refresh', { userId });
|
||||||
}
|
}
|
||||||
|
|
||||||
const counts = await notificationService.getNotificationCount(userId);
|
// Pass forceRefresh flag to bypass cache
|
||||||
|
const counts = await notificationService.getNotificationCount(userId, forceRefresh);
|
||||||
|
|
||||||
// Add Cache-Control header - rely on server-side cache, minimal client cache
|
// Add Cache-Control header - rely on server-side cache, minimal client cache
|
||||||
const response = NextResponse.json(counts);
|
const response = NextResponse.json(counts);
|
||||||
|
|||||||
@ -82,10 +82,12 @@ export function Parole() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Si nouveau message non lu détecté, déclencher notification
|
// Si nouveau message non lu détecté, déclencher notification
|
||||||
if (currentUnreadCount > lastUnreadCountRef.current) {
|
// On déclenche aussi si le count a changé (augmenté ou diminué) pour forcer le refresh
|
||||||
console.log('[Parole] ⚡ Nouveau message non lu détecté, déclenchement notification', {
|
if (currentUnreadCount !== lastUnreadCountRef.current) {
|
||||||
|
console.log('[Parole] ⚡ Unread count changed, triggering notification refresh', {
|
||||||
previous: lastUnreadCountRef.current,
|
previous: lastUnreadCountRef.current,
|
||||||
current: currentUnreadCount
|
current: currentUnreadCount,
|
||||||
|
isIncrease: currentUnreadCount > lastUnreadCountRef.current
|
||||||
});
|
});
|
||||||
triggerNotificationRefresh();
|
triggerNotificationRefresh();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -182,25 +182,31 @@ export class NotificationService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get notification counts for a user
|
* Get notification counts for a user
|
||||||
|
* @param forceRefresh If true, bypass cache and fetch fresh data
|
||||||
*/
|
*/
|
||||||
async getNotificationCount(userId: string): Promise<NotificationCount> {
|
async getNotificationCount(userId: string, forceRefresh: boolean = false): Promise<NotificationCount> {
|
||||||
logger.debug('[NOTIFICATION_SERVICE] getNotificationCount called', { userId });
|
logger.debug('[NOTIFICATION_SERVICE] getNotificationCount called', { userId, forceRefresh });
|
||||||
const redis = getRedisClient();
|
const redis = getRedisClient();
|
||||||
const cacheKey = NotificationService.NOTIFICATION_COUNT_CACHE_KEY(userId);
|
const cacheKey = NotificationService.NOTIFICATION_COUNT_CACHE_KEY(userId);
|
||||||
|
|
||||||
// Try to get from cache first
|
// If force refresh, skip cache
|
||||||
try {
|
if (!forceRefresh) {
|
||||||
const cachedData = await redis.get(cacheKey);
|
// Try to get from cache first
|
||||||
if (cachedData) {
|
try {
|
||||||
logger.debug('[NOTIFICATION_SERVICE] Using cached notification counts', { userId });
|
const cachedData = await redis.get(cacheKey);
|
||||||
|
if (cachedData) {
|
||||||
|
logger.debug('[NOTIFICATION_SERVICE] Using cached notification counts', { userId });
|
||||||
|
|
||||||
// Background refresh is now handled by unified refresh system
|
// Background refresh is now handled by unified refresh system
|
||||||
// Cache TTL is aligned with refresh interval (30s)
|
// Cache TTL is aligned with refresh interval (30s)
|
||||||
|
|
||||||
return JSON.parse(cachedData);
|
return JSON.parse(cachedData);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[NOTIFICATION_SERVICE] Error retrieving notification counts from cache:', error);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} else {
|
||||||
console.error('[NOTIFICATION_SERVICE] Error retrieving notification counts from cache:', error);
|
logger.debug('[NOTIFICATION_SERVICE] Force refresh requested, bypassing cache', { userId });
|
||||||
}
|
}
|
||||||
|
|
||||||
// No cached data, fetch counts from all adapters
|
// No cached data, fetch counts from all adapters
|
||||||
|
|||||||
@ -28,7 +28,13 @@ export class RocketChatAdapter implements NotificationAdapter {
|
|||||||
private async getUserEmail(): Promise<string | null> {
|
private async getUserEmail(): Promise<string | null> {
|
||||||
try {
|
try {
|
||||||
const session = await getServerSession(authOptions);
|
const session = await getServerSession(authOptions);
|
||||||
return session?.user?.email || null;
|
const email = session?.user?.email || null;
|
||||||
|
logger.debug('[ROCKETCHAT_ADAPTER] getUserEmail', {
|
||||||
|
hasSession: !!session,
|
||||||
|
hasEmail: !!email,
|
||||||
|
emailHash: email ? Buffer.from(email.toLowerCase()).toString('base64').slice(0, 12) : null,
|
||||||
|
});
|
||||||
|
return email;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[ROCKETCHAT_ADAPTER] Error getting user email', {
|
logger.error('[ROCKETCHAT_ADAPTER] Error getting user email', {
|
||||||
error: error instanceof Error ? error.message : String(error),
|
error: error instanceof Error ? error.message : String(error),
|
||||||
@ -65,11 +71,35 @@ export class RocketChatAdapter implements NotificationAdapter {
|
|||||||
|
|
||||||
const usersData = await usersResponse.json();
|
const usersData = await usersResponse.json();
|
||||||
if (!usersData.success || !Array.isArray(usersData.users)) {
|
if (!usersData.success || !Array.isArray(usersData.users)) {
|
||||||
|
logger.error('[ROCKETCHAT_ADAPTER] Invalid users list response', {
|
||||||
|
success: usersData.success,
|
||||||
|
hasUsers: Array.isArray(usersData.users),
|
||||||
|
});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.debug('[ROCKETCHAT_ADAPTER] Searching for user', {
|
||||||
|
username,
|
||||||
|
totalUsers: usersData.users.length,
|
||||||
|
});
|
||||||
|
|
||||||
const currentUser = usersData.users.find((u: any) => u.username === username);
|
const currentUser = usersData.users.find((u: any) => u.username === username);
|
||||||
return currentUser?._id || null;
|
|
||||||
|
if (!currentUser) {
|
||||||
|
logger.warn('[ROCKETCHAT_ADAPTER] User not found in RocketChat', {
|
||||||
|
username,
|
||||||
|
searchedIn: usersData.users.length,
|
||||||
|
availableUsernames: usersData.users.slice(0, 5).map((u: any) => u.username),
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug('[ROCKETCHAT_ADAPTER] Found user', {
|
||||||
|
username,
|
||||||
|
userId: currentUser._id,
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentUser._id;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[ROCKETCHAT_ADAPTER] Error getting RocketChat user ID', {
|
logger.error('[ROCKETCHAT_ADAPTER] Error getting RocketChat user ID', {
|
||||||
error: error instanceof Error ? error.message : String(error),
|
error: error instanceof Error ? error.message : String(error),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user