package httpapi import ( "errors" "net/http" "strings" "github.com/descrybe/descrybe-v2/apps/api/internal/aiprompts" "github.com/descrybe/descrybe-v2/apps/api/internal/aiprovider" "github.com/descrybe/descrybe-v2/apps/api/internal/company" ) func (s *Server) handleGetAIIntegration(w http.ResponseWriter, r *http.Request) { if s.AI == nil { Error(w, http.StatusServiceUnavailable, "ai integration unavailable") return } cid, _ := CompanyIDFromContext(r.Context()) cfg, err := s.AI.GetConfig(r.Context(), cid) if err != nil { Error(w, http.StatusInternalServerError, "failed to load ai settings") return } JSON(w, http.StatusOK, cfg) } func (s *Server) handlePutAIIntegration(w http.ResponseWriter, r *http.Request) { role, _ := RoleFromContext(r.Context()) if role != "admin" { Error(w, http.StatusForbidden, "admin required") return } if s.AI == nil { Error(w, http.StatusServiceUnavailable, "ai integration unavailable") return } cid, _ := CompanyIDFromContext(r.Context()) var body aiprovider.UpdateInput if err := DecodeJSON(r, &body); err != nil { Error(w, http.StatusBadRequest, "invalid json") return } cfg, err := s.AI.UpdateConfig(r.Context(), cid, body) if err != nil { ClientOrLog(w, http.StatusBadRequest, "could not update ai settings", err, aiprovider.ClientError) return } JSON(w, http.StatusOK, cfg) } func (s *Server) handleTestAIIntegration(w http.ResponseWriter, r *http.Request) { role, _ := RoleFromContext(r.Context()) if role != "admin" { Error(w, http.StatusForbidden, "admin required") return } if s.AI == nil { Error(w, http.StatusServiceUnavailable, "ai integration unavailable") return } cid, _ := CompanyIDFromContext(r.Context()) result, err := s.AI.TestConnection(r.Context(), cid) if errors.Is(err, aiprovider.ErrNotConfigured) { Error(w, http.StatusBadRequest, "ai provider not configured") return } if err != nil { // Safe message only — never echo provider error bodies (may contain key fragments). JSON(w, http.StatusOK, result) return } JSON(w, http.StatusOK, result) } func (s *Server) handleGetAIPrompts(w http.ResponseWriter, r *http.Request) { if s.AIPrompts == nil { Error(w, http.StatusServiceUnavailable, "ai prompts unavailable") return } cid, _ := CompanyIDFromContext(r.Context()) lang := strings.TrimSpace(r.URL.Query().Get("language")) if lang == "" { lang = company.LoadLanguage(r.Context(), s.Pool, cid) } bundle, err := s.AIPrompts.GetBundle(r.Context(), cid, lang) if err != nil { Error(w, http.StatusInternalServerError, "failed to load ai prompts") return } JSON(w, http.StatusOK, bundle) } func (s *Server) handlePutAIPrompts(w http.ResponseWriter, r *http.Request) { role, _ := RoleFromContext(r.Context()) if role != "admin" { Error(w, http.StatusForbidden, "admin required") return } if s.AIPrompts == nil { Error(w, http.StatusServiceUnavailable, "ai prompts unavailable") return } cid, _ := CompanyIDFromContext(r.Context()) var body aiprompts.UpdateInput if err := DecodeJSON(r, &body); err != nil { Error(w, http.StatusBadRequest, "invalid json") return } bundle, err := s.AIPrompts.Update(r.Context(), cid, body) if err != nil { ClientOrLog(w, http.StatusBadRequest, "could not update ai prompts", err, aiprompts.ClientError) return } JSON(w, http.StatusOK, bundle) }