All files / lib system-config.ts

0% Statements 0/55
0% Branches 0/1
0% Functions 0/1
0% Lines 0/55

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:*');
}