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.
91 lines
4.0 KiB
Markdown
91 lines
4.0 KiB
Markdown
# 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).
|