* feat(demo): add DEMO_MODE runtime helpers and /api/demo/info endpoint * feat(demo): enforce simulated and blocked API actions under DEMO_MODE * feat(demo): add deterministic seed dataset and 6-hour auto-reset * feat(demo-ui): add demo banner and custom sonner toasts for simulated/blocked actions * test+docs(demo): add demo mode coverage, behavior matrix, and operator docs * formatting * tests * feat(demo): seed resets from typed baseline defaults * formatting * feat(demo): enrich baseline seed data and demo project catalog * feat(demo): expand seeded applications and chart time ranges * refactor(demo): split demo seed data from generation logic * feat(demo): cap generated application history to 30 days * feat(demo): rebalance generated job status distribution * feat(demo-ui): make demo banner fixed and topmost * minor fixes * formatting * duration revert * durations * feat(demo): share demo info hook, brighten demo toasts, and enforce webhook auth * comment explaning * formatting * comments * deadline builder comment
70 lines
1.9 KiB
TypeScript
70 lines
1.9 KiB
TypeScript
import { logger } from "@infra/logger";
|
|
import {
|
|
DEMO_RESET_CADENCE_HOURS,
|
|
isDemoMode,
|
|
setDemoResetTimes,
|
|
} from "@server/config/demo";
|
|
import {
|
|
DEMO_BASELINE_NAME,
|
|
DEMO_BASELINE_VERSION,
|
|
} from "@server/config/demo-defaults";
|
|
import { applyDemoBaseline, buildDemoBaseline } from "./demo-seed";
|
|
|
|
const RESET_INTERVAL_MS = DEMO_RESET_CADENCE_HOURS * 60 * 60 * 1000;
|
|
|
|
let resetTimer: ReturnType<typeof setTimeout> | null = null;
|
|
let isResetRunning = false;
|
|
|
|
function computeNextReset(now: Date): Date {
|
|
return new Date(now.getTime() + RESET_INTERVAL_MS);
|
|
}
|
|
|
|
function scheduleNextReset(): void {
|
|
const now = new Date();
|
|
const nextReset = computeNextReset(now);
|
|
const delay = nextReset.getTime() - now.getTime();
|
|
setDemoResetTimes({ nextResetAt: nextReset.toISOString() });
|
|
|
|
if (resetTimer) clearTimeout(resetTimer);
|
|
resetTimer = setTimeout(() => {
|
|
void runDemoResetCycle();
|
|
}, delay);
|
|
}
|
|
|
|
export async function resetDemoData(): Promise<void> {
|
|
const baseline = buildDemoBaseline(new Date());
|
|
await applyDemoBaseline(baseline);
|
|
}
|
|
|
|
export async function runDemoResetCycle(): Promise<void> {
|
|
if (isResetRunning) return;
|
|
isResetRunning = true;
|
|
|
|
try {
|
|
await resetDemoData();
|
|
const nowIso = new Date().toISOString();
|
|
setDemoResetTimes({ lastResetAt: nowIso });
|
|
scheduleNextReset();
|
|
logger.info("Demo dataset reset completed", {
|
|
lastResetAt: nowIso,
|
|
baselineVersion: DEMO_BASELINE_VERSION,
|
|
});
|
|
} catch (error) {
|
|
logger.error("Failed to reset demo dataset", { error });
|
|
scheduleNextReset();
|
|
} finally {
|
|
isResetRunning = false;
|
|
}
|
|
}
|
|
|
|
export async function initializeDemoModeServices(): Promise<void> {
|
|
if (!isDemoMode()) return;
|
|
|
|
await runDemoResetCycle();
|
|
logger.info("Demo mode services initialized", {
|
|
resetCadenceHours: DEMO_RESET_CADENCE_HOURS,
|
|
baselineVersion: DEMO_BASELINE_VERSION,
|
|
baselineName: DEMO_BASELINE_NAME,
|
|
});
|
|
}
|