feat(260929-if2): Erinnerungen anlegen und zur Faelligkeit benachrichtigen (Tracer)

- Reminder-Tabelle mit Zeilenschutz (Mandant+Benutzer, Systemlesen fuer den E-Mail-Planer), API reminders (Liste, Anlegen)
- Kachel "Erinnerungen", globaler Melder im Portalrahmen (Browser und Desktop, je Faelligkeit einmal)
- Desktop: Laufzeit-Berechtigung fuer Benachrichtigungen nur fuer die gespeicherte Server-Adresse
- Zugriffsklassifikation nachgemessen

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-29 13:54:07 +02:00
parent cd1f8f6cda
commit 325c5ddbf2
31 changed files with 1969 additions and 11 deletions
+25
View File
@@ -54,6 +54,7 @@ model User {
groupMemberships GroupMembership[]
moduleGrants ModuleGrant[]
customModules CustomModule[]
reminders Reminder[]
@@index([tenantId])
@@index([username])
@@ -739,3 +740,27 @@ model CustomModule {
@@index([tenantId])
@@index([tenantId, ownerUserId])
}
// quick-260929-if2: persoenliche Erinnerungen, einmalig (D-01). Eine Zeile
// gehoert genau einem Benutzer (D-05); fuer fremde Kennungen antwortet die API
// mit 404. "Erledigt" loescht die Zeile (E-02), es gibt keine Historie.
// emailSentAt/emailAttempts sind die Rechenspur des E-Mail-Planers (Anspruch
// vor dem Senden, hoechstens 3 Versuche); ein Verschieben (dueAt) setzt beide
// zurueck, damit die E-Mail erneut verschickt wird (D-03).
model Reminder {
id String @id @default(uuid())
tenantId String
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
title String
description String @default("")
dueAt DateTime
emailEnabled Boolean @default(false)
emailSentAt DateTime?
emailAttempts Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([tenantId, userId, dueAt])
@@index([dueAt])
}