package maintenance import ( "fmt" "sync" "time" ) // Mode represents the maintenance mode state type Mode struct { mu sync.RWMutex enabled bool enabledAt time.Time enabledBy string reason string allowedUsers []string // Users allowed to operate during maintenance lastBackupID string // ID of backup created before entering maintenance } // Service manages maintenance mode type Service struct { mode *Mode } // NewService creates a new maintenance service func NewService() *Service { return &Service{ mode: &Mode{ allowedUsers: []string{}, }, } } // IsEnabled returns whether maintenance mode is currently enabled func (s *Service) IsEnabled() bool { s.mode.mu.RLock() defer s.mode.mu.RUnlock() return s.mode.enabled } // Enable enables maintenance mode func (s *Service) Enable(enabledBy, reason string, allowedUsers []string) error { s.mode.mu.Lock() defer s.mode.mu.Unlock() if s.mode.enabled { return fmt.Errorf("maintenance mode is already enabled") } s.mode.enabled = true s.mode.enabledAt = time.Now() s.mode.enabledBy = enabledBy s.mode.reason = reason if allowedUsers != nil { s.mode.allowedUsers = allowedUsers } else { s.mode.allowedUsers = []string{} } return nil } // Disable disables maintenance mode func (s *Service) Disable(disabledBy string) error { s.mode.mu.Lock() defer s.mode.mu.Unlock() if !s.mode.enabled { return fmt.Errorf("maintenance mode is not enabled") } s.mode.enabled = false s.mode.enabledBy = "" s.mode.reason = "" s.mode.allowedUsers = []string{} s.mode.lastBackupID = "" return nil } // GetStatus returns the current maintenance mode status func (s *Service) GetStatus() Status { s.mode.mu.RLock() defer s.mode.mu.RUnlock() return Status{ Enabled: s.mode.enabled, EnabledAt: s.mode.enabledAt, EnabledBy: s.mode.enabledBy, Reason: s.mode.reason, AllowedUsers: s.mode.allowedUsers, LastBackupID: s.mode.lastBackupID, } } // SetLastBackupID sets the backup ID created before entering maintenance func (s *Service) SetLastBackupID(backupID string) { s.mode.mu.Lock() defer s.mode.mu.Unlock() s.mode.lastBackupID = backupID } // IsUserAllowed checks if a user is allowed to operate during maintenance func (s *Service) IsUserAllowed(userID string) bool { s.mode.mu.RLock() defer s.mode.mu.RUnlock() if !s.mode.enabled { return true // No restrictions when not in maintenance } // Check if user is in allowed list for _, allowed := range s.mode.allowedUsers { if allowed == userID { return true } } return false } // Status represents the maintenance mode status type Status struct { Enabled bool `json:"enabled"` EnabledAt time.Time `json:"enabled_at,omitempty"` EnabledBy string `json:"enabled_by,omitempty"` Reason string `json:"reason,omitempty"` AllowedUsers []string `json:"allowed_users,omitempty"` LastBackupID string `json:"last_backup_id,omitempty"` }