Such-Oberfläche (Next.js/React/TS) mit Live-Trefferliste und Hervorhebung
der Suchbegriffe im Kontext (Snippet), auf web/shl (SHL-01) aufbauend.
- app/api/search/route.ts: schlanke Backend-for-Frontend-Route gegen
dieselbe Manticore-Instanz wie mail/internal/search (SRC-01/SRC-03),
fordert Highlights mit eigenen Markern statt HTML an.
- lib/highlight.ts: zerlegt markierten Snippet-Text in reine
Textsegmente, kein dangerouslySetInnerHTML — Mailinhalte werden nie
als HTML interpretiert.
- app/page.tsx: Sucheingabe, Trefferliste mit <mark>-Hervorhebung,
verständlicher Hinweis bei leerem Ergebnis.
- app/mail/[messageId]/page.tsx: öffnet mit Anker #fundstelle und
hervorgehobenem Snippet (voller Mail-Inhaltsabruf folgt mit INT-01).
- lib/contrast.ts: reale WCAG-2.1-Kontrastberechnung.
Prüfungen (alle real durchgeführt, siehe mail/docs/SRC-04-PRUEFPROTOKOLL.md):
1. Manueller Test gegen echten next start + live Manticore auf
192.168.1.131: Hervorhebung real bestätigt.
2. lib/highlightColors.test.ts: echte WCAG-Berechnung, Hell 14,29:1,
Dunkel 6,43:1 (>= 4.5:1 AA).
3. Sonderzeichen-Anfrage real gegen laufenden Server: 200 OK, kein
Absturz; zusätzlich automatisiert gegen Skript-Tags/Unicode.
Kein Umbau: mail/internal/*, web/shl, web/retention-admin unverändert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
Indexierungs-Worker, der neu archivierte Mails asynchron in den
Manticore-Index (SRC-01) einpflegt und Löschungen nachzieht.
- indexworker/queue.go: Postgres-Jobqueue (mail_index_jobs), FOR UPDATE
SKIP LOCKED, Stale-Lock-Wiedervorlage bei Worker-Absturz, arithmetischer
Backoff bei Fail (kein String-Concat für Intervalle) — Konvention aus
dms/internal/jobqueue (FDN-04), hier bewusst ohne DLQ (nicht Bestandteil
der Akzeptanzkriterien dieser Kachel).
- indexworker/worker.go: RunOnce verarbeitet index-/delete-Jobs über
search.Client.
- search: minimale Erweiterung um Client.Delete und deterministisches
DocumentID(tenantSlug, messageID), damit Index/Delete für dieselbe Mail
immer dasselbe Dokument treffen.
Prüfungen (alle real durchgeführt, siehe mail/docs/SRC-02-PRUEFPROTOKOLL.md):
1. TestDequeue_WorkerCrashMidRunLosesNoJob: simulierter Worker-Absturz,
Job wird nach Ablauf der Stale-Lock-Frist real erneut zugestellt.
2. TestDeleteJob_RemovesMailFromSearchResults: Lösch-Job entfernt Mail
nachweislich aus Suchtreffern.
3. TestConsistency_DatabaseAndIndexMatchOnSample: DB-Job-Status und
Index-Inhalt stichprobenartig real abgeglichen.
Zusätzlich TestIndexJob_MakesMailSearchable für Akzeptanzkriterium 1.
Kein Umbau: storage/crypto/encstorage/dedup unverändert, bestehendes
SRC-01-Verhalten unverändert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
- mail/internal/dedup/hash.go: HashAndBuffer, SHA-256 auf Klartext VOR
Verschluesselung (ARC-02), liefert erneut lesbaren Reader zurueck.
- mail/internal/dedup/store.go: Store (Postgres, tenant_slug fest im
Primaerschluessel gebunden), Register: Duplikat referenziert Original
statt redundant zu speichern.
- Alle 3 Pflichtpruefungen real bestanden (siehe
mail/docs/ARC-03-PRUEFPROTOKOLL.md): Duplikat aus zwei Quellen
erkannt, zwei Mandanten mit identischem Inhalt nicht verknuepft,
knapp unterschiedliche Nachricht korrekt nicht erkannt.
- Kein Umbau: internal/storage, internal/crypto, internal/encstorage
unveraendert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- mail/internal/crypto: Envelope-Encryption (AES-256-GCM), DEK pro
Objekt, HTTPKEKProvider bezieht Tenant-KEK ueber Core API-12 -
bewaehrtes Muster aus DMS FDN-09, Neuimplementierung (Mail kann DMS
nicht importieren)
- mail/internal/encstorage: verbindet ARC-01 (storage.Service) mit
ARC-02 (crypto.Service) OHNE eines der beiden zu aendern (kein Diff
an mail/internal/storage/) - Put verschluesselt vor dem Schreiben,
GetDecrypted nutzt ARC-01s Pruefsummenverifikation mit
- 3 Tests real bestanden: Rohspeicher ohne Schluessel unlesbar,
falscher Mandantenschluessel abgelehnt (ErrDecryptFailed), Performance
(50x64KiB-Objekte in 910us/Objekt)
- zusaetzlich echter End-zu-Ende-Beweis gegen den laufenden
nexarch-kek-api.service (API-12): vollstaendiger Put->GetDecrypted-
Roundtrip ueber echten HTTP-KEK-Bezug, nicht-existenter Tenant real
abgelehnt (404)
- offener Punkt ehrlich vermerkt: internal/crypto/internal/encstorage
fehlen noch in QA-01s Pflichttest-Gate-Pfadmustern
Pruefungen siehe mail/docs/ARC-02-PRUEFPROTOKOLL.md
- mail/internal/storage: LocalDriver/S3Driver (bewaehrtes Muster aus
DMS FDN-03, bewusste Neuimplementierung - Mail kann DMS nicht
importieren), ObjectKey mit festem Pfadschema
- Service.Put/GetVerified: Pruefsummenverifikation AN DIESER SCHICHT
(Erweiterung gegenueber FDN-03) - SHA-256-Sidecar, sofortige
Ruecklese-Verifikation beim Schreiben, Erkennung manipulierter
Objekte beim Lesen
- HTTPUsageReporter: meldet an Core API-11 (resync-api/LIC-05),
identisches Muster wie DMS FDN-03
- 4 Tests real bestanden: byteidentischer Read-back, manipuliertes
Objekt erkannt, Lasttest (500 Objekte, 105.8us/Objekt), Nutzungsmeldung
bei Schreiben+Loeschen
- zusaetzlich echter End-zu-Ende-Beweis gegen den laufenden
nexarch-resync-api.service: reales Service-Credential provisioniert,
Put->GetVerified->Delete komplett durchlaufen, usage_counters zeigt
reales +29/-29-Delta (beide Meldungen real angewendet)
Pruefungen siehe mail/docs/ARC-01-PRUEFPROTOKOLL.md
- mail/go.mod: erstes eigenstaendiges Go-Modul fuer NEXARCH Mail
- mail/docs/TESTSTRATEGIE-MAIL.md: Testpyramide (Unit/Integration/
Protokoll-Zustandsmaschinen/E2E/Vertragstests), Pflichttest-Merge-Gate,
Bug-Tracking-Konvention (Gitea-Issues), analog Core QA-01
- mail/internal/example: ein reales, kleines Beispiel (Adress-
Normalisierung) mit je einem Test pro Testart (Unit/Integration/E2E),
6 Tests real bestanden
- mail/internal/pflichttestgate + cmd/pflichttestgate: Merge-Gate-CLI,
echter End-zu-Ende-Beweis (Binary lehnt Verstoss ab, akzeptiert
begleiteten Test), .gitea/workflows/mail-pflichttest-gate.yml
- Ehrlich dokumentiert: kein Gitea-API-Token verfuegbar, daher kein
echter Issue angelegt - Bug-Tracking-Vorgehen stattdessen anhand
eines realen, bereits dokumentierten Befunds (RET-10) durchgespielt,
als offener Punkt vermerkt
- Gegenlesen durch zweite Person (Nutzer) noch ausstehend
Pruefungen siehe mail/docs/TESTSTRATEGIE-MAIL.md