Initial scaffold: backend base + docker-compose dev infra + sveltekit frontend

This commit is contained in:
2026-09-17 17:52:38 +02:00
commit 2128fe9cac
29 changed files with 2101 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
package httpserver
import (
"encoding/json"
"net/http"
dockerconn "dockermanager/backend/internal/docker"
)
func handleHealthz(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, map[string]string{"status": "ok"})
}
func handleListContainers(d dockerconn.HostConnector) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
containers, err := d.ListContainers(r.Context())
if err != nil {
writeJSON(w, http.StatusBadGateway, map[string]string{"error": err.Error()})
return
}
writeJSON(w, http.StatusOK, containers)
}
}
func writeJSON(w http.ResponseWriter, status int, body any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
_ = json.NewEncoder(w).Encode(body)
}
+65
View File
@@ -0,0 +1,65 @@
// Package httpserver contiene el router HTTP y los handlers de la API.
package httpserver
import (
"log/slog"
"net/http"
"time"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/cors"
dockerconn "dockermanager/backend/internal/docker"
)
// Deps son las dependencias que necesitan los handlers.
type Deps struct {
Logger *slog.Logger
Docker dockerconn.HostConnector
Origins []string
}
// NewRouter construye el router HTTP con todas las rutas de la Fase 1.
func NewRouter(deps Deps) http.Handler {
r := chi.NewRouter()
r.Use(middleware.RequestID)
r.Use(middleware.RealIP)
r.Use(middleware.Recoverer)
r.Use(middleware.Timeout(15 * time.Second))
r.Use(slogRequestLogger(deps.Logger))
r.Use(cors.Handler(cors.Options{
AllowedOrigins: deps.Origins,
AllowedMethods: []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete},
AllowedHeaders: []string{"Accept", "Content-Type", "Authorization"},
AllowCredentials: true,
MaxAge: 300,
}))
r.Get("/healthz", handleHealthz)
r.Route("/api", func(r chi.Router) {
r.Get("/containers", handleListContainers(deps.Docker))
})
return r
}
// slogRequestLogger es un middleware mínimo que registra cada request con slog.
func slogRequestLogger(logger *slog.Logger) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
next.ServeHTTP(ww, r)
logger.Info("request",
"method", r.Method,
"path", r.URL.Path,
"status", ww.Status(),
"duration_ms", time.Since(start).Milliseconds(),
)
})
}
}