import { db, eq, featureFlags, platformSettings } from "@spinza/database"; import { DAILY_REWARDS, RESCUE_CREDITS_AMOUNT, RESCUE_CREDITS_COOLDOWN_HOURS } from "@spinza/shared"; /** In-process cache of flags & settings, refreshed every 10 s. */ let flags = new Map(); let settings = new Map(); let loadedAt = 0; const TTL = 10_000; export async function refreshSettings(force = false): Promise { if (!force && Date.now() - loadedAt < TTL) return; const [f, s] = await Promise.all([db.select().from(featureFlags), db.select().from(platformSettings)]); flags = new Map(f.map((x) => [x.key, x.enabled])); settings = new Map(s.map((x) => [x.key, x.value])); loadedAt = Date.now(); } export function flag(key: string, def = true): boolean { return flags.has(key) ? (flags.get(key) as boolean) : def; } export function setting(key: string, def: T): T { return settings.has(key) ? (settings.get(key) as T) : def; } export interface MaintenanceSetting { enabled: boolean; message: string; } export const maintenance = () => setting("maintenance", { enabled: false, message: "Spinza is getting an upgrade. Your credits and progress are safe." }); export const rescueConfig = () => setting("rescue", { amount: RESCUE_CREDITS_AMOUNT, cooldownHours: RESCUE_CREDITS_COOLDOWN_HOURS, threshold: 0 }); export const dailySchedule = () => setting("dailyRewards", { schedule: DAILY_REWARDS as readonly number[] }).schedule; export const profanityWords = () => setting("profanity", { words: [] as string[] }).words; export async function setFlag(key: string, enabled: boolean): Promise { await db.insert(featureFlags).values({ key, enabled }).onConflictDoUpdate({ target: featureFlags.key, set: { enabled, updatedAt: new Date() } }); await refreshSettings(true); } export async function setSetting(key: string, value: unknown): Promise { await db.insert(platformSettings).values({ key, value }).onConflictDoUpdate({ target: platformSettings.key, set: { value, updatedAt: new Date() } }); await refreshSettings(true); } export function allFlags(): Record { return Object.fromEntries(flags); } export function allSettings(): Record { return Object.fromEntries(settings); } export { eq };