Neues Paket mail/internal/healthcheck: Checker sammelt benannte CheckFunc-Prüfungen, liefert Gesamt- und Einzelstatus je Komponente (ok/degraded, nie ein generischer Fehler). Fehlertexte einzelner Prüfungen fließen nie in die HTTP-Antwort — nur Name+Status je Komponente. Vier konkrete Prüfungen (checks.go) gegen die real vorhandenen Ticket-Abhängigkeiten: DatabaseCheck (pgxpool.Ping), ObjectStorageCheck (HeadBucket gegen den ARC-06-Bucket), SearchIndexCheck (reale Manticore-Anfrage), JobQueueCheck (COUNT gegen 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 auf einem vom Aufrufer bereitgestellten *http.ServeMux, gleiches Pfadschema wie mailapi (INT-01) — Core API-01 hat weiterhin keinen abrufbaren Router. Alle drei Pflichtprüfungen mit echten Nachweisen: simulierter Ausfall einer von vier Abhängigkeiten korrekt als degraded abgebildet, eine Prüfung mit absichtlich eingebetteter Verbindungszeichenfolge inkl. Passwort im Fehlertext taucht nirgends in der HTTP-Antwort auf, echter httptest-HTTP-Server-Integrationstest gegen den Endpunkt. Alle vier konkreten Prüfungen zusätzlich real gegen laufende Postgres-, MinIO- und Manticore-Instanzen verifiziert (inkl. echter ARC-06-Provisionierung). go build/go vet/golangci-lint clean, gesamtes Mail-Modul regressionsfrei getestet.
92 lines
3.8 KiB
Markdown
92 lines
3.8 KiB
Markdown
# 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).
|