import { Injectable } from '@nestjs/common'; import { PrismaService } from '../../common/prisma.service'; export const CONFIG_KEYS = { SEAT_HOLD_DURATION_MINUTES: 'seat_hold_duration_minutes', HOLD_CUTOFF_HOURS_BEFORE_DEPARTURE: 'hold_cutoff_hours_before_departure', BOARDING_WINDOW_HOURS_BEFORE_DEPARTURE: 'boarding_window_hours_before_departure', THROTTLE_AUTH_LIMIT: 'throttle_auth_limit', THROTTLE_AUTH_TTL_MS: 'throttle_auth_ttl_ms', THROTTLE_STRICT_LIMIT: 'throttle_strict_limit', THROTTLE_STRICT_TTL_MS: 'throttle_strict_ttl_ms', THROTTLE_DEFAULT_LIMIT: 'throttle_default_limit', THROTTLE_DEFAULT_TTL_MS: 'throttle_default_ttl_ms', } as const; const DEFAULTS: Record = { [CONFIG_KEYS.SEAT_HOLD_DURATION_MINUTES]: '5', [CONFIG_KEYS.HOLD_CUTOFF_HOURS_BEFORE_DEPARTURE]: '2', [CONFIG_KEYS.BOARDING_WINDOW_HOURS_BEFORE_DEPARTURE]: '4', [CONFIG_KEYS.THROTTLE_AUTH_LIMIT]: '5', [CONFIG_KEYS.THROTTLE_AUTH_TTL_MS]: '60000', [CONFIG_KEYS.THROTTLE_STRICT_LIMIT]: '20', [CONFIG_KEYS.THROTTLE_STRICT_TTL_MS]: '60000', [CONFIG_KEYS.THROTTLE_DEFAULT_LIMIT]: '100', [CONFIG_KEYS.THROTTLE_DEFAULT_TTL_MS]: '60000', }; @Injectable() export class SystemConfigService { constructor(private prisma: PrismaService) {} async getAll(): Promise> { const rows = await this.prisma.systemConfig.findMany(); const result: Record = { ...DEFAULTS }; for (const row of rows) result[row.key] = row.value; return result; } async getValue(key: string): Promise { const row = await this.prisma.systemConfig.findUnique({ where: { key } }); return row?.value ?? DEFAULTS[key] ?? ''; } async getNumber(key: string): Promise { return parseInt(await this.getValue(key), 10) || parseInt(DEFAULTS[key] ?? '0', 10); } async set(key: string, value: string): Promise { await this.prisma.systemConfig.upsert({ where: { key }, update: { value }, create: { key, value }, }); } async updateMany(entries: Record): Promise> { await Promise.all(Object.entries(entries).map(([k, v]) => this.set(k, v))); return this.getAll(); } }