package http import ( "context" "embed" "fmt" "io/fs" "net/http" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" "trankilou.fr/lassistanoque/backend/internal/config" "trankilou.fr/lassistanoque/backend/internal/http/handlers" "trankilou.fr/lassistanoque/backend/internal/service/agent" "trankilou.fr/lassistanoque/backend/internal/service/auth" "trankilou.fr/lassistanoque/backend/internal/service/chat" "trankilou.fr/lassistanoque/backend/internal/service/provider" "trankilou.fr/lassistanoque/backend/internal/service/storage" "trankilou.fr/lassistanoque/backend/internal/service/task" "trankilou.fr/lassistanoque/backend/internal/service/tool" "trankilou.fr/lassistanoque/backend/internal/service/user" ) //go:embed web/_app/* var appFiles embed.FS //go:embed web/assets/* var assetsFiles embed.FS //go:embed web/index.html var indexhtml []byte //go:embed web/robots.txt var robotstxt []byte type Router struct { server *http.Server } type Dependencies struct { StorageService *storage.Service AuthService *auth.Service UserService *user.Service ProviderService *provider.Service AgentService *agent.Service ChatService *chat.Service ToolService *tool.Service TaskService *task.Service TokenManager auth.TokenManager } func NewRouter(deps Dependencies) *Router { cfg := config.GetConfig() e := echo.New() e.Use(middleware.RequestLogger()) e.Use(middleware.CORS("http://localhost:5173")) // SPA fsapp, err := fs.Sub(appFiles, "web/_app") if err != nil { panic(err) } fsassets, err := fs.Sub(assetsFiles, "web/assets") if err != nil { panic(err) } appHandler := http.FileServer(http.FS(fsapp)) assetsHandler := http.FileServer(http.FS(fsassets)) e.GET("/_app/*", echo.WrapHandler(http.StripPrefix("/_app/", appHandler))) e.GET("/assets/*", echo.WrapHandler(http.StripPrefix("/assets/", assetsHandler))) e.GET("/robots.txt", func(c *echo.Context) error { return c.Blob(http.StatusOK, "plain/text", robotstxt) }) e.GET("/*", func(c *echo.Context) error { fmt.Println("match /*") fmt.Println(string(indexhtml)) return c.Blob(http.StatusOK, "text/html", indexhtml) }) // API api := e.Group("/api") _ = handlers.NewAuthGroup("/auth", api, deps.AuthService) _ = handlers.NewUserGroup("/user", api, deps.UserService, deps.TokenManager.TokenMiddleware) _ = handlers.NewMiscGroup("/misc", api, deps.TokenManager.TokenMiddleware) _ = handlers.NewModelGroup("/provider", api, deps.ProviderService, deps.TokenManager.TokenMiddleware) _ = handlers.NewAgentGroup("/agent", api, deps.AgentService, deps.UserService, deps.TokenManager.TokenMiddleware) _ = handlers.NewToolGroup("/tool", api, deps.ToolService, deps.UserService, deps.TokenManager.TokenMiddleware) _ = handlers.NewTeamGroup("/team", api, deps.UserService, deps.TokenManager.TokenMiddleware) _ = handlers.NewChatGroup("/chat", api, deps.ChatService, deps.TokenManager.TokenMiddleware) _ = handlers.NewTaskGroup("/task", api, deps.TaskService, deps.TokenManager.TokenMiddleware) server := http.Server{ Addr: fmt.Sprintf(":%d", cfg.HttpPort), Handler: e, } return &Router{ &server, } } func (r *Router) Start() error { return r.server.ListenAndServe() } func (r *Router) Stop(ctx context.Context) error { return r.server.Shutdown(ctx) }