package services import ( "context" "encoding/json" "fmt" "git.pengzhan.dev/haopengzhan/rsspipe/internal/db" "git.pengzhan.dev/haopengzhan/rsspipe/internal/events" "git.pengzhan.dev/haopengzhan/rsspipe/internal/logger" "git.pengzhan.dev/haopengzhan/rsspipe/internal/models" "go.uber.org/zap" ) type SettingsService struct { db *db.DB bus *events.EventBus log *zap.Logger } func NewSettingsService(database *db.DB, bus *events.EventBus) *SettingsService { return &SettingsService{ db: database, bus: bus, log: logger.Named("settings-service"), } } func (s *SettingsService) GetPreferences(ctx context.Context, username string) (map[string]interface{}, error) { user, err := s.db.GetUserByUsername(username) if err != nil { return nil, err } if user.Preferences == nil { return make(map[string]interface{}), nil } return user.Preferences, nil } func (s *SettingsService) UpdatePreferences(ctx context.Context, username string, newPrefs map[string]interface{}) (map[string]interface{}, error) { user, err := s.db.GetUserByUsername(username) if err != nil { return nil, err } if user.Preferences == nil { user.Preferences = make(map[string]interface{}) } for k, v := range newPrefs { user.Preferences[k] = v } if err := s.db.UpdateUserPreferences(user.ID, user.Preferences); err != nil { return nil, err } if s.bus != nil { s.bus.Publish(ctx, events.Event{ Type: events.EventPreferencesSync, DirectAttrs: user.Preferences, }) } return user.Preferences, nil } func (s *SettingsService) GetAISettings(ctx context.Context) (*models.AISettings, error) { raw, err := s.db.GetSetting("ai_settings") if err != nil || raw == "" { return &models.AISettings{ Enabled: false, Provider: "openai", BaseURL: "https://api.openai.com/v1", APIKey: "", Model: "gpt-4o-mini", Temperature: 0.3, MaxTokens: 1000, Prompts: []models.PromptTemplate{}, }, nil } var cfg models.AISettings if err := json.Unmarshal([]byte(raw), &cfg); err != nil { return nil, fmt.Errorf("failed to parse AI settings: %w", err) } return &cfg, nil } func (s *SettingsService) UpdateAISettings(ctx context.Context, cfg models.AISettings) (*models.AISettings, error) { bytes, err := json.Marshal(cfg) if err != nil { return nil, fmt.Errorf("failed to marshal AI settings: %w", err) } if err := s.db.SetSetting("ai_settings", string(bytes)); err != nil { return nil, err } return &cfg, nil }