import { Injectable, Inject } from '@nestjs/common'; import { CACHE_MANAGER } from '@nestjs/cache-manager'; import { Cache } from 'cache-manager'; import { ConfigService } from '@nestjs/config'; @Injectable() export class CacheService { constructor( @Inject(CACHE_MANAGER) private cacheManager: Cache, private configService: ConfigService, ) {} async get(key: string): Promise { return this.cacheManager.get(key); } async set(key: string, value: unknown, ttl?: number): Promise { await this.cacheManager.set(key, value, ttl); } private buildKey(...parts: string[]): string { return parts.join(':'); } async getOrFetch( keyPrefix: string, keyParts: string[], fetchFn: () => Promise, ttlConfigKey: string, ): Promise<{ data: T; fromCache: boolean; cachedAt: string | null }> { const key = this.buildKey(keyPrefix, ...keyParts); const ttl = this.configService.get(`app.cache.${ttlConfigKey}`, 900); const cached = await this.get(key); if (cached !== undefined) { return { data: cached, fromCache: true, cachedAt: null }; } const data = await fetchFn(); await this.set(key, data, ttl); return { data, fromCache: false, cachedAt: new Date().toISOString() }; } }