package server import ( "net/http" "gcy_hpc_server/internal/middleware" "github.com/gin-gonic/gin" "go.uber.org/zap" ) type JobHandler interface { SubmitJob(c *gin.Context) GetJobs(c *gin.Context) GetJobHistory(c *gin.Context) GetJob(c *gin.Context) CancelJob(c *gin.Context) } type ClusterHandler interface { GetNodes(c *gin.Context) GetNode(c *gin.Context) GetPartitions(c *gin.Context) GetPartition(c *gin.Context) GetDiag(c *gin.Context) } type ApplicationHandler interface { ListApplications(c *gin.Context) CreateApplication(c *gin.Context) GetApplication(c *gin.Context) UpdateApplication(c *gin.Context) DeleteApplication(c *gin.Context) SubmitApplication(c *gin.Context) } type UploadHandler interface { InitUpload(c *gin.Context) GetUploadStatus(c *gin.Context) UploadChunk(c *gin.Context) CompleteUpload(c *gin.Context) CancelUpload(c *gin.Context) } type FileHandler interface { ListFiles(c *gin.Context) GetFile(c *gin.Context) DownloadFile(c *gin.Context) DeleteFile(c *gin.Context) } type FolderHandler interface { CreateFolder(c *gin.Context) GetFolder(c *gin.Context) ListFolders(c *gin.Context) DeleteFolder(c *gin.Context) } type TaskHandler interface { CreateTask(c *gin.Context) ListTasks(c *gin.Context) } // NewRouter creates a Gin engine with all API v1 routes registered with real handlers. func NewRouter(jobH JobHandler, clusterH ClusterHandler, appH ApplicationHandler, uploadH UploadHandler, fileH FileHandler, folderH FolderHandler, taskH TaskHandler, logger *zap.Logger) *gin.Engine { gin.SetMode(gin.ReleaseMode) r := gin.New() r.Use(gin.Recovery()) if logger != nil { r.Use(middleware.RequestLogger(logger)) } v1 := r.Group("/api/v1") jobs := v1.Group("/jobs") jobs.POST("/submit", jobH.SubmitJob) jobs.GET("", jobH.GetJobs) jobs.GET("/history", jobH.GetJobHistory) jobs.GET("/:id", jobH.GetJob) jobs.DELETE("/:id", jobH.CancelJob) v1.GET("/nodes", clusterH.GetNodes) v1.GET("/nodes/:name", clusterH.GetNode) v1.GET("/partitions", clusterH.GetPartitions) v1.GET("/partitions/:name", clusterH.GetPartition) v1.GET("/diag", clusterH.GetDiag) apps := v1.Group("/applications") apps.GET("", appH.ListApplications) apps.POST("", appH.CreateApplication) apps.GET("/:id", appH.GetApplication) apps.PUT("/:id", appH.UpdateApplication) apps.DELETE("/:id", appH.DeleteApplication) apps.POST("/:id/submit", appH.SubmitApplication) files := v1.Group("/files") if uploadH != nil { uploads := files.Group("/uploads") uploads.POST("", uploadH.InitUpload) uploads.GET("/:id", uploadH.GetUploadStatus) uploads.PUT("/:id/chunks/:index", uploadH.UploadChunk) uploads.POST("/:id/complete", uploadH.CompleteUpload) uploads.DELETE("/:id", uploadH.CancelUpload) } if fileH != nil { files.GET("", fileH.ListFiles) files.GET("/:id", fileH.GetFile) files.GET("/:id/download", fileH.DownloadFile) files.DELETE("/:id", fileH.DeleteFile) } if folderH != nil { folders := files.Group("/folders") folders.POST("", folderH.CreateFolder) folders.GET("", folderH.ListFolders) folders.GET("/:id", folderH.GetFolder) folders.DELETE("/:id", folderH.DeleteFolder) } if taskH != nil { tasks := v1.Group("/tasks") { tasks.POST("", taskH.CreateTask) tasks.GET("", taskH.ListTasks) } } return r } // NewTestRouter creates a router for testing without real handlers. func NewTestRouter() *gin.Engine { gin.SetMode(gin.TestMode) r := gin.New() r.Use(gin.Recovery()) v1 := r.Group("/api/v1") registerPlaceholderRoutes(v1) return r } func registerPlaceholderRoutes(v1 *gin.RouterGroup) { jobs := v1.Group("/jobs") jobs.POST("/submit", notImplemented) jobs.GET("", notImplemented) jobs.GET("/history", notImplemented) jobs.GET("/:id", notImplemented) jobs.DELETE("/:id", notImplemented) v1.GET("/nodes", notImplemented) v1.GET("/nodes/:name", notImplemented) v1.GET("/partitions", notImplemented) v1.GET("/partitions/:name", notImplemented) v1.GET("/diag", notImplemented) apps := v1.Group("/applications") apps.GET("", notImplemented) apps.POST("", notImplemented) apps.GET("/:id", notImplemented) apps.PUT("/:id", notImplemented) apps.DELETE("/:id", notImplemented) apps.POST("/:id/submit", notImplemented) files := v1.Group("/files") uploads := files.Group("/uploads") uploads.POST("", notImplemented) uploads.GET("/:id", notImplemented) uploads.PUT("/:id/chunks/:index", notImplemented) uploads.POST("/:id/complete", notImplemented) uploads.DELETE("/:id", notImplemented) files.GET("", notImplemented) files.GET("/:id", notImplemented) files.GET("/:id/download", notImplemented) files.DELETE("/:id", notImplemented) folders := files.Group("/folders") folders.POST("", notImplemented) folders.GET("", notImplemented) folders.GET("/:id", notImplemented) folders.DELETE("/:id", notImplemented) v1.POST("/tasks", notImplemented) v1.GET("/tasks", notImplemented) } func notImplemented(c *gin.Context) { c.JSON(http.StatusNotImplemented, APIResponse{ Success: false, Error: "not implemented", }) }