edtech / apps /api /src /services /normalization.ts
CognxSafeTrack
chore: stabilization, audit fixes and project synchronization
7b0c22b
raw
history blame
2.5 kB
import { prisma } from './prisma';
import Redis from 'ioredis';
import { logger } from '../logger';
const redis = process.env.REDIS_URL
? new Redis(process.env.REDIS_URL)
: new Redis({ host: process.env.REDIS_HOST || 'localhost', port: parseInt(process.env.REDIS_PORT || '6379') });
redis.on('error', (err) => logger.error({ err }, '[REDIS] Normalization service error:'));
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<Record<string, string>> {
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<string, string> = {};
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(() => {});
}
};