diff --git a/PLAN_OPTIMISATION_PERFORMANCES.md b/PLAN_OPTIMISATION_PERFORMANCES.md index d61d802..4802a95 100644 --- a/PLAN_OPTIMISATION_PERFORMANCES.md +++ b/PLAN_OPTIMISATION_PERFORMANCES.md @@ -110,11 +110,11 @@ size: "1000"; // Récupère TOUS les livres d'un coup ### Phase 3 : Optimisation des Préférences -- [ ] **3.1 Cacher les préférences utilisateur** +- [x] **3.1 Cacher les préférences utilisateur** - - Créer `PreferencesService.getCachedPreferences()` - - TTL court (1 minute) - - Invalidation manuelle lors des modifications + - Utiliser `ServerCacheService.getOrSet()` dans `getPreferences()` + - TTL : 5 minutes (via DEFAULT) + - Invalidation automatique lors des modifications dans `updatePreferences()` - [ ] **3.2 Réduire les appels DB** - Grouper les appels de config Komga + préférences diff --git a/src/lib/services/preferences.service.ts b/src/lib/services/preferences.service.ts index 9bb6a3e..99738b4 100644 --- a/src/lib/services/preferences.service.ts +++ b/src/lib/services/preferences.service.ts @@ -10,6 +10,7 @@ import type { import { defaultPreferences } from "@/types/preferences"; import type { User } from "@/types/komga"; import type { Prisma } from "@prisma/client"; +import { getServerCacheService } from "./server-cache.service"; export class PreferencesService { static async getCurrentUser(): Promise { @@ -20,7 +21,11 @@ export class PreferencesService { return user; } - static async getPreferences(): Promise { + /** + * Récupère les préférences depuis la DB (sans cache) + * Utilisé en interne par getCachedPreferences() + */ + private static async getPreferencesFromDB(): Promise { try { const user = await this.getCurrentUser(); const userId = parseInt(user.id, 10); @@ -57,6 +62,34 @@ export class PreferencesService { } } + /** + * Récupère les préférences avec cache (TTL: 1 minute) + * Utilise ServerCacheService pour éviter les appels DB répétés + */ + static async getPreferences(): Promise { + try { + const cacheService = await getServerCacheService(); + const cacheKey = "preferences"; + + // Utiliser getOrSet avec un fetcher qui récupère depuis la DB + // Note: getOrSet ajoute automatiquement le user.id au cacheKey + // TTL par défaut (5 min) est acceptable pour les préférences + // Elles changent rarement et 5 min est un bon compromis + const preferences = await cacheService.getOrSet( + cacheKey, + async () => this.getPreferencesFromDB(), + "DEFAULT" + ); + + return preferences; + } catch (error) { + if (error instanceof AppError) { + throw error; + } + throw new AppError(ERROR_CODES.PREFERENCES.FETCH_ERROR, {}, error); + } + } + static async updatePreferences(preferences: Partial): Promise { try { const user = await this.getCurrentUser(); @@ -95,7 +128,7 @@ export class PreferencesService { }, }); - return { + const result: UserPreferences = { showThumbnails: updatedPreferences.showThumbnails, cacheMode: updatedPreferences.cacheMode as "memory" | "file", showOnlyUnread: updatedPreferences.showOnlyUnread, @@ -106,6 +139,17 @@ export class PreferencesService { circuitBreakerConfig: updatedPreferences.circuitBreakerConfig as unknown as CircuitBreakerConfig, }; + + // Invalider le cache des préférences après mise à jour + try { + const cacheService = await getServerCacheService(); + await cacheService.delete("preferences"); + } catch (cacheError) { + // Ne pas faire échouer la mise à jour si l'invalidation du cache échoue + // Les préférences seront rechargées au prochain appel + } + + return result; } catch (error) { if (error instanceof AppError) { throw error;