package server import ( "fmt" "log/slog" "net/http" "time" "level3.git.onstackit.cloud/LEVEL3/gabriel/src/api" "level3.git.onstackit.cloud/LEVEL3/gabriel/src/metrics" ) func (s *Server) IndexDoc(w http.ResponseWriter, r *http.Request, instanceId string) { slog.Debug("IndexDoc endpoint called", "instanceId", instanceId) start := time.Now() req, err := reqBody[api.DocumentCreateRequest](r.Body) if err != nil { slog.Debug("Failed to parse index doc request body", "error", err) http.Error(w, fmt.Sprintf("Invalid request body: %v", err), http.StatusBadRequest) return } if req.Text == "" { slog.Debug("Text is required") http.Error(w, "text is required", http.StatusBadRequest) return } username, ok := s.usernameFromCtx(r) if !ok { http.Error(w, "Internal server error", http.StatusInternalServerError) return } doc, err := s.search.Index(r.Context(), instanceId, username, req.Text, req.Index) if err != nil { slog.Error("Failed to index document", "instanceId", instanceId, "error", err) metrics.RecordESOp("index_doc", instanceId, "error", start) s.logs.Add(instanceId, api.IndexDoc, api.Failure, fmt.Sprintf("Failed to index document: %v", err), username) writeServiceError(w, err) return } slog.Info("Successfully indexed document", "instanceId", instanceId, "docId", doc.ID) metrics.RecordESOp("index_doc", instanceId, "ok", start) s.logs.Add(instanceId, api.IndexDoc, api.Success, fmt.Sprintf("Document indexed (id: %s)", doc.ID), username) writeJSONResponse(w, http.StatusCreated, api.DocumentIndexResponse{ DocumentId: doc.ID, Index: doc.Index, }) } func (s *Server) SearchDocs(w http.ResponseWriter, r *http.Request, instanceId string, params api.SearchDocsParams) { slog.Debug("SearchDocs endpoint called", "instanceId", instanceId, "query", params.Q) start := time.Now() username, ok := s.usernameFromCtx(r) if !ok { http.Error(w, "Internal server error", http.StatusInternalServerError) return } docs, err := s.search.Search(r.Context(), instanceId, username, params) if err != nil { slog.Error("Failed to search documents", "instanceId", instanceId, "error", err) metrics.RecordESOp("search", instanceId, "error", start) s.logs.Add(instanceId, api.SearchDocs, api.Failure, fmt.Sprintf("Search failed: %v", err), username) writeServiceError(w, err) return } slog.Debug("Search returned documents", "instanceId", instanceId, "count", len(docs)) metrics.RecordESOp("search", instanceId, "ok", start) s.logs.Add(instanceId, api.SearchDocs, api.Success, fmt.Sprintf("Search returned %d results", len(docs)), username) writeJSONResponse(w, http.StatusOK, docs) } func (s *Server) DeleteDoc(w http.ResponseWriter, r *http.Request, instanceId string, docId string, params api.DeleteDocParams) { slog.Debug("DeleteDoc endpoint called", "instanceId", instanceId, "docId", docId, "index", params.Index) start := time.Now() username, ok := s.usernameFromCtx(r) if !ok { http.Error(w, "Internal server error", http.StatusInternalServerError) return } if err := s.search.Delete(r.Context(), instanceId, username, docId, params); err != nil { slog.Error("Failed to delete document", "instanceId", instanceId, "docId", docId, "error", err) metrics.RecordESOp("doc_delete", instanceId, "error", start) s.logs.Add(instanceId, api.DeleteDoc, api.Failure, fmt.Sprintf("Failed to delete document '%s'", docId), username) writeServiceError(w, err) return } slog.Info("Successfully deleted document", "instanceId", instanceId, "docId", docId) metrics.RecordESOp("doc_delete", instanceId, "ok", start) s.logs.Add(instanceId, api.DeleteDoc, api.Success, fmt.Sprintf("Document '%s' deleted", docId), username) w.WriteHeader(http.StatusNoContent) } func (s *Server) ListIndices(w http.ResponseWriter, r *http.Request, instanceId string) { slog.Debug("ListIndices endpoint called", "instanceId", instanceId) start := time.Now() username, ok := s.usernameFromCtx(r) if !ok { http.Error(w, "Internal server error", http.StatusInternalServerError) return } indices, err := s.search.ListIndices(r.Context(), instanceId, username) if err != nil { slog.Error("Failed to list indices", "instanceId", instanceId, "error", err) metrics.RecordESOp("list_indices", instanceId, "error", start) s.logs.Add(instanceId, api.ListIndices, api.Failure, fmt.Sprintf("Failed to list indices: %v", err), username) writeServiceError(w, err) return } slog.Debug("Listed indices", "instanceId", instanceId, "count", len(indices)) metrics.RecordESOp("list_indices", instanceId, "ok", start) s.logs.Add(instanceId, api.ListIndices, api.Success, fmt.Sprintf("Listed %d indices", len(indices)), username) writeJSONResponse(w, http.StatusOK, api.IndexList{Indices: indices}) }