import { cache } from './redis'; // API Response caching export const apiCache = { // Generate cache key based on query parameters generateProjectsKey(params: Record = {}) { const { page = '1', limit = '50', category, featured, published, difficulty, search } = params; const keyParts = ['api:projects']; if (page !== '1') keyParts.push(`page:${page}`); if (limit !== '50') keyParts.push(`limit:${limit}`); if (category) keyParts.push(`cat:${category}`); if (featured !== null) keyParts.push(`feat:${featured}`); if (published !== null) keyParts.push(`pub:${published}`); if (difficulty) keyParts.push(`diff:${difficulty}`); if (search) keyParts.push(`search:${search}`); return keyParts.join(':'); }, async getProjects(params: Record = {}) { const key = this.generateProjectsKey(params); return await cache.get(key); }, async setProjects(params: Record = {}, projects: unknown, ttlSeconds = 300) { const key = this.generateProjectsKey(params); return await cache.set(key, projects, ttlSeconds); }, async getProject(id: number) { return await cache.get(`api:project:${id}`); }, async setProject(id: number, project: unknown, ttlSeconds = 300) { return await cache.set(`api:project:${id}`, project, ttlSeconds); }, async invalidateProject(id: number) { await cache.del(`api:project:${id}`); // Invalidate all project list caches await this.invalidateAllProjectLists(); }, async invalidateAllProjectLists() { // Clear all project list caches by pattern // This is a simplified approach - in production you'd use Redis SCAN const commonKeys = [ 'api:projects', 'api:projects:pub:true', 'api:projects:feat:true:pub:true:limit:6', 'api:projects:page:1:limit:50', 'api:projects:pub:true:page:1:limit:50' ]; for (const key of commonKeys) { await cache.del(key); } }, async invalidateAll() { await this.invalidateAllProjectLists(); // Clear all project caches const keys = await this.getAllProjectKeys(); for (const key of keys) { await cache.del(key); } }, async getAllProjectKeys() { // This would need to be implemented with Redis SCAN // For now, we'll use a simple approach return []; } }; // Performance metrics caching export const performanceCache = { async getMetrics(url: string) { return await cache.get(`perf:${url}`); }, async setMetrics(url: string, metrics: unknown, ttlSeconds = 600) { return await cache.set(`perf:${url}`, metrics, ttlSeconds); }, async getWebVitals() { return await cache.get('perf:webvitals'); }, async setWebVitals(vitals: unknown, ttlSeconds = 300) { return await cache.set('perf:webvitals', vitals, ttlSeconds); } }; // User session caching export const userCache = { async getSession(sessionId: string) { return await cache.get(`user:session:${sessionId}`); }, async setSession(sessionId: string, data: unknown, ttlSeconds = 86400) { return await cache.set(`user:session:${sessionId}`, data, ttlSeconds); }, async deleteSession(sessionId: string) { return await cache.del(`user:session:${sessionId}`); }, async getUserPreferences(userId: string) { return await cache.get(`user:prefs:${userId}`); }, async setUserPreferences(userId: string, prefs: unknown, ttlSeconds = 86400) { return await cache.set(`user:prefs:${userId}`, prefs, ttlSeconds); } };