diff --git a/database/migrations/2026_06_28_100000_create_frontdesk_employee_tables.php b/database/migrations/2026_06_28_100000_create_frontdesk_employee_tables.php index eb298a7..8400336 100644 --- a/database/migrations/2026_06_28_100000_create_frontdesk_employee_tables.php +++ b/database/migrations/2026_06_28_100000_create_frontdesk_employee_tables.php @@ -8,54 +8,62 @@ return new class extends Migration { public function up(): void { - Schema::create('frontdesk_employees', function (Blueprint $table) { - $table->id(); - $table->string('owner_ref')->index(); - $table->foreignId('organization_id')->constrained('frontdesk_organizations')->cascadeOnDelete(); - $table->foreignId('branch_id')->nullable()->constrained('frontdesk_branches')->nullOnDelete(); - $table->string('employee_code'); - $table->string('full_name'); - $table->string('department')->nullable(); - $table->string('email')->nullable(); - $table->string('phone')->nullable(); - $table->string('pin_hash'); - $table->foreignId('host_id')->nullable()->constrained('frontdesk_hosts')->nullOnDelete(); - $table->boolean('active')->default(true); - $table->timestamps(); - $table->softDeletes(); - $table->unique(['organization_id', 'employee_code']); - $table->index(['owner_ref', 'organization_id']); - }); + if (! Schema::hasTable('frontdesk_employees')) { + Schema::create('frontdesk_employees', function (Blueprint $table) { + $table->id(); + $table->string('owner_ref')->index(); + $table->foreignId('organization_id')->constrained('frontdesk_organizations')->cascadeOnDelete(); + $table->foreignId('branch_id')->nullable()->constrained('frontdesk_branches')->nullOnDelete(); + $table->string('employee_code'); + $table->string('full_name'); + $table->string('department')->nullable(); + $table->string('email')->nullable(); + $table->string('phone')->nullable(); + $table->string('pin_hash'); + $table->foreignId('host_id')->nullable()->constrained('frontdesk_hosts')->nullOnDelete(); + $table->boolean('active')->default(true); + $table->timestamps(); + $table->softDeletes(); + $table->unique(['organization_id', 'employee_code']); + $table->index(['owner_ref', 'organization_id']); + }); + } - Schema::create('frontdesk_employee_presence', function (Blueprint $table) { - $table->id(); - $table->foreignId('employee_id')->unique()->constrained('frontdesk_employees')->cascadeOnDelete(); - $table->string('status')->default('off_site'); // off_site, on_site, stepped_out - $table->foreignId('branch_id')->nullable()->constrained('frontdesk_branches')->nullOnDelete(); - $table->foreignId('device_id')->nullable()->constrained('frontdesk_devices')->nullOnDelete(); - $table->string('destination')->nullable(); - $table->string('step_out_reason')->nullable(); - $table->text('notes')->nullable(); - $table->timestamp('signed_in_at')->nullable(); - $table->timestamp('last_event_at')->nullable(); - $table->timestamps(); - }); + if (! Schema::hasTable('frontdesk_employee_presence')) { + Schema::create('frontdesk_employee_presence', function (Blueprint $table) { + $table->id(); + $table->foreignId('employee_id')->unique()->constrained('frontdesk_employees')->cascadeOnDelete(); + $table->string('status')->default('off_site'); + $table->foreignId('branch_id')->nullable()->constrained('frontdesk_branches')->nullOnDelete(); + $table->foreignId('device_id')->nullable()->constrained('frontdesk_devices')->nullOnDelete(); + $table->string('destination')->nullable(); + $table->string('step_out_reason')->nullable(); + $table->text('notes')->nullable(); + $table->timestamp('signed_in_at')->nullable(); + $table->timestamp('last_event_at')->nullable(); + $table->timestamps(); + }); + } - Schema::create('frontdesk_employee_presence_events', function (Blueprint $table) { - $table->id(); - $table->string('owner_ref')->index(); - $table->foreignId('organization_id')->constrained('frontdesk_organizations')->cascadeOnDelete(); - $table->foreignId('employee_id')->constrained('frontdesk_employees')->cascadeOnDelete(); - $table->string('event'); // sign_in, sign_out, step_out, step_in - $table->string('status_after'); - $table->foreignId('branch_id')->nullable()->constrained('frontdesk_branches')->nullOnDelete(); - $table->foreignId('device_id')->nullable()->constrained('frontdesk_devices')->nullOnDelete(); - $table->string('destination')->nullable(); - $table->string('step_out_reason')->nullable(); - $table->text('notes')->nullable(); - $table->timestamps(); - $table->index(['organization_id', 'created_at']); - }); + if (! Schema::hasTable('frontdesk_employee_presence_events')) { + Schema::create('frontdesk_employee_presence_events', function (Blueprint $table) { + $table->id(); + $table->string('owner_ref')->index(); + $table->foreignId('organization_id')->constrained('frontdesk_organizations')->cascadeOnDelete(); + $table->foreignId('employee_id')->constrained('frontdesk_employees')->cascadeOnDelete(); + $table->string('event'); + $table->string('status_after'); + $table->foreignId('branch_id')->nullable()->constrained('frontdesk_branches')->nullOnDelete(); + $table->foreignId('device_id')->nullable()->constrained('frontdesk_devices')->nullOnDelete(); + $table->string('destination')->nullable(); + $table->string('step_out_reason')->nullable(); + $table->text('notes')->nullable(); + $table->timestamps(); + $table->index(['organization_id', 'created_at'], 'fd_emp_events_org_created_idx'); + }); + } else { + $this->ensureEventsIndex(); + } } public function down(): void @@ -64,4 +72,23 @@ return new class extends Migration Schema::dropIfExists('frontdesk_employee_presence'); Schema::dropIfExists('frontdesk_employees'); } + + protected function ensureEventsIndex(): void + { + $connection = Schema::getConnection(); + $database = $connection->getDatabaseName(); + $exists = $connection->selectOne( + 'SELECT 1 FROM information_schema.statistics + WHERE table_schema = ? AND table_name = ? AND index_name = ?', + [$database, 'frontdesk_employee_presence_events', 'fd_emp_events_org_created_idx'], + ); + + if ($exists) { + return; + } + + Schema::table('frontdesk_employee_presence_events', function (Blueprint $table) { + $table->index(['organization_id', 'created_at'], 'fd_emp_events_org_created_idx'); + }); + } };