Files
Agent-System/internal/server/chat_search_api.go
T
weichenandCursor d9f3d40423 feat(abac): enforce stage access on chat, search and SSE streams.
Tag messages with stage_key metadata, block sends for unauthorized roles, and filter history/search/case results by allowed stages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00

82 lines
2.2 KiB
Go

package server
import (
"encoding/json"
"net/http"
"strconv"
"strings"
"chat-agent-system/internal/ctxmgr"
)
// handleChatSearch 处理消息三模检索 (keyword/fuzzy/semantic/hybrid)
// GET /api/v1/chat/search?session_id=&q=&mode=&category=&date_from=&date_to=&limit=&user_id=
func (s *Server) handleChatSearch(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
return
}
user, ok := s.requireAuthenticatedUser(w, r)
if !ok {
return
}
if s.svc == nil || s.svc.ContextManager() == nil {
http.Error(w, "context manager not initialized", http.StatusServiceUnavailable)
return
}
sessionID := strings.TrimSpace(r.URL.Query().Get("session_id"))
if sessionID == "" {
http.Error(w, "missing required query param 'session_id'", http.StatusBadRequest)
return
}
query := strings.TrimSpace(r.URL.Query().Get("q"))
if query == "" {
http.Error(w, "missing or empty query param 'q'", http.StatusBadRequest)
return
}
mode := ctxmgr.ChatSearchMode(strings.TrimSpace(r.URL.Query().Get("mode")))
category := strings.TrimSpace(r.URL.Query().Get("category"))
dateFrom := strings.TrimSpace(r.URL.Query().Get("date_from"))
dateTo := strings.TrimSpace(r.URL.Query().Get("date_to"))
limit := 50
if limStr := r.URL.Query().Get("limit"); limStr != "" {
if val, err := strconv.Atoi(limStr); err == nil && val > 0 {
limit = val
}
}
searchQuery := ctxmgr.ChatSearchQuery{
SessionID: sessionID,
UserID: user.ID,
Query: query,
Mode: mode,
Category: category,
DateFrom: dateFrom,
DateTo: dateTo,
Limit: limit,
}
hits, err := s.svc.ContextManager().SearchChatMessages(r.Context(), searchQuery)
if err != nil {
http.Error(w, "SearchChatMessages error: "+err.Error(), http.StatusInternalServerError)
return
}
if projectID, pidErr := s.svc.ContextManager().GetSessionProjectID(r.Context(), sessionID); pidErr == nil && projectID > 0 {
hits = s.filterChatSearchHitsByStageAccess(r.Context(), projectID, user.ID, hits)
}
if hits == nil {
hits = []ctxmgr.ChatSearchHit{}
}
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(hits)
}