package httpapp import ( "encoding/json" "log" "net/http" ) func (a *App) handleDashboard(w http.ResponseWriter, r *http.Request) { data := map[string]any{ "Title": "Dashboard", "Build": map[string]string{ "version": "v0.1.0-dev", }, } a.render(w, "dashboard.html", data) } func (a *App) handleHealthz(w http.ResponseWriter, r *http.Request) { id, _ := r.Context().Value(requestIDKey).(string) resp := map[string]any{ "status": "ok", "ts": id, // request ID for correlation } writeJSON(w, http.StatusOK, resp) } func (a *App) handleMetrics(w http.ResponseWriter, r *http.Request) { // Stub metrics (Prometheus format). We'll wire real collectors later. w.Header().Set("Content-Type", "text/plain; version=0.0.4") w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte( `# HELP pluto_build_info Build info # TYPE pluto_build_info gauge pluto_build_info{version="v0.1.0-dev"} 1 # HELP pluto_up Whether the pluto-api process is up # TYPE pluto_up gauge pluto_up 1 `, )) } func (a *App) render(w http.ResponseWriter, name string, data any) { w.Header().Set("Content-Type", "text/html; charset=utf-8") // base.html defines layout; dashboard.html will invoke it via template inheritance style. if err := a.tmpl.ExecuteTemplate(w, name, data); err != nil { log.Printf("template render error: %v", err) http.Error(w, "template render error", http.StatusInternalServerError) return } } func writeJSON(w http.ResponseWriter, code int, v any) { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(code) if err := json.NewEncoder(w).Encode(v); err != nil { log.Printf("json encode error: %v", err) } }