package server import ( "context" "fmt" "net/http" "os" "markdown-editor/internal/handlers" "markdown-editor/internal/logger" "markdown-editor/internal/storage" "github.com/gorilla/mux" "github.com/rs/cors" "github.com/sirupsen/logrus" ) type Server struct { logger *logrus.Logger storage storage.Storage handlers *handlers.Handlers router *mux.Router server *http.Server dataDir string port int host string } func StartServer(dataDir string, port int, host string) error { log := logger.NewLogger() log.Info("Starting markdown editor server") // Initialize storage storage, err := storage.NewFileStorage(dataDir) if err != nil { log.Errorf("Failed to initialize storage: %v", err) return err } // Initialize handlers handlers := handlers.NewHandlers(log, storage) // Create server s := &Server{ logger: log, storage: storage, handlers: handlers, dataDir: dataDir, port: port, host: host, } // Setup routes s.setupRoutes() // Start server s.logger.Infof("Server starting on %s:%d", host, port) return s.serve() } func (s *Server) setupRoutes() { s.router = mux.NewRouter() // API routes apiRouter := s.router.PathPrefix("/api").Subrouter() apiRouter.Handle("/files", s.handlers.ListFiles()).Methods("GET") apiRouter.Handle("/files", s.handlers.CreateFile()).Methods("POST") apiRouter.Handle("/files/{filename}", s.handlers.GetFile()).Methods("GET") apiRouter.Handle("/files/{filename}", s.handlers.UpdateFile()).Methods("PUT") apiRouter.Handle("/files/{filename}", s.handlers.DeleteFile()).Methods("DELETE") // Static file serving frontendDir := "frontend/build" if frontendDirEnv := os.Getenv("FRONTEND_BUILD_DIR"); frontendDirEnv != "" { frontendDir = frontendDirEnv } s.router.PathPrefix("/").Handler(http.FileServer(http.Dir(frontendDir))) // Enable CORS cors := cors.New(cors.Options{ AllowedOrigins: []string{"http://localhost:3000", "http://localhost:8080"}, AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, AllowedHeaders: []string{"Content-Type", "Authorization"}, AllowCredentials: true, }) s.router.Use(cors.Handler) } func (s *Server) serve() error { s.server = &http.Server{ Addr: fmt.Sprintf("%s:%d", s.host, s.port), Handler: s.router, } return s.server.ListenAndServe() } func (s *Server) Shutdown(ctx context.Context) error { s.logger.Info("Shutting down server...") return s.server.Shutdown(ctx) }