186 lines
7.4 KiB
PHP
186 lines
7.4 KiB
PHP
<?php
|
|
|
|
namespace Database\Seeders;
|
|
|
|
use App\Models\Activity;
|
|
use App\Models\Backup;
|
|
use App\Models\Certificate;
|
|
use App\Models\Cluster;
|
|
use App\Models\Cron;
|
|
use App\Models\Invitation;
|
|
use App\Models\SecurityEvent;
|
|
use App\Models\Server;
|
|
use App\Models\Site;
|
|
use App\Models\TeamMember;
|
|
use App\Models\User;
|
|
use App\Models\Workspace;
|
|
use Illuminate\Database\Seeder;
|
|
|
|
class DatabaseSeeder extends Seeder
|
|
{
|
|
public function run(): void
|
|
{
|
|
/* ───── Primary user ───── */
|
|
$marie = User::updateOrCreate(
|
|
['email' => 'm.weber@acme-cluster.de'],
|
|
[
|
|
'name' => 'Marie Weber',
|
|
'password' => bcrypt('clupilot'),
|
|
'email_verified_at' => now(),
|
|
]
|
|
);
|
|
|
|
/* ───── Workspace (Acme Agency) — Pro plan ───── */
|
|
$workspace = Workspace::updateOrCreate(
|
|
['slug' => 'acme-agency'],
|
|
[
|
|
'name' => 'Acme Agency',
|
|
'owner_user_id' => $marie->id,
|
|
'plan' => 'pro',
|
|
'trial_ends_at' => null,
|
|
'billing_email' => 'billing@acme-agency.de',
|
|
'region' => 'eu-central-1',
|
|
]
|
|
);
|
|
|
|
$marie->update(['current_workspace_id' => $workspace->id]);
|
|
|
|
/* Bind workspace so BelongsToWorkspace creating-hook auto-fills FK. */
|
|
app()->instance('currentWorkspace', $workspace);
|
|
|
|
/* ───── Team membership (owner) ───── */
|
|
TeamMember::updateOrCreate(
|
|
['user_id' => $marie->id],
|
|
[
|
|
'workspace_id' => $workspace->id,
|
|
'role' => 'owner',
|
|
'scope' => 'All clusters',
|
|
'two_fa_enabled' => true,
|
|
'last_active_at' => now(),
|
|
]
|
|
);
|
|
|
|
/* ───── Dev login ───── */
|
|
$admin = User::updateOrCreate(
|
|
['email' => 'admin@clupilot.test'],
|
|
[
|
|
'name' => 'Admin',
|
|
'password' => bcrypt('clupilot'),
|
|
'email_verified_at' => now(),
|
|
'current_workspace_id' => $workspace->id,
|
|
]
|
|
);
|
|
|
|
/* ───── Cluster: Acme ───── */
|
|
$cluster = Cluster::firstOrCreate(
|
|
['workspace_id' => $workspace->id, 'slug' => 'acme-cluster'],
|
|
[
|
|
'name' => 'Acme Cluster',
|
|
'region' => 'eu-central-1',
|
|
'env' => 'prod',
|
|
'monthly_price_cents' => 24900,
|
|
'node_count' => 6,
|
|
'backups_enabled' => true,
|
|
]
|
|
);
|
|
|
|
/* ───── 6 servers ───── */
|
|
$servers = [
|
|
['name' => 'eu-prod-01', 'region' => 'eu-central-1', 'flag' => '🇩🇪', 'env' => 'prod', 'status' => 'ok', 'cpu' => 42, 'ram' => 58, 'disk' => 47],
|
|
['name' => 'eu-prod-02', 'region' => 'eu-central-1', 'flag' => '🇩🇪', 'env' => 'prod', 'status' => 'ok', 'cpu' => 36, 'ram' => 64, 'disk' => 51],
|
|
['name' => 'edge-ams', 'region' => 'eu-west-1', 'flag' => '🇳🇱', 'env' => 'edge', 'status' => 'ok', 'cpu' => 21, 'ram' => 45, 'disk' => 38],
|
|
['name' => 'us-east-01', 'region' => 'us-east-1', 'flag' => '🇺🇸', 'env' => 'prod', 'status' => 'warn', 'cpu' => 78, 'ram' => 71, 'disk' => 54],
|
|
['name' => 'staging', 'region' => 'eu-central-1', 'flag' => '🇩🇪', 'env' => 'staging', 'status' => 'ok', 'cpu' => 18, 'ram' => 32, 'disk' => 22],
|
|
['name' => 'ap-bom-01', 'region' => 'ap-south-1', 'flag' => '🇮🇳', 'env' => 'prod', 'status' => 'ok', 'cpu' => 28, 'ram' => 52, 'disk' => 43],
|
|
];
|
|
|
|
$serverModels = [];
|
|
foreach ($servers as $s) {
|
|
$serverModels[] = Server::firstOrCreate(
|
|
['workspace_id' => $workspace->id, 'name' => $s['name']],
|
|
[
|
|
'cluster_id' => $cluster->id,
|
|
'region' => $s['region'],
|
|
'country_flag' => $s['flag'],
|
|
'env' => $s['env'],
|
|
'cpu_cores' => 8,
|
|
'ram_gb' => 32,
|
|
'disk_gb' => 320,
|
|
'cpu_load_pct' => $s['cpu'],
|
|
'ram_used_pct' => $s['ram'],
|
|
'disk_used_pct' => $s['disk'],
|
|
'status' => $s['status'],
|
|
'ip' => fake()->ipv4(),
|
|
]
|
|
);
|
|
}
|
|
|
|
/* ───── 87 sites ───── */
|
|
$distribution = [23, 19, 14, 18, 6, 7];
|
|
foreach ($serverModels as $i => $server) {
|
|
$target = $distribution[$i] ?? 5;
|
|
$existing = $server->sites()->count();
|
|
if ($existing < $target) {
|
|
Site::factory()->count($target - $existing)
|
|
->create(['workspace_id' => $workspace->id, 'server_id' => $server->id]);
|
|
}
|
|
}
|
|
|
|
$allSites = Site::query()->where('workspace_id', $workspace->id)->get();
|
|
|
|
foreach ($allSites as $site) {
|
|
if (! $site->certificate) {
|
|
Certificate::factory()->create([
|
|
'workspace_id' => $workspace->id,
|
|
'site_id' => $site->id,
|
|
'domain' => '*.' . $site->domain,
|
|
]);
|
|
}
|
|
}
|
|
|
|
$backupSites = $allSites->random(min(28, $allSites->count()));
|
|
foreach ($backupSites as $site) {
|
|
Backup::factory()->count(rand(2, 6))->create(['workspace_id' => $workspace->id, 'site_id' => $site->id]);
|
|
}
|
|
|
|
foreach ($allSites->random(min(20, $allSites->count())) as $site) {
|
|
Cron::factory()->count(rand(1, 4))->create(['workspace_id' => $workspace->id, 'site_id' => $site->id]);
|
|
}
|
|
|
|
SecurityEvent::factory()->count(128)
|
|
->create(['workspace_id' => $workspace->id, 'site_id' => $allSites->random()->id]);
|
|
|
|
if ($workspace->members()->count() < 5) {
|
|
User::factory()->count(4)->create()->each(function (User $u) use ($workspace) {
|
|
$u->update(['current_workspace_id' => $workspace->id]);
|
|
TeamMember::factory()->create(['workspace_id' => $workspace->id, 'user_id' => $u->id]);
|
|
});
|
|
}
|
|
|
|
if ($workspace->invitations()->count() < 3) {
|
|
Invitation::factory()->count(3)->create([
|
|
'workspace_id' => $workspace->id,
|
|
'invited_by_user_id' => $marie->id,
|
|
'accepted_at' => null,
|
|
]);
|
|
}
|
|
|
|
Activity::factory()->count(30)->create(['workspace_id' => $workspace->id, 'user_id' => $marie->id]);
|
|
|
|
/* ───── Demo: second workspace (Personal) — Free plan ───── */
|
|
$personal = Workspace::firstOrCreate(
|
|
['slug' => 'marie-personal'],
|
|
[
|
|
'name' => 'Marie · Personal',
|
|
'owner_user_id' => $marie->id,
|
|
'plan' => 'free',
|
|
]
|
|
);
|
|
|
|
TeamMember::firstOrCreate(
|
|
['workspace_id' => $personal->id, 'user_id' => $marie->id],
|
|
['role' => 'owner', 'two_fa_enabled' => true, 'last_active_at' => now()],
|
|
);
|
|
}
|
|
}
|