package handlers import ( "encoding/json" "io" "net/http" "net/url" "strings" "time" "github.com/go-chi/chi/v5" ) // LandvexRealHandler hanterar riktig integration mot Landvex API type LandvexRealHandler struct { baseURL string client *http.Client } // NewLandvexRealHandler skapar en ny handler func NewLandvexRealHandler() *LandvexRealHandler { return &LandvexRealHandler{ baseURL: getEnv("LANDVEX_API_URL", "http://172.17.0.1:8081"), client: &http.Client{Timeout: 10 * time.Second}, } } // LandvexObject representerar ett Landvex-objekt type LandvexObject struct { LvxID string `json:"lvx_id"` Slug string `json:"slug"` Namn map[string]string `json:"namn"` Beskrivning map[string]string `json:"beskrivning"` Kategorier []string `json:"kategorier"` Standarder []string `json:"standarder"` Metadata map[string]interface{} `json:"metadata"` } // LandvexSearchResult representerar sökresultat type LandvexSearchResult struct { LvxID string `json:"lvx_id"` Namn map[string]string `json:"namn"` Relevans float64 `json:"relevans"` Kategorier []string `json:"kategorier"` } // fetchFromLandvex hämtar data från Landvex API func (h *LandvexRealHandler) fetchFromLandvex(endpoint string) (map[string]interface{}, error) { resp, err := h.client.Get(h.baseURL + endpoint) if err != nil { return nil, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { return nil, err } return result, nil } // GetHealth hämtar health från Landvex func (h *LandvexRealHandler) GetHealth(w http.ResponseWriter, r *http.Request) { health, err := h.fetchFromLandvex("/health") if err != nil { writeJSON(w, http.StatusServiceUnavailable, map[string]interface{}{ "ok": false, "error": err.Error(), }) return } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "landvex": health, }) } // GetObjects hämtar alla objekt func (h *LandvexRealHandler) GetObjects(w http.ResponseWriter, r *http.Request) { // Sök efter alla objekt (tom sökning) results, err := h.fetchFromLandvex("/v0/search?q=") if err != nil { writeJSON(w, http.StatusServiceUnavailable, map[string]interface{}{ "ok": false, "error": err.Error(), }) return } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "results": results, }) } // GetObject hämtar ett specifikt objekt func (h *LandvexRealHandler) GetObject(w http.ResponseWriter, r *http.Request) { lvxID := chi.URLParam(r, "id") obj, err := h.fetchFromLandvex("/v0/objects/" + lvxID) if err != nil { writeJSON(w, http.StatusServiceUnavailable, map[string]interface{}{ "ok": false, "error": err.Error(), }) return } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "object": obj, }) } // Search söker i Landvex func (h *LandvexRealHandler) Search(w http.ResponseWriter, r *http.Request) { query := r.URL.Query().Get("q") if query == "" { writeJSON(w, http.StatusBadRequest, map[string]interface{}{ "ok": false, "error": "missing query parameter 'q'", }) return } resp, err := h.client.Get(h.baseURL + "/v0/search?q=" + url.QueryEscape(query)) if err != nil { writeJSON(w, http.StatusServiceUnavailable, map[string]interface{}{ "ok": false, "error": err.Error(), }) return } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { writeJSON(w, http.StatusInternalServerError, map[string]interface{}{ "ok": false, "error": err.Error(), }) return } // Landvex returnerar inte JSON med ok/error, utan direkt resultat var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "query": query, "raw": string(body), "parse_error": err.Error(), }) return } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "query": query, "results": result, }) } // Identify identifierar ett objekt från bild/text func (h *LandvexRealHandler) Identify(w http.ResponseWriter, r *http.Request) { var req struct { ImageURL string `json:"image_url,omitempty"` Description string `json:"description,omitempty"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeJSON(w, http.StatusBadRequest, map[string]interface{}{ "ok": false, "error": err.Error(), }) return } // Vidarebefordra till Landvex identify landvexReq := map[string]interface{}{ "image_url": req.ImageURL, "description": req.Description, } reqBody, _ := json.Marshal(landvexReq) resp, err := h.client.Post(h.baseURL+"/v0/identify", "application/json", strings.NewReader(string(reqBody))) if err != nil { writeJSON(w, http.StatusServiceUnavailable, map[string]interface{}{ "ok": false, "error": err.Error(), }) return } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { writeJSON(w, http.StatusInternalServerError, map[string]interface{}{ "ok": false, "error": err.Error(), }) return } var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { writeJSON(w, http.StatusInternalServerError, map[string]interface{}{ "ok": false, "error": err.Error(), }) return } writeJSON(w, http.StatusOK, map[string]interface{}{ "ok": true, "result": result, }) }