From 4fe9daf55c8d3fb4dacb0578ad5a1e0c269c6f66 Mon Sep 17 00:00:00 2001 From: BaileyCodes Date: Thu, 11 Jun 2026 20:42:58 -0500 Subject: [PATCH] fix: idempotent migrations with hasTable guards, fix install retry --- ...01_create_addon_network_metrics_tables.php | 6 + ...01_01_000002_create_addon_roles_tables.php | 169 ++++++++++-------- ...003_create_addon_file_revisions_tables.php | 8 +- ..._01_000004_create_addon_console_tables.php | 8 +- 4 files changed, 108 insertions(+), 83 deletions(-) diff --git a/database/migrations/addon/2024_01_01_000001_create_addon_network_metrics_tables.php b/database/migrations/addon/2024_01_01_000001_create_addon_network_metrics_tables.php index 69e57d3..9b46336 100644 --- a/database/migrations/addon/2024_01_01_000001_create_addon_network_metrics_tables.php +++ b/database/migrations/addon/2024_01_01_000001_create_addon_network_metrics_tables.php @@ -15,6 +15,7 @@ return new class extends Migration { public function up(): void { + if (!Schema::hasTable('addon_network_metrics')) { Schema::create('addon_network_metrics', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedInteger('server_id')->index(); @@ -35,7 +36,9 @@ return new class extends Migration ->references('id')->on('nodes') ->onDelete('cascade'); }); + } // end hasTable check + if (!Schema::hasTable('addon_network_port_metrics')) { Schema::create('addon_network_port_metrics', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedInteger('server_id')->index(); @@ -53,7 +56,9 @@ return new class extends Migration ->references('id')->on('servers') ->onDelete('cascade'); }); + } // end hasTable check + if (!Schema::hasTable('addon_network_flows')) { Schema::create('addon_network_flows', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedInteger('src_server_id')->nullable()->index(); @@ -75,6 +80,7 @@ return new class extends Migration ->references('id')->on('servers') ->onDelete('set null'); }); + } // end hasTable check } public function down(): void diff --git a/database/migrations/addon/2024_01_01_000002_create_addon_roles_tables.php b/database/migrations/addon/2024_01_01_000002_create_addon_roles_tables.php index 8028618..d2cabff 100644 --- a/database/migrations/addon/2024_01_01_000002_create_addon_roles_tables.php +++ b/database/migrations/addon/2024_01_01_000002_create_addon_roles_tables.php @@ -15,98 +15,108 @@ return new class extends Migration { public function up(): void { - Schema::create('addon_roles', function (Blueprint $table) { - $table->increments('id'); - $table->string('name', 100); - $table->text('description')->nullable(); - $table->string('color', 7)->default('#6366f1'); // indigo - $table->unsignedInteger('priority')->default(0); - $table->boolean('is_default')->default(false); - $table->unsignedInteger('created_by')->nullable(); - $table->timestamps(); + if (!Schema::hasTable('addon_roles')) { + Schema::create('addon_roles', function (Blueprint $table) { + $table->increments('id'); + $table->string('name', 100); + $table->text('description')->nullable(); + $table->string('color', 7)->default('#6366f1'); + $table->unsignedInteger('priority')->default(0); + $table->boolean('is_default')->default(false); + $table->unsignedInteger('created_by')->nullable(); + $table->timestamps(); - $table->foreign('created_by') - ->references('id')->on('users') - ->onDelete('set null'); - }); + $table->foreign('created_by') + ->references('id')->on('users') + ->onDelete('set null'); + }); + } - Schema::create('addon_role_permissions', function (Blueprint $table) { - $table->bigIncrements('id'); - $table->unsignedInteger('role_id'); - $table->string('permission', 100); - $table->enum('value', ['allow', 'deny']); - $table->timestamps(); + if (!Schema::hasTable('addon_role_permissions')) { + Schema::create('addon_role_permissions', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedInteger('role_id'); + $table->string('permission', 100); + $table->enum('value', ['allow', 'deny']); + $table->timestamps(); - $table->unique(['role_id', 'permission']); - $table->index(['role_id', 'permission']); + $table->unique(['role_id', 'permission']); + $table->index(['role_id', 'permission']); - $table->foreign('role_id') - ->references('id')->on('addon_roles') - ->onDelete('cascade'); - }); + $table->foreign('role_id') + ->references('id')->on('addon_roles') + ->onDelete('cascade'); + }); + } - Schema::create('addon_server_role_assignments', function (Blueprint $table) { - $table->bigIncrements('id'); - $table->unsignedInteger('server_id'); - $table->unsignedInteger('user_id'); - $table->unsignedInteger('role_id'); - $table->unsignedInteger('assigned_by')->nullable(); - $table->timestamps(); + if (!Schema::hasTable('addon_server_role_assignments')) { + Schema::create('addon_server_role_assignments', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedInteger('server_id'); + $table->unsignedInteger('user_id'); + $table->unsignedInteger('role_id'); + $table->unsignedInteger('assigned_by')->nullable(); + $table->timestamps(); - $table->unique(['server_id', 'user_id', 'role_id']); - $table->index(['server_id', 'user_id']); + $table->unique(['server_id', 'user_id', 'role_id']); + $table->index(['server_id', 'user_id']); - $table->foreign('server_id') - ->references('id')->on('servers') - ->onDelete('cascade'); - $table->foreign('user_id') - ->references('id')->on('users') - ->onDelete('cascade'); - $table->foreign('role_id') - ->references('id')->on('addon_roles') - ->onDelete('cascade'); - $table->foreign('assigned_by') - ->references('id')->on('users') - ->onDelete('set null'); - }); + $table->foreign('server_id') + ->references('id')->on('servers') + ->onDelete('cascade'); + $table->foreign('user_id') + ->references('id')->on('users') + ->onDelete('cascade'); + $table->foreign('role_id') + ->references('id')->on('addon_roles') + ->onDelete('cascade'); + $table->foreign('assigned_by') + ->references('id')->on('users') + ->onDelete('set null'); + }); + } - Schema::create('addon_server_permission_overrides', function (Blueprint $table) { - $table->bigIncrements('id'); - $table->unsignedInteger('server_id'); - $table->unsignedInteger('user_id'); - $table->string('permission', 100); - $table->enum('value', ['allow', 'deny', 'unset'])->default('unset'); - $table->unsignedInteger('set_by')->nullable(); - $table->timestamps(); + if (!Schema::hasTable('addon_server_permission_overrides')) { + Schema::create('addon_server_permission_overrides', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedInteger('server_id'); + $table->unsignedInteger('user_id'); + $table->string('permission', 100); + $table->enum('value', ['allow', 'deny', 'unset'])->default('unset'); + $table->unsignedInteger('set_by')->nullable(); + $table->timestamps(); - $table->unique(['server_id', 'user_id', 'permission']); - $table->index(['server_id', 'user_id']); + $table->unique(['server_id', 'user_id', 'permission']); + $table->index(['server_id', 'user_id']); - $table->foreign('server_id') - ->references('id')->on('servers') - ->onDelete('cascade'); - $table->foreign('user_id') - ->references('id')->on('users') - ->onDelete('cascade'); - }); + $table->foreign('server_id') + ->references('id')->on('servers') + ->onDelete('cascade'); + $table->foreign('user_id') + ->references('id')->on('users') + ->onDelete('cascade'); + }); + } - Schema::create('addon_role_audit_log', function (Blueprint $table) { - $table->bigIncrements('id'); - $table->unsignedInteger('actor_id')->nullable(); - $table->string('action', 80); - $table->string('target_type', 50)->nullable(); - $table->unsignedBigInteger('target_id')->nullable(); - $table->json('payload')->nullable(); - $table->string('ip_address', 45)->nullable(); - $table->timestamp('created_at')->useCurrent(); + if (!Schema::hasTable('addon_role_audit_log')) { + Schema::create('addon_role_audit_log', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->unsignedInteger('actor_id')->nullable(); + $table->string('action', 80); + $table->string('target_type', 50)->nullable(); + $table->unsignedBigInteger('target_id')->nullable(); + $table->json('payload')->nullable(); + $table->string('ip_address', 45)->nullable(); + $table->timestamp('created_at')->useCurrent(); - $table->index(['actor_id', 'created_at']); - $table->index(['action', 'created_at']); + $table->index(['actor_id', 'created_at']); + $table->index(['action', 'created_at']); - $table->foreign('actor_id') - ->references('id')->on('users') - ->onDelete('set null'); - }); + $table->foreign('actor_id') + ->references('id')->on('users') + ->onDelete('set null'); + }); + } } public function down(): void @@ -118,3 +128,4 @@ return new class extends Migration Schema::dropIfExists('addon_roles'); } }; + diff --git a/database/migrations/addon/2024_01_01_000003_create_addon_file_revisions_tables.php b/database/migrations/addon/2024_01_01_000003_create_addon_file_revisions_tables.php index a7cfc4d..4f5243d 100644 --- a/database/migrations/addon/2024_01_01_000003_create_addon_file_revisions_tables.php +++ b/database/migrations/addon/2024_01_01_000003_create_addon_file_revisions_tables.php @@ -15,7 +15,8 @@ return new class extends Migration { public function up(): void { - Schema::create('addon_file_revisions', function (Blueprint $table) { + if (!Schema::hasTable('addon_file_revisions')) { + Schema::create('addon_file_revisions', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedInteger('server_id'); $table->string('file_path', 500); @@ -41,8 +42,10 @@ return new class extends Migration ->references('id')->on('users') ->onDelete('set null'); }); + } // end hasTable addon_file_revisions - Schema::create('addon_file_revision_storage_usage', function (Blueprint $table) { + if (!Schema::hasTable('addon_file_revision_storage_usage')) { + Schema::create('addon_file_revision_storage_usage', function (Blueprint $table) { $table->unsignedInteger('server_id')->primary(); $table->unsignedBigInteger('total_bytes')->default(0); $table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate(); @@ -51,6 +54,7 @@ return new class extends Migration ->references('id')->on('servers') ->onDelete('cascade'); }); + } // end hasTable addon_file_revision_storage_usage } public function down(): void diff --git a/database/migrations/addon/2024_01_01_000004_create_addon_console_tables.php b/database/migrations/addon/2024_01_01_000004_create_addon_console_tables.php index b817bd5..409123d 100644 --- a/database/migrations/addon/2024_01_01_000004_create_addon_console_tables.php +++ b/database/migrations/addon/2024_01_01_000004_create_addon_console_tables.php @@ -15,7 +15,8 @@ return new class extends Migration { public function up(): void { - Schema::create('addon_command_definitions', function (Blueprint $table) { + if (!Schema::hasTable('addon_command_definitions')) { + Schema::create('addon_command_definitions', function (Blueprint $table) { $table->increments('id'); $table->unsignedInteger('server_id')->nullable()->index(); $table->unsignedInteger('node_id')->nullable()->index(); @@ -33,8 +34,10 @@ return new class extends Migration ->references('id')->on('nodes') ->onDelete('cascade'); }); + } // end hasTable addon_command_definitions - Schema::create('addon_console_player_cache', function (Blueprint $table) { + if (!Schema::hasTable('addon_console_player_cache')) { + Schema::create('addon_console_player_cache', function (Blueprint $table) { $table->unsignedInteger('server_id'); $table->string('player_name', 64); $table->timestamp('last_seen_at')->useCurrent()->useCurrentOnUpdate(); @@ -46,6 +49,7 @@ return new class extends Migration ->references('id')->on('servers') ->onDelete('cascade'); }); + } // end hasTable addon_console_player_cache } public function down(): void