From a3df33a4e06c1df38e51c9ec81951402e0a6914a Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 25 Nov 2025 15:18:43 +0100 Subject: [PATCH 1/3] fix: correct webhook notification settings migration and model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add missing traefik_outdated_webhook_notifications field to migration schema and population logic - Remove incorrect docker_cleanup_webhook_notifications from model (split into success/failure variants) - Consolidate webhook notification migrations from 2025_10_10 to 2025_11_25 for proper execution order - Ensure all 15 notification fields are properly defined and consistent across migration, model, and Livewire component 🤖 Generated with Claude Code Co-Authored-By: Claude --- app/Models/WebhookNotificationSettings.php | 2 - ...tification_settings_for_existing_teams.php | 47 ----------- ...120002_create_cloud_init_scripts_table.php | 36 -------- ...te_webhook_notification_settings_table.php | 52 ------------ ...te_webhook_notification_settings_table.php | 83 +++++++++++++++++++ ...000002_create_cloud_init_scripts_table.php | 33 ++++++++ 6 files changed, 116 insertions(+), 137 deletions(-) delete mode 100644 database/migrations/2025_10_10_120001_populate_webhook_notification_settings_for_existing_teams.php delete mode 100644 database/migrations/2025_10_10_120002_create_cloud_init_scripts_table.php delete mode 100644 database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php create mode 100644 database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php create mode 100644 database/migrations/2025_11_25_000002_create_cloud_init_scripts_table.php diff --git a/app/Models/WebhookNotificationSettings.php b/app/Models/WebhookNotificationSettings.php index 79bd0ae62..a7039c033 100644 --- a/app/Models/WebhookNotificationSettings.php +++ b/app/Models/WebhookNotificationSettings.php @@ -24,7 +24,6 @@ class WebhookNotificationSettings extends Model 'backup_failure_webhook_notifications', 'scheduled_task_success_webhook_notifications', 'scheduled_task_failure_webhook_notifications', - 'docker_cleanup_webhook_notifications', 'server_disk_usage_webhook_notifications', 'server_reachable_webhook_notifications', 'server_unreachable_webhook_notifications', @@ -45,7 +44,6 @@ protected function casts(): array 'backup_failure_webhook_notifications' => 'boolean', 'scheduled_task_success_webhook_notifications' => 'boolean', 'scheduled_task_failure_webhook_notifications' => 'boolean', - 'docker_cleanup_webhook_notifications' => 'boolean', 'server_disk_usage_webhook_notifications' => 'boolean', 'server_reachable_webhook_notifications' => 'boolean', 'server_unreachable_webhook_notifications' => 'boolean', diff --git a/database/migrations/2025_10_10_120001_populate_webhook_notification_settings_for_existing_teams.php b/database/migrations/2025_10_10_120001_populate_webhook_notification_settings_for_existing_teams.php deleted file mode 100644 index de2707557..000000000 --- a/database/migrations/2025_10_10_120001_populate_webhook_notification_settings_for_existing_teams.php +++ /dev/null @@ -1,47 +0,0 @@ -get(); - - foreach ($teams as $team) { - DB::table('webhook_notification_settings')->updateOrInsert( - ['team_id' => $team->id], - [ - 'webhook_enabled' => false, - 'webhook_url' => null, - 'deployment_success_webhook_notifications' => false, - 'deployment_failure_webhook_notifications' => true, - 'status_change_webhook_notifications' => false, - 'backup_success_webhook_notifications' => false, - 'backup_failure_webhook_notifications' => true, - 'scheduled_task_success_webhook_notifications' => false, - 'scheduled_task_failure_webhook_notifications' => true, - 'docker_cleanup_success_webhook_notifications' => false, - 'docker_cleanup_failure_webhook_notifications' => true, - 'server_disk_usage_webhook_notifications' => true, - 'server_reachable_webhook_notifications' => false, - 'server_unreachable_webhook_notifications' => true, - 'server_patch_webhook_notifications' => false, - ] - ); - } - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - // We don't need to do anything in down() since the webhook_notification_settings - // table will be dropped by the create migration's down() method - } -}; diff --git a/database/migrations/2025_10_10_120002_create_cloud_init_scripts_table.php b/database/migrations/2025_10_10_120002_create_cloud_init_scripts_table.php deleted file mode 100644 index ae63dc53a..000000000 --- a/database/migrations/2025_10_10_120002_create_cloud_init_scripts_table.php +++ /dev/null @@ -1,36 +0,0 @@ -id(); - $table->foreignId('team_id')->constrained()->onDelete('cascade'); - $table->string('name'); - $table->text('script'); // Encrypted in the model - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('cloud_init_scripts'); - } -}; diff --git a/database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php b/database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php deleted file mode 100644 index c0689f81e..000000000 --- a/database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php +++ /dev/null @@ -1,52 +0,0 @@ -id(); - $table->foreignId('team_id')->constrained()->cascadeOnDelete(); - - $table->boolean('webhook_enabled')->default(false); - $table->text('webhook_url')->nullable(); - - $table->boolean('deployment_success_webhook_notifications')->default(false); - $table->boolean('deployment_failure_webhook_notifications')->default(true); - $table->boolean('status_change_webhook_notifications')->default(false); - $table->boolean('backup_success_webhook_notifications')->default(false); - $table->boolean('backup_failure_webhook_notifications')->default(true); - $table->boolean('scheduled_task_success_webhook_notifications')->default(false); - $table->boolean('scheduled_task_failure_webhook_notifications')->default(true); - $table->boolean('docker_cleanup_success_webhook_notifications')->default(false); - $table->boolean('docker_cleanup_failure_webhook_notifications')->default(true); - $table->boolean('server_disk_usage_webhook_notifications')->default(true); - $table->boolean('server_reachable_webhook_notifications')->default(false); - $table->boolean('server_unreachable_webhook_notifications')->default(true); - $table->boolean('server_patch_webhook_notifications')->default(false); - - $table->unique(['team_id']); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('webhook_notification_settings'); - } -}; diff --git a/database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php b/database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php new file mode 100644 index 000000000..b0f513c73 --- /dev/null +++ b/database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php @@ -0,0 +1,83 @@ +id(); + $table->foreignId('team_id')->constrained()->cascadeOnDelete(); + + $table->boolean('webhook_enabled')->default(false); + $table->text('webhook_url')->nullable(); + + $table->boolean('deployment_success_webhook_notifications')->default(false); + $table->boolean('deployment_failure_webhook_notifications')->default(true); + $table->boolean('status_change_webhook_notifications')->default(false); + $table->boolean('backup_success_webhook_notifications')->default(false); + $table->boolean('backup_failure_webhook_notifications')->default(true); + $table->boolean('scheduled_task_success_webhook_notifications')->default(false); + $table->boolean('scheduled_task_failure_webhook_notifications')->default(true); + $table->boolean('docker_cleanup_success_webhook_notifications')->default(false); + $table->boolean('docker_cleanup_failure_webhook_notifications')->default(true); + $table->boolean('server_disk_usage_webhook_notifications')->default(true); + $table->boolean('server_reachable_webhook_notifications')->default(false); + $table->boolean('server_unreachable_webhook_notifications')->default(true); + $table->boolean('server_patch_webhook_notifications')->default(false); + $table->boolean('traefik_outdated_webhook_notifications')->default(true); + + $table->unique(['team_id']); + }); + } + + // Populate webhook notification settings for existing teams (only if they don't already have settings) + $teams = DB::table('teams')->get(); + + foreach ($teams as $team) { + // Check if settings already exist for this team + $exists = DB::table('webhook_notification_settings') + ->where('team_id', $team->id) + ->exists(); + + if (! $exists) { + DB::table('webhook_notification_settings')->insert([ + 'team_id' => $team->id, + 'webhook_enabled' => false, + 'webhook_url' => null, + 'deployment_success_webhook_notifications' => false, + 'deployment_failure_webhook_notifications' => true, + 'status_change_webhook_notifications' => false, + 'backup_success_webhook_notifications' => false, + 'backup_failure_webhook_notifications' => true, + 'scheduled_task_success_webhook_notifications' => false, + 'scheduled_task_failure_webhook_notifications' => true, + 'docker_cleanup_success_webhook_notifications' => false, + 'docker_cleanup_failure_webhook_notifications' => true, + 'server_disk_usage_webhook_notifications' => true, + 'server_reachable_webhook_notifications' => false, + 'server_unreachable_webhook_notifications' => true, + 'server_patch_webhook_notifications' => false, + 'traefik_outdated_webhook_notifications' => true, + ]); + } + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('webhook_notification_settings'); + } +}; diff --git a/database/migrations/2025_11_25_000002_create_cloud_init_scripts_table.php b/database/migrations/2025_11_25_000002_create_cloud_init_scripts_table.php new file mode 100644 index 000000000..11c5b99a3 --- /dev/null +++ b/database/migrations/2025_11_25_000002_create_cloud_init_scripts_table.php @@ -0,0 +1,33 @@ +id(); + $table->foreignId('team_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->text('script'); // Encrypted in the model + $table->timestamps(); + }); + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('cloud_init_scripts'); + } +}; From 477738dd2f7f76d8964f256de4403944b5af23fb Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 25 Nov 2025 15:35:01 +0100 Subject: [PATCH 2/3] fix: update webhook notification settings migration to use updateOrInsert and add logging --- app/Models/WebhookNotificationSettings.php | 4 ++ ...te_webhook_notification_settings_table.php | 58 +++++++++---------- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/app/Models/WebhookNotificationSettings.php b/app/Models/WebhookNotificationSettings.php index a7039c033..731006181 100644 --- a/app/Models/WebhookNotificationSettings.php +++ b/app/Models/WebhookNotificationSettings.php @@ -24,6 +24,8 @@ class WebhookNotificationSettings extends Model 'backup_failure_webhook_notifications', 'scheduled_task_success_webhook_notifications', 'scheduled_task_failure_webhook_notifications', + 'docker_cleanup_success_webhook_notifications', + 'docker_cleanup_failure_webhook_notifications', 'server_disk_usage_webhook_notifications', 'server_reachable_webhook_notifications', 'server_unreachable_webhook_notifications', @@ -44,6 +46,8 @@ protected function casts(): array 'backup_failure_webhook_notifications' => 'boolean', 'scheduled_task_success_webhook_notifications' => 'boolean', 'scheduled_task_failure_webhook_notifications' => 'boolean', + 'docker_cleanup_success_webhook_notifications' => 'boolean', + 'docker_cleanup_failure_webhook_notifications' => 'boolean', 'server_disk_usage_webhook_notifications' => 'boolean', 'server_reachable_webhook_notifications' => 'boolean', 'server_unreachable_webhook_notifications' => 'boolean', diff --git a/database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php b/database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php index b0f513c73..eb1653238 100644 --- a/database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php +++ b/database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php @@ -3,6 +3,7 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Schema; return new class extends Migration @@ -41,36 +42,35 @@ public function up(): void } // Populate webhook notification settings for existing teams (only if they don't already have settings) - $teams = DB::table('teams')->get(); - - foreach ($teams as $team) { - // Check if settings already exist for this team - $exists = DB::table('webhook_notification_settings') - ->where('team_id', $team->id) - ->exists(); - - if (! $exists) { - DB::table('webhook_notification_settings')->insert([ - 'team_id' => $team->id, - 'webhook_enabled' => false, - 'webhook_url' => null, - 'deployment_success_webhook_notifications' => false, - 'deployment_failure_webhook_notifications' => true, - 'status_change_webhook_notifications' => false, - 'backup_success_webhook_notifications' => false, - 'backup_failure_webhook_notifications' => true, - 'scheduled_task_success_webhook_notifications' => false, - 'scheduled_task_failure_webhook_notifications' => true, - 'docker_cleanup_success_webhook_notifications' => false, - 'docker_cleanup_failure_webhook_notifications' => true, - 'server_disk_usage_webhook_notifications' => true, - 'server_reachable_webhook_notifications' => false, - 'server_unreachable_webhook_notifications' => true, - 'server_patch_webhook_notifications' => false, - 'traefik_outdated_webhook_notifications' => true, - ]); + DB::table('teams')->chunkById(100, function ($teams) { + foreach ($teams as $team) { + try { + DB::table('webhook_notification_settings')->updateOrInsert( + ['team_id' => $team->id], + [ + 'webhook_enabled' => false, + 'webhook_url' => null, + 'deployment_success_webhook_notifications' => false, + 'deployment_failure_webhook_notifications' => true, + 'status_change_webhook_notifications' => false, + 'backup_success_webhook_notifications' => false, + 'backup_failure_webhook_notifications' => true, + 'scheduled_task_success_webhook_notifications' => false, + 'scheduled_task_failure_webhook_notifications' => true, + 'docker_cleanup_success_webhook_notifications' => false, + 'docker_cleanup_failure_webhook_notifications' => true, + 'server_disk_usage_webhook_notifications' => true, + 'server_reachable_webhook_notifications' => false, + 'server_unreachable_webhook_notifications' => true, + 'server_patch_webhook_notifications' => false, + 'traefik_outdated_webhook_notifications' => true, + ] + ); + } catch (\Throwable $e) { + Log::error('Error creating webhook notification settings for team '.$team->id.': '.$e->getMessage()); + } } - } + }); } /** From 3bdcc06838cb7f291a5bc61770220a33a790b034 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 25 Nov 2025 15:40:45 +0100 Subject: [PATCH 3/3] fix: prevent overwriting existing webhook notification settings during migration --- ...reate_webhook_notification_settings_table.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php b/database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php index eb1653238..df620bd6e 100644 --- a/database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php +++ b/database/migrations/2025_11_25_000001_create_webhook_notification_settings_table.php @@ -45,9 +45,15 @@ public function up(): void DB::table('teams')->chunkById(100, function ($teams) { foreach ($teams as $team) { try { - DB::table('webhook_notification_settings')->updateOrInsert( - ['team_id' => $team->id], - [ + // Check if settings already exist for this team + $exists = DB::table('webhook_notification_settings') + ->where('team_id', $team->id) + ->exists(); + + if (! $exists) { + // Only insert if no settings exist - don't overwrite existing preferences + DB::table('webhook_notification_settings')->insert([ + 'team_id' => $team->id, 'webhook_enabled' => false, 'webhook_url' => null, 'deployment_success_webhook_notifications' => false, @@ -64,8 +70,8 @@ public function up(): void 'server_unreachable_webhook_notifications' => true, 'server_patch_webhook_notifications' => false, 'traefik_outdated_webhook_notifications' => true, - ] - ); + ]); + } } catch (\Throwable $e) { Log::error('Error creating webhook notification settings for team '.$team->id.': '.$e->getMessage()); }