mailrules.Store (IMP-03) bekommt Update (bislang nur Create/List/
Delete) — gleiches Muster wie Create: Musterprüfung vor dem Schreiben,
streng auf tenant_slug+id beschränkt, ErrNotFound bei fremder/nicht
existierender ID.
Neues Paket mail/internal/mailrulesapi: vier Endpunkte (GET/POST
/api/v1/mail/rules, PUT/DELETE /api/v1/mail/rules/{id}), tenant-Query-
Parameter Pflicht, gleiche Konvention wie mailapi (INT-01).
Akzeptanzkriterium 3 ist strukturell garantiert: mailrulesapi ruft
ausschließlich mailrules.Store auf, denselben Store, den IMP-03s
Import-Pfad ohnehin verwendet — kein zweiter, paralleler Schreibpfad.
Alle drei Pflichtprüfungen mit echten Nachweisen: vollständiger
Anlegen/Priorisieren/Einsehen/Löschen-Zyklus über echte HTTP-Requests;
eine über die API angelegte Regel wird über genau den Weg gelesen und
ausgewertet, den IMP-03s Import-Pfad geht (Store.List ->
mailrules.NewEngine -> Evaluate) und liefert das korrekte
Klassifizierungsergebnis; Mandant Bs Update-Versuch mit der echten,
bekannten ID von Mandant As Regel liefert 404, Mandant As Regel bleibt
unverändert.
go build/go vet/golangci-lint clean, gesamtes Mail-Modul
regressionsfrei getestet — bestehende mailrules-Tests (IMP-03/IMP-09)
bleiben nach der Update-Erweiterung unverändert grün.
Testsuite für Import-Scheduler, Anhangsverarbeitung und Regelwerk,
inklusive Tenant-Scoping und nicht-konformer Server.
- tenant_scoping_test.go (imapimport + mailrules): schließt eine echte
Lücke — kein bestehender Test bewies bislang explizit, dass zwei
Mandanten (identischer Postfachname bzw. fehlende eigene Regel) sich
nicht gegenseitig beeinflussen.
- importtestgate/gate.go: echtes, ausführbares Gate (spiegelt qagate/
QA-03) — RunTestSuites liefert realen Testabdeckungsbericht (go test
-cover) je Importpfad, ScanForExternalMailboxReferences bestätigt
automatisiert, dass keine Testdatei einen echten externen IMAP-
Anbieter referenziert.
- Echten Bug beim eigenen Testlauf gefunden und behoben: die
t.Cleanup-Löschfilter in scheduler_test.go/engine_test.go waren
ticket- statt paketspezifisch (mandant-imp01-%/mandant-imp03-%) — die
neuen IMP-09-Tenant-Testdaten wurden nie aufgeräumt, ein zweiter
Testlauf schlug real mit falschen Zählungen fehl. Auf mandant-%
verallgemeinert.
Prüfungen (alle real durchgeführt, siehe mail/docs/IMP-09-PRUEFPROTOKOLL.md):
1. TestRun_RealGateAgainstImportPackages: realer Abdeckungsbericht
imapimport 81.5%, attachments 94.4%, mailrules 71.2%.
2. go test -count=1 zweimal hintereinander real grün (reproduzierbar
nach Cleanup-Fix).
3. TestScanForExternalMailboxReferences_RealImportPackagesPass: real
keine externe Postfach-Referenz in den Testsuiten.
Kein Umbau der geprüften Produktionslogik.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
Regelwerk für automatische Zuordnung, Verschlagwortung und
Klassifizierung importierter E-Mails nach Absender, Betreff, Postfach
und Anhangstyp.
- store.go: Postgres-Store für Regeln (Absender-/Betreff-/Postfach-/
Anhangstyp-Muster als reguläre Ausdrücke, Category einwertig, Tag
mehrwertig, Priority — niedrigere Zahl = höhere Priorität).
- engine.go: Engine.Evaluate wertet Regeln in Prioritätsreihenfolge aus,
"first match wins" für Category, alle zutreffenden Regeln tragen zu
Tags bei. Muster werden beim Erzeugen der Engine einmal kompiliert.
- Bewusst keine Funktion zum rückwirkenden Neuklassifizieren bestehender
Nachrichten — nur explizite RunOnce-artige Neuauswertung wirkt.
Prüfungen (alle real durchgeführt, siehe mail/docs/IMP-03-PRUEFPROTOKOLL.md):
1. TestEvaluate_ConflictingRulesRespectDocumentedPriority: höherpriorisierte
Regel gewinnt real bei widersprüchlichen Kategorien.
2. TestNewEngine_NewRuleDoesNotAffectAlreadyCapturedResult: bereits
erfasstes Ergebnis bleibt real unverändert nach neuer Regel.
3. TestEvaluate_TwentyPlusRulesStayPerformant: 31 Regeln, 2,64µs/Auswertung.
Kein Umbau: kein bestehendes Paket angefasst.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ