/** * 공통 코드 캐시 시스템 * 자주 사용되는 공통 코드들을 메모리에 캐싱하여 성능을 향상시킵니다. */ import { commonCodeApi } from "@/lib/api/commonCode"; interface CacheEntry { data: any; timestamp: number; expiry: number; } class CodeCache { private cache = new Map(); private defaultTTL = 5 * 60 * 1000; // 5분 /** * 캐시에 데이터 저장 */ set(key: string, data: any, ttl?: number): void { const expiry = ttl || this.defaultTTL; const entry: CacheEntry = { data, timestamp: Date.now(), expiry, }; this.cache.set(key, entry); } /** * 캐시에서 데이터 조회 */ get(key: string): any | null { const entry = this.cache.get(key); if (!entry) { return null; } // TTL 체크 if (Date.now() - entry.timestamp > entry.expiry) { this.cache.delete(key); return null; } return entry.data; } /** * 캐시에서 데이터 삭제 */ delete(key: string): boolean { return this.cache.delete(key); } /** * 모든 캐시 삭제 */ clear(): void { this.cache.clear(); } /** * 만료된 캐시 정리 */ cleanup(): void { const now = Date.now(); for (const [key, entry] of this.cache.entries()) { if (now - entry.timestamp > entry.expiry) { this.cache.delete(key); } } } /** * 캐시 상태 조회 */ getStats(): { size: number; keys: string[] } { return { size: this.cache.size, keys: Array.from(this.cache.keys()), }; } /** * 공통 코드 캐시 키 생성 */ createCodeKey(category: string, companyCode?: string): string { return `code:${category}:${companyCode || "*"}`; } /** * 여러 코드 카테고리를 배치로 미리 로딩 */ async preloadCodes(categories: string[]): Promise { console.log(`🔄 코드 배치 로딩 시작: ${categories.join(", ")}`); const promises = categories.map(async (category) => { try { const response = await commonCodeApi.codes.getList(category, { isActive: true }); if (response.success && response.data) { const cacheKey = this.createCodeKey(category); this.set(cacheKey, response.data, this.defaultTTL); console.log(`✅ 코드 로딩 완료: ${category} (${response.data.length}개)`); } } catch (error) { console.error(`❌ 코드 로딩 실패: ${category}`, error); } }); await Promise.all(promises); console.log(`✅ 코드 배치 로딩 완료: ${categories.length}개 카테고리`); } /** * 코드를 동기적으로 조회 (캐시에서만) */ getCodeSync(category: string, companyCode?: string): any[] | null { const cacheKey = this.createCodeKey(category, companyCode); return this.get(cacheKey); } /** * 코드를 비동기적으로 조회 (캐시 미스 시 API 호출) */ async getCodeAsync(category: string, companyCode?: string): Promise { const cached = this.getCodeSync(category, companyCode); if (cached) { return cached; } try { const response = await commonCodeApi.codes.getList(category, { isActive: true }); if (response.success && response.data) { const cacheKey = this.createCodeKey(category, companyCode); this.set(cacheKey, response.data, this.defaultTTL); return response.data; } } catch (error) { console.error(`❌ 코드 조회 실패: ${category}`, error); } return []; } } // 싱글톤 인스턴스 생성 const codeCache = new CodeCache(); // 주기적으로 만료된 캐시 정리 (10분마다) if (typeof window !== "undefined") { setInterval( () => { codeCache.cleanup(); }, 10 * 60 * 1000, ); } export default codeCache; export { CodeCache, codeCache };