package http import ( "counter/internal/delivery/http/handlers" "counter/internal/delivery/http/middleware" "counter/internal/infrastructure/config" "counter/internal/infrastructure/logging" "counter/internal/infrastructure/metrics" "counter/internal/infrastructure/security" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" ) // Router sets up all HTTP routes and middleware type Router struct { router *gin.Engine authHandler *handlers.AuthHandler counterHandler *handlers.CounterHandler config *config.Config logger logging.Logger metricsService metrics.MetricsService jwtService security.JWTService } // NewRouter creates a new router with all dependencies func NewRouter( authHandler *handlers.AuthHandler, counterHandler *handlers.CounterHandler, cfg *config.Config, logger logging.Logger, metricsService metrics.MetricsService, jwtService security.JWTService, ) *Router { // Set Gin mode gin.SetMode(cfg.GinMode) router := gin.Default() return &Router{ router: router, authHandler: authHandler, counterHandler: counterHandler, config: cfg, logger: logger, metricsService: metricsService, jwtService: jwtService, } } // SetupRoutes configures all routes and middleware func (r *Router) SetupRoutes() { // Configure CORS corsConfig := cors.DefaultConfig() corsConfig.AllowOrigins = []string{"http://localhost:3000", "http://localhost:5173"} // React dev servers corsConfig.AllowMethods = []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"} corsConfig.AllowHeaders = []string{"Origin", "Content-Type", "Accept", "Authorization"} corsConfig.AllowCredentials = true r.router.Use(cors.New(corsConfig)) // Add middleware r.router.Use(middleware.MetricsMiddleware(r.metricsService)) r.router.Use(middleware.LoggingMiddleware(r.logger, r.config)) // Health check endpoint r.router.GET("/health", func(c *gin.Context) { c.JSON(200, gin.H{"status": "ok"}) }) // API routes api := r.router.Group("/api/v1") { // Authentication routes authGroup := api.Group("/auth") { authGroup.POST("/register", r.authHandler.Register) authGroup.POST("/login", r.authHandler.Login) authGroup.GET("/me", middleware.AuthMiddleware(r.jwtService), r.authHandler.GetMe) } // Counter routes (protected) counterGroup := api.Group("/counters") counterGroup.Use(middleware.AuthMiddleware(r.jwtService)) { counterGroup.POST("", r.counterHandler.Create) counterGroup.GET("", r.counterHandler.List) counterGroup.GET("/:id", r.counterHandler.Get) counterGroup.PUT("/:id", r.counterHandler.Update) counterGroup.DELETE("/:id", r.counterHandler.Delete) counterGroup.POST("/:id/increment", r.counterHandler.Increment) counterGroup.GET("/:id/entries", r.counterHandler.GetEntries) counterGroup.GET("/:id/stats", r.counterHandler.GetStats) } } // Serve static files (React app) r.router.Static("/static", "./frontend/build/static") r.router.StaticFile("/", "./frontend/build/index.html") r.router.NoRoute(func(c *gin.Context) { c.File("./frontend/build/index.html") }) } // GetRouter returns the configured Gin router func (r *Router) GetRouter() *gin.Engine { return r.router }