package health import ( "encoding/json" "net/http" ) // LivenessHandler beantwortet IMMER "lebt", solange der Prozess ueberhaupt // HTTP-Anfragen verarbeiten kann — prueft bewusst KEINE externen // Abhaengigkeiten (Akzeptanzkriterium 2: Liveness und Readiness getrennt). // Ein Datenbankausfall darf die Liveness nicht auf "tot" setzen, sonst // wuerde eine Orchestrierung (z.B. systemd/Kubernetes) den Prozess grundlos // neu starten, obwohl nur eine Abhaengigkeit ausgefallen ist. func LivenessHandler(w http.ResponseWriter, r *http.Request) { writeStatus(w, http.StatusOK, map[string]any{"status": "alive"}) } // ReadinessHandler prueft ALLE registrierten Abhaengigkeiten // (Akzeptanzkriterium 1) und liefert 503, sobald eine davon fehlschlaegt // (Akzeptanzkriterium 3) — unterscheidet sich damit nachweislich von // LivenessHandler im Fehlerfall (Akzeptanzkriterium 2 / Pruefung 3). func (r *Registry) ReadinessHandler() http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { ready, results := r.CheckAll(req.Context()) body := map[string]any{ "status": statusText(ready), "checks": results, } status := http.StatusOK if !ready { status = http.StatusServiceUnavailable } writeStatus(w, status, body) } } func statusText(ready bool) string { if ready { return "ready" } return "not_ready" } func writeStatus(w http.ResponseWriter, status int, body map[string]any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) _ = json.NewEncoder(w).Encode(body) }