- Updated .env.example to include new configuration options for the UltiAI branding and API endpoints. - Enhanced Nginx configuration to support new API routes for the MCP and WebSocket connections. - Introduced sub-filters for branding adjustments in Nginx responses. - Added new JavaScript patch for API endpoint adjustments. - Implemented tests for new API functionalities and improved error handling in the AI gateway.
88 lines
2.4 KiB
Go
88 lines
2.4 KiB
Go
package discovery
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/websearch"
|
|
)
|
|
|
|
func (s *Service) GetSearchSettings(ctx context.Context, externalUserID string) (websearch.Settings, error) {
|
|
return s.loadSearchSettings(ctx, externalUserID)
|
|
}
|
|
|
|
func (s *Service) UpdateSearchSettings(ctx context.Context, externalUserID string, settings websearch.Settings) (websearch.Settings, error) {
|
|
if s.db == nil {
|
|
return websearch.Settings{}, fmt.Errorf("database unavailable")
|
|
}
|
|
existing, _ := s.loadSearchSettings(ctx, externalUserID)
|
|
settings = mergeSearchProviderSecrets(existing, settings)
|
|
raw, err := json.Marshal(settings)
|
|
if err != nil {
|
|
return websearch.Settings{}, err
|
|
}
|
|
_, err = s.db.Exec(ctx, `
|
|
INSERT INTO settings (user_id, preferences)
|
|
VALUES (
|
|
(SELECT id FROM users WHERE external_id = $1),
|
|
jsonb_build_object('search', $2::jsonb)
|
|
)
|
|
ON CONFLICT (user_id) DO UPDATE SET
|
|
preferences = jsonb_set(
|
|
COALESCE(settings.preferences, '{}'::jsonb),
|
|
'{search}',
|
|
$2::jsonb
|
|
),
|
|
updated_at = NOW()
|
|
`, externalUserID, string(raw))
|
|
if err != nil {
|
|
return websearch.Settings{}, err
|
|
}
|
|
return s.loadSearchSettings(ctx, externalUserID)
|
|
}
|
|
|
|
func (s *Service) loadSearchSettings(ctx context.Context, externalUserID string) (websearch.Settings, error) {
|
|
var raw []byte
|
|
err := s.db.QueryRow(ctx, `
|
|
SELECT COALESCE(s.preferences->'search', '{}'::jsonb)
|
|
FROM users u
|
|
LEFT JOIN settings s ON s.user_id = u.id
|
|
WHERE u.external_id = $1
|
|
`, externalUserID).Scan(&raw)
|
|
if err != nil {
|
|
return websearch.Settings{}, err
|
|
}
|
|
var settings websearch.Settings
|
|
_ = json.Unmarshal(raw, &settings)
|
|
return settings, nil
|
|
}
|
|
|
|
func searchSettingsConfigured(settings websearch.Settings) bool {
|
|
_, err := websearch.ResolveProvider(settings)
|
|
return err == nil
|
|
}
|
|
|
|
func mergeSearchProviderSecrets(existing, patch websearch.Settings) websearch.Settings {
|
|
if len(patch.Providers) == 0 {
|
|
return patch
|
|
}
|
|
existingByID := make(map[string]websearch.Provider, len(existing.Providers))
|
|
for _, provider := range existing.Providers {
|
|
if provider.ID != "" {
|
|
existingByID[provider.ID] = provider
|
|
}
|
|
}
|
|
for i, provider := range patch.Providers {
|
|
if strings.TrimSpace(provider.APIKey) != "" || provider.ID == "" {
|
|
continue
|
|
}
|
|
if old, ok := existingByID[provider.ID]; ok && strings.TrimSpace(old.APIKey) != "" {
|
|
provider.APIKey = old.APIKey
|
|
patch.Providers[i] = provider
|
|
}
|
|
}
|
|
return patch
|
|
}
|