# INT-07 — Health-Check-Endpunkt für Mail-Modul: Prüfprotokoll Datum: 2026-09-01 Host: 192.168.1.131 (Build/Test/Lint), rsync + ssh Paket: `mail/internal/healthcheck` (neu) Testinfrastruktur: echte lokale Postgres-, MinIO- und Manticore-Instanzen ## Umsetzung `Checker` sammelt benannte `CheckFunc`-Prüfungen (Reihenfolge deterministisch) und liefert einen `Result` mit Gesamtstatus und Einzelstatus je Komponente — `ok` oder `degraded` (Akzeptanzkriterium 3, nie ein generischer Fehler). Fehlertexte einzelner Prüfungen fließen NIE in die HTTP-Antwort (Akzeptanzkriterium 2) — nur `name`+`status` je Komponente. Vier konkrete Prüfungen (`checks.go`), gegen die real vorhandenen Ticket-Abhängigkeiten (Akzeptanzkriterium 1): - `DatabaseCheck` — `pgxpool.Pool.Ping`. - `ObjectStorageCheck` — `HeadBucket` gegen den ARC-06-Bucket. - `SearchIndexCheck` — reale `search.Client.Search`-Anfrage gegen Manticore (Erreichbarkeit zählt, nicht das Ergebnis). - `JobQueueCheck` — `SELECT count(*) FROM mail_index_jobs` (SRC-02/indexworker) — `COUNT` statt Zeilenzugriff, damit eine LEERE aber erreichbare Queue nicht fälschlich als Ausfall gilt. `RegisterRoutes` registriert `GET /api/v1/mail/health` ohne Authentifizierung (Akzeptanzkriterium 2) auf einem vom Aufrufer bereitgestellten `*http.ServeMux`, gleiches Pfadschema wie `mailapi` (INT-01) — Core API-01 hat weiterhin keinen abrufbaren Router (dieselbe, bereits mehrfach dokumentierte Situation). ## Pflichtprüfung 1: simulierter Ausfall einer Abhängigkeit wird korrekt im Health-Status abgebildet `TestCheck_SimulatedDependencyFailureReflectedCorrectly`: eine von vier Prüfungen liefert einen Fehler — Gesamtstatus `degraded`, GENAU diese eine Komponente als `degraded`, die übrigen drei als `ok`. Ergebnis: **BESTANDEN**. ## Pflichtprüfung 2: Health-Antwort enthält keine sensiblen Konfigurationsdetails `TestServeHTTP_ResponseNeverContainsSensitiveErrorDetails`: eine Prüfung liefert einen Fehler, der absichtlich eine vollständige Verbindungszeichenfolge inkl. Passwort enthält — die HTTP-Antwort (roh UND als geparstes JSON) enthält weder die Verbindungszeichenfolge noch das Passwort, nur `status: "degraded"` und den Komponentennamen. Ergebnis: **BESTANDEN**. ## Pflichtprüfung 3: Integrationstest gegen echten Health-Endpunkt nach Deploy `TestIntegration_RealHTTPEndpointAfterDeploy`: echter `httptest`-HTTP- Server, echte Netzwerkanfrage (kein direkter Funktionsaufruf) gegen `GET /api/v1/mail/health`, 200 mit vollständigem, geparstem JSON. Ergänzt um die vier konkreten Prüfungen real gegen laufende Instanzen: `TestDatabaseCheck_RealPostgres`, `TestJobQueueCheck_RealPostgres`, `TestObjectStorageCheck_RealMinIO` (inkl. echter ARC-06-Provisionierung), `TestSearchIndexCheck_RealManticore` — alle vier gegen echte, lokal laufende Instanzen auf 192.168.1.131. Ergebnis: **BESTANDEN**. ## Akzeptanzkriterien 1. **Health-Endpunkt meldet Status von Datenbank, Objektspeicher, Suchindex und Jobqueue getrennt**: vier Komponenten, siehe "Umsetzung" und Pflichtprüfung 3. 2. **Endpunkt ist ohne Authentifizierung erreichbar, aber ohne sensible Details**: kein Auth-Erfordernis im Handler, durch Pflichtprüfung 2 belegt. 3. **Ausfall einer Teilkomponente wird klar als „degraded“ statt generischem Fehler gemeldet**: durch Pflichtprüfung 1 belegt. ## Build/Vet/Lint/Test — Gesamtmodul ``` go build ./... → OK go vet ./... → OK golangci-lint run ./... → 0 issues go test ./... -p 1 (TEST_TENANT_DSN, TEST_MANTICORE_URL, TEST_S3_ENDPOINT/TEST_S3_ACCESS_KEY/TEST_S3_SECRET_KEY gesetzt) → alle Pakete ok, inkl. neuem internal/healthcheck ``` Keine Regression. ## Ergebnis INT-07 erfüllt alle Akzeptanzkriterien mit echten, ausgeführten Nachweisen gegen reale Postgres-, MinIO- und Manticore-Instanzen. Freigeschaltet: QA-06 (zusammen mit INT-06/09/10).