Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | import { prisma } from './db'; import { cached, cacheInvalidatePattern } from './cache'; /** * Master-editable system constants. Stored as a singleton row (id="default") * in `SystemConfig`. Falls back to typed defaults if the row doesn't exist * yet — first update via `setSystemConfig()` creates it. * * Values here drive UI + server-side validation; never inline a literal * constant for any field listed here. */ export type SystemConfig = { refundDailyBudgetTHB: number; refundPerItemCapTHB: number; }; const DEFAULTS: SystemConfig = { refundDailyBudgetTHB: 1000, refundPerItemCapTHB: 1000, }; const TTL = 300; const KEY = 'config:system'; export function getSystemConfig() { return cached<SystemConfig>( KEY, async () => { const row = await prisma.systemConfig.findUnique({ where: { id: 'default' } }); if (!row) return DEFAULTS; return { refundDailyBudgetTHB: Number(row.refundDailyBudgetTHB), refundPerItemCapTHB: Number(row.refundPerItemCapTHB), }; }, { ttlSeconds: TTL }, ); } export async function setSystemConfig(input: Partial<SystemConfig>) { const data: { refundDailyBudgetTHB?: number; refundPerItemCapTHB?: number } = {}; if (input.refundDailyBudgetTHB != null) data.refundDailyBudgetTHB = input.refundDailyBudgetTHB; if (input.refundPerItemCapTHB != null) data.refundPerItemCapTHB = input.refundPerItemCapTHB; await prisma.systemConfig.upsert({ where: { id: 'default' }, update: data, create: { id: 'default', ...DEFAULTS, ...data }, }); // Both the config itself AND every dashboard/claim stat using refundBudget become stale. await cacheInvalidatePattern('config:*'); await cacheInvalidatePattern('stats:*'); } |