package router import ( "net/http" "net/http/httputil" "net/url" "strings" "github.com/basketikun/infinite-canvas/handler" "github.com/basketikun/infinite-canvas/middleware" "github.com/gin-gonic/gin" ) const webBaseURL = "http://127.0.0.1:3001" func New() *gin.Engine { router := gin.Default() router.RedirectTrailingSlash = false _ = router.SetTrustedProxies(nil) api := router.Group("/api") api.GET("/health", func(c *gin.Context) { c.String(http.StatusOK, "ok") }) api.POST("/auth/register", gin.WrapF(handler.Register)) api.POST("/auth/login", gin.WrapF(handler.Login)) api.GET("/auth/me", middleware.OptionalAuth, gin.WrapF(handler.CurrentUser)) api.GET("/prompts", middleware.OptionalAuth, gin.WrapF(handler.Prompts)) api.GET("/assets", middleware.OptionalAuth, gin.WrapF(handler.Assets)) api.POST("/admin/login", gin.WrapF(handler.AdminLogin)) admin := api.Group("/admin", middleware.AdminAuth) admin.GET("/users", gin.WrapF(handler.AdminUsers)) admin.POST("/users", gin.WrapF(handler.AdminSaveUser)) admin.DELETE("/users/:id", func(c *gin.Context) { handler.AdminDeleteUser(c.Writer, c.Request, c.Param("id")) }) admin.GET("/prompt-categories", gin.WrapF(handler.AdminPromptCategories)) admin.POST("/prompt-categories/sync", gin.WrapF(handler.AdminSyncPromptCategories)) admin.GET("/prompts", gin.WrapF(handler.AdminPrompts)) admin.POST("/prompts", gin.WrapF(handler.AdminSavePrompt)) admin.DELETE("/prompts/:id", func(c *gin.Context) { handler.AdminDeletePrompt(c.Writer, c.Request, c.Param("id")) }) admin.GET("/assets", gin.WrapF(handler.AdminAssets)) admin.POST("/assets", gin.WrapF(handler.AdminSaveAsset)) admin.DELETE("/assets/:id", func(c *gin.Context) { handler.AdminDeleteAsset(c.Writer, c.Request, c.Param("id")) }) webURL, _ := url.Parse(webBaseURL) webProxy := httputil.NewSingleHostReverseProxy(webURL) router.NoRoute(func(c *gin.Context) { path := c.Request.URL.Path if path == "/api" || strings.HasPrefix(path, "/api/") { middleware.NotFoundJSON(c) return } webProxy.ServeHTTP(c.Writer, c.Request) }) return router }