package main import ( "context" "log" "os" "os/signal" "syscall" "time" "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/middleware/cors" "github.com/gofiber/fiber/v3/middleware/logger" "github.com/gofiber/fiber/v3/middleware/recover" "github.com/gofiber/fiber/v3/middleware/requestid" "github.com/knowfoolery/backend/services/gateway-service/config" "github.com/knowfoolery/backend/services/gateway-service/internal/handlers" "github.com/knowfoolery/backend/services/gateway-service/internal/middleware" "github.com/knowfoolery/backend/services/gateway-service/internal/proxy" "github.com/knowfoolery/backend/services/gateway-service/internal/security" ) func main() { cfg := config.Load() app := fiber.New(fiber.Config{ AppName: "Know Foolery Gateway", ReadTimeout: 30 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 120 * time.Second, ErrorHandler: handlers.ErrorHandler, }) app.Use(requestid.New()) app.Use(logger.New(logger.Config{ Format: "${time} ${status} - ${method} ${path} - ${latency}\n", })) app.Use(recover.New()) app.Use(cors.New(cors.Config{ AllowOrigins: cfg.CORS.AllowedOrigins, AllowMethods: cfg.CORS.AllowedMethods, AllowHeaders: cfg.CORS.AllowedHeaders, AllowCredentials: cfg.CORS.AllowCredentials, MaxAge: cfg.CORS.MaxAge, })) authMiddleware := middleware.NewAuthMiddleware(cfg.Auth) rateLimiter := middleware.NewRateLimiter(cfg.RateLimit) healthChecker := middleware.NewHealthChecker(cfg.Services) app.Use(rateLimiter.Handler()) proxyManager := proxy.NewManager(cfg.Services) securityManager := security.NewManager(cfg.Security) v1 := app.Group("/api/v1") app.Get("/health", handlers.HealthCheck) app.Get("/metrics", handlers.Metrics) v1.Use(authMiddleware.Handler()) v1.Use(healthChecker.Handler()) v1.Use(securityManager.Handler()) v1.All("/game/*", proxyManager.ProxyToService("game-service")) v1.All("/questions/*", proxyManager.ProxyToService("question-service")) v1.All("/users/*", proxyManager.ProxyToService("user-service")) v1.All("/leaderboard/*", proxyManager.ProxyToService("leaderboard-service")) v1.All("/sessions/*", proxyManager.ProxyToService("session-service")) adminRoutes := v1.Group("/admin") adminRoutes.Use(authMiddleware.RequireAdminRole()) adminRoutes.All("/*", proxyManager.ProxyToService("admin-service")) go func() { if err := app.Listen(cfg.Server.Port); err != nil { log.Printf("Gateway server error: %v", err) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Println("Shutting down gateway server...") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := app.ShutdownWithContext(ctx); err != nil { log.Printf("Gateway server shutdown error: %v", err) } log.Println("Gateway server shutdown complete") }