import { prisma } from './prisma'; import { logger } from '../logger'; import { redis } from '../lib/redis'; const CACHE_KEY = 'normalization:rules:wolof'; const CACHE_TTL = 3600; // 1 hour export const normalizationService = { /** * Get all normalization rules for a language */ async getRules(language: string = 'WOLOF'): Promise> { const cacheKey = `${CACHE_KEY}:${language}`; try { const cached = await redis.get(cacheKey); if (cached) return JSON.parse(cached); } catch (err) { logger.error({ err }, '[NORMALIZATION] Redis get error'); } const rules = await prisma.normalizationRule.findMany({ where: { language } }); const ruleMap: Record = {}; rules.forEach((r: { original: string; replacement: string }) => { ruleMap[r.original.toLowerCase()] = r.replacement; }); try { await redis.set(cacheKey, JSON.stringify(ruleMap), 'EX', CACHE_TTL); } catch (err) { logger.error({ err }, '[NORMALIZATION] Redis set error'); } return ruleMap; }, /** * Create or update a rule */ async saveRule(original: string, replacement: string, language: string = 'WOLOF') { const rule = await prisma.normalizationRule.upsert({ where: { original }, update: { replacement, language }, create: { original, replacement, language } }); // Invalidate cache await redis.del(`${CACHE_KEY}:${language}`).catch(() => {}); return rule; }, /** * Batch save rules */ async saveRules(rules: { original: string, replacement: string }[], language: string = 'WOLOF') { const operations = rules.map(r => prisma.normalizationRule.upsert({ where: { original: r.original }, update: { replacement: r.replacement, language }, create: { original: r.original, replacement: r.replacement, language } })); await Promise.all(operations); await redis.del(`${CACHE_KEY}:${language}`).catch(() => {}); } };