Files
databasus/backend/internal/features/healthcheck/config/service.go
2025-12-25 21:26:53 +03:00

144 lines
3.6 KiB
Go

package healthcheck_config
import (
"databasus-backend/internal/features/audit_logs"
"databasus-backend/internal/features/databases"
users_models "databasus-backend/internal/features/users/models"
workspaces_services "databasus-backend/internal/features/workspaces/services"
"errors"
"fmt"
"log/slog"
"github.com/google/uuid"
)
type HealthcheckConfigService struct {
databaseService *databases.DatabaseService
healthcheckConfigRepository *HealthcheckConfigRepository
workspaceService *workspaces_services.WorkspaceService
auditLogService *audit_logs.AuditLogService
logger *slog.Logger
}
func (s *HealthcheckConfigService) OnDatabaseCreated(
databaseID uuid.UUID,
) {
err := s.initializeDefaultConfig(databaseID)
if err != nil {
s.logger.Error("failed to initialize default healthcheck config", "error", err)
}
}
func (s *HealthcheckConfigService) Save(
user users_models.User,
configDTO HealthcheckConfigDTO,
) error {
database, err := s.databaseService.GetDatabaseByID(configDTO.DatabaseID)
if err != nil {
return err
}
if database.WorkspaceID == nil {
return errors.New("cannot modify healthcheck config for databases without workspace")
}
canManage, err := s.workspaceService.CanUserManageDBs(*database.WorkspaceID, &user)
if err != nil {
return err
}
if !canManage {
return errors.New("insufficient permissions to modify healthcheck config")
}
healthcheckConfig := configDTO.ToDTO()
s.logger.Info("healthcheck config", "config", healthcheckConfig)
healthcheckConfig.DatabaseID = database.ID
err = s.healthcheckConfigRepository.Save(healthcheckConfig)
if err != nil {
return err
}
// for DBs with disabled healthcheck, we keep
// health status as available
if !healthcheckConfig.IsHealthcheckEnabled &&
database.HealthStatus != nil {
err = s.databaseService.SetHealthStatus(
database.ID,
nil,
)
if err != nil {
return err
}
}
s.auditLogService.WriteAuditLog(
fmt.Sprintf("Healthcheck config updated for database '%s'", database.Name),
&user.ID,
database.WorkspaceID,
)
return nil
}
func (s *HealthcheckConfigService) GetByDatabaseID(
user users_models.User,
databaseID uuid.UUID,
) (*HealthcheckConfig, error) {
database, err := s.databaseService.GetDatabaseByID(databaseID)
if err != nil {
return nil, err
}
if database.WorkspaceID == nil {
return nil, errors.New("cannot access healthcheck config for databases without workspace")
}
canAccess, _, err := s.workspaceService.CanUserAccessWorkspace(*database.WorkspaceID, &user)
if err != nil {
return nil, err
}
if !canAccess {
return nil, errors.New("insufficient permissions to view healthcheck config")
}
config, err := s.healthcheckConfigRepository.GetByDatabaseID(database.ID)
if err != nil {
return nil, err
}
if config == nil {
err = s.initializeDefaultConfig(database.ID)
if err != nil {
return nil, err
}
config, err = s.healthcheckConfigRepository.GetByDatabaseID(database.ID)
if err != nil {
return nil, err
}
}
return config, nil
}
func (s *HealthcheckConfigService) GetDatabasesWithEnabledHealthcheck() (
[]HealthcheckConfig, error,
) {
return s.healthcheckConfigRepository.GetDatabasesWithEnabledHealthcheck()
}
func (s *HealthcheckConfigService) initializeDefaultConfig(
databaseID uuid.UUID,
) error {
return s.healthcheckConfigRepository.Save(&HealthcheckConfig{
DatabaseID: databaseID,
IsHealthcheckEnabled: true,
IsSentNotificationWhenUnavailable: true,
IntervalMinutes: 1,
AttemptsBeforeConcideredAsDown: 3,
StoreAttemptsDays: 7,
})
}