api-server/src/modules/config/config.service.ts
WangDL 8d52214dd5
Some checks failed
Deploy API Server / build-and-deploy (push) Has been cancelled
feat: M0-03 Config & Feature Flag — DB-backed config + Redis cache + Admin AAPI
2026-05-22 22:36:32 +08:00

49 lines
2.1 KiB
TypeScript

import { Injectable, Logger } from '@nestjs/common';
import { PrismaService } from '../../infrastructure/database/prisma.service';
import { RedisService } from '../../infrastructure/redis/redis.service';
const CACHE_PREFIX = 'config:';
const CACHE_TTL = 60; // seconds
@Injectable()
export class AppConfigService {
private readonly logger = new Logger(ConfigService.name);
constructor(
private readonly prisma: PrismaService,
private readonly redis: RedisService,
) {}
async get(key: string, defaultValue?: string): Promise<string | null> {
try {
const cached = await this.redis.get(CACHE_PREFIX + key);
if (cached) return cached;
} catch {}
const config = await this.prisma.appConfig.findUnique({ where: { key } });
if (config) {
try { await this.redis.set(CACHE_PREFIX + key, config.value, CACHE_TTL); } catch {}
return config.value;
}
return defaultValue ?? null;
}
async set(key: string, value: string, updatedBy?: string): Promise<void> {
const existing = await this.prisma.appConfig.findUnique({ where: { key } });
if (existing) {
await this.prisma.appConfig.update({ where: { key }, data: { value, updatedBy } });
if (existing.value !== value) {
await this.prisma.configChangeLog.create({ data: { entityType: 'AppConfig', entityId: existing.id, field: 'value', oldValue: existing.value, newValue: value, changedBy: updatedBy } });
}
} else {
const created = await this.prisma.appConfig.create({ data: { key, value, updatedBy } });
await this.prisma.configChangeLog.create({ data: { entityType: 'AppConfig', entityId: created.id, field: 'value', newValue: value, changedBy: updatedBy } });
}
try { await this.redis.set(CACHE_PREFIX + key, value, CACHE_TTL); } catch {}
}
async getAll() { return this.prisma.appConfig.findMany({ orderBy: { key: 'asc' } }) }
async delete(key: string) { await this.prisma.appConfig.delete({ where: { key } }); try { await this.redis.del(CACHE_PREFIX + key) } catch {} }
async getChangeLogs(limit = 50) { return this.prisma.configChangeLog.findMany({ orderBy: { createdAt: 'desc' }, take: limit }) }
}