// Filename: internal/service/token_manager.go package service import ( "fmt" "gemini-balancer/internal/models" "gemini-balancer/internal/repository" "gemini-balancer/internal/store" "gemini-balancer/internal/syncer" "github.com/sirupsen/logrus" ) const TopicTokenChanged = "events:token_changed" type TokenManager struct { repo repository.AuthTokenRepository syncer *syncer.CacheSyncer[[]*models.AuthToken] logger *logrus.Entry } // NewTokenManager's signature is updated to accept the new repository. func NewTokenManager(repo repository.AuthTokenRepository, store store.Store, logger *logrus.Logger) (*TokenManager, error) { tm := &TokenManager{ repo: repo, logger: logger.WithField("component", "TokenManager🔐"), } tokenLoader := func() ([]*models.AuthToken, error) { tm.logger.Info("Loading all auth tokens via repository...") tokens, err := tm.repo.GetAllTokensWithGroups() if err != nil { return nil, fmt.Errorf("failed to load auth tokens from repo: %w", err) } tm.logger.Infof("Successfully loaded and decrypted %d auth tokens into cache.", len(tokens)) return tokens, nil } s, err := syncer.NewCacheSyncer(tokenLoader, store, TopicTokenChanged) if err != nil { return nil, fmt.Errorf("failed to create token manager syncer: %w", err) } tm.syncer = s return tm, nil } func (tm *TokenManager) GetAllTokens() []*models.AuthToken { return tm.syncer.Get() } // BatchUpdateTokens is now a thin wrapper around the repository method. func (tm *TokenManager) BatchUpdateTokens(incomingTokens []*models.TokenUpdateRequest) error { tm.logger.Info("Delegating BatchUpdateTokens to repository...") if err := tm.repo.BatchUpdateTokens(incomingTokens); err != nil { tm.logger.Errorf("Repository failed to batch update tokens: %v", err) return err } tm.logger.Info("BatchUpdateTokens finished successfully. Invalidating cache.") return tm.Invalidate() } func (tm *TokenManager) Invalidate() error { return tm.syncer.Invalidate() } func (tm *TokenManager) Stop() { tm.syncer.Stop() }