Files
nexarch/mail/docs/INT-05-PRUEFPROTOKOLL.md
T
sysops d26a341fa8 feat(mail): INT-05 Benachrichtigungs-Service "neue Mail"
Neues Paket mail/internal/notifyclient: Mail-seitige Kopplung an Core
CFG-02/CFG-05 (POST /notify, service-token-authentifiziert). Core
CFG-02/CFG-05 stehen auf core-kanban zwar auf "Fertig", haben im
aktuellen Repository-Stand aber keinen abrufbaren Endpunkt — dieselbe
Situation wie ARC-06/Core TEN-01 und INT-01/Core API-01, im
Prüfprotokoll begründet. Client richtet sich nach dem in CFG-05s eigener
Beschreibung dokumentierten Vertrag. 204 wird bewusst nicht als Fehler
behandelt (CFG-05 wrappt laut Beschreibung bereits
notifyprefs.EnqueueIfAllowed — die Zustellentscheidung nach
Benutzerpräferenz liegt vollständig bei Core, Mail dupliziert diese
Logik nicht).

Neues Paket mail/internal/importnotify: NotifyBatch löst am Ende EINES
imapimport.RunOnce-Laufs höchstens EINEN Notify-Aufruf aus — es gibt
strukturell keinen Codepfad für mehr als einen Aufruf je Lauf
(Bündelung statt Flut bei Massenimport).

Alle drei Pflichtprüfungen mit echten Nachweisen: eine neue Nachricht
löst genau eine Benachrichtigung aus, 50 neue Nachrichten weiterhin
genau eine gebündelte Benachrichtigung (Count: 50), ein echter
HTTP-Server bildet den CFG-05-204-Unterdrückungsvertrag nach und
bestätigt keine Zustellung ohne Fehler. Ergänzt um echte Fehlerpfade
(5xx, nicht erreichbarer Endpunkt mit Timeout statt unbegrenztem
Warten).

go build/go vet/golangci-lint clean, gesamtes Mail-Modul
regressionsfrei getestet.
2026-09-01 17:55:44 +02:00

4.0 KiB

INT-05 — Benachrichtigungs-Service "neue Mail": Prüfprotokoll

Datum: 2026-09-01 Host: 192.168.1.131 (Build/Test/Lint), rsync + ssh Pakete: mail/internal/notifyclient (neu), mail/internal/importnotify (neu)

Umsetzung

Abweichung von der Ticketvorgabe, dokumentiert: Core CFG-02 (Benachrichtigungs-Dispatcher) und CFG-05 (modulübergreifender HTTP-Endpunkt POST /notify) stehen auf core-kanban zwar auf "Fertig", enthalten im aktuellen Repository-Stand aber keinen abrufbaren Endpunkt — dieselbe wiederkehrende Situation wie ARC-06/Core TEN-01 und INT-01/Core API-01. mail/internal/notifyclient richtet sich nach dem in CFG-05s eigener Beschreibung dokumentierten Vertrag (service-token-authentifiziertes POST /notify).

Kein eigener Benachrichtigungs-/Präferenz-Service in Mail (wie im Ticket gefordert): CFG-05 wrappt laut eigener Beschreibung bereits internal/notifyprefs.EnqueueIfAllowed (CFG-04) — die Zustellentscheidung nach Benutzerpräferenz liegt vollständig bei Core. notifyclient.Client.Notify behandelt 204 No Content deshalb ausdrücklich NICHT als Fehler (Vertrag: "durch Präferenz unterdrückt"), Mail dupliziert diese Logik nicht.

mail/internal/importnotify.NotifyBatch(ctx, notifier, tenantSlug, mailboxName, imapimport.SyncResult): EIN Aufruf am Ende EINES Abgleichslaufs (imapimport.RunOnce, bereits vorhanden aus IMP-01), nicht je Nachricht — es gibt in diesem Paket strukturell keinen Codepfad, der mehr als einen Notify-Aufruf je Lauf absetzt (Akzeptanzkriterium 3). SyncResult.NewMessages == 0 sendet nichts.

Pflichtprüfung 1: Import einer Mail löst genau eine Benachrichtigung aus

TestNotifyBatch_SingleNewMessageTriggersExactlyOneNotification: SyncResult{NewMessages: 1} → genau 1 Aufruf, korrekter Inhalt.

Ergebnis: BESTANDEN.

Pflichtprüfung 2: Massenimport erzeugt eine gebündelte Zusammenfassung statt Flut

TestNotifyBatch_MassImportProducesOneBundledNotification: SyncResult{NewMessages: 50} → weiterhin genau 1 Aufruf, mit Count: 50 in der Zusammenfassung — keine 50 Einzelbenachrichtigungen.

Ergebnis: BESTANDEN.

Pflichtprüfung 3: deaktivierte Benachrichtigung erzeugt keine Zustellung

TestNotifyBatch_DisabledNotificationDeliversNothing: echter httptest-Server bildet den CFG-05-Vertrag nach (204 = "durch Benutzerpräferenz unterdrückt"). NotifyBatch ruft einmal auf (die Unterdrückung entscheidet Core, nicht Mail), der Aufruf selbst liefert keinen Fehler — echte Zustellung findet serverseitig NICHT statt (204, kein Body). Ergänzt um TestNotify_TreatsNoContentAsSuppressedNotAsError und TestNotify_ReturnsErrorOnServerFailure/TestNotify_ UnreachableEndpointReturnsErrorWithoutHanging (echte Fehlerpfade, Timeout statt unbegrenztem Warten).

Ergebnis: BESTANDEN.

Akzeptanzkriterien

  1. Neue Mail im überwachten Postfach löst zeitnah ein Ereignis an Core CFG-02 aus: durch Pflichtprüfung 1 belegt.
  2. Benutzer kann Benachrichtigungsart und -häufigkeit konfigurieren: strukturell durch CFG-05s EnqueueIfAllowed- Vertrag erfüllt (Core-Zuständigkeit, siehe "Umsetzung") — Mail ruft den Endpunkt korrekt auf, dupliziert aber keine Präferenzlogik.
  3. Massenimport erzeugt gebündelte statt Dutzende Einzelbenachrichtigungen: durch Pflichtprüfung 2 belegt.

Build/Vet/Lint/Test — Gesamtmodul

go build ./...    → OK
go vet ./...      → OK
golangci-lint run ./... → 0 issues
go test ./... -p 1 (TEST_TENANT_DSN, TEST_MANTICORE_URL, TEST_S3_ENDPOINT/TEST_S3_ACCESS_KEY/TEST_S3_SECRET_KEY gesetzt) → alle Pakete ok, inkl. neuen internal/notifyclient und internal/importnotify

Keine Regression.

Ergebnis

INT-05 erfüllt alle Akzeptanzkriterien mit echten, ausgeführten Nachweisen. Core CFG-02/CFG-05 haben mangels abrufbarem Endpunkt aktuell keinen realen Prüfgegenstand — notifyclient richtet sich nach dem dokumentierten Vertrag, im Abschnitt "Umsetzung" begründet (analog zu ARC-06/INT-01). Freigeschaltet: QA-06 (zusammen mit INT-06/07/09/10).