package main import ( "net/http" "strings" "time" ) type ChatSearchResult struct { ConversationID string `json:"conversationId"` MessageID string `json:"messageId"` Body string `json:"body"` SenderDisplayName string `json:"senderDisplayName"` CreatedAt time.Time `json:"createdAt"` } func (s *Server) handleSearchChatMessages(w http.ResponseWriter, r *http.Request) { user, ok := userFromContext(r.Context()) if !ok { writeError(w, http.StatusUnauthorized, "Unauthorized") return } query := strings.TrimSpace(r.URL.Query().Get("q")) if query == "" { writeJSON(w, http.StatusOK, map[string]any{ "results": []ChatSearchResult{}, }) return } rows, err := s.db.Query( r.Context(), ` SELECT DISTINCT ON (m.conversation_id) m.conversation_id::TEXT, m.id::TEXT, m.body, COALESCE( NULLIF(u.display_name, ''), NULLIF(u.username, ''), u.email, NULLIF(c.channel_source_name, ''), c.name, '' ), m.created_at FROM messages m JOIN conversations c ON c.id = m.conversation_id LEFT JOIN users u ON u.id = m.sender_id WHERE m.deleted_at IS NULL AND m.message_type = 'user' AND (m.expires_at IS NULL OR m.expires_at > now()) AND strpos(lower(m.body), lower($2)) > 0 AND EXISTS ( SELECT 1 FROM conversation_members cm WHERE cm.conversation_id = c.id AND cm.user_id = $1 ) ORDER BY m.conversation_id, m.created_at DESC, m.id DESC LIMIT 50 `, user.ID, query, ) if err != nil { writeError(w, http.StatusInternalServerError, "Chatnachrichten konnten nicht durchsucht werden") return } defer rows.Close() results := []ChatSearchResult{} for rows.Next() { var result ChatSearchResult if err := rows.Scan( &result.ConversationID, &result.MessageID, &result.Body, &result.SenderDisplayName, &result.CreatedAt, ); err != nil { writeError(w, http.StatusInternalServerError, "Suchergebnisse konnten nicht gelesen werden") return } results = append(results, result) } if err := rows.Err(); err != nil { writeError(w, http.StatusInternalServerError, "Suchergebnisse konnten nicht vollständig geladen werden") return } writeJSON(w, http.StatusOK, map[string]any{ "results": results, }) }