From cb41a0b5d3a56a42c457bd365544a44a73e597e7 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Fri, 13 Mar 2026 13:23:12 +0700 Subject: [PATCH] feat: Add `migrate:all` command to orchestrate data migrations and refactor existing commands for enum-based data mapping. --- app/Console/Commands/MigrateAllCommand.php | 59 +++++++++++++++++++ .../Commands/MigrateContentRecapCommand.php | 32 ++++++++-- .../MigrateIssueManagementCommand.php | 2 +- .../MigrateMediaMonitoringCommand.php | 17 +++++- app/Console/Commands/MigrateUserCommand.php | 1 + database/seeders/DatabaseSeeder.php | 6 +- database/seeders/UserSeeder.php | 10 ---- 7 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 app/Console/Commands/MigrateAllCommand.php diff --git a/app/Console/Commands/MigrateAllCommand.php b/app/Console/Commands/MigrateAllCommand.php new file mode 100644 index 0000000..fb9a7a8 --- /dev/null +++ b/app/Console/Commands/MigrateAllCommand.php @@ -0,0 +1,59 @@ +info('🚀 Starting global data migration process...'); + $startTime = microtime(true); + + $commands = [ + 'migrate:user' => '👥 Migrating users...', + 'migrate:department' => '🏢 Migrating departments...', + 'migrate:location' => '📍 Migrating locations & sub-locations...', + 'migrate:classification' => '🏷️ Migrating classifications & sub-classifications...', + 'migrate:theme' => '🎨 Migrating themes...', + 'migrate:media-monitoring' => '🖥️ Migrating media monitoring...', + 'migrate:company' => '🏭 Migrating companies & partner media...', + 'migrate:journalist' => '📰 Migrating journalists...', + 'migrate:news' => '🗞️ Migrating news...', + 'migrate:announcement' => '📢 Migrating announcements...', + 'migrate:cooperation' => '🤝 Migrating cooperations, proposals & reports...', + 'migrate:content-recap' => '📊 Migrating content recaps...', + 'migrate:issue-management' => '⚠️ Migrating issue management...', + ]; + + foreach ($commands as $command => $description) { + $this->newLine(); + $this->info($description); + $this->call($command); + } + + $endTime = microtime(true); + $duration = number_format($endTime - $startTime, 2); + + $this->newLine(); + $this->info("✅ Global migration completed in {$duration} seconds!"); + } +} diff --git a/app/Console/Commands/MigrateContentRecapCommand.php b/app/Console/Commands/MigrateContentRecapCommand.php index b42413b..45cff24 100644 --- a/app/Console/Commands/MigrateContentRecapCommand.php +++ b/app/Console/Commands/MigrateContentRecapCommand.php @@ -2,8 +2,10 @@ namespace App\Console\Commands; +use App\Enums\Channel; use App\Enums\ContentType; use App\Enums\IsActive; +use App\Enums\SocialMedia; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; @@ -48,7 +50,6 @@ public function handle() $newId = DB::table('classifications')->insertGetId([ 'name' => $legacyClass->name, 'is_active' => IsActive::ACTIVE->value, - 'sort_order' => 0, 'created_at' => $legacyClass->created_at ?? now(), 'updated_at' => $legacyClass->updated_at ?? now(), 'deleted_at' => $legacyClass->deleted_at, @@ -91,8 +92,8 @@ public function handle() 'link' => Str::limit($legacy->link, 50, ''), 'posting_date' => $legacy->posting_date === '0000-00-00' ? now()->toDateString() : $legacy->posting_date, 'type' => $this->mapContentType($legacy->content_type), - 'channel' => Str::limit($legacy->channel, 20, ''), - 'social_media' => Str::limit($legacy->social_media ?? '-', 50, ''), + 'channel' => $this->mapChannel($legacy->channel), + 'social_media' => $this->mapSocialMedia($legacy->social_media), 'created_at' => $legacy->created_at ?? now(), 'updated_at' => $legacy->updated_at ?? now(), 'deleted_at' => $legacy->deleted_at, @@ -104,7 +105,7 @@ public function handle() $this->info('Content recap migration completed successfully!'); } - private function mapContentType(?string $legacyType): string + private function mapContentType(?string $legacyType): int { return match (strtolower($legacyType ?? '')) { 'foto' => ContentType::FOTO->value, @@ -113,4 +114,27 @@ private function mapContentType(?string $legacyType): string default => ContentType::FOTO->value, }; } + + private function mapChannel(?string $legacyChannel): int + { + return match (strtolower($legacyChannel ?? '')) { + 'website' => Channel::WEBSITE->value, + 'tiktok' => Channel::TIKTOK->value, + 'youtube' => Channel::YOUTUBE->value, + 'facebook' => Channel::FACEBOOK->value, + 'instagram' => Channel::INSTAGRAM->value, + 'twitter' => Channel::TWITTER->value, + default => Channel::WEBSITE->value, + }; + } + + private function mapSocialMedia(?string $legacySocial): int + { + return match (strtolower($legacySocial ?? '')) { + 'ppid diskominfo purwakarta' => SocialMedia::PPID_DISKOMINFO_PURWAKARTA->value, + 'diskominfo purwakarta' => SocialMedia::DISKOMINFO_PURWAKARTA->value, + 'purwakarta saber hoaks' => SocialMedia::PURWAKARTA_SABER_HOAKS->value, + default => SocialMedia::DISKOMINFO_PURWAKARTA->value, + }; + } } diff --git a/app/Console/Commands/MigrateIssueManagementCommand.php b/app/Console/Commands/MigrateIssueManagementCommand.php index 148a4a0..cfd7f24 100644 --- a/app/Console/Commands/MigrateIssueManagementCommand.php +++ b/app/Console/Commands/MigrateIssueManagementCommand.php @@ -63,7 +63,7 @@ public function handle() $this->info('Issue management migration completed successfully!'); } - private function mapSentiment(string $legacyValue): string + private function mapSentiment(string $legacyValue): int { return match (strtolower($legacyValue)) { 'positif' => IssueSentiment::POSITIVE->value, diff --git a/app/Console/Commands/MigrateMediaMonitoringCommand.php b/app/Console/Commands/MigrateMediaMonitoringCommand.php index f99a12d..7e30fa5 100644 --- a/app/Console/Commands/MigrateMediaMonitoringCommand.php +++ b/app/Console/Commands/MigrateMediaMonitoringCommand.php @@ -2,6 +2,7 @@ namespace App\Console\Commands; +use App\Enums\Channel; use App\Enums\IsActive; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; @@ -49,7 +50,7 @@ public function handle() 'code' => Str::limit($legacy->code, 10, ''), 'media_name' => Str::limit($legacy->media_name, 50, ''), 'title' => $legacy->title, - 'channel' => Str::limit($legacy->channel, 20, ''), + 'channel' => $this->mapChannel($legacy->channel), 'writter' => Str::limit($legacy->writter, 50, ''), 'link' => $legacy->link, 'news_page' => Str::limit($legacy->news_page, 20, ''), @@ -74,7 +75,6 @@ public function handle() ['name' => $themeName], [ 'is_active' => IsActive::ACTIVE->value, - 'sort_order' => 0, 'created_at' => now(), 'updated_at' => now(), ] @@ -97,4 +97,17 @@ public function handle() $this->info('Media monitoring migration completed successfully!'); } + + private function mapChannel(?string $legacyChannel): int + { + return match (strtolower($legacyChannel ?? '')) { + 'website' => Channel::WEBSITE->value, + 'tiktok' => Channel::TIKTOK->value, + 'youtube' => Channel::YOUTUBE->value, + 'facebook' => Channel::FACEBOOK->value, + 'instagram' => Channel::INSTAGRAM->value, + 'twitter' => Channel::TWITTER->value, + default => Channel::WEBSITE->value, + }; + } } diff --git a/app/Console/Commands/MigrateUserCommand.php b/app/Console/Commands/MigrateUserCommand.php index 6fd8d09..aa2d4ca 100644 --- a/app/Console/Commands/MigrateUserCommand.php +++ b/app/Console/Commands/MigrateUserCommand.php @@ -52,6 +52,7 @@ public function handle() // Using DB facade directly to insert ensures the legacy password hash // is NOT double-hashed by the model's "hashed" cast. $userId = DB::table('users')->insertGetId([ + 'id' => $legacy->id, 'name' => Str::limit($legacy->name, 100), 'email' => $legacy->email, 'username' => $username, diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 6b43e93..54b5a71 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -4,6 +4,7 @@ use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; +use Illuminate\Support\Facades\Artisan; class DatabaseSeeder extends Seeder { @@ -16,7 +17,10 @@ public function run(): void { $this->call([ ShieldSeeder::class, - UserSeeder::class, ]); + + Artisan::call('migrate:all', [], $this->command->getOutput()); + + (new UserSeeder)->run(); } } diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php index 709553f..db4a4b5 100644 --- a/database/seeders/UserSeeder.php +++ b/database/seeders/UserSeeder.php @@ -23,15 +23,5 @@ public function run(): void ]); $developer->assignRole(RoleEnum::DEVELOPER->value); - - $administrator = User::create([ - 'name' => 'Administrator', - 'email' => 'admin@gmail.com', - 'username' => 'admin', - 'password' => Hash::make(config('auth.password_default')), - 'email_verified_at' => now(), - ]); - - $administrator->assignRole(RoleEnum::ADMINISTRATOR->value); } }