Files
archivmail/features/PROJ-6-volltext-suche.md
T
sysops d360c9a5ba feat(PROJ-17): Admin Dashboard Systemauslastung immer anzeigen
- Systemauslastungs-Sektion wird immer gerendert (nicht nur bei Erfolg)
- Fehlermeldung wenn /api/admin/system/stats nicht erreichbar ist
- Feature-Status auf In Review gesetzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 11:43:19 +01:00

129 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PROJ-6: Volltext-Suche & Filterung
## Status: In Progress
**Created:** 2026-03-12
**Last Updated:** 2026-03-12
## Dependencies
- Requires: PROJ-1 (Authentifizierung) Suche nur für eingeloggte Nutzer
- Requires: PROJ-5 (Speicherung & Indexierung) Suchergebnisse kommen aus dem Index
## User Stories
- Als Nutzer möchte ich nach Schlüsselwörtern suchen, damit ich relevante E-Mails schnell finden kann.
- Als Nutzer möchte ich Suchergebnisse nach Absender, Empfänger, Datum und Anhang filtern, damit ich die Treffermenge eingrenzen kann.
- Als Nutzer möchte ich Suchergebnisse nach Datum sortieren können (neueste/älteste zuerst).
- Als Nutzer möchte ich Suchbegriffe in den Ergebnissen hervorgehoben sehen (Highlighting).
- Als Nutzer sehe ich nur E-Mails, auf die ich Zugriffsrecht habe, damit Datenschutz gewahrt bleibt.
## Acceptance Criteria
- [ ] Sucheingabe mit Echtzeit-Vorschau (oder sofortiger Submit)
- [ ] Suche in: Betreff, Absender, Empfänger, Body-Text
- [ ] Filteroptionen: Datum (vonbis), Absender-Domain, hat Anhang (ja/nein), Label
- [ ] Sortierung: nach Relevanz, nach Datum (auf-/absteigend)
- [ ] Suchergebnisse paginiert (Standard: 25 pro Seite)
- [ ] Suchbegriff in Betreff und Body-Snippet hervorgehoben
- [ ] Suchanfragen liefern Ergebnisse in < 2 Sekunden (bei 100.000+ E-Mails)
- [ ] Nutzer sehen nur E-Mails in ihren zugewiesenen Postfächern
## Edge Cases
- Suchanfrage ohne Ergebnisse → "Keine Ergebnisse" Meldung mit Vorschlägen
- Sonderzeichen in Suchanfrage (", *, ?) → Escaping oder Query-Syntax erlauben
- Suche bei sehr großem Index (1M+ Mails) → Performance-Test erforderlich
- Gleichzeitige Suchanfragen von vielen Nutzern → kein Query-Blocking
## Technical Requirements
- **Such-Engine: Xapian** die Web-GUI sucht ausschließlich über den Xapian-Index
- Kein SQL-Fulltext-Query gegen PostgreSQL DB wird nur für Metadaten-Lookup nach Treffern genutzt
- Suchfluss: Web-GUI → API → Xapian-Query → Treffer-IDs → PostgreSQL-Metadaten-Lookup → Antwort
- Xapian QueryParser: AND, OR, NOT, Phrasen (`"exakter Text"`), Wildcards (`word*`), Feldpräfixe (`from:`, `subject:`)
- Relevanz-Ranking über Xapian BM25Weight
- Snippet/Highlighting über `Xapian::MSet::snippet()`
- `ReadonlyDatabase` für parallele Lesezugriffe (mehrere Nutzer gleichzeitig möglich)
- Antwortzeit < 2 Sekunden für Volltext-Suche über 100.000 E-Mails
- Suchanfragen werden für Audit-Log erfasst (optional, konfigurierbar)
---
## Tech Design (Solution Architect)
### Komponentenstruktur
**Next.js Frontend:**
```
/search
├── SearchBar ← Eingabefeld, Submit bei Enter oder Button
├── FilterPanel ← aufklappbar
│ ├── DateRangePicker ← vonbis Datum
│ ├── DomainFilter ← Absender-Domain Freitext
│ ├── AttachmentToggle ← nur Mails mit Anhang
│ └── LabelFilter ← Label-Auswahl (Mehrfachauswahl)
├── SortControls ← Relevanz / Datum aufsteigend / absteigend
├── ResultsList
│ └── MailCard (pro Treffer)
│ ├── Betreff (Suchbegriff hervorgehoben)
│ ├── Von / An / Datum / Größe
│ ├── Body-Snippet (Suchbegriff hervorgehoben)
│ └── Anhang-Indikator
├── Pagination ← Seiten-Navigation
└── EmptyState ← "Keine Ergebnisse" mit Suchtipps
```
**Go Backend:**
```
GET /api/search
├── Session Middleware ← Auth prüfen
├── Role Filter Builder ← user: nur eigene Postfächer / auditor: alle
├── Xapian QueryParser ← Nutzer-Query parsen (AND/OR/NOT/Wildcards)
├── Xapian ReadonlyDatabase ← Query ausführen, MSet zurückgeben
│ ├── BM25 Relevanz-Ranking ← beste Treffer zuerst
│ └── MSet::snippet() ← Highlighting-Snippets erzeugen
├── PostgreSQL Metadaten-Lookup ← From, To, Subject, Date, Size, Attachments
└── JSON Response Assembly ← Ergebnis zusammenbauen
```
### Suchfluss
```
Next.js (Browser) Go Backend
│ │
│ GET /api/search │
│ ?q=Rechnung&date_from=2024-01 │
│ &has_attachments=true&page=2 │
│ ────────────────────────────────► │
│ Session prüfen
│ Rolle ermitteln:
│ user → Filter: nur eigene Postfach-IDs
│ auditor → kein Filter
│ │
│ Xapian QueryParser
│ → Query + Datumsfilter + Anhang-Filter
│ │
│ Xapian ReadonlyDatabase
│ → MSet: [doc_id_1, doc_id_5, ...]
│ → Snippets mit Highlighting
│ │
│ PostgreSQL
│ → Metadaten für doc_ids laden
│ │
│ ◄────────────────────────────────
│ { total, page, mails: [...] } │
│ MailCards rendern + highlighten │
```
### Technische Entscheidungen
| Entscheidung | Begründung |
|---|---|
| **Xapian für alles, kein SQL-Fulltext** | Optimiert für Volltext PostgreSQL LIKE-Suche wäre bei 100k+ Mails zu langsam |
| **ReadonlyDatabase** | Beliebig viele parallele Lesezugriffe kein Blocking bei gleichzeitigen Nutzern |
| **Rolle als Xapian-Term** | Postfach-ID beim Indexieren als Term gespeichert Rollenfilter läuft in Xapian, nicht nachträglich in der DB |
| **Snippets aus Xapian** | `MSet::snippet()` hebt Suchbegriff im Originaltext hervor kein separates Rendering nötig |
| **Paginierung über Xapian Offset** | Nur angefragter Seitenausschnitt zurückgegeben kein Full-Scan pro Seite |
| **PostgreSQL nur für Metadaten** | Nach Xapian-Suche werden nur gefundene IDs nachgeschlagen minimale DB-Last |
| **URL-State mit `nuqs`** | Suchparameter in der URL → Back-Button funktioniert, Suchergebnisse sind verlinkbar |
## QA Test Results
_To be added by /qa_
## Deployment
_To be added by /deploy_