package routes import ( "fmt" "net/http" handlers "go-server/internal/handlers" "go-server/internal/middleware" "go-server/internal/repository" "go-server/internal/service" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // Route defines the structure for dynamic routing type Route struct { Method string Path string HandlerFunc gin.HandlerFunc IsAuthRequired bool } // Controller defines the structure for a controller with routes type Controller struct { Routes []Route } // SetupRouter dynamically sets up routes func SetupRouter(db *gorm.DB) *gin.Engine { gin.SetMode(gin.ReleaseMode) r := gin.New() r.Use(middleware.CORS()) r.Use(middleware.Logger()) r.Use(gin.Recovery()) // Serve simple text at "/" r.GET("/", func(c *gin.Context) { c.String(http.StatusOK, "Hello") }) // Custom 404 handler r.NoRoute(func(c *gin.Context) { c.String(http.StatusNotFound, "Not Found") }) // Initialize Repositories userRepo := repository.NewUserRepository(db) nutrientRepo := repository.NewNutrientRepository(db) supplementRepo := repository.NewSupplementRepository(db) dailyOverviewRepo := repository.NewDailyOverviewRepository(db) categoryRepo := repository.NewCategoryRepository(db) todoRepo := repository.NewTodoRepository(db) // Initialize Services userService := service.NewUserService(userRepo) nutrientService := service.NewNutrientService(nutrientRepo) supplementService := service.NewSupplementService(supplementRepo, nutrientRepo) dailyOverviewService := service.NewDailyOverviewService(dailyOverviewRepo) categoryService := service.NewCategoryService(categoryRepo) todoService := service.NewTodoService(todoRepo) // Initialize Controllers adminController := handlers.NewAdminController(userService) nutrientController := handlers.NewNutrientController(nutrientService) supplementController := handlers.NewSupplementController(supplementService) dailyOverviewController := handlers.NewDailyOverviewController(dailyOverviewService) categoryController := handlers.NewCategoryController(categoryService) todoController := handlers.NewTodoController(todoService) skipAuth := true // Define controllers and their routes controllers := map[string]Controller{ "admin": { Routes: []Route{ {"GET", "/user/get-all", adminController.GetUsers, true}, {"DELETE", "/user/:id", adminController.DeleteUser, true}, {"POST", "/user/:id/change-password", adminController.ChangePassword, true}, {"POST", "/user", adminController.CreateUser, true}, }, }, "nutrient": { Routes: []Route{ {"GET", "/get-all", nutrientController.GetAll, !skipAuth}, }, }, "supplement": { Routes: []Route{ {"GET", "/get-all", supplementController.GetAll, !skipAuth}, {"GET", "/get-daily-supplements-overview", supplementController.GetDailySupplementsOverview, !skipAuth}, }, }, "daily-overview": { Routes: []Route{ {"GET", "/overview", dailyOverviewController.GetDailyOverview, !skipAuth}, // Complete overview {"GET", "/totals", dailyOverviewController.GetNutrientTotals, !skipAuth}, // Just nutrient totals {"GET", "/breakdown", dailyOverviewController.GetSupplementBreakdown, !skipAuth}, // Supplement breakdown {"POST", "/query", dailyOverviewController.ExecuteCustomQuery, !skipAuth}, // Custom SQL queries }, }, "category": { Routes: []Route{ {"GET", "/get-all", categoryController.GetAll, !skipAuth}, }, }, "todo": { Routes: []Route{ {"POST", "/create", todoController.CreateTodo, !skipAuth}, // Create new todo {"GET", "/list", todoController.GetTodos, !skipAuth}, // Get all todos with stats {"GET", "/today", todoController.GetTodaysSummary, !skipAuth}, // Get today's summary {"PUT", "/:id", todoController.UpdateTodo, !skipAuth}, // Update todo {"DELETE", "/:id", todoController.DeleteTodo, !skipAuth}, // Delete todo {"POST", "/:id/complete", todoController.CompleteTodo, !skipAuth}, // Complete todo {"GET", "/activity", todoController.GetActivityLog, !skipAuth}, // Get activity log {"GET", "/activity/:date", todoController.GetActivityLogByDate, !skipAuth}, // Get activity for date {"GET", "/weekly", todoController.GetWeeklySummary, !skipAuth}, // Get weekly summary }, }, } // Register all routes dynamically api := r.Group("/api") apiPublic := api.Group("") apiAuth := api.Group("") apiAuth.Use(middleware.AuthRequired()) for key, controller := range controllers { for _, route := range controller.Routes { path := fmt.Sprintf("/%s%s", key, route.Path) fmt.Println("Route registered", route.Method, path) if route.IsAuthRequired { apiAuth.Handle(route.Method, path, route.HandlerFunc) } else { apiPublic.Handle(route.Method, path, route.HandlerFunc) } } } return r }