fix(reminders): keine Dauermeldung ohne localStorage, Mail nach Zeitaenderung, null-Pruefung
- Merkliste zusaetzlich im Arbeitsspeicher (sonst alle 10 s dieselbe Meldung) - Aendern der Faelligkeit atomar gegen gleichzeitiges Faelligwerden, setzt Mail-Spur zurueck - UpdateReminderDto lehnt null ab (400 statt 500) - keine Mails an deaktivierte Benutzer - Spaeter erinnern beschriftet heute/morgen nach dem berechneten Zeitpunkt - Bearbeiten schickt dueAt nur bei geaenderter Zeit Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -26,7 +26,7 @@ const BATCH = 200;
|
||||
* Scheitert der Transport, gibt der Planer den Anspruch wieder frei
|
||||
* (`emailSentAt = null`), sodass der naechste Durchlauf es erneut versucht —
|
||||
* hoechstens dreimal. Fehlt beim Senden die SMTP-Einrichtung oder die Adresse
|
||||
* des Benutzers, bleibt der Anspruch: die Faelligkeit gilt als erledigt und
|
||||
* des Benutzers oder ist sein Konto deaktiviert (`isActive = false`), bleibt der Anspruch: die Faelligkeit gilt als erledigt und
|
||||
* wird nur protokolliert, es gibt keine Wiederholschleife. Ein Verschieben
|
||||
* („Spaeter erinnern“) setzt beide Felder zurueck (siehe `RemindersService`).
|
||||
*
|
||||
@@ -104,9 +104,7 @@ export class ReminderMailScheduler implements OnApplicationBootstrap {
|
||||
await this.processCandidate(candidate, now);
|
||||
} catch (err) {
|
||||
// Eine kaputte Zeile darf die uebrigen nicht anhalten.
|
||||
this.logger.error(
|
||||
`Reminder email for ${candidate.id} failed: ${(err as Error).message}`,
|
||||
);
|
||||
this.logger.error(`Reminder email for ${candidate.id} failed: ${(err as Error).message}`);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -140,14 +138,15 @@ export class ReminderMailScheduler implements OnApplicationBootstrap {
|
||||
where: { id: c.id, tenantId: c.tenantId, dueAt: c.dueAt },
|
||||
select: { title: true, description: true, dueAt: true },
|
||||
});
|
||||
// Nur aktive Konten: ein deaktivierter Benutzer gilt wie einer ohne Adresse.
|
||||
const user = await tenantPrisma.user.findFirst({
|
||||
where: { id: c.userId, tenantId: c.tenantId },
|
||||
where: { id: c.userId, tenantId: c.tenantId, isActive: true },
|
||||
select: { email: true },
|
||||
});
|
||||
const smtp = await this.settingsService.getSmtpConfig(c.tenantId);
|
||||
if (!row || !user?.email || smtp === null) {
|
||||
this.logger.log(
|
||||
`Reminder email for ${c.id} übersprungen (${!row ? 'Zeile geändert' : !user?.email ? 'keine E-Mail-Adresse' : 'kein E-Mail-Versand eingerichtet'})`,
|
||||
`Reminder email for ${c.id} übersprungen (${!row ? 'Zeile geändert' : !user ? 'Benutzer deaktiviert' : !user.email ? 'keine E-Mail-Adresse' : 'kein E-Mail-Versand eingerichtet'})`,
|
||||
);
|
||||
return; // Anspruch bleibt: gilt als erledigt, keine Wiederholschleife (E-04)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user