package main import ( "fmt" "net/http" "os" "github.com/evanreichard/markdown-editor/internal/api" "github.com/evanreichard/markdown-editor/internal/config" "github.com/evanreichard/markdown-editor/internal/logging" "github.com/evanreichard/markdown-editor/internal/router" "github.com/evanreichard/markdown-editor/internal/storage" "github.com/spf13/cobra" ) var ( dataDir string port string host string staticDir string ) var rootCmd = &cobra.Command{ Use: "server", Short: "Markdown editor server", Long: "A markdown editor server with REST API and frontend support", Run: runServer, } func init() { rootCmd.Flags().StringVar(&dataDir, "data-dir", "./data", "Storage path for markdown files") rootCmd.Flags().StringVar(&port, "port", "8080", "Server port") rootCmd.Flags().StringVar(&host, "host", "127.0.0.1", "Bind address") rootCmd.Flags().StringVar(&staticDir, "static-dir", "./frontend/dist", "Path to static assets") } func runServer(cmd *cobra.Command, args []string) { cfg := &config.Config{ DataDir: dataDir, Port: port, Host: host, } logging.Init() logging.Logger.WithFields(map[string]interface{}{ "data_dir": cfg.DataDir, "host": cfg.Host, "port": cfg.Port, "static_dir": staticDir, }).Info("Starting markdown editor server") // Initialize storage store, err := storage.New(cfg.DataDir) if err != nil { logging.Logger.WithError(err).Fatal("Failed to initialize storage") } // Initialize handlers handlers := api.New(store) // Create router mux := router.New(handlers, staticDir) // Wrap with logging middleware handler := logging.RequestMiddleware(mux) // Start server addr := cfg.Addr() logging.Logger.WithField("addr", addr).Info("Server listening") if err := http.ListenAndServe(addr, handler); err != nil { logging.Logger.WithError(err).Fatal("Server error") } } func main() { if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } }