Files
nexarch/mail/docs/SRC-08-PRUEFPROTOKOLL.md
T
sysopsandClaude Sonnet 5 ff4d716b94 SRC-08: gespeicherte-suchanfragen
Gespeicherte Suchanfragen: Suchkriterien inklusive aktiver Filter
benannt speichern und live wiederausführen.

- savedsearch/store.go: Postgres-Store, Save (Upsert über tenant_slug/
  user_id/name), List/Get streng auf Mandant+Benutzer beschränkt,
  Delete entfernt genau eine Zeile. Execute führt jede Ausführung LIVE
  gegen search.Client aus, kein eingefrorener Snapshot.
- search/facets.go: kleinste nötige Erweiterung — Client.SearchWithFilters
  (gemeinsame buildFilteredMust-Hilfsfunktion mit Facets extrahiert)
  liefert tatsächlich gefilterte Treffer statt nur Zählungen, sonst gäbe
  es keinen echten Weg, gespeicherte Filter beim Wiederausführen
  anzuwenden.

Prüfungen (alle real durchgeführt, siehe mail/docs/SRC-08-PRUEFPROTOKOLL.md):
1. TestExecute_SavedSearchWithMultipleFiltersReproducesCorrectly: 2
   kombinierte Filter liefern real genau das eine passende Dokument.
2. TestList_UserSeesNoOtherTenantsSavedSearches: Mandant B sieht real
   keine gespeicherten Suchen von Mandant A.
3. TestDelete_RemovesOnlyThatSavedSearch: Löschen entfernt real nur die
   eine gespeicherte Suche, die andere bleibt unverändert.

Kein Umbau: Search/Index/Delete-Verhalten sonst unverändert,
dedup/indexworker/storage/crypto/encstorage unverändert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
2026-08-31 13:31:19 +02:00

3.2 KiB
Raw Blame History

SRC-08 Prüfprotokoll: Gespeicherte Suchanfragen

Voraussetzung SRC-03 (Fertig).

Umsetzung

  • mail/internal/savedsearch/store.goStore (Postgres, mail_saved_searches): Save (Upsert über UNIQUE(tenant_slug, user_id, name), Akzeptanzkriterium 1), List/Get streng auf Mandant UND Benutzer beschränkt (Akzeptanzkriterium 3), Delete löscht genau eine Zeile über tenant_slug + user_id + id. „Benutzer" ist bis zu einer zentralen Session-/IAM-Anbindung (Core-Board-Scope) ein vom Aufrufer mitgegebener opaker userID-String — dieselbe Konvention wie der Tenant-Kontext in web/mail-search (SRC-04).
  • Execute(ctx, client, saved) führt die gespeicherte Suche LIVE gegen search.Client aus — speichert selbst keine Treffer, jeder Aufruf fragt Manticore neu ab (Akzeptanzkriterium 2).
  • mail/internal/search/facets.go — kleinste nötige Erweiterung: neue Methode Client.SearchWithFilters (gemeinsame buildFilteredMust- Hilfsfunktion mit Facets extrahiert) liefert TATSÄCHLICH gefilterte Treffer statt nur Facettenzählungen — ohne dies gäbe es keinen echten Weg, gespeicherte Filter beim Wiederausführen anzuwenden.
  • Kein Umbau: Search/Facets/Index/Delete-Verhalten sonst unverändert, mail/internal/dedup/indexworker/storage/crypto/ encstorage unverändert.

Prüfungen

# Prüfung Ergebnis
1 Test: gespeicherte Suche mit mehreren Filtern wird korrekt reproduziert bestanden TestExecute_SavedSearchWithMultipleFiltersReproducesCorrectly: 3 Dokumente, 2 Filter (Sender+Postfach) gespeichert, Execute liefert real genau das eine Dokument, das beide Filter erfüllt
2 Test: Benutzer sieht keine gespeicherten Suchen anderer Mandanten bestanden TestList_UserSeesNoOtherTenantsSavedSearches: zwei Mandanten mit je einer gespeicherten Suche, List bei Mandant B liefert real nur die eigene, nicht die von Mandant A
3 Test: Löschen einer gespeicherten Suche entfernt nur diese bestanden TestDelete_RemovesOnlyThatSavedSearch: zwei gespeicherte Suchen, eine gelöscht, Get liefert für die gelöschte real ErrNotFound, die andere bleibt real unverändert abrufbar

Zusätzlich (Akzeptanzkriterium 2, kein eingefrorener Snapshot): TestExecute_ReturnsCurrentResultsNotFrozenSnapshot — Ausführung vor einer neuen Indexierung liefert real 0 Treffer, danach real 1 Treffer, ohne dass die gespeicherte Suche selbst verändert wurde.

Build/Test-Ergebnis (192.168.1.131)

go build ./...  -> clean
go vet ./...    -> clean
golangci-lint run ./...  -> 0 issues
TEST_TENANT_DSN=postgresql://nexarch_test:***@localhost:5432/tenant_acme?sslmode=disable \
TEST_MANTICORE_URL=http://127.0.0.1:9308 \
  go test ./... -p 1  -> alle Pakete bestanden, inkl. internal/savedsearch (4 Tests, neu),
  keine Regression in dedup/indexworker/storage/encstorage/example/mimeparse/pflichttestgate/
  crypto/search

Gesamtergebnis

Bestanden. Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt. Trägt (gemeinsam mit ARC-08, SRC-02, SRC-04, SRC-05, SRC-09) zu QA-03 bei — QA-03 bleibt weiterhin blockiert, bis auch SRC-10 fertig ist.