package routes import ( "sno/internal/handlers" "sno/internal/middleware" "sno/internal/service" "sno/internal/types" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/gofiber/fiber/v2/middleware/cors" ) func Setup(app *fiber.App, quizHandler *handlers.QuizHandler, questionHandler *handlers.QuestionHandler, rewardHandler *handlers.RewardHandler, userHandler *handlers.UserHandler, adminHandler *handlers.AdminHandler, qrHandler *handlers.QRHandler, authHandler *handlers.AuthHandler, adminService service.AdminService, botToken string) { // General middleware app.Use(logger.New()) // CORS middleware - must come before auth middleware to handle preflight requests app.Use(cors.New(cors.Config{ AllowOrigins: "*", AllowMethods: "GET,POST,PUT,DELETE,OPTIONS", AllowHeaders: "Origin,Content-Type,Accept,Authorization,X-Telegram-Init-Data,X-Telegram-WebApp-Init-Data", AllowCredentials: false, ExposeHeaders: "Content-Length", MaxAge: 86400, // Pre-flight request cache duration (24 hours) })) // Group API routes api := app.Group("/api") // --- Auth Routes --- api.Post("/auth/validate", authHandler.Validate) // Validates Telegram initData without middleware auth := api.Group("/auth") auth.Use(middleware.AuthMiddleware(middleware.AuthConfig{BotToken: botToken})) auth.Get("/me", authHandler.GetMe) // Get current authenticated user auth.Get("/admin-role", authHandler.GetAdminRole) // Get admin role for current user // --- Protected Routes (require auth) --- protected := api.Group("") protected.Use(middleware.AuthMiddleware(middleware.AuthConfig{BotToken: botToken})) // --- User Routes --- protected.Get("/me", userHandler.GetMe) // Get current user profile user := protected.Group("/user") user.Get("/transactions", userHandler.GetUserTransactions) user.Get("/purchases", userHandler.GetUserPurchases) // --- Quiz Routes --- quiz := protected.Group("/quizzes") quiz.Get("/", quizHandler.GetAllQuizzes) quiz.Get("/:id", quizHandler.GetQuizByID) quiz.Post("/:id/submit", quizHandler.SubmitQuiz) quiz.Get("/:id/can-repeat", quizHandler.CanRepeat) // --- Reward (Shop) Routes --- reward := protected.Group("/rewards") reward.Get("/", rewardHandler.GetAllRewards) reward.Post("/:id/purchase", rewardHandler.PurchaseReward) // --- QR & Deep Link Routes --- qr := protected.Group("/qr") qr.Post("/validate", qrHandler.Validate) // --- Admin Routes (with role-based middleware) --- admin := api.Group("/admin") // Admin middleware configuration adminConfig := middleware.AdminConfig{ AdminService: adminService, // Need to pass this from main } // Admin routes requiring any admin role (admin or operator) adminAnyRole := admin.Group("") adminAnyRole.Use(middleware.WithAdminRoles(adminConfig, types.RoleAdmin, types.RoleOperator)) // Admin routes requiring admin role only adminOnly := admin.Group("") adminOnly.Use(middleware.WithAdminRoles(adminConfig, types.RoleAdmin)) // Admin: Quizzes (operator+) adminAnyRole.Post("/quizzes", quizHandler.CreateQuiz) adminAnyRole.Post("/quizzes/:quiz_id/questions", questionHandler.CreateQuestion) adminAnyRole.Put("/quizzes/:quiz_id/questions/:question_id", questionHandler.UpdateQuestion) adminAnyRole.Delete("/quizzes/:quiz_id/questions/:question_id", questionHandler.DeleteQuestion) adminOnly.Put("/quizzes/:id", quizHandler.UpdateQuiz) adminOnly.Delete("/quizzes/:id", quizHandler.DeleteQuiz) // Admin: Rewards (operator+) adminAnyRole.Post("/rewards", rewardHandler.CreateReward) adminOnly.Put("/rewards/:id", rewardHandler.UpdateReward) adminOnly.Delete("/rewards/:id", rewardHandler.DeleteReward) // Admin: Users & Balance (admin only) adminOnly.Post("/users/grant-stars", adminHandler.GrantStars) adminAnyRole.Post("/qrcodes", adminHandler.GenerateQRCodes) // Admin: Operators (admin only) adminOnly.Post("/operators", adminHandler.CreateOperator) adminOnly.Delete("/operators/:id", adminHandler.DeleteOperator) // Admin: Analytics (operator+) adminAnyRole.Get("/analytics", adminHandler.GetAnalytics) }