Files
boc/backend/handlers/landvex_real.go
T
Bernt 78b57273e2 security: Add proper authentication, RBAC, and tenant isolation
- Add password hashing with bcrypt
- Add AuthService with proper login
- Add password strength validation
- Add RBAC middleware (AdminOnly, ManagerOrAdmin)
- Add tenant isolation middleware
- Update CRM handler with tenant filtering
- Add JWT fallback for development mode
- Add user context helpers
- Build successful
2026-08-10 12:52:48 +00:00

225 lines
5.5 KiB
Go

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,
})
}