Facetten- und Filter-API für Suche (Absender, Zeitraum, Postfach, Anhangstyp, Tag), mandantengetrennt, mit UND-Verknüpfung mehrerer Filter. - migrations/0002..0005: vier nummerierte ALTER-Migrationen für die neuen Facettenfelder (Manticore erlaubt nur eine Spalte je ALTER-Anweisung), EnsureSchema wendet sie idempotent nach. - fields.go: FacetFields-Whitelist, einzige zulässige Facettendimensionen. - facets.go: Client.Facets nutzt Manticores strukturierte aggs.terms/ aggs.range-API, kein dynamischer SQL-Klauselbau. Filter kombinieren als zusätzliche equals-Klauseln in derselben bool.must-Liste wie der Tenant-Filter. Zeitraum-Facette über feste Buckets via aggs.range. Prüfungen (alle real durchgeführt, siehe mail/docs/SRC-05-PRUEFPROTOKOLL.md): 1. TestFacets_CountsMatchActualHits: Facettenzahlen stimmen real mit der tatsächlichen Treffermenge überein. 2. TestFacets_ThreeFiltersCombineWithAND: 3 kombinierte Filter schränken 4 Dokumente real auf genau 1 verbleibenden Treffer ein. 3. TestFacets_TenantSeparation: Facetten eines Mandanten enthalten real keine Werte eines anderen. Kein Umbau: Search/Delete/Index-Verhalten aus SRC-01/SRC-03 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
3.0 KiB
3.0 KiB
SRC-05 – Prüfprotokoll: Facetten- & Filter-API
Voraussetzung SRC-03 (Fertig).
Umsetzung
mail/internal/search/migrations/0002..0005_*.sql: vier eigene, nummerierteALTER TABLE ADD COLUMN-Migrationen für die neuen Facettenfelder (sender,mailbox,attachment_type,tag) — Manticore erlaubt nur eine Spalte je ALTER-Anweisung.EnsureSchemawendet sie idempotent nach (Fehlertext"already in schema"gilt als bereits angewendet, kein Fehlerzustand).fields.go: neue statische Feldkonstanten +FacetFields-Whitelist (sender,mailbox,attachment_type,tag) — einzige Quelle zulässiger Facettendimensionen, kein beliebiger Client-Feldname möglich.facets.go—Client.Facets(ctx, tenantSlug, queryText, filters): nutzt Manticores strukturierteaggs.terms/aggs.range-API (kein dynamischer SQL-Klauselbau). Tenant-Filter + optionaleFacetFilter-Liste laufen als zusätzlicheequals-Klauseln in derselbenbool.must-Liste (Akzeptanzkriterium 2: UND-Verknüpfung). Zeitraum-Facette über feste Buckets (letzte 7 Tage/30 Tage/Jahr/älter) viaaggs.rangeaufsent_at.Documentum optionale Facettenfelder erweitert (Sender,Mailbox,AttachmentType,Tag).- Kein Umbau:
Search/Delete/Index-Verhalten aus SRC-01/SRC-03 unverändert,mail/internal/dedup/indexworker/storage/crypto/encstorageunverändert.
Prüfungen
| # | Prüfung | Ergebnis |
|---|---|---|
| 1 | Test: Facettenzahlen stimmen mit tatsächlicher Treffermenge überein | bestanden – TestFacets_CountsMatchActualHits: 3 reale Dokumente indexiert, Facette sender liefert real alice@example.com→2, bob@example.com→1, Facette attachment_type liefert real pdf→2 |
| 2 | Test: Kombination von drei Filtern liefert korrekt eingeschränkte Treffer | bestanden – TestFacets_ThreeFiltersCombineWithAND: 4 Dokumente, von denen 3 je genau einen der drei Filter (Sender/Postfach/Anhangstyp) verletzen — nach Kombination aller drei Filter bleibt real genau 1 Treffer übrig |
| 3 | Test: Facetten eines Mandanten enthalten keine Werte eines anderen | bestanden – TestFacets_TenantSeparation: identische Feldstruktur bei zwei Mandanten, Facette bei Mandant B enthält real keinen Wert von Mandant A |
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/search (10 Tests,
keine Regression in dedup/indexworker/storage/encstorage/example/mimeparse/pflichttestgate)
Gesamtergebnis
Bestanden. Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt. Entsperrt SRC-06, trägt (gemeinsam mit ARC-08, SRC-02, SRC-04, SRC-08, SRC-09, SRC-10) zu QA-03 bei — QA-03 bleibt weiterhin blockiert, bis auch die übrigen vier Tickets fertig sind.