package server import ( "encoding/json" "log/slog" "net/http" "github.com/go-chi/chi/v5" mcdslauth "git.wntrmute.dev/kyle/mcdsl/auth" "git.wntrmute.dev/kyle/mcdsl/health" "git.wntrmute.dev/kyle/mcns/internal/db" ) // Deps holds dependencies injected into the REST handlers. type Deps struct { DB *db.DB Auth *mcdslauth.Authenticator Logger *slog.Logger } // NewRouter builds the chi router with all MCNS REST endpoints. func NewRouter(deps Deps) *chi.Mux { r := chi.NewRouter() r.Use(loggingMiddleware(deps.Logger)) // Public endpoints. r.Post("/v1/auth/login", loginHandler(deps.Auth)) r.Get("/v1/health", health.Handler(deps.DB.DB)) // Authenticated endpoints. r.Group(func(r chi.Router) { r.Use(requireAuth(deps.Auth)) r.Post("/v1/auth/logout", logoutHandler(deps.Auth)) // Zone endpoints — reads for all authenticated users, writes for admin. r.Get("/v1/zones", listZonesHandler(deps.DB)) r.Get("/v1/zones/{zone}", getZoneHandler(deps.DB)) // Admin-only zone mutations. r.With(requireAdmin).Post("/v1/zones", createZoneHandler(deps.DB)) r.With(requireAdmin).Put("/v1/zones/{zone}", updateZoneHandler(deps.DB)) r.With(requireAdmin).Delete("/v1/zones/{zone}", deleteZoneHandler(deps.DB)) // Record endpoints — reads for all authenticated users, writes for admin. r.Get("/v1/zones/{zone}/records", listRecordsHandler(deps.DB)) r.Get("/v1/zones/{zone}/records/{id}", getRecordHandler(deps.DB)) // Admin-only record mutations. r.With(requireAdmin).Post("/v1/zones/{zone}/records", createRecordHandler(deps.DB)) r.With(requireAdmin).Put("/v1/zones/{zone}/records/{id}", updateRecordHandler(deps.DB)) r.With(requireAdmin).Delete("/v1/zones/{zone}/records/{id}", deleteRecordHandler(deps.DB)) }) return r } // writeJSON writes a JSON response with the given status code. func writeJSON(w http.ResponseWriter, status int, v any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) _ = json.NewEncoder(w).Encode(v) } // writeError writes a standard error response. func writeError(w http.ResponseWriter, status int, message string) { writeJSON(w, status, map[string]string{"error": message}) }