/** * Device-Lock Auto-Release Cron * * Läuft alle 24h. Findet alle UserDevice-Rows die: * - boundToPlan gesetzt haben (Lock aktiv) * - lastSeenAt < NOW() - 30 Tage (Gerät inaktiv) * * → setzt boundToPlan + releaseRequestedAt zurück auf NULL. * * Begründung 30-Tage-Limit: schützt vor verlorenen/verkauften/defekten * Geräten ohne dass User in Customer-Support muss. Nach 30 Tagen ohne * authentifizierten API-Call ist das Gerät faktisch nicht mehr in Benutzung. * * Zusätzlich wird hier der "abgelaufene Release-Request" Lazy-Check * nicht ersetzt — der läuft in findActiveDeviceLock() inline. Dieser * Cron ist nur für den 30-Tage-Inaktivitäts-Case. */ import { consola } from "consola"; import { autoReleaseInactiveDevices } from "../db/devices"; const TWENTY_FOUR_HOURS = 24 * 60 * 60 * 1000; export default defineNitroPlugin((nitro) => { if (import.meta.dev) { consola.info("[device-lock-cron] Skipping cron in dev mode"); return; } consola.info("[device-lock-cron] Starting (24h interval)"); // Erster Lauf nach 2 Minuten (Server-Boot-Phase abwarten) const initialTimer = setTimeout(() => { runAutoRelease().catch(() => {}); }, 2 * 60 * 1000); const interval = setInterval(() => { runAutoRelease().catch(() => {}); }, TWENTY_FOUR_HOURS); nitro.hooks.hook("close", () => { clearTimeout(initialTimer); clearInterval(interval); }); }); async function runAutoRelease() { try { const released = await autoReleaseInactiveDevices(); if (released > 0) { consola.success(`[device-lock-cron] Auto-released ${released} inactive device locks (30d)`); } else { consola.info("[device-lock-cron] No inactive device locks to release"); } } catch (err: any) { consola.error("[device-lock-cron] run failed:", err?.message ?? err); } }