diff --git a/cmd/server/main.go b/cmd/server/main.go index 16516fb..c7f07a3 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -12,13 +12,12 @@ import ( "bookhoard/internal/sync" "context" "log" - "net/http" "time" "github.com/go-playground/validator/v10" "github.com/jackc/pgx/v5/pgxpool" - "github.com/labstack/echo/v4" - echomiddleware "github.com/labstack/echo/v4/middleware" + "github.com/labstack/echo/v5" + echomiddleware "github.com/labstack/echo/v5/middleware" ) // CustomValidator wraps the go-playground validator @@ -139,7 +138,7 @@ func main() { e.Validator = &CustomValidator{validator: v} // Middleware - e.Use(echomiddleware.Logger()) + e.Use(echomiddleware.RequestLogger()) e.Use(echomiddleware.Recover()) e.Use(echomiddleware.CORS()) e.Use(ratelimit.RequestTracingMiddleware(cfg)) @@ -197,17 +196,14 @@ func main() { // ======================================================================== // START SERVER (managed by app lifecycle) // ======================================================================== - log.Printf("Starting server on port %s", cfg.ServerPort) - // Start HTTP server in background - go func() { - if err := e.Start(":" + cfg.ServerPort); err != nil && err != http.ErrServerClosed { - log.Fatalf("Server failed to start: %v", err) - } - }() + // Start HTTP server + if err := application.StartServer(":" + cfg.ServerPort); err != nil { + log.Fatalf("Failed to start server: %v", err) + } - // Start application (blocks until shutdown signal) + // Start application lifecycle (blocks until shutdown signal) if err := application.Start(); err != nil { log.Fatalf("Application error: %v", err) } diff --git a/internal/docs/http_handler.go b/internal/docs/http_handler.go index d670dfd..7aab862 100644 --- a/internal/docs/http_handler.go +++ b/internal/docs/http_handler.go @@ -8,8 +8,9 @@ import ( "bookhoard/internal/database" "bookhoard/templates" + "github.com/google/uuid" - "github.com/labstack/echo/v4" + "github.com/labstack/echo/v5" ) // HTTPHandler wraps the docs handler for Echo framework @@ -25,7 +26,7 @@ func NewHTTPHandler(docsPath string) *HTTPHandler { } // ShowDocumentation renders a documentation page -func (h *HTTPHandler) ShowDocumentation(c echo.Context) error { +func (h *HTTPHandler) ShowDocumentation(c *echo.Context) error { // Get the document path from URL parameter docPath := c.Param("*") @@ -101,7 +102,7 @@ func (h *HTTPHandler) ShowDocumentation(c echo.Context) error { } // ShowAPIEndpoint shows a specific API endpoint documentation -func (h *HTTPHandler) ShowAPIEndpoint(c echo.Context, endpointPath string) error { +func (h *HTTPHandler) ShowAPIEndpoint(c *echo.Context, endpointPath string) error { // Check if user is logged in isLoggedIn := false if userID := c.Get("user_id"); userID != nil { @@ -182,7 +183,7 @@ func (h *HTTPHandler) ShowAPIEndpoint(c echo.Context, endpointPath string) error } // showLegacyAPIEndpoint shows API endpoint documentation without explorer data -func (h *HTTPHandler) showLegacyAPIEndpoint(c echo.Context, endpointPath string, isLoggedIn bool) error { +func (h *HTTPHandler) showLegacyAPIEndpoint(c *echo.Context, endpointPath string, isLoggedIn bool) error { endpoints := h.docs.GetAPIEndpoints() // Find the endpoint @@ -269,12 +270,12 @@ func (h *HTTPHandler) showLegacyAPIEndpoint(c echo.Context, endpointPath string, } // DocsHome redirects to the documentation index -func (h *HTTPHandler) DocsHome(c echo.Context) error { +func (h *HTTPHandler) DocsHome(c *echo.Context) error { return c.Redirect(http.StatusFound, "/docs/index.md") } // APIHome shows the API documentation home page -func (h *HTTPHandler) APIHome(c echo.Context) error { +func (h *HTTPHandler) APIHome(c *echo.Context) error { endpoints := h.docs.GetAPIEndpoints() nav := h.docs.BuildNavigation() @@ -343,7 +344,7 @@ func (h *HTTPHandler) APIHome(c echo.Context) error { } // Search searches through documentation -func (h *HTTPHandler) Search(c echo.Context) error { +func (h *HTTPHandler) Search(c *echo.Context) error { query := c.QueryParam("q") if query == "" { return c.JSON(http.StatusBadRequest, map[string]string{ @@ -404,7 +405,7 @@ type SearchResult struct { } // TryEndpoint executes an API endpoint (for the interactive explorer) -func (h *HTTPHandler) TryEndpoint(c echo.Context) error { +func (h *HTTPHandler) TryEndpoint(c *echo.Context) error { // This would execute the actual API request // For now, return a placeholder return c.JSON(http.StatusOK, map[string]interface{}{ @@ -413,7 +414,7 @@ func (h *HTTPHandler) TryEndpoint(c echo.Context) error { } // ServeSearchIndex serves the Lunr.js search index -func (h *HTTPHandler) ServeSearchIndex(c echo.Context) error { +func (h *HTTPHandler) ServeSearchIndex(c *echo.Context) error { index, err := h.docs.GenerateSearchIndex() if err != nil { return c.JSON(http.StatusInternalServerError, map[string]string{