package router import ( "github.com/gin-gonic/gin" "zeromesh/internal/config" "zeromesh/internal/database" "zeromesh/internal/handler" "zeromesh/internal/middleware" "zeromesh/internal/repository" "zeromesh/internal/service" ) func Setup(cfg *config.Config, db *database.DB) *gin.Engine { r := gin.Default() // Repositories userRepo := repository.NewUserRepo(db) netRepo := repository.NewNetworkRepo(db) nodeRepo := repository.NewNodeRepo(db) logRepo := repository.NewLogRepo(db) // Services authService := service.NewAuthService(userRepo, cfg.JWT) netService := service.NewNetworkService(netRepo, nodeRepo, userRepo) nodeService := service.NewNodeService(nodeRepo, userRepo) logService := service.NewLogService(logRepo) // Global middleware r.Use(middleware.CORS(cfg.CORS.AllowedOrigins)) if cfg.RateLimit.Enabled { rl := middleware.NewRateLimiter(cfg.RateLimit.RequestsPerSecond, cfg.RateLimit.BurstSize) r.Use(rl.Handler()) } requestLogger := middleware.NewRequestLogger(logService) r.Use(requestLogger.Handler()) // Handlers authHandler := handler.NewAuthHandler(authService) netHandler := handler.NewNetworkHandler(netService) nodeHandler := handler.NewNodeHandler(nodeService) adminHandler := handler.NewAdminHandler(authService, db, nodeService, netService) logHandler := handler.NewLogHandler(logService) // Logging API — skip logger middleware (avoid recursion) logApi := r.Group("/api/v1/log") logApi.Use(middleware.JWTAuth(cfg.JWT.Secret)) { logApi.GET("/api", logHandler.ListApiLogs) logApi.GET("/error", logHandler.ListErrorLogs) logApi.GET("/grouped", logHandler.ListApiLogGrouped) logApi.DELETE("/api", logHandler.ClearApiLogs) logApi.DELETE("/error", logHandler.ClearErrorLogs) } // Public routes r.GET("/api/health", func(c *gin.Context) { c.JSON(200, gin.H{"status": "ok"}) }) r.GET("/api/v1/admin/check", authHandler.CheckAdmin) api := r.Group("/api/v1") { api.POST("/auth/login", authHandler.Login) api.POST("/auth/register", authHandler.Register) api.POST("/auth/init", authHandler.InitAdmin) } // Authenticated routes auth := r.Group("/api/v1") auth.Use(middleware.JWTAuth(cfg.JWT.Secret)) { // Dashboard (user + admin) auth.GET("/dashboard", adminHandler.Dashboard) // Profile auth.GET("/user/profile", func(c *gin.Context) { uid := c.GetUint("user_id") u, err := userRepo.FindByID(uid) if err != nil { c.JSON(404, gin.H{"error": "user not found"}) return } netCount, _ := netRepo.CountByUser(uid) nodeCount, _ := nodeRepo.CountByUser(uid) c.JSON(200, gin.H{ "user": u, "used_networks": netCount, "used_nodes": nodeCount, }) }) // Nodes (user-scoped) auth.POST("/node/register", nodeHandler.Register) auth.GET("/node/list", nodeHandler.List) auth.GET("/node/online", nodeHandler.ListOnline) // Networks (user-scoped) auth.POST("/network/create", netHandler.Create) auth.GET("/network/list", netHandler.List) auth.GET("/network/:id", netHandler.Get) auth.DELETE("/network/:id", netHandler.Delete) auth.GET("/network/:id/members", netHandler.Members) auth.POST("/network/:id/authorize", netHandler.Authorize) auth.POST("/network/:id/deauthorize", netHandler.Deauthorize) // Admin-only admin := auth.Group("/admin") admin.Use(func(c *gin.Context) { if c.GetString("role") != "admin" { c.AbortWithStatusJSON(403, gin.H{"error": "forbidden"}) return } c.Next() }) { admin.GET("/dashboard", adminHandler.Dashboard) admin.GET("/networks", netHandler.List) admin.GET("/nodes", nodeHandler.List) } } return r }