php-tenant/Database/Seeders/WorkspaceSeeder.php
Snider d0ad2737cb refactor: rename namespace from Core\Mod\Tenant to Core\Tenant
Simplifies the namespace hierarchy by removing the intermediate Mod
segment. Updates all 118 files including models, services, controllers,
middleware, tests, and composer.json autoload configuration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 16:30:46 +00:00

183 lines
6 KiB
PHP

<?php
namespace Core\Tenant\Database\Seeders;
use Core\Tenant\Enums\UserTier;
use Core\Tenant\Models\Package;
use Core\Tenant\Models\User;
use Core\Tenant\Models\Workspace;
use Core\Tenant\Models\WorkspacePackage;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Schema;
class WorkspaceSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
if (! Schema::hasTable('workspaces') || ! Schema::hasTable('users')) {
return;
}
// Environment-aware domains: .test for local, .uk.com for production
$isLocal = app()->environment('local');
$domain = $isLocal ? 'host.test' : 'host.uk.com';
$email = 'snider@host.uk.com';
// Create system user first so we can assign ownership
$systemUser = User::updateOrCreate(
['id' => 1],
[
'name' => 'Snider',
'email' => $email,
'password' => Hash::make('change-me-in-env'),
'tier' => UserTier::HADES,
'tier_expires_at' => null,
'email_verified_at' => now(),
]
);
// Service workspaces - marketing domains are handled by Mod modules, not workspace routing.
// The workspace domain field is for custom user-assigned domains (e.g., mybrand.com).
// Service domains (lthn.test, social.host.test, etc.) are routed via Mod\{Service}\Boot.
$workspaces = [
[
'name' => 'Host UK',
'slug' => 'main',
'domain' => $domain, // Main marketing site
'icon' => 'globe',
'color' => 'violet',
'description' => 'Main website content',
'type' => 'cms',
'sort_order' => 0,
],
[
'name' => 'Social',
'slug' => 'social',
'domain' => '', // Marketing domain routed via Mod\Social
'icon' => 'share-nodes',
'color' => 'green',
'description' => 'Social media scheduling',
'type' => 'custom',
'sort_order' => 2,
],
[
'name' => 'Analytics',
'slug' => 'analytics',
'domain' => '', // Marketing domain routed via Mod\Analytics
'icon' => 'chart-line',
'color' => 'yellow',
'description' => 'Privacy-first analytics',
'type' => 'custom',
'sort_order' => 3,
],
[
'name' => 'Trust',
'slug' => 'trust',
'domain' => '', // Marketing domain routed via Mod\Trust
'icon' => 'shield-check',
'color' => 'orange',
'description' => 'Social proof widgets',
'type' => 'custom',
'sort_order' => 4,
],
[
'name' => 'Notify',
'slug' => 'notify',
'domain' => '', // Marketing domain routed via Mod\Notify
'icon' => 'bell',
'color' => 'red',
'description' => 'Push notifications',
'type' => 'custom',
'sort_order' => 5,
],
[
'name' => 'LtHn',
'slug' => 'lthn',
'domain' => '', // Marketing domain routed via Mod\LtHn
'icon' => 'link',
'color' => 'cyan',
'description' => 'lt.hn bio link service',
'type' => 'custom',
'sort_order' => 6,
],
];
foreach ($workspaces as $workspace) {
$ws = Workspace::updateOrCreate(
['slug' => $workspace['slug']],
array_merge($workspace, ['is_active' => true])
);
// Attach system user as owner if not already attached
if (! $ws->users()->where('user_id', $systemUser->id)->exists()) {
$ws->users()->attach($systemUser->id, [
'role' => 'owner',
'is_default' => false,
]);
}
}
// Provision hades to main workspace only
$this->provisionWorkspaceEntitlements();
}
/**
* Provision packages for workspaces.
*/
protected function provisionWorkspaceEntitlements(): void
{
if (! Schema::hasTable('entitlement_workspace_packages')) {
return;
}
// Main workspace gets full Hades access
$this->provisionPackage('main', 'hades');
// Service workspaces get analytics, social, trust, notify for tracking & upsell
$serviceWorkspaces = ['social', 'analytics', 'trust', 'notify', 'lthn'];
$marketingServices = [
'core-srv-analytics-access',
'core-srv-social-access',
'core-srv-trust-access',
'core-srv-notify-access',
];
foreach ($serviceWorkspaces as $workspace) {
foreach ($marketingServices as $package) {
$this->provisionPackage($workspace, $package);
}
}
}
/**
* Provision a package to a workspace.
*/
protected function provisionPackage(string $workspaceSlug, string $packageCode): void
{
$package = Package::where('code', $packageCode)->first();
if (! $package) {
return;
}
$workspace = Workspace::where('slug', $workspaceSlug)->first();
if (! $workspace) {
return;
}
WorkspacePackage::updateOrCreate(
[
'workspace_id' => $workspace->id,
'package_id' => $package->id,
],
[
'status' => WorkspacePackage::STATUS_ACTIVE,
'starts_at' => now(),
'expires_at' => null,
]
);
}
}