From 9b89b7b9ab2e4262d67fa3fea89ac97eee4176df Mon Sep 17 00:00:00 2001 From: Vladimir Zagainov Date: Mon, 17 Aug 2026 23:12:24 +0300 Subject: [PATCH] fix: address code review findings --- cmd/api/handlers.go | 14 +++++++++++--- internal/routing/graph.go | 13 +++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/cmd/api/handlers.go b/cmd/api/handlers.go index d77b082..e7fb504 100644 --- a/cmd/api/handlers.go +++ b/cmd/api/handlers.go @@ -438,7 +438,7 @@ func adminAuth(hc *HandlerContext, w http.ResponseWriter, r *http.Request) bool } providedAPIKey := r.Header.Get("X-Admin-Api-Key") if !hmac.Equal([]byte(providedAPIKey), []byte(expectedAPIKey)) { - http.Error(w, "unauthorized: admin API key required", http.StatusUnauthorized) + http.Error(w, "unauthorized: invalid admin API key", http.StatusUnauthorized) return false } return true @@ -574,11 +574,13 @@ func RemoveSavedCity(hc *HandlerContext, w http.ResponseWriter, r *http.Request) userID = "default" } - cityCode := strings.TrimPrefix(r.URL.Path, "/v1/preferences/saved-cities/") - if cityCode == "" || cityCode == "/v1/preferences/saved-cities/" { + parts := strings.Split(r.URL.Path, "/") + // Expected: /v1/preferences/saved-cities/{city_code} -> parts: ["", "v1", "preferences", "saved-cities", "{city_code}"] + if len(parts) < 5 { http.Error(w, "missing city code", http.StatusBadRequest) return } + cityCode := parts[4] if err := hc.Preferences.RemoveSavedCity(r.Context(), userID, cityCode); err != nil { http.Error(w, "failed to remove saved city: "+err.Error(), http.StatusInternalServerError) @@ -628,6 +630,12 @@ func AddSearchHistory(hc *HandlerContext, w http.ResponseWriter, r *http.Request return } + // Validate input length + if len(req.FromCity) > 100 || len(req.ToCity) > 100 || len(req.Date) > 20 { + http.Error(w, "invalid city or date format", http.StatusBadRequest) + return + } + if err := hc.Preferences.AddSearchHistory(r.Context(), userID, req.FromCity, req.ToCity, req.Date); err != nil { http.Error(w, "failed to add search history: "+err.Error(), http.StatusInternalServerError) return diff --git a/internal/routing/graph.go b/internal/routing/graph.go index f11f76c..c55bb8e 100644 --- a/internal/routing/graph.go +++ b/internal/routing/graph.go @@ -343,7 +343,9 @@ func (g *Graph) FindRoute(originID, destID string, opts SearchOptions, closedSta } } } - } // Build adjacency list from edges + } + + // Build adjacency list from edges adj := g.buildAdjacencyList() // BFS with transfer tracking @@ -976,7 +978,7 @@ type HubStation struct { // rule from the transfer rules, or returns the default MCT. func getMCTForTransfer(optsMCT int, g *Graph) int { // Default MCT if no rules match - defaultMCT := 1800 // 30 minutes + defaultMCT := storage.DefaultMCT // 30 minutes // If the user explicitly set an MCT via SearchOptions, prefer that if optsMCT > 0 { @@ -984,11 +986,10 @@ func getMCTForTransfer(optsMCT int, g *Graph) int { } // Try to determine MCT from node types in the graph - // This is a simplified lookup; in a full implementation, this would - // query the transfer_rules table from the database + // In a full implementation, this would query the transfer_rules table + // from the database using storage.MinTransferTime(ruleKey, rules, defaultMCT) + // For now, return the default MCT. - // For now, return the default MCT. In a full implementation, - // this would query the transfer_rules table. return defaultMCT }