From 1c29e469a7d98ec66450509f957f4d20cb9018bd Mon Sep 17 00:00:00 2001 From: GoHorse Deploy Date: Sat, 7 Feb 2026 17:22:15 +0000 Subject: [PATCH] fix: make migration 032 idempotent and fix UUID type in credentials bootstrap - Migration 032: add NOT EXISTS check to avoid duplicate key violation - CredentialsBootstrap: use NULLIF for updated_by UUID column, pass empty string instead of system_bootstrap --- backend/internal/services/credentials_service.go | 4 ++-- backend/migrations/032_update_superadmin_lol.sql | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/internal/services/credentials_service.go b/backend/internal/services/credentials_service.go index b813f60..7f1dcf3 100644 --- a/backend/internal/services/credentials_service.go +++ b/backend/internal/services/credentials_service.go @@ -33,7 +33,7 @@ func NewCredentialsService(db *sql.DB) *CredentialsService { func (s *CredentialsService) SaveCredentials(ctx context.Context, serviceName, encryptedPayload, updatedBy string) error { query := ` INSERT INTO external_services_credentials (service_name, encrypted_payload, updated_by, updated_at) - VALUES ($1, $2, $3, NOW()) + VALUES ($1, $2, NULLIF($3, '')::uuid, NOW()) ON CONFLICT (service_name) DO UPDATE SET encrypted_payload = EXCLUDED.encrypted_payload, @@ -334,7 +334,7 @@ func (s *CredentialsService) BootstrapCredentials(ctx context.Context) error { fmt.Printf("[CredentialsBootstrap] Failed to encrypt %s: %v\n", service, err) continue } - if err := s.SaveCredentials(ctx, service, encrypted, "system_bootstrap"); err != nil { + if err := s.SaveCredentials(ctx, service, encrypted, ""); err != nil { fmt.Printf("[CredentialsBootstrap] Failed to save %s: %v\n", service, err) } else { fmt.Printf("[CredentialsBootstrap] Successfully migrated %s\n", service) diff --git a/backend/migrations/032_update_superadmin_lol.sql b/backend/migrations/032_update_superadmin_lol.sql index efdedf9..a3f2c12 100644 --- a/backend/migrations/032_update_superadmin_lol.sql +++ b/backend/migrations/032_update_superadmin_lol.sql @@ -1,9 +1,11 @@ -- Migration: Update Super Admin to 'lol' and force password reset -- Description: Updates the superadmin identifier, email, name, and sets status to enforce password change. +-- Made idempotent: only runs if target identifier doesn't already exist. -- Increase status column length to support 'force_change_password' (21 chars) ALTER TABLE users ALTER COLUMN status TYPE VARCHAR(50); +-- Only update if 'lol' identifier doesn't already exist UPDATE users SET identifier = 'lol', @@ -12,4 +14,5 @@ SET name = 'Dr. Horse Expert', status = 'force_change_password', updated_at = CURRENT_TIMESTAMP -WHERE identifier = 'superadmin' OR email = 'admin@gohorsejobs.com'; +WHERE (identifier = 'superadmin' OR email = 'admin@gohorsejobs.com') + AND NOT EXISTS (SELECT 1 FROM users WHERE identifier = 'lol');