package router import ( "net/http" "time" "github.com/CubeCraft-Creations/Extrudex/backend/internal/config" "github.com/CubeCraft-Creations/Extrudex/backend/internal/handlers" "github.com/CubeCraft-Creations/Extrudex/backend/internal/repositories" "github.com/CubeCraft-Creations/Extrudex/backend/internal/services" "github.com/CubeCraft-Creations/Extrudex/backend/internal/sse" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/jackc/pgx/v5/pgxpool" ) // New creates and configures a Chi router with all middleware and handlers mounted. func New(cfg *config.Config, dbPool *pgxpool.Pool, sseBC *sse.Broadcaster) chi.Router { r := chi.NewRouter() // Middleware r.Use(middleware.RequestID) r.Use(middleware.RealIP) r.Use(middleware.Logger) r.Use(middleware.Recoverer) // Timeout middleware is applied per-route below to exclude SSE // CORS r.Use(func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", cfg.CorsOrigin) w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") if r.Method == http.MethodOptions { w.WriteHeader(http.StatusNoContent) return } next.ServeHTTP(w, r) }) }) // Health check (with timeout) healthHandler := handlers.NewHealthHandler(dbPool) r.With(middleware.Timeout(30 * time.Second)).Get("/health", healthHandler.ServeHTTP) // ── Repositories ────────────────────────────────────────────────────── materialRepo := repositories.NewMaterialRepository(dbPool) filamentRepo := repositories.NewFilamentRepository(dbPool) printerRepo := repositories.NewPrinterRepository(dbPool) printJobRepo := repositories.NewPrintJobRepository(dbPool) usageLogRepo := repositories.NewUsageLogRepository(dbPool) // ── Services ────────────────────────────────────────────────────────── filamentService := services.NewFilamentService(filamentRepo) printerService := services.NewPrinterService(printerRepo) printJobService := services.NewPrintJobService(printJobRepo) // ── Handlers ────────────────────────────────────────────────────────── materialHandler := handlers.NewMaterialHandler(materialRepo) filamentHandler := handlers.NewFilamentHandler(filamentService) printerHandler := handlers.NewPrinterHandler(printerService) printJobHandler := handlers.NewPrintJobHandler(printJobService) usageLogHandler := handlers.NewUsageLogHandler(usageLogRepo) // ── API Routes (with timeout) ───────────────────────────────────────── r.Route("/api", func(r chi.Router) { r.Use(middleware.Timeout(60 * time.Second)) r.Get("/materials", materialHandler.List) r.Route("/filaments", func(r chi.Router) { r.Get("/", filamentHandler.List) r.Post("/", filamentHandler.Create) r.Route("/{id}", func(r chi.Router) { r.Get("/", filamentHandler.Get) r.Put("/", filamentHandler.Update) r.Delete("/", filamentHandler.Delete) }) }) r.Get("/printers", printerHandler.List) r.Get("/print-jobs", printJobHandler.List) r.Get("/usage-logs", usageLogHandler.List) // SSE Events stream sseHandler := sse.NewHandler(sseBC) r.Get("/events", sseHandler.ServeHTTP) }) return r }