sno-quiz/backend/internal/routes/routes.go
2025-09-17 22:22:14 +03:00

104 lines
4.0 KiB
Go

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)
}