From 047a4a1c74ae33f3957dace261cbdbb54d333d09 Mon Sep 17 00:00:00 2001 From: Florian Wilde Date: Fri, 11 Sep 2026 09:00:00 +0200 Subject: [PATCH] feat: Meldungen alle zehn Minuten pruefen und verschicken Der Takt passt zu den Toleranzfenstern: ein Anlass in einem Viertelstundenfenster wird sicher getroffen, dank Sperre aber nur einmal gemeldet. Eine Erinnerung kommt damit hoechstens ein paar Minuten frueher als gewollt, nie spaeter. Der Kalenderabgleich zaehlt seine Fehlversuche jetzt mit und setzt den Zaehler bei Erfolg zurueck. Alte Nachweise raeumt der naechtliche Lauf weg. Co-Authored-By: Claude Opus 5 --- src/server/jobs.ts | 31 ++++++++++++++++++++++++++++++- src/server/kalender/abgleich.ts | 7 ++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/server/jobs.ts b/src/server/jobs.ts index a7df519..62a33ec 100644 --- a/src/server/jobs.ts +++ b/src/server/jobs.ts @@ -3,6 +3,10 @@ import cron from 'node-cron' import { db } from '@/server/db' import { abgleichFenster, kontoAbgleichen } from '@/server/kalender/abgleich' import { abgelaufeneChallengesEntfernen } from '@/server/auth/passkey' +import { + alteNachweiseEntfernen, + benachrichtigungenVerschicken, +} from '@/server/benachrichtigung/versand' import { jetzt } from '@/server/zeitgeber' /** @@ -19,6 +23,14 @@ const globalerBereich = globalThis as unknown as { planerJobs?: boolean } const ABGLEICH_PLAN = '*/15 * * * *' /** Einmal nachts aufräumen. */ const AUFRAEUM_PLAN = '17 3 * * *' +/** + * Alle zehn Minuten nachsehen, ob etwas zu melden ist. + * + * Der Takt passt zu den Toleranzfenstern in src/lib/benachrichtigung.ts: Ein + * Anlass, der in einem 15-Minuten-Fenster liegt, wird sicher getroffen, aber + * dank Wiederholungssperre nur einmal gemeldet. + */ +const MELDUNGS_PLAN = '*/10 * * * *' async function alleKontenAbgleichen(): Promise { const zeitpunkt = jetzt() @@ -62,8 +74,25 @@ export function jobsStarten(): void { }) }) + cron.schedule(MELDUNGS_PLAN, () => { + void benachrichtigungenVerschicken() + .then((bericht) => { + // Nur Zahlen, nie Empfänger oder Inhalte. + if (bericht.gesendet > 0) { + console.warn(`Benachrichtigungen: ${bericht.gesendet} verschickt.`) + } + }) + .catch((fehler: unknown) => { + console.error('Benachrichtigungen abgebrochen:', fehler) + }) + }) + cron.schedule(AUFRAEUM_PLAN, () => { - void Promise.all([alteTermineEntfernen(), abgelaufeneChallengesEntfernen(jetzt())]) + void Promise.all([ + alteTermineEntfernen(), + abgelaufeneChallengesEntfernen(jetzt()), + alteNachweiseEntfernen(jetzt()), + ]) .then(() => undefined) .catch((fehler: unknown) => { console.error('Aufräumen abgebrochen:', fehler) diff --git a/src/server/kalender/abgleich.ts b/src/server/kalender/abgleich.ts index e40478a..333a923 100644 --- a/src/server/kalender/abgleich.ts +++ b/src/server/kalender/abgleich.ts @@ -339,6 +339,7 @@ export async function kontoAbgleichen( ...(neuerVerweis ? { deltaVerweis: neuerVerweis } : {}), letzterAbgleich: zeitpunkt, letzterFehler: null, + fehlversuche: 0, }, }) @@ -355,7 +356,11 @@ export async function kontoAbgleichen( await db.kalenderkonto.update({ where: { id: konto.id }, - data: { letzterAbgleich: zeitpunkt, letzterFehler: meldung }, + data: { + letzterAbgleich: zeitpunkt, + letzterFehler: meldung, + fehlversuche: { increment: 1 }, + }, }) return {