feat(phase3): import/export, sparklines, user theme overrides

- JSON import/export with conflict resolution (skip/overwrite) + admin UI
- Ping history sparklines on AppWidget and AppCard (24h, 288 points)
- Hourly cleanup job for old AppStatus records
- User theme preferences (hue, saturation, mode, background, locale)
- Settings page with ThemeCustomizer (sliders, toggles, live preview)
- Prisma migration for user preference fields
- i18n translations for all new strings (EN/RU)
This commit is contained in:
2026-03-25 00:51:01 +03:00
parent d155b3ce4a
commit c6a7de895d
30 changed files with 1633 additions and 44 deletions
+17 -2
View File
@@ -1,11 +1,13 @@
import cron from 'node-cron';
import { checkAllApps } from '$lib/server/services/healthcheckService.js';
import { checkAllApps, pruneOldStatuses } from '$lib/server/services/healthcheckService.js';
let scheduledTask: cron.ScheduledTask | null = null;
let cleanupTask: cron.ScheduledTask | null = null;
/**
* Start the healthcheck scheduler.
* Runs checkAllApps on a cron schedule (default: every 60 seconds).
* Also starts an hourly cleanup job to prune old status records.
*/
export function startScheduler(cronExpression: string = '* * * * *'): void {
if (scheduledTask) {
@@ -20,6 +22,15 @@ export function startScheduler(cronExpression: string = '* * * * *'): void {
}
});
// Cleanup job: run every hour at minute 0
cleanupTask = cron.schedule('0 * * * *', async () => {
try {
await pruneOldStatuses();
} catch {
// Swallow errors to prevent scheduler crash
}
});
// Run an initial check shortly after startup
setTimeout(() => {
checkAllApps().catch(() => {
@@ -29,11 +40,15 @@ export function startScheduler(cronExpression: string = '* * * * *'): void {
}
/**
* Stop the healthcheck scheduler.
* Stop the healthcheck scheduler and cleanup job.
*/
export function stopScheduler(): void {
if (scheduledTask) {
scheduledTask.stop();
scheduledTask = null;
}
if (cleanupTask) {
cleanupTask.stop();
cleanupTask = null;
}
}