diff --git a/README.md b/README.md index c77a071c..246cffd9 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,8 @@ ### Platform - Install PHP dependencies: `cd apps/platform && composer install` - Start Sail: `cd apps/platform && ./vendor/bin/sail up -d` - Generate the app key: `cd apps/platform && ./vendor/bin/sail artisan key:generate` -- Run migrations and seeders: `cd apps/platform && ./vendor/bin/sail artisan migrate --seed` +- Apply incremental migrations on an already cut-over local database: `cd apps/platform && ./vendor/bin/sail artisan migrate` +- Initialize or reset the local database: `cd apps/platform && ./vendor/bin/sail artisan migrate:fresh --seed` - Run frontend watch/build inside Sail: `corepack pnpm dev:platform`, `cd apps/platform && ./vendor/bin/sail pnpm dev`, or `cd apps/platform && ./vendor/bin/sail pnpm build` - Run tests: `cd apps/platform && ./vendor/bin/sail artisan test --compact` @@ -152,6 +153,7 @@ ### DB Reset and Seed Rules - Default lanes use SQLite `:memory:` with `RefreshDatabase` as the reset strategy. - The isolated PostgreSQL coverage remains the `Pgsql` suite and is reserved for schema or foreign-key assertions. +- Spec 279 managed-environment core cutover is destructive for old local databases. If a local database still contains legacy `tenants`, `tenant_user`, `tenant_memberships`, or `user_tenant_preferences` tables, reset it with `cd apps/platform && ./vendor/bin/sail artisan migrate:fresh --seed` instead of trying to preserve that schema. - Keep seeds out of default lanes. Opt into seeded fixtures only inside the test that needs business-truth seed data. - Schema-baseline or dump-based acceleration remains a follow-up investigation, not a default requirement for the current lane model. diff --git a/apps/platform/app/Console/Commands/ClassifyProviderConnections.php b/apps/platform/app/Console/Commands/ClassifyProviderConnections.php index bf52155e..8087faa9 100644 --- a/apps/platform/app/Console/Commands/ClassifyProviderConnections.php +++ b/apps/platform/app/Console/Commands/ClassifyProviderConnections.php @@ -6,7 +6,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\AuditLogger; use App\Services\Providers\ProviderConnectionClassificationResult; use App\Services\Providers\ProviderConnectionClassifier; @@ -43,9 +43,9 @@ public function handle(ProviderConnectionClassifier $classifier): int } $tenantCounts = (clone $query) - ->selectRaw('tenant_id, count(*) as aggregate') - ->groupBy('tenant_id') - ->pluck('aggregate', 'tenant_id') + ->selectRaw('managed_environment_id, count(*) as aggregate') + ->groupBy('managed_environment_id') + ->pluck('aggregate', 'managed_environment_id') ->map(static fn (mixed $count): int => (int) $count) ->all(); @@ -84,7 +84,7 @@ public function handle(ProviderConnectionClassifier $classifier): int $tenant = $connection->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { $this->warn(sprintf('Skipping provider connection #%d without tenant context.', (int) $connection->getKey())); continue; @@ -123,11 +123,11 @@ private function query(): Builder $tenantOption = $this->option('tenant'); if (is_string($tenantOption) && trim($tenantOption) !== '') { - $tenant = Tenant::query() + $tenant = ManagedEnvironment::query() ->forTenant(trim($tenantOption)) ->firstOrFail(); - $query->where('tenant_id', (int) $tenant->getKey()); + $query->where('managed_environment_id', (int) $tenant->getKey()); } $connectionOption = $this->option('connection'); @@ -175,7 +175,7 @@ private function applyClassification( return $connection->fresh(['tenant', 'credential']); } - private function auditStart(Tenant $tenant, int $candidateCount): void + private function auditStart(ManagedEnvironment $tenant, int $candidateCount): void { app(AuditLogger::class)->log( tenant: $tenant, @@ -195,7 +195,7 @@ private function auditStart(Tenant $tenant, int $candidateCount): void } private function auditApplied( - Tenant $tenant, + ManagedEnvironment $tenant, ProviderConnection $connection, ProviderConnectionClassificationResult $result, ): void { diff --git a/apps/platform/app/Console/Commands/OpsReconcileAdapterRuns.php b/apps/platform/app/Console/Commands/OpsReconcileAdapterRuns.php index 39e73fad..8b07c046 100644 --- a/apps/platform/app/Console/Commands/OpsReconcileAdapterRuns.php +++ b/apps/platform/app/Console/Commands/OpsReconcileAdapterRuns.php @@ -15,7 +15,7 @@ class OpsReconcileAdapterRuns extends Command */ protected $signature = 'ops:reconcile-adapter-runs {--type= : Adapter run type (e.g. restore.execute)} - {--tenant= : Tenant ID} + {--tenant= : ManagedEnvironment ID} {--older-than=60 : Only consider runs older than N minutes} {--dry-run=true : Preview only (true/false)} {--limit=50 : Max number of runs to inspect}'; @@ -56,7 +56,7 @@ public function handle() $result = $reconciler->reconcile([ 'type' => $type, - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'older_than_minutes' => $olderThanMinutes, 'limit' => $limit, 'dry_run' => $dryRun, diff --git a/apps/platform/app/Console/Commands/PurgeLegacyBaselineGapRuns.php b/apps/platform/app/Console/Commands/PurgeLegacyBaselineGapRuns.php index e012742d..e467f1c2 100644 --- a/apps/platform/app/Console/Commands/PurgeLegacyBaselineGapRuns.php +++ b/apps/platform/app/Console/Commands/PurgeLegacyBaselineGapRuns.php @@ -5,7 +5,7 @@ namespace App\Console\Commands; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationCatalog; use App\Support\OperationRunType; use Illuminate\Console\Command; @@ -51,7 +51,7 @@ public function handle(): int } if ($tenantIds !== []) { - $query->whereIn('tenant_id', $tenantIds); + $query->whereIn('managed_environment_id', $tenantIds); } $candidates = $query->get(); @@ -66,12 +66,12 @@ public function handle(): int } $this->table( - ['Run', 'Type', 'Tenant', 'Workspace', 'Legacy signal'], + ['Run', 'Type', 'ManagedEnvironment', 'Workspace', 'Legacy signal'], $matched ->map(fn (OperationRun $run): array => [ 'Run' => (string) $run->getKey(), 'Type' => (string) $run->type, - 'Tenant' => $run->tenant_id !== null ? (string) $run->tenant_id : '—', + 'ManagedEnvironment' => $run->managed_environment_id !== null ? (string) $run->managed_environment_id : '—', 'Workspace' => $run->workspace_id !== null ? (string) $run->workspace_id : '—', 'Legacy signal' => $this->legacySignal($run), ]) @@ -145,9 +145,9 @@ private function resolveTenantIds(array $tenantIdentifiers): array $tenantIds = []; foreach ($tenantIdentifiers as $identifier) { - $tenant = Tenant::query()->forTenant($identifier)->first(); + $tenant = ManagedEnvironment::query()->forTenant($identifier)->first(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $tenantIds[] = (int) $tenant->getKey(); } } diff --git a/apps/platform/app/Console/Commands/ReclassifyEnrollmentConfigurations.php b/apps/platform/app/Console/Commands/ReclassifyEnrollmentConfigurations.php index 9bf795a0..b99394d0 100644 --- a/apps/platform/app/Console/Commands/ReclassifyEnrollmentConfigurations.php +++ b/apps/platform/app/Console/Commands/ReclassifyEnrollmentConfigurations.php @@ -4,7 +4,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use Illuminate\Console\Command; @@ -43,7 +43,7 @@ public function handle(): int ->where('policy_type', 'enrollmentRestriction'); if ($tenant) { - $query->where('tenant_id', $tenant->id); + $query->where('managed_environment_id', $tenant->id); } $candidates = $query->get(); @@ -69,9 +69,9 @@ public function handle(): int } $this->line(sprintf( - 'ESP detected: policy=%s tenant_id=%s external_id=%s', + 'ESP detected: policy=%s managed_environment_id=%s external_id=%s', (string) $policy->getKey(), - (string) $policy->tenant_id, + (string) $policy->managed_environment_id, (string) $policy->external_id, )); @@ -80,7 +80,7 @@ public function handle(): int } $existingTarget = Policy::query() - ->where('tenant_id', $policy->tenant_id) + ->where('managed_environment_id', $policy->managed_environment_id) ->where('external_id', $policy->external_id) ->where('policy_type', 'windowsEnrollmentStatusPage') ->first(); @@ -130,7 +130,7 @@ private function fetchSnapshotOrNull(Policy $policy): ?array return null; } - $tenantIdentifier = $tenant->tenant_id ?? $tenant->external_id; + $tenantIdentifier = $tenant->managed_environment_id ?? $tenant->external_id; $response = $this->graphClient->getPolicy('enrollmentRestriction', $policy->external_id, [ 'tenant' => $tenantIdentifier, @@ -148,7 +148,7 @@ private function fetchSnapshotOrNull(Policy $policy): ?array return is_array($payload) ? $payload : null; } - private function resolveTenantOrNull(): ?Tenant + private function resolveTenantOrNull(): ?ManagedEnvironment { $tenantOption = $this->option('tenant'); @@ -156,7 +156,7 @@ private function resolveTenantOrNull(): ?Tenant return null; } - return Tenant::query() + return ManagedEnvironment::query() ->forTenant($tenantOption) ->firstOrFail(); } diff --git a/apps/platform/app/Console/Commands/SeedBackupHealthBrowserFixture.php b/apps/platform/app/Console/Commands/SeedBackupHealthBrowserFixture.php index 641a0d1d..d00cd28f 100644 --- a/apps/platform/app/Console/Commands/SeedBackupHealthBrowserFixture.php +++ b/apps/platform/app/Console/Commands/SeedBackupHealthBrowserFixture.php @@ -7,8 +7,8 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\UserTenantPreference; use App\Models\Workspace; @@ -42,7 +42,7 @@ public function handle(): int $workspaceConfig = is_array($fixture['workspace'] ?? null) ? $fixture['workspace'] : []; $userConfig = is_array($fixture['user'] ?? null) ? $fixture['user'] : []; $scenarioConfig = is_array($fixture['blocked_drillthrough'] ?? null) ? $fixture['blocked_drillthrough'] : []; - $tenantRouteKey = (string) ($scenarioConfig['tenant_id'] ?? $scenarioConfig['tenant_external_id'] ?? '18000000-0000-4000-8000-000000000180'); + $tenantRouteKey = (string) ($scenarioConfig['managed_environment_id'] ?? $scenarioConfig['tenant_external_id'] ?? '18000000-0000-4000-8000-000000000180'); $workspace = Workspace::query()->updateOrCreate( ['slug' => (string) ($workspaceConfig['slug'] ?? 'spec-180-backup-health-smoke')], @@ -60,16 +60,13 @@ public function handle(): int ], ); - $tenant = Tenant::query()->updateOrCreate( - ['external_id' => $tenantRouteKey], + $tenant = ManagedEnvironment::query()->updateOrCreate( + ['slug' => $tenantRouteKey], [ 'workspace_id' => (int) $workspace->getKey(), - 'name' => (string) ($scenarioConfig['tenant_name'] ?? 'Spec 180 Blocked Backup Tenant'), - 'tenant_id' => $tenantRouteKey, - 'app_certificate_thumbprint' => null, - 'app_notes' => null, - 'status' => Tenant::STATUS_ACTIVE, - 'environment' => 'dev', + 'name' => (string) ($scenarioConfig['tenant_name'] ?? 'Spec 180 Blocked Backup ManagedEnvironment'), + 'lifecycle_status' => ManagedEnvironment::STATUS_ACTIVE, + 'kind' => 'dev', 'is_current' => false, 'metadata' => ['fixture' => 'spec-180-browser-smoke'], 'rbac_status' => 'ok', @@ -82,8 +79,8 @@ public function handle(): int ['role' => 'owner'], ); - TenantMembership::query()->updateOrCreate( - ['tenant_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey()], + ManagedEnvironmentMembership::query()->updateOrCreate( + ['managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey()], ['role' => 'owner', 'source' => 'manual', 'source_ref' => 'spec-180-browser-smoke'], ); @@ -91,16 +88,16 @@ public function handle(): int $user->forceFill(['last_workspace_id' => (int) $workspace->getKey()])->save(); } - if (Schema::hasTable('user_tenant_preferences')) { + if (Schema::hasTable('user_managed_environment_preferences')) { UserTenantPreference::query()->updateOrCreate( - ['user_id' => (int) $user->getKey(), 'tenant_id' => (int) $tenant->getKey()], + ['user_id' => (int) $user->getKey(), 'managed_environment_id' => (int) $tenant->getKey()], ['last_used_at' => now()], ); } $policy = Policy::query()->updateOrCreate( [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => (string) ($scenarioConfig['policy_external_id'] ?? 'spec-180-rbac-stale-policy'), 'policy_type' => (string) ($scenarioConfig['policy_type'] ?? 'settingsCatalogPolicy'), ], @@ -113,7 +110,7 @@ public function handle(): int ); $backupSet = BackupSet::withTrashed()->firstOrNew([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => (string) ($scenarioConfig['backup_set_name'] ?? 'Spec 180 Blocked Stale Backup'), ]); @@ -137,7 +134,7 @@ public function handle(): int ]); $backupItem->forceFill([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'platform' => 'windows', 'captured_at' => $backupSet->completed_at, @@ -173,8 +170,8 @@ public function handle(): int ['Workspace', (string) $workspace->name], ['User email', (string) $user->email], ['User password', $password], - ['Tenant', (string) $tenant->name], - ['Tenant external id', (string) $tenant->external_id], + ['ManagedEnvironment', (string) $tenant->name], + ['ManagedEnvironment external id', (string) $tenant->external_id], ['Dashboard URL', "/admin/t/{$tenant->external_id}"], ['Fixture login URL', route('admin.local.backup-health-browser-fixture-login', absolute: false)], ['Blocked route', "/admin/t/{$tenant->external_id}/backup-sets"], diff --git a/apps/platform/app/Console/Commands/SyncPolicies.php b/apps/platform/app/Console/Commands/SyncPolicies.php index 9a34d819..7411a43e 100644 --- a/apps/platform/app/Console/Commands/SyncPolicies.php +++ b/apps/platform/app/Console/Commands/SyncPolicies.php @@ -3,7 +3,7 @@ namespace App\Console\Commands; use App\Jobs\SyncPoliciesJob; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Console\Command; class SyncPolicies extends Command @@ -24,16 +24,16 @@ public function handle(): int return Command::SUCCESS; } - private function resolveTenant(): Tenant + private function resolveTenant(): ManagedEnvironment { $tenantId = $this->option('tenant'); if ($tenantId) { - return Tenant::query() + return ManagedEnvironment::query() ->forTenant($tenantId) ->firstOrFail(); } - return Tenant::currentOrFail(); + return ManagedEnvironment::currentOrFail(); } } diff --git a/apps/platform/app/Console/Commands/TenantpilotBackfillWorkspaceIds.php b/apps/platform/app/Console/Commands/TenantpilotBackfillWorkspaceIds.php index b7ae1168..148124bc 100644 --- a/apps/platform/app/Console/Commands/TenantpilotBackfillWorkspaceIds.php +++ b/apps/platform/app/Console/Commands/TenantpilotBackfillWorkspaceIds.php @@ -258,21 +258,21 @@ private function collectTableStats(array $tables): array $missing = (int) DB::table($table)->whereNull('workspace_id')->count(); $unresolvableQuery = DB::table($table) - ->leftJoin('tenants', 'tenants.id', '=', sprintf('%s.tenant_id', $table)) + ->leftJoin('managed_environments', 'managed_environments.id', '=', sprintf('%s.managed_environment_id', $table)) ->whereNull(sprintf('%s.workspace_id', $table)) ->where(function ($query): void { - $query->whereNull('tenants.id') - ->orWhereNull('tenants.workspace_id'); + $query->whereNull('managed_environments.id') + ->orWhereNull('managed_environments.workspace_id'); }); $unresolvable = (int) $unresolvableQuery->count(); $sampleIds = DB::table($table) - ->leftJoin('tenants', 'tenants.id', '=', sprintf('%s.tenant_id', $table)) + ->leftJoin('managed_environments', 'managed_environments.id', '=', sprintf('%s.managed_environment_id', $table)) ->whereNull(sprintf('%s.workspace_id', $table)) ->where(function ($query): void { - $query->whereNull('tenants.id') - ->orWhereNull('tenants.workspace_id'); + $query->whereNull('managed_environments.id') + ->orWhereNull('managed_environments.workspace_id'); }) ->orderBy(sprintf('%s.id', $table)) ->limit(5) @@ -302,11 +302,11 @@ private function collectWorkspaceWorkloads(array $tables, ?int $maxRows): array foreach ($tables as $table) { $rows = DB::table($table) - ->join('tenants', 'tenants.id', '=', sprintf('%s.tenant_id', $table)) + ->join('managed_environments', 'managed_environments.id', '=', sprintf('%s.managed_environment_id', $table)) ->whereNull(sprintf('%s.workspace_id', $table)) - ->whereNotNull('tenants.workspace_id') - ->selectRaw('tenants.workspace_id as workspace_id, COUNT(*) as row_count') - ->groupBy('tenants.workspace_id') + ->whereNotNull('managed_environments.workspace_id') + ->selectRaw('managed_environments.workspace_id as workspace_id, COUNT(*) as row_count') + ->groupBy('managed_environments.workspace_id') ->get(); foreach ($rows as $row) { diff --git a/apps/platform/app/Console/Commands/TenantpilotDispatchBackupSchedules.php b/apps/platform/app/Console/Commands/TenantpilotDispatchBackupSchedules.php index 6c2e12b1..072e3fb2 100644 --- a/apps/platform/app/Console/Commands/TenantpilotDispatchBackupSchedules.php +++ b/apps/platform/app/Console/Commands/TenantpilotDispatchBackupSchedules.php @@ -7,7 +7,7 @@ class TenantpilotDispatchBackupSchedules extends Command { - protected $signature = 'tenantpilot:schedules:dispatch {--tenant=* : Limit to tenant_id/external_id}'; + protected $signature = 'tenantpilot:schedules:dispatch {--tenant=* : Limit to managed_environment_id/external_id}'; protected $description = 'Dispatch due backup schedules (idempotent per schedule minute-slot).'; diff --git a/apps/platform/app/Console/Commands/TenantpilotDispatchDirectoryGroupsSync.php b/apps/platform/app/Console/Commands/TenantpilotDispatchDirectoryGroupsSync.php index c4cf3672..77cce59f 100644 --- a/apps/platform/app/Console/Commands/TenantpilotDispatchDirectoryGroupsSync.php +++ b/apps/platform/app/Console/Commands/TenantpilotDispatchDirectoryGroupsSync.php @@ -2,7 +2,7 @@ namespace App\Console\Commands; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\OperationRunService; use App\Support\OperationRunType; use Carbon\CarbonImmutable; @@ -10,7 +10,7 @@ class TenantpilotDispatchDirectoryGroupsSync extends Command { - protected $signature = 'tenantpilot:directory-groups:dispatch {--tenant=* : Limit to tenant_id/external_id}'; + protected $signature = 'tenantpilot:directory-groups:dispatch {--tenant=* : Limit to managed_environment_id/external_id}'; protected $description = 'Dispatch scheduled directory group sync runs (idempotent per tenant minute-slot).'; @@ -96,7 +96,7 @@ public function handle(): int */ private function resolveTenants(array $tenantIdentifiers): \Illuminate\Support\Collection { - $query = Tenant::activeQuery(); + $query = ManagedEnvironment::activeQuery(); if ($tenantIdentifiers !== []) { $query->where(function ($subQuery) use ($tenantIdentifiers) { @@ -107,8 +107,7 @@ private function resolveTenants(array $tenantIdentifiers): \Illuminate\Support\C continue; } - $subQuery->orWhere('tenant_id', $identifier) - ->orWhere('external_id', $identifier); + $subQuery->orWhere('slug', $identifier); } }); } diff --git a/apps/platform/app/Console/Commands/TenantpilotPurgeNonPersistentData.php b/apps/platform/app/Console/Commands/TenantpilotPurgeNonPersistentData.php index 93097419..e9b33041 100644 --- a/apps/platform/app/Console/Commands/TenantpilotPurgeNonPersistentData.php +++ b/apps/platform/app/Console/Commands/TenantpilotPurgeNonPersistentData.php @@ -10,7 +10,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunType; use Illuminate\Console\Command; use Illuminate\Support\Arr; @@ -26,7 +26,7 @@ class TenantpilotPurgeNonPersistentData extends Command * @var string */ protected $signature = 'tenantpilot:purge-nonpersistent - {tenant? : Tenant id / tenant_id / external_id (defaults to current tenant)} + {tenant? : ManagedEnvironment id / managed_environment_id / external_id (defaults to current tenant)} {--all : Purge for all tenants} {--force : Actually delete rows}'; @@ -68,7 +68,7 @@ public function handle(): int $counts = $this->countsForTenant($tenant); $this->line(''); - $this->info("Tenant: {$tenant->id} ({$tenant->name})"); + $this->info("ManagedEnvironment: {$tenant->id} ({$tenant->name})"); $this->table( ['Table', 'Rows'], collect($counts) @@ -83,31 +83,31 @@ public function handle(): int DB::transaction(function () use ($tenant): void { BackupSchedule::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->delete(); OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->delete(); RestoreRun::withTrashed() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->forceDelete(); BackupItem::withTrashed() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->forceDelete(); BackupSet::withTrashed() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->forceDelete(); PolicyVersion::withTrashed() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->forceDelete(); Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->delete(); }); @@ -122,19 +122,19 @@ public function handle(): int private function resolveTenants() { if ((bool) $this->option('all')) { - return Tenant::query()->get(); + return ManagedEnvironment::query()->get(); } $tenantArg = $this->argument('tenant'); if ($tenantArg !== null && $tenantArg !== '') { - $tenant = Tenant::query()->forTenant($tenantArg)->first(); + $tenant = ManagedEnvironment::query()->forTenant($tenantArg)->first(); return $tenant ? collect([$tenant]) : collect(); } try { - return collect([Tenant::currentOrFail()]); + return collect([ManagedEnvironment::currentOrFail()]); } catch (RuntimeException) { return collect(); } @@ -143,30 +143,30 @@ private function resolveTenants() /** * @return array */ - private function countsForTenant(Tenant $tenant): array + private function countsForTenant(ManagedEnvironment $tenant): array { return [ - 'backup_schedules' => BackupSchedule::query()->where('tenant_id', $tenant->id)->count(), - 'operation_runs' => OperationRun::query()->where('tenant_id', $tenant->id)->count(), - 'audit_logs_retained' => AuditLog::query()->where('tenant_id', $tenant->id)->count(), - 'restore_runs' => RestoreRun::withTrashed()->where('tenant_id', $tenant->id)->count(), - 'backup_items' => BackupItem::withTrashed()->where('tenant_id', $tenant->id)->count(), - 'backup_sets' => BackupSet::withTrashed()->where('tenant_id', $tenant->id)->count(), - 'policy_versions' => PolicyVersion::withTrashed()->where('tenant_id', $tenant->id)->count(), - 'policies' => Policy::query()->where('tenant_id', $tenant->id)->count(), + 'backup_schedules' => BackupSchedule::query()->where('managed_environment_id', $tenant->id)->count(), + 'operation_runs' => OperationRun::query()->where('managed_environment_id', $tenant->id)->count(), + 'audit_logs_retained' => AuditLog::query()->where('managed_environment_id', $tenant->id)->count(), + 'restore_runs' => RestoreRun::withTrashed()->where('managed_environment_id', $tenant->id)->count(), + 'backup_items' => BackupItem::withTrashed()->where('managed_environment_id', $tenant->id)->count(), + 'backup_sets' => BackupSet::withTrashed()->where('managed_environment_id', $tenant->id)->count(), + 'policy_versions' => PolicyVersion::withTrashed()->where('managed_environment_id', $tenant->id)->count(), + 'policies' => Policy::query()->where('managed_environment_id', $tenant->id)->count(), ]; } /** * @param array $counts */ - private function recordPurgeOperationRun(Tenant $tenant, array $counts): void + private function recordPurgeOperationRun(ManagedEnvironment $tenant, array $counts): void { $deletedRows = Arr::except($counts, ['audit_logs_retained']); OperationRun::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->id, + 'managed_environment_id' => (int) $tenant->id, 'user_id' => null, 'initiator_name' => 'System', 'type' => OperationRunType::BackupSchedulePurge->value, diff --git a/apps/platform/app/Console/Commands/TenantpilotReconcileBackupScheduleOperationRuns.php b/apps/platform/app/Console/Commands/TenantpilotReconcileBackupScheduleOperationRuns.php index bd0185ab..ea160fa7 100644 --- a/apps/platform/app/Console/Commands/TenantpilotReconcileBackupScheduleOperationRuns.php +++ b/apps/platform/app/Console/Commands/TenantpilotReconcileBackupScheduleOperationRuns.php @@ -4,7 +4,7 @@ use App\Models\BackupSchedule; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\OperationRunService; use App\Services\Operations\OperationLifecycleReconciler; use App\Support\OperationCatalog; @@ -15,7 +15,7 @@ class TenantpilotReconcileBackupScheduleOperationRuns extends Command { protected $signature = 'tenantpilot:operation-runs:reconcile-backup-schedules - {--tenant=* : Limit to tenant_id/external_id} + {--tenant=* : Limit to managed_environment_id/external_id} {--older-than=5 : Only reconcile runs older than N minutes} {--dry-run : Do not write changes}'; @@ -46,7 +46,7 @@ public function handle( return self::SUCCESS; } - $query->whereIn('tenant_id', $tenantIds); + $query->whereIn('managed_environment_id', $tenantIds); } $reconciled = 0; @@ -78,7 +78,7 @@ public function handle( $schedule = BackupSchedule::query() ->whereKey((int) $backupScheduleId) - ->where('tenant_id', (int) $operationRun->tenant_id) + ->where('managed_environment_id', (int) $operationRun->managed_environment_id) ->first(); if (! $schedule instanceof BackupSchedule) { @@ -135,7 +135,7 @@ private function resolveTenantIds(array $tenantIdentifiers): array $tenantIds = []; foreach ($tenantIdentifiers as $identifier) { - $tenant = Tenant::query() + $tenant = ManagedEnvironment::query() ->forTenant($identifier) ->first(); diff --git a/apps/platform/app/Console/Commands/TenantpilotReconcileOperationRuns.php b/apps/platform/app/Console/Commands/TenantpilotReconcileOperationRuns.php index 49a096b9..d19014f6 100644 --- a/apps/platform/app/Console/Commands/TenantpilotReconcileOperationRuns.php +++ b/apps/platform/app/Console/Commands/TenantpilotReconcileOperationRuns.php @@ -4,7 +4,7 @@ namespace App\Console\Commands; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Operations\OperationLifecycleReconciler; use App\Support\Operations\OperationLifecyclePolicy; use Illuminate\Console\Command; @@ -13,7 +13,7 @@ class TenantpilotReconcileOperationRuns extends Command { protected $signature = 'tenantpilot:operation-runs:reconcile {--type=* : Limit reconciliation to one or more covered operation types} - {--tenant=* : Limit reconciliation to tenant_id or tenant external_id} + {--tenant=* : Limit reconciliation to managed_environment_id or tenant external_id} {--workspace=* : Limit reconciliation to workspace ids} {--limit=100 : Maximum number of active runs to inspect} {--dry-run : Report the changes without writing them}'; @@ -93,9 +93,9 @@ private function resolveTenantIds(array $tenantIdentifiers): array $tenantIds = []; foreach ($tenantIdentifiers as $identifier) { - $tenant = Tenant::query()->forTenant($identifier)->first(); + $tenant = ManagedEnvironment::query()->forTenant($identifier)->first(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $tenantIds[] = (int) $tenant->getKey(); } } diff --git a/apps/platform/app/Console/Commands/TestSettingsCatalogCache.php b/apps/platform/app/Console/Commands/TestSettingsCatalogCache.php index 08c1a953..c5b98b61 100644 --- a/apps/platform/app/Console/Commands/TestSettingsCatalogCache.php +++ b/apps/platform/app/Console/Commands/TestSettingsCatalogCache.php @@ -55,7 +55,7 @@ public function handle(PolicySnapshotService $snapshotService): int // Create PolicyVersion to save the snapshot $policy->versions()->create([ - 'tenant_id' => $policy->tenant_id, + 'managed_environment_id' => $policy->managed_environment_id, 'version_number' => $policy->versions()->max('version_number') + 1, 'policy_type' => $policy->policy_type, 'platform' => $policy->platform, diff --git a/apps/platform/app/Contracts/Hardening/WriteGateInterface.php b/apps/platform/app/Contracts/Hardening/WriteGateInterface.php index 747ae67c..d61795ea 100644 --- a/apps/platform/app/Contracts/Hardening/WriteGateInterface.php +++ b/apps/platform/app/Contracts/Hardening/WriteGateInterface.php @@ -3,7 +3,7 @@ namespace App\Contracts\Hardening; use App\Exceptions\Hardening\ProviderAccessHardeningRequired; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; interface WriteGateInterface { @@ -12,12 +12,12 @@ interface WriteGateInterface * * @throws ProviderAccessHardeningRequired when the operation is blocked */ - public function evaluate(Tenant $tenant, string $operationType): void; + public function evaluate(ManagedEnvironment $tenant, string $operationType): void; /** * Check whether the gate would block a write operation for the given tenant. * * Non-throwing variant for UI disabled-state checks. */ - public function wouldBlock(Tenant $tenant): bool; + public function wouldBlock(ManagedEnvironment $tenant): bool; } diff --git a/apps/platform/app/Filament/Concerns/InteractsWithTenantOwnedRecords.php b/apps/platform/app/Filament/Concerns/InteractsWithTenantOwnedRecords.php index 71739161..adaec474 100644 --- a/apps/platform/app/Filament/Concerns/InteractsWithTenantOwnedRecords.php +++ b/apps/platform/app/Filament/Concerns/InteractsWithTenantOwnedRecords.php @@ -4,7 +4,7 @@ namespace App\Filament\Concerns; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\WorkspaceIsolation\TenantOwnedQueryScope; use App\Support\WorkspaceIsolation\TenantOwnedRecordResolver; use Illuminate\Database\Eloquent\Builder; @@ -23,7 +23,7 @@ protected static function tenantOwnedRelationshipName(): string : 'tenant'; } - protected static function resolveTenantContextForTenantOwnedRecords(): ?Tenant + protected static function resolveTenantContextForTenantOwnedRecords(): ?ManagedEnvironment { if (method_exists(static::class, 'resolveTenantContextForCurrentPanel')) { return static::resolveTenantContextForCurrentPanel(); @@ -41,7 +41,7 @@ public static function getTenantOwnedEloquentQuery(): Builder return static::scopeTenantOwnedQuery(parent::getEloquentQuery()); } - protected static function scopeTenantOwnedQuery(Builder $query, ?Tenant $tenant = null): Builder + protected static function scopeTenantOwnedQuery(Builder $query, ?ManagedEnvironment $tenant = null): Builder { return app(TenantOwnedQueryScope::class)->apply( $query, @@ -50,7 +50,7 @@ protected static function scopeTenantOwnedQuery(Builder $query, ?Tenant $tenant ); } - protected static function resolveTenantOwnedRecord(Model|int|string|null $record, ?Builder $query = null, ?Tenant $tenant = null): ?Model + protected static function resolveTenantOwnedRecord(Model|int|string|null $record, ?Builder $query = null, ?ManagedEnvironment $tenant = null): ?Model { $scopedQuery = static::scopeTenantOwnedQuery( $query ?? parent::getEloquentQuery(), @@ -60,7 +60,7 @@ protected static function resolveTenantOwnedRecord(Model|int|string|null $record return app(TenantOwnedRecordResolver::class)->resolve($scopedQuery, $record); } - protected static function resolveTenantOwnedRecordOrFail(Model|int|string|null $record, ?Builder $query = null, ?Tenant $tenant = null): Model + protected static function resolveTenantOwnedRecordOrFail(Model|int|string|null $record, ?Builder $query = null, ?ManagedEnvironment $tenant = null): Model { $scopedQuery = static::scopeTenantOwnedQuery( $query ?? parent::getEloquentQuery(), diff --git a/apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php b/apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php index 9d4e29d7..b4400a9c 100644 --- a/apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php +++ b/apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php @@ -4,50 +4,50 @@ namespace App\Filament\Concerns; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperateHub\OperateHubShell; use Filament\Facades\Filament; use RuntimeException; trait ResolvesPanelTenantContext { - protected static function resolveTenantContextForCurrentPanel(): ?Tenant + protected static function resolveTenantContextForCurrentPanel(): ?ManagedEnvironment { $request = request(); if (static::currentPanelId($request) === 'admin') { $tenant = app(OperateHubShell::class)->tenantOwnedPanelContext(request()); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } - public static function panelTenantContext(): ?Tenant + public static function panelTenantContext(): ?ManagedEnvironment { return static::resolveTenantContextForCurrentPanel(); } - public static function trustedPanelTenantContext(): ?Tenant + public static function trustedPanelTenantContext(): ?ManagedEnvironment { return static::panelTenantContext(); } - protected static function resolveTenantContextForCurrentPanelOrFail(): Tenant + protected static function resolveTenantContextForCurrentPanelOrFail(): ManagedEnvironment { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new RuntimeException('No tenant context selected.'); } return $tenant; } - protected static function resolveTrustedPanelTenantContextOrFail(): Tenant + protected static function resolveTrustedPanelTenantContextOrFail(): ManagedEnvironment { return static::resolveTenantContextForCurrentPanelOrFail(); } diff --git a/apps/platform/app/Filament/Concerns/ScopesGlobalSearchToTenant.php b/apps/platform/app/Filament/Concerns/ScopesGlobalSearchToTenant.php index 3934aa3e..af5d38b5 100644 --- a/apps/platform/app/Filament/Concerns/ScopesGlobalSearchToTenant.php +++ b/apps/platform/app/Filament/Concerns/ScopesGlobalSearchToTenant.php @@ -4,7 +4,7 @@ namespace App\Filament\Concerns; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperateHub\OperateHubShell; use App\Support\WorkspaceIsolation\TenantOwnedModelFamilies; use Filament\Facades\Filament; @@ -54,7 +54,7 @@ protected static function resolveGlobalSearchTenant(): ?Model if (Filament::getCurrentPanel()?->getId() === 'admin') { $tenant = app(OperateHubShell::class)->activeEntitledTenant(request()); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } $tenant = Filament::getTenant(); diff --git a/apps/platform/app/Filament/Pages/BaselineCompareLanding.php b/apps/platform/app/Filament/Pages/BaselineCompareLanding.php index 1188d374..29411f13 100644 --- a/apps/platform/app/Filament/Pages/BaselineCompareLanding.php +++ b/apps/platform/app/Filament/Pages/BaselineCompareLanding.php @@ -9,7 +9,7 @@ use App\Filament\Resources\FindingResource; use App\Models\BaselineProfile; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Baselines\BaselineCompareService; @@ -185,7 +185,7 @@ public static function canAccess(): bool $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return false; } @@ -217,7 +217,7 @@ public function refreshStats(): void { $tenant = static::resolveTenantContextForCurrentPanel(); $stats = BaselineCompareStats::forTenant($tenant); - $aggregate = $tenant instanceof Tenant + $aggregate = $tenant instanceof ManagedEnvironment ? $this->governanceAggregate($tenant, $stats) : null; @@ -442,7 +442,7 @@ private function compareNowAction(): Action $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { Notification::make()->title('Select a tenant to compare baselines')->danger()->send(); return; @@ -509,7 +509,7 @@ public function getFindingsUrl(): ?string { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -524,7 +524,7 @@ public function getRunUrl(): ?string $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -551,7 +551,7 @@ public function openCompareMatrixUrl(): ?string return $url.(str_contains($url, '?') ? '&' : '?').http_build_query($query); } - private function governanceAggregate(Tenant $tenant, BaselineCompareStats $stats): TenantGovernanceAggregate + private function governanceAggregate(ManagedEnvironment $tenant, BaselineCompareStats $stats): TenantGovernanceAggregate { /** @var TenantGovernanceAggregateResolver $resolver */ $resolver = app(TenantGovernanceAggregateResolver::class); @@ -575,7 +575,7 @@ private function resolveCompareMatrixProfile(): ?BaselineProfile { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } diff --git a/apps/platform/app/Filament/Pages/BaselineCompareMatrix.php b/apps/platform/app/Filament/Pages/BaselineCompareMatrix.php index 8f5b0e8c..a67552ad 100644 --- a/apps/platform/app/Filament/Pages/BaselineCompareMatrix.php +++ b/apps/platform/app/Filament/Pages/BaselineCompareMatrix.php @@ -7,7 +7,7 @@ use App\Filament\Resources\BaselineProfileResource; use App\Filament\Resources\FindingResource; use App\Models\BaselineProfile; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\WorkspaceCapabilityResolver; @@ -283,7 +283,7 @@ public function form(Schema $schema): Schema ]) ->schema([ Select::make('draftTenantSort') - ->label('Tenant sort') + ->label('ManagedEnvironment sort') ->options(fn (): array => $this->matrixOptions('tenantSortOptions')) ->default('tenant_name') ->native(false) @@ -441,7 +441,7 @@ public function tenantCompareUrl(int $tenantId, ?string $subjectKey = null): ?st { $tenant = $this->tenant($tenantId); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -456,7 +456,7 @@ public function findingUrl(int $tenantId, int $findingId, ?string $subjectKey = { $tenant = $this->tenant($tenantId); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -573,7 +573,7 @@ public function stagedFilterSummary(): array } if ($this->draftTenantSort !== $this->tenantSort) { - $summary['Tenant sort'] = $this->draftTenantSort; + $summary['ManagedEnvironment sort'] = $this->draftTenantSort; } if ($this->draftSubjectSort !== $this->subjectSort) { @@ -855,7 +855,7 @@ private function routeParameters(array $overrides = []): array ], static fn (mixed $value): bool => $value !== null && $value !== [] && $value !== ''); } - private function navigationContext(?Tenant $tenant = null, ?string $subjectKey = null): CanonicalNavigationContext + private function navigationContext(?ManagedEnvironment $tenant = null, ?string $subjectKey = null): CanonicalNavigationContext { /** @var BaselineProfile $profile */ $profile = $this->getRecord(); @@ -870,9 +870,9 @@ private function navigationContext(?Tenant $tenant = null, ?string $subjectKey = ); } - private function tenant(int $tenantId): ?Tenant + private function tenant(int $tenantId): ?ManagedEnvironment { - return Tenant::query() + return ManagedEnvironment::query() ->whereKey($tenantId) ->where('workspace_id', (int) $this->getRecord()->workspace_id) ->first(); diff --git a/apps/platform/app/Filament/Pages/ChooseTenant.php b/apps/platform/app/Filament/Pages/ChooseTenant.php index eefc4085..8627d58c 100644 --- a/apps/platform/app/Filament/Pages/ChooseTenant.php +++ b/apps/platform/app/Filament/Pages/ChooseTenant.php @@ -4,7 +4,7 @@ namespace App\Filament\Pages; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\UserTenantPreference; use App\Services\Tenants\TenantOperabilityService; @@ -43,14 +43,14 @@ protected function getLayoutData(): array } /** - * @return Collection + * @return Collection */ public function getTenants(): Collection { $user = auth()->user(); if (! $user instanceof User) { - return Tenant::query()->whereRaw('1 = 0')->get(); + return ManagedEnvironment::query()->whereRaw('1 = 0')->get(); } $tenants = $user->getTenants(Filament::getCurrentOrDefaultPanel()); @@ -75,9 +75,9 @@ public function selectTenant(int $tenantId): void $tenant = null; if ($workspaceId === null) { - $tenant = Tenant::query()->whereKey($tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey($tenantId)->first(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $workspace = $tenant->workspace; if ($workspace !== null && $user->canAccessTenant($tenant)) { @@ -93,14 +93,14 @@ public function selectTenant(int $tenantId): void return; } - if (! $tenant instanceof Tenant || (int) $tenant->workspace_id !== $workspaceId) { - $tenant = Tenant::query() + if (! $tenant instanceof ManagedEnvironment || (int) $tenant->workspace_id !== $workspaceId) { + $tenant = ManagedEnvironment::query() ->where('workspace_id', $workspaceId) ->whereKey($tenantId) ->first(); } - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -129,12 +129,12 @@ public function selectTenant(int $tenantId): void $this->redirect(TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant)); } - public function tenantLifecyclePresentation(Tenant $tenant): TenantLifecyclePresentation + public function tenantLifecyclePresentation(ManagedEnvironment $tenant): TenantLifecyclePresentation { return TenantLifecyclePresentation::fromTenant($tenant); } - private function persistLastTenant(User $user, Tenant $tenant): void + private function persistLastTenant(User $user, ManagedEnvironment $tenant): void { if (Schema::hasColumn('users', 'last_tenant_id')) { $user->forceFill(['last_tenant_id' => $tenant->getKey()])->save(); @@ -142,12 +142,12 @@ private function persistLastTenant(User $user, Tenant $tenant): void return; } - if (! Schema::hasTable('user_tenant_preferences')) { + if (! Schema::hasTable('user_managed_environment_preferences')) { return; } UserTenantPreference::query()->updateOrCreate( - ['user_id' => $user->getKey(), 'tenant_id' => $tenant->getKey()], + ['user_id' => $user->getKey(), 'managed_environment_id' => $tenant->getKey()], ['last_used_at' => now()] ); } diff --git a/apps/platform/app/Filament/Pages/ChooseWorkspace.php b/apps/platform/app/Filament/Pages/ChooseWorkspace.php index ead7ecc8..634eb2e6 100644 --- a/apps/platform/app/Filament/Pages/ChooseWorkspace.php +++ b/apps/platform/app/Filament/Pages/ChooseWorkspace.php @@ -64,7 +64,7 @@ public function getWorkspaces(): Collection }) ->whereNull('archived_at') ->withCount(['tenants' => function ($query): void { - $query->where('status', 'active'); + $query->where('lifecycle_status', 'active'); }]) ->orderBy('name') ->get(); diff --git a/apps/platform/app/Filament/Pages/CrossTenantComparePage.php b/apps/platform/app/Filament/Pages/CrossTenantComparePage.php index 8189b9be..7b7db1a0 100644 --- a/apps/platform/app/Filament/Pages/CrossTenantComparePage.php +++ b/apps/platform/app/Filament/Pages/CrossTenantComparePage.php @@ -6,7 +6,7 @@ use App\Filament\Resources\TenantResource; use App\Models\InventoryItem; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Audit\WorkspaceAuditLogger; @@ -60,7 +60,7 @@ class CrossTenantComparePage extends Page implements HasForms protected static string|UnitEnum|null $navigationGroup = 'Governance'; - protected static ?string $title = 'Cross-Tenant Compare'; + protected static ?string $title = 'Cross-ManagedEnvironment Compare'; protected static ?string $slug = 'cross-tenant-compare'; @@ -178,7 +178,7 @@ protected function getHeaderActions(): array $sourceTenant = $this->selectedSourceTenant(); - if ($sourceTenant instanceof Tenant) { + if ($sourceTenant instanceof ManagedEnvironment) { $actions[] = Action::make('open_source_tenant') ->label('Open source tenant') ->icon('heroicon-o-arrow-top-right-on-square') @@ -188,7 +188,7 @@ protected function getHeaderActions(): array $targetTenant = $this->selectedTargetTenant(); - if ($targetTenant instanceof Tenant) { + if ($targetTenant instanceof ManagedEnvironment) { $actions[] = Action::make('open_target_tenant') ->label('Open target tenant') ->icon('heroicon-o-arrow-top-right-on-square') @@ -388,17 +388,17 @@ public function selectionUrl(): string } public static function launchUrl( - ?Tenant $sourceTenant = null, - ?Tenant $targetTenant = null, + ?ManagedEnvironment $sourceTenant = null, + ?ManagedEnvironment $targetTenant = null, ?CanonicalNavigationContext $navigationContext = null, ): string { $parameters = []; - if ($sourceTenant instanceof Tenant) { + if ($sourceTenant instanceof ManagedEnvironment) { $parameters[self::SOURCE_TENANT_QUERY_KEY] = (int) $sourceTenant->getKey(); } - if ($targetTenant instanceof Tenant) { + if ($targetTenant instanceof ManagedEnvironment) { $parameters[self::TARGET_TENANT_QUERY_KEY] = (int) $targetTenant->getKey(); } @@ -442,7 +442,7 @@ public function sourceTenantUrl(): ?string { $tenant = $this->selectedSourceTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -453,7 +453,7 @@ public function targetTenantUrl(): ?string { $tenant = $this->selectedTargetTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -556,7 +556,7 @@ private function authorizePromotionExecution(): void $targetTenant = $this->selectedTargetTenant(); - if (! $targetTenant instanceof Tenant) { + if (! $targetTenant instanceof ManagedEnvironment) { abort(404); } @@ -573,7 +573,7 @@ private function compareSelection(): ?CrossTenantCompareSelection $sourceTenant = $this->selectedSourceTenant(); $targetTenant = $this->selectedTargetTenant(); - if (! $sourceTenant instanceof Tenant || ! $targetTenant instanceof Tenant) { + if (! $sourceTenant instanceof ManagedEnvironment || ! $targetTenant instanceof ManagedEnvironment) { return null; } @@ -590,7 +590,7 @@ private function compareSelection(): ?CrossTenantCompareSelection ); } - private function selectedSourceTenant(): ?Tenant + private function selectedSourceTenant(): ?ManagedEnvironment { if ($this->sourceTenantId === null) { return null; @@ -599,7 +599,7 @@ private function selectedSourceTenant(): ?Tenant return $this->resolveAuthorizedTenant($this->sourceTenantId); } - private function selectedTargetTenant(): ?Tenant + private function selectedTargetTenant(): ?ManagedEnvironment { if ($this->targetTenantId === null) { return null; @@ -608,7 +608,7 @@ private function selectedTargetTenant(): ?Tenant return $this->resolveAuthorizedTenant($this->targetTenantId); } - private function resolveAuthorizedTenant(string $tenantId): Tenant + private function resolveAuthorizedTenant(string $tenantId): ManagedEnvironment { $workspace = $this->workspace(); $user = auth()->user(); @@ -617,12 +617,12 @@ private function resolveAuthorizedTenant(string $tenantId): Tenant abort(404); } - $tenant = Tenant::query() + $tenant = ManagedEnvironment::query() ->where('workspace_id', (int) $workspace->getKey()) ->whereKey((int) $tenantId) ->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -652,16 +652,16 @@ private function tenantOptions(): array $resolver = app(CapabilityResolver::class); $tenants = $user->tenants() - ->where('tenants.workspace_id', (int) $workspace->getKey()) - ->select('tenants.*') - ->orderBy('tenants.name') + ->where('managed_environments.workspace_id', (int) $workspace->getKey()) + ->select('managed_environments.*') + ->orderBy('managed_environments.name') ->get(); $resolver->primeMemberships($user, $tenants->modelKeys()); return $tenants - ->filter(fn (Tenant $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_VIEW)) - ->mapWithKeys(fn (Tenant $tenant): array => [ + ->filter(fn (ManagedEnvironment $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_VIEW)) + ->mapWithKeys(fn (ManagedEnvironment $tenant): array => [ (string) $tenant->getKey() => (string) $tenant->name, ]) ->all(); @@ -679,7 +679,7 @@ private function policyTypeOptions(): array } return InventoryItem::query() - ->whereIn('tenant_id', $tenantIds) + ->whereIn('managed_environment_id', $tenantIds) ->whereNotNull('policy_type') ->where('policy_type', '!=', '') ->distinct() @@ -740,7 +740,7 @@ private function executePromotionDisabledReason(): ?string $targetTenant = $this->selectedTargetTenant(); - if ($targetTenant instanceof Tenant) { + if ($targetTenant instanceof ManagedEnvironment) { /** @var CapabilityResolver $resolver */ $resolver = app(CapabilityResolver::class); diff --git a/apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php b/apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php index 1963e182..9add7bb1 100644 --- a/apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php +++ b/apps/platform/app/Filament/Pages/Findings/FindingsHygieneReport.php @@ -7,7 +7,7 @@ use App\Filament\Resources\FindingExceptionResource; use App\Filament\Resources\FindingResource; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\WorkspaceCapabilityResolver; @@ -54,7 +54,7 @@ class FindingsHygieneReport extends Page implements HasTable protected string $view = 'filament.pages.findings.findings-hygiene-report'; /** - * @var array|null + * @var array|null */ private ?array $visibleTenants = null; @@ -109,7 +109,7 @@ public function table(Table $table): Table ->persistFiltersInSession() ->columns([ TextColumn::make('tenant.name') - ->label('Tenant'), + ->label('ManagedEnvironment'), TextColumn::make('subject_display_name') ->label('Finding') ->state(fn (Finding $record): string => $record->resolvedSubjectDisplayName() ?? 'Finding #'.$record->getKey()) @@ -138,8 +138,8 @@ public function table(Table $table): Table ->description(fn (Finding $record): ?string => FindingExceptionResource::relativeTimeDescription($this->hygieneService()->lastWorkflowActivityAt($record))), ]) ->filters([ - SelectFilter::make('tenant_id') - ->label('Tenant') + SelectFilter::make('managed_environment_id') + ->label('ManagedEnvironment') ->options(fn (): array => $this->tenantFilterOptions()) ->searchable(), ]) @@ -183,10 +183,10 @@ public function availableFilters(): array ], [ 'key' => 'tenant', - 'label' => 'Tenant', + 'label' => 'ManagedEnvironment', 'fixed' => false, 'options' => collect($this->visibleTenants()) - ->map(fn (Tenant $tenant): array => [ + ->map(fn (ManagedEnvironment $tenant): array => [ 'value' => (string) $tenant->getKey(), 'label' => (string) $tenant->name, ]) @@ -290,12 +290,12 @@ public function updatedTableFilters(): void public function clearTenantFilter(): void { - $this->removeTableFilter('tenant_id'); + $this->removeTableFilter('managed_environment_id'); $this->resetTable(); } /** - * @return array + * @return array */ public function visibleTenants(): array { @@ -394,7 +394,7 @@ private function filteredIssueQuery(bool $includeTenantFilter = true, ?string $r private function tenantFilterOptions(): array { return collect($this->visibleTenants()) - ->mapWithKeys(static fn (Tenant $tenant): array => [ + ->mapWithKeys(static fn (ManagedEnvironment $tenant): array => [ (string) $tenant->getKey() => (string) $tenant->name, ]) ->all(); @@ -413,8 +413,8 @@ private function applyRequestedTenantPrefilter(): void continue; } - $this->tableFilters['tenant_id']['value'] = (string) $tenant->getKey(); - $this->tableDeferredFilters['tenant_id']['value'] = (string) $tenant->getKey(); + $this->tableFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); + $this->tableDeferredFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); return; } @@ -422,7 +422,7 @@ private function applyRequestedTenantPrefilter(): void private function normalizeTenantFilterState(): void { - $configuredTenantFilter = data_get($this->currentFiltersState(), 'tenant_id.value'); + $configuredTenantFilter = data_get($this->currentFiltersState(), 'managed_environment_id.value'); if ($configuredTenantFilter === null || $configuredTenantFilter === '') { return; @@ -432,7 +432,7 @@ private function normalizeTenantFilterState(): void return; } - $this->removeTableFilter('tenant_id'); + $this->removeTableFilter('managed_environment_id'); } /** @@ -450,7 +450,7 @@ private function currentFiltersState(): array private function currentTenantFilterId(): ?int { - $tenantFilter = data_get($this->currentFiltersState(), 'tenant_id.value'); + $tenantFilter = data_get($this->currentFiltersState(), 'managed_environment_id.value'); if (! is_numeric($tenantFilter)) { return null; @@ -467,7 +467,7 @@ private function currentTenantFilterId(): ?int return null; } - private function filteredTenant(): ?Tenant + private function filteredTenant(): ?ManagedEnvironment { $tenantId = $this->currentTenantFilterId(); @@ -484,11 +484,11 @@ private function filteredTenant(): ?Tenant return null; } - private function activeVisibleTenant(): ?Tenant + private function activeVisibleTenant(): ?ManagedEnvironment { $activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request()); - if (! $activeTenant instanceof Tenant) { + if (! $activeTenant instanceof ManagedEnvironment) { return null; } @@ -505,13 +505,13 @@ private function tenantPrefilterSource(): string { $tenant = $this->filteredTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return 'none'; } $activeTenant = $this->activeVisibleTenant(); - if ($activeTenant instanceof Tenant && $activeTenant->is($tenant)) { + if ($activeTenant instanceof ManagedEnvironment && $activeTenant->is($tenant)) { return 'active_tenant_context'; } @@ -561,7 +561,7 @@ private function findingDetailUrl(Finding $record): string { $tenant = $record->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return '#'; } diff --git a/apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php b/apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php index 20e538b7..0c7a52cc 100644 --- a/apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php +++ b/apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php @@ -7,7 +7,7 @@ use App\Filament\Resources\FindingExceptionResource; use App\Filament\Resources\FindingResource; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -62,12 +62,12 @@ class FindingsIntakeQueue extends Page implements HasTable protected string $view = 'filament.pages.findings.findings-intake-queue'; /** - * @var array|null + * @var array|null */ private ?array $authorizedTenants = null; /** - * @var array|null + * @var array|null */ private ?array $visibleTenants = null; @@ -135,7 +135,7 @@ public function table(Table $table): Table ->persistFiltersInSession() ->columns([ TextColumn::make('tenant.name') - ->label('Tenant'), + ->label('ManagedEnvironment'), TextColumn::make('subject_display_name') ->label('Finding') ->state(fn (Finding $record): string => $record->resolvedSubjectDisplayName() ?? 'Finding #'.$record->getKey()) @@ -166,8 +166,8 @@ public function table(Table $table): Table ->color(fn (Finding $record): string => $this->queueReasonColor($record)), ]) ->filters([ - SelectFilter::make('tenant_id') - ->label('Tenant') + SelectFilter::make('managed_environment_id') + ->label('ManagedEnvironment') ->options(fn (): array => $this->tenantFilterOptions()) ->searchable(), ]) @@ -278,12 +278,12 @@ public function updatedTableFilters(): void public function clearTenantFilter(): void { - $this->removeTableFilter('tenant_id'); + $this->removeTableFilter('managed_environment_id'); $this->resetTable(); } /** - * @return array + * @return array */ public function visibleTenants(): array { @@ -301,12 +301,12 @@ public function visibleTenants(): array $resolver = app(CapabilityResolver::class); $resolver->primeMemberships( $user, - array_map(static fn (Tenant $tenant): int => (int) $tenant->getKey(), $tenants), + array_map(static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $tenants), ); return $this->visibleTenants = array_values(array_filter( $tenants, - fn (Tenant $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW), + fn (ManagedEnvironment $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW), )); } @@ -335,7 +335,7 @@ private function claimAction(): Action $tenant = $record->tenant; $user = auth()->user(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new NotFoundHttpException; } @@ -406,7 +406,7 @@ private function authorizePageAccess(): void } /** - * @return array + * @return array */ private function authorizedTenants(): array { @@ -422,10 +422,10 @@ private function authorizedTenants(): array } return $this->authorizedTenants = $user->tenants() - ->where('tenants.workspace_id', (int) $workspace->getKey()) - ->where('tenants.status', 'active') - ->orderBy('tenants.name') - ->get(['tenants.id', 'tenants.name', 'tenants.external_id', 'tenants.workspace_id']) + ->where('managed_environments.workspace_id', (int) $workspace->getKey()) + ->where('managed_environments.lifecycle_status', 'active') + ->orderBy('managed_environments.name') + ->get(['managed_environments.id', 'managed_environments.name', 'managed_environments.slug', 'managed_environments.workspace_id']) ->all(); } @@ -448,7 +448,7 @@ private function queueBaseQuery(): Builder { $workspace = $this->workspace(); $tenantIds = array_map( - static fn (Tenant $tenant): int => (int) $tenant->getKey(), + static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $this->visibleTenants(), ); @@ -460,7 +460,7 @@ private function queueBaseQuery(): Builder ->with(['tenant', 'ownerUser', 'assigneeUser']) ->withSubjectDisplayName() ->where('workspace_id', (int) $workspace->getKey()) - ->whereIn('tenant_id', $tenantIds === [] ? [-1] : $tenantIds) + ->whereIn('managed_environment_id', $tenantIds === [] ? [-1] : $tenantIds) ->whereNull('assignee_user_id') ->whereIn('status', Finding::openStatuses()); } @@ -479,7 +479,7 @@ private function filteredQueueQuery( $resolvedQueueView = $queueView ?? $this->queueView; if ($includeTenantFilter && ($tenantId = $this->currentTenantFilterId()) !== null) { - $query->where('tenant_id', $tenantId); + $query->where('managed_environment_id', $tenantId); } if ($resolvedQueueView === 'needs_triage') { @@ -514,7 +514,7 @@ private function filteredQueueQuery( private function tenantFilterOptions(): array { return collect($this->visibleTenants()) - ->mapWithKeys(static fn (Tenant $tenant): array => [ + ->mapWithKeys(static fn (ManagedEnvironment $tenant): array => [ (string) $tenant->getKey() => (string) $tenant->name, ]) ->all(); @@ -533,8 +533,8 @@ private function applyRequestedTenantPrefilter(): void continue; } - $this->tableFilters['tenant_id']['value'] = (string) $tenant->getKey(); - $this->tableDeferredFilters['tenant_id']['value'] = (string) $tenant->getKey(); + $this->tableFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); + $this->tableDeferredFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); return; } @@ -542,7 +542,7 @@ private function applyRequestedTenantPrefilter(): void private function normalizeTenantFilterState(): void { - $configuredTenantFilter = data_get($this->currentQueueFiltersState(), 'tenant_id.value'); + $configuredTenantFilter = data_get($this->currentQueueFiltersState(), 'managed_environment_id.value'); if ($configuredTenantFilter === null || $configuredTenantFilter === '') { return; @@ -552,7 +552,7 @@ private function normalizeTenantFilterState(): void return; } - $this->removeTableFilter('tenant_id'); + $this->removeTableFilter('managed_environment_id'); } /** @@ -570,7 +570,7 @@ private function currentQueueFiltersState(): array private function currentTenantFilterId(): ?int { - $tenantFilter = data_get($this->currentQueueFiltersState(), 'tenant_id.value'); + $tenantFilter = data_get($this->currentQueueFiltersState(), 'managed_environment_id.value'); if (! is_numeric($tenantFilter)) { return null; @@ -587,7 +587,7 @@ private function currentTenantFilterId(): ?int return null; } - private function filteredTenant(): ?Tenant + private function filteredTenant(): ?ManagedEnvironment { $tenantId = $this->currentTenantFilterId(); @@ -604,11 +604,11 @@ private function filteredTenant(): ?Tenant return null; } - private function activeVisibleTenant(): ?Tenant + private function activeVisibleTenant(): ?ManagedEnvironment { $activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request()); - if (! $activeTenant instanceof Tenant) { + if (! $activeTenant instanceof ManagedEnvironment) { return null; } @@ -625,13 +625,13 @@ private function tenantPrefilterSource(): string { $tenant = $this->filteredTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return 'none'; } $activeTenant = $this->activeVisibleTenant(); - if ($activeTenant instanceof Tenant && $activeTenant->is($tenant)) { + if ($activeTenant instanceof ManagedEnvironment && $activeTenant->is($tenant)) { return 'active_tenant_context'; } @@ -690,7 +690,7 @@ private function findingDetailUrl(Finding $record): string { $tenant = $record->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return '#'; } diff --git a/apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php b/apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php index 15f9a7b7..c0f54e3f 100644 --- a/apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php +++ b/apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php @@ -7,7 +7,7 @@ use App\Filament\Resources\FindingExceptionResource; use App\Filament\Resources\FindingResource; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -58,12 +58,12 @@ class MyFindingsInbox extends Page implements HasTable protected string $view = 'filament.pages.findings.my-findings-inbox'; /** - * @var array|null + * @var array|null */ private ?array $authorizedTenants = null; /** - * @var array|null + * @var array|null */ private ?array $visibleTenants = null; @@ -127,7 +127,7 @@ public function table(Table $table): Table ->persistFiltersInSession() ->columns([ TextColumn::make('tenant.name') - ->label('Tenant'), + ->label('ManagedEnvironment'), TextColumn::make('subject_display_name') ->label('Finding') ->state(fn (Finding $record): string => $record->resolvedSubjectDisplayName() ?? 'Finding #'.$record->getKey()) @@ -153,8 +153,8 @@ public function table(Table $table): Table ->description(fn (Finding $record): ?string => FindingExceptionResource::relativeTimeDescription($record->due_at) ?? FindingResource::dueAttentionLabelFor($record)), ]) ->filters([ - SelectFilter::make('tenant_id') - ->label('Tenant') + SelectFilter::make('managed_environment_id') + ->label('ManagedEnvironment') ->options(fn (): array => $this->tenantFilterOptions()) ->searchable(), Filter::make('overdue') @@ -207,10 +207,10 @@ public function availableFilters(): array ], [ 'key' => 'tenant', - 'label' => 'Tenant', + 'label' => 'ManagedEnvironment', 'fixed' => false, 'options' => collect($this->visibleTenants()) - ->map(fn (Tenant $tenant): array => [ + ->map(fn (ManagedEnvironment $tenant): array => [ 'value' => (string) $tenant->getKey(), 'label' => (string) $tenant->name, ]) @@ -272,7 +272,7 @@ public function emptyState(): array $activeTenant = $this->activeVisibleTenant(); - if ($activeTenant instanceof Tenant) { + if ($activeTenant instanceof ManagedEnvironment) { return [ 'title' => 'No visible assigned findings right now', 'body' => 'Nothing currently assigned to you needs attention in the visible tenant scope. You can still open tenant findings for broader context.', @@ -302,12 +302,12 @@ public function updatedTableFilters(): void public function clearTenantFilter(): void { - $this->removeTableFilter('tenant_id'); + $this->removeTableFilter('managed_environment_id'); $this->resetTable(); } /** - * @return array + * @return array */ public function visibleTenants(): array { @@ -325,12 +325,12 @@ public function visibleTenants(): array $resolver = app(CapabilityResolver::class); $resolver->primeMemberships( $user, - array_map(static fn (Tenant $tenant): int => (int) $tenant->getKey(), $tenants), + array_map(static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $tenants), ); return $this->visibleTenants = array_values(array_filter( $tenants, - fn (Tenant $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW), + fn (ManagedEnvironment $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW), )); } @@ -355,7 +355,7 @@ private function authorizePageAccess(): void } /** - * @return array + * @return array */ private function authorizedTenants(): array { @@ -371,10 +371,10 @@ private function authorizedTenants(): array } return $this->authorizedTenants = $user->tenants() - ->where('tenants.workspace_id', (int) $workspace->getKey()) - ->where('tenants.status', 'active') - ->orderBy('tenants.name') - ->get(['tenants.id', 'tenants.name', 'tenants.external_id', 'tenants.workspace_id']) + ->where('managed_environments.workspace_id', (int) $workspace->getKey()) + ->where('managed_environments.lifecycle_status', 'active') + ->orderBy('managed_environments.name') + ->get(['managed_environments.id', 'managed_environments.name', 'managed_environments.slug', 'managed_environments.workspace_id']) ->all(); } @@ -398,7 +398,7 @@ private function queueBaseQuery(): Builder $user = auth()->user(); $workspace = $this->workspace(); $tenantIds = array_map( - static fn (Tenant $tenant): int => (int) $tenant->getKey(), + static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $this->visibleTenants(), ); @@ -410,7 +410,7 @@ private function queueBaseQuery(): Builder ->with(['tenant', 'ownerUser', 'assigneeUser']) ->withSubjectDisplayName() ->where('workspace_id', (int) $workspace->getKey()) - ->whereIn('tenant_id', $tenantIds === [] ? [-1] : $tenantIds) + ->whereIn('managed_environment_id', $tenantIds === [] ? [-1] : $tenantIds) ->where('assignee_user_id', (int) $user->getKey()) ->whereIn('status', Finding::openStatusesForQuery()) ->orderByRaw( @@ -428,7 +428,7 @@ private function filteredQueueQuery(bool $includeTenantFilter = true): Builder $filters = $this->currentQueueFiltersState(); if ($includeTenantFilter && ($tenantId = $this->currentTenantFilterIdFromFilters($filters)) !== null) { - $query->where('tenant_id', $tenantId); + $query->where('managed_environment_id', $tenantId); } if ($this->filterIsActive($filters, 'overdue')) { @@ -454,7 +454,7 @@ private function filteredQueueQuery(bool $includeTenantFilter = true): Builder private function tenantFilterOptions(): array { return collect($this->visibleTenants()) - ->mapWithKeys(static fn (Tenant $tenant): array => [ + ->mapWithKeys(static fn (ManagedEnvironment $tenant): array => [ (string) $tenant->getKey() => (string) $tenant->name, ]) ->all(); @@ -473,8 +473,8 @@ private function applyRequestedTenantPrefilter(): void continue; } - $this->tableFilters['tenant_id']['value'] = (string) $tenant->getKey(); - $this->tableDeferredFilters['tenant_id']['value'] = (string) $tenant->getKey(); + $this->tableFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); + $this->tableDeferredFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); return; } @@ -482,7 +482,7 @@ private function applyRequestedTenantPrefilter(): void private function normalizeTenantFilterState(): void { - $configuredTenantFilter = data_get($this->currentQueueFiltersState(), 'tenant_id.value'); + $configuredTenantFilter = data_get($this->currentQueueFiltersState(), 'managed_environment_id.value'); if ($configuredTenantFilter === null || $configuredTenantFilter === '') { return; @@ -492,7 +492,7 @@ private function normalizeTenantFilterState(): void return; } - $this->removeTableFilter('tenant_id'); + $this->removeTableFilter('managed_environment_id'); } /** @@ -518,7 +518,7 @@ private function currentTenantFilterId(): ?int */ private function currentTenantFilterIdFromFilters(array $filters): ?int { - $tenantFilter = data_get($filters, 'tenant_id.value'); + $tenantFilter = data_get($filters, 'managed_environment_id.value'); if (! is_numeric($tenantFilter)) { return null; @@ -543,7 +543,7 @@ private function filterIsActive(array $filters, string $name): bool return (bool) data_get($filters, "{$name}.isActive", false); } - private function filteredTenant(): ?Tenant + private function filteredTenant(): ?ManagedEnvironment { $tenantId = $this->currentTenantFilterId(); @@ -560,11 +560,11 @@ private function filteredTenant(): ?Tenant return null; } - private function activeVisibleTenant(): ?Tenant + private function activeVisibleTenant(): ?ManagedEnvironment { $activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request()); - if (! $activeTenant instanceof Tenant) { + if (! $activeTenant instanceof ManagedEnvironment) { return null; } @@ -581,13 +581,13 @@ private function tenantPrefilterSource(): string { $tenant = $this->filteredTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return 'none'; } $activeTenant = $this->activeVisibleTenant(); - if ($activeTenant instanceof Tenant && $activeTenant->is($tenant)) { + if ($activeTenant instanceof ManagedEnvironment && $activeTenant->is($tenant)) { return 'active_tenant_context'; } @@ -632,7 +632,7 @@ private function findingDetailUrl(Finding $record): string { $tenant = $record->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return '#'; } diff --git a/apps/platform/app/Filament/Pages/Governance/DecisionRegister.php b/apps/platform/app/Filament/Pages/Governance/DecisionRegister.php index d078c80e..9e08b330 100644 --- a/apps/platform/app/Filament/Pages/Governance/DecisionRegister.php +++ b/apps/platform/app/Filament/Pages/Governance/DecisionRegister.php @@ -6,7 +6,7 @@ use App\Filament\Resources\FindingExceptionResource; use App\Models\FindingException; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -58,12 +58,12 @@ class DecisionRegister extends Page implements HasTable protected string $view = 'filament.pages.governance.decision-register'; /** - * @var array|null + * @var array|null */ private ?array $authorizedTenants = null; /** - * @var array|null + * @var array|null */ private ?array $visibleDecisionTenants = null; @@ -92,7 +92,7 @@ public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration { return ActionSurfaceDeclaration::forPage(ActionSurfaceProfile::ListOnlyReadOnly, ActionSurfaceType::ReadOnlyRegistryReport) ->satisfy(ActionSurfaceSlot::ListHeader, 'Header controls keep tenant and register-state scope visible without introducing a second mutation surface.') - ->satisfy(ActionSurfaceSlot::InspectAffordance, ActionSurfaceInspectAffordance::ViewAction->value) + ->satisfy(ActionSurfaceSlot::InspectAffordance, ActionSurfaceInspectAffordance::ClickableRow->value) ->exempt(ActionSurfaceSlot::ListRowMoreMenu, 'The decision register keeps one dominant row action and avoids a More menu in v1.') ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'The decision register is read-only and intentionally omits bulk actions.') ->satisfy(ActionSurfaceSlot::ListEmptyState, 'Filtered empty states stay truthful and provide one path back to the broader register scope.') @@ -166,7 +166,7 @@ public function pageUrl(array $overrides = []): string return static::getUrl( panel: 'admin', parameters: array_filter([ - 'tenant_id' => is_string($resolvedTenant) && $resolvedTenant !== '' ? $resolvedTenant : null, + 'managed_environment_id' => is_string($resolvedTenant) && $resolvedTenant !== '' ? $resolvedTenant : null, 'register_state' => is_string($resolvedRegisterState) && $resolvedRegisterState !== 'open' ? $resolvedRegisterState : null, ], static fn (mixed $value): bool => $value !== null && $value !== ''), ); @@ -205,7 +205,7 @@ public function availableRegisterStates(): array public function hasTenantPrefilter(): bool { - return $this->selectedTenant() instanceof Tenant; + return $this->selectedTenant() instanceof ManagedEnvironment; } public function isActiveRegisterState(string $registerState): bool @@ -274,10 +274,10 @@ public function table(Table $table): Table ->persistFiltersInSession() ->persistSearchInSession() ->persistSortInSession() - ->recordUrl(null) + ->recordUrl(fn (FindingException $record): ?string => $this->decisionUrl($record)) ->columns([ TextColumn::make('tenant.name') - ->label('Tenant') + ->label('ManagedEnvironment') ->searchable() ->sortable(), TextColumn::make('status') @@ -327,12 +327,6 @@ public function table(Table $table): Table ->visible(fn (): bool => $this->registerState === 'recently_closed') ->wrap(), ]) - ->actions([ - Action::make('open_decision') - ->label('Open decision') - ->color('gray') - ->url(fn (FindingException $record): ?string => $this->decisionUrl($record)), - ]) ->emptyStateHeading($this->emptyStateHeading()) ->emptyStateDescription($this->emptyStateDescription()) ->emptyStateActions($this->emptyStateActions()); @@ -363,13 +357,13 @@ private function emptyStateActions(): array private function tableQuery(): Builder { $tenantIds = array_values(array_map( - static fn (Tenant $tenant): int => (int) $tenant->getKey(), + static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $this->currentScopeTenants(), )); $query = FindingException::query() ->where('workspace_id', (int) $this->workspace()?->getKey()) - ->whereIn('tenant_id', $tenantIds) + ->whereIn('managed_environment_id', $tenantIds) ->with(['tenant', 'owner', 'currentDecision']); if ($this->registerState === 'recently_closed') { @@ -428,7 +422,7 @@ private function ensureRegisterIsVisible(): void } /** - * @return array + * @return array */ private function authorizedTenants(): array { @@ -447,7 +441,7 @@ private function authorizedTenants(): array } /** - * @return array + * @return array */ private function visibleDecisionTenants(): array { @@ -468,7 +462,7 @@ private function visibleDecisionTenants(): array private function applyRequestedTenantPrefilter(): void { - $requestedTenant = request()->query('tenant_id', request()->query('tenant')); + $requestedTenant = request()->query('managed_environment_id', request()->query('tenant')); if (! is_string($requestedTenant) && ! is_numeric($requestedTenant)) { return; @@ -502,7 +496,7 @@ private function resolveRequestedRegisterState(): string private static function hasRequestedTenantPrefilter(): bool { - $requestedTenant = request()->query('tenant_id', request()->query('tenant')); + $requestedTenant = request()->query('managed_environment_id', request()->query('tenant')); return is_string($requestedTenant) || is_numeric($requestedTenant); } @@ -519,21 +513,21 @@ private static function resolveWorkspaceFromRequest(): ?Workspace } /** - * @return array + * @return array */ private static function resolveAuthorizedTenantsFor(User $user, Workspace $workspace): array { return $user->tenants() - ->where('tenants.workspace_id', (int) $workspace->getKey()) - ->where('tenants.status', 'active') - ->orderBy('tenants.name') - ->get(['tenants.id', 'tenants.name', 'tenants.external_id', 'tenants.workspace_id']) + ->where('managed_environments.workspace_id', (int) $workspace->getKey()) + ->where('managed_environments.lifecycle_status', 'active') + ->orderBy('managed_environments.name') + ->get(['managed_environments.id', 'managed_environments.name', 'managed_environments.slug', 'managed_environments.workspace_id']) ->all(); } /** - * @param array|null $authorizedTenants - * @return array + * @param array|null $authorizedTenants + * @return array */ private static function resolveVisibleDecisionTenantsFor(User $user, Workspace $workspace, ?array $authorizedTenants = null): array { @@ -546,12 +540,12 @@ private static function resolveVisibleDecisionTenantsFor(User $user, Workspace $ $resolver = app(CapabilityResolver::class); $resolver->primeMemberships( $user, - array_map(static fn (Tenant $tenant): int => (int) $tenant->getKey(), $tenants), + array_map(static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $tenants), ); return array_values(array_filter( $tenants, - fn (Tenant $tenant): bool => $resolver->can($user, $tenant, Capabilities::FINDING_EXCEPTION_VIEW), + fn (ManagedEnvironment $tenant): bool => $resolver->can($user, $tenant, Capabilities::FINDING_EXCEPTION_VIEW), )); } @@ -564,7 +558,7 @@ private function workspace(): ?Workspace return $this->workspace = static::resolveWorkspaceFromRequest(); } - private function selectedTenant(): ?Tenant + private function selectedTenant(): ?ManagedEnvironment { if (! is_int($this->tenantId)) { return null; @@ -580,13 +574,13 @@ private function selectedTenant(): ?Tenant } /** - * @return array + * @return array */ private function currentScopeTenants(): array { $selectedTenant = $this->selectedTenant(); - if ($selectedTenant instanceof Tenant) { + if ($selectedTenant instanceof ManagedEnvironment) { return [$selectedTenant]; } @@ -682,7 +676,7 @@ public function decisionUrl(FindingException $record): ?string { $tenant = $record->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } diff --git a/apps/platform/app/Filament/Pages/Governance/GovernanceInbox.php b/apps/platform/app/Filament/Pages/Governance/GovernanceInbox.php index dc13ea03..7dc74725 100644 --- a/apps/platform/app/Filament/Pages/Governance/GovernanceInbox.php +++ b/apps/platform/app/Filament/Pages/Governance/GovernanceInbox.php @@ -6,7 +6,7 @@ use App\Filament\Pages\Findings\FindingsIntakeQueue; use App\Filament\Pages\Findings\MyFindingsInbox; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -47,17 +47,17 @@ class GovernanceInbox extends Page protected string $view = 'filament.pages.governance.governance-inbox'; /** - * @var array|null + * @var array|null */ private ?array $authorizedTenants = null; /** - * @var array|null + * @var array|null */ private ?array $visibleFindingTenants = null; /** - * @var array|null + * @var array|null */ private ?array $reviewTenants = null; @@ -113,7 +113,7 @@ public function appliedScope(): array return [ 'workspace_label' => $this->workspace()?->name, 'tenant_label' => $selectedTenant?->name, - 'tenant_prefilter_source' => $selectedTenant instanceof Tenant ? 'explicit_filter' : 'none', + 'tenant_prefilter_source' => $selectedTenant instanceof ManagedEnvironment ? 'explicit_filter' : 'none', 'family_key' => $this->family, 'family_label' => $this->family !== null ? ($availableFamilies->get($this->family)['label'] ?? Str::headline($this->family)) @@ -162,7 +162,7 @@ public function calmEmptyState(): array public function hasTenantPrefilter(): bool { - return $this->selectedTenant() instanceof Tenant; + return $this->selectedTenant() instanceof ManagedEnvironment; } public function isActiveFamily(?string $familyKey): bool @@ -183,7 +183,7 @@ public function pageUrl(array $overrides = []): string return static::getUrl( panel: 'admin', parameters: array_filter([ - 'tenant_id' => is_string($resolvedTenant) && $resolvedTenant !== '' ? $resolvedTenant : null, + 'managed_environment_id' => is_string($resolvedTenant) && $resolvedTenant !== '' ? $resolvedTenant : null, 'family' => is_string($resolvedFamily) && $resolvedFamily !== '' ? $resolvedFamily : null, ], static fn (mixed $value): bool => $value !== null && $value !== ''), ); @@ -290,7 +290,7 @@ private function hasVisibleFindingExceptionsFamily(): bool } /** - * @return array + * @return array */ private function visibleFindingTenants(): array { @@ -308,17 +308,17 @@ private function visibleFindingTenants(): array $resolver = app(CapabilityResolver::class); $resolver->primeMemberships( $user, - array_map(static fn (Tenant $tenant): int => (int) $tenant->getKey(), $tenants), + array_map(static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $tenants), ); return $this->visibleFindingTenants = array_values(array_filter( $tenants, - fn (Tenant $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW), + fn (ManagedEnvironment $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW), )); } /** - * @return array + * @return array */ private function reviewTenants(): array { @@ -343,7 +343,7 @@ private function reviewTenants(): array } /** - * @return array + * @return array */ private function authorizedTenants(): array { @@ -359,16 +359,16 @@ private function authorizedTenants(): array } return $this->authorizedTenants = $user->tenants() - ->where('tenants.workspace_id', (int) $workspace->getKey()) - ->where('tenants.status', 'active') - ->orderBy('tenants.name') - ->get(['tenants.id', 'tenants.name', 'tenants.external_id', 'tenants.workspace_id']) + ->where('managed_environments.workspace_id', (int) $workspace->getKey()) + ->where('managed_environments.lifecycle_status', 'active') + ->orderBy('managed_environments.name') + ->get(['managed_environments.id', 'managed_environments.name', 'managed_environments.slug', 'managed_environments.workspace_id']) ->all(); } private function applyRequestedTenantPrefilter(): void { - $requestedTenant = request()->query('tenant_id', request()->query('tenant')); + $requestedTenant = request()->query('managed_environment_id', request()->query('tenant')); if (! is_string($requestedTenant) && ! is_numeric($requestedTenant)) { return; @@ -490,7 +490,7 @@ private function unfilteredInboxPayload(): array ); } - private function selectedTenant(): ?Tenant + private function selectedTenant(): ?ManagedEnvironment { if (! is_int($this->tenantId)) { return null; diff --git a/apps/platform/app/Filament/Pages/InventoryCoverage.php b/apps/platform/app/Filament/Pages/InventoryCoverage.php index ba1f8a7e..74b9dbfb 100644 --- a/apps/platform/app/Filament/Pages/InventoryCoverage.php +++ b/apps/platform/app/Filament/Pages/InventoryCoverage.php @@ -9,7 +9,7 @@ use App\Filament\Resources\InventoryItemResource; use App\Filament\Widgets\Inventory\InventoryKpiHeader; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -89,7 +89,7 @@ public static function canAccess(): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -509,7 +509,7 @@ public function basisRunSummary(): array $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $truth instanceof TenantCoverageTruth || ! $tenant instanceof Tenant) { + if (! $truth instanceof TenantCoverageTruth || ! $tenant instanceof ManagedEnvironment) { return []; } @@ -551,7 +551,7 @@ protected function coverageTruth(): ?TenantCoverageTruth $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -560,7 +560,7 @@ protected function coverageTruth(): ?TenantCoverageTruth return $this->cachedCoverageTruth; } - private function inventorySyncHistoryUrl(Tenant $tenant): string + private function inventorySyncHistoryUrl(ManagedEnvironment $tenant): string { return OperationRunLinks::index($tenant, operationType: OperationRunType::InventorySync->value); } diff --git a/apps/platform/app/Filament/Pages/Monitoring/AuditLog.php b/apps/platform/app/Filament/Pages/Monitoring/AuditLog.php index 4bf45cda..87195f97 100644 --- a/apps/platform/app/Filament/Pages/Monitoring/AuditLog.php +++ b/apps/platform/app/Filament/Pages/Monitoring/AuditLog.php @@ -6,7 +6,7 @@ use App\Models\AuditLog as AuditLogModel; use App\Models\SupportAccessGrant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\WorkspaceCapabilityResolver; @@ -72,7 +72,7 @@ class AuditLog extends Page implements HasTable 'invalidFallback' => 'discard_and_continue', ], [ - 'stateKey' => 'tenant_id', + 'stateKey' => 'managed_environment_id', 'stateClass' => 'contextual_prefilter', 'carrier' => 'session', 'queryRole' => 'durable_restorable', @@ -96,7 +96,7 @@ class AuditLog extends Page implements HasTable 'precedenceOrder' => ['query', 'session', 'default'], 'appliesOnInitialMountOnly' => true, 'activeStateBecomesAuthoritativeAfterMount' => true, - 'clearsOnTenantSwitch' => ['tenant_id', 'action', 'actor_label', 'resource_type'], + 'clearsOnTenantSwitch' => ['managed_environment_id', 'action', 'actor_label', 'resource_type'], 'invalidRequestedStateFallback' => 'clear_selection_and_continue', ], 'inspectContract' => [ @@ -132,7 +132,7 @@ class AuditLog extends Page implements HasTable protected string $view = 'filament.pages.monitoring.audit-log'; /** - * @var array|null + * @var array|null */ private ?array $authorizedTenants = null; @@ -281,7 +281,7 @@ public function table(Table $table): Table ->searchable() ->toggleable(), TextColumn::make('tenant.name') - ->label('Tenant') + ->label('ManagedEnvironment') ->formatStateUsing(fn (?string $state): string => $state ?: 'Workspace') ->toggleable(), TextColumn::make('recorded_at') @@ -290,8 +290,8 @@ public function table(Table $table): Table ->sortable(), ]) ->filters([ - SelectFilter::make('tenant_id') - ->label('Tenant') + SelectFilter::make('managed_environment_id') + ->label('ManagedEnvironment') ->options(fn (): array => $this->tenantFilterOptions()) ->default(fn (): ?string => $this->defaultTenantFilter()) ->searchable(), @@ -335,7 +335,7 @@ public function table(Table $table): Table } /** - * @return array + * @return array */ public function authorizedTenants(): array { @@ -351,9 +351,9 @@ public function authorizedTenants(): array } $tenants = collect($user->getTenants(Filament::getCurrentOrDefaultPanel())) - ->filter(static fn (Tenant $tenant): bool => (int) $tenant->workspace_id === (int) $workspaceId) - ->filter(static fn (Tenant $tenant): bool => $tenant->isActive()) - ->keyBy(fn (Tenant $tenant): int => (int) $tenant->getKey()) + ->filter(static fn (ManagedEnvironment $tenant): bool => (int) $tenant->workspace_id === (int) $workspaceId) + ->filter(static fn (ManagedEnvironment $tenant): bool => $tenant->isActive()) + ->keyBy(fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey()) ->all(); return $this->authorizedTenants = $tenants; @@ -389,7 +389,7 @@ private function auditBaseQuery(): Builder { $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); $authorizedTenantIds = array_map( - static fn (Tenant $tenant): int => (int) $tenant->getKey(), + static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $this->authorizedTenants(), ); @@ -397,10 +397,10 @@ private function auditBaseQuery(): Builder ->with(['tenant', 'workspace', 'operationRun']) ->forWorkspace((int) $workspaceId) ->where(function (Builder $query) use ($authorizedTenantIds): void { - $query->whereNull('tenant_id'); + $query->whereNull('managed_environment_id'); if ($authorizedTenantIds !== []) { - $query->orWhereIn('tenant_id', $authorizedTenantIds); + $query->orWhereIn('managed_environment_id', $authorizedTenantIds); } }) ->when($this->supportAccessOnly, function (Builder $query): void { @@ -552,9 +552,9 @@ private function matchesSelectedAuditFilters(AuditLogModel $record): bool $filters = $this->currentTableFiltersState(); - $tenantFilter = data_get($filters, 'tenant_id.value'); + $tenantFilter = data_get($filters, 'managed_environment_id.value'); - if (is_numeric($tenantFilter) && (int) $record->tenant_id !== (int) $tenantFilter) { + if (is_numeric($tenantFilter) && (int) $record->managed_environment_id !== (int) $tenantFilter) { return false; } @@ -608,7 +608,7 @@ private function matchesSelectedAuditSearch(AuditLogModel $record): bool private function tenantFilterOptions(): array { return collect($this->authorizedTenants()) - ->mapWithKeys(static fn (Tenant $tenant): array => [ + ->mapWithKeys(static fn (ManagedEnvironment $tenant): array => [ (string) $tenant->getKey() => $tenant->getFilamentName(), ]) ->all(); @@ -618,7 +618,7 @@ private function defaultTenantFilter(): ?string { $activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request()); - if (! $activeTenant instanceof Tenant) { + if (! $activeTenant instanceof ManagedEnvironment) { return null; } diff --git a/apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php b/apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php index 6b83efcc..e1adbc4a 100644 --- a/apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php +++ b/apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php @@ -6,7 +6,7 @@ use App\Filament\Resources\EvidenceSnapshotResource; use App\Models\EvidenceSnapshot; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Support\Badges\BadgeCatalog; @@ -46,7 +46,7 @@ class EvidenceOverview extends Page implements HasTable 'surfaceType' => 'simple_monitoring', 'stateFields' => [ [ - 'stateKey' => 'tenant_id', + 'stateKey' => 'managed_environment_id', 'stateClass' => 'contextual_prefilter', 'carrier' => 'query_param', 'queryRole' => 'durable_restorable', @@ -90,7 +90,7 @@ class EvidenceOverview extends Page implements HasTable 'precedenceOrder' => ['query', 'session', 'default'], 'appliesOnInitialMountOnly' => true, 'activeStateBecomesAuthoritativeAfterMount' => true, - 'clearsOnTenantSwitch' => ['tenant_id'], + 'clearsOnTenantSwitch' => ['managed_environment_id'], 'invalidRequestedStateFallback' => 'discard_and_continue', ], 'inspectContract' => [ @@ -101,7 +101,7 @@ class EvidenceOverview extends Page implements HasTable 'shareable' => false, 'invalidSelectionFallback' => 'discard_and_continue', ], - 'shareableStateKeys' => ['tenant_id', 'search'], + 'shareableStateKeys' => ['managed_environment_id', 'search'], 'localOnlyStateKeys' => [], ]; @@ -123,7 +123,7 @@ class EvidenceOverview extends Page implements HasTable public array $rows = []; /** - * @var array|null + * @var array|null */ private ?array $accessibleTenants = null; @@ -181,14 +181,14 @@ public function table(Table $table): Table return $this->paginateRows($rows, $page, $recordsPerPage); }) ->filters([ - SelectFilter::make('tenant_id') - ->label('Tenant') + SelectFilter::make('managed_environment_id') + ->label('ManagedEnvironment') ->options(fn (): array => $this->tenantFilterOptions()) ->searchable(), ]) ->columns([ TextColumn::make('tenant_name') - ->label('Tenant') + ->label('ManagedEnvironment') ->sortable(), TextColumn::make('artifact_truth_label') ->label('Outcome') @@ -240,7 +240,7 @@ protected function getHeaderActions(): array public function clearOverviewFilters(): void { $this->tableFilters = [ - 'tenant_id' => ['value' => null], + 'managed_environment_id' => ['value' => null], ]; $this->tableDeferredFilters = $this->tableFilters; $this->tableSearch = ''; @@ -284,7 +284,7 @@ private function authorizeWorkspaceAccess(): void } /** - * @return array + * @return array */ private function accessibleTenants(): array { @@ -301,10 +301,10 @@ private function accessibleTenants(): array $workspaceId = $this->workspaceId(); return $this->accessibleTenants = $user->tenants() - ->where('tenants.workspace_id', $workspaceId) - ->orderBy('tenants.name') + ->where('managed_environments.workspace_id', $workspaceId) + ->orderBy('managed_environments.name') ->get() - ->filter(fn (Tenant $tenant): bool => (int) $tenant->workspace_id === $workspaceId && $user->can('evidence.view', $tenant)) + ->filter(fn (ManagedEnvironment $tenant): bool => (int) $tenant->workspace_id === $workspaceId && $user->can('evidence.view', $tenant)) ->values() ->all(); } @@ -315,7 +315,7 @@ private function accessibleTenants(): array private function tenantFilterOptions(): array { return collect($this->accessibleTenants()) - ->mapWithKeys(static fn (Tenant $tenant): array => [ + ->mapWithKeys(static fn (ManagedEnvironment $tenant): array => [ (string) $tenant->getKey() => $tenant->name, ]) ->all(); @@ -328,11 +328,11 @@ private function tenantFilterOptions(): array private function rowsForState(array $filters = [], ?string $search = null): Collection { $rows = $this->baseRows(); - $tenantFilter = $this->normalizeTenantFilter($filters['tenant_id']['value'] ?? data_get($this->tableFilters, 'tenant_id.value')); + $tenantFilter = $this->normalizeTenantFilter($filters['managed_environment_id']['value'] ?? data_get($this->tableFilters, 'managed_environment_id.value')); $normalizedSearch = Str::lower(trim((string) ($search ?? $this->tableSearch))); if ($tenantFilter !== null) { - $rows = $rows->where('tenant_id', $tenantFilter); + $rows = $rows->where('managed_environment_id', $tenantFilter); } if ($normalizedSearch === '') { @@ -375,7 +375,7 @@ private function latestAccessibleSnapshots(): Collection } $tenantIds = collect($this->accessibleTenants()) - ->map(static fn (Tenant $tenant): int => (int) $tenant->getKey()) + ->map(static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey()) ->all(); $query = EvidenceSnapshot::query() @@ -387,10 +387,10 @@ private function latestAccessibleSnapshots(): Collection if ($tenantIds === []) { $query->whereRaw('1 = 0'); } else { - $query->whereIn('tenant_id', $tenantIds); + $query->whereIn('managed_environment_id', $tenantIds); } - return $this->cachedSnapshots = $query->get()->unique('tenant_id')->values(); + return $this->cachedSnapshots = $query->get()->unique('managed_environment_id')->values(); } /** @@ -401,13 +401,13 @@ private function currentReviewTenantIds(Collection $snapshots): array { return TenantReview::query() ->where('workspace_id', $this->workspaceId()) - ->whereIn('tenant_id', $snapshots->pluck('tenant_id')->map(static fn (mixed $tenantId): int => (int) $tenantId)->all()) + ->whereIn('managed_environment_id', $snapshots->pluck('managed_environment_id')->map(static fn (mixed $tenantId): int => (int) $tenantId)->all()) ->whereIn('status', [ TenantReviewStatus::Draft->value, TenantReviewStatus::Ready->value, TenantReviewStatus::Published->value, ]) - ->pluck('tenant_id') + ->pluck('managed_environment_id') ->mapWithKeys(static fn (mixed $tenantId): array => [(int) $tenantId => true]) ->all(); } @@ -420,7 +420,7 @@ private function rowForSnapshot(EvidenceSnapshot $snapshot, array $currentReview { $truth = $this->snapshotTruth($snapshot); $outcome = $this->snapshotOutcome($snapshot); - $tenantId = (int) $snapshot->tenant_id; + $tenantId = (int) $snapshot->managed_environment_id; $hasCurrentReview = $currentReviewTenantIds[$tenantId] ?? false; $nextStep = ! $hasCurrentReview && $truth->contentState === 'trusted' && $truth->freshnessState === 'current' ? 'Create a current review from this evidence snapshot' @@ -428,7 +428,7 @@ private function rowForSnapshot(EvidenceSnapshot $snapshot, array $currentReview return [ 'tenant_name' => $snapshot->tenant?->name ?? 'Unknown tenant', - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'snapshot_id' => (int) $snapshot->getKey(), 'generated_at' => $snapshot->generated_at?->toDateTimeString(), 'artifact_truth_label' => $outcome->primaryLabel, @@ -495,18 +495,18 @@ private function seedTableStateFromQuery(): void $this->tableSearch = trim((string) request()->query('search', '')); } - if (! array_key_exists('tenant_id', $query)) { + if (! array_key_exists('managed_environment_id', $query)) { return; } - $tenantFilter = $this->normalizeTenantFilter(request()->query('tenant_id')); + $tenantFilter = $this->normalizeTenantFilter(request()->query('managed_environment_id')); if ($tenantFilter === null) { return; } $this->tableFilters = [ - 'tenant_id' => ['value' => (string) $tenantFilter], + 'managed_environment_id' => ['value' => (string) $tenantFilter], ]; $this->tableDeferredFilters = $this->tableFilters; } @@ -519,7 +519,7 @@ private function normalizeTenantFilter(mixed $value): ?int $requestedTenantId = (int) $value; $allowedTenantIds = collect($this->accessibleTenants()) - ->map(static fn (Tenant $tenant): int => (int) $tenant->getKey()) + ->map(static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey()) ->all(); return in_array($requestedTenantId, $allowedTenantIds, true) @@ -529,7 +529,7 @@ private function normalizeTenantFilter(mixed $value): ?int private function hasActiveOverviewFilters(): bool { - return filled(data_get($this->tableFilters, 'tenant_id.value')) + return filled(data_get($this->tableFilters, 'managed_environment_id.value')) || trim((string) $this->tableSearch) !== ''; } diff --git a/apps/platform/app/Filament/Pages/Monitoring/FindingExceptionsQueue.php b/apps/platform/app/Filament/Pages/Monitoring/FindingExceptionsQueue.php index a5281933..68ab5676 100644 --- a/apps/platform/app/Filament/Pages/Monitoring/FindingExceptionsQueue.php +++ b/apps/platform/app/Filament/Pages/Monitoring/FindingExceptionsQueue.php @@ -7,7 +7,7 @@ use App\Filament\Resources\FindingExceptionResource; use App\Filament\Resources\FindingResource; use App\Models\FindingException; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\WorkspaceCapabilityResolver; @@ -101,7 +101,7 @@ class FindingExceptionsQueue extends Page implements HasTable 'precedenceOrder' => ['query', 'session', 'default'], 'appliesOnInitialMountOnly' => true, 'activeStateBecomesAuthoritativeAfterMount' => true, - 'clearsOnTenantSwitch' => ['tenant', 'tenant_id', 'status', 'current_validity_state'], + 'clearsOnTenantSwitch' => ['tenant', 'managed_environment_id', 'status', 'current_validity_state'], 'invalidRequestedStateFallback' => 'clear_selection_and_continue', ], 'inspectContract' => [ @@ -133,7 +133,7 @@ class FindingExceptionsQueue extends Page implements HasTable protected string $view = 'filament.pages.monitoring.finding-exceptions-queue'; /** - * @var array|null + * @var array|null */ private ?array $authorizedTenants = null; @@ -224,7 +224,7 @@ protected function getHeaderActions(): array ->color('gray') ->visible(fn (): bool => $this->hasActiveQueueFilters()) ->action(function (): void { - $this->removeTableFilter('tenant_id'); + $this->removeTableFilter('managed_environment_id'); $this->removeTableFilter('status'); $this->removeTableFilter('current_validity_state'); $this->selectedFindingExceptionId = null; @@ -235,11 +235,11 @@ protected function getHeaderActions(): array ->label('View tenant register') ->icon('heroicon-o-arrow-top-right-on-square') ->color('gray') - ->visible(fn (): bool => $this->filteredTenant() instanceof Tenant) + ->visible(fn (): bool => $this->filteredTenant() instanceof ManagedEnvironment) ->url(function (): ?string { $tenant = $this->filteredTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -383,7 +383,7 @@ public function table(Table $table): Table ->icon(BadgeRenderer::icon(BadgeDomain::FindingRiskGovernanceValidity)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::FindingRiskGovernanceValidity)), TextColumn::make('tenant.name') - ->label('Tenant') + ->label('ManagedEnvironment') ->searchable(), TextColumn::make('finding_summary') ->label('Finding') @@ -416,8 +416,8 @@ public function table(Table $table): Table ->sortable(), ]) ->filters([ - SelectFilter::make('tenant_id') - ->label('Tenant') + SelectFilter::make('managed_environment_id') + ->label('ManagedEnvironment') ->options(fn (): array => $this->tenantFilterOptions()) ->searchable(), SelectFilter::make('status') @@ -443,7 +443,7 @@ public function table(Table $table): Table ->icon('heroicon-o-x-mark') ->color('gray') ->action(function (): void { - $this->removeTableFilter('tenant_id'); + $this->removeTableFilter('managed_environment_id'); $this->removeTableFilter('status'); $this->removeTableFilter('current_validity_state'); $this->selectedFindingExceptionId = null; @@ -515,7 +515,7 @@ public function clearSelectedException(): void } /** - * @return array + * @return array */ public function authorizedTenants(): array { @@ -536,12 +536,12 @@ public function authorizedTenants(): array } $tenants = $user->tenants() - ->where('tenants.workspace_id', $workspaceId) - ->orderBy('tenants.name') + ->where('managed_environments.workspace_id', $workspaceId) + ->orderBy('managed_environments.name') ->get(); return $this->authorizedTenants = $tenants - ->filter(fn (Tenant $tenant): bool => (int) $tenant->workspace_id === $workspaceId) + ->filter(fn (ManagedEnvironment $tenant): bool => (int) $tenant->workspace_id === $workspaceId) ->values() ->all(); } @@ -550,7 +550,7 @@ private function queueBaseQuery(): Builder { $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); $tenantIds = array_values(array_map( - static fn (Tenant $tenant): int => (int) $tenant->getKey(), + static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $this->authorizedTenants(), )); @@ -565,7 +565,7 @@ private function queueBaseQuery(): Builder 'evidenceReferences', ]) ->where('workspace_id', (int) $workspaceId) - ->whereIn('tenant_id', $tenantIds === [] ? [-1] : $tenantIds); + ->whereIn('managed_environment_id', $tenantIds === [] ? [-1] : $tenantIds); } /** @@ -574,7 +574,7 @@ private function queueBaseQuery(): Builder private function tenantFilterOptions(): array { return Collection::make($this->authorizedTenants()) - ->mapWithKeys(static fn (Tenant $tenant): array => [ + ->mapWithKeys(static fn (ManagedEnvironment $tenant): array => [ (string) $tenant->getKey() => $tenant->name, ]) ->all(); @@ -593,14 +593,14 @@ private function applyRequestedTenantPrefilter(): void continue; } - $this->tableFilters['tenant_id']['value'] = (string) $tenant->getKey(); - $this->tableDeferredFilters['tenant_id']['value'] = (string) $tenant->getKey(); + $this->tableFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); + $this->tableDeferredFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); return; } } - private function filteredTenant(): ?Tenant + private function filteredTenant(): ?ManagedEnvironment { $tenantId = $this->currentTenantFilterId(); @@ -741,9 +741,9 @@ private function matchesSelectedFindingExceptionFilters(FindingException $record { $filters = $this->currentQueueFiltersState(); - $tenantFilter = data_get($filters, 'tenant_id.value'); + $tenantFilter = data_get($filters, 'managed_environment_id.value'); - if (is_numeric($tenantFilter) && (int) $record->tenant_id !== (int) $tenantFilter) { + if (is_numeric($tenantFilter) && (int) $record->managed_environment_id !== (int) $tenantFilter) { return false; } diff --git a/apps/platform/app/Filament/Pages/Monitoring/Operations.php b/apps/platform/app/Filament/Pages/Monitoring/Operations.php index 990351d1..190d2842 100644 --- a/apps/platform/app/Filament/Pages/Monitoring/Operations.php +++ b/apps/platform/app/Filament/Pages/Monitoring/Operations.php @@ -7,7 +7,7 @@ use App\Filament\Resources\OperationRunResource; use App\Filament\Widgets\Operations\OperationsKpiHeader; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Filament\CanonicalAdminTenantFilterState; use App\Support\Navigation\CanonicalNavigationContext; use App\Support\OperateHub\OperateHubShell; @@ -44,7 +44,7 @@ class Operations extends Page implements HasForms, HasTable 'surfaceType' => 'simple_monitoring', 'stateFields' => [ [ - 'stateKey' => 'tenant_id', + 'stateKey' => 'managed_environment_id', 'stateClass' => 'contextual_prefilter', 'carrier' => 'query_param', 'queryRole' => 'durable_restorable', @@ -98,7 +98,7 @@ class Operations extends Page implements HasForms, HasTable 'precedenceOrder' => ['query', 'session', 'default'], 'appliesOnInitialMountOnly' => true, 'activeStateBecomesAuthoritativeAfterMount' => true, - 'clearsOnTenantSwitch' => ['tenant_id', 'type', 'initiator_name'], + 'clearsOnTenantSwitch' => ['managed_environment_id', 'type', 'initiator_name'], 'invalidRequestedStateFallback' => 'discard_and_continue', ], 'inspectContract' => [ @@ -109,7 +109,7 @@ class Operations extends Page implements HasForms, HasTable 'shareable' => false, 'invalidSelectionFallback' => 'discard_and_continue', ], - 'shareableStateKeys' => ['tenant_id', 'tenant_scope', 'problemClass', 'activeTab'], + 'shareableStateKeys' => ['managed_environment_id', 'tenant_scope', 'problemClass', 'activeTab'], 'localOnlyStateKeys' => [], ]; @@ -199,7 +199,7 @@ protected function getHeaderActions(): array ->icon('heroicon-o-arrow-left') ->color('gray') ->url($navigationContext->backLinkUrl); - } elseif ($activeTenant instanceof Tenant) { + } elseif ($activeTenant instanceof ManagedEnvironment) { $actions[] = Action::make('operate_hub_back_to_tenant_operations') ->label('Back to '.$activeTenant->name) ->icon('heroicon-o-arrow-left') @@ -207,7 +207,7 @@ protected function getHeaderActions(): array ->url(\App\Filament\Pages\TenantDashboard::getUrl(panel: 'tenant', tenant: $activeTenant)); } - if ($activeTenant instanceof Tenant) { + if ($activeTenant instanceof ManagedEnvironment) { $actions[] = Action::make('operate_hub_show_all_tenants') ->label('Show all tenants') ->color('gray') @@ -216,7 +216,7 @@ protected function getHeaderActions(): array app(WorkspaceContext::class)->clearLastTenantId(request()); - $this->removeTableFilter('tenant_id'); + $this->removeTableFilter('managed_environment_id'); $this->redirect('/admin/operations'); }); @@ -248,20 +248,20 @@ public function landingHierarchySummary(): array if ($navigationContext?->backLinkLabel !== null && $navigationContext->backLinkUrl !== null) { $returnLabel = $navigationContext->backLinkLabel; $returnBody = 'Return to the originating monitoring surface without competing with the current tab, filters, or row inspection flow.'; - } elseif ($activeTenant instanceof Tenant) { + } elseif ($activeTenant instanceof ManagedEnvironment) { $returnLabel = 'Back to '.$activeTenant->name; $returnBody = 'Return to the tenant dashboard when you need tenant-specific context outside this workspace monitoring landing.'; } return [ 'scope_label' => $operateHubShell->scopeLabel(request()), - 'scope_body' => $activeTenant instanceof Tenant + 'scope_body' => $activeTenant instanceof ManagedEnvironment ? 'The landing is currently narrowed to one tenant inside the active workspace.' : 'The landing is currently showing workspace-wide monitoring across all entitled tenants.', 'return_label' => $returnLabel, 'return_body' => $returnBody, - 'scope_reset_label' => $activeTenant instanceof Tenant ? 'Show all tenants' : null, - 'scope_reset_body' => $activeTenant instanceof Tenant + 'scope_reset_label' => $activeTenant instanceof ManagedEnvironment ? 'Show all tenants' : null, + 'scope_reset_body' => $activeTenant instanceof ManagedEnvironment ? 'Reset the landing back to workspace-wide monitoring when tenant-specific context is no longer needed.' : null, 'inspect_body' => 'Open a run from the table to enter the canonical monitoring detail viewer.', @@ -312,7 +312,7 @@ public function table(Table $table): Table ) ->when( $tenantFilter !== null, - fn (Builder $query): Builder => $query->where('tenant_id', $tenantFilter), + fn (Builder $query): Builder => $query->where('managed_environment_id', $tenantFilter), ); return $this->applyActiveTab($query); @@ -393,19 +393,19 @@ private function scopedSummaryQuery(): ?Builder ->where('workspace_id', (int) $workspaceId) ->when( $tenantFilter !== null, - fn (Builder $query): Builder => $query->where('tenant_id', $tenantFilter), + fn (Builder $query): Builder => $query->where('managed_environment_id', $tenantFilter), ); } private function applyRequestedDashboardPrefilter(): void { if (! $this->shouldForceWorkspaceWideTenantScope()) { - $requestedTenantId = $this->normalizeEntitledTenantFilter(request()->query('tenant_id')); + $requestedTenantId = $this->normalizeEntitledTenantFilter(request()->query('managed_environment_id')); if ($requestedTenantId !== null) { $tenantId = (string) $requestedTenantId; - $this->tableFilters['tenant_id']['value'] = $tenantId; - $this->tableDeferredFilters['tenant_id']['value'] = $tenantId; + $this->tableFilters['managed_environment_id']['value'] = $tenantId; + $this->tableDeferredFilters['managed_environment_id']['value'] = $tenantId; } } @@ -435,7 +435,7 @@ private function operationsUrl(array $overrides = []): string $this->navigationContext()?->toQuery() ?? [], [ 'tenant_scope' => $this->shouldForceWorkspaceWideTenantScope() ? 'all' : null, - 'tenant_id' => $this->shouldForceWorkspaceWideTenantScope() ? null : $this->currentTenantFilterId(), + 'managed_environment_id' => $this->shouldForceWorkspaceWideTenantScope() ? null : $this->currentTenantFilterId(), 'activeTab' => $this->activeTab !== 'all' ? $this->activeTab : null, 'problemClass' => in_array($this->activeTab, self::problemClassTabs(), true) ? $this->activeTab : null, ], @@ -485,9 +485,9 @@ private function authorizedTenantIds(): array } return collect($user->getTenants(Filament::getCurrentOrDefaultPanel())) - ->filter(static fn (Tenant $tenant): bool => (int) $tenant->workspace_id === $workspaceId) - ->filter(static fn (Tenant $tenant): bool => $tenant->isActive()) - ->map(static fn (Tenant $tenant): int => (int) $tenant->getKey()) + ->filter(static fn (ManagedEnvironment $tenant): bool => (int) $tenant->workspace_id === $workspaceId) + ->filter(static fn (ManagedEnvironment $tenant): bool => $tenant->isActive()) + ->map(static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey()) ->values() ->all(); } diff --git a/apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php b/apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php index ee56279b..f3ddd4c5 100644 --- a/apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php +++ b/apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php @@ -7,7 +7,7 @@ use App\Filament\Resources\OperationRunResource; use App\Models\OperationRun; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; use App\Services\Auth\CapabilityResolver; @@ -108,7 +108,7 @@ protected function getHeaderActions(): array $operateHubShell = app(OperateHubShell::class); $navigationContext = $this->navigationContext(); $activeTenant = $operateHubShell->activeEntitledTenant(request()); - $runTenantId = isset($this->run) ? (int) ($this->run->tenant_id ?? 0) : 0; + $runTenantId = isset($this->run) ? (int) ($this->run->managed_environment_id ?? 0) : 0; $actions = [ Action::make('operate_hub_scope_run_detail') @@ -122,7 +122,7 @@ protected function getHeaderActions(): array ->label($navigationContext->backLinkLabel) ->color('gray') ->url($navigationContext->backLinkUrl); - } elseif ($activeTenant instanceof Tenant && (int) $activeTenant->getKey() === $runTenantId) { + } elseif ($activeTenant instanceof ManagedEnvironment && (int) $activeTenant->getKey() === $runTenantId) { $actions[] = Action::make('operate_hub_back_to_tenant_run_detail') ->label('← Back to '.$activeTenant->name) ->color('gray') @@ -134,7 +134,7 @@ protected function getHeaderActions(): array ->url(fn (): string => OperationRunLinks::index()); } - if ($activeTenant instanceof Tenant) { + if ($activeTenant instanceof ManagedEnvironment) { $actions[] = Action::make('operate_hub_show_all_operations') ->label('Show all operations') ->color('gray') @@ -201,7 +201,7 @@ public function monitoringDetailSummary(): array $operateHubShell = app(OperateHubShell::class); $navigationContext = $this->navigationContext(); $activeTenant = $operateHubShell->activeEntitledTenant(request()); - $runTenantId = isset($this->run) ? (int) ($this->run->tenant_id ?? 0) : 0; + $runTenantId = isset($this->run) ? (int) ($this->run->managed_environment_id ?? 0) : 0; $navigationLabel = 'Back to Operations'; $navigationBody = 'Return to the operations landing when this review is complete.'; @@ -209,7 +209,7 @@ public function monitoringDetailSummary(): array if ($navigationContext?->backLinkLabel !== null && $navigationContext->backLinkUrl !== null) { $navigationLabel = $navigationContext->backLinkLabel; $navigationBody = 'Return to the originating surface while keeping refresh and follow-up work separate from navigation.'; - } elseif ($activeTenant instanceof Tenant && (int) $activeTenant->getKey() === $runTenantId) { + } elseif ($activeTenant instanceof ManagedEnvironment && (int) $activeTenant->getKey() === $runTenantId) { $navigationLabel = 'Back to '.$activeTenant->name; $navigationBody = 'Return to the active tenant dashboard, then widen back to the workspace view only when you need broader monitoring context.'; } @@ -391,7 +391,7 @@ private function auditOperationSupportDiagnosticsOpen(): void ); } - private function supportDiagnosticsTenant(): ?Tenant + private function supportDiagnosticsTenant(): ?ManagedEnvironment { if (! isset($this->run)) { return null; @@ -399,7 +399,7 @@ private function supportDiagnosticsTenant(): ?Tenant $tenant = $this->run->tenant; - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return $tenant; } @@ -417,12 +417,12 @@ private function resolveViewerActor(): User return $user; } - private function resolveRunTenantForCapability(string $capability): Tenant + private function resolveRunTenantForCapability(string $capability): ManagedEnvironment { $tenant = $this->supportDiagnosticsTenant(); $user = $this->resolveViewerActor(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -444,7 +444,7 @@ private function operationSupportRequestAttachmentSummary(): string $tenant = $this->supportDiagnosticsTenant(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return 'Only canonical redacted run context will be attached.'; } @@ -554,7 +554,7 @@ private function supportRequestNotificationBody(SupportRequest $supportRequest): /** * @param array $bundle */ - private function recordSupportDiagnosticsOpened(Tenant $tenant, array $bundle, User $user): void + private function recordSupportDiagnosticsOpened(ManagedEnvironment $tenant, array $bundle, User $user): void { if (! isset($this->run)) { return; @@ -729,11 +729,11 @@ public function canonicalContextBanner(): ?array $activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request()); $runTenant = $this->run->tenant; - if (! $runTenant instanceof Tenant) { + if (! $runTenant instanceof ManagedEnvironment) { return [ 'tone' => 'slate', 'title' => 'Workspace-level operation', - 'body' => $activeTenant instanceof Tenant + 'body' => $activeTenant instanceof ManagedEnvironment ? 'This canonical workspace view is not tied to the current tenant context ('.$activeTenant->name.').' : 'This canonical workspace view is not tied to any tenant.', ]; @@ -743,7 +743,7 @@ public function canonicalContextBanner(): ?array $tone = 'sky'; $title = null; - if ($activeTenant instanceof Tenant && ! $activeTenant->is($runTenant)) { + if ($activeTenant instanceof ManagedEnvironment && ! $activeTenant->is($runTenant)) { $title = 'Current tenant context differs from this operation'; array_unshift($messages, 'Current tenant context: '.$activeTenant->name.'.'); $messages[] = 'This canonical workspace view remains valid without switching tenant context.'; @@ -759,7 +759,7 @@ public function canonicalContextBanner(): ?array if ($referencedTenant->contextNote !== null) { $messages[] = $referencedTenant->contextNote; } - } elseif (! $activeTenant instanceof Tenant) { + } elseif (! $activeTenant instanceof ManagedEnvironment) { $title ??= 'Canonical workspace view'; $messages[] = 'No tenant context is currently selected.'; } @@ -925,7 +925,7 @@ private function canResumeCapture(): bool && $resolver->can($user, $workspace, Capabilities::WORKSPACE_BASELINES_MANAGE); } - private function relatedLinksTenant(): ?Tenant + private function relatedLinksTenant(): ?ManagedEnvironment { if (! isset($this->run)) { return null; @@ -934,7 +934,7 @@ private function relatedLinksTenant(): ?Tenant $user = auth()->user(); $tenant = $this->run->tenant; - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return null; } diff --git a/apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php b/apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php index d30b66cb..aac4c605 100644 --- a/apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php +++ b/apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php @@ -8,7 +8,7 @@ use App\Models\EvidenceSnapshot; use App\Models\FindingException; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Models\Workspace; @@ -74,6 +74,7 @@ public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration return ActionSurfaceDeclaration::forPage(ActionSurfaceProfile::RunLog, ActionSurfaceType::ReadOnlyRegistryReport) ->satisfy(ActionSurfaceSlot::ListHeader, 'Header actions provide a single Clear filters action for the customer review workspace.') ->satisfy(ActionSurfaceSlot::InspectAffordance, ActionSurfaceInspectAffordance::PrimaryLinkColumn->value) + ->withPrimaryLinkColumnReason('Only the dedicated review-open column should navigate away; the rest of the row stays comparative workspace context.') ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'The customer review workspace remains scan-first and does not expose bulk actions.') ->satisfy(ActionSurfaceSlot::ListEmptyState, 'The empty state keeps exactly one Clear filters CTA when filters are active.') ->exempt(ActionSurfaceSlot::DetailHeader, 'The dedicated open link column opens the latest published review detail instead of an inline canonical detail panel.'); @@ -94,7 +95,7 @@ public function getTitle(): string return __('localization.review.customer_review_workspace'); } - public static function tenantPrefilterUrl(Tenant $tenant): string + public static function tenantPrefilterUrl(ManagedEnvironment $tenant): string { $tenantIdentifier = filled($tenant->external_id) ? (string) $tenant->external_id @@ -106,7 +107,7 @@ public static function tenantPrefilterUrl(Tenant $tenant): string } /** - * @var array|null + * @var array|null */ private ?array $authorizedTenants = null; @@ -161,36 +162,36 @@ public function table(Table $table): Table ->width('9rem') ->extraHeaderAttributes(['class' => 'whitespace-normal']) ->badge() - ->getStateUsing(fn (Tenant $record): string => $this->governancePackageAvailabilityLabel($record)) - ->color(fn (Tenant $record): string => $this->governancePackageAvailabilityColor($record)) - ->tooltip(fn (Tenant $record): string => $this->governancePackageAvailability($record)['description']), + ->getStateUsing(fn (ManagedEnvironment $record): string => $this->governancePackageAvailabilityLabel($record)) + ->color(fn (ManagedEnvironment $record): string => $this->governancePackageAvailabilityColor($record)) + ->tooltip(fn (ManagedEnvironment $record): string => $this->governancePackageAvailability($record)['description']), TextColumn::make('latest_review') ->label(__('localization.review.status')) ->width('9rem') ->badge() - ->getStateUsing(fn (Tenant $record): string => $this->latestReviewStateLabel($record)) - ->color(fn (Tenant $record): string => $this->latestReviewStateColor($record)), + ->getStateUsing(fn (ManagedEnvironment $record): string => $this->latestReviewStateLabel($record)) + ->color(fn (ManagedEnvironment $record): string => $this->latestReviewStateColor($record)), TextColumn::make('evidence_proof_state') ->label(__('localization.review.evidence_status')) ->width('8rem') ->badge() - ->getStateUsing(fn (Tenant $record): string => $this->evidenceStatusLabel($record)) - ->color(fn (Tenant $record): string => $this->evidenceStatusColor($record)), + ->getStateUsing(fn (ManagedEnvironment $record): string => $this->evidenceStatusLabel($record)) + ->color(fn (ManagedEnvironment $record): string => $this->evidenceStatusColor($record)), TextColumn::make('recommended_next_action') ->label(__('localization.review.next_step')) ->width('10rem') ->extraHeaderAttributes(['class' => 'whitespace-normal']) - ->getStateUsing(fn (Tenant $record): string => $this->controlRecommendedNextAction($record)) + ->getStateUsing(fn (ManagedEnvironment $record): string => $this->controlRecommendedNextAction($record)) ->wrap(), TextColumn::make('open_review') ->label(__('localization.review.open')) ->width('8rem') ->getStateUsing(fn (): string => __('localization.review.open_review')) - ->url(fn (Tenant $record): ?string => $this->latestReviewUrl($record)) + ->url(fn (ManagedEnvironment $record): ?string => $this->latestReviewUrl($record)) ->color('primary'), ]) ->filters([ - SelectFilter::make('tenant_id') + SelectFilter::make('managed_environment_id') ->label(__('localization.review.tenant')) ->options(fn (): array => $this->tenantFilterOptions()) ->default(fn (): ?string => $this->defaultTenantFilter()) @@ -220,7 +221,7 @@ public function table(Table $table): Table } /** - * @return array + * @return array */ public function authorizedTenants(): array { @@ -296,7 +297,7 @@ private function workspaceQuery(): Builder $workspace = $this->workspace(); if (! $user instanceof User || ! $workspace instanceof Workspace) { - return Tenant::query()->whereRaw('1 = 0'); + return ManagedEnvironment::query()->whereRaw('1 = 0'); } return app(TenantReviewRegisterService::class)->customerWorkspaceTenantQuery($user, $workspace); @@ -308,7 +309,7 @@ private function workspaceQuery(): Builder private function tenantFilterOptions(): array { return collect($this->authorizedTenants()) - ->mapWithKeys(static fn (Tenant $tenant): array => [ + ->mapWithKeys(static fn (ManagedEnvironment $tenant): array => [ (string) $tenant->getKey() => $tenant->name, ]) ->all(); @@ -325,7 +326,7 @@ private function defaultTenantFilter(): ?string private function applyRequestedTenantPrefilter(): void { - $requestedTenant = request()->query('tenant', request()->query('tenant_id')); + $requestedTenant = request()->query('tenant', request()->query('managed_environment_id')); if (! is_string($requestedTenant) && ! is_numeric($requestedTenant)) { return; @@ -336,8 +337,8 @@ private function applyRequestedTenantPrefilter(): void continue; } - $this->tableFilters['tenant_id']['value'] = (string) $tenant->getKey(); - $this->tableDeferredFilters['tenant_id']['value'] = (string) $tenant->getKey(); + $this->tableFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); + $this->tableDeferredFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); return; } @@ -358,10 +359,10 @@ private function clearWorkspaceFilters(): void private function currentTenantFilterId(): ?int { - $tenantFilter = data_get($this->tableFilters, 'tenant_id.value'); + $tenantFilter = data_get($this->tableFilters, 'managed_environment_id.value'); if (! is_numeric($tenantFilter)) { - $tenantFilter = data_get(session()->get($this->getTableFiltersSessionKey(), []), 'tenant_id.value'); + $tenantFilter = data_get(session()->get($this->getTableFiltersSessionKey(), []), 'managed_environment_id.value'); } return is_numeric($tenantFilter) ? (int) $tenantFilter : null; @@ -376,14 +377,14 @@ private function workspace(): ?Workspace : null; } - private function latestPublishedReview(Tenant $tenant): ?TenantReview + private function latestPublishedReview(ManagedEnvironment $tenant): ?TenantReview { $review = $tenant->tenantReviews->first(); return $review instanceof TenantReview ? $review : null; } - private function latestReviewUrl(Tenant $tenant): ?string + private function latestReviewUrl(ManagedEnvironment $tenant): ?string { $review = $this->latestPublishedReview($tenant); @@ -406,12 +407,12 @@ private function latestReviewUrl(Tenant $tenant): ?string return $this->appendQuery(TenantReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant, 'tenant'), $query); } - private function latestPublishedAt(Tenant $tenant): ?\Illuminate\Support\Carbon + private function latestPublishedAt(ManagedEnvironment $tenant): ?\Illuminate\Support\Carbon { return $this->latestPublishedReview($tenant)?->published_at; } - private function reviewTruth(Tenant $tenant): ?ArtifactTruthEnvelope + private function reviewTruth(ManagedEnvironment $tenant): ?ArtifactTruthEnvelope { $review = $this->latestPublishedReview($tenant); @@ -420,7 +421,7 @@ private function reviewTruth(Tenant $tenant): ?ArtifactTruthEnvelope : null; } - private function reviewOutcome(Tenant $tenant): ?CompressedGovernanceOutcome + private function reviewOutcome(ManagedEnvironment $tenant): ?CompressedGovernanceOutcome { $presenter = app(ArtifactTruthPresenter::class); $review = $this->latestPublishedReview($tenant); @@ -434,7 +435,7 @@ private function reviewOutcome(Tenant $tenant): ?CompressedGovernanceOutcome ?? $presenter->compressedOutcomeFromEnvelope($truth, SurfaceCompressionContext::reviewRegister()); } - private function latestReviewStateLabel(Tenant $tenant): string + private function latestReviewStateLabel(ManagedEnvironment $tenant): string { $review = $this->latestPublishedReview($tenant); @@ -447,7 +448,7 @@ private function latestReviewStateLabel(Tenant $tenant): string : __('localization.review.ready_for_release'); } - private function latestReviewStateColor(Tenant $tenant): string + private function latestReviewStateColor(ManagedEnvironment $tenant): string { $review = $this->latestPublishedReview($tenant); @@ -466,17 +467,17 @@ private function latestReviewStateColor(Tenant $tenant): string : 'warning'; } - private function latestReviewStateIcon(Tenant $tenant): ?string + private function latestReviewStateIcon(ManagedEnvironment $tenant): ?string { return $this->reviewOutcome($tenant)?->primaryBadge->icon; } - private function latestReviewStateIconColor(Tenant $tenant): ?string + private function latestReviewStateIconColor(ManagedEnvironment $tenant): ?string { return $this->reviewOutcome($tenant)?->primaryBadge->iconColor; } - private function reviewOutcomeDescription(Tenant $tenant): ?string + private function reviewOutcomeDescription(ManagedEnvironment $tenant): ?string { $review = $this->latestPublishedReview($tenant); @@ -501,7 +502,7 @@ private function reviewOutcomeDescription(Tenant $tenant): ?string return trim($primaryReason.' '.__('localization.review.terminal_outcomes').': '.$findingOutcomeSummary.'.'); } - private function controlReadinessLabel(Tenant $tenant): string + private function controlReadinessLabel(ManagedEnvironment $tenant): string { $control = $this->primaryControlSummary($tenant); @@ -519,7 +520,7 @@ private function controlReadinessLabel(Tenant $tenant): string /** * @return array */ - private function governancePackageSummary(Tenant $tenant): array + private function governancePackageSummary(ManagedEnvironment $tenant): array { $review = $this->latestPublishedReview($tenant); @@ -536,7 +537,7 @@ private function governancePackageSummary(Tenant $tenant): array /** * @return array{state:string,label:string,description:string} */ - private function governancePackageAvailability(Tenant $tenant): array + private function governancePackageAvailability(ManagedEnvironment $tenant): array { $review = $this->latestPublishedReview($tenant); @@ -603,7 +604,7 @@ private function governancePackageAvailability(Tenant $tenant): array ]; } - private function governancePackageAvailabilityLabel(Tenant $tenant): string + private function governancePackageAvailabilityLabel(ManagedEnvironment $tenant): string { return match ($this->governancePackageAvailability($tenant)['state']) { 'available' => __('localization.review.available'), @@ -614,7 +615,7 @@ private function governancePackageAvailabilityLabel(Tenant $tenant): string }; } - private function governancePackageAvailabilityColor(Tenant $tenant): string + private function governancePackageAvailabilityColor(ManagedEnvironment $tenant): string { return match ($this->governancePackageAvailability($tenant)['state']) { 'available' => 'success', @@ -624,7 +625,7 @@ private function governancePackageAvailabilityColor(Tenant $tenant): string }; } - private function governancePackageTeaser(Tenant $tenant): string + private function governancePackageTeaser(ManagedEnvironment $tenant): string { $package = $this->governancePackageSummary($tenant); @@ -637,7 +638,7 @@ private function governancePackageTeaser(Tenant $tenant): string return $this->governancePackageAvailability($tenant)['description']; } - private function controlReadinessColor(Tenant $tenant): string + private function controlReadinessColor(ManagedEnvironment $tenant): string { return match ((string) ($this->primaryControlSummary($tenant)['readiness_bucket'] ?? 'unmapped')) { 'follow_up_required' => 'warning', @@ -647,7 +648,7 @@ private function controlReadinessColor(Tenant $tenant): string }; } - private function controlReadinessDescription(Tenant $tenant): string + private function controlReadinessDescription(ManagedEnvironment $tenant): string { $review = $this->latestPublishedReview($tenant); @@ -684,7 +685,7 @@ private function controlReadinessDescription(Tenant $tenant): string return trim($summary.($limitations !== null ? ' '.$limitations : '')); } - private function controlEvidenceBasisSummary(Tenant $tenant): string + private function controlEvidenceBasisSummary(ManagedEnvironment $tenant): string { $control = $this->primaryControlSummary($tenant); @@ -699,7 +700,7 @@ private function controlEvidenceBasisSummary(Tenant $tenant): string : __('localization.review.control_evidence_unavailable'); } - private function controlRecommendedNextAction(Tenant $tenant): string + private function controlRecommendedNextAction(ManagedEnvironment $tenant): string { if ($this->primaryControlSummary($tenant) === null) { return __('localization.review.workspace_next_step_control_mapping'); @@ -715,7 +716,7 @@ private function controlRecommendedNextAction(Tenant $tenant): string }; } - private function workspaceReviewNeedsAttention(Tenant $tenant): bool + private function workspaceReviewNeedsAttention(ManagedEnvironment $tenant): bool { $review = $this->latestPublishedReview($tenant); @@ -734,7 +735,7 @@ private function workspaceReviewNeedsAttention(Tenant $tenant): bool return $this->governancePackageAvailability($tenant)['state'] !== 'available'; } - private function evidenceStatusState(Tenant $tenant): string + private function evidenceStatusState(ManagedEnvironment $tenant): string { $review = $this->latestPublishedReview($tenant); @@ -779,7 +780,7 @@ private function evidenceStatusColorForState(string $state): string }; } - private function controlRecommendedNextActionDescription(Tenant $tenant): string + private function controlRecommendedNextActionDescription(ManagedEnvironment $tenant): string { $control = $this->primaryControlSummary($tenant); @@ -797,7 +798,7 @@ private function controlRecommendedNextActionDescription(Tenant $tenant): string /** * @return array|null */ - private function primaryControlSummary(Tenant $tenant): ?array + private function primaryControlSummary(ManagedEnvironment $tenant): ?array { $review = $this->latestPublishedReview($tenant); @@ -837,7 +838,7 @@ private function controlLimitationSummary(TenantReview $review): ?string : __('localization.review.control_limitations_summary', ['limitations' => implode(', ', $labels)]); } - private function findingSummary(Tenant $tenant): string + private function findingSummary(ManagedEnvironment $tenant): string { $review = $this->latestPublishedReview($tenant); @@ -864,7 +865,7 @@ private function findingSummary(Tenant $tenant): string ]); } - private function acceptedRiskSummary(Tenant $tenant): string + private function acceptedRiskSummary(ManagedEnvironment $tenant): string { $review = $this->latestPublishedReview($tenant); @@ -892,7 +893,7 @@ private function acceptedRiskSummary(Tenant $tenant): string : $countSummary.' '.$accountability; } - private function evidenceProofAvailability(Tenant $tenant): string + private function evidenceProofAvailability(ManagedEnvironment $tenant): string { $review = $this->latestPublishedReview($tenant); @@ -918,12 +919,12 @@ private function evidenceProofAvailability(Tenant $tenant): string return __('localization.review.evidence_proof_available'); } - private function evidenceStatusLabel(Tenant $tenant): string + private function evidenceStatusLabel(ManagedEnvironment $tenant): string { return $this->evidenceStatusLabelForState($this->evidenceStatusState($tenant)); } - private function evidenceStatusColor(Tenant $tenant): string + private function evidenceStatusColor(ManagedEnvironment $tenant): string { return $this->evidenceStatusColorForState($this->evidenceStatusState($tenant)); } @@ -960,7 +961,7 @@ private function currentTenantFilterInterpretationVersion(): ?string $tenant = $this->authorizedTenants()[$tenantId] ?? null; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -972,12 +973,12 @@ private function currentTenantFilterInterpretationVersion(): ?string ?->controlInterpretationVersion(); } - private function acceptedRiskAccountability(Tenant $tenant): ?string + private function acceptedRiskAccountability(ManagedEnvironment $tenant): ?string { $exception = FindingException::query() ->with(['owner', 'approver', 'currentDecision']) ->where('workspace_id', (int) $tenant->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->current() ->orderByRaw("case when current_validity_state in ('valid', 'expiring') then 0 else 1 end") ->latest('approved_at') diff --git a/apps/platform/app/Filament/Pages/Reviews/ReviewRegister.php b/apps/platform/app/Filament/Pages/Reviews/ReviewRegister.php index ef641a46..0a970bee 100644 --- a/apps/platform/app/Filament/Pages/Reviews/ReviewRegister.php +++ b/apps/platform/app/Filament/Pages/Reviews/ReviewRegister.php @@ -5,7 +5,7 @@ namespace App\Filament\Pages\Reviews; use App\Filament\Resources\TenantReviewResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Models\Workspace; @@ -61,7 +61,7 @@ class ReviewRegister extends Page implements HasTable protected string $view = 'filament.pages.reviews.review-register'; /** - * @var array|null + * @var array|null */ private ?array $authorizedTenants = null; @@ -114,7 +114,7 @@ public function table(Table $table): Table ->persistSortInSession() ->recordUrl(fn (TenantReview $record): string => TenantReviewResource::tenantScopedUrl('view', ['record' => $record], $record->tenant, 'tenant')) ->columns([ - TextColumn::make('tenant.name')->label('Tenant')->searchable(), + TextColumn::make('tenant.name')->label('ManagedEnvironment')->searchable(), TextColumn::make('status') ->badge() ->formatStateUsing(BadgeRenderer::label(BadgeDomain::TenantReviewStatus)) @@ -138,8 +138,8 @@ public function table(Table $table): Table ->wrap(), ]) ->filters([ - SelectFilter::make('tenant_id') - ->label('Tenant') + SelectFilter::make('managed_environment_id') + ->label('ManagedEnvironment') ->options(fn (): array => $this->tenantFilterOptions()) ->default(fn (): ?string => $this->defaultTenantFilter()) ->searchable(), @@ -210,7 +210,7 @@ public function table(Table $table): Table } /** - * @return array + * @return array */ public function authorizedTenants(): array { @@ -270,7 +270,7 @@ private function registerQuery(): Builder private function tenantFilterOptions(): array { return collect($this->authorizedTenants()) - ->mapWithKeys(static fn (Tenant $tenant): array => [ + ->mapWithKeys(static fn (ManagedEnvironment $tenant): array => [ (string) $tenant->getKey() => $tenant->name, ]) ->all(); @@ -298,8 +298,8 @@ private function applyRequestedTenantPrefilter(): void continue; } - $this->tableFilters['tenant_id']['value'] = (string) $tenant->getKey(); - $this->tableDeferredFilters['tenant_id']['value'] = (string) $tenant->getKey(); + $this->tableFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); + $this->tableDeferredFilters['managed_environment_id']['value'] = (string) $tenant->getKey(); return; } @@ -323,10 +323,10 @@ private function clearRegisterFilters(): void private function currentTenantFilterId(): ?int { - $tenantFilter = data_get($this->tableFilters, 'tenant_id.value'); + $tenantFilter = data_get($this->tableFilters, 'managed_environment_id.value'); if (! is_numeric($tenantFilter)) { - $tenantFilter = data_get(session()->get($this->getTableFiltersSessionKey(), []), 'tenant_id.value'); + $tenantFilter = data_get(session()->get($this->getTableFiltersSessionKey(), []), 'managed_environment_id.value'); } return is_numeric($tenantFilter) ? (int) $tenantFilter : null; diff --git a/apps/platform/app/Filament/Pages/Tenancy/RegisterTenant.php b/apps/platform/app/Filament/Pages/Tenancy/RegisterTenant.php index d09bd81e..dacba259 100644 --- a/apps/platform/app/Filament/Pages/Tenancy/RegisterTenant.php +++ b/apps/platform/app/Filament/Pages/Tenancy/RegisterTenant.php @@ -2,7 +2,7 @@ namespace App\Filament\Pages\Tenancy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceMembership; use App\Services\Auth\CapabilityResolver; @@ -43,7 +43,7 @@ public static function canView(): bool } } - $tenantIds = $user->tenants()->withTrashed()->pluck('tenants.id'); + $tenantIds = $user->tenants()->withTrashed()->pluck('managed_environments.id'); if ($tenantIds->isEmpty()) { return false; @@ -52,7 +52,7 @@ public static function canView(): bool /** @var CapabilityResolver $resolver */ $resolver = app(CapabilityResolver::class); - foreach (Tenant::query()->whereIn('id', $tenantIds)->cursor() as $tenant) { + foreach (ManagedEnvironment::query()->whereIn('id', $tenantIds)->cursor() as $tenant) { if ($resolver->can($user, $tenant, Capabilities::TENANT_MANAGE)) { return true; } @@ -77,8 +77,8 @@ public function form(Schema $schema): Schema ]) ->default('other') ->required(), - Forms\Components\TextInput::make('tenant_id') - ->label('Tenant ID (GUID)') + Forms\Components\TextInput::make('managed_environment_id') + ->label('ManagedEnvironment ID (GUID)') ->required() ->maxLength(255) ->unique(ignoreRecord: true), @@ -104,7 +104,7 @@ protected function handleRegistration(array $data): Model $data['workspace_id'] = $workspaceId; } - $tenant = Tenant::create($data); + $tenant = ManagedEnvironment::create($data); $user = auth()->user(); diff --git a/apps/platform/app/Filament/Pages/TenantDashboard.php b/apps/platform/app/Filament/Pages/TenantDashboard.php index 3cfd5b30..f7acdcba 100644 --- a/apps/platform/app/Filament/Pages/TenantDashboard.php +++ b/apps/platform/app/Filament/Pages/TenantDashboard.php @@ -9,7 +9,7 @@ use App\Filament\Widgets\Dashboard\TenantDashboardContextChips; use App\Filament\Widgets\Dashboard\TenantDashboardOverview; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; use App\Services\Auth\CapabilityResolver; @@ -62,7 +62,7 @@ public function getTitle(): string | Htmlable { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return __('localization.dashboard.tenant_title'); } @@ -99,6 +99,7 @@ public static function getUrl(array $parameters = [], bool $isAbsolute = true, ? public function getWidgets(): array { return [ + TenantTriageArrivalContinuity::class, TenantDashboardContextChips::class, DashboardKpis::class, TenantDashboardOverview::class, @@ -228,7 +229,7 @@ private function governanceInboxHeaderAction(): ?Action $tenant = Filament::getTenant(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User || ! $user->canAccessTenant($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User || ! $user->canAccessTenant($tenant)) { return null; } @@ -237,7 +238,7 @@ private function governanceInboxHeaderAction(): ?Action ->icon('heroicon-o-inbox-stack') ->color('primary') ->url(GovernanceInbox::getUrl(panel: 'admin').'?'.http_build_query([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ])); } @@ -285,7 +286,7 @@ private function dashboardSummary(): ?TenantDashboardSummary $tenant = Filament::getTenant(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return null; } @@ -459,7 +460,7 @@ private function auditTenantSupportDiagnosticsOpen(): void /** * @param array $bundle */ - private function recordSupportDiagnosticsOpened(Tenant $tenant, array $bundle, User $user): void + private function recordSupportDiagnosticsOpened(ManagedEnvironment $tenant, array $bundle, User $user): void { $auditKey = 'tenant:'.$tenant->getKey(); @@ -500,12 +501,12 @@ private function resolveDashboardActor(): User return $user; } - private function resolveCurrentTenantForCapability(string $capability): Tenant + private function resolveCurrentTenantForCapability(string $capability): ManagedEnvironment { $user = $this->resolveDashboardActor(); $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -527,7 +528,7 @@ private function tenantSupportRequestAttachmentSummary(): string $tenant = Filament::getTenant(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return 'Only canonical redacted tenant context will be attached.'; } diff --git a/apps/platform/app/Filament/Pages/TenantDiagnostics.php b/apps/platform/app/Filament/Pages/TenantDiagnostics.php index 1ce207ef..cc65794d 100644 --- a/apps/platform/app/Filament/Pages/TenantDiagnostics.php +++ b/apps/platform/app/Filament/Pages/TenantDiagnostics.php @@ -5,7 +5,7 @@ namespace App\Filament\Pages; use App\Filament\Concerns\ResolvesPanelTenantContext; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Services\Auth\TenantDiagnosticsService; use App\Services\Auth\TenantMembershipManager; @@ -32,7 +32,7 @@ public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration { return ActionSurfaceDeclaration::forPage(ActionSurfaceProfile::ListOnlyReadOnly) ->satisfy(ActionSurfaceSlot::ListHeader, 'Header exposes capability-gated tenant repair actions when inconsistent membership state is detected.') - ->exempt(ActionSurfaceSlot::InspectAffordance, 'Tenant diagnostics is already the singleton diagnostic surface for the active tenant.') + ->exempt(ActionSurfaceSlot::InspectAffordance, 'ManagedEnvironment diagnostics is already the singleton diagnostic surface for the active tenant.') ->exempt(ActionSurfaceSlot::ListRowMoreMenu, 'The diagnostics page does not render row-level secondary actions.') ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'The diagnostics page does not expose bulk actions.') ->exempt(ActionSurfaceSlot::ListEmptyState, 'Diagnostics content is always rendered instead of a list-style empty state.'); @@ -47,8 +47,8 @@ public function mount(): void $tenant = static::resolveTenantContextForCurrentPanelOrFail(); $tenantId = (int) $tenant->getKey(); - $this->missingOwner = ! TenantMembership::query() - ->where('tenant_id', $tenantId) + $this->missingOwner = ! ManagedEnvironmentMembership::query() + ->where('managed_environment_id', $tenantId) ->where('role', 'owner') ->exists(); diff --git a/apps/platform/app/Filament/Pages/TenantRequiredPermissions.php b/apps/platform/app/Filament/Pages/TenantRequiredPermissions.php index 5b522a51..97732ae4 100644 --- a/apps/platform/app/Filament/Pages/TenantRequiredPermissions.php +++ b/apps/platform/app/Filament/Pages/TenantRequiredPermissions.php @@ -6,7 +6,7 @@ use App\Filament\Resources\ProviderConnectionResource; use App\Filament\Resources\TenantResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceMembership; use App\Services\Intune\TenantRequiredPermissionsViewModelBuilder; @@ -69,16 +69,16 @@ public static function canAccess(): bool return static::hasScopedTenantAccess(static::resolveScopedTenant()); } - public function currentTenant(): ?Tenant + public function currentTenant(): ?ManagedEnvironment { return $this->trustedScopedTenant(); } - public function mount(Tenant|string|null $tenant = null): void + public function mount(ManagedEnvironment|string|null $tenant = null): void { $tenant = static::resolveScopedTenant($tenant); - if (! $tenant instanceof Tenant || ! static::hasScopedTenantAccess($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! static::hasScopedTenantAccess($tenant)) { abort(404); } @@ -206,7 +206,7 @@ public function reRunVerificationUrl(): string { $tenant = $this->trustedScopedTenant(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return TenantResource::getUrl('view', ['record' => $tenant]); } @@ -217,53 +217,53 @@ public function manageProviderConnectionUrl(): ?string { $tenant = $this->trustedScopedTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } return ProviderConnectionResource::getUrl('index', ['tenant' => $tenant], panel: 'admin'); } - protected static function resolveScopedTenant(Tenant|string|null $tenant = null): ?Tenant + protected static function resolveScopedTenant(ManagedEnvironment|string|null $tenant = null): ?ManagedEnvironment { - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return $tenant; } if (is_string($tenant) && $tenant !== '') { - return Tenant::query() - ->where('external_id', $tenant) + return ManagedEnvironment::query() + ->where('slug', $tenant) ->first(); } $routeTenant = request()->route('tenant'); - if ($routeTenant instanceof Tenant) { + if ($routeTenant instanceof ManagedEnvironment) { return $routeTenant; } if (is_string($routeTenant) && $routeTenant !== '') { - return Tenant::query() - ->where('external_id', $routeTenant) + return ManagedEnvironment::query() + ->where('slug', $routeTenant) ->first(); } $queryTenant = request()->query('tenant'); if (is_string($queryTenant) && $queryTenant !== '') { - return Tenant::query() - ->where('external_id', $queryTenant) + return ManagedEnvironment::query() + ->where('slug', $queryTenant) ->first(); } return null; } - private static function hasScopedTenantAccess(?Tenant $tenant): bool + private static function hasScopedTenantAccess(?ManagedEnvironment $tenant): bool { $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -285,7 +285,7 @@ private static function hasScopedTenantAccess(?Tenant $tenant): bool return $user->canAccessTenant($tenant); } - private function trustedScopedTenant(): ?Tenant + private function trustedScopedTenant(): ?ManagedEnvironment { $user = auth()->user(); @@ -303,7 +303,7 @@ private function trustedScopedTenant(): ?Tenant $routeTenant = static::resolveScopedTenant(); - if ($routeTenant instanceof Tenant) { + if ($routeTenant instanceof ManagedEnvironment) { try { return $workspaceContext->ensureTenantAccessibleInCurrentWorkspace($routeTenant, $user, request()); } catch (NotFoundHttpException) { @@ -315,9 +315,9 @@ private function trustedScopedTenant(): ?Tenant return null; } - $tenant = Tenant::query()->withTrashed()->whereKey($this->scopedTenantId)->first(); + $tenant = ManagedEnvironment::query()->withTrashed()->whereKey($this->scopedTenantId)->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -350,7 +350,7 @@ private function viewModelForState(array $state): array { $tenant = $this->trustedScopedTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } diff --git a/apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php b/apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php index dabd623c..081f3871 100644 --- a/apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php +++ b/apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php @@ -16,8 +16,8 @@ use App\Jobs\ProviderInventorySyncJob; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\VerificationCheckAcknowledgement; @@ -133,7 +133,7 @@ protected function getLayoutData(): array public Workspace $workspace; - public ?Tenant $managedTenant = null; + public ?ManagedEnvironment $managedTenant = null; #[Locked] public ?int $managedTenantId = null; @@ -190,7 +190,7 @@ protected function getHeaderActions(): array $actions[] = Action::make('view_linked_tenant') ->label($this->linkedTenantActionLabel()) ->color('gray') - ->url($tenant instanceof Tenant ? TenantResource::getUrl('view', ['record' => $tenant]) : null); + ->url($tenant instanceof ManagedEnvironment ? TenantResource::getUrl('view', ['record' => $tenant]) : null); } if ($this->canResumeDraft($draft)) { @@ -224,7 +224,7 @@ private function canViewLinkedTenant(): bool $user = auth()->user(); $tenant = $this->currentManagedTenantRecord(); - if (! $user instanceof User || ! $tenant instanceof Tenant) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment) { return false; } @@ -245,7 +245,7 @@ private function linkedTenantActionLabel(): string { $tenant = $this->currentManagedTenantRecord(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return 'View tenant'; } @@ -325,10 +325,10 @@ public function content(Schema $schema): Schema Step::make('Identify managed tenant') ->description('Create or resume a managed tenant in this workspace.') ->schema([ - Section::make('Tenant') + Section::make('ManagedEnvironment') ->schema([ TextInput::make('entra_tenant_id') - ->label('Tenant ID (GUID)') + ->label('ManagedEnvironment ID (GUID)') ->required() ->placeholder('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx') ->rules(['uuid']) @@ -373,7 +373,7 @@ public function content(Schema $schema): Schema ]); } catch (NotFoundHttpException) { Notification::make() - ->title('Tenant not available') + ->title('ManagedEnvironment not available') ->body('This tenant cannot be onboarded in this workspace.') ->danger() ->send(); @@ -475,7 +475,7 @@ public function content(Schema $schema): Schema ->visible(fn (Get $get): bool => $get('connection_mode') === 'new'), TextInput::make('new_connection.target_scope_id') ->label('Target scope ID') - ->default(fn (): string => $this->currentManagedTenantRecord()?->tenant_id ?? '') + ->default(fn (): string => $this->currentManagedTenantRecord()?->managed_environment_id ?? '') ->disabled() ->dehydrated(false) ->visible(fn (Get $get): bool => $get('connection_mode') === 'new') @@ -518,7 +518,7 @@ public function content(Schema $schema): Schema ]), ]) ->afterValidation(function (): void { - if (! $this->managedTenant instanceof Tenant) { + if (! $this->managedTenant instanceof ManagedEnvironment) { throw new Halt; } @@ -567,7 +567,7 @@ public function content(Schema $schema): Schema SchemaActions::make([ Action::make('wizardStartVerification') ->label('Start verification') - ->visible(fn (): bool => $this->managedTenant instanceof Tenant && ! $this->verificationRunIsActive()) + ->visible(fn (): bool => $this->managedTenant instanceof ManagedEnvironment && ! $this->verificationRunIsActive()) ->disabled(fn (): bool => ! $this->currentUserCan(Capabilities::WORKSPACE_MANAGED_TENANT_ONBOARD_VERIFICATION_START)) ->tooltip(fn (): ?string => $this->currentUserCan(Capabilities::WORKSPACE_MANAGED_TENANT_ONBOARD_VERIFICATION_START) ? null @@ -583,7 +583,7 @@ public function content(Schema $schema): Schema ->default(null) ->view('filament.forms.components.managed-tenant-onboarding-verification-report') ->viewData(fn (): array => $this->verificationReportViewData()) - ->visible(fn (): bool => $this->managedTenant instanceof Tenant), + ->visible(fn (): bool => $this->managedTenant instanceof ManagedEnvironment), ]), ]) ->beforeValidation(function (): void { @@ -612,7 +612,7 @@ public function content(Schema $schema): Schema SchemaActions::make([ Action::make('wizardStartBootstrap') ->label('Start bootstrap') - ->visible(fn (): bool => $this->managedTenant instanceof Tenant) + ->visible(fn (): bool => $this->managedTenant instanceof ManagedEnvironment) ->disabled(fn (): bool => ! $this->canStartAnyBootstrap()) ->tooltip(fn (): ?string => $this->canStartAnyBootstrap() ? null @@ -646,7 +646,7 @@ public function content(Schema $schema): Schema ->compact() ->columns(2) ->schema([ - Text::make('Tenant') + Text::make('ManagedEnvironment') ->color('gray'), Text::make(fn (): string => $this->completionSummaryTenantLine()) ->weight(FontWeight::SemiBold), @@ -683,7 +683,7 @@ public function content(Schema $schema): Schema ->info() ->footer([ UnorderedList::make([ - 'Tenant status will be set to Active.', + 'ManagedEnvironment status will be set to Active.', 'Backup, inventory, and compliance operations become available.', 'The provider connection will be used for provider API calls.', ]), @@ -705,7 +705,7 @@ public function content(Schema $schema): Schema ->color('success') ->requiresConfirmation() ->modalHeading('Complete onboarding') - ->modalDescription(fn (): string => $this->managedTenant instanceof Tenant + ->modalDescription(fn (): string => $this->managedTenant instanceof ManagedEnvironment ? sprintf('Are you sure you want to complete onboarding for "%s"? This will make the tenant operational.', $this->managedTenant->name) : 'Are you sure you want to complete onboarding for this tenant?') ->modalSubmitActionLabel('Yes, complete onboarding') @@ -758,7 +758,7 @@ private function loadOnboardingDraft(User $user, TenantOnboardingSession|int|str $tenant = $draft->tenant; - if ($tenant instanceof Tenant && (int) $tenant->workspace_id === (int) $this->workspace->getKey()) { + if ($tenant instanceof ManagedEnvironment && (int) $tenant->workspace_id === (int) $this->workspace->getKey()) { $this->setManagedTenant($tenant); } @@ -974,7 +974,7 @@ private function resumeContextSchema(): array ->collapsed() ->columns(2) ->schema([ - Text::make('Tenant') + Text::make('ManagedEnvironment') ->color('gray'), Text::make(fn () => $this->draftTitle($this->currentOnboardingSessionRecord() ?? $draft)) ->weight(FontWeight::SemiBold), @@ -1225,7 +1225,7 @@ private function onboardingReadinessPayload(TenantOnboardingSession $draft): arr ? $snapshot['last_completed_checkpoint'] : null; - $tenant = $draft->tenant instanceof Tenant ? $draft->tenant : null; + $tenant = $draft->tenant instanceof ManagedEnvironment ? $draft->tenant : null; $providerConnection = $this->readinessProviderConnection($draft); $selectedProviderConnectionId = $providerConnection instanceof ProviderConnection ? (int) $providerConnection->getKey() @@ -1240,7 +1240,7 @@ private function onboardingReadinessPayload(TenantOnboardingSession $draft): arr $verificationMatchesSelectedConnection = $verificationRun instanceof OperationRun ? $this->readinessRunMatchesSelectedConnection($verificationRun, $selectedProviderConnectionId) : null; - $permissions = $tenant instanceof Tenant ? $this->readinessPermissionOverview($tenant) : null; + $permissions = $tenant instanceof ManagedEnvironment ? $this->readinessPermissionOverview($tenant) : null; $verificationReport = $verificationRun instanceof OperationRun ? VerificationReportViewer::report($verificationRun) : null; $verificationReport = is_array($verificationReport) ? $verificationReport : null; $verificationPrimaryReasonCode = $verificationReport !== null @@ -1300,7 +1300,7 @@ private function onboardingReadinessPayload(TenantOnboardingSession $draft): arr ? $this->readinessVerificationOverall($verificationRun, $verificationReport) : null, ], - 'verification_assist' => $tenant instanceof Tenant && $verificationReport !== null + 'verification_assist' => $tenant instanceof ManagedEnvironment && $verificationReport !== null ? app(VerificationAssistViewModelBuilder::class)->visibility($tenant, $verificationReport) : $this->hiddenVerificationAssistVisibility(), 'permissions' => $permissions, @@ -1443,14 +1443,14 @@ private function readinessProviderConnection(TenantOnboardingSession $draft): ?P $state['provider_connection_id'] ?? $state['selected_provider_connection_id'] ?? null, ); - if ($providerConnectionId === null || $draft->tenant_id === null) { + if ($providerConnectionId === null || $draft->managed_environment_id === null) { return null; } return ProviderConnection::query() ->whereKey($providerConnectionId) ->where('workspace_id', (int) $draft->workspace_id) - ->where('tenant_id', (int) $draft->tenant_id) + ->where('managed_environment_id', (int) $draft->managed_environment_id) ->first(); } @@ -1488,7 +1488,7 @@ private function readinessProviderSummary(?ProviderConnection $connection): ?arr /** * @return array{overall: string|null, counts: array, freshness: array{last_refreshed_at: string|null, is_stale: bool}, missing_permissions: array{application: list, delegated: list}, required_permissions_url: string|null} */ - private function readinessPermissionOverview(Tenant $tenant): array + private function readinessPermissionOverview(ManagedEnvironment $tenant): array { $viewModel = app(TenantRequiredPermissionsViewModelBuilder::class)->build($tenant, [ 'status' => 'all', @@ -1608,7 +1608,7 @@ private function readinessSummaryText( bool $verificationMismatch, ): string { if (! $this->readinessDraftHasTenantIdentity($draft)) { - return 'Tenant identity required'; + return 'ManagedEnvironment identity required'; } if (! $providerConnection instanceof ProviderConnection) { @@ -1704,7 +1704,7 @@ private function readinessNextAction( return $this->readinessAction( label: 'Grant admin consent', kind: 'grant_consent', - url: $draft->tenant instanceof Tenant ? RequiredPermissionsLinks::adminConsentPrimaryUrl($draft->tenant) : null, + url: $draft->tenant instanceof ManagedEnvironment ? RequiredPermissionsLinks::adminConsentPrimaryUrl($draft->tenant) : null, ); } @@ -1718,7 +1718,7 @@ private function readinessNextAction( return $this->readinessAction( label: 'Grant admin consent', kind: 'grant_consent', - url: $draft->tenant instanceof Tenant ? RequiredPermissionsLinks::adminConsentPrimaryUrl($draft->tenant) : null, + url: $draft->tenant instanceof ManagedEnvironment ? RequiredPermissionsLinks::adminConsentPrimaryUrl($draft->tenant) : null, ); } @@ -1726,7 +1726,7 @@ private function readinessNextAction( return $this->readinessAction( label: 'Review permissions', kind: 'review_permissions', - url: $draft->tenant instanceof Tenant ? RequiredPermissionsLinks::requiredPermissions($draft->tenant) : null, + url: $draft->tenant instanceof ManagedEnvironment ? RequiredPermissionsLinks::requiredPermissions($draft->tenant) : null, ); } @@ -1862,7 +1862,7 @@ private function readinessConnectionRecentlyUpdated(TenantOnboardingSession $dra private function readinessDraftHasTenantIdentity(TenantOnboardingSession $draft): bool { - if ($draft->tenant_id !== null) { + if ($draft->managed_environment_id !== null) { return true; } @@ -1981,7 +1981,7 @@ private function resumeOnboardingDraft(int $draftId, bool $logSelection): void 'metadata' => [ 'workspace_id' => (int) $this->workspace->getKey(), 'onboarding_session_id' => (int) $draft->getKey(), - 'tenant_db_id' => $draft->tenant_id !== null ? (int) $draft->tenant_id : null, + 'tenant_db_id' => $draft->managed_environment_id !== null ? (int) $draft->managed_environment_id : null, ], ], actor: $user, @@ -2055,7 +2055,7 @@ private function cancelOnboardingDraft(): void context: [ 'metadata' => [ 'workspace_id' => (int) $this->workspace->getKey(), - 'tenant_db_id' => $this->onboardingSession->tenant_id !== null ? (int) $this->onboardingSession->tenant_id : null, + 'tenant_db_id' => $this->onboardingSession->managed_environment_id !== null ? (int) $this->onboardingSession->managed_environment_id : null, 'onboarding_session_id' => (int) $this->onboardingSession->getKey(), ], ], @@ -2067,7 +2067,7 @@ private function cancelOnboardingDraft(): void $normalizedTenant = $this->lifecycleService()->syncLinkedTenantAfterCancellation($this->onboardingSession); - if ($normalizedTenant instanceof Tenant) { + if ($normalizedTenant instanceof ManagedEnvironment) { app(WorkspaceAuditLogger::class)->logTenantLifecycleAction( tenant: $normalizedTenant, action: AuditActionId::TenantReturnedToDraft, @@ -2129,7 +2129,7 @@ private function deleteOnboardingDraft(): void $draftTitle = $this->draftTitle($draft); $draftStatus = $draft->status()->value; $draftLifecycle = $draft->lifecycleState()->value; - $tenantId = $draft->tenant_id !== null ? (int) $draft->tenant_id : null; + $tenantId = $draft->managed_environment_id !== null ? (int) $draft->managed_environment_id : null; $draft->delete(); @@ -2312,14 +2312,14 @@ private function setOnboardingSession(?TenantOnboardingSession $draft): void ? $draft->expectedVersion() : null; - if ($draft instanceof TenantOnboardingSession && $draft->tenant instanceof Tenant) { + if ($draft instanceof TenantOnboardingSession && $draft->tenant instanceof ManagedEnvironment) { $this->setManagedTenant($draft->tenant); return; } - if ($draft instanceof TenantOnboardingSession && $draft->tenant_id !== null) { - $this->managedTenantId = (int) $draft->tenant_id; + if ($draft instanceof TenantOnboardingSession && $draft->managed_environment_id !== null) { + $this->managedTenantId = (int) $draft->managed_environment_id; return; } @@ -2327,14 +2327,14 @@ private function setOnboardingSession(?TenantOnboardingSession $draft): void $this->setManagedTenant(null); } - private function setManagedTenant(?Tenant $tenant): void + private function setManagedTenant(?ManagedEnvironment $tenant): void { $this->managedTenant = $tenant; - $this->managedTenantId = $tenant instanceof Tenant + $this->managedTenantId = $tenant instanceof ManagedEnvironment ? (int) $tenant->getKey() : null; - if ($this->onboardingSession instanceof TenantOnboardingSession && $tenant instanceof Tenant) { + if ($this->onboardingSession instanceof TenantOnboardingSession && $tenant instanceof ManagedEnvironment) { $this->onboardingSession->setRelation('tenant', $tenant); } } @@ -2362,15 +2362,15 @@ private function currentOnboardingSessionRecord(): ?TenantOnboardingSession return $query->first(); } - private function currentManagedTenantRecord(): ?Tenant + private function currentManagedTenantRecord(): ?ManagedEnvironment { $draft = $this->currentOnboardingSessionRecord(); - if ($draft instanceof TenantOnboardingSession && $draft->tenant instanceof Tenant) { + if ($draft instanceof TenantOnboardingSession && $draft->tenant instanceof ManagedEnvironment) { return $draft->tenant; } - if ($this->managedTenant instanceof Tenant + if ($this->managedTenant instanceof ManagedEnvironment && $this->managedTenantId !== null && (int) $this->managedTenant->getKey() === $this->managedTenantId) { return $this->managedTenant; @@ -2380,7 +2380,7 @@ private function currentManagedTenantRecord(): ?Tenant return $this->managedTenant; } - $query = Tenant::query()->withTrashed()->whereKey($this->managedTenantId); + $query = ManagedEnvironment::query()->withTrashed()->whereKey($this->managedTenantId); if (isset($this->workspace)) { $query->where('workspace_id', (int) $this->workspace->getKey()); @@ -2497,7 +2497,7 @@ public function refreshCheckpointLifecycle(): void $tenant = $this->currentManagedTenantRecord(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $this->setManagedTenant($tenant->fresh()); } @@ -2527,9 +2527,9 @@ private function initializeWizardData(): void $tenant = $this->currentManagedTenantRecord(); - if ($tenant instanceof Tenant) { - $this->data['entra_tenant_id'] ??= (string) $tenant->tenant_id; - $this->data['new_connection']['target_scope_id'] ??= (string) $tenant->tenant_id; + if ($tenant instanceof ManagedEnvironment) { + $this->data['entra_tenant_id'] ??= (string) $tenant->managed_environment_id; + $this->data['new_connection']['target_scope_id'] ??= (string) $tenant->managed_environment_id; $this->data['environment'] ??= (string) ($tenant->environment ?? 'other'); $this->data['name'] ??= (string) $tenant->name; $this->data['primary_domain'] ??= (string) ($tenant->domain ?? ''); @@ -2608,14 +2608,14 @@ private function providerConnectionOptions(): array { $tenant = $this->currentManagedTenantRecord(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } return ProviderConnection::query() ->with('tenant') ->where('workspace_id', (int) $this->workspace->getKey()) - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->orderByDesc('is_default') ->orderBy('display_name') ->get() @@ -2868,12 +2868,12 @@ private function verificationReportViewData(): array $previousRunUrl = $this->verificationPreviousRunUrl($changeIndicator); $user = auth()->user(); - $canAcknowledge = $user instanceof User && $this->managedTenant instanceof Tenant + $canAcknowledge = $user instanceof User && $this->managedTenant instanceof ManagedEnvironment ? $user->can(Capabilities::TENANT_VERIFICATION_ACKNOWLEDGE, $this->managedTenant) : false; $acknowledgements = VerificationCheckAcknowledgement::query() - ->where('tenant_id', (int) $run->tenant_id) + ->where('managed_environment_id', (int) $run->managed_environment_id) ->where('workspace_id', (int) $run->workspace_id) ->where('operation_run_id', (int) $run->getKey()) ->with('acknowledgedByUser') @@ -2965,7 +2965,7 @@ private function verificationContextualHelp(array $verificationReport, Operation { $tenant = $this->managedTenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -3056,13 +3056,13 @@ public function acknowledgeVerificationCheckAction(): Action abort(403); } - if (! $this->managedTenant instanceof Tenant) { + if (! $this->managedTenant instanceof ManagedEnvironment) { abort(404); } $tenant = $this->managedTenant->fresh(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -3108,7 +3108,7 @@ public function acknowledgeVerificationCheckAction(): Action return false; } - if (! $this->managedTenant instanceof Tenant) { + if (! $this->managedTenant instanceof ManagedEnvironment) { return false; } @@ -3235,7 +3235,7 @@ private function touchOnboardingSessionStep(string $step): void context: [ 'metadata' => [ 'workspace_id' => (int) $this->workspace->getKey(), - 'tenant_db_id' => $this->onboardingSession->tenant_id !== null ? (int) $this->onboardingSession->tenant_id : null, + 'tenant_db_id' => $this->onboardingSession->managed_environment_id !== null ? (int) $this->onboardingSession->managed_environment_id : null, 'onboarding_session_id' => (int) $this->onboardingSession->getKey(), 'current_step' => $step, ], @@ -3282,17 +3282,17 @@ private function authorizeEditableDraft(User $user): void } } - private function trustedManagedTenantForUser(User $user): Tenant + private function trustedManagedTenantForUser(User $user): ManagedEnvironment { $tenant = $this->currentManagedTenantRecord(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } $tenant = $tenant->fresh(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -3309,7 +3309,7 @@ private function canResumeDraft(?TenantOnboardingSession $draft): bool return false; } - if (! $draft->tenant instanceof Tenant) { + if (! $draft->tenant instanceof ManagedEnvironment) { return $this->lifecycleService()->canResumeDraft($draft); } @@ -3334,12 +3334,12 @@ private function authorizeWorkspaceMember(User $user): void ); } - private function resolveWorkspaceIdForUnboundTenant(Tenant $tenant): ?int + private function resolveWorkspaceIdForUnboundTenant(ManagedEnvironment $tenant): ?int { - $workspaceId = DB::table('tenant_memberships') - ->join('workspace_memberships', 'workspace_memberships.user_id', '=', 'tenant_memberships.user_id') - ->where('tenant_memberships.tenant_id', (int) $tenant->getKey()) - ->orderByRaw("CASE tenant_memberships.role WHEN 'owner' THEN 0 WHEN 'manager' THEN 1 WHEN 'operator' THEN 2 ELSE 3 END") + $workspaceId = DB::table('managed_environment_memberships') + ->join('workspace_memberships', 'workspace_memberships.user_id', '=', 'managed_environment_memberships.user_id') + ->where('managed_environment_memberships.managed_environment_id', (int) $tenant->getKey()) + ->orderByRaw("CASE managed_environment_memberships.role WHEN 'owner' THEN 0 WHEN 'manager' THEN 1 WHEN 'operator' THEN 2 ELSE 3 END") ->value('workspace_memberships.workspace_id'); return $workspaceId === null ? null : (int) $workspaceId; @@ -3385,13 +3385,13 @@ public function identifyManagedTenant(array $data): void $currentDraftId = $this->onboardingSession?->getKey(); $sessionWasCreated = false; - $existingTenant = Tenant::query() + $existingTenant = ManagedEnvironment::query() ->withTrashed() - ->where('tenant_id', $entraTenantId) + ->where('slug', $entraTenantId) ->first(); - if ($existingTenant instanceof Tenant) { - if ($existingTenant->trashed() || $existingTenant->status === Tenant::STATUS_ARCHIVED) { + if ($existingTenant instanceof ManagedEnvironment) { + if ($existingTenant->trashed() || $existingTenant->status === ManagedEnvironment::STATUS_ARCHIVED) { abort(404); } @@ -3411,7 +3411,7 @@ public function identifyManagedTenant(array $data): void 'name' => $tenantName, 'environment' => $environment, 'domain' => $primaryDomain, - 'status' => $existingTenant->status === Tenant::STATUS_DRAFT ? Tenant::STATUS_ONBOARDING : $existingTenant->status, + 'status' => $existingTenant->status === ManagedEnvironment::STATUS_DRAFT ? ManagedEnvironment::STATUS_ONBOARDING : $existingTenant->status, 'metadata' => array_merge(is_array($existingTenant->metadata) ? $existingTenant->metadata : [], array_filter([ 'notes' => $notes, ], static fn ($value): bool => $value !== null)), @@ -3420,30 +3420,30 @@ public function identifyManagedTenant(array $data): void $tenant = $existingTenant; } else { try { - $tenant = Tenant::query()->create([ + $tenant = ManagedEnvironment::query()->create([ 'workspace_id' => (int) $this->workspace->getKey(), 'name' => $tenantName, - 'tenant_id' => $entraTenantId, + 'slug' => $entraTenantId, 'domain' => $primaryDomain, 'environment' => $environment, - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, 'metadata' => array_filter([ 'notes' => $notes, ], static fn ($value): bool => $value !== null), ]); } catch (QueryException $exception) { - // Race-safe global uniqueness: if another workspace created the tenant_id first, + // Race-safe global uniqueness: if another workspace created the managed_environment_id first, // treat it as deny-as-not-found. - $existingTenant = Tenant::query() + $existingTenant = ManagedEnvironment::query() ->withTrashed() - ->where('tenant_id', $entraTenantId) + ->where('slug', $entraTenantId) ->first(); - if ($existingTenant instanceof Tenant && (int) $existingTenant->workspace_id !== (int) $this->workspace->getKey()) { + if ($existingTenant instanceof ManagedEnvironment && (int) $existingTenant->workspace_id !== (int) $this->workspace->getKey()) { abort(404); } - if ($existingTenant instanceof Tenant && (int) $existingTenant->workspace_id === (int) $this->workspace->getKey()) { + if ($existingTenant instanceof ManagedEnvironment && (int) $existingTenant->workspace_id === (int) $this->workspace->getKey()) { $tenant = $existingTenant; } else { throw $exception; @@ -3459,13 +3459,13 @@ public function identifyManagedTenant(array $data): void source: 'manual', ); - $ownerCount = TenantMembership::query() - ->where('tenant_id', $tenant->getKey()) + $ownerCount = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', $tenant->getKey()) ->where('role', 'owner') ->count(); if ($ownerCount === 0) { - throw new RuntimeException('Tenant must have at least one owner.'); + throw new RuntimeException('ManagedEnvironment must have at least one owner.'); } $this->selectedProviderConnectionId ??= $this->resolveDefaultProviderConnectionId($tenant); @@ -3477,7 +3477,7 @@ public function identifyManagedTenant(array $data): void preferredDraft: $this->onboardingSession, expectedVersion: $this->expectedDraftVersion(), mutator: function (TenantOnboardingSession $draft) use ($tenant, $entraTenantId, $tenantName, $environment, $primaryDomain, $notes): void { - $draft->tenant_id = (int) $tenant->getKey(); + $draft->managed_environment_id = (int) $tenant->getKey(); $draft->current_step = 'identify'; $draft->state = array_merge($draft->state ?? [], [ 'entra_tenant_id' => $entraTenantId, @@ -3571,7 +3571,7 @@ public function selectProviderConnection(int $providerConnectionId): void $connection = ProviderConnection::query() ->where('workspace_id', (int) $this->workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereKey($providerConnectionId) ->first(); @@ -3651,7 +3651,7 @@ public function createProviderConnection(array $data): void $tenant = $this->trustedManagedTenantForUser($user)->fresh(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -3675,10 +3675,10 @@ public function createProviderConnection(array $data): void $targetScope = app(ProviderConnectionTargetScopeNormalizer::class)->normalizeInput( provider: 'microsoft', scopeKind: ProviderConnectionTargetScopeDescriptor::SCOPE_KIND_TENANT, - scopeIdentifier: (string) $tenant->tenant_id, + scopeIdentifier: (string) $tenant->managed_environment_id, scopeDisplayName: $displayName, providerSpecificIdentity: [ - 'microsoft_tenant_id' => (string) $tenant->tenant_id, + 'microsoft_tenant_id' => (string) $tenant->managed_environment_id, ], ); @@ -3702,17 +3702,17 @@ public function createProviderConnection(array $data): void /** @var ProviderConnection $connection */ $connection = DB::transaction(function () use ($tenant, $displayName, $clientId, $clientSecret, $makeDefault, $usesDedicatedCredential, &$wasExistingConnection, &$previousConnectionType): ProviderConnection { $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') - ->where('entra_tenant_id', (string) $tenant->tenant_id) + ->where('entra_tenant_id', (string) $tenant->managed_environment_id) ->first(); if (! $connection instanceof ProviderConnection) { $connection = ProviderConnection::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => $displayName, 'is_enabled' => true, 'connection_type' => ProviderConnectionType::Platform->value, @@ -3894,7 +3894,7 @@ public function startVerification(): void return; } - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -4075,7 +4075,7 @@ public function startBootstrap(array $operationTypes): void $tenant = $this->trustedManagedTenantForUser($user)->fresh(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -4503,7 +4503,7 @@ private function verificationIsBlocked(): bool private function canCompleteOnboarding(): bool { - if (! $this->managedTenant instanceof Tenant) { + if (! $this->managedTenant instanceof ManagedEnvironment) { return false; } @@ -4669,7 +4669,7 @@ private function completionSummaryTenantLine(): string { $tenant = $this->currentManagedTenantRecord(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return '—'; } @@ -4683,7 +4683,7 @@ private function completionSummaryConnectionLabel(): string { $tenant = $this->currentManagedTenantRecord(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return '—'; } @@ -4706,7 +4706,7 @@ private function completionSummaryConnectionLabel(): string private function completionSummaryConnectionDetail(): string { - if (! $this->managedTenant instanceof Tenant) { + if (! $this->managedTenant instanceof ManagedEnvironment) { return ''; } @@ -5043,7 +5043,7 @@ public function completeOnboarding(): void $tenant = $tenant->fresh(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -5064,7 +5064,7 @@ public function completeOnboarding(): void try { DB::transaction(function () use ($tenant, $user): void { - $tenant->update(['status' => Tenant::STATUS_ACTIVE]); + $tenant->update(['status' => ManagedEnvironment::STATUS_ACTIVE]); $this->setOnboardingSession($this->mutationService()->mutate( draft: $this->onboardingSession, @@ -5080,8 +5080,8 @@ public function completeOnboarding(): void } catch (OnboardingDraftConflictException) { $tenant->refresh(); - if ($tenant->status === Tenant::STATUS_ACTIVE) { - $tenant->update(['status' => Tenant::STATUS_ONBOARDING]); + if ($tenant->status === ManagedEnvironment::STATUS_ACTIVE) { + $tenant->update(['status' => ManagedEnvironment::STATUS_ONBOARDING]); } $this->handleDraftConflict('Completing onboarding was blocked because the onboarding draft changed.'); @@ -5090,8 +5090,8 @@ public function completeOnboarding(): void } catch (OnboardingDraftImmutableException) { $tenant->refresh(); - if ($tenant->status === Tenant::STATUS_ACTIVE) { - $tenant->update(['status' => Tenant::STATUS_ONBOARDING]); + if ($tenant->status === ManagedEnvironment::STATUS_ACTIVE) { + $tenant->update(['status' => ManagedEnvironment::STATUS_ONBOARDING]); } $this->handleImmutableDraft('Completing onboarding was blocked because the onboarding draft is no longer editable.'); @@ -5203,7 +5203,7 @@ private function verificationAssistVisibility(): array $user = $this->currentUser(); $run = $this->verificationRun(); - if (! $tenant instanceof Tenant || ! $user instanceof User || ! $user->canAccessTenant($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User || ! $user->canAccessTenant($tenant)) { return $this->hiddenVerificationAssistVisibility(); } @@ -5244,7 +5244,7 @@ private function verificationAssistViewModel(): array $user = $this->currentUser(); $run = $this->verificationRun(); - if (! $tenant instanceof Tenant || ! $user instanceof User || ! $user->canAccessTenant($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User || ! $user->canAccessTenant($tenant)) { abort(404); } @@ -5336,14 +5336,14 @@ private function inlineEditSelectedConnectionFill(int $providerConnectionId): ar $this->authorizeWorkspaceMutation($user, Capabilities::WORKSPACE_MANAGED_TENANT_ONBOARD_CONNECTION_MANAGE); - if (! $this->managedTenant instanceof Tenant) { + if (! $this->managedTenant instanceof ManagedEnvironment) { abort(404); } $connection = ProviderConnection::query() ->with('credential') ->where('workspace_id', (int) $this->workspace->getKey()) - ->where('tenant_id', (int) $this->managedTenant->getKey()) + ->where('managed_environment_id', (int) $this->managedTenant->getKey()) ->whereKey($providerConnectionId) ->first(); @@ -5375,14 +5375,14 @@ public function updateSelectedProviderConnectionInline(int $providerConnectionId $this->authorizeWorkspaceMutation($user, Capabilities::WORKSPACE_MANAGED_TENANT_ONBOARD_CONNECTION_MANAGE); - if (! $this->managedTenant instanceof Tenant) { + if (! $this->managedTenant instanceof ManagedEnvironment) { abort(404); } $connection = ProviderConnection::query() ->with('credential') ->where('workspace_id', (int) $this->workspace->getKey()) - ->where('tenant_id', (int) $this->managedTenant->getKey()) + ->where('managed_environment_id', (int) $this->managedTenant->getKey()) ->whereKey($providerConnectionId) ->first(); @@ -5570,11 +5570,11 @@ private function bootstrapOperationOptions(): array ->all(); } - private function resolveDefaultProviderConnectionId(Tenant $tenant): ?int + private function resolveDefaultProviderConnectionId(ManagedEnvironment $tenant): ?int { $id = ProviderConnection::query() ->where('workspace_id', (int) $this->workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('is_default', true) ->orderByDesc('id') ->value('id'); @@ -5585,14 +5585,14 @@ private function resolveDefaultProviderConnectionId(Tenant $tenant): ?int $fallback = ProviderConnection::query() ->where('workspace_id', (int) $this->workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->orderByDesc('id') ->value('id'); return is_int($fallback) ? $fallback : null; } - private function resolveSelectedProviderConnection(Tenant $tenant): ?ProviderConnection + private function resolveSelectedProviderConnection(ManagedEnvironment $tenant): ?ProviderConnection { $providerConnectionId = $this->selectedProviderConnectionId; @@ -5611,7 +5611,7 @@ private function resolveSelectedProviderConnection(Tenant $tenant): ?ProviderCon return ProviderConnection::query() ->where('workspace_id', (int) $this->workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereKey($providerConnectionId) ->first(); } @@ -5629,7 +5629,7 @@ private function resolvePersistedProviderConnectionId(mixed $providerConnectionI $tenantId = $this->managedTenant?->getKey(); if (! is_int($tenantId) && $this->onboardingSession instanceof TenantOnboardingSession) { - $tenantId = is_numeric($this->onboardingSession->tenant_id) ? (int) $this->onboardingSession->tenant_id : null; + $tenantId = is_numeric($this->onboardingSession->managed_environment_id) ? (int) $this->onboardingSession->managed_environment_id : null; } if (! is_int($tenantId)) { @@ -5639,7 +5639,7 @@ private function resolvePersistedProviderConnectionId(mixed $providerConnectionI $exists = ProviderConnection::query() ->whereKey($providerConnectionId) ->where('workspace_id', (int) $this->workspace->getKey()) - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->exists(); return $exists ? $providerConnectionId : null; diff --git a/apps/platform/app/Filament/Pages/Workspaces/ManagedTenantsLanding.php b/apps/platform/app/Filament/Pages/Workspaces/ManagedTenantsLanding.php index cc51adc5..6bd7cd14 100644 --- a/apps/platform/app/Filament/Pages/Workspaces/ManagedTenantsLanding.php +++ b/apps/platform/app/Filament/Pages/Workspaces/ManagedTenantsLanding.php @@ -6,7 +6,7 @@ use App\Filament\Pages\ChooseTenant; use App\Filament\Resources\TenantResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Tenants\TenantOperabilityService; @@ -48,26 +48,26 @@ public function mount(Workspace $workspace): void } /** - * @return Collection + * @return Collection */ public function getTenants(): Collection { $user = auth()->user(); if (! $user instanceof User) { - return Tenant::query()->whereRaw('1 = 0')->get(); + return ManagedEnvironment::query()->whereRaw('1 = 0')->get(); } $tenantIds = $user->tenantMemberships() - ->pluck('tenant_id'); + ->pluck('managed_environment_id'); - return Tenant::query() + return ManagedEnvironment::query() ->withTrashed() ->whereIn('id', $tenantIds) ->where('workspace_id', $this->workspace->getKey()) ->orderBy('name') ->get() - ->filter(function (Tenant $tenant) use ($user): bool { + ->filter(function (ManagedEnvironment $tenant) use ($user): bool { return app(TenantOperabilityService::class)->outcomeFor( tenant: $tenant, question: TenantOperabilityQuestion::AdministrativeDiscoverability, @@ -92,13 +92,13 @@ public function openTenant(int $tenantId): void abort(403); } - $tenant = Tenant::query() + $tenant = ManagedEnvironment::query() ->withTrashed() ->where('workspace_id', $this->workspace->getKey()) ->whereKey($tenantId) ->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } diff --git a/apps/platform/app/Filament/Resources/AlertDeliveryResource.php b/apps/platform/app/Filament/Resources/AlertDeliveryResource.php index 16a1e4d7..b2e2e793 100644 --- a/apps/platform/app/Filament/Resources/AlertDeliveryResource.php +++ b/apps/platform/app/Filament/Resources/AlertDeliveryResource.php @@ -8,7 +8,7 @@ use App\Filament\Resources\AlertDeliveryResource\Pages; use App\Models\AlertDelivery; use App\Models\AlertDestination; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Badges\BadgeDomain; use App\Support\Badges\BadgeRenderer; @@ -133,13 +133,13 @@ public static function getEloquentQuery(): Builder ->when( $user instanceof User, fn (Builder $query): Builder => $query->where(function (Builder $q) use ($user): void { - $q->whereIn('tenant_id', $user->tenantMemberships()->select('tenant_id')) - ->orWhereNull('tenant_id'); + $q->whereIn('managed_environment_id', $user->tenantMemberships()->select('managed_environment_id')) + ->orWhereNull('managed_environment_id'); }), ) ->when( - $activeTenant instanceof Tenant, - fn (Builder $query): Builder => $query->where('tenant_id', (int) $activeTenant->getKey()), + $activeTenant instanceof ManagedEnvironment, + fn (Builder $query): Builder => $query->where('managed_environment_id', (int) $activeTenant->getKey()), ) ->latest('id'); } @@ -169,7 +169,7 @@ public static function infolist(Schema $schema): Schema ->formatStateUsing(fn (?string $state): string => ucfirst((string) $state)) ->placeholder('—'), TextEntry::make('tenant.name') - ->label('Tenant'), + ->label('ManagedEnvironment'), TextEntry::make('rule.name') ->label('Rule') ->placeholder('—'), @@ -230,7 +230,7 @@ public static function table(Table $table): Table ->since() ->sortable(), TextColumn::make('tenant.name') - ->label('Tenant') + ->label('ManagedEnvironment') ->searchable(), TextColumn::make('event_type') ->label('Event') @@ -257,12 +257,12 @@ public static function table(Table $table): Table ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ - SelectFilter::make('tenant_id') - ->label('Tenant') + SelectFilter::make('managed_environment_id') + ->label('ManagedEnvironment') ->options(function (): array { $activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request()); - if ($activeTenant instanceof Tenant) { + if ($activeTenant instanceof ManagedEnvironment) { return [ (string) $activeTenant->getKey() => $activeTenant->getFilamentName(), ]; @@ -275,7 +275,7 @@ public static function table(Table $table): Table } return collect($user->getTenants(Filament::getCurrentOrDefaultPanel())) - ->mapWithKeys(static fn (Tenant $tenant): array => [ + ->mapWithKeys(static fn (ManagedEnvironment $tenant): array => [ (string) $tenant->getKey() => $tenant->getFilamentName(), ]) ->all(); @@ -283,7 +283,7 @@ public static function table(Table $table): Table ->default(function (): ?string { $activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request()); - if (! $activeTenant instanceof Tenant) { + if (! $activeTenant instanceof ManagedEnvironment) { return null; } diff --git a/apps/platform/app/Filament/Resources/AlertRuleResource.php b/apps/platform/app/Filament/Resources/AlertRuleResource.php index af838a87..fbe3d233 100644 --- a/apps/platform/app/Filament/Resources/AlertRuleResource.php +++ b/apps/platform/app/Filament/Resources/AlertRuleResource.php @@ -8,7 +8,7 @@ use App\Filament\Resources\AlertRuleResource\Pages; use App\Models\AlertDestination; use App\Models\AlertRule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; use App\Support\Audit\AuditActionId; @@ -434,9 +434,9 @@ private static function tenantOptions(): array return []; } - return Tenant::query() + return ManagedEnvironment::query() ->where('workspace_id', $workspaceId) - ->where('status', 'active') + ->where('lifecycle_status', ManagedEnvironment::STATUS_ACTIVE) ->orderBy('name') ->pluck('name', 'id') ->all(); diff --git a/apps/platform/app/Filament/Resources/BackupScheduleResource.php b/apps/platform/app/Filament/Resources/BackupScheduleResource.php index a900b52a..281f5be8 100644 --- a/apps/platform/app/Filament/Resources/BackupScheduleResource.php +++ b/apps/platform/app/Filament/Resources/BackupScheduleResource.php @@ -9,7 +9,7 @@ use App\Filament\Resources\BackupScheduleResource\RelationManagers\BackupScheduleOperationRunsRelationManager; use App\Jobs\RunBackupScheduleJob; use App\Models\BackupSchedule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Rules\SupportedPolicyTypesRule; use App\Services\Auth\CapabilityResolver; @@ -92,7 +92,7 @@ public static function canViewAny(): bool $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -108,7 +108,7 @@ public static function canView(Model $record): bool $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -120,7 +120,7 @@ public static function canView(Model $record): bool } if ($record instanceof BackupSchedule) { - return (int) $record->tenant_id === (int) $tenant->getKey(); + return (int) $record->managed_environment_id === (int) $tenant->getKey(); } return true; @@ -132,7 +132,7 @@ public static function canCreate(): bool $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -148,7 +148,7 @@ public static function canEdit(Model $record): bool $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -164,7 +164,7 @@ public static function canDelete(Model $record): bool $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -180,7 +180,7 @@ public static function canDeleteAny(): bool $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -440,7 +440,7 @@ public static function table(Table $table): Table ->action(function (BackupSchedule $record, HasTable $livewire): void { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { Notification::make() ->title('No tenant selected') ->danger() @@ -511,7 +511,7 @@ public static function table(Table $table): Table ->action(function (BackupSchedule $record, HasTable $livewire): void { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { Notification::make() ->title('No tenant selected') ->danger() @@ -590,7 +590,7 @@ public static function table(Table $table): Table $record->restore(); - if ($record->tenant instanceof Tenant) { + if ($record->tenant instanceof ManagedEnvironment) { $auditLogger->log( tenant: $record->tenant, action: 'backup_schedule.restored', @@ -633,7 +633,7 @@ public static function table(Table $table): Table $record->delete(); - if ($record->tenant instanceof Tenant) { + if ($record->tenant instanceof ManagedEnvironment) { $auditLogger->log( tenant: $record->tenant, action: 'backup_schedule.archived', @@ -685,7 +685,7 @@ public static function table(Table $table): Table return; } - if ($record->tenant instanceof Tenant) { + if ($record->tenant instanceof ManagedEnvironment) { $auditLogger->log( tenant: $record->tenant, action: 'backup_schedule.force_deleted', @@ -728,7 +728,7 @@ public static function table(Table $table): Table ->action(function (Collection $records, HasTable $livewire): void { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { Notification::make() ->title('No tenant selected') ->danger() @@ -825,7 +825,7 @@ public static function table(Table $table): Table ->action(function (Collection $records, HasTable $livewire): void { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { Notification::make() ->title('No tenant selected') ->danger() @@ -1062,7 +1062,7 @@ public static function ensurePolicyTypes(array $data): array public static function assignTenant(array $data): array { - $data['tenant_id'] = static::resolveTenantContextForCurrentPanelOrFail()->getKey(); + $data['managed_environment_id'] = static::resolveTenantContextForCurrentPanelOrFail()->getKey(); return $data; } diff --git a/apps/platform/app/Filament/Resources/BackupScheduleResource/Pages/ListBackupSchedules.php b/apps/platform/app/Filament/Resources/BackupScheduleResource/Pages/ListBackupSchedules.php index 782355c4..74e451c9 100644 --- a/apps/platform/app/Filament/Resources/BackupScheduleResource/Pages/ListBackupSchedules.php +++ b/apps/platform/app/Filament/Resources/BackupScheduleResource/Pages/ListBackupSchedules.php @@ -3,7 +3,7 @@ namespace App\Filament\Resources\BackupScheduleResource\Pages; use App\Filament\Resources\BackupScheduleResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\BackupHealth\TenantBackupHealthAssessment; use App\Support\BackupHealth\TenantBackupHealthResolver; use App\Support\Filament\CanonicalAdminTenantFilterState; diff --git a/apps/platform/app/Filament/Resources/BackupScheduleResource/RelationManagers/BackupScheduleOperationRunsRelationManager.php b/apps/platform/app/Filament/Resources/BackupScheduleResource/RelationManagers/BackupScheduleOperationRunsRelationManager.php index 44dbec94..9b30da1d 100644 --- a/apps/platform/app/Filament/Resources/BackupScheduleResource/RelationManagers/BackupScheduleOperationRunsRelationManager.php +++ b/apps/platform/app/Filament/Resources/BackupScheduleResource/RelationManagers/BackupScheduleOperationRunsRelationManager.php @@ -3,7 +3,7 @@ namespace App\Filament\Resources\BackupScheduleResource\RelationManagers; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Badges\BadgeDomain; use App\Support\Badges\BadgeRenderer; use App\Support\OperationCatalog; @@ -37,12 +37,12 @@ public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration public function table(Table $table): Table { return $table - ->modifyQueryUsing(fn (Builder $query) => $query->where('tenant_id', Tenant::currentOrFail()->getKey())) + ->modifyQueryUsing(fn (Builder $query) => $query->where('managed_environment_id', ManagedEnvironment::currentOrFail()->getKey())) ->defaultSort('created_at', 'desc') ->paginated(\App\Support\Filament\TablePaginationProfiles::relationManager()) ->recordUrl(function (OperationRun $record): string { $record = $this->resolveOwnerScopedOperationRun($record); - $tenant = Tenant::currentOrFail(); + $tenant = ManagedEnvironment::currentOrFail(); return OperationRunLinks::view($record, $tenant); }) @@ -106,7 +106,7 @@ private function resolveOwnerScopedOperationRun(mixed $record): OperationRun $resolvedRecord = $this->getOwnerRecord() ->operationRuns() - ->where('tenant_id', Tenant::currentOrFail()->getKey()) + ->where('managed_environment_id', ManagedEnvironment::currentOrFail()->getKey()) ->whereKey($recordId) ->first(); diff --git a/apps/platform/app/Filament/Resources/BackupSetResource.php b/apps/platform/app/Filament/Resources/BackupSetResource.php index 5cb8a559..a65d6c70 100644 --- a/apps/platform/app/Filament/Resources/BackupSetResource.php +++ b/apps/platform/app/Filament/Resources/BackupSetResource.php @@ -10,7 +10,7 @@ use App\Jobs\BulkBackupSetForceDeleteJob; use App\Jobs\BulkBackupSetRestoreJob; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Intune\AuditLogger; @@ -96,7 +96,7 @@ public static function canViewAny(): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -112,7 +112,7 @@ public static function canCreate(): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -352,7 +352,7 @@ public static function table(Table $table): Table $count = $records->count(); $ids = $records->pluck('id')->toArray(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -369,7 +369,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'backup_set.delete', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $initiator, $ids): void { @@ -422,7 +422,7 @@ public static function table(Table $table): Table $count = $records->count(); $ids = $records->pluck('id')->toArray(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -439,7 +439,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'backup_set.restore', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $initiator, $ids): void { @@ -507,7 +507,7 @@ public static function table(Table $table): Table $count = $records->count(); $ids = $records->pluck('id')->toArray(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -524,7 +524,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'backup_set.force_delete', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $initiator, $ids): void { @@ -651,7 +651,7 @@ private static function primaryRelatedEntry(BackupSet $record): ?RelatedContextE */ public static function createBackupSet(array $data): BackupSet { - /** @var Tenant $tenant */ + /** @var ManagedEnvironment $tenant */ $tenant = static::resolveTenantContextForCurrentPanel(); /** @var BackupService $service */ @@ -846,7 +846,7 @@ private static function backupHealthContinuityAssessment(BackupSet $record): ?Te /** @var TenantBackupHealthResolver $resolver */ $resolver = app(TenantBackupHealthResolver::class); - $assessment = $resolver->assess((int) $record->tenant_id); + $assessment = $resolver->assess((int) $record->managed_environment_id); if ($assessment->latestRelevantBackupSetId !== (int) $record->getKey()) { return null; diff --git a/apps/platform/app/Filament/Resources/BackupSetResource/Pages/ViewBackupSet.php b/apps/platform/app/Filament/Resources/BackupSetResource/Pages/ViewBackupSet.php index 0d6d8036..19791d03 100644 --- a/apps/platform/app/Filament/Resources/BackupSetResource/Pages/ViewBackupSet.php +++ b/apps/platform/app/Filament/Resources/BackupSetResource/Pages/ViewBackupSet.php @@ -7,7 +7,7 @@ use App\Filament\Concerns\ResolvesPanelTenantContext; use App\Filament\Resources\BackupSetResource; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\AuditLogger; use App\Support\Auth\Capabilities; use App\Support\Navigation\CrossResourceNavigationMatrix; @@ -72,7 +72,7 @@ private function restoreAction(): Action $record->restore(); $record->items()->withTrashed()->restore(); - if ($record->tenant instanceof Tenant) { + if ($record->tenant instanceof ManagedEnvironment) { $auditLogger->log( tenant: $record->tenant, action: 'backup.restored', @@ -113,7 +113,7 @@ private function archiveAction(): Action $record->delete(); - if ($record->tenant instanceof Tenant) { + if ($record->tenant instanceof ManagedEnvironment) { $auditLogger->log( tenant: $record->tenant, action: 'backup.deleted', @@ -162,7 +162,7 @@ private function forceDeleteAction(): Action return; } - if ($record->tenant instanceof Tenant) { + if ($record->tenant instanceof ManagedEnvironment) { $auditLogger->log( tenant: $record->tenant, action: 'backup.force_deleted', diff --git a/apps/platform/app/Filament/Resources/BackupSetResource/RelationManagers/BackupItemsRelationManager.php b/apps/platform/app/Filament/Resources/BackupSetResource/RelationManagers/BackupItemsRelationManager.php index 1e5226db..60bcdbe2 100644 --- a/apps/platform/app/Filament/Resources/BackupSetResource/RelationManagers/BackupItemsRelationManager.php +++ b/apps/platform/app/Filament/Resources/BackupSetResource/RelationManagers/BackupItemsRelationManager.php @@ -7,7 +7,7 @@ use App\Jobs\RemovePoliciesFromBackupSetJob; use App\Models\BackupItem; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Support\Auth\Capabilities; @@ -122,12 +122,12 @@ public function table(Table $table): Table abort(403); } - $tenant = $backupSet->tenant ?? Tenant::current(); - if (! $tenant instanceof Tenant) { + $tenant = $backupSet->tenant ?? ManagedEnvironment::current(); + if (! $tenant instanceof ManagedEnvironment) { abort(404); } - if ((int) $tenant->getKey() !== (int) $backupSet->tenant_id) { + if ((int) $tenant->getKey() !== (int) $backupSet->managed_environment_id) { abort(404); } @@ -201,12 +201,12 @@ public function table(Table $table): Table abort(403); } - $tenant = $backupSet->tenant ?? Tenant::current(); - if (! $tenant instanceof Tenant) { + $tenant = $backupSet->tenant ?? ManagedEnvironment::current(); + if (! $tenant instanceof ManagedEnvironment) { abort(404); } - if ((int) $tenant->getKey() !== (int) $backupSet->tenant_id) { + if ((int) $tenant->getKey() !== (int) $backupSet->managed_environment_id) { abort(404); } @@ -477,7 +477,7 @@ private function backupItemInspectUrl(BackupItem $record): ?string $resolvedRecord = $backupSet->items() ->with(['policy', 'policyVersion', 'policyVersion.policy']) - ->where('tenant_id', (int) $backupSet->tenant_id) + ->where('managed_environment_id', (int) $backupSet->managed_environment_id) ->whereKey($resolvedId) ->first(); @@ -485,9 +485,9 @@ private function backupItemInspectUrl(BackupItem $record): ?string abort(404); } - $tenant = $backupSet->tenant ?? Tenant::current(); + $tenant = $backupSet->tenant ?? ManagedEnvironment::current(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -516,7 +516,7 @@ private function resolveOwnerScopedBackupItemId(BackupSet $backupSet, mixed $rec } $resolvedId = $backupSet->items() - ->where('tenant_id', (int) $backupSet->tenant_id) + ->where('managed_environment_id', (int) $backupSet->managed_environment_id) ->whereKey($recordId) ->value('id'); @@ -545,7 +545,7 @@ private function resolveOwnerScopedBackupItemIdsFromKeys(BackupSet $backupSet, a } $resolvedIds = $backupSet->items() - ->where('tenant_id', (int) $backupSet->tenant_id) + ->where('managed_environment_id', (int) $backupSet->managed_environment_id) ->whereIn('id', $requestedIds) ->pluck('id') ->map(fn (mixed $value): int => (int) $value) diff --git a/apps/platform/app/Filament/Resources/BaselineProfileResource.php b/apps/platform/app/Filament/Resources/BaselineProfileResource.php index a367debf..9a0f1293 100644 --- a/apps/platform/app/Filament/Resources/BaselineProfileResource.php +++ b/apps/platform/app/Filament/Resources/BaselineProfileResource.php @@ -10,7 +10,7 @@ use App\Models\BaselineSnapshot; use App\Models\BaselineTenantAssignment; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Audit\WorkspaceAuditLogger; @@ -968,7 +968,7 @@ private static function hasEligibleCompareTarget(BaselineProfile $profile): bool $tenantIds = BaselineTenantAssignment::query() ->where('workspace_id', (int) $profile->workspace_id) ->where('baseline_profile_id', (int) $profile->getKey()) - ->pluck('tenant_id') + ->pluck('managed_environment_id') ->all(); if ($tenantIds === []) { @@ -977,11 +977,11 @@ private static function hasEligibleCompareTarget(BaselineProfile $profile): bool $resolver = app(CapabilityResolver::class); - return Tenant::query() + return ManagedEnvironment::query() ->where('workspace_id', (int) $profile->workspace_id) ->whereIn('id', $tenantIds) ->get(['id']) - ->contains(fn (Tenant $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_SYNC)); + ->contains(fn (ManagedEnvironment $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_SYNC)); } /** diff --git a/apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php b/apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php index 86a53c4e..a9b1a6e9 100644 --- a/apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php +++ b/apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php @@ -7,7 +7,7 @@ use App\Filament\Resources\BaselineProfileResource; use App\Models\BaselineProfile; use App\Models\BaselineTenantAssignment; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -77,7 +77,7 @@ private function captureAction(): Action ->modalDescription($modalDescription) ->form([ Select::make('source_tenant_id') - ->label('Source Tenant') + ->label('Source ManagedEnvironment') ->options(fn (): array => $this->getWorkspaceTenantOptions()) ->required() ->searchable(), @@ -91,9 +91,9 @@ private function captureAction(): Action /** @var BaselineProfile $profile */ $profile = $this->getRecord(); - $sourceTenant = Tenant::query()->find((int) $data['source_tenant_id']); + $sourceTenant = ManagedEnvironment::query()->find((int) $data['source_tenant_id']); - if (! $sourceTenant instanceof Tenant) { + if (! $sourceTenant instanceof ManagedEnvironment) { Notification::make() ->title('Source tenant not found') ->danger() @@ -188,7 +188,7 @@ private function compareNowAction(): Action ->modalDescription($modalDescription) ->form([ Select::make('target_tenant_id') - ->label('Target Tenant') + ->label('Target ManagedEnvironment') ->options(fn (): array => $this->getEligibleCompareTenantOptions()) ->required() ->searchable(), @@ -204,9 +204,9 @@ private function compareNowAction(): Action /** @var BaselineProfile $profile */ $profile = $this->getRecord(); - $targetTenant = Tenant::query()->find((int) $data['target_tenant_id']); + $targetTenant = ManagedEnvironment::query()->find((int) $data['target_tenant_id']); - if (! $targetTenant instanceof Tenant || (int) $targetTenant->workspace_id !== (int) $profile->workspace_id) { + if (! $targetTenant instanceof ManagedEnvironment || (int) $targetTenant->workspace_id !== (int) $profile->workspace_id) { Notification::make() ->title('Target tenant not found') ->danger() @@ -217,13 +217,13 @@ private function compareNowAction(): Action $assignment = BaselineTenantAssignment::query() ->where('workspace_id', (int) $profile->workspace_id) - ->where('tenant_id', (int) $targetTenant->getKey()) + ->where('managed_environment_id', (int) $targetTenant->getKey()) ->where('baseline_profile_id', (int) $profile->getKey()) ->first(); if (! $assignment instanceof BaselineTenantAssignment) { Notification::make() - ->title('Tenant not assigned') + ->title('ManagedEnvironment not assigned') ->body('This tenant is not assigned to this baseline profile.') ->warning() ->send(); @@ -384,7 +384,7 @@ private function getWorkspaceTenantOptions(): array return []; } - return Tenant::query() + return ManagedEnvironment::query() ->where('workspace_id', $workspaceId) ->orderBy('name') ->pluck('name', 'id') @@ -408,7 +408,7 @@ private function getEligibleCompareTenantOptions(): array $tenantIds = BaselineTenantAssignment::query() ->where('workspace_id', (int) $profile->workspace_id) ->where('baseline_profile_id', (int) $profile->getKey()) - ->pluck('tenant_id') + ->pluck('managed_environment_id') ->all(); if ($tenantIds === []) { @@ -419,14 +419,14 @@ private function getEligibleCompareTenantOptions(): array $options = []; - $tenants = Tenant::query() + $tenants = ManagedEnvironment::query() ->where('workspace_id', (int) $profile->workspace_id) ->whereIn('id', $tenantIds) ->orderBy('name') ->get(['id', 'name']); foreach ($tenants as $tenant) { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { continue; } @@ -510,7 +510,7 @@ private function visibleAssignedTenantCount(BaselineProfile $profile): int $tenantIds = BaselineTenantAssignment::query() ->where('workspace_id', (int) $profile->workspace_id) ->where('baseline_profile_id', (int) $profile->getKey()) - ->pluck('tenant_id') + ->pluck('managed_environment_id') ->all(); if ($tenantIds === []) { @@ -519,11 +519,11 @@ private function visibleAssignedTenantCount(BaselineProfile $profile): int $resolver = app(CapabilityResolver::class); - return Tenant::query() + return ManagedEnvironment::query() ->where('workspace_id', (int) $profile->workspace_id) ->whereIn('id', $tenantIds) ->get(['id']) - ->filter(fn (Tenant $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_VIEW)) + ->filter(fn (ManagedEnvironment $tenant): bool => $resolver->can($user, $tenant, Capabilities::TENANT_VIEW)) ->count(); } } diff --git a/apps/platform/app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php b/apps/platform/app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php index 81a8d500..2e724340 100644 --- a/apps/platform/app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php +++ b/apps/platform/app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php @@ -6,7 +6,7 @@ use App\Models\BaselineProfile; use App\Models\BaselineTenantAssignment; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Audit\WorkspaceAuditLogger; @@ -27,7 +27,7 @@ class BaselineTenantAssignmentsRelationManager extends RelationManager { protected static string $relationship = 'tenantAssignments'; - protected static ?string $title = 'Tenant assignments'; + protected static ?string $title = 'ManagedEnvironment assignments'; /** * @var array|null @@ -51,7 +51,7 @@ public function table(Table $table): Table ->paginated(\App\Support\Filament\TablePaginationProfiles::relationManager()) ->columns([ Tables\Columns\TextColumn::make('tenant.name') - ->label('Tenant') + ->label('ManagedEnvironment') ->searchable(), Tables\Columns\TextColumn::make('assignedByUser.name') ->label('Assigned by') @@ -78,12 +78,12 @@ public function table(Table $table): Table private function assignTenantAction(): Action { return Action::make('assign') - ->label('Assign Tenant') + ->label('Assign ManagedEnvironment') ->icon('heroicon-o-plus') ->visible(fn (): bool => $this->hasManageCapability()) ->form([ - Select::make('tenant_id') - ->label('Tenant') + Select::make('managed_environment_id') + ->label('ManagedEnvironment') ->options(fn (): array => $this->getTenantOptions()) ->disableOptionWhen(fn (string $value): bool => array_key_exists((int) $value, $this->getTenantAssignmentSummaries())) ->required() @@ -103,18 +103,18 @@ private function assignTenantAction(): Action /** @var BaselineProfile $profile */ $profile = $this->getOwnerRecord(); - $tenantId = (int) $data['tenant_id']; + $tenantId = (int) $data['managed_environment_id']; $existing = BaselineTenantAssignment::query() ->where('workspace_id', $profile->workspace_id) - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->first(); if ($existing instanceof BaselineTenantAssignment) { $assignedBaselineName = $this->getAssignedBaselineNameForTenant($tenantId); Notification::make() - ->title('Tenant already assigned') + ->title('ManagedEnvironment already assigned') ->body($assignedBaselineName === null ? 'This tenant already has a baseline assignment in this workspace.' : "This tenant is already assigned to baseline: {$assignedBaselineName}.") @@ -126,7 +126,7 @@ private function assignTenantAction(): Action $assignment = BaselineTenantAssignment::create([ 'workspace_id' => (int) $profile->workspace_id, - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'baseline_profile_id' => (int) $profile->getKey(), 'assigned_by_user_id' => (int) $user->getKey(), ]); @@ -134,7 +134,7 @@ private function assignTenantAction(): Action $this->auditAssignment($profile, $assignment, $user, 'created'); Notification::make() - ->title('Tenant assigned') + ->title('ManagedEnvironment assigned') ->success() ->send(); @@ -190,11 +190,11 @@ private function getTenantOptions(): array $assignmentSummaries = $this->getTenantAssignmentSummaries(); - return Tenant::query() + return ManagedEnvironment::query() ->where('workspace_id', $profile->workspace_id) ->orderBy('name') ->get(['id', 'name']) - ->mapWithKeys(function (Tenant $tenant) use ($assignmentSummaries): array { + ->mapWithKeys(function (ManagedEnvironment $tenant) use ($assignmentSummaries): array { $tenantId = (int) $tenant->getKey(); $assignmentSummary = $assignmentSummaries[$tenantId] ?? null; @@ -220,12 +220,12 @@ private function getTenantAssignmentSummaries(): array $this->tenantAssignmentSummaries = BaselineTenantAssignment::query() ->where('workspace_id', (int) $profile->workspace_id) ->with('baselineProfile:id,name') - ->get(['tenant_id', 'baseline_profile_id']) + ->get(['managed_environment_id', 'baseline_profile_id']) ->mapWithKeys(function (BaselineTenantAssignment $assignment): array { $baselineProfile = $assignment->baselineProfile; return [ - (int) $assignment->tenant_id => [ + (int) $assignment->managed_environment_id => [ 'baseline_profile_id' => (int) $assignment->baseline_profile_id, 'baseline_profile_name' => $baselineProfile instanceof BaselineProfile ? (string) $baselineProfile->name @@ -242,7 +242,7 @@ private function getTenantAssignmentSummaries(): array * @param array{baseline_profile_id:int, baseline_profile_name:string}|null $assignmentSummary */ private function formatTenantOptionLabel( - Tenant $tenant, + ManagedEnvironment $tenant, ?array $assignmentSummary, ): string { $tenantName = (string) $tenant->name; @@ -282,7 +282,7 @@ private function auditAssignment( return; } - $tenant = Tenant::query()->find($assignment->tenant_id); + $tenant = ManagedEnvironment::query()->find($assignment->managed_environment_id); $auditLogger = app(WorkspaceAuditLogger::class); @@ -292,8 +292,8 @@ private function auditAssignment( context: [ 'baseline_profile_id' => (int) $profile->getKey(), 'baseline_profile_name' => (string) $profile->name, - 'tenant_id' => (int) $assignment->tenant_id, - 'tenant_name' => $tenant instanceof Tenant ? (string) $tenant->display_name : '—', + 'managed_environment_id' => (int) $assignment->managed_environment_id, + 'tenant_name' => $tenant instanceof ManagedEnvironment ? (string) $tenant->display_name : '—', ], actor: $user, resourceType: 'baseline_profile', diff --git a/apps/platform/app/Filament/Resources/EntraGroupResource.php b/apps/platform/app/Filament/Resources/EntraGroupResource.php index cc26b85f..cf43da3a 100644 --- a/apps/platform/app/Filament/Resources/EntraGroupResource.php +++ b/apps/platform/app/Filament/Resources/EntraGroupResource.php @@ -7,7 +7,7 @@ use App\Filament\Concerns\ScopesGlobalSearchToTenant; use App\Filament\Resources\EntraGroupResource\Pages; use App\Models\EntraGroup; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Badges\BadgeDomain; use App\Support\Badges\BadgeRenderer; use App\Support\Filament\TablePaginationProfiles; @@ -204,7 +204,7 @@ public static function resolveScopedRecordOrFail(int|string $key): Model public static function getGlobalSearchResultUrl(Model $record): string { - $tenant = $record instanceof EntraGroup && $record->tenant instanceof Tenant + $tenant = $record instanceof EntraGroup && $record->tenant instanceof ManagedEnvironment ? $record->tenant : static::panelTenantContext(); @@ -225,7 +225,7 @@ public static function getPages(): array public static function scopedUrl( string $page = 'index', array $parameters = [], - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?string $panel = null, ): string { $panelId = $panel ?? Filament::getCurrentOrDefaultPanel()?->getId() ?? 'admin'; diff --git a/apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php b/apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php index 354313f8..d816a248 100644 --- a/apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php +++ b/apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php @@ -3,7 +3,7 @@ namespace App\Filament\Resources\EntraGroupResource\Pages; use App\Filament\Resources\EntraGroupResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Directory\EntraGroupSyncService; use App\Support\Auth\Capabilities; @@ -30,7 +30,7 @@ public function mount(): void if ( Filament::getCurrentPanel()?->getId() === 'admin' - && ! EntraGroupResource::panelTenantContext() instanceof Tenant + && ! EntraGroupResource::panelTenantContext() instanceof ManagedEnvironment ) { abort(404); } @@ -47,7 +47,7 @@ protected function getHeaderActions(): array ->label('Operations') ->icon('heroicon-o-clock') ->url(fn (): string => OperationRunLinks::index($tenant)) - ->visible(fn (): bool => $tenant instanceof Tenant), + ->visible(fn (): bool => $tenant instanceof ManagedEnvironment), UiEnforcement::forAction( Action::make('sync_groups') ->label('Sync Groups') @@ -57,7 +57,7 @@ protected function getHeaderActions(): array $user = auth()->user(); $tenant = EntraGroupResource::panelTenantContext(); - if (! $user instanceof User || ! $tenant instanceof Tenant) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment) { return; } diff --git a/apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ViewEntraGroup.php b/apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ViewEntraGroup.php index cfd821fb..00cf8f11 100644 --- a/apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ViewEntraGroup.php +++ b/apps/platform/app/Filament/Resources/EntraGroupResource/Pages/ViewEntraGroup.php @@ -4,7 +4,7 @@ use App\Filament\Resources\EntraGroupResource; use App\Models\EntraGroup; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Filament\Resources\Pages\ViewRecord; @@ -27,16 +27,16 @@ protected function authorizeAccess(): void if ( Filament::getCurrentPanel()?->getId() === 'admin' - && ! $tenant instanceof Tenant + && ! $tenant instanceof ManagedEnvironment ) { abort(404); } - if (! $user instanceof User || ! $tenant instanceof Tenant || ! $record instanceof EntraGroup) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment || ! $record instanceof EntraGroup) { abort(404); } - if ((int) $record->tenant_id !== (int) $tenant->getKey()) { + if ((int) $record->managed_environment_id !== (int) $tenant->getKey()) { abort(404); } diff --git a/apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php b/apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php index dd345b3f..31e000c8 100644 --- a/apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php +++ b/apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php @@ -11,7 +11,7 @@ use App\Filament\Resources\ReviewPackResource; use App\Models\EvidenceSnapshot; use App\Models\EvidenceSnapshotItem; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Evidence\EvidenceSnapshotService; use App\Support\Auth\Capabilities; @@ -86,7 +86,7 @@ public static function canViewAny(): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -102,7 +102,7 @@ public static function canView(Model $record): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -111,7 +111,7 @@ public static function canView(Model $record): bool } return ! $record instanceof EvidenceSnapshot - || ((int) $record->tenant_id === (int) $tenant->getKey() && (int) $record->workspace_id === (int) $tenant->workspace_id); + || ((int) $record->managed_environment_id === (int) $tenant->getKey() && (int) $record->workspace_id === (int) $tenant->workspace_id); } public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration @@ -167,7 +167,7 @@ public static function infolist(Schema $schema): Schema ->color(BadgeRenderer::color(BadgeDomain::EvidenceCompleteness)) ->icon(BadgeRenderer::icon(BadgeDomain::EvidenceCompleteness)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::EvidenceCompleteness)), - TextEntry::make('tenant.name')->label('Tenant'), + TextEntry::make('tenant.name')->label('ManagedEnvironment'), TextEntry::make('generated_at')->dateTime()->placeholder('—'), TextEntry::make('expires_at')->dateTime()->placeholder('—'), TextEntry::make('operationRun.id') @@ -258,7 +258,7 @@ public static function relatedContextEntries(EvidenceSnapshot $record): array ->latest('created_at') ->first(); - if ($pack instanceof \App\Models\ReviewPack && $pack->tenant instanceof Tenant) { + if ($pack instanceof \App\Models\ReviewPack && $pack->tenant instanceof ManagedEnvironment) { $packUrl = ReviewPackResource::getUrl('view', ['record' => $pack], tenant: $pack->tenant); if (static::isCustomerWorkspaceFlow()) { @@ -278,7 +278,7 @@ public static function relatedContextEntries(EvidenceSnapshot $record): array )->toArray(); } - if ($record->tenant instanceof Tenant) { + if ($record->tenant instanceof ManagedEnvironment) { $entries[] = RelatedContextEntry::available( key: 'customer_review_workspace', label: 'Customer workspace', @@ -783,7 +783,7 @@ public static function executeGeneration(array $data): void $tenant = Filament::getTenant(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { Notification::make()->danger()->title('Unable to create snapshot — missing context.')->send(); return; diff --git a/apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php b/apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php index 900c582d..5e826ed8 100644 --- a/apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php +++ b/apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php @@ -7,7 +7,7 @@ use App\Filament\Resources\EvidenceSnapshotResource; use App\Filament\Pages\Reviews\CustomerReviewWorkspace; use App\Models\EvidenceSnapshot; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; use App\Services\Evidence\EvidenceSnapshotService; @@ -122,7 +122,7 @@ private function auditCustomerWorkspaceProofOpen(): void $tenant = $record->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } diff --git a/apps/platform/app/Filament/Resources/FindingExceptionResource.php b/apps/platform/app/Filament/Resources/FindingExceptionResource.php index 34885fb6..4fcdeb04 100644 --- a/apps/platform/app/Filament/Resources/FindingExceptionResource.php +++ b/apps/platform/app/Filament/Resources/FindingExceptionResource.php @@ -10,7 +10,7 @@ use App\Filament\Resources\FindingResource; use App\Models\FindingException; use App\Models\FindingExceptionEvidenceReference; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\WorkspaceCapabilityResolver; @@ -82,7 +82,7 @@ public static function canViewAny(): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -98,7 +98,7 @@ public static function canView(Model $record): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -107,7 +107,7 @@ public static function canView(Model $record): bool } return ! $record instanceof FindingException - || ((int) $record->tenant_id === (int) $tenant->getKey() && (int) $record->workspace_id === (int) $tenant->workspace_id); + || ((int) $record->managed_environment_id === (int) $tenant->getKey() && (int) $record->workspace_id === (int) $tenant->workspace_id); } public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration @@ -134,12 +134,12 @@ public static function exceptionStatsForCurrentTenant(): array { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return ['active' => 0, 'expiring' => 0, 'expired' => 0, 'pending' => 0, 'total' => 0]; } $counts = FindingException::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->selectRaw('count(*) as total') ->selectRaw("count(*) filter (where status = 'active') as active") @@ -191,7 +191,7 @@ public static function infolist(Schema $schema): Schema ->color(fn (FindingException $record): string => static::governanceWarningColor($record)) ->columnSpanFull() ->visible(fn (FindingException $record): bool => static::governanceWarning($record) !== null), - TextEntry::make('tenant.name')->label('Tenant'), + TextEntry::make('tenant.name')->label('ManagedEnvironment'), TextEntry::make('finding_summary') ->label('Finding') ->state(fn (FindingException $record): string => static::findingSummary($record)), @@ -264,7 +264,7 @@ public static function relatedContextEntries(FindingException $record): array { $entries = []; - if ($record->finding && $record->tenant instanceof Tenant) { + if ($record->finding && $record->tenant instanceof ManagedEnvironment) { $entries[] = RelatedContextEntry::available( key: 'finding', label: 'Finding', @@ -278,7 +278,7 @@ public static function relatedContextEntries(FindingException $record): array )->toArray(); } - if ($record->tenant instanceof Tenant && static::canAccessApprovalQueueForTenant($record->tenant)) { + if ($record->tenant instanceof ManagedEnvironment && static::canAccessApprovalQueueForTenant($record->tenant)) { $entries[] = RelatedContextEntry::available( key: 'approval_queue', label: 'Approval queue', @@ -428,7 +428,7 @@ public static function table(Table $table): Table ->action(function (FindingException $record, array $data, FindingExceptionService $service): void { $user = auth()->user(); - if (! $user instanceof User || ! $record->tenant instanceof Tenant) { + if (! $user instanceof User || ! $record->tenant instanceof ManagedEnvironment) { abort(404); } @@ -532,13 +532,13 @@ private static function tenantMemberOptions(): array { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } - return \App\Models\TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) - ->join('users', 'users.id', '=', 'tenant_memberships.user_id') + return \App\Models\ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) + ->join('users', 'users.id', '=', 'managed_environment_memberships.user_id') ->orderBy('users.name') ->pluck('users.name', 'users.id') ->mapWithKeys(fn (string $name, int|string $id): array => [(int) $id => $name]) @@ -608,7 +608,7 @@ private static function canManageRecord(FindingException $record): bool $user = auth()->user(); return $user instanceof User - && $record->tenant instanceof Tenant + && $record->tenant instanceof ManagedEnvironment && $user->canAccessTenant($record->tenant) && $user->can(Capabilities::FINDING_EXCEPTION_MANAGE, $record->tenant); } @@ -643,12 +643,12 @@ private static function governanceWarningColor(FindingException $record): string return 'danger'; } - public static function canAccessApprovalQueueForTenant(?Tenant $tenant = null): bool + public static function canAccessApprovalQueueForTenant(?ManagedEnvironment $tenant = null): bool { $tenant ??= static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -665,11 +665,11 @@ public static function canAccessApprovalQueueForTenant(?Tenant $tenant = null): && $resolver->can($user, $workspace, Capabilities::FINDING_EXCEPTION_APPROVE); } - public static function approvalQueueUrl(?Tenant $tenant = null): ?string + public static function approvalQueueUrl(?ManagedEnvironment $tenant = null): ?string { $tenant ??= static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } diff --git a/apps/platform/app/Filament/Resources/FindingExceptionResource/Pages/ViewFindingException.php b/apps/platform/app/Filament/Resources/FindingExceptionResource/Pages/ViewFindingException.php index 5a65a07a..22de0e24 100644 --- a/apps/platform/app/Filament/Resources/FindingExceptionResource/Pages/ViewFindingException.php +++ b/apps/platform/app/Filament/Resources/FindingExceptionResource/Pages/ViewFindingException.php @@ -6,7 +6,7 @@ use App\Filament\Resources\FindingExceptionResource; use App\Models\FindingException; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Findings\FindingExceptionService; use App\Support\Auth\Capabilities; @@ -198,13 +198,13 @@ private function tenantMemberOptions(): array $tenant = $record->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } - return \App\Models\TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) - ->join('users', 'users.id', '=', 'tenant_memberships.user_id') + return \App\Models\ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) + ->join('users', 'users.id', '=', 'managed_environment_memberships.user_id') ->orderBy('users.name') ->pluck('users.name', 'users.id') ->mapWithKeys(fn (string $name, int|string $id): array => [(int) $id => $name]) @@ -217,7 +217,7 @@ private function canManageRecord(): bool $user = auth()->user(); return $record instanceof FindingException - && $record->tenant instanceof Tenant + && $record->tenant instanceof ManagedEnvironment && $user instanceof User && $user->canAccessTenant($record->tenant) && $user->can(Capabilities::FINDING_EXCEPTION_MANAGE, $record->tenant); diff --git a/apps/platform/app/Filament/Resources/FindingResource.php b/apps/platform/app/Filament/Resources/FindingResource.php index bf92c24e..ec0996af 100644 --- a/apps/platform/app/Filament/Resources/FindingResource.php +++ b/apps/platform/app/Filament/Resources/FindingResource.php @@ -9,8 +9,8 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\PolicyVersion; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Services\Drift\DriftFindingDiffBuilder; use App\Services\Findings\FindingExceptionService; @@ -110,7 +110,7 @@ public static function canViewAny(): bool $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -127,7 +127,7 @@ public static function canView(Model $record): bool $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -140,7 +140,7 @@ public static function canView(Model $record): bool } if ($record instanceof Finding) { - return (int) $record->tenant_id === (int) $tenant->getKey() + return (int) $record->managed_environment_id === (int) $tenant->getKey() && (int) $record->workspace_id === (int) $tenant->workspace_id; } @@ -679,17 +679,17 @@ private static function driftDiffUnavailableMessage(Finding $record): string /** * @return array{0: ?PolicyVersion, 1: ?PolicyVersion} */ - private static function resolveDriftDiffVersions(Finding $record, Tenant $tenant): array + private static function resolveDriftDiffVersions(Finding $record, ManagedEnvironment $tenant): array { $baselineId = Arr::get($record->evidence_jsonb ?? [], 'baseline.policy_version_id'); $currentId = Arr::get($record->evidence_jsonb ?? [], 'current.policy_version_id'); $baselineVersion = is_numeric($baselineId) - ? PolicyVersion::query()->where('tenant_id', $tenant->getKey())->find((int) $baselineId) + ? PolicyVersion::query()->where('managed_environment_id', $tenant->getKey())->find((int) $baselineId) : null; $currentVersion = is_numeric($currentId) - ? PolicyVersion::query()->where('tenant_id', $tenant->getKey())->find((int) $currentId) + ? PolicyVersion::query()->where('managed_environment_id', $tenant->getKey())->find((int) $currentId) : null; return [$baselineVersion, $currentVersion]; @@ -974,7 +974,7 @@ public static function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } @@ -989,7 +989,7 @@ public static function table(Table $table): Table continue; } - if ((int) $record->tenant_id !== (int) $tenant->getKey()) { + if ((int) $record->managed_environment_id !== (int) $tenant->getKey()) { $skippedCount++; continue; @@ -1057,7 +1057,7 @@ public static function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } @@ -1076,7 +1076,7 @@ public static function table(Table $table): Table continue; } - if ((int) $record->tenant_id !== (int) $tenant->getKey()) { + if ((int) $record->managed_environment_id !== (int) $tenant->getKey()) { $skippedCount++; continue; @@ -1149,7 +1149,7 @@ public static function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } @@ -1166,7 +1166,7 @@ public static function table(Table $table): Table continue; } - if ((int) $record->tenant_id !== (int) $tenant->getKey()) { + if ((int) $record->managed_environment_id !== (int) $tenant->getKey()) { $skippedCount++; continue; @@ -1228,7 +1228,7 @@ public static function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } @@ -1245,7 +1245,7 @@ public static function table(Table $table): Table continue; } - if ((int) $record->tenant_id !== (int) $tenant->getKey()) { + if ((int) $record->managed_environment_id !== (int) $tenant->getKey()) { $skippedCount++; continue; @@ -1369,9 +1369,9 @@ private static function findingRunNavigationContext(Finding $record): CanonicalN tenantId: $tenant?->getKey(), backLinkLabel: 'Back to finding', backLinkUrl: static::getUrl('view', ['record' => $record], tenant: $tenant), - filterPayload: $tenant instanceof Tenant ? [ + filterPayload: $tenant instanceof ManagedEnvironment ? [ 'tableFilters' => [ - 'tenant_id' => ['value' => (string) $tenant->getKey()], + 'managed_environment_id' => ['value' => (string) $tenant->getKey()], ], ] : [], ); @@ -1418,7 +1418,7 @@ public static function triageAction(): Actions\Action static::runWorkflowMutation( record: $record, successTitle: 'Finding triaged', - callback: fn (Finding $finding, Tenant $tenant, User $user): Finding => $workflow->triage($finding, $tenant, $user), + callback: fn (Finding $finding, ManagedEnvironment $tenant, User $user): Finding => $workflow->triage($finding, $tenant, $user), ); }) ) @@ -1442,7 +1442,7 @@ public static function startProgressAction(): Actions\Action static::runWorkflowMutation( record: $record, successTitle: 'Finding moved to in progress', - callback: fn (Finding $finding, Tenant $tenant, User $user): Finding => $workflow->startProgress($finding, $tenant, $user), + callback: fn (Finding $finding, ManagedEnvironment $tenant, User $user): Finding => $workflow->startProgress($finding, $tenant, $user), ); }) ) @@ -1514,7 +1514,7 @@ public static function resolveAction(): Actions\Action static::runWorkflowMutation( record: $record, successTitle: $rule->successTitle, - callback: fn (Finding $finding, Tenant $tenant, User $user): Finding => $workflow->resolve( + callback: fn (Finding $finding, ManagedEnvironment $tenant, User $user): Finding => $workflow->resolve( $finding, $tenant, $user, @@ -1555,7 +1555,7 @@ public static function closeAction(): Actions\Action static::runWorkflowMutation( record: $record, successTitle: $rule->successTitle, - callback: fn (Finding $finding, Tenant $tenant, User $user): Finding => $workflow->close( + callback: fn (Finding $finding, ManagedEnvironment $tenant, User $user): Finding => $workflow->close( $finding, $tenant, $user, @@ -1760,7 +1760,7 @@ public static function reopenAction(): Actions\Action static::runWorkflowMutation( record: $record, successTitle: $rule->successTitle, - callback: fn (Finding $finding, Tenant $tenant, User $user): Finding => $workflow->reopen( + callback: fn (Finding $finding, ManagedEnvironment $tenant, User $user): Finding => $workflow->reopen( $finding, $tenant, $user, @@ -1776,7 +1776,7 @@ public static function reopenAction(): Actions\Action } /** - * @param callable(Finding, Tenant, User): Finding $callback + * @param callable(Finding, ManagedEnvironment, User): Finding $callback */ private static function runWorkflowMutation(Finding $record, string $successTitle, callable $callback): void { @@ -1785,11 +1785,11 @@ private static function runWorkflowMutation(Finding $record, string $successTitl $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } - if ((int) $record->tenant_id !== (int) $tenant->getKey()) { + if ((int) $record->managed_environment_id !== (int) $tenant->getKey()) { Notification::make() ->title('Finding belongs to a different tenant') ->danger() @@ -1837,11 +1837,11 @@ private static function runResponsibilityMutation(Finding $record, array $data, $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } - if ((int) $record->tenant_id !== (int) $tenant->getKey()) { + if ((int) $record->managed_environment_id !== (int) $tenant->getKey()) { Notification::make() ->title('Finding belongs to a different tenant') ->danger() @@ -1906,7 +1906,7 @@ private static function runExceptionRequestMutation(Finding $record, array $data $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } @@ -1942,7 +1942,7 @@ private static function runExceptionRenewalMutation(Finding $record, array $data $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } @@ -1978,7 +1978,7 @@ private static function runExceptionRevocationMutation(Finding $record, array $d $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } @@ -2074,7 +2074,7 @@ private static function resolveCurrentFindingExceptionOrFail(Finding $record): F return $exception; } - private static function findingExceptionViewUrl(\App\Models\FindingException $exception, Tenant $tenant): string + private static function findingExceptionViewUrl(\App\Models\FindingException $exception, ManagedEnvironment $tenant): string { $panelId = Filament::getCurrentPanel()?->getId(); @@ -2388,13 +2388,13 @@ private static function tenantMemberOptions(): array { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } - return TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) - ->join('users', 'users.id', '=', 'tenant_memberships.user_id') + return ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) + ->join('users', 'users.id', '=', 'managed_environment_memberships.user_id') ->orderBy('users.name') ->pluck('users.name', 'users.id') ->mapWithKeys(fn (string $name, int|string $id): array => [(int) $id => $name]) @@ -2408,14 +2408,14 @@ public static function findingStatsForCurrentTenant(): array { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return ['open' => 0, 'overdue' => 0, 'high_severity' => 0, 'risk_accepted' => 0, 'total' => 0]; } $now = now()->toDateTimeString(); $counts = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->selectRaw('count(*) as total') ->selectRaw("sum(case when status in ('new', 'triaged', 'in_progress', 'reopened') then 1 else 0 end) as open") ->selectRaw("sum(case when status in ('new', 'triaged', 'in_progress', 'reopened') and due_at is not null and due_at < ? then 1 else 0 end) as overdue", [$now]) diff --git a/apps/platform/app/Filament/Resources/FindingResource/Pages/ListFindings.php b/apps/platform/app/Filament/Resources/FindingResource/Pages/ListFindings.php index 633920ea..b1519a1b 100644 --- a/apps/platform/app/Filament/Resources/FindingResource/Pages/ListFindings.php +++ b/apps/platform/app/Filament/Resources/FindingResource/Pages/ListFindings.php @@ -7,7 +7,7 @@ use App\Filament\Widgets\Tenant\BaselineCompareCoverageBanner; use App\Filament\Widgets\Tenant\FindingStatsOverview; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Findings\FindingWorkflowService; use App\Support\Auth\Capabilities; @@ -152,7 +152,7 @@ protected function getHeaderActions(): array abort(403); } - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } diff --git a/apps/platform/app/Filament/Resources/InventoryItemResource.php b/apps/platform/app/Filament/Resources/InventoryItemResource.php index db81bca3..aca7d434 100644 --- a/apps/platform/app/Filament/Resources/InventoryItemResource.php +++ b/apps/platform/app/Filament/Resources/InventoryItemResource.php @@ -7,7 +7,7 @@ use App\Filament\Concerns\ResolvesPanelTenantContext; use App\Filament\Resources\InventoryItemResource\Pages; use App\Models\InventoryItem; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -76,7 +76,7 @@ public static function canViewAny(): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -91,7 +91,7 @@ public static function canView(Model $record): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -106,7 +106,7 @@ public static function canView(Model $record): bool } if ($record instanceof InventoryItem) { - return (int) $record->tenant_id === (int) $tenant->getKey(); + return (int) $record->managed_environment_id === (int) $tenant->getKey(); } return true; @@ -151,7 +151,7 @@ public static function infolist(Schema $schema): Schema $tenant = $record->tenant; - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return OperationRunLinks::view((int) $record->last_seen_operation_run_id, $tenant); } diff --git a/apps/platform/app/Filament/Resources/InventoryItemResource/Pages/ListInventoryItems.php b/apps/platform/app/Filament/Resources/InventoryItemResource/Pages/ListInventoryItems.php index 968fcf4a..1a6f5c3a 100644 --- a/apps/platform/app/Filament/Resources/InventoryItemResource/Pages/ListInventoryItems.php +++ b/apps/platform/app/Filament/Resources/InventoryItemResource/Pages/ListInventoryItems.php @@ -6,7 +6,7 @@ use App\Filament\Resources\InventoryItemResource; use App\Filament\Widgets\Inventory\InventoryKpiHeader; use App\Jobs\RunInventorySyncJob; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Intune\AuditLogger; use App\Services\Inventory\InventorySyncService; @@ -49,7 +49,7 @@ public function mount(): void $tenant = static::resolveTenantContextForCurrentPanel(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { app(WorkspaceContext::class)->rememberTenantContext($tenant, request()); } @@ -128,7 +128,7 @@ protected function getHeaderActions(): array ->dehydrated() ->rules(['boolean']) ->columnSpanFull(), - Hidden::make('tenant_id') + Hidden::make('managed_environment_id') ->default(fn (): ?string => static::resolveTenantContextForCurrentPanel()?->getKey()) ->dehydrated(), ]) @@ -139,7 +139,7 @@ protected function getHeaderActions(): array } $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return false; } @@ -149,11 +149,11 @@ protected function getHeaderActions(): array $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } - $requestedTenantId = $data['tenant_id'] ?? null; + $requestedTenantId = $data['managed_environment_id'] ?? null; if ($requestedTenantId !== null && (int) $requestedTenantId !== (int) $tenant->getKey()) { Notification::make() ->title('Not allowed') diff --git a/apps/platform/app/Filament/Resources/InventoryItemResource/Pages/ViewInventoryItem.php b/apps/platform/app/Filament/Resources/InventoryItemResource/Pages/ViewInventoryItem.php index d4c77849..68b5b66c 100644 --- a/apps/platform/app/Filament/Resources/InventoryItemResource/Pages/ViewInventoryItem.php +++ b/apps/platform/app/Filament/Resources/InventoryItemResource/Pages/ViewInventoryItem.php @@ -4,7 +4,7 @@ use App\Filament\Concerns\ResolvesPanelTenantContext; use App\Filament\Resources\InventoryItemResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Resources\Pages\ViewRecord; use Illuminate\Database\Eloquent\Model; @@ -19,7 +19,7 @@ public function mount(int|string $record): void { $tenant = static::resolveTenantContextForCurrentPanel(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { app(WorkspaceContext::class)->rememberTenantContext($tenant, request()); } diff --git a/apps/platform/app/Filament/Resources/OperationRunResource.php b/apps/platform/app/Filament/Resources/OperationRunResource.php index e3cf6469..d46737dd 100644 --- a/apps/platform/app/Filament/Resources/OperationRunResource.php +++ b/apps/platform/app/Filament/Resources/OperationRunResource.php @@ -6,7 +6,7 @@ use App\Filament\Support\VerificationReportViewer; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\VerificationCheckAcknowledgement; use App\Support\Badges\BadgeCatalog; @@ -175,8 +175,8 @@ public static function table(Table $table): Table ->description(fn (OperationRun $record): ?string => static::surfaceGuidance($record)), ]) ->filters([ - Tables\Filters\SelectFilter::make('tenant_id') - ->label('Tenant') + Tables\Filters\SelectFilter::make('managed_environment_id') + ->label('ManagedEnvironment') ->options(function (): array { $user = auth()->user(); @@ -185,7 +185,7 @@ public static function table(Table $table): Table } return collect($user->getTenants(Filament::getCurrentOrDefaultPanel())) - ->mapWithKeys(static fn (Tenant $tenant): array => [ + ->mapWithKeys(static fn (ManagedEnvironment $tenant): array => [ (string) $tenant->getKey() => $tenant->getFilamentName(), ]) ->all(); @@ -193,7 +193,7 @@ public static function table(Table $table): Table ->default(function (): ?string { $activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request()); - if (! $activeTenant instanceof Tenant) { + if (! $activeTenant instanceof ManagedEnvironment) { return null; } @@ -278,7 +278,7 @@ private static function enterpriseDetailPage(OperationRun $record): \App\Support $outcomeSpec = BadgeRenderer::spec(BadgeDomain::OperationRunOutcome, static::outcomeBadgeState($record)); $targetScope = static::targetScopeDisplay($record) ?? 'No target scope details were recorded for this operation.'; $summaryLine = \App\Support\OpsUx\SummaryCountsNormalizer::renderSummaryLine(is_array($record->summary_counts) ? $record->summary_counts : []); - $referencedTenantLifecycle = $record->tenant instanceof Tenant + $referencedTenantLifecycle = $record->tenant instanceof ManagedEnvironment ? ReferencedTenantLifecyclePresentation::forOperationRun($record->tenant) : null; $artifactTruth = static::artifactTruthEnvelope($record); @@ -520,7 +520,7 @@ private static function enterpriseDetailPage(OperationRun $record): \App\Support entries: [ $factory->keyFact('Identity hash', $record->run_identity_hash, mono: true), $factory->keyFact('Workspace scope', $record->workspace_id), - $factory->keyFact('Tenant scope', $record->tenant_id), + $factory->keyFact('ManagedEnvironment scope', $record->managed_environment_id), ], description: 'Stored run context stays available for debugging without dominating the default reading path.', view: 'filament.infolists.entries.snapshot-json', @@ -620,7 +620,7 @@ private static function supportingGroups( $lifecycleItems = array_values(array_filter([ $referencedTenantLifecycle !== null ? $factory->keyFact( - 'Tenant lifecycle', + 'ManagedEnvironment lifecycle', $referencedTenantLifecycle->presentation->label, badge: $factory->statusBadge( $referencedTenantLifecycle->presentation->label, @@ -631,7 +631,7 @@ private static function supportingGroups( ) : null, $referencedTenantLifecycle?->selectorAvailabilityMessage() !== null - ? $factory->keyFact('Tenant selector context', $referencedTenantLifecycle->selectorAvailabilityMessage()) + ? $factory->keyFact('ManagedEnvironment selector context', $referencedTenantLifecycle->selectorAvailabilityMessage()) : null, $referencedTenantLifecycle?->contextNote !== null ? $factory->keyFact('Viewer context', $referencedTenantLifecycle->contextNote) @@ -1266,13 +1266,13 @@ private static function verificationReportViewData(OperationRun $record): array if ($changeIndicator !== null) { $tenant = app(OperateHubShell::class)->activeEntitledTenant(request()); - $previousRunUrl = $tenant instanceof Tenant + $previousRunUrl = $tenant instanceof ManagedEnvironment ? OperationRunLinks::view($changeIndicator['previous_report_id'], $tenant) : OperationRunLinks::tenantlessView($changeIndicator['previous_report_id']); } $acknowledgements = VerificationCheckAcknowledgement::query() - ->where('tenant_id', (int) ($record->tenant_id ?? 0)) + ->where('managed_environment_id', (int) ($record->managed_environment_id ?? 0)) ->where('workspace_id', (int) ($record->workspace_id ?? 0)) ->where('operation_run_id', (int) $record->getKey()) ->with('acknowledgedByUser') @@ -1605,7 +1605,7 @@ public static function restoreContinuation(OperationRun $record): ?array $attention = app(RestoreSafetyResolver::class)->resultAttentionForRun($restoreRun); $tenant = $record->tenant; $user = auth()->user(); - $canOpenRestore = $tenant instanceof Tenant + $canOpenRestore = $tenant instanceof ManagedEnvironment && $user instanceof User && app(\App\Services\Auth\CapabilityResolver::class)->isMember($user, $tenant); diff --git a/apps/platform/app/Filament/Resources/PolicyResource.php b/apps/platform/app/Filament/Resources/PolicyResource.php index 1869379f..73b1ae9a 100644 --- a/apps/platform/app/Filament/Resources/PolicyResource.php +++ b/apps/platform/app/Filament/Resources/PolicyResource.php @@ -13,7 +13,7 @@ use App\Jobs\BulkPolicyUnignoreJob; use App\Jobs\SyncPoliciesJob; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Intune\PolicyNormalizer; @@ -96,7 +96,7 @@ public static function canViewAny(): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -132,7 +132,7 @@ public static function makeSyncAction(string $name = 'sync'): Actions\Action $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $user instanceof User || ! $tenant instanceof Tenant) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -533,7 +533,7 @@ public static function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -565,7 +565,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'policy.export', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $user, $ids, $data): void { @@ -610,7 +610,7 @@ public static function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -722,7 +722,7 @@ public static function table(Table $table): Table $count = $records->count(); $ids = $records->pluck('id')->toArray(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -756,7 +756,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'policy.export', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $user, $ids, $data, $count): void { @@ -816,7 +816,7 @@ public static function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -889,7 +889,7 @@ public static function table(Table $table): Table $count = $records->count(); $ids = $records->pluck('id')->toArray(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -909,7 +909,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'policy.unignore', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $user, $ids, $count): void { @@ -985,7 +985,7 @@ public static function table(Table $table): Table $count = $records->count(); $ids = $records->pluck('id')->toArray(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } @@ -1001,7 +1001,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'policy.delete', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $user, $ids): void { diff --git a/apps/platform/app/Filament/Resources/PolicyResource/Pages/ViewPolicy.php b/apps/platform/app/Filament/Resources/PolicyResource/Pages/ViewPolicy.php index dbc27ae3..ede9387f 100644 --- a/apps/platform/app/Filament/Resources/PolicyResource/Pages/ViewPolicy.php +++ b/apps/platform/app/Filament/Resources/PolicyResource/Pages/ViewPolicy.php @@ -97,7 +97,7 @@ private function makeCaptureSnapshotAction(): Action tenant: $tenant, type: 'policy.capture_snapshot', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $policy, $user, $includeAssignments, $includeScopeTags): void { diff --git a/apps/platform/app/Filament/Resources/PolicyResource/RelationManagers/VersionsRelationManager.php b/apps/platform/app/Filament/Resources/PolicyResource/RelationManagers/VersionsRelationManager.php index 0ddffb09..ed1829cb 100644 --- a/apps/platform/app/Filament/Resources/PolicyResource/RelationManagers/VersionsRelationManager.php +++ b/apps/platform/app/Filament/Resources/PolicyResource/RelationManagers/VersionsRelationManager.php @@ -7,7 +7,7 @@ use App\Filament\Resources\RestoreRunResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Intune\RestoreService; @@ -75,7 +75,7 @@ public function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { Notification::make() ->title($this->text('relation.missing_context_title')) ->danger() @@ -84,7 +84,7 @@ public function table(Table $table): Table return; } - if ($record->tenant_id !== $tenant->id) { + if ($record->managed_environment_id !== $tenant->id) { Notification::make() ->title($this->text('versions.different_tenant_title')) ->danger() @@ -132,7 +132,7 @@ public function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return true; } @@ -152,7 +152,7 @@ public function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return null; } @@ -205,7 +205,7 @@ private function resolveOwnerScopedVersionRecord(Policy $policy, mixed $record): } $resolvedRecord = $policy->versions() - ->where('tenant_id', (int) $policy->tenant_id) + ->where('managed_environment_id', (int) $policy->managed_environment_id) ->whereKey($recordId) ->first(); diff --git a/apps/platform/app/Filament/Resources/PolicyVersionResource.php b/apps/platform/app/Filament/Resources/PolicyVersionResource.php index 33d2e1d5..ece11ea3 100644 --- a/apps/platform/app/Filament/Resources/PolicyVersionResource.php +++ b/apps/platform/app/Filament/Resources/PolicyVersionResource.php @@ -14,7 +14,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Intune\AuditLogger; @@ -94,7 +94,7 @@ public static function canViewAny(): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -321,7 +321,7 @@ public static function table(Table $table): Table $retentionDays = (int) ($data['retention_days'] ?? 90); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -342,7 +342,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'policy_version.prune', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $initiator, $ids, $retentionDays): void { @@ -398,7 +398,7 @@ public static function table(Table $table): Table $count = $records->count(); $ids = $records->pluck('id')->toArray(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -419,7 +419,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'policy_version.restore', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $initiator, $ids): void { @@ -482,7 +482,7 @@ public static function table(Table $table): Table $count = $records->count(); $ids = $records->pluck('id')->toArray(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -503,7 +503,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'policy_version.force_delete', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $initiator, $ids): void { @@ -607,7 +607,7 @@ public static function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -624,7 +624,7 @@ public static function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return true; } @@ -641,7 +641,7 @@ public static function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return null; } @@ -666,7 +666,7 @@ public static function table(Table $table): Table $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { abort(403); } @@ -691,7 +691,7 @@ public static function table(Table $table): Table return; } - if (! $tenant || $record->tenant_id !== $tenant->id) { + if (! $tenant || $record->managed_environment_id !== $tenant->id) { Notification::make() ->title(static::text('versions.different_tenant_title')) ->danger() @@ -712,7 +712,7 @@ public static function table(Table $table): Table } $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => static::text('versions.backup_set_name', [ 'policy' => $policy->display_name, 'version' => $record->version_number, @@ -770,7 +770,7 @@ public static function table(Table $table): Table } $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_version_id' => $record->id, @@ -803,7 +803,7 @@ public static function table(Table $table): Table $user = auth()->user(); $tenant = $record->tenant; - if (! $user instanceof User || ! $tenant instanceof Tenant) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment) { abort(403); } @@ -845,7 +845,7 @@ public static function table(Table $table): Table $user = auth()->user(); $tenant = $record->tenant; - if (! $user instanceof User || ! $tenant instanceof Tenant) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment) { abort(403); } @@ -888,7 +888,7 @@ public static function table(Table $table): Table $user = auth()->user(); $tenant = $record->tenant; - if (! $user instanceof User || ! $tenant instanceof Tenant) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment) { abort(403); } diff --git a/apps/platform/app/Filament/Resources/ProviderConnectionResource.php b/apps/platform/app/Filament/Resources/ProviderConnectionResource.php index 7abe627e..67bf2588 100644 --- a/apps/platform/app/Filament/Resources/ProviderConnectionResource.php +++ b/apps/platform/app/Filament/Resources/ProviderConnectionResource.php @@ -8,7 +8,7 @@ use App\Jobs\ProviderInventorySyncJob; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Intune\AuditLogger; @@ -99,7 +99,7 @@ public static function canCreate(): bool $tenant = static::resolveTenantForCreate(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -115,7 +115,7 @@ protected static function hasTenantCapability(string $capability): bool $tenant = static::resolveScopedTenant(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -126,7 +126,7 @@ protected static function hasTenantCapability(string $capability): bool && $resolver->can($user, $tenant, $capability); } - protected static function resolveScopedTenant(): ?Tenant + protected static function resolveScopedTenant(): ?ManagedEnvironment { $tenantExternalId = static::resolveRequestedTenantExternalId(); @@ -136,19 +136,19 @@ protected static function resolveScopedTenant(): ?Tenant $routeTenant = request()->route('tenant'); - if ($routeTenant instanceof Tenant) { + if ($routeTenant instanceof ManagedEnvironment) { return $routeTenant; } if (is_string($routeTenant) && $routeTenant !== '') { - return Tenant::query() - ->where('external_id', $routeTenant) + return ManagedEnvironment::query() + ->where('slug', $routeTenant) ->first(); } $recordTenant = static::resolveTenantFromRouteRecord(); - if ($recordTenant instanceof Tenant) { + if ($recordTenant instanceof ManagedEnvironment) { return $recordTenant; } @@ -161,16 +161,16 @@ protected static function resolveScopedTenant(): ?Tenant return static::resolveTenantContextForCurrentPanel(); } - public static function resolveTenantForRecord(?ProviderConnection $record = null): ?Tenant + public static function resolveTenantForRecord(?ProviderConnection $record = null): ?ManagedEnvironment { if ($record instanceof ProviderConnection) { $tenant = $record->tenant; - if (! $tenant instanceof Tenant && is_numeric($record->tenant_id)) { - $tenant = Tenant::query()->whereKey((int) $record->tenant_id)->first(); + if (! $tenant instanceof ManagedEnvironment && is_numeric($record->managed_environment_id)) { + $tenant = ManagedEnvironment::query()->whereKey((int) $record->managed_environment_id)->first(); } - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return $tenant; } } @@ -180,7 +180,7 @@ public static function resolveTenantForRecord(?ProviderConnection $record = null public static function resolveRequestedTenantExternalId(): ?string { - $queryTenant = request()->query('tenant_id'); + $queryTenant = request()->query('managed_environment_id'); if (is_string($queryTenant) && $queryTenant !== '') { return $queryTenant; @@ -195,26 +195,26 @@ public static function resolveContextTenantExternalId(): ?string $contextTenantId = app(WorkspaceContext::class)->lastTenantId(request()); if ($workspaceId !== null && $contextTenantId !== null) { - $tenant = Tenant::query() + $tenant = ManagedEnvironment::query() ->whereKey($contextTenantId) ->where('workspace_id', (int) $workspaceId) ->first(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return (string) $tenant->external_id; } } $tenant = static::resolveTenantContextForCurrentPanel(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return (string) $tenant->external_id; } return null; } - public static function resolveTenantForCreate(): ?Tenant + public static function resolveTenantForCreate(): ?ManagedEnvironment { $tenantExternalId = static::resolveRequestedTenantExternalId() ?? static::resolveContextTenantExternalId(); @@ -226,7 +226,7 @@ public static function resolveTenantForCreate(): ?Tenant $user = auth()->user(); $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); - if (! $tenant instanceof Tenant || ! $user instanceof User || $workspaceId === null) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User || $workspaceId === null) { return null; } @@ -277,7 +277,7 @@ private static function extractTenantExternalIdFromUrl(string $url): ?string if (is_string($query) && $query !== '') { parse_str($query, $queryParams); - $tenantExternalId = $queryParams['tenant_id'] ?? null; + $tenantExternalId = $queryParams['managed_environment_id'] ?? null; if (is_string($tenantExternalId) && $tenantExternalId !== '') { return $tenantExternalId; @@ -297,18 +297,18 @@ private static function extractTenantExternalIdFromUrl(string $url): ?string return (string) $matches[1]; } - private static function resolveTenantByExternalId(?string $externalId): ?Tenant + private static function resolveTenantByExternalId(?string $externalId): ?ManagedEnvironment { if (! is_string($externalId) || $externalId === '') { return null; } - return Tenant::query() - ->where('external_id', $externalId) + return ManagedEnvironment::query() + ->where('slug', $externalId) ->first(); } - private static function resolveTenantFromRouteRecord(): ?Tenant + private static function resolveTenantFromRouteRecord(): ?ManagedEnvironment { $record = request()->route('record'); @@ -340,7 +340,7 @@ private static function applyMembershipScope(Builder $query): Builder if (! is_int($workspaceId)) { $tenant = static::resolveTenantContextForCurrentPanel(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $workspaceId = (int) $tenant->workspace_id; } } @@ -354,12 +354,12 @@ private static function applyMembershipScope(Builder $query): Builder ->whereExists(function ($membershipScope) use ($user, $workspaceId): void { $membershipScope ->selectRaw('1') - ->from('tenants as scoped_tenants') - ->join('tenant_memberships as scoped_memberships', function (JoinClause $join) use ($user): void { - $join->on('scoped_memberships.tenant_id', '=', 'scoped_tenants.id') + ->from('managed_environments as scoped_tenants') + ->join('managed_environment_memberships as scoped_memberships', function (JoinClause $join) use ($user): void { + $join->on('scoped_memberships.managed_environment_id', '=', 'scoped_tenants.id') ->where('scoped_memberships.user_id', '=', (int) $user->getKey()); }) - ->whereColumn('scoped_tenants.id', 'provider_connections.tenant_id') + ->whereColumn('scoped_tenants.id', 'provider_connections.managed_environment_id') ->where('scoped_tenants.workspace_id', '=', $workspaceId); }); } @@ -376,16 +376,16 @@ private static function tenantFilterOptions(): array return []; } - return Tenant::query() - ->select(['tenants.external_id', 'tenants.name', 'tenants.environment']) - ->join('tenant_memberships as filter_memberships', function (JoinClause $join) use ($user): void { - $join->on('filter_memberships.tenant_id', '=', 'tenants.id') + return ManagedEnvironment::query() + ->select(['managed_environments.slug', 'managed_environments.name', 'managed_environments.kind']) + ->join('managed_environment_memberships as filter_memberships', function (JoinClause $join) use ($user): void { + $join->on('filter_memberships.managed_environment_id', '=', 'managed_environments.id') ->where('filter_memberships.user_id', '=', (int) $user->getKey()); }) - ->where('tenants.workspace_id', $workspaceId) - ->orderBy('tenants.name') + ->where('managed_environments.workspace_id', $workspaceId) + ->orderBy('managed_environments.name') ->get() - ->mapWithKeys(function (Tenant $tenant): array { + ->mapWithKeys(function (ManagedEnvironment $tenant): array { $environment = strtoupper((string) ($tenant->environment ?? '')); $label = $environment !== '' ? "{$tenant->name} ({$environment})" : (string) $tenant->name; @@ -712,7 +712,7 @@ public static function table(Table $table): Table } return $query->whereHas('tenant', function (Builder $tenantQuery) use ($tenantExternalId): void { - $tenantQuery->where('external_id', $tenantExternalId); + $tenantQuery->where('slug', $tenantExternalId); }); }) ->defaultSort('display_name') @@ -723,7 +723,7 @@ public static function table(Table $table): Table ->recordUrl(fn (ProviderConnection $record): string => static::getUrl('view', ['record' => $record])) ->columns([ Tables\Columns\TextColumn::make('tenant.name') - ->label('Tenant') + ->label('ManagedEnvironment') ->description(function (ProviderConnection $record): ?string { $environment = $record->tenant?->environment; @@ -736,7 +736,7 @@ public static function table(Table $table): Table ->url(function (ProviderConnection $record): ?string { $tenant = static::resolveTenantForRecord($record); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -801,7 +801,7 @@ public static function table(Table $table): Table ]) ->filters([ SelectFilter::make('tenant') - ->label('Tenant') + ->label('ManagedEnvironment') ->default(static::resolveScopedTenant()?->external_id) ->options(static::tenantFilterOptions()) ->query(function (Builder $query, array $data): Builder { @@ -812,7 +812,7 @@ public static function table(Table $table): Table } return $query->whereHas('tenant', function (Builder $tenantQuery) use ($value): void { - $tenantQuery->where('external_id', $value); + $tenantQuery->where('slug', $value); }); }), SelectFilter::make('provider') @@ -952,7 +952,7 @@ public static function makeInventorySyncAction(): Actions\Action gate: $gate, operationType: OperationRunType::InventorySync->value, blockedTitle: 'Inventory sync blocked', - dispatcher: function (Tenant $tenant, User $user, ProviderConnection $connection, OperationRun $operationRun): void { + dispatcher: function (ManagedEnvironment $tenant, User $user, ProviderConnection $connection, OperationRun $operationRun): void { ProviderInventorySyncJob::dispatch( tenantId: (int) $tenant->getKey(), userId: (int) $user->getKey(), @@ -983,7 +983,7 @@ public static function makeComplianceSnapshotAction(): Actions\Action gate: $gate, operationType: 'compliance.snapshot', blockedTitle: 'Compliance snapshot blocked', - dispatcher: function (Tenant $tenant, User $user, ProviderConnection $connection, OperationRun $operationRun): void { + dispatcher: function (ManagedEnvironment $tenant, User $user, ProviderConnection $connection, OperationRun $operationRun): void { ProviderComplianceSnapshotJob::dispatch( tenantId: (int) $tenant->getKey(), userId: (int) $user->getKey(), @@ -1012,7 +1012,7 @@ public static function makeSetDefaultAction(): Actions\Action ->action(function (ProviderConnection $record, AuditLogger $auditLogger): void { $tenant = static::resolveTenantForRecord($record); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -1070,7 +1070,7 @@ public static function makeEnableDedicatedOverrideAction(string $source, ?string ->action(function (array $data, ProviderConnection $record, ProviderConnectionMutationService $mutations, AuditLogger $auditLogger) use ($source): void { $tenant = static::resolveTenantForRecord($record); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -1147,7 +1147,7 @@ public static function makeRotateDedicatedCredentialAction(?string $modalDescrip ->action(function (array $data, ProviderConnection $record, ProviderConnectionMutationService $mutations): void { $tenant = static::resolveTenantForRecord($record); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -1185,7 +1185,7 @@ public static function makeDeleteDedicatedCredentialAction(?string $modalDescrip ->action(function (ProviderConnection $record, ProviderConnectionMutationService $mutations): void { $tenant = static::resolveTenantForRecord($record); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -1218,7 +1218,7 @@ public static function makeRevertToPlatformAction(string $source, ?string $modal ->action(function (ProviderConnection $record, ProviderConnectionMutationService $mutations, AuditLogger $auditLogger) use ($source): void { $tenant = static::resolveTenantForRecord($record); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -1275,7 +1275,7 @@ public static function makeEnableConnectionAction(): Actions\Action ->action(function (ProviderConnection $record, AuditLogger $auditLogger): void { $tenant = static::resolveTenantForRecord($record); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -1350,7 +1350,7 @@ public static function makeDisableConnectionAction(): Actions\Action ->action(function (ProviderConnection $record, AuditLogger $auditLogger): void { $tenant = static::resolveTenantForRecord($record); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -1398,7 +1398,7 @@ private static function recordAllowsProviderExecution(ProviderConnection $record $tenant = static::resolveTenantForRecord($record); $user = auth()->user(); - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment && $user instanceof User && $user->canAccessTenant($tenant) && (bool) $record->is_enabled; @@ -1409,7 +1409,7 @@ private static function handleCheckConnectionAction(ProviderConnection $record, $tenant = static::resolveTenantForRecord($record); $user = auth()->user(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -1464,7 +1464,7 @@ private static function handleCheckConnectionAction(ProviderConnection $record, } /** - * @param callable(Tenant, User, ProviderConnection, OperationRun): void $dispatcher + * @param callable(ManagedEnvironment, User, ProviderConnection, OperationRun): void $dispatcher */ private static function handleProviderOperationAction( ProviderConnection $record, @@ -1477,7 +1477,7 @@ private static function handleProviderOperationAction( $tenant = static::resolveTenantForRecord($record); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return; } @@ -1543,7 +1543,7 @@ public static function getPages(): array private static function normalizeTenantExternalId(mixed $tenant): ?string { - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return (string) $tenant->external_id; } @@ -1552,9 +1552,9 @@ private static function normalizeTenantExternalId(mixed $tenant): ?string } if (is_numeric($tenant)) { - $tenantModel = Tenant::query()->whereKey((int) $tenant)->first(); + $tenantModel = ManagedEnvironment::query()->whereKey((int) $tenant)->first(); - if ($tenantModel instanceof Tenant) { + if ($tenantModel instanceof ManagedEnvironment) { return (string) $tenantModel->external_id; } } @@ -1575,7 +1575,7 @@ public static function getUrl(?string $name = null, array $parameters = [], bool unset($parameters['tenant']); } - if ($tenantExternalId === null && $tenant instanceof Tenant) { + if ($tenantExternalId === null && $tenant instanceof ManagedEnvironment) { $tenantExternalId = (string) $tenant->external_id; } @@ -1591,8 +1591,8 @@ public static function getUrl(?string $name = null, array $parameters = [], bool $tenantExternalId = static::resolveScopedTenant()?->external_id; } - if (! array_key_exists('tenant_id', $parameters) && is_string($tenantExternalId) && $tenantExternalId !== '') { - $parameters['tenant_id'] = $tenantExternalId; + if (! array_key_exists('managed_environment_id', $parameters) && is_string($tenantExternalId) && $tenantExternalId !== '') { + $parameters['managed_environment_id'] = $tenantExternalId; } return parent::getUrl($name, $parameters, $isAbsolute, $panel, null, $shouldGuessMissingParameters); diff --git a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/CreateProviderConnection.php b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/CreateProviderConnection.php index 67ff1bdc..0805ef04 100644 --- a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/CreateProviderConnection.php +++ b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/CreateProviderConnection.php @@ -3,7 +3,7 @@ namespace App\Filament\Resources\ProviderConnectionResource\Pages; use App\Filament\Resources\ProviderConnectionResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Intune\AuditLogger; use App\Support\Providers\ProviderConnectionType; @@ -26,7 +26,7 @@ protected function mutateFormDataBeforeCreate(array $data): array { $tenant = $this->currentTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -49,7 +49,7 @@ protected function mutateFormDataBeforeCreate(array $data): array return [ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $data['entra_tenant_id'], 'display_name' => $data['display_name'], @@ -73,7 +73,7 @@ protected function afterCreate(): void { $tenant = $this->currentTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -115,11 +115,11 @@ protected function afterCreate(): void ->send(); } - private function currentTenant(): ?Tenant + private function currentTenant(): ?ManagedEnvironment { $tenant = ProviderConnectionResource::resolveTenantForCreate(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return $tenant; } diff --git a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php index 4a0734f8..2201e634 100644 --- a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php +++ b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php @@ -7,7 +7,7 @@ use App\Jobs\ProviderInventorySyncJob; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Intune\AuditLogger; @@ -48,13 +48,13 @@ public function mount($record): void ? ProviderConnectionResource::resolveTenantForRecord($this->record) : null; - if ($recordTenant instanceof Tenant) { + if ($recordTenant instanceof ManagedEnvironment) { $this->scopedTenantExternalId = (string) $recordTenant->external_id; return; } - $tenantIdFromQuery = request()->query('tenant_id'); + $tenantIdFromQuery = request()->query('managed_environment_id'); if (is_string($tenantIdFromQuery) && $tenantIdFromQuery !== '') { $this->scopedTenantExternalId = $tenantIdFromQuery; @@ -64,7 +64,7 @@ public function mount($record): void $tenant = request()->route('tenant'); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $this->scopedTenantExternalId = (string) $tenant->external_id; return; @@ -107,7 +107,7 @@ protected function afterSave(): void ? ($record->tenant ?? $this->currentTenant()) : $this->currentTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -182,21 +182,21 @@ protected function getHeaderActions(): array ->label('View last check run') ->icon('heroicon-o-eye') ->color('gray') - ->visible(fn (ProviderConnection $record): bool => $tenant instanceof Tenant + ->visible(fn (ProviderConnection $record): bool => $tenant instanceof ManagedEnvironment && OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'provider.connection.check') ->where('context->provider_connection_id', (int) $record->getKey()) ->exists()) ->url(function (ProviderConnection $record): ?string { $tenant = $this->currentTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'provider.connection.check') ->where('context->provider_connection_id', (int) $record->getKey()) ->orderByDesc('id') @@ -246,7 +246,7 @@ protected function getFormActions(): array $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return [ $this->getCancelFormAction(), ]; @@ -271,7 +271,7 @@ protected function handleRecordUpdate(Model $record, array $data): Model $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { abort(404); } @@ -288,40 +288,40 @@ protected function handleRecordUpdate(Model $record, array $data): Model return parent::handleRecordUpdate($record, $data); } - private function currentTenant(): ?Tenant + private function currentTenant(): ?ManagedEnvironment { if (isset($this->record) && $this->record instanceof ProviderConnection) { $recordTenant = ProviderConnectionResource::resolveTenantForRecord($this->record); - if ($recordTenant instanceof Tenant) { + if ($recordTenant instanceof ManagedEnvironment) { return $recordTenant; } } if (is_string($this->scopedTenantExternalId) && $this->scopedTenantExternalId !== '') { - return Tenant::query() - ->where('external_id', $this->scopedTenantExternalId) + return ManagedEnvironment::query() + ->where('slug', $this->scopedTenantExternalId) ->first(); } $tenant = request()->route('tenant'); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return $tenant; } if (is_string($tenant) && $tenant !== '') { - return Tenant::query() - ->where('external_id', $tenant) + return ManagedEnvironment::query() + ->where('slug', $tenant) ->first(); } $tenantFromCreateResolution = ProviderConnectionResource::resolveTenantForCreate(); - if ($tenantFromCreateResolution instanceof Tenant) { + if ($tenantFromCreateResolution instanceof ManagedEnvironment) { return $tenantFromCreateResolution; } - return Tenant::current(); + return ManagedEnvironment::current(); } } diff --git a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php index 03415391..d84fe15e 100644 --- a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php +++ b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php @@ -3,7 +3,7 @@ namespace App\Filament\Resources\ProviderConnectionResource\Pages; use App\Filament\Resources\ProviderConnectionResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -48,7 +48,7 @@ protected function getHeaderActions(): array } return ProviderConnectionResource::getUrl('create', [ - 'tenant_id' => $tenantExternalId, + 'managed_environment_id' => $tenantExternalId, ]); }) ->visible(function () use ($resolver): bool { @@ -59,7 +59,7 @@ protected function getHeaderActions(): array $tenant = $this->resolveTenantForCreateAction(); $user = auth()->user(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return true; } @@ -73,7 +73,7 @@ protected function getHeaderActions(): array $tenant = $this->resolveTenantForCreateAction(); $user = auth()->user(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return true; } @@ -90,7 +90,7 @@ protected function getHeaderActions(): array ->tooltip(function () use ($resolver): ?string { $tenant = $this->resolveTenantForCreateAction(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return 'Select a tenant to create provider connections.'; } @@ -114,7 +114,7 @@ protected function getHeaderActions(): array $tenant = $this->resolveTenantForCreateAction(); $user = auth()->user(); - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment && $user instanceof User && $resolver->isMember($user, $tenant); }), @@ -136,14 +136,14 @@ private function makeEmptyStateCreateAction(): Actions\CreateAction } return ProviderConnectionResource::getUrl('create', [ - 'tenant_id' => $tenantExternalId, + 'managed_environment_id' => $tenantExternalId, ]); }) ->visible(function () use ($resolver): bool { $tenant = $this->resolveTenantForCreateAction(); $user = auth()->user(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return true; } @@ -157,7 +157,7 @@ private function makeEmptyStateCreateAction(): Actions\CreateAction $tenant = $this->resolveTenantForCreateAction(); $user = auth()->user(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return true; } @@ -174,7 +174,7 @@ private function makeEmptyStateCreateAction(): Actions\CreateAction ->tooltip(function () use ($resolver): ?string { $tenant = $this->resolveTenantForCreateAction(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return 'Select a tenant to create provider connections.'; } @@ -198,7 +198,7 @@ private function makeEmptyStateCreateAction(): Actions\CreateAction $tenant = $this->resolveTenantForCreateAction(); $user = auth()->user(); - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment && $user instanceof User && $resolver->isMember($user, $tenant); }); @@ -222,7 +222,7 @@ private function resolveTenantExternalIdForCreateAction(): ?string return ProviderConnectionResource::resolveContextTenantExternalId(); } - private function resolveTenantForCreateAction(): ?Tenant + private function resolveTenantForCreateAction(): ?ManagedEnvironment { $tenantExternalId = $this->resolveTenantExternalIdForCreateAction(); @@ -230,8 +230,8 @@ private function resolveTenantForCreateAction(): ?Tenant return null; } - return Tenant::query() - ->where('external_id', $tenantExternalId) + return ManagedEnvironment::query() + ->where('slug', $tenantExternalId) ->first(); } diff --git a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php index 96c8c489..4d451ae0 100644 --- a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php +++ b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php @@ -4,7 +4,7 @@ use App\Filament\Resources\ProviderConnectionResource; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\Capabilities; use App\Support\Links\RequiredPermissionsLinks; use App\Support\Rbac\UiEnforcement; @@ -25,11 +25,11 @@ protected function getHeaderActions(): array ->label('Grant admin consent') ->icon('heroicon-o-clipboard-document') ->url(function () use ($tenant): ?string { - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment ? RequiredPermissionsLinks::adminConsentPrimaryUrl($tenant) : null; }) - ->visible(fn (): bool => $tenant instanceof Tenant) + ->visible(fn (): bool => $tenant instanceof ManagedEnvironment) ->openUrlInNewTab() ) ->requireCapability(Capabilities::PROVIDER_MANAGE) @@ -64,7 +64,7 @@ private function sharedConnectionActions(): array ]; } - private function currentTenant(): ?Tenant + private function currentTenant(): ?ManagedEnvironment { if (! $this->record instanceof ProviderConnection) { return null; diff --git a/apps/platform/app/Filament/Resources/RestoreRunResource.php b/apps/platform/app/Filament/Resources/RestoreRunResource.php index b1cc61a3..331f2dd3 100644 --- a/apps/platform/app/Filament/Resources/RestoreRunResource.php +++ b/apps/platform/app/Filament/Resources/RestoreRunResource.php @@ -16,7 +16,7 @@ use App\Models\EntraGroup; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Rules\SkipOrUuidRule; @@ -111,7 +111,7 @@ public static function canViewAny(): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -127,7 +127,7 @@ public static function canCreate(): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -192,7 +192,7 @@ public static function form(Schema $schema): Schema tenant: $tenant ); - $groupCacheQuery = EntraGroup::query()->where('tenant_id', $tenant->getKey()); + $groupCacheQuery = EntraGroup::query()->where('managed_environment_id', $tenant->getKey()); $hasCachedGroups = $groupCacheQuery->exists(); $stalenessDays = (int) config('directory_groups.staleness_days', 30); @@ -505,7 +505,7 @@ public static function getWizardSteps(): array tenant: $tenant ); - $groupCacheQuery = EntraGroup::query()->where('tenant_id', $tenant->getKey()); + $groupCacheQuery = EntraGroup::query()->where('managed_environment_id', $tenant->getKey()); $hasCachedGroups = $groupCacheQuery->exists(); $stalenessDays = (int) config('directory_groups.staleness_days', 30); @@ -630,7 +630,7 @@ public static function getWizardSteps(): array $backupSet = BackupSet::find($backupSetId); - if (! $backupSet || $backupSet->tenant_id !== $tenant->id) { + if (! $backupSet || $backupSet->managed_environment_id !== $tenant->id) { Notification::make() ->title('Unable to run checks') ->body('Backup set is not available for the active tenant.') @@ -749,7 +749,7 @@ public static function getWizardSteps(): array $backupSet = BackupSet::find($backupSetId); - if (! $backupSet || $backupSet->tenant_id !== $tenant->id) { + if (! $backupSet || $backupSet->managed_environment_id !== $tenant->id) { Notification::make() ->title('Unable to generate preview') ->body('Backup set is not available for the active tenant.') @@ -827,7 +827,7 @@ public static function getWizardSteps(): array ->label('Environment') ->content(fn (): string => app()->environment('production') ? 'prod' : 'test'), Forms\Components\Placeholder::make('confirm_tenant_label') - ->label('Tenant hard-confirm label') + ->label('ManagedEnvironment hard-confirm label') ->content(function (): string { $tenant = static::resolveTenantContextForCurrentPanel(); @@ -835,7 +835,7 @@ public static function getWizardSteps(): array return ''; } - $tenantIdentifier = $tenant->tenant_id ?? $tenant->external_id; + $tenantIdentifier = $tenant->managed_environment_id ?? $tenant->external_id; return (string) ($tenant->name ?? $tenantIdentifier ?? $tenant->getKey()); }), @@ -914,12 +914,12 @@ public static function getWizardSteps(): array return []; } - $tenantIdentifier = $tenant->tenant_id ?? $tenant->external_id; + $tenantIdentifier = $tenant->managed_environment_id ?? $tenant->external_id; return [(string) ($tenant->name ?? $tenantIdentifier ?? $tenant->getKey())]; }) ->validationMessages([ - 'in' => 'Tenant hard-confirm does not match.', + 'in' => 'ManagedEnvironment hard-confirm does not match.', ]) ->helperText(function (): string { $tenant = static::resolveTenantContextForCurrentPanel(); @@ -928,7 +928,7 @@ public static function getWizardSteps(): array return ''; } - $tenantIdentifier = $tenant->tenant_id ?? $tenant->external_id; + $tenantIdentifier = $tenant->managed_environment_id ?? $tenant->external_id; $expected = (string) ($tenant->name ?? $tenantIdentifier ?? $tenant->getKey()); return "Type: {$expected}"; @@ -1156,7 +1156,7 @@ public static function table(Table $table): Table $count = $records->count(); $ids = static::resolveProtectedRestoreRunIds($records); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -1173,7 +1173,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'restore_run.delete', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $initiator, $ids): void { @@ -1226,7 +1226,7 @@ public static function table(Table $table): Table $count = $records->count(); $ids = static::resolveProtectedRestoreRunIds($records); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -1243,7 +1243,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'restore_run.restore', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($count, $tenant, $initiator, $ids): void { @@ -1316,7 +1316,7 @@ public static function table(Table $table): Table $count = $records->count(); $ids = static::resolveProtectedRestoreRunIds($records); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -1333,7 +1333,7 @@ public static function table(Table $table): Table tenant: $tenant, type: 'restore_run.force_delete', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($count, $tenant, $initiator, $ids): void { @@ -1469,7 +1469,7 @@ private static function restoreItemOptionData(?int $backupSetId): array return Cache::store('array')->rememberForever($cacheKey, function () use ($backupSetId, $tenant): array { $items = BackupItem::query() ->where('backup_set_id', $backupSetId) - ->whereHas('backupSet', fn ($query) => $query->where('tenant_id', $tenant->getKey())) + ->whereHas('backupSet', fn ($query) => $query->where('managed_environment_id', $tenant->getKey())) ->where(function ($query) { $query->whereNull('policy_id') ->orWhereDoesntHave('policy') @@ -1544,7 +1544,7 @@ private static function restoreItemGroupedOptions(?int $backupSetId): array $items = BackupItem::query() ->where('backup_set_id', $backupSetId) - ->whereHas('backupSet', fn ($query) => $query->where('tenant_id', $tenant->getKey())) + ->whereHas('backupSet', fn ($query) => $query->where('managed_environment_id', $tenant->getKey())) ->where(function ($query) { $query->whereNull('policy_id') ->orWhereDoesntHave('policy') @@ -1598,7 +1598,7 @@ private static function restoreBackupSetOptions(): array $tenantId = static::resolveTenantContextForCurrentPanelOrFail()->getKey(); return BackupSet::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->with([ 'items' => fn ($query) => $query->select([ 'id', @@ -1638,12 +1638,12 @@ private static function restoreBackupSetHelperText(mixed $backupSetId): string $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return $default; } $backupSet = BackupSet::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->with([ 'items' => fn ($query) => $query->select([ 'id', @@ -1695,7 +1695,7 @@ public static function createRestoreRun(array $data): RestoreRun $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { abort(403); } @@ -1713,7 +1713,7 @@ public static function createRestoreRun(array $data): RestoreRun /** @var BackupSet $backupSet */ $backupSet = BackupSet::findOrFail($data['backup_set_id']); - if ($backupSet->tenant_id !== $tenant->id) { + if ($backupSet->managed_environment_id !== $tenant->id) { abort(403, 'Backup set does not belong to the active tenant.'); } @@ -1756,7 +1756,7 @@ public static function createRestoreRun(array $data): RestoreRun $previewDiffs = $data['preview_diffs'] ?? null; $previewRanAt = $data['preview_ran_at'] ?? null; - $tenantIdentifier = $tenant->tenant_id ?? $tenant->external_id; + $tenantIdentifier = $tenant->managed_environment_id ?? $tenant->external_id; $highlanderLabel = (string) ($tenant->name ?? $tenantIdentifier ?? $tenant->getKey()); if (! $isDryRun) { @@ -1835,7 +1835,7 @@ public static function createRestoreRun(array $data): RestoreRun if (! is_string($tenantConfirm) || $tenantConfirm !== $highlanderLabel) { throw ValidationException::withMessages([ - 'tenant_confirm' => 'Tenant hard-confirm does not match.', + 'tenant_confirm' => 'ManagedEnvironment hard-confirm does not match.', ]); } } @@ -1988,7 +1988,7 @@ public static function createRestoreRun(array $data): RestoreRun * @return array{0: \App\Services\Providers\ProviderOperationStartResult, 1: ?RestoreRun} */ private static function startQueuedRestoreExecution( - Tenant $tenant, + ManagedEnvironment $tenant, BackupSet $backupSet, ?array $selectedItemIds, array $preview, @@ -2029,7 +2029,7 @@ private static function startQueuedRestoreExecution( &$queuedRestoreRun, ): void { $queuedRestoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'operation_run_id' => $run->getKey(), 'requested_by' => $actorEmail, @@ -2137,7 +2137,7 @@ private static function startQueuedRestoreExecution( * @param array|null $selectedItemIds */ private static function guardRestoreExecutionOperationalControl( - Tenant $tenant, + ManagedEnvironment $tenant, BackupSet $backupSet, ?array $selectedItemIds, ?User $initiator, @@ -2241,7 +2241,7 @@ private static function wizardSafetyState(array $data): array $previewIntegrity = $resolver->previewIntegrityFromData($data); $checksIntegrity = $resolver->checksIntegrityFromData($data); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return [ 'currentScope' => $scope, 'previewIntegrity' => $previewIntegrity->toArray(), @@ -2346,7 +2346,7 @@ private static function restoreSafetyResolver(): RestoreSafetyResolver * @param array|null $selectedItemIds * @return array */ - private static function unresolvedGroups(?int $backupSetId, ?array $selectedItemIds, Tenant $tenant): array + private static function unresolvedGroups(?int $backupSetId, ?array $selectedItemIds, ManagedEnvironment $tenant): array { if (! $backupSetId) { return []; @@ -2421,7 +2421,7 @@ private static function unresolvedGroups(?int $backupSetId, ?array $selectedItem * @param array|null $selectedItemIds * @return array */ - private static function groupMappingPlaceholders(?int $backupSetId, string $scopeMode, ?array $selectedItemIds, ?Tenant $tenant): array + private static function groupMappingPlaceholders(?int $backupSetId, string $scopeMode, ?array $selectedItemIds, ?ManagedEnvironment $tenant): array { if (! $tenant || ! $backupSetId) { return []; @@ -2601,7 +2601,7 @@ private static function rerunActionWithGate(): Actions\Action|BulkAction $groupMapping = is_array($record->group_mapping) ? $record->group_mapping : []; $actorEmail = auth()->user()?->email; $actorName = auth()->user()?->name; - $tenantIdentifier = $tenant->tenant_id ?? $tenant->external_id; + $tenantIdentifier = $tenant->managed_environment_id ?? $tenant->external_id; $highlanderLabel = (string) ($tenant->name ?? $tenantIdentifier ?? $tenant->getKey()); $preview = $restoreService->preview($tenant, $backupSet, $selectedItemIds); @@ -2729,7 +2729,7 @@ private static function rerunActionWithGate(): Actions\Action|BulkAction $tenant = $record instanceof RestoreRun ? $record->tenant : static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return true; } @@ -2753,8 +2753,8 @@ private static function rerunActionWithGate(): Actions\Action|BulkAction $tenant = $record instanceof RestoreRun ? $record->tenant : static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { - return 'Tenant unavailable'; + if (! $tenant instanceof ManagedEnvironment) { + return 'ManagedEnvironment unavailable'; } // Check RBAC capability first diff --git a/apps/platform/app/Filament/Resources/RestoreRunResource/Pages/CreateRestoreRun.php b/apps/platform/app/Filament/Resources/RestoreRunResource/Pages/CreateRestoreRun.php index dc547e47..425fc090 100644 --- a/apps/platform/app/Filament/Resources/RestoreRunResource/Pages/CreateRestoreRun.php +++ b/apps/platform/app/Filament/Resources/RestoreRunResource/Pages/CreateRestoreRun.php @@ -5,7 +5,7 @@ use App\Filament\Concerns\ResolvesPanelTenantContext; use App\Filament\Resources\RestoreRunResource; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -28,7 +28,7 @@ protected function authorizeAccess(): void $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { abort(404); } @@ -69,7 +69,7 @@ protected function afterFill(): void } $belongsToTenant = BackupSet::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->whereKey($backupSetId) ->exists(); diff --git a/apps/platform/app/Filament/Resources/ReviewPackResource.php b/apps/platform/app/Filament/Resources/ReviewPackResource.php index d589692d..9e24db2c 100644 --- a/apps/platform/app/Filament/Resources/ReviewPackResource.php +++ b/apps/platform/app/Filament/Resources/ReviewPackResource.php @@ -9,7 +9,7 @@ use App\Filament\Resources\EvidenceSnapshotResource as TenantEvidenceSnapshotResource; use App\Filament\Resources\ReviewPackResource\Pages; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\ReviewPackService; use App\Support\Auth\Capabilities; @@ -67,10 +67,10 @@ class ReviewPackResource extends Resource public static function canViewAny(): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -83,10 +83,10 @@ public static function canViewAny(): bool public static function canView(Model $record): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -99,7 +99,7 @@ public static function canView(Model $record): bool } if ($record instanceof ReviewPack) { - return (int) $record->tenant_id === (int) $tenant->getKey(); + return (int) $record->managed_environment_id === (int) $tenant->getKey(); } return true; @@ -142,7 +142,7 @@ public static function infolist(Schema $schema): Schema ->color(BadgeRenderer::color(BadgeDomain::ReviewPackStatus)) ->icon(BadgeRenderer::icon(BadgeDomain::ReviewPackStatus)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::ReviewPackStatus)), - TextEntry::make('tenant.name')->label('Tenant'), + TextEntry::make('tenant.name')->label('ManagedEnvironment'), TextEntry::make('generated_at')->dateTime()->placeholder('—'), TextEntry::make('expires_at')->dateTime()->placeholder('—'), TextEntry::make('file_size') @@ -192,7 +192,7 @@ public static function infolist(Schema $schema): Schema ->schema([ TextEntry::make('initiator.name')->label('Initiated by')->placeholder('—'), TextEntry::make('tenantReview.id') - ->label('Tenant review') + ->label('ManagedEnvironment review') ->formatStateUsing(fn (?int $state): string => $state ? '#'.$state : '—') ->url(fn (ReviewPack $record): ?string => $record->tenantReview && $record->tenant ? TenantReviewResource::tenantScopedUrl('view', ['record' => $record->tenantReview], $record->tenant) @@ -201,7 +201,7 @@ public static function infolist(Schema $schema): Schema TextEntry::make('customer_workspace') ->label('Customer workspace') ->state(fn (): string => 'Open workspace') - ->url(fn (ReviewPack $record): ?string => $record->tenant instanceof Tenant + ->url(fn (ReviewPack $record): ?string => $record->tenant instanceof ManagedEnvironment ? CustomerReviewWorkspace::tenantPrefilterUrl($record->tenant) : null) ->placeholder('—'), @@ -222,7 +222,7 @@ public static function infolist(Schema $schema): Schema $tenant = $record->tenant; - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return OperationRunLinks::view((int) $record->operation_run_id, $tenant); } @@ -291,7 +291,7 @@ public static function table(Table $table): Table ->description(fn (ReviewPack $record): ?string => static::compressedOutcome($record)->primaryReason) ->wrap(), Tables\Columns\TextColumn::make('tenant.name') - ->label('Tenant') + ->label('ManagedEnvironment') ->searchable(), Tables\Columns\TextColumn::make('generated_at') ->dateTime() @@ -413,15 +413,15 @@ public static function reviewPackGenerationFormSchema(): array public static function getEloquentQuery(): Builder { - $tenant = Tenant::current() ?? static::resolveTenantContextForCurrentPanel() ?? Filament::getTenant(); + $tenant = ManagedEnvironment::current() ?? static::resolveTenantContextForCurrentPanel() ?? Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return parent::getEloquentQuery()->whereRaw('1 = 0'); } return parent::getEloquentQuery() ->with(['tenant', 'operationRun', 'evidenceSnapshot', 'tenantReview']) - ->where('tenant_id', (int) $tenant->getKey()); + ->where('managed_environment_id', (int) $tenant->getKey()); } public static function getPages(): array @@ -504,7 +504,7 @@ public static function executeGeneration(array $data): void $tenant = Filament::getTenant(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { Notification::make()->danger()->title('Unable to generate pack — missing context.')->send(); return; @@ -572,30 +572,30 @@ public static function executeGeneration(array $data): void /** * @return array */ - public static function reviewPackGenerationDecision(?Tenant $tenant = null): array + public static function reviewPackGenerationDecision(?ManagedEnvironment $tenant = null): array { - $tenant ??= Tenant::current() ?? static::resolveTenantContextForCurrentPanel() ?? Filament::getTenant(); + $tenant ??= ManagedEnvironment::current() ?? static::resolveTenantContextForCurrentPanel() ?? Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } return app(ReviewPackService::class)->reviewPackGenerationDecisionForTenant($tenant); } - public static function currentTenantContext(): ?Tenant + public static function currentTenantContext(): ?ManagedEnvironment { - $tenant = Tenant::current() ?? static::resolveTenantContextForCurrentPanel() ?? Filament::getTenant(); + $tenant = ManagedEnvironment::current() ?? static::resolveTenantContextForCurrentPanel() ?? Filament::getTenant(); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } - public static function reviewPackGenerationBlocked(?Tenant $tenant = null): bool + public static function reviewPackGenerationBlocked(?ManagedEnvironment $tenant = null): bool { return (bool) (static::reviewPackGenerationDecision($tenant)['is_blocked'] ?? false); } - public static function reviewPackGenerationBlockReason(?Tenant $tenant = null): ?string + public static function reviewPackGenerationBlockReason(?ManagedEnvironment $tenant = null): ?string { $decision = static::reviewPackGenerationDecision($tenant); @@ -608,7 +608,7 @@ public static function reviewPackGenerationBlockReason(?Tenant $tenant = null): return is_string($reason) && $reason !== '' ? $reason : null; } - public static function reviewPackGenerationWarningReason(?Tenant $tenant = null): ?string + public static function reviewPackGenerationWarningReason(?ManagedEnvironment $tenant = null): ?string { $decision = static::reviewPackGenerationDecision($tenant); @@ -621,12 +621,12 @@ public static function reviewPackGenerationWarningReason(?Tenant $tenant = null) return is_string($reason) && $reason !== '' ? $reason : null; } - public static function reviewPackGenerationActionTooltip(?Tenant $tenant = null): ?string + public static function reviewPackGenerationActionTooltip(?ManagedEnvironment $tenant = null): ?string { $tenant ??= static::currentTenantContext(); $user = auth()->user(); - if ($tenant instanceof Tenant && $user instanceof User && ! $user->can(Capabilities::REVIEW_PACK_MANAGE, $tenant)) { + if ($tenant instanceof ManagedEnvironment && $user instanceof User && ! $user->can(Capabilities::REVIEW_PACK_MANAGE, $tenant)) { return AuthUiTooltips::insufficientPermission(); } diff --git a/apps/platform/app/Filament/Resources/StoredReportResource.php b/apps/platform/app/Filament/Resources/StoredReportResource.php index 87e3df33..d3c4488c 100644 --- a/apps/platform/app/Filament/Resources/StoredReportResource.php +++ b/apps/platform/app/Filament/Resources/StoredReportResource.php @@ -9,7 +9,7 @@ use App\Filament\Pages\TenantDashboard; use App\Filament\Resources\StoredReportResource\Pages; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Auth\Capabilities; use App\Support\Badges\BadgeDomain; @@ -78,7 +78,7 @@ public static function canView(Model $record): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -90,7 +90,7 @@ public static function canView(Model $record): bool return true; } - if ((int) $record->tenant_id !== (int) $tenant->getKey() || (int) $record->workspace_id !== (int) $tenant->workspace_id) { + if ((int) $record->managed_environment_id !== (int) $tenant->getKey() || (int) $record->workspace_id !== (int) $tenant->workspace_id) { return false; } @@ -133,7 +133,7 @@ public static function getEloquentQuery(): Builder $tenant = static::resolveTenantContextForCurrentPanel(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $query->where('workspace_id', (int) $tenant->workspace_id); } @@ -154,7 +154,7 @@ public static function resolveScopedRecordOrFail(int|string|null $record): Model $tenant = static::resolveTenantContextForCurrentPanel(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $query->where('workspace_id', (int) $tenant->workspace_id); } @@ -387,7 +387,7 @@ public static function visibleReportTypesForCurrentUser(): array $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User || ! $user->canAccessTenant($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User || ! $user->canAccessTenant($tenant)) { return []; } @@ -544,7 +544,7 @@ public static function highestRiskAssignmentLabel(StoredReport $report): ?string public static function currentReportFor(StoredReport $report): ?StoredReport { $current = StoredReport::query() - ->where('tenant_id', (int) $report->tenant_id) + ->where('managed_environment_id', (int) $report->managed_environment_id) ->where('workspace_id', (int) $report->workspace_id) ->where('report_type', (string) $report->report_type) ->orderByDesc('created_at') @@ -564,7 +564,7 @@ public static function currentReportUrlFor(StoredReport $report): ?string $tenant = $current->tenant ?? static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -577,7 +577,7 @@ public static function scopeCurrentRecords(Builder $query): Builder $subQuery ->selectRaw('1') ->from('stored_reports as newer_stored_reports') - ->whereColumn('newer_stored_reports.tenant_id', 'stored_reports.tenant_id') + ->whereColumn('newer_stored_reports.managed_environment_id', 'stored_reports.managed_environment_id') ->whereColumn('newer_stored_reports.workspace_id', 'stored_reports.workspace_id') ->whereColumn('newer_stored_reports.report_type', 'stored_reports.report_type') ->where(function ($newerQuery): void { @@ -659,7 +659,7 @@ private static function tenantOverviewUrl(): string { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return '#'; } diff --git a/apps/platform/app/Filament/Resources/TenantResource.php b/apps/platform/app/Filament/Resources/TenantResource.php index d5ed91d7..b90bafa5 100644 --- a/apps/platform/app/Filament/Resources/TenantResource.php +++ b/apps/platform/app/Filament/Resources/TenantResource.php @@ -12,7 +12,7 @@ use App\Models\EntraGroup; use App\Models\EntraRoleDefinition; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\TenantTriageReview; use App\Models\User; @@ -95,7 +95,7 @@ class TenantResource extends Resource { // ... [Properties Omitted for Brevity] ... - protected static ?string $model = Tenant::class; + protected static ?string $model = ManagedEnvironment::class; protected static bool $isDiscovered = false; @@ -103,7 +103,7 @@ class TenantResource extends Resource protected static ?string $recordTitleAttribute = 'name'; - protected static ?string $recordRouteKeyName = 'external_id'; + protected static ?string $recordRouteKeyName = 'slug'; protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-building-office-2'; @@ -127,7 +127,7 @@ class TenantResource extends Resource ]; /** - * Tenant creation is handled exclusively by the onboarding wizard. + * ManagedEnvironment creation is handled exclusively by the onboarding wizard. * The CRUD create page has been removed. */ public static function canCreate(): bool @@ -146,7 +146,7 @@ public static function canEdit(Model $record): bool /** @var CapabilityResolver $resolver */ $resolver = app(CapabilityResolver::class); - return $record instanceof Tenant + return $record instanceof ManagedEnvironment && $resolver->can($user, $record, Capabilities::TENANT_MANAGE); } @@ -161,7 +161,7 @@ public static function canDelete(Model $record): bool /** @var CapabilityResolver $resolver */ $resolver = app(CapabilityResolver::class); - return $record instanceof Tenant + return $record instanceof ManagedEnvironment && $resolver->can($user, $record, Capabilities::TENANT_DELETE); } @@ -185,7 +185,7 @@ public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration ->satisfy(ActionSurfaceSlot::ListRowMoreMenu, 'At most one non-inspect row action stays primary; overflow keeps helpers first, workflow actions next, and destructive actions last.') ->satisfy(ActionSurfaceSlot::ListBulkMoreGroup, 'Bulk actions are grouped under "More".') ->satisfy(ActionSurfaceSlot::ListEmptyState, 'Create action is reused in the list empty state.') - ->satisfy(ActionSurfaceSlot::DetailHeader, 'Tenant view remains the workflow-heavy special type: shared administrative actions stay grouped into external-link, setup, triage, and lifecycle buckets, while navigation-only context stays outside the header action strip.'); + ->satisfy(ActionSurfaceSlot::DetailHeader, 'ManagedEnvironment view remains the workflow-heavy special type: shared administrative actions stay grouped into external-link, setup, triage, and lifecycle buckets, while navigation-only context stays outside the header action strip.'); } public static function makeAdminConsentAction(): Actions\Action @@ -194,8 +194,8 @@ public static function makeAdminConsentAction(): Actions\Action Actions\Action::make('admin_consent') ->label('Grant admin consent') ->icon('heroicon-o-clipboard-document') - ->url(fn (Tenant $record): string => static::adminConsentUrl($record) ?? '#') - ->visible(fn (Tenant $record): bool => static::adminConsentUrl($record) !== null) + ->url(fn (ManagedEnvironment $record): string => static::adminConsentUrl($record) ?? '#') + ->visible(fn (ManagedEnvironment $record): bool => static::adminConsentUrl($record) !== null) ->openUrlInNewTab(), ) ->preserveVisibility() @@ -208,8 +208,8 @@ public static function makeOpenInEntraAction(): Actions\Action return Actions\Action::make('open_in_entra') ->label('Open in Entra') ->icon('heroicon-o-arrow-top-right-on-square') - ->url(fn (Tenant $record): string => static::entraUrl($record) ?? '#') - ->visible(fn (Tenant $record): bool => static::entraUrl($record) !== null) + ->url(fn (ManagedEnvironment $record): string => static::entraUrl($record) ?? '#') + ->visible(fn (ManagedEnvironment $record): bool => static::entraUrl($record) !== null) ->openUrlInNewTab(); } @@ -219,7 +219,7 @@ public static function makeMembershipsAction(): Actions\Action Actions\Action::make('memberships') ->label('Manage memberships') ->icon('heroicon-o-users') - ->url(fn (Tenant $record): string => static::getUrl('memberships', ['record' => $record], panel: 'admin')), + ->url(fn (ManagedEnvironment $record): string => static::getUrl('memberships', ['record' => $record], panel: 'admin')), ) ->requireCapability(Capabilities::TENANT_MEMBERSHIP_VIEW) ->tooltip('You do not have permission to view tenant memberships.') @@ -235,8 +235,8 @@ public static function makeSyncTenantAction(): Actions\Action ->icon('heroicon-o-arrow-path') ->color('warning') ->requiresConfirmation() - ->visible(fn (Tenant $record): bool => static::syncActionVisible($record)) - ->action(function (Tenant $record, AuditLogger $auditLogger, $livewire = null): void { + ->visible(fn (ManagedEnvironment $record): bool => static::syncActionVisible($record)) + ->action(function (ManagedEnvironment $record, AuditLogger $auditLogger, $livewire = null): void { static::handleSyncTenantAction($record, $auditLogger, $livewire); }) ) @@ -253,8 +253,8 @@ public static function makeVerifyConfigurationAction(string $surfaceKind = 'tena ->icon('heroicon-o-check-badge') ->color('primary') ->requiresConfirmation() - ->visible(fn (Tenant $record): bool => static::verificationActionVisible($record)) - ->action(function (Tenant $record, StartVerification $verification, $livewire = null) use ($surfaceKind): void { + ->visible(fn (ManagedEnvironment $record): bool => static::verificationActionVisible($record)) + ->action(function (ManagedEnvironment $record, StartVerification $verification, $livewire = null) use ($surfaceKind): void { static::handleVerifyConfigurationAction($record, $verification, $livewire, $surfaceKind); }), ) @@ -271,7 +271,7 @@ public static function tenantViewTriageState(): array return static::portfolioReturnFiltersFromRequest(request()->query()); } - public static function tenantViewTriageGroupVisible(Tenant $tenant): bool + public static function tenantViewTriageGroupVisible(ManagedEnvironment $tenant): bool { return static::selectedActionTriageReviewRowForTenant($tenant, static::tenantViewTriageState()) !== null && static::userCanSeeTriageReviewAction($tenant); @@ -285,21 +285,21 @@ public static function makeTenantViewMarkReviewedAction(): Actions\Action ->color('success') ->requiresConfirmation() ->modalHeading('Mark reviewed') - ->modalDescription(fn (Tenant $record): string => static::triageReviewActionModalDescription( + ->modalDescription(fn (ManagedEnvironment $record): string => static::triageReviewActionModalDescription( $record, static::tenantViewTriageState(), TenantTriageReview::STATE_REVIEWED, )) - ->visible(fn (Tenant $record): bool => static::selectedActionTriageReviewRowForTenant( + ->visible(fn (ManagedEnvironment $record): bool => static::selectedActionTriageReviewRowForTenant( $record, static::tenantViewTriageState(), ) !== null && static::userCanSeeTriageReviewAction($record)) - ->disabled(fn (Tenant $record): bool => static::triageReviewActionIsDisabled($record)) - ->tooltip(fn (Tenant $record): ?string => static::triageReviewActionTooltip($record)) - ->before(function (Tenant $record): void { + ->disabled(fn (ManagedEnvironment $record): bool => static::triageReviewActionIsDisabled($record)) + ->tooltip(fn (ManagedEnvironment $record): ?string => static::triageReviewActionTooltip($record)) + ->before(function (ManagedEnvironment $record): void { static::authorizeTriageReviewAction($record); }) - ->action(function (Tenant $record, TenantTriageReviewService $service): void { + ->action(function (ManagedEnvironment $record, TenantTriageReviewService $service): void { static::handleTriageReviewMutation( tenant: $record, triageState: static::tenantViewTriageState(), @@ -317,21 +317,21 @@ public static function makeTenantViewMarkFollowUpNeededAction(): Actions\Action ->color('warning') ->requiresConfirmation() ->modalHeading('Mark follow-up needed') - ->modalDescription(fn (Tenant $record): string => static::triageReviewActionModalDescription( + ->modalDescription(fn (ManagedEnvironment $record): string => static::triageReviewActionModalDescription( $record, static::tenantViewTriageState(), TenantTriageReview::STATE_FOLLOW_UP_NEEDED, )) - ->visible(fn (Tenant $record): bool => static::selectedActionTriageReviewRowForTenant( + ->visible(fn (ManagedEnvironment $record): bool => static::selectedActionTriageReviewRowForTenant( $record, static::tenantViewTriageState(), ) !== null && static::userCanSeeTriageReviewAction($record)) - ->disabled(fn (Tenant $record): bool => static::triageReviewActionIsDisabled($record)) - ->tooltip(fn (Tenant $record): ?string => static::triageReviewActionTooltip($record)) - ->before(function (Tenant $record): void { + ->disabled(fn (ManagedEnvironment $record): bool => static::triageReviewActionIsDisabled($record)) + ->tooltip(fn (ManagedEnvironment $record): ?string => static::triageReviewActionTooltip($record)) + ->before(function (ManagedEnvironment $record): void { static::authorizeTriageReviewAction($record); }) - ->action(function (Tenant $record, TenantTriageReviewService $service): void { + ->action(function (ManagedEnvironment $record, TenantTriageReviewService $service): void { static::handleTriageReviewMutation( tenant: $record, triageState: static::tenantViewTriageState(), @@ -347,13 +347,13 @@ public static function makeRestoreTenantAction(TenantActionSurface $surface, ?st Actions\Action::make('restore') ->label(fn (): string => GovernanceActionCatalog::rule('restore_tenant')->canonicalLabel) ->color('success') - ->icon(fn (Tenant $record): string => static::lifecycleActionDescriptor($record, $surface)?->icon ?? 'heroicon-o-arrow-uturn-left') + ->icon(fn (ManagedEnvironment $record): string => static::lifecycleActionDescriptor($record, $surface)?->icon ?? 'heroicon-o-arrow-uturn-left') ->successNotificationTitle(fn (): string => GovernanceActionCatalog::rule('restore_tenant')->successTitle) ->requiresConfirmation() ->modalHeading(GovernanceActionCatalog::rule('restore_tenant')->modalHeading) ->modalDescription(GovernanceActionCatalog::rule('restore_tenant')->modalDescription) - ->visible(fn (Tenant $record): bool => static::lifecycleActionDescriptor($record, $surface)?->key === 'restore') - ->action(function (Tenant $record, WorkspaceAuditLogger $auditLogger): void { + ->visible(fn (ManagedEnvironment $record): bool => static::lifecycleActionDescriptor($record, $surface)?->key === 'restore') + ->action(function (ManagedEnvironment $record, WorkspaceAuditLogger $auditLogger): void { static::restoreTenant($record, $auditLogger); }) ) @@ -373,7 +373,7 @@ public static function makeArchiveTenantAction(TenantActionSurface $surface, ?st Actions\Action::make('archive') ->label(fn (): string => GovernanceActionCatalog::rule('archive_tenant')->canonicalLabel) ->color('danger') - ->icon(fn (Tenant $record): string => static::lifecycleActionDescriptor($record, $surface)?->icon ?? 'heroicon-o-archive-box-x-mark') + ->icon(fn (ManagedEnvironment $record): string => static::lifecycleActionDescriptor($record, $surface)?->icon ?? 'heroicon-o-archive-box-x-mark') ->successNotificationTitle(fn (): string => GovernanceActionCatalog::rule('archive_tenant')->successTitle) ->requiresConfirmation() ->modalHeading(GovernanceActionCatalog::rule('archive_tenant')->modalHeading) @@ -385,8 +385,8 @@ public static function makeArchiveTenantAction(TenantActionSurface $surface, ?st ->required() ->maxLength(2000), ]) - ->visible(fn (Tenant $record): bool => static::lifecycleActionDescriptor($record, $surface)?->key === 'archive') - ->action(function (Tenant $record, array $data, WorkspaceAuditLogger $auditLogger): void { + ->visible(fn (ManagedEnvironment $record): bool => static::lifecycleActionDescriptor($record, $surface)?->key === 'archive') + ->action(function (ManagedEnvironment $record, array $data, WorkspaceAuditLogger $auditLogger): void { static::archiveTenant($record, $auditLogger, (string) ($data['archive_reason'] ?? '')); }) ) @@ -400,7 +400,7 @@ public static function makeArchiveTenantAction(TenantActionSurface $surface, ?st return $builder->apply(); } - private static function syncActionVisible(Tenant $record): bool + private static function syncActionVisible(ManagedEnvironment $record): bool { if (! $record->isActive()) { return false; @@ -415,7 +415,7 @@ private static function syncActionVisible(Tenant $record): bool return $user->canAccessTenant($record); } - private static function handleSyncTenantAction(Tenant $record, AuditLogger $auditLogger, mixed $livewire = null): void + private static function handleSyncTenantAction(ManagedEnvironment $record, AuditLogger $auditLogger, mixed $livewire = null): void { $user = auth()->user(); @@ -493,7 +493,7 @@ private static function handleSyncTenantAction(Tenant $record, AuditLogger $audi resourceType: 'tenant', resourceId: (string) $record->id, status: 'success', - context: ['metadata' => ['tenant_id' => $record->tenant_id]], + context: ['metadata' => ['managed_environment_id' => $record->managed_environment_id]], ); OpsUxBrowserEvents::dispatchRunEnqueued($livewire); @@ -507,7 +507,7 @@ private static function handleSyncTenantAction(Tenant $record, AuditLogger $audi } private static function handleVerifyConfigurationAction( - Tenant $record, + ManagedEnvironment $record, StartVerification $verification, mixed $livewire = null, string $surfaceKind = 'tenant_list_row', @@ -586,8 +586,8 @@ public static function form(Schema $schema): Schema ->schema([ Forms\Components\Placeholder::make('related_context') ->label('Related context') - ->content(fn (?Tenant $record): HtmlString => static::tenantEditContextHtml($record)) - ->visible(fn (?Tenant $record): bool => $record instanceof Tenant && static::tenantEditContextEntries($record) !== []), + ->content(fn (?ManagedEnvironment $record): HtmlString => static::tenantEditContextHtml($record)) + ->visible(fn (?ManagedEnvironment $record): bool => $record instanceof ManagedEnvironment && static::tenantEditContextEntries($record) !== []), Forms\Components\TextInput::make('name') ->required() ->maxLength(255), @@ -600,8 +600,8 @@ public static function form(Schema $schema): Schema ]) ->default('other') ->required(), - Forms\Components\TextInput::make('tenant_id') - ->label('Tenant ID (GUID)') + Forms\Components\TextInput::make('managed_environment_id') + ->label('ManagedEnvironment ID (GUID)') ->required() ->maxLength(255) ->unique(ignoreRecord: true), @@ -630,7 +630,7 @@ public static function getEloquentQuery(): Builder $tenantIds = $user->tenants() ->withTrashed() ->where('workspace_id', $workspaceId) - ->pluck('tenants.id'); + ->pluck('managed_environments.id'); return parent::getEloquentQuery() ->withTrashed() @@ -647,7 +647,7 @@ public static function getGlobalSearchEloquentQuery(): Builder return static::tenantOperability()->applyAdministrativeDiscoverabilityScope( static::getEloquentQuery(), - (new Tenant)->getTable(), + (new ManagedEnvironment)->getTable(), ); } @@ -659,7 +659,7 @@ public static function table(Table $table): Table return static::applyWorstFirstTriageOrdering($query); } - $nameColumn = (new Tenant)->qualifyColumn('name'); + $nameColumn = (new ManagedEnvironment)->qualifyColumn('name'); if (! method_exists($livewire, 'getTableSortColumn') || $livewire->getTableSortColumn() !== 'name') { $query->orderBy($nameColumn, $direction); @@ -671,7 +671,7 @@ public static function table(Table $table): Table ->persistFiltersInSession() ->persistSearchInSession() ->persistSortInSession() - ->recordUrl(fn (Tenant $record): string => static::getUrl('view', ['record' => $record])) + ->recordUrl(fn (ManagedEnvironment $record): string => static::getUrl('view', ['record' => $record])) ->columns([ Tables\Columns\TextColumn::make('name') ->searchable() @@ -679,29 +679,29 @@ public static function table(Table $table): Table Tables\Columns\TextColumn::make('backup_posture') ->label('Backup posture') ->badge() - ->state(fn (Tenant $record): ?string => static::backupHealthAssessmentForTenant($record)?->posture) - ->formatStateUsing(fn (mixed $state, Tenant $record): string => TenantRecoveryTriagePresentation::backupPostureLabel( + ->state(fn (ManagedEnvironment $record): ?string => static::backupHealthAssessmentForTenant($record)?->posture) + ->formatStateUsing(fn (mixed $state, ManagedEnvironment $record): string => TenantRecoveryTriagePresentation::backupPostureLabel( static::backupHealthAssessmentForTenant($record), )) - ->color(fn (Tenant $record): string => TenantRecoveryTriagePresentation::backupPostureTone( + ->color(fn (ManagedEnvironment $record): string => TenantRecoveryTriagePresentation::backupPostureTone( static::backupHealthAssessmentForTenant($record), )), Tables\Columns\TextColumn::make('recovery_evidence') ->label('Recovery evidence') ->badge() - ->state(fn (Tenant $record): ?string => TenantRecoveryTriagePresentation::recoveryEvidenceState( + ->state(fn (ManagedEnvironment $record): ?string => TenantRecoveryTriagePresentation::recoveryEvidenceState( static::recoveryEvidenceForTenant($record), )) - ->formatStateUsing(fn (mixed $state, Tenant $record): string => TenantRecoveryTriagePresentation::recoveryEvidenceLabel( + ->formatStateUsing(fn (mixed $state, ManagedEnvironment $record): string => TenantRecoveryTriagePresentation::recoveryEvidenceLabel( static::recoveryEvidenceForTenant($record), )) - ->color(fn (Tenant $record): string => TenantRecoveryTriagePresentation::recoveryEvidenceTone( + ->color(fn (ManagedEnvironment $record): string => TenantRecoveryTriagePresentation::recoveryEvidenceTone( static::recoveryEvidenceForTenant($record), )), Tables\Columns\TextColumn::make('review_state') ->label('Review state') ->badge() - ->state(fn (Tenant $record, mixed $livewire): ?string => static::selectedTriageReviewRowForTenant( + ->state(fn (ManagedEnvironment $record, mixed $livewire): ?string => static::selectedTriageReviewRowForTenant( $record, static::currentPortfolioTriageState($livewire), )['derived_state'] ?? null) @@ -709,20 +709,20 @@ public static function table(Table $table): Table ->color(BadgeRenderer::color(BadgeDomain::TenantTriageReviewState)) ->icon(BadgeRenderer::icon(BadgeDomain::TenantTriageReviewState)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::TenantTriageReviewState)) - ->description(fn (Tenant $record, mixed $livewire): ?string => static::triageReviewDescriptionForTenant( + ->description(fn (ManagedEnvironment $record, mixed $livewire): ?string => static::triageReviewDescriptionForTenant( $record, static::currentPortfolioTriageState($livewire), )), - Tables\Columns\TextColumn::make('tenant_id') - ->label('Tenant ID') + Tables\Columns\TextColumn::make('managed_environment_id') + ->label('ManagedEnvironment ID') ->copyable() - ->searchable() + ->searchable(['slug']) ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('environment') ->badge() ->formatStateUsing(TagBadgeRenderer::label(TagBadgeDomain::TenantEnvironment)) ->color(TagBadgeRenderer::color(TagBadgeDomain::TenantEnvironment)) - ->sortable(), + ->sortable(['kind']), Tables\Columns\TextColumn::make('policies_count') ->label('Policies') ->numeric() @@ -746,7 +746,7 @@ public static function table(Table $table): Table ->color(BadgeRenderer::color(BadgeDomain::TenantStatus)) ->icon(BadgeRenderer::icon(BadgeDomain::TenantStatus)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::TenantStatus)) - ->description(fn (Tenant $record): string => static::tenantLifecyclePresentation($record)->shortDescription) + ->description(fn (ManagedEnvironment $record): string => static::tenantLifecyclePresentation($record)->shortDescription) ->sortable(), Tables\Columns\TextColumn::make('created_at') ->dateTime() @@ -761,6 +761,7 @@ public static function table(Table $table): Table ->falseLabel('Archived') ->default(true), Tables\Filters\SelectFilter::make('environment') + ->attribute('kind') ->options([ 'prod' => 'PROD', 'dev' => 'DEV', @@ -807,16 +808,16 @@ public static function table(Table $table): Table ]) ->actions([ Actions\Action::make('related_onboarding') - ->label(fn (Tenant $record): string => static::relatedOnboardingDraftActionLabel($record, TenantActionSurface::TenantIndexRow) ?? 'Resume onboarding') - ->icon(fn (Tenant $record): string => static::relatedOnboardingDraftAction($record, TenantActionSurface::TenantIndexRow)?->icon ?? 'heroicon-o-arrow-path') - ->url(fn (Tenant $record): string => static::relatedOnboardingDraftUrl($record) ?? route('admin.onboarding')) - ->visible(fn (Tenant $record): bool => static::tenantIndexPrimaryAction($record)?->key === 'related_onboarding'), + ->label(fn (ManagedEnvironment $record): string => static::relatedOnboardingDraftActionLabel($record, TenantActionSurface::TenantIndexRow) ?? 'Resume onboarding') + ->icon(fn (ManagedEnvironment $record): string => static::relatedOnboardingDraftAction($record, TenantActionSurface::TenantIndexRow)?->icon ?? 'heroicon-o-arrow-path') + ->url(fn (ManagedEnvironment $record): string => static::relatedOnboardingDraftUrl($record) ?? route('admin.onboarding')) + ->visible(fn (ManagedEnvironment $record): bool => static::tenantIndexPrimaryAction($record)?->key === 'related_onboarding'), Actions\Action::make('openTenant') ->label('Open') ->icon('heroicon-o-arrow-right') ->color('primary') - ->url(function (?Tenant $record = null, mixed $livewire = null): string { - if (! $record instanceof Tenant) { + ->url(function (?ManagedEnvironment $record = null, mixed $livewire = null): string { + if (! $record instanceof ManagedEnvironment) { return '#'; } @@ -835,19 +836,19 @@ public static function table(Table $table): Table return static::tenantDashboardOpenUrl($record, $triageState); }) - ->visible(fn (Tenant $record): bool => $record->isActive() && static::tenantIndexPrimaryAction($record)?->key !== 'related_onboarding'), + ->visible(fn (ManagedEnvironment $record): bool => $record->isActive() && static::tenantIndexPrimaryAction($record)?->key !== 'related_onboarding'), ActionGroup::make([ Actions\Action::make('related_onboarding_overflow') - ->label(fn (Tenant $record): string => static::relatedOnboardingDraftActionLabel($record, TenantActionSurface::TenantIndexRow) ?? 'View related onboarding') - ->icon(fn (Tenant $record): string => static::relatedOnboardingDraftAction($record, TenantActionSurface::TenantIndexRow)?->icon ?? 'heroicon-o-eye') - ->url(fn (Tenant $record): string => static::relatedOnboardingDraftUrl($record) ?? route('admin.onboarding')) - ->visible(fn (Tenant $record): bool => static::relatedOnboardingDraftAction($record, TenantActionSurface::TenantIndexRow) instanceof TenantActionDescriptor + ->label(fn (ManagedEnvironment $record): string => static::relatedOnboardingDraftActionLabel($record, TenantActionSurface::TenantIndexRow) ?? 'View related onboarding') + ->icon(fn (ManagedEnvironment $record): string => static::relatedOnboardingDraftAction($record, TenantActionSurface::TenantIndexRow)?->icon ?? 'heroicon-o-eye') + ->url(fn (ManagedEnvironment $record): string => static::relatedOnboardingDraftUrl($record) ?? route('admin.onboarding')) + ->visible(fn (ManagedEnvironment $record): bool => static::relatedOnboardingDraftAction($record, TenantActionSurface::TenantIndexRow) instanceof TenantActionDescriptor && static::tenantIndexPrimaryAction($record)?->key !== 'related_onboarding'), Actions\Action::make('compareTenants') ->label('Compare tenants') ->icon('heroicon-o-scale') ->color('gray') - ->url(function (Tenant $record, mixed $livewire): string { + ->url(function (ManagedEnvironment $record, mixed $livewire): string { $triageState = $livewire instanceof Pages\ListTenants ? static::currentPortfolioTriageState($livewire) : []; @@ -863,12 +864,12 @@ public static function table(Table $table): Table return static::crossTenantCompareOpenUrl($record, $triageState); }) - ->visible(fn (Tenant $record): bool => static::crossTenantCompareActionVisible($record)), + ->visible(fn (ManagedEnvironment $record): bool => static::crossTenantCompareActionVisible($record)), UiEnforcement::forAction( Actions\Action::make('edit') ->label('Edit') ->icon('heroicon-o-pencil-square') - ->url(fn (Tenant $record) => static::getUrl('edit', ['record' => $record])) + ->url(fn (ManagedEnvironment $record) => static::getUrl('edit', ['record' => $record])) ) ->requireCapability(Capabilities::TENANT_MANAGE) ->apply(), @@ -882,22 +883,22 @@ public static function table(Table $table): Table ->color('success') ->requiresConfirmation() ->modalHeading('Mark reviewed') - ->modalDescription(fn (Tenant $record, mixed $livewire): string => static::triageReviewActionModalDescription( + ->modalDescription(fn (ManagedEnvironment $record, mixed $livewire): string => static::triageReviewActionModalDescription( $record, static::currentPortfolioTriageState($livewire), TenantTriageReview::STATE_REVIEWED, )) - ->visible(fn (Tenant $record, mixed $livewire): bool => static::selectedTriageReviewRowForTenant( + ->visible(fn (ManagedEnvironment $record, mixed $livewire): bool => static::selectedTriageReviewRowForTenant( $record, static::currentPortfolioTriageState($livewire), ) !== null && static::userCanSeeTriageReviewAction($record)) - ->disabled(fn (Tenant $record): bool => static::triageReviewActionIsDisabled($record)) - ->tooltip(fn (Tenant $record): ?string => static::triageReviewActionTooltip($record)) - ->before(function (Tenant $record): void { + ->disabled(fn (ManagedEnvironment $record): bool => static::triageReviewActionIsDisabled($record)) + ->tooltip(fn (ManagedEnvironment $record): ?string => static::triageReviewActionTooltip($record)) + ->before(function (ManagedEnvironment $record): void { static::authorizeTriageReviewAction($record); }) ->action(function ( - Tenant $record, + ManagedEnvironment $record, mixed $livewire, TenantTriageReviewService $service, ): void { @@ -914,22 +915,22 @@ public static function table(Table $table): Table ->color('warning') ->requiresConfirmation() ->modalHeading('Mark follow-up needed') - ->modalDescription(fn (Tenant $record, mixed $livewire): string => static::triageReviewActionModalDescription( + ->modalDescription(fn (ManagedEnvironment $record, mixed $livewire): string => static::triageReviewActionModalDescription( $record, static::currentPortfolioTriageState($livewire), TenantTriageReview::STATE_FOLLOW_UP_NEEDED, )) - ->visible(fn (Tenant $record, mixed $livewire): bool => static::selectedTriageReviewRowForTenant( + ->visible(fn (ManagedEnvironment $record, mixed $livewire): bool => static::selectedTriageReviewRowForTenant( $record, static::currentPortfolioTriageState($livewire), ) !== null && static::userCanSeeTriageReviewAction($record)) - ->disabled(fn (Tenant $record): bool => static::triageReviewActionIsDisabled($record)) - ->tooltip(fn (Tenant $record): ?string => static::triageReviewActionTooltip($record)) - ->before(function (Tenant $record): void { + ->disabled(fn (ManagedEnvironment $record): bool => static::triageReviewActionIsDisabled($record)) + ->tooltip(fn (ManagedEnvironment $record): ?string => static::triageReviewActionTooltip($record)) + ->before(function (ManagedEnvironment $record): void { static::authorizeTriageReviewAction($record); }) ->action(function ( - Tenant $record, + ManagedEnvironment $record, mixed $livewire, TenantTriageReviewService $service, ): void { @@ -948,8 +949,8 @@ public static function table(Table $table): Table ->color('danger') ->icon('heroicon-o-trash') ->requiresConfirmation() - ->visible(fn (?Tenant $record): bool => (bool) $record?->trashed()) - ->action(function (?Tenant $record, AuditLogger $auditLogger): void { + ->visible(fn (?ManagedEnvironment $record): bool => (bool) $record?->trashed()) + ->action(function (?ManagedEnvironment $record, AuditLogger $auditLogger): void { if ($record === null) { return; } @@ -967,11 +968,11 @@ public static function table(Table $table): Table abort(403); } - $tenant = Tenant::withTrashed()->find($record->id); + $tenant = ManagedEnvironment::withTrashed()->find($record->id); if (! $tenant?->trashed()) { Notification::make() - ->title('Tenant must be archived first') + ->title('ManagedEnvironment must be archived first') ->danger() ->send(); @@ -984,13 +985,13 @@ public static function table(Table $table): Table resourceType: 'tenant', resourceId: (string) $tenant->id, status: 'success', - context: ['metadata' => ['tenant_id' => $tenant->tenant_id]] + context: ['metadata' => ['managed_environment_id' => $tenant->managed_environment_id]] ); $tenant->forceDelete(); Notification::make() - ->title('Tenant permanently deleted') + ->title('ManagedEnvironment permanently deleted') ->success() ->send(); }), @@ -1056,8 +1057,8 @@ public static function table(Table $table): Table $resolver = app(CapabilityResolver::class); return $records - ->filter(fn ($record) => $record instanceof Tenant) - ->contains(fn (Tenant $tenant): bool => ! $resolver->can($user, $tenant, Capabilities::TENANT_SYNC)); + ->filter(fn ($record) => $record instanceof ManagedEnvironment) + ->contains(fn (ManagedEnvironment $tenant): bool => ! $resolver->can($user, $tenant, Capabilities::TENANT_SYNC)); }) ->tooltip(function (Collection $records): ?string { $user = auth()->user(); @@ -1074,8 +1075,8 @@ public static function table(Table $table): Table $resolver = app(CapabilityResolver::class); $isDenied = $records - ->filter(fn ($record) => $record instanceof Tenant) - ->contains(fn (Tenant $tenant): bool => ! $resolver->can($user, $tenant, Capabilities::TENANT_SYNC)); + ->filter(fn ($record) => $record instanceof ManagedEnvironment) + ->contains(fn (ManagedEnvironment $tenant): bool => ! $resolver->can($user, $tenant, Capabilities::TENANT_SYNC)); return $isDenied ? UiTooltips::insufficientPermission() : null; }) @@ -1090,8 +1091,8 @@ public static function table(Table $table): Table $resolver = app(CapabilityResolver::class); $eligible = $records - ->filter(fn ($record) => $record instanceof Tenant && $record->isActive()) - ->filter(fn (Tenant $tenant) => $resolver->can($user, $tenant, Capabilities::TENANT_SYNC)); + ->filter(fn ($record) => $record instanceof ManagedEnvironment && $record->isActive()) + ->filter(fn (ManagedEnvironment $tenant) => $resolver->can($user, $tenant, Capabilities::TENANT_SYNC)); if ($eligible->isEmpty()) { Notification::make() @@ -1104,7 +1105,7 @@ public static function table(Table $table): Table return; } - $tenantContext = Tenant::current() ?? $eligible->first(); + $tenantContext = ManagedEnvironment::current() ?? $eligible->first(); if (! $tenantContext) { return; @@ -1124,7 +1125,7 @@ public static function table(Table $table): Table tenant: $tenantContext, type: 'tenant.sync', targetScope: [ - 'entra_tenant_id' => (string) ($tenantContext->tenant_id ?? $tenantContext->external_id), + 'entra_tenant_id' => (string) ($tenantContext->managed_environment_id ?? $tenantContext->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenantContext, $user, $ids): void { @@ -1209,7 +1210,7 @@ public static function sanitizeTriageSort(mixed $value): ?string * triage_sort?: string|null * } $triageState */ - public static function tenantDashboardOpenUrl(Tenant $record, array $triageState = []): string + public static function tenantDashboardOpenUrl(ManagedEnvironment $record, array $triageState = []): string { $arrivalState = static::portfolioArrivalStateForTenant($record, $triageState); @@ -1234,7 +1235,7 @@ public static function tenantDashboardOpenUrl(Tenant $record, array $triageState * triage_sort?: string|null * } $triageState */ - public static function crossTenantCompareOpenUrl(Tenant $record, array $triageState = []): string + public static function crossTenantCompareOpenUrl(ManagedEnvironment $record, array $triageState = []): string { return static::crossTenantCompareOpenUrlForSelection( targetTenant: $record, @@ -1251,9 +1252,9 @@ public static function crossTenantCompareOpenUrl(Tenant $record, array $triageSt * } $triageState */ public static function crossTenantCompareOpenUrlForSelection( - Tenant $targetTenant, + ManagedEnvironment $targetTenant, array $triageState = [], - ?Tenant $sourceTenant = null, + ?ManagedEnvironment $sourceTenant = null, ): string { $normalizedState = static::portfolioReturnFilters( static::sanitizeBackupPostures($triageState['backup_posture'] ?? []), @@ -1267,7 +1268,7 @@ public static function crossTenantCompareOpenUrlForSelection( targetTenant: $targetTenant, navigationContext: CanonicalNavigationContext::forTenantRegistry( backLinkUrl: static::getUrl(panel: 'admin', parameters: $normalizedState), - tenantId: $sourceTenant instanceof Tenant ? null : (int) $targetTenant->getKey(), + tenantId: $sourceTenant instanceof ManagedEnvironment ? null : (int) $targetTenant->getKey(), ), ); } @@ -1281,7 +1282,7 @@ public static function crossTenantCompareOpenUrlForSelection( * } $triageState * @return array|null */ - private static function portfolioArrivalStateForTenant(Tenant $record, array $triageState = []): ?array + private static function portfolioArrivalStateForTenant(ManagedEnvironment $record, array $triageState = []): ?array { $backupPostures = static::sanitizeBackupPostures($triageState['backup_posture'] ?? []); $recoveryEvidenceFilters = static::sanitizeRecoveryEvidenceStates($triageState['recovery_evidence'] ?? []); @@ -1362,7 +1363,7 @@ private static function portfolioReturnFiltersFromRequest(array $query): array ); } - private static function crossTenantCompareActionVisible(Tenant $record): bool + private static function crossTenantCompareActionVisible(ManagedEnvironment $record): bool { if (! $record->isActive()) { return false; @@ -1410,19 +1411,19 @@ private static function crossTenantCompareBulkDisabledReason(Collection $records } $tenants = $records - ->filter(fn ($record): bool => $record instanceof Tenant) + ->filter(fn ($record): bool => $record instanceof ManagedEnvironment) ->values(); if ($records->count() !== 2 || $tenants->count() !== 2) { return 'Select exactly two tenants to compare.'; } - if ($tenants->contains(fn (Tenant $tenant): bool => ! $tenant->isActive())) { + if ($tenants->contains(fn (ManagedEnvironment $tenant): bool => ! $tenant->isActive())) { return 'Only active tenants can be compared.'; } $workspaceIds = $tenants - ->map(fn (Tenant $tenant): int => (int) $tenant->workspace_id) + ->map(fn (ManagedEnvironment $tenant): int => (int) $tenant->workspace_id) ->unique() ->values(); @@ -1449,7 +1450,7 @@ private static function crossTenantCompareBulkDisabledReason(Collection $records /** @var CapabilityResolver $tenantResolver */ $tenantResolver = app(CapabilityResolver::class); - $isDenied = $tenants->contains(fn (Tenant $tenant): bool => ! $user->canAccessTenant($tenant) + $isDenied = $tenants->contains(fn (ManagedEnvironment $tenant): bool => ! $user->canAccessTenant($tenant) || ! $tenantResolver->can($user, $tenant, Capabilities::TENANT_VIEW)); return $isDenied ? UiTooltips::insufficientPermission() : null; @@ -1492,8 +1493,8 @@ private static function crossTenantCompareInactiveSelectionRecordKeys(mixed $liv } return collect($tableRecords) - ->filter(fn ($record): bool => $record instanceof Tenant && ! $record->isActive()) - ->map(fn (Tenant $tenant): string => (string) $livewire->getTableRecordKey($tenant)) + ->filter(fn ($record): bool => $record instanceof ManagedEnvironment && ! $record->isActive()) + ->map(fn (ManagedEnvironment $tenant): string => (string) $livewire->getTableRecordKey($tenant)) ->values() ->all(); } @@ -1514,7 +1515,7 @@ private static function crossTenantCompareBulkOpenUrl(Collection $records, mixed } $tenants = $records - ->filter(fn ($record): bool => $record instanceof Tenant) + ->filter(fn ($record): bool => $record instanceof ManagedEnvironment) ->values(); return static::crossTenantCompareOpenUrlForSelection( @@ -1658,7 +1659,7 @@ private static function triageSortIsWorstFirst(?string $value): bool return $value === TenantRecoveryTriagePresentation::TRIAGE_SORT_WORST_FIRST; } - private static function backupHealthAssessmentForTenant(Tenant $tenant): ?TenantBackupHealthAssessment + private static function backupHealthAssessmentForTenant(ManagedEnvironment $tenant): ?TenantBackupHealthAssessment { return static::postureSnapshot()['backup_health'][(int) $tenant->getKey()] ?? null; } @@ -1666,7 +1667,7 @@ private static function backupHealthAssessmentForTenant(Tenant $tenant): ?Tenant /** * @return array|null */ - private static function recoveryEvidenceForTenant(Tenant $tenant): ?array + private static function recoveryEvidenceForTenant(ManagedEnvironment $tenant): ?array { return static::postureSnapshot()['recovery_evidence'][(int) $tenant->getKey()] ?? null; } @@ -1743,7 +1744,7 @@ private static function triageReviewSnapshot(): array * } $triageState * @return array|null */ - private static function selectedTriageReviewRowForTenant(Tenant $tenant, array $triageState = []): ?array + private static function selectedTriageReviewRowForTenant(ManagedEnvironment $tenant, array $triageState = []): ?array { $rows = static::triageReviewSnapshot()['rows'][(int) $tenant->getKey()] ?? null; @@ -1863,7 +1864,7 @@ private static function triageConcernFamilyLabel(string $concernFamily): string * triage_sort?: string|null * } $triageState */ - private static function triageReviewDescriptionForTenant(Tenant $tenant, array $triageState = []): ?string + private static function triageReviewDescriptionForTenant(ManagedEnvironment $tenant, array $triageState = []): ?string { $row = static::selectedTriageReviewRowForTenant($tenant, $triageState); @@ -1893,7 +1894,7 @@ private static function triageReviewDescriptionForTenant(Tenant $tenant, array $ * } $triageState */ private static function triageReviewActionModalDescription( - Tenant $tenant, + ManagedEnvironment $tenant, array $triageState, string $targetManualState, ): string { @@ -1914,7 +1915,7 @@ private static function triageReviewActionModalDescription( ]); } - private static function userCanSeeTriageReviewAction(Tenant $tenant): bool + private static function userCanSeeTriageReviewAction(ManagedEnvironment $tenant): bool { $user = auth()->user(); @@ -1925,7 +1926,7 @@ private static function userCanSeeTriageReviewAction(Tenant $tenant): bool return app(CapabilityResolver::class)->isMember($user, $tenant); } - private static function triageReviewActionIsDisabled(Tenant $tenant): bool + private static function triageReviewActionIsDisabled(ManagedEnvironment $tenant): bool { $user = auth()->user(); @@ -1942,7 +1943,7 @@ private static function triageReviewActionIsDisabled(Tenant $tenant): bool return ! $resolver->can($user, $tenant, Capabilities::TENANT_TRIAGE_REVIEW_MANAGE); } - private static function triageReviewActionTooltip(Tenant $tenant): ?string + private static function triageReviewActionTooltip(ManagedEnvironment $tenant): ?string { $user = auth()->user(); @@ -1959,7 +1960,7 @@ private static function triageReviewActionTooltip(Tenant $tenant): ?string return null; } - private static function authorizeTriageReviewAction(Tenant $tenant): void + private static function authorizeTriageReviewAction(ManagedEnvironment $tenant): void { $user = auth()->user(); @@ -1987,7 +1988,7 @@ private static function authorizeTriageReviewAction(Tenant $tenant): void * } $triageState */ private static function handleTriageReviewMutation( - Tenant $tenant, + ManagedEnvironment $tenant, array $triageState, string $targetManualState, TenantTriageReviewService $service, @@ -2053,7 +2054,7 @@ private static function handleTriageReviewMutation( * } $triageState * @return array|null */ - private static function selectedActionTriageReviewRowForTenant(Tenant $tenant, array $triageState = []): ?array + private static function selectedActionTriageReviewRowForTenant(ManagedEnvironment $tenant, array $triageState = []): ?array { $tenantId = (int) $tenant->getKey(); $workspaceId = (int) $tenant->workspace_id; @@ -2100,7 +2101,7 @@ private static function applySnapshotTenantSubsetFilter( return $query->whereRaw('1 = 0'); } - return $query->whereIn((new Tenant)->qualifyColumn('id'), $tenantIds); + return $query->whereIn((new ManagedEnvironment)->qualifyColumn('id'), $tenantIds); } private static function applyRecoveryEvidenceFilter(Builder $query, array $selectedValues): Builder @@ -2124,7 +2125,7 @@ private static function applyRecoveryEvidenceFilter(Builder $query, array $selec return $query->whereRaw('1 = 0'); } - return $query->whereIn((new Tenant)->qualifyColumn('id'), $tenantIds); + return $query->whereIn((new ManagedEnvironment)->qualifyColumn('id'), $tenantIds); } /** @@ -2166,7 +2167,7 @@ private static function applyReviewStateFilter(Builder $query, array $selectedVa return $query->whereRaw('1 = 0'); } - return $query->whereIn((new Tenant)->qualifyColumn('id'), $tenantIds); + return $query->whereIn((new ManagedEnvironment)->qualifyColumn('id'), $tenantIds); } private static function applyWorstFirstTriageOrdering(Builder $query): Builder @@ -2177,8 +2178,8 @@ private static function applyWorstFirstTriageOrdering(Builder $query): Builder return $query; } - $qualifiedId = (new Tenant)->qualifyColumn('id'); - $qualifiedName = (new Tenant)->qualifyColumn('name'); + $qualifiedId = (new ManagedEnvironment)->qualifyColumn('id'); + $qualifiedName = (new ManagedEnvironment)->qualifyColumn('name'); $clauses = []; $bindings = []; @@ -2290,9 +2291,9 @@ private static function visibleTenantIdsForPostureSnapshot(): array return $query ->reorder() - ->orderBy((new Tenant)->qualifyColumn('name')) - ->orderBy((new Tenant)->qualifyColumn('id')) - ->pluck((new Tenant)->qualifyColumn('id')) + ->orderBy((new ManagedEnvironment)->qualifyColumn('name')) + ->orderBy((new ManagedEnvironment)->qualifyColumn('id')) + ->pluck((new ManagedEnvironment)->qualifyColumn('id')) ->map(static fn (mixed $tenantId): int => (int) $tenantId) ->all(); } @@ -2343,7 +2344,7 @@ public static function infolist(Schema $schema): Schema Section::make('Identity') ->schema([ Infolists\Components\TextEntry::make('name'), - Infolists\Components\TextEntry::make('tenant_id')->label('Tenant ID')->copyable(), + Infolists\Components\TextEntry::make('managed_environment_id')->label('ManagedEnvironment ID')->copyable(), Infolists\Components\TextEntry::make('domain')->copyable(), Infolists\Components\TextEntry::make('status') ->badge() @@ -2353,7 +2354,7 @@ public static function infolist(Schema $schema): Schema ->iconColor(BadgeRenderer::iconColor(BadgeDomain::TenantStatus)), Infolists\Components\TextEntry::make('lifecycle_summary') ->label('Lifecycle summary') - ->state(fn (Tenant $record): string => static::tenantLifecyclePresentation($record)->longDescription) + ->state(fn (ManagedEnvironment $record): string => static::tenantLifecyclePresentation($record)->longDescription) ->columnSpanFull(), ]) ->columns(2) @@ -2363,16 +2364,16 @@ public static function infolist(Schema $schema): Schema Infolists\Components\ViewEntry::make('related_context') ->label('') ->view('filament.infolists.entries.related-context') - ->state(fn (Tenant $record): array => static::tenantViewContextEntries($record)) + ->state(fn (ManagedEnvironment $record): array => static::tenantViewContextEntries($record)) ->columnSpanFull(), ]) ->columnSpanFull() - ->visible(fn (Tenant $record): bool => static::tenantViewContextEntries($record) !== []), + ->visible(fn (ManagedEnvironment $record): bool => static::tenantViewContextEntries($record) !== []), Section::make('Provider') ->schema([ Infolists\Components\ViewEntry::make('provider_connection_state') ->label('Provider connection') - ->state(fn (Tenant $record): array => static::providerConnectionState($record)) + ->state(fn (ManagedEnvironment $record): array => static::providerConnectionState($record)) ->view('filament.infolists.entries.provider-connection-state') ->columnSpanFull(), ]) @@ -2385,7 +2386,7 @@ public static function infolist(Schema $schema): Schema ->icon('heroicon-o-shield-exclamation') ->color('warning') ->columnSpanFull() - ->visible(fn (Tenant $record): bool => blank($record->rbac_status)), + ->visible(fn (ManagedEnvironment $record): bool => blank($record->rbac_status)), Infolists\Components\TextEntry::make('rbac_status') ->label('RBAC status') ->badge() @@ -2393,10 +2394,10 @@ public static function infolist(Schema $schema): Schema ->color(BadgeRenderer::color(BadgeDomain::TenantRbacStatus)) ->icon(BadgeRenderer::icon(BadgeDomain::TenantRbacStatus)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::TenantRbacStatus)) - ->visible(fn (Tenant $record): bool => filled($record->rbac_status)), + ->visible(fn (ManagedEnvironment $record): bool => filled($record->rbac_status)), Infolists\Components\TextEntry::make('rbac_explanation') ->label('Summary') - ->state(function (Tenant $record): string { + ->state(function (ManagedEnvironment $record): string { $status = $record->rbac_status; $lastChecked = $record->rbac_last_checked_at; $threshold = (int) config('tenantpilot.hardening.intune_write_gate.freshness_threshold_hours', 24); @@ -2416,24 +2417,24 @@ public static function infolist(Schema $schema): Schema return 'RBAC is healthy and up to date. Write operations are permitted.'; }) ->columnSpanFull() - ->visible(fn (Tenant $record): bool => filled($record->rbac_status)), + ->visible(fn (ManagedEnvironment $record): bool => filled($record->rbac_status)), Infolists\Components\TextEntry::make('rbac_last_checked_at') ->label('Last checked') ->since() - ->visible(fn (Tenant $record): bool => filled($record->rbac_status)), + ->visible(fn (ManagedEnvironment $record): bool => filled($record->rbac_status)), Infolists\Components\TextEntry::make('rbac_role_display_name') ->label('RBAC role') - ->visible(fn (Tenant $record): bool => filled($record->rbac_status)), + ->visible(fn (ManagedEnvironment $record): bool => filled($record->rbac_status)), Section::make('RBAC Details') ->schema([ Infolists\Components\TextEntry::make('rbac_status_reason_label') ->label('Reason') - ->state(fn (Tenant $record): ?string => app(\App\Support\ReasonTranslation\ReasonPresenter::class) + ->state(fn (ManagedEnvironment $record): ?string => app(\App\Support\ReasonTranslation\ReasonPresenter::class) ->primaryLabel(app(\App\Support\ReasonTranslation\ReasonPresenter::class)->forRbacReason($record->rbac_status_reason, 'detail'))) ->visible(fn (?string $state): bool => filled($state)), Infolists\Components\TextEntry::make('rbac_status_reason_explanation') ->label('Explanation') - ->state(fn (Tenant $record): ?string => app(\App\Support\ReasonTranslation\ReasonPresenter::class) + ->state(fn (ManagedEnvironment $record): ?string => app(\App\Support\ReasonTranslation\ReasonPresenter::class) ->shortExplanation(app(\App\Support\ReasonTranslation\ReasonPresenter::class)->forRbacReason($record->rbac_status_reason, 'detail'))) ->visible(fn (?string $state): bool => filled($state)) ->columnSpanFull(), @@ -2456,12 +2457,12 @@ public static function infolist(Schema $schema): Schema Infolists\Components\ViewEntry::make('rbac_summary') ->label('Last RBAC Setup') ->view('filament.infolists.entries.rbac-summary') - ->visible(fn (Tenant $record) => filled($record->rbac_last_setup_at)), + ->visible(fn (ManagedEnvironment $record) => filled($record->rbac_last_setup_at)), ]) ->columns(2) ->collapsible() ->collapsed() - ->visible(fn (Tenant $record): bool => filled($record->rbac_status)), + ->visible(fn (ManagedEnvironment $record): bool => filled($record->rbac_status)), ]) ->columns(2) ->columnSpanFull() @@ -2470,7 +2471,7 @@ public static function infolist(Schema $schema): Schema ->schema([ Infolists\Components\TextEntry::make('admin_consent_url') ->label('Grant admin consent URL') - ->state(fn (Tenant $record) => static::adminConsentUrl($record)) + ->state(fn (ManagedEnvironment $record) => static::adminConsentUrl($record)) ->visible(fn (?string $state) => filled($state)) ->copyable() ->columnSpanFull(), @@ -2489,7 +2490,7 @@ public static function infolist(Schema $schema): Schema ->schema([ Infolists\Components\RepeatableEntry::make('permissions') ->label('') - ->state(fn (Tenant $record) => static::storedPermissionSnapshot($record)) + ->state(fn (ManagedEnvironment $record) => static::storedPermissionSnapshot($record)) ->schema([ Infolists\Components\TextEntry::make('key')->label('Permission')->badge(), Infolists\Components\TextEntry::make('type')->badge(), @@ -2513,7 +2514,7 @@ public static function infolist(Schema $schema): Schema /** * @return array,status:string,details:array|null}> */ - protected static function storedPermissionSnapshot(Tenant $tenant): array + protected static function storedPermissionSnapshot(ManagedEnvironment $tenant): array { $required = config('intune_permissions.permissions', []); @@ -2546,7 +2547,7 @@ protected static function storedPermissionSnapshot(Tenant $tenant): array return $snapshot; } - protected static function tenantLifecyclePresentation(Tenant $tenant): TenantLifecyclePresentation + protected static function tenantLifecyclePresentation(ManagedEnvironment $tenant): TenantLifecyclePresentation { return TenantLifecyclePresentation::fromTenant($tenant); } @@ -2564,7 +2565,7 @@ public static function tenantActionPolicy(): TenantActionPolicySurface /** * @return Collection */ - public static function tenantActionCatalog(Tenant $tenant, TenantActionSurface $surface = TenantActionSurface::TenantIndexRow): Collection + public static function tenantActionCatalog(ManagedEnvironment $tenant, TenantActionSurface $surface = TenantActionSurface::TenantIndexRow): Collection { $cacheKey = static::tenantActionCatalogCacheKey($tenant, $surface); @@ -2575,35 +2576,35 @@ public static function tenantActionCatalog(Tenant $tenant, TenantActionSurface $ return static::$tenantActionCatalogCache[$cacheKey]; } - public static function lifecycleActionDescriptor(Tenant $tenant, TenantActionSurface $surface = TenantActionSurface::TenantIndexRow): ?TenantActionDescriptor + public static function lifecycleActionDescriptor(ManagedEnvironment $tenant, TenantActionSurface $surface = TenantActionSurface::TenantIndexRow): ?TenantActionDescriptor { return static::tenantActionDescriptorForSurface($tenant, $surface, 'restore') ?? static::tenantActionDescriptorForSurface($tenant, $surface, 'archive'); } - public static function tenantIndexPrimaryAction(Tenant $tenant): ?TenantActionDescriptor + public static function tenantIndexPrimaryAction(ManagedEnvironment $tenant): ?TenantActionDescriptor { $catalog = static::tenantActionCatalog($tenant, TenantActionSurface::TenantIndexRow); return $catalog[1] ?? null; } - public static function relatedOnboardingDraft(Tenant $tenant): ?TenantOnboardingSession + public static function relatedOnboardingDraft(ManagedEnvironment $tenant): ?TenantOnboardingSession { return static::tenantActionPolicy()->relatedOnboardingDraft($tenant); } - public static function relatedOnboardingDraftAction(Tenant $tenant, TenantActionSurface $surface = TenantActionSurface::TenantViewHeader): ?TenantActionDescriptor + public static function relatedOnboardingDraftAction(ManagedEnvironment $tenant, TenantActionSurface $surface = TenantActionSurface::TenantViewHeader): ?TenantActionDescriptor { return static::tenantActionDescriptorForSurface($tenant, $surface, 'related_onboarding'); } - public static function relatedOnboardingDraftActionLabel(Tenant $tenant, TenantActionSurface $surface = TenantActionSurface::TenantViewHeader): ?string + public static function relatedOnboardingDraftActionLabel(ManagedEnvironment $tenant, TenantActionSurface $surface = TenantActionSurface::TenantViewHeader): ?string { return static::relatedOnboardingDraftAction($tenant, $surface)?->label; } - public static function relatedOnboardingDraftUrl(Tenant $tenant): ?string + public static function relatedOnboardingDraftUrl(ManagedEnvironment $tenant): ?string { $draft = static::relatedOnboardingDraft($tenant); @@ -2617,14 +2618,14 @@ public static function relatedOnboardingDraftUrl(Tenant $tenant): ?string /** * @return array> */ - public static function tenantViewContextEntries(Tenant $tenant): array + public static function tenantViewContextEntries(ManagedEnvironment $tenant): array { $entries = []; if (static::canEdit($tenant)) { $entries[] = RelatedContextEntry::available( key: 'tenant_edit', - label: 'Tenant edit', + label: 'ManagedEnvironment edit', value: 'Edit tenant', secondaryValue: 'Update tenant identity and lifecycle metadata.', targetUrl: static::getUrl('edit', ['record' => $tenant]), @@ -2636,7 +2637,7 @@ public static function tenantViewContextEntries(Tenant $tenant): array } elseif (static::viewerCanInspectTenantContext($tenant)) { $entries[] = RelatedContextEntry::unavailable( key: 'tenant_edit', - label: 'Tenant edit', + label: 'ManagedEnvironment edit', state: new UnavailableRelationState( relationKey: 'tenant_edit', referenceValue: null, @@ -2655,7 +2656,7 @@ public static function tenantViewContextEntries(Tenant $tenant): array label: 'Provider connections', value: 'Open provider connections', secondaryValue: 'Inspect consent, credentials, and health for this tenant.', - targetUrl: ProviderConnectionResource::getUrl('index', ['tenant_id' => $tenant->external_id], panel: 'admin'), + targetUrl: ProviderConnectionResource::getUrl('index', ['managed_environment_id' => $tenant->external_id], panel: 'admin'), targetKind: 'canonical_page', priority: 20, actionLabel: 'Open', @@ -2703,12 +2704,12 @@ public static function tenantViewContextEntries(Tenant $tenant): array /** * @return array> */ - public static function tenantEditContextEntries(Tenant $tenant): array + public static function tenantEditContextEntries(ManagedEnvironment $tenant): array { $entries = [ RelatedContextEntry::available( key: 'tenant_view', - label: 'Tenant detail', + label: 'ManagedEnvironment detail', value: 'Open tenant detail', secondaryValue: 'Review verification, RBAC, and lifecycle context without leaving the tenant resource.', targetUrl: static::getUrl('view', ['record' => $tenant]), @@ -2742,9 +2743,9 @@ public static function tenantEditContextEntries(Tenant $tenant): array ->all(); } - public static function tenantEditContextHtml(?Tenant $tenant): HtmlString + public static function tenantEditContextHtml(?ManagedEnvironment $tenant): HtmlString { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return new HtmlString(''); } @@ -2759,29 +2760,29 @@ public static function tenantEditContextHtml(?Tenant $tenant): HtmlString ])->render()); } - public static function tenantViewLifecycleGroupVisible(Tenant $tenant): bool + public static function tenantViewLifecycleGroupVisible(ManagedEnvironment $tenant): bool { return in_array(static::lifecycleActionDescriptor($tenant, TenantActionSurface::TenantViewHeader)?->key, ['archive', 'restore'], true); } - public static function tenantViewExternalGroupVisible(Tenant $tenant): bool + public static function tenantViewExternalGroupVisible(ManagedEnvironment $tenant): bool { return static::adminConsentUrl($tenant) !== null || static::entraUrl($tenant) !== null; } - public static function tenantViewSetupGroupVisible(Tenant $tenant): bool + public static function tenantViewSetupGroupVisible(ManagedEnvironment $tenant): bool { return $tenant->isActive(); } - public static function verificationActionVisible(Tenant $tenant): bool + public static function verificationActionVisible(ManagedEnvironment $tenant): bool { $outcome = static::verificationReadinessOutcome($tenant); return $outcome->allowed || $outcome->isDeniedForCapability(); } - public static function verificationReadinessOutcome(Tenant $tenant): TenantOperabilityOutcome + public static function verificationReadinessOutcome(ManagedEnvironment $tenant): TenantOperabilityOutcome { $user = auth()->user(); @@ -2794,7 +2795,7 @@ public static function verificationReadinessOutcome(Tenant $tenant): TenantOpera ); } - private static function tenantActionDescriptorForSurface(Tenant $tenant, TenantActionSurface $surface, string $key): ?TenantActionDescriptor + private static function tenantActionDescriptorForSurface(ManagedEnvironment $tenant, TenantActionSurface $surface, string $key): ?TenantActionDescriptor { $descriptor = static::tenantActionCatalog($tenant, $surface) ->first(fn (TenantActionDescriptor $descriptor): bool => $descriptor->key === $key); @@ -2802,7 +2803,7 @@ private static function tenantActionDescriptorForSurface(Tenant $tenant, TenantA return $descriptor instanceof TenantActionDescriptor ? $descriptor : null; } - private static function tenantActionCatalogCacheKey(Tenant $tenant, TenantActionSurface $surface): string + private static function tenantActionCatalogCacheKey(ManagedEnvironment $tenant, TenantActionSurface $surface): string { $relatedDraft = static::relatedOnboardingDraft($tenant); @@ -2822,14 +2823,14 @@ private static function tenantActionCatalogCacheKey(Tenant $tenant, TenantAction ]); } - private static function viewerCanInspectTenantContext(Tenant $tenant): bool + private static function viewerCanInspectTenantContext(ManagedEnvironment $tenant): bool { $user = auth()->user(); return $user instanceof User && $user->canAccessTenant($tenant); } - private static function viewerHasTenantCapability(Tenant $tenant, string $capability): bool + private static function viewerHasTenantCapability(ManagedEnvironment $tenant, string $capability): bool { $user = auth()->user(); @@ -2844,7 +2845,7 @@ private static function viewerHasTenantCapability(Tenant $tenant, string $capabi && $resolver->can($user, $tenant, $capability); } - public static function archiveTenant(Tenant $record, WorkspaceAuditLogger $auditLogger, string $reason): void + public static function archiveTenant(ManagedEnvironment $record, WorkspaceAuditLogger $auditLogger, string $reason): void { $user = auth()->user(); $reason = static::validatedLifecycleReason($reason, 'archive_reason'); @@ -2882,7 +2883,7 @@ public static function archiveTenant(Tenant $record, WorkspaceAuditLogger $audit tenant: $record, action: AuditActionId::TenantArchived, actor: $user, - context: ['metadata' => ['tenant_id' => $record->tenant_id, 'reason' => $reason]] + context: ['metadata' => ['managed_environment_id' => $record->managed_environment_id, 'reason' => $reason]] ); Notification::make() @@ -2892,7 +2893,7 @@ public static function archiveTenant(Tenant $record, WorkspaceAuditLogger $audit ->send(); } - public static function restoreTenant(Tenant $record, WorkspaceAuditLogger $auditLogger): void + public static function restoreTenant(ManagedEnvironment $record, WorkspaceAuditLogger $auditLogger): void { $user = auth()->user(); @@ -2929,7 +2930,7 @@ public static function restoreTenant(Tenant $record, WorkspaceAuditLogger $audit tenant: $record, action: AuditActionId::TenantRestored, actor: $user, - context: ['metadata' => ['tenant_id' => $record->tenant_id]] + context: ['metadata' => ['managed_environment_id' => $record->managed_environment_id]] ); Notification::make() @@ -2995,14 +2996,14 @@ public static function rbacAction(): Actions\Action ->searchable() ->optionsLimit(20) ->searchDebounce(400) - ->getSearchResultsUsing(fn (string $search, ?Tenant $record) => static::roleSearchOptions($record, $search)) - ->getOptionLabelUsing(fn (?string $value, ?Tenant $record) => static::roleLabelFromCache($record, $value)) - ->helperText(fn (?Tenant $record) => static::roleSearchHelper($record)) - ->hintAction(fn (?Tenant $record) => static::syncRoleDefinitionsAction()) + ->getSearchResultsUsing(fn (string $search, ?ManagedEnvironment $record) => static::roleSearchOptions($record, $search)) + ->getOptionLabelUsing(fn (?string $value, ?ManagedEnvironment $record) => static::roleLabelFromCache($record, $value)) + ->helperText(fn (?ManagedEnvironment $record) => static::roleSearchHelper($record)) + ->hintAction(fn (?ManagedEnvironment $record) => static::syncRoleDefinitionsAction()) ->hint('Wizard grants Intune RBAC roles only. "Intune Administrator" is an Entra directory role and is not assigned here.') ->noSearchResultsMessage('No Intune RBAC roleDefinitions found (tenant may restrict RBAC or missing permission).') ->loadingMessage('Loading roles...') - ->afterStateUpdated(function (Set $set, ?string $state, ?Tenant $record) { + ->afterStateUpdated(function (Set $set, ?string $state, ?ManagedEnvironment $record) { $set('role_display_name', static::roleNameFromCache($record, $state)); }), Forms\Components\Hidden::make('role_display_name') @@ -3025,9 +3026,9 @@ public static function rbacAction(): Actions\Action ->placeholder('Search security groups') ->visible(fn (Get $get) => $get('scope') === 'scope_group') ->required(fn (Get $get) => $get('scope') === 'scope_group') - ->disabled(fn (?Tenant $record): bool => static::delegatedToken($record) === null) - ->getSearchResultsUsing(fn (string $search, ?Tenant $record) => static::groupSearchOptions($record, $search)) - ->getOptionLabelUsing(fn (?string $value, ?Tenant $record) => static::groupLabelFromCache($record, $value)) + ->disabled(fn (?ManagedEnvironment $record): bool => static::delegatedToken($record) === null) + ->getSearchResultsUsing(fn (string $search, ?ManagedEnvironment $record) => static::groupSearchOptions($record, $search)) + ->getOptionLabelUsing(fn (?string $value, ?ManagedEnvironment $record) => static::groupLabelFromCache($record, $value)) ->noSearchResultsMessage('No security groups found') ->loadingMessage('Searching groups...'), Forms\Components\Select::make('group_mode') @@ -3052,14 +3053,14 @@ public static function rbacAction(): Actions\Action ->placeholder('Search security groups') ->visible(fn (Get $get) => $get('group_mode') === 'existing') ->required(fn (Get $get) => $get('group_mode') === 'existing') - ->disabled(fn (?Tenant $record): bool => static::delegatedToken($record) === null) - ->getSearchResultsUsing(fn (string $search, ?Tenant $record) => static::groupSearchOptions($record, $search)) - ->getOptionLabelUsing(fn (?string $value, ?Tenant $record) => static::groupLabelFromCache($record, $value)) + ->disabled(fn (?ManagedEnvironment $record): bool => static::delegatedToken($record) === null) + ->getSearchResultsUsing(fn (string $search, ?ManagedEnvironment $record) => static::groupSearchOptions($record, $search)) + ->getOptionLabelUsing(fn (?string $value, ?ManagedEnvironment $record) => static::groupLabelFromCache($record, $value)) ->noSearchResultsMessage('No security groups found') ->loadingMessage('Searching groups...'), ]) - ->visible(fn (Tenant $record): bool => $record->isActive()) - ->disabled(function (Tenant $record): bool { + ->visible(fn (ManagedEnvironment $record): bool => $record->isActive()) + ->disabled(function (ManagedEnvironment $record): bool { $user = auth()->user(); if (! $user instanceof User) { @@ -3074,7 +3075,7 @@ public static function rbacAction(): Actions\Action ->requiresConfirmation() ->action(function ( array $data, - Tenant $record, + ManagedEnvironment $record, RbacOnboardingService $service, AuditLogger $auditLogger ) { @@ -3171,10 +3172,10 @@ public static function rbacAction(): Actions\Action }); } - public static function adminConsentUrl(Tenant $tenant): ?string + public static function adminConsentUrl(ManagedEnvironment $tenant): ?string { $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->orderByDesc('is_default') ->orderBy('id') @@ -3205,12 +3206,12 @@ public static function adminConsentUrl(Tenant $tenant): ?string * last_error_reason_code:?string * } */ - private static function providerConnectionState(Tenant $tenant): array + private static function providerConnectionState(ManagedEnvironment $tenant): array { - $ctaUrl = ProviderConnectionResource::getUrl('index', ['tenant_id' => (string) $tenant->external_id], panel: 'admin'); + $ctaUrl = ProviderConnectionResource::getUrl('index', ['managed_environment_id' => (string) $tenant->external_id], panel: 'admin'); $defaultConnection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('is_default', true) ->orderBy('id') @@ -3219,7 +3220,7 @@ private static function providerConnectionState(Tenant $tenant): array $connection = $defaultConnection instanceof ProviderConnection ? $defaultConnection : ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->orderBy('id') ->first(); @@ -3259,10 +3260,10 @@ private static function providerConnectionState(Tenant $tenant): array ]; } - public static function entraUrl(Tenant $tenant): ?string + public static function entraUrl(ManagedEnvironment $tenant): ?string { $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->orderByDesc('is_default') ->orderBy('id') @@ -3272,6 +3273,10 @@ public static function entraUrl(Tenant $tenant): ?string ? $connection->effectiveAppId() : null; + if (! filled($effectiveAppId)) { + $effectiveAppId = $tenant->legacyProviderClientId(); + } + if (filled($effectiveAppId)) { return sprintf( 'https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/%s', @@ -3289,7 +3294,7 @@ public static function entraUrl(Tenant $tenant): ?string return null; } - private static function delegatedToken(?Tenant $tenant): ?string + private static function delegatedToken(?ManagedEnvironment $tenant): ?string { if (! $tenant) { return null; @@ -3301,12 +3306,12 @@ private static function delegatedToken(?Tenant $tenant): ?string return Cache::get($userKey) ?? Cache::get($sessionKey); } - private static function loginToSearchRolesAction(?Tenant $tenant): ?Actions\Action + private static function loginToSearchRolesAction(?ManagedEnvironment $tenant): ?Actions\Action { return null; } - public static function roleSearchHelper(?Tenant $tenant): ?string + public static function roleSearchHelper(?ManagedEnvironment $tenant): ?string { if (! $tenant) { return null; @@ -3318,7 +3323,7 @@ public static function roleSearchHelper(?Tenant $tenant): ?string /** * @return array */ - public static function roleSearchOptions(?Tenant $tenant, string $search): array + public static function roleSearchOptions(?ManagedEnvironment $tenant, string $search): array { $token = static::delegatedToken($tenant); @@ -3332,7 +3337,7 @@ public static function roleSearchOptions(?Tenant $tenant, string $search): array /** * @return array */ - private static function searchRoleDefinitionsDelegated(?Tenant $tenant, string $search, string $token): array + private static function searchRoleDefinitionsDelegated(?ManagedEnvironment $tenant, string $search, string $token): array { if (! $tenant || mb_strlen($search) < 2) { return []; @@ -3378,7 +3383,7 @@ private static function searchRoleDefinitionsDelegated(?Tenant $tenant, string $ /** * @return array */ - private static function searchRoleDefinitions(?Tenant $tenant, string $search): array + private static function searchRoleDefinitions(?ManagedEnvironment $tenant, string $search): array { if (! $tenant || mb_strlen($search) < 2) { return []; @@ -3387,7 +3392,7 @@ private static function searchRoleDefinitions(?Tenant $tenant, string $search): $needle = mb_strtolower($search); return EntraRoleDefinition::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereRaw('lower(display_name) like ?', [$needle.'%']) ->orderBy('display_name') ->limit(20) @@ -3398,14 +3403,14 @@ private static function searchRoleDefinitions(?Tenant $tenant, string $search): ->all(); } - public static function roleLabelFromCache(?Tenant $tenant, ?string $roleId): ?string + public static function roleLabelFromCache(?ManagedEnvironment $tenant, ?string $roleId): ?string { if (! $tenant || blank($roleId)) { return $roleId; } $displayName = EntraRoleDefinition::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('entra_id', $roleId) ->value('display_name'); @@ -3414,14 +3419,14 @@ public static function roleLabelFromCache(?Tenant $tenant, ?string $roleId): ?st return static::formatRoleLabel($displayName, $roleId); } - private static function roleNameFromCache(?Tenant $tenant, ?string $roleId): ?string + private static function roleNameFromCache(?ManagedEnvironment $tenant, ?string $roleId): ?string { if (! $tenant || blank($roleId)) { return $roleId; } $displayName = EntraRoleDefinition::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('entra_id', $roleId) ->value('display_name'); @@ -3435,12 +3440,12 @@ private static function formatRoleLabel(?string $displayName, string $id): strin return trim(($displayName ?: 'RBAC role').$suffix); } - private static function loginToSearchGroupsAction(?Tenant $tenant): ?Actions\Action + private static function loginToSearchGroupsAction(?ManagedEnvironment $tenant): ?Actions\Action { return null; } - public static function groupSearchHelper(?Tenant $tenant): ?string + public static function groupSearchHelper(?ManagedEnvironment $tenant): ?string { if (! $tenant) { return null; @@ -3452,7 +3457,7 @@ public static function groupSearchHelper(?Tenant $tenant): ?string /** * @return array */ - public static function groupSearchOptions(?Tenant $tenant, string $search): array + public static function groupSearchOptions(?ManagedEnvironment $tenant, string $search): array { if (! $tenant || mb_strlen($search) < 2) { return []; @@ -3497,7 +3502,7 @@ public static function groupSearchOptions(?Tenant $tenant, string $search): arra $needle = mb_strtolower($search); return EntraGroup::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereRaw('lower(display_name) like ?', [$needle.'%']) ->orderBy('display_name') ->limit(20) @@ -3508,7 +3513,7 @@ public static function groupSearchOptions(?Tenant $tenant, string $search): arra ->all(); } - public static function groupLabelFromCache(?Tenant $tenant, ?string $groupId): ?string + public static function groupLabelFromCache(?ManagedEnvironment $tenant, ?string $groupId): ?string { if (! $tenant || blank($groupId)) { return $groupId; @@ -3525,8 +3530,8 @@ public static function syncRoleDefinitionsAction(): Actions\Action ->label('Sync now') ->icon('heroicon-o-arrow-path') ->color('warning') - ->visible(fn (?Tenant $record): bool => $record instanceof Tenant && $record->isActive()) - ->action(function (Tenant $record, RoleDefinitionsSyncService $syncService): void { + ->visible(fn (?ManagedEnvironment $record): bool => $record instanceof ManagedEnvironment && $record->isActive()) + ->action(function (ManagedEnvironment $record, RoleDefinitionsSyncService $syncService): void { $user = auth()->user(); if (! $user instanceof User) { diff --git a/apps/platform/app/Filament/Resources/TenantResource/Pages/EditTenant.php b/apps/platform/app/Filament/Resources/TenantResource/Pages/EditTenant.php index 6aff9f02..75d0ed9f 100644 --- a/apps/platform/app/Filament/Resources/TenantResource/Pages/EditTenant.php +++ b/apps/platform/app/Filament/Resources/TenantResource/Pages/EditTenant.php @@ -3,7 +3,7 @@ namespace App\Filament\Resources\TenantResource\Pages; use App\Filament\Resources\TenantResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Tenants\TenantActionSurface; use Filament\Actions; use Filament\Resources\Pages\EditRecord; @@ -28,7 +28,7 @@ protected function getHeaderActions(): array ->label('Lifecycle') ->icon('heroicon-o-archive-box') ->color('gray') - ->visible(fn (): bool => $this->getRecord() instanceof Tenant + ->visible(fn (): bool => $this->getRecord() instanceof ManagedEnvironment && in_array( TenantResource::lifecycleActionDescriptor($this->getRecord(), TenantActionSurface::TenantEditHeader)?->key, ['archive', 'restore'], diff --git a/apps/platform/app/Filament/Resources/TenantResource/Pages/ManageTenantMemberships.php b/apps/platform/app/Filament/Resources/TenantResource/Pages/ManageTenantMemberships.php index 71a784ad..0b8a3990 100644 --- a/apps/platform/app/Filament/Resources/TenantResource/Pages/ManageTenantMemberships.php +++ b/apps/platform/app/Filament/Resources/TenantResource/Pages/ManageTenantMemberships.php @@ -11,7 +11,7 @@ class ManageTenantMemberships extends ViewTenant public function getSubheading(): ?string { - return 'Tenant access is managed here. Use the tenant overview for provider state, verification, and operational context.'; + return 'ManagedEnvironment access is managed here. Use the tenant overview for provider state, verification, and operational context.'; } protected function getHeaderWidgets(): array diff --git a/apps/platform/app/Filament/Resources/TenantResource/Pages/ViewTenant.php b/apps/platform/app/Filament/Resources/TenantResource/Pages/ViewTenant.php index 04b53346..be2f6d44 100644 --- a/apps/platform/app/Filament/Resources/TenantResource/Pages/ViewTenant.php +++ b/apps/platform/app/Filament/Resources/TenantResource/Pages/ViewTenant.php @@ -8,7 +8,7 @@ use App\Filament\Widgets\Tenant\TenantArchivedBanner; use App\Filament\Widgets\Tenant\TenantVerificationReport; use App\Jobs\RefreshTenantRbacHealthJob; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Support\Auth\Capabilities; @@ -62,7 +62,7 @@ protected function getHeaderActions(): array ->label('External links') ->icon('heroicon-o-arrow-top-right-on-square') ->color('gray') - ->visible(fn (): bool => $this->getRecord() instanceof Tenant + ->visible(fn (): bool => $this->getRecord() instanceof ManagedEnvironment && TenantResource::tenantViewExternalGroupVisible($this->getRecord())), Actions\ActionGroup::make([ TenantResource::makeSyncTenantAction(), @@ -74,8 +74,8 @@ protected function getHeaderActions(): array ->icon('heroicon-o-arrow-path') ->color('primary') ->requiresConfirmation() - ->visible(fn (Tenant $record): bool => $record->isActive()) - ->action(function (Tenant $record): void { + ->visible(fn (ManagedEnvironment $record): bool => $record->isActive()) + ->action(function (ManagedEnvironment $record): void { $user = auth()->user(); if (! $user instanceof User) { @@ -93,7 +93,7 @@ protected function getHeaderActions(): array tenant: $record, type: OperationRunType::RbacHealthCheck->value, inputs: [ - 'tenant_id' => (int) $record->getKey(), + 'managed_environment_id' => (int) $record->getKey(), 'surface' => 'tenant_view_header', ], initiator: $user, @@ -139,7 +139,7 @@ protected function getHeaderActions(): array ->label('Setup') ->icon('heroicon-o-wrench-screwdriver') ->color('gray') - ->visible(fn (): bool => $this->getRecord() instanceof Tenant + ->visible(fn (): bool => $this->getRecord() instanceof ManagedEnvironment && TenantResource::tenantViewSetupGroupVisible($this->getRecord())), Actions\ActionGroup::make([ TenantResource::makeTenantViewMarkReviewedAction(), @@ -148,7 +148,7 @@ protected function getHeaderActions(): array ->label('Triage') ->icon('heroicon-o-check-circle') ->color('gray') - ->visible(fn (): bool => $this->getRecord() instanceof Tenant + ->visible(fn (): bool => $this->getRecord() instanceof ManagedEnvironment && TenantResource::tenantViewTriageGroupVisible($this->getRecord())), Actions\ActionGroup::make([ TenantResource::makeRestoreTenantAction(TenantActionSurface::TenantViewHeader), @@ -157,7 +157,7 @@ protected function getHeaderActions(): array ->label('Lifecycle') ->icon('heroicon-o-archive-box') ->color('gray') - ->visible(fn (): bool => $this->getRecord() instanceof Tenant + ->visible(fn (): bool => $this->getRecord() instanceof ManagedEnvironment && TenantResource::tenantViewLifecycleGroupVisible($this->getRecord())), ])); } diff --git a/apps/platform/app/Filament/Resources/TenantResource/RelationManagers/TenantMembershipsRelationManager.php b/apps/platform/app/Filament/Resources/TenantResource/RelationManagers/TenantMembershipsRelationManager.php index f85d2446..ff9b7d38 100644 --- a/apps/platform/app/Filament/Resources/TenantResource/RelationManagers/TenantMembershipsRelationManager.php +++ b/apps/platform/app/Filament/Resources/TenantResource/RelationManagers/TenantMembershipsRelationManager.php @@ -3,8 +3,8 @@ namespace App\Filament\Resources\TenantResource\RelationManagers; use App\Filament\Resources\TenantResource\Pages\ManageTenantMemberships; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Auth\TenantMembershipManager; @@ -30,7 +30,7 @@ public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration { return ActionSurfaceDeclaration::forRelationManager(ActionSurfaceProfile::RelationManager) ->satisfy(ActionSurfaceSlot::ListHeader, 'Add member action is available in the relation header.') - ->exempt(ActionSurfaceSlot::InspectAffordance, 'Tenant membership rows are managed inline and have no separate inspect destination.') + ->exempt(ActionSurfaceSlot::InspectAffordance, 'ManagedEnvironment membership rows are managed inline and have no separate inspect destination.') ->exempt(ActionSurfaceSlot::ListRowMoreMenu, 'Change role and remove stay direct for focused inline membership management.') ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'Bulk membership mutations are intentionally omitted.') ->exempt(ActionSurfaceSlot::ListEmptyState, 'No empty-state actions are exposed; add member remains available in the header.'); @@ -38,7 +38,7 @@ public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration public static function canViewForRecord(Model $ownerRecord, string $pageClass): bool { - if (! $ownerRecord instanceof Tenant) { + if (! $ownerRecord instanceof ManagedEnvironment) { return false; } @@ -74,7 +74,7 @@ public function table(Table $table): Table ->searchable(), Tables\Columns\TextColumn::make('user_domain') ->label(__('Domain')) - ->getStateUsing(function (TenantMembership $record): ?string { + ->getStateUsing(function (ManagedEnvironmentMembership $record): ?string { $email = $record->user?->email; if (! is_string($email) || $email === '' || ! str_contains($email, '@')) { @@ -124,7 +124,7 @@ public function table(Table $table): Table ->action(function (array $data, TenantMembershipManager $manager): void { $tenant = $this->getOwnerRecord(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -184,10 +184,10 @@ public function table(Table $table): Table 'readonly' => __('Readonly'), ]), ]) - ->action(function (TenantMembership $record, array $data, TenantMembershipManager $manager): void { + ->action(function (ManagedEnvironmentMembership $record, array $data, TenantMembershipManager $manager): void { $tenant = $this->getOwnerRecord(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -228,10 +228,10 @@ public function table(Table $table): Table ->color('danger') ->icon('heroicon-o-x-mark') ->requiresConfirmation() - ->action(function (TenantMembership $record, TenantMembershipManager $manager): void { + ->action(function (ManagedEnvironmentMembership $record, TenantMembershipManager $manager): void { $tenant = $this->getOwnerRecord(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } diff --git a/apps/platform/app/Filament/Resources/TenantReviewResource.php b/apps/platform/app/Filament/Resources/TenantReviewResource.php index 0f15c2e3..69b909be 100644 --- a/apps/platform/app/Filament/Resources/TenantReviewResource.php +++ b/apps/platform/app/Filament/Resources/TenantReviewResource.php @@ -11,7 +11,7 @@ use App\Exceptions\Entitlements\WorkspaceEntitlementBlockedException; use App\Models\EvidenceSnapshot; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\TenantReviewSection; use App\Models\User; @@ -112,7 +112,7 @@ public static function canViewAny(): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return false; } @@ -128,7 +128,7 @@ public static function canView(Model $record): bool $tenant = static::resolveTenantContextForCurrentPanel(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User || ! $record instanceof TenantReview) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User || ! $record instanceof TenantReview) { return false; } @@ -136,7 +136,7 @@ public static function canView(Model $record): bool return false; } - if ((int) $record->tenant_id !== (int) $tenant->getKey()) { + if ((int) $record->managed_environment_id !== (int) $tenant->getKey()) { return false; } @@ -149,7 +149,7 @@ public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration ->satisfy(ActionSurfaceSlot::ListHeader, 'Create review is available from the review library header.') ->satisfy(ActionSurfaceSlot::InspectAffordance, ActionSurfaceInspectAffordance::ClickableRow->value) ->satisfy(ActionSurfaceSlot::ListEmptyState, 'Empty state includes exactly one Create first review CTA.') - ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'Tenant reviews do not expose bulk actions in the first slice.') + ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'ManagedEnvironment reviews do not expose bulk actions in the first slice.') ->exempt(ActionSurfaceSlot::ListRowMoreMenu, 'Clickable-row inspection stays primary while Export executive pack remains the only inline row shortcut.') ->satisfy(ActionSurfaceSlot::DetailHeader, 'Detail exposes one dominant lifecycle action, groups the remaining lifecycle actions under "More", keeps archive in a danger bucket, and renders operation/export/evidence navigation in contextual summary content.'); } @@ -404,7 +404,7 @@ public static function executeCreateReview(array $data): void $tenant = Filament::getTenant(); $user = auth()->user(); - if (! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { Notification::make()->danger()->title(__('localization.review.unable_create_missing_context'))->send(); return; @@ -422,7 +422,7 @@ public static function executeCreateReview(array $data): void $snapshot = is_numeric($snapshotId) ? EvidenceSnapshot::query() ->whereKey((int) $snapshotId) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->first() : null; @@ -474,23 +474,23 @@ public static function executeCreateReview(array $data): void /** * @return array */ - public static function reviewPackGenerationDecision(?Tenant $tenant = null): array + public static function reviewPackGenerationDecision(?ManagedEnvironment $tenant = null): array { $tenant ??= Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } return app(ReviewPackService::class)->reviewPackGenerationDecisionForTenant($tenant); } - public static function reviewPackGenerationBlocked(?Tenant $tenant = null): bool + public static function reviewPackGenerationBlocked(?ManagedEnvironment $tenant = null): bool { return (bool) (static::reviewPackGenerationDecision($tenant)['is_blocked'] ?? false); } - public static function reviewPackGenerationBlockReason(?Tenant $tenant = null): ?string + public static function reviewPackGenerationBlockReason(?ManagedEnvironment $tenant = null): ?string { $decision = static::reviewPackGenerationDecision($tenant); @@ -503,7 +503,7 @@ public static function reviewPackGenerationBlockReason(?Tenant $tenant = null): return is_string($reason) && $reason !== '' ? $reason : null; } - public static function reviewPackGenerationWarningReason(?Tenant $tenant = null): ?string + public static function reviewPackGenerationWarningReason(?ManagedEnvironment $tenant = null): ?string { $decision = static::reviewPackGenerationDecision($tenant); @@ -516,12 +516,12 @@ public static function reviewPackGenerationWarningReason(?Tenant $tenant = null) return is_string($reason) && $reason !== '' ? $reason : null; } - public static function reviewPackGenerationActionTooltip(?Tenant $tenant = null): ?string + public static function reviewPackGenerationActionTooltip(?ManagedEnvironment $tenant = null): ?string { $tenant ??= static::panelTenantContext(); $user = auth()->user(); - if ($tenant instanceof Tenant && $user instanceof User && ! $user->can(Capabilities::TENANT_REVIEW_MANAGE, $tenant)) { + if ($tenant instanceof ManagedEnvironment && $user instanceof User && ! $user->can(Capabilities::TENANT_REVIEW_MANAGE, $tenant)) { return AuthUiTooltips::insufficientPermission(); } @@ -534,7 +534,7 @@ public static function executeExport(TenantReview $review): void $review->loadMissing(['tenant', 'currentExportReviewPack']); $user = auth()->user(); - if (! $user instanceof User || ! $review->tenant instanceof Tenant) { + if (! $user instanceof User || ! $review->tenant instanceof ManagedEnvironment) { Notification::make()->danger()->title(__('localization.review.unable_export_missing_context'))->send(); return; @@ -602,7 +602,7 @@ public static function executeExport(TenantReview $review): void public static function tenantScopedUrl( string $page = 'index', array $parameters = [], - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?string $panel = null, ): string { $panelId = $panel ?? 'tenant'; @@ -617,12 +617,12 @@ private static function evidenceSnapshotOptions(): array { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } return EvidenceSnapshot::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereNotNull('generated_at') ->orderByDesc('generated_at') ->orderByDesc('id') @@ -728,7 +728,7 @@ private static function customerEvidenceStatusLabel(TenantReview $record): strin return __('localization.review.evidence_pending'); } - if (! $user instanceof User || ! $tenant instanceof Tenant || ! $user->can(Capabilities::EVIDENCE_VIEW, $tenant)) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment || ! $user->can(Capabilities::EVIDENCE_VIEW, $tenant)) { return __('localization.review.evidence_restricted'); } @@ -799,7 +799,7 @@ private static function governancePackageAvailability(TenantReview $record): arr ]; } - if (! $user instanceof User || ! $tenant instanceof Tenant || ! $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant)) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment || ! $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant)) { return [ 'state' => 'blocked', 'label' => __('localization.review.governance_package_blocked'), @@ -907,7 +907,7 @@ private static function sectionPresentation(TenantReviewSection $section): array $tenant = $section->tenant; $links = []; - if ($section->isControlInterpretation() && $review instanceof TenantReview && $tenant instanceof Tenant && $review->evidenceSnapshot instanceof EvidenceSnapshot) { + if ($section->isControlInterpretation() && $review instanceof TenantReview && $tenant instanceof ManagedEnvironment && $review->evidenceSnapshot instanceof EvidenceSnapshot) { $user = auth()->user(); if ($user instanceof User && $user->can(Capabilities::EVIDENCE_VIEW, $tenant)) { diff --git a/apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php b/apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php index e4f0680a..56836621 100644 --- a/apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php +++ b/apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php @@ -7,7 +7,7 @@ use App\Filament\Pages\Reviews\CustomerReviewWorkspace; use App\Filament\Resources\TenantReviewResource; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Services\ReviewPackService; @@ -48,11 +48,11 @@ protected function authorizeAccess(): void $record = $this->getRecord(); $user = auth()->user(); - if (! $user instanceof User || ! $tenant instanceof Tenant || ! $record instanceof TenantReview) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment || ! $record instanceof TenantReview) { abort(404); } - if ((int) $record->tenant_id !== (int) $tenant->getKey()) { + if ((int) $record->managed_environment_id !== (int) $tenant->getKey()) { abort(404); } @@ -370,7 +370,7 @@ private function currentReviewPackDownloadUrl(): ?string $tenant = $this->record->tenant; $user = auth()->user(); - if (! $pack instanceof ReviewPack || ! $tenant instanceof Tenant || ! $user instanceof User) { + if (! $pack instanceof ReviewPack || ! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { return null; } @@ -408,7 +408,7 @@ private function currentReviewPackUnavailableReason(): ?string return __('localization.review.customer_review_pack_missing'); } - if (! $user instanceof User || ! $tenant instanceof Tenant || ! $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant)) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment || ! $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant)) { return __('localization.review.customer_review_pack_forbidden'); } @@ -437,7 +437,7 @@ private function auditCustomerWorkspaceOpen(): void $user = auth()->user(); $tenant = $this->record->tenant; - if (! $user instanceof User || ! $tenant instanceof Tenant) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment) { return; } @@ -455,7 +455,7 @@ private function auditCustomerWorkspaceOpen(): void actor: $user, resourceType: 'tenant_review', resourceId: (string) $this->record->getKey(), - targetLabel: sprintf('Tenant review #%d', (int) $this->record->getKey()), + targetLabel: sprintf('ManagedEnvironment review #%d', (int) $this->record->getKey()), tenant: $tenant, ); } diff --git a/apps/platform/app/Filament/Support/VerificationReportViewer.php b/apps/platform/app/Filament/Support/VerificationReportViewer.php index 1e198727..b2d12d08 100644 --- a/apps/platform/app/Filament/Support/VerificationReportViewer.php +++ b/apps/platform/app/Filament/Support/VerificationReportViewer.php @@ -75,7 +75,7 @@ public static function previousRun(OperationRun $run, array $report): ?Operation $previous = OperationRun::query() ->whereKey($previousReportId) - ->where('tenant_id', (int) $run->tenant_id) + ->where('managed_environment_id', (int) $run->managed_environment_id) ->where('workspace_id', (int) $run->workspace_id) ->first(); diff --git a/apps/platform/app/Filament/System/Pages/Auth/Login.php b/apps/platform/app/Filament/System/Pages/Auth/Login.php index a667c04f..0a520cff 100644 --- a/apps/platform/app/Filament/System/Pages/Auth/Login.php +++ b/apps/platform/app/Filament/System/Pages/Auth/Login.php @@ -5,7 +5,7 @@ namespace App\Filament\System\Pages\Auth; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\AuditLogger; use Filament\Auth\Http\Responses\Contracts\LoginResponse; use Filament\Auth\Pages\Login as BaseLogin; @@ -88,7 +88,7 @@ private function throttleKey(string $email): string private function audit(string $status, string $email, ?PlatformUser $actor, ?string $reason = null): void { - $tenant = Tenant::query()->where('external_id', 'platform')->first(); + $tenant = ManagedEnvironment::query()->where('slug', 'platform')->first(); if (! $tenant) { return; diff --git a/apps/platform/app/Filament/System/Pages/Directory/Tenants.php b/apps/platform/app/Filament/System/Pages/Directory/Tenants.php index bcf17044..c704dbe1 100644 --- a/apps/platform/app/Filament/System/Pages/Directory/Tenants.php +++ b/apps/platform/app/Filament/System/Pages/Directory/Tenants.php @@ -5,7 +5,7 @@ namespace App\Filament\System\Pages\Directory; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\PlatformCapabilities; use App\Support\Badges\BadgeDomain; use App\Support\Badges\BadgeRenderer; @@ -41,7 +41,7 @@ public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration return ActionSurfaceDeclaration::forPage(ActionSurfaceProfile::ListOnlyReadOnly, ActionSurfaceType::ReadOnlyRegistryReport) ->exempt(ActionSurfaceSlot::ListHeader, 'System tenant directory stays scan-first and does not expose page header actions.') ->satisfy(ActionSurfaceSlot::InspectAffordance, ActionSurfaceInspectAffordance::ClickableRow->value) - ->exempt(ActionSurfaceSlot::ListRowMoreMenu, 'Tenant directory rows navigate directly to the detail page and have no secondary actions.') + ->exempt(ActionSurfaceSlot::ListRowMoreMenu, 'ManagedEnvironment directory rows navigate directly to the detail page and have no secondary actions.') ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'System tenant directory does not expose bulk actions.') ->satisfy(ActionSurfaceSlot::ListEmptyState, 'The empty state explains that tenants appear here after onboarding and inventory sync.'); } @@ -65,7 +65,7 @@ public function table(Table $table): Table ->defaultSort('name') ->paginated(\App\Support\Filament\TablePaginationProfiles::customPage()) ->query(function (): Builder { - return Tenant::query() + return ManagedEnvironment::query() ->with('workspace') ->withCount([ 'providerConnections as critical_provider_connections_count' => fn (Builder $query): Builder => $query @@ -81,7 +81,7 @@ public function table(Table $table): Table }) ->columns([ TextColumn::make('name') - ->label('Tenant') + ->label('ManagedEnvironment') ->searchable() ->sortable(), TextColumn::make('workspace.name') @@ -96,21 +96,21 @@ public function table(Table $table): Table ->iconColor(BadgeRenderer::iconColor(BadgeDomain::TenantStatus)), TextColumn::make('health') ->label('Health') - ->state(fn (Tenant $record): string => $this->healthForTenant($record)) + ->state(fn (ManagedEnvironment $record): string => $this->healthForTenant($record)) ->badge() ->formatStateUsing(BadgeRenderer::label(BadgeDomain::SystemHealth)) ->color(BadgeRenderer::color(BadgeDomain::SystemHealth)) ->icon(BadgeRenderer::icon(BadgeDomain::SystemHealth)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::SystemHealth)), ]) - ->recordUrl(fn (Tenant $record): string => SystemDirectoryLinks::tenantDetail($record)) + ->recordUrl(fn (ManagedEnvironment $record): string => SystemDirectoryLinks::tenantDetail($record)) ->emptyStateHeading('No tenants found') ->emptyStateDescription('Tenants will appear here as inventory is onboarded.'); } - private function healthForTenant(Tenant $tenant): string + private function healthForTenant(ManagedEnvironment $tenant): string { - if ((string) $tenant->status === Tenant::STATUS_ARCHIVED) { + if ((string) $tenant->status === ManagedEnvironment::STATUS_ARCHIVED) { return 'unknown'; } @@ -125,7 +125,7 @@ private function healthForTenant(Tenant $tenant): string return 'warn'; } - if ((string) $tenant->status === Tenant::STATUS_ONBOARDING) { + if ((string) $tenant->status === ManagedEnvironment::STATUS_ONBOARDING) { return 'warn'; } diff --git a/apps/platform/app/Filament/System/Pages/Directory/ViewTenant.php b/apps/platform/app/Filament/System/Pages/Directory/ViewTenant.php index 2a2f4072..11d6b8f2 100644 --- a/apps/platform/app/Filament/System/Pages/Directory/ViewTenant.php +++ b/apps/platform/app/Filament/System/Pages/Directory/ViewTenant.php @@ -8,7 +8,7 @@ use App\Models\OperationRun; use App\Models\PlatformUser; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantPermission; use App\Support\Auth\PlatformCapabilities; use App\Support\CustomerHealth\WorkspaceHealthSummaryQuery; @@ -29,7 +29,7 @@ class ViewTenant extends Page protected string $view = 'filament.system.pages.directory.view-tenant'; - public Tenant $tenant; + public ManagedEnvironment $tenant; public static function canAccess(): bool { @@ -39,7 +39,7 @@ public static function canAccess(): bool && $user->hasCapability(PlatformCapabilities::DIRECTORY_VIEW); } - public function mount(Tenant $tenant): void + public function mount(ManagedEnvironment $tenant): void { $tenant->load('workspace'); @@ -52,7 +52,7 @@ public function mount(Tenant $tenant): void public function providerConnections(): Collection { return ProviderConnection::query() - ->where('tenant_id', (int) $this->tenant->getKey()) + ->where('managed_environment_id', (int) $this->tenant->getKey()) ->orderByDesc('is_default') ->orderBy('provider') ->get([ @@ -74,7 +74,7 @@ public function providerConnections(): Collection public function tenantPermissions(): Collection { return TenantPermission::query() - ->where('tenant_id', (int) $this->tenant->getKey()) + ->where('managed_environment_id', (int) $this->tenant->getKey()) ->orderBy('permission_key') ->limit(20) ->get(['id', 'permission_key', 'status', 'last_checked_at']); @@ -86,7 +86,7 @@ public function tenantPermissions(): Collection public function recentRuns(): Collection { return OperationRun::query() - ->where('tenant_id', (int) $this->tenant->getKey()) + ->where('managed_environment_id', (int) $this->tenant->getKey()) ->latest('id') ->limit(8) ->get(['id', 'type', 'created_at']) diff --git a/apps/platform/app/Filament/System/Pages/Directory/ViewWorkspace.php b/apps/platform/app/Filament/System/Pages/Directory/ViewWorkspace.php index 1df5dd41..eef8bb10 100644 --- a/apps/platform/app/Filament/System/Pages/Directory/ViewWorkspace.php +++ b/apps/platform/app/Filament/System/Pages/Directory/ViewWorkspace.php @@ -8,7 +8,7 @@ use App\Models\OperationRun; use App\Models\PlatformUser; use App\Models\SupportAccessGrant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Models\WorkspaceSubscription; use App\Services\Auth\SupportAccessGrantManager; @@ -62,15 +62,15 @@ public function mount(Workspace $workspace): void } /** - * @return Collection + * @return Collection */ public function workspaceTenants(): Collection { - return Tenant::query() + return ManagedEnvironment::query() ->where('workspace_id', (int) $this->workspace->getKey()) ->orderBy('name') ->limit(10) - ->get(['id', 'name', 'status', 'workspace_id', 'external_id']); + ->get(['id', 'name', 'lifecycle_status', 'workspace_id', 'slug']); } /** diff --git a/apps/platform/app/Filament/System/Pages/Directory/Workspaces.php b/apps/platform/app/Filament/System/Pages/Directory/Workspaces.php index 4b827508..9d82c83e 100644 --- a/apps/platform/app/Filament/System/Pages/Directory/Workspaces.php +++ b/apps/platform/app/Filament/System/Pages/Directory/Workspaces.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Auth\PlatformCapabilities; use App\Support\Badges\BadgeDomain; @@ -72,7 +72,7 @@ public function table(Table $table): Table return Workspace::query() ->withCount([ 'tenants', - 'tenants as onboarding_tenants_count' => fn (Builder $query): Builder => $query->where('status', Tenant::STATUS_ONBOARDING), + 'tenants as onboarding_tenants_count' => fn (Builder $query): Builder => $query->where('lifecycle_status', ManagedEnvironment::STATUS_ONBOARDING), ]); }) ->columns([ diff --git a/apps/platform/app/Filament/System/Pages/Ops/Controls.php b/apps/platform/app/Filament/System/Pages/Ops/Controls.php index 9fe0d816..1d34eb2c 100644 --- a/apps/platform/app/Filament/System/Pages/Ops/Controls.php +++ b/apps/platform/app/Filament/System/Pages/Ops/Controls.php @@ -7,7 +7,7 @@ use App\Models\AuditLog; use App\Models\OperationalControlActivation; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Services\Audit\AuditRecorder; use App\Services\Audit\WorkspaceAuditLogger; @@ -148,9 +148,9 @@ public function scopeImpactPreview(string $controlKey, string $scopeType, ?int $ ]; } - $tenantCount = Tenant::query() + $tenantCount = ManagedEnvironment::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('external_id', '!=', 'platform') + ->where('slug', '!=', 'platform') ->count(); return [ @@ -163,12 +163,12 @@ public function scopeImpactPreview(string $controlKey, string $scopeType, ?int $ ]; } - $tenantCount = Tenant::query() - ->where('external_id', '!=', 'platform') + $tenantCount = ManagedEnvironment::query() + ->where('slug', '!=', 'platform') ->count(); - $workspaceCount = Tenant::query() - ->where('external_id', '!=', 'platform') + $workspaceCount = ManagedEnvironment::query() + ->where('slug', '!=', 'platform') ->distinct('workspace_id') ->count('workspace_id'); diff --git a/apps/platform/app/Filament/System/Pages/Ops/Failures.php b/apps/platform/app/Filament/System/Pages/Ops/Failures.php index 1c81b016..c53d5ea8 100644 --- a/apps/platform/app/Filament/System/Pages/Ops/Failures.php +++ b/apps/platform/app/Filament/System/Pages/Ops/Failures.php @@ -162,7 +162,7 @@ public function table(Table $table): Table ->label('Workspace') ->toggleable(), TextColumn::make('tenant.name') - ->label('Tenant') + ->label('ManagedEnvironment') ->formatStateUsing(fn (?string $state): string => $state ?: 'Tenantless') ->toggleable(), TextColumn::make('created_at')->label('Started')->since(), diff --git a/apps/platform/app/Filament/System/Pages/Ops/Runs.php b/apps/platform/app/Filament/System/Pages/Ops/Runs.php index 7e0ffbe1..43c3a7b4 100644 --- a/apps/platform/app/Filament/System/Pages/Ops/Runs.php +++ b/apps/platform/app/Filament/System/Pages/Ops/Runs.php @@ -143,7 +143,7 @@ public function table(Table $table): Table ->label('Workspace') ->toggleable(), TextColumn::make('tenant.name') - ->label('Tenant') + ->label('ManagedEnvironment') ->formatStateUsing(fn (?string $state): string => $state ?: 'Tenantless') ->toggleable(), TextColumn::make('initiator_name')->label('Initiator'), diff --git a/apps/platform/app/Filament/System/Pages/Ops/Stuck.php b/apps/platform/app/Filament/System/Pages/Ops/Stuck.php index e58ffc44..e95d39be 100644 --- a/apps/platform/app/Filament/System/Pages/Ops/Stuck.php +++ b/apps/platform/app/Filament/System/Pages/Ops/Stuck.php @@ -146,7 +146,7 @@ public function table(Table $table): Table ->label('Workspace') ->toggleable(), TextColumn::make('tenant.name') - ->label('Tenant') + ->label('ManagedEnvironment') ->formatStateUsing(fn (?string $state): string => $state ?: 'Tenantless') ->toggleable(), TextColumn::make('created_at')->label('Started')->since(), diff --git a/apps/platform/app/Filament/System/Widgets/ControlTowerTopOffenders.php b/apps/platform/app/Filament/System/Widgets/ControlTowerTopOffenders.php index dd509536..74c2b170 100644 --- a/apps/platform/app/Filament/System/Widgets/ControlTowerTopOffenders.php +++ b/apps/platform/app/Filament/System/Widgets/ControlTowerTopOffenders.php @@ -5,7 +5,7 @@ namespace App\Filament\System\Widgets; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\OperationCatalog; use App\Support\OperationRunOutcome; @@ -35,11 +35,11 @@ protected function getViewData(): array /** @var Collection $grouped */ $grouped = OperationRun::query() - ->selectRaw('workspace_id, tenant_id, type, COUNT(*) AS failed_count') + ->selectRaw('workspace_id, managed_environment_id, type, COUNT(*) AS failed_count') ->where('created_at', '>=', $start) ->where('status', OperationRunStatus::Completed->value) ->where('outcome', OperationRunOutcome::Failed->value) - ->groupBy('workspace_id', 'tenant_id', 'type') + ->groupBy('workspace_id', 'managed_environment_id', 'type') ->orderByDesc('failed_count') ->limit(10) ->get(); @@ -53,7 +53,7 @@ protected function getViewData(): array ->all(); $tenantIds = $grouped - ->pluck('tenant_id') + ->pluck('managed_environment_id') ->filter(fn ($value): bool => is_numeric($value)) ->map(fn ($value): int => (int) $value) ->unique() @@ -65,7 +65,7 @@ protected function getViewData(): array ->pluck('name', 'id') ->all(); - $tenantNames = Tenant::query() + $tenantNames = ManagedEnvironment::query() ->whereIn('id', $tenantIds) ->pluck('name', 'id') ->all(); @@ -74,14 +74,14 @@ protected function getViewData(): array 'windowLabel' => SystemConsoleWindow::options()[$window->value] ?? 'Last 24 hours', 'offenders' => $grouped->map(function (OperationRun $record) use ($workspaceNames, $tenantNames): array { $workspaceId = is_numeric($record->workspace_id) ? (int) $record->workspace_id : null; - $tenantId = is_numeric($record->tenant_id) ? (int) $record->tenant_id : null; + $tenantId = is_numeric($record->managed_environment_id) ? (int) $record->managed_environment_id : null; return [ 'workspace_label' => $workspaceId !== null ? ($workspaceNames[$workspaceId] ?? ('Workspace #'.$workspaceId)) : 'Unknown workspace', 'tenant_label' => $tenantId !== null - ? ($tenantNames[$tenantId] ?? ('Tenant #'.$tenantId)) + ? ($tenantNames[$tenantId] ?? ('ManagedEnvironment #'.$tenantId)) : 'Tenantless', 'operation_label' => OperationCatalog::label((string) $record->type), 'failed_count' => (int) $record->getAttribute('failed_count'), diff --git a/apps/platform/app/Filament/Widgets/Alerts/AlertsKpiHeader.php b/apps/platform/app/Filament/Widgets/Alerts/AlertsKpiHeader.php index 2e6e3b82..f2f413be 100644 --- a/apps/platform/app/Filament/Widgets/Alerts/AlertsKpiHeader.php +++ b/apps/platform/app/Filament/Widgets/Alerts/AlertsKpiHeader.php @@ -10,7 +10,7 @@ use App\Models\AlertDelivery; use App\Models\AlertDestination; use App\Models\AlertRule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\OperateHub\OperateHubShell; use App\Support\Workspaces\WorkspaceContext; @@ -94,12 +94,12 @@ private function deliveriesQueryForViewer(User $user, int $workspaceId): Builder { $query = AlertDelivery::query() ->where('workspace_id', $workspaceId) - ->whereIn('tenant_id', $user->tenantMemberships()->select('tenant_id')); + ->whereIn('managed_environment_id', $user->tenantMemberships()->select('managed_environment_id')); $activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request()); - if ($activeTenant instanceof Tenant) { - $query->where('tenant_id', (int) $activeTenant->getKey()); + if ($activeTenant instanceof ManagedEnvironment) { + $query->where('managed_environment_id', (int) $activeTenant->getKey()); } return $query; diff --git a/apps/platform/app/Filament/Widgets/Dashboard/BaselineCompareNow.php b/apps/platform/app/Filament/Widgets/Dashboard/BaselineCompareNow.php index 5d144024..aee1a863 100644 --- a/apps/platform/app/Filament/Widgets/Dashboard/BaselineCompareNow.php +++ b/apps/platform/app/Filament/Widgets/Dashboard/BaselineCompareNow.php @@ -8,7 +8,7 @@ use App\Filament\Resources\FindingResource; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Auth\Capabilities; use App\Support\Baselines\BaselineCompareSummaryAssessment; @@ -43,7 +43,7 @@ protected function getViewData(): array 'summaryAssessment' => null, ]; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return $empty; } @@ -55,7 +55,7 @@ protected function getViewData(): array $tenantLandingUrl = BaselineCompareLanding::getUrl(panel: 'tenant', tenant: $tenant); $operationsFollowUpCount = (int) OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->dashboardNeedsFollowUp() ->count(); $summaryAssessment = $this->dashboardSummaryAssessment($aggregate, $operationsFollowUpCount); @@ -133,7 +133,7 @@ private function dashboardSummaryAssessment(TenantGovernanceAggregate $aggregate return $summaryAssessment; } - private function runUrl(Tenant $tenant, TenantGovernanceAggregate $aggregate): ?string + private function runUrl(ManagedEnvironment $tenant, TenantGovernanceAggregate $aggregate): ?string { $runId = $aggregate->stats->operationRunId; @@ -150,7 +150,7 @@ private function runUrl(Tenant $tenant, TenantGovernanceAggregate $aggregate): ? return OperationRunLinks::view($run, $tenant); } - private function findingsUrl(Tenant $tenant, TenantGovernanceAggregate $aggregate): ?string + private function findingsUrl(ManagedEnvironment $tenant, TenantGovernanceAggregate $aggregate): ?string { if (! $this->canOpenFindings($tenant)) { return null; @@ -182,7 +182,7 @@ private function findingsUrl(Tenant $tenant, TenantGovernanceAggregate $aggregat return FindingResource::getUrl('index', $parameters, panel: 'tenant', tenant: $tenant); } - private function canOpenFindings(Tenant $tenant): bool + private function canOpenFindings(ManagedEnvironment $tenant): bool { $user = auth()->user(); @@ -198,7 +198,7 @@ private function canOpenRun(OperationRun $run): bool return $user instanceof User && $user->can('view', $run); } - private function governanceAggregate(Tenant $tenant): TenantGovernanceAggregate + private function governanceAggregate(ManagedEnvironment $tenant): TenantGovernanceAggregate { /** @var TenantGovernanceAggregateResolver $resolver */ $resolver = app(TenantGovernanceAggregateResolver::class); diff --git a/apps/platform/app/Filament/Widgets/Dashboard/DashboardKpis.php b/apps/platform/app/Filament/Widgets/Dashboard/DashboardKpis.php index bb3711bc..6cae2688 100644 --- a/apps/platform/app/Filament/Widgets/Dashboard/DashboardKpis.php +++ b/apps/platform/app/Filament/Widgets/Dashboard/DashboardKpis.php @@ -4,7 +4,7 @@ namespace App\Filament\Widgets\Dashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OpsUx\ActiveRuns; use App\Support\TenantDashboard\TenantDashboardSummaryBuilder; use Filament\Facades\Filament; @@ -28,7 +28,7 @@ protected function getStats(): array { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } diff --git a/apps/platform/app/Filament/Widgets/Dashboard/NeedsAttention.php b/apps/platform/app/Filament/Widgets/Dashboard/NeedsAttention.php index 2aa30245..5b3e1425 100644 --- a/apps/platform/app/Filament/Widgets/Dashboard/NeedsAttention.php +++ b/apps/platform/app/Filament/Widgets/Dashboard/NeedsAttention.php @@ -12,7 +12,7 @@ use App\Models\FindingException; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Auth\Capabilities; use App\Support\BackupHealth\BackupHealthActionTarget; @@ -42,7 +42,7 @@ protected function getViewData(): array { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return [ 'pollingInterval' => null, 'items' => [], @@ -74,15 +74,15 @@ protected function getViewData(): array $expiringGovernanceCount = $aggregate->expiringGovernanceCount; $highSeverityCount = $aggregate->highSeverityActiveFindingsCount; $staleActiveOperationsCount = (int) OperationRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->activeStaleAttention() ->count(); $terminalFollowUpOperationsCount = (int) OperationRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->terminalFollowUp() ->count(); $activeRuns = (int) OperationRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->healthyActive() ->count(); @@ -245,7 +245,7 @@ protected function getViewData(): array * @param array $parameters * @return array */ - private function findingsAction(Tenant $tenant, string $label, array $parameters): array + private function findingsAction(ManagedEnvironment $tenant, string $label, array $parameters): array { $url = $this->canOpenFindings($tenant) ? FindingResource::getUrl('index', $parameters, panel: 'tenant', tenant: $tenant) @@ -259,7 +259,7 @@ private function findingsAction(Tenant $tenant, string $label, array $parameters ]; } - private function canOpenFindings(Tenant $tenant): bool + private function canOpenFindings(ManagedEnvironment $tenant): bool { $user = auth()->user(); @@ -268,7 +268,7 @@ private function canOpenFindings(Tenant $tenant): bool && $user->can(Capabilities::TENANT_FINDINGS_VIEW, $tenant); } - private function governanceAggregate(Tenant $tenant): TenantGovernanceAggregate + private function governanceAggregate(ManagedEnvironment $tenant): TenantGovernanceAggregate { /** @var TenantGovernanceAggregateResolver $resolver */ $resolver = app(TenantGovernanceAggregateResolver::class); @@ -279,7 +279,7 @@ private function governanceAggregate(Tenant $tenant): TenantGovernanceAggregate return $aggregate; } - private function backupHealthAssessment(Tenant $tenant): TenantBackupHealthAssessment + private function backupHealthAssessment(ManagedEnvironment $tenant): TenantBackupHealthAssessment { /** @var TenantBackupHealthResolver $resolver */ $resolver = app(TenantBackupHealthResolver::class); @@ -290,7 +290,7 @@ private function backupHealthAssessment(Tenant $tenant): TenantBackupHealthAsses /** * @return array */ - private function recoveryEvidence(Tenant $tenant): array + private function recoveryEvidence(ManagedEnvironment $tenant): array { /** @var RestoreSafetyResolver $resolver */ $resolver = app(RestoreSafetyResolver::class); @@ -298,7 +298,7 @@ private function recoveryEvidence(Tenant $tenant): array return $resolver->dashboardRecoveryEvidence($tenant); } - private function backupHealthAttentionItem(Tenant $tenant, TenantBackupHealthAssessment $assessment): ?BackupHealthDashboardSignal + private function backupHealthAttentionItem(ManagedEnvironment $tenant, TenantBackupHealthAssessment $assessment): ?BackupHealthDashboardSignal { if (! $assessment->hasActiveReason()) { return null; @@ -337,7 +337,7 @@ private function backupHealthHealthyCheck(TenantBackupHealthAssessment $assessme * @param array $recoveryEvidence * @return array|null */ - private function recoveryEvidenceAttentionItem(Tenant $tenant, TenantBackupHealthAssessment $backupHealth, array $recoveryEvidence): ?array + private function recoveryEvidenceAttentionItem(ManagedEnvironment $tenant, TenantBackupHealthAssessment $backupHealth, array $recoveryEvidence): ?array { $overviewState = is_string($recoveryEvidence['overview_state'] ?? null) ? $recoveryEvidence['overview_state'] @@ -410,7 +410,7 @@ private function recoveryEvidenceHealthyCheck(array $recoveryEvidence): ?array /** * @return array{actionLabel: string|null, actionUrl: string|null, actionDisabled: bool, helperText: string|null} */ - private function backupHealthActionPayload(Tenant $tenant, ?BackupHealthActionTarget $target, ?string $label): array + private function backupHealthActionPayload(ManagedEnvironment $tenant, ?BackupHealthActionTarget $target, ?string $label): array { if (! $target instanceof BackupHealthActionTarget) { return [ @@ -460,7 +460,7 @@ private function backupHealthActionPayload(Tenant $tenant, ?BackupHealthActionTa /** * @return array{actionLabel: string|null, actionUrl: string|null, actionDisabled: bool, helperText: string|null} */ - private function backupHealthBackupSetActionPayload(Tenant $tenant, BackupHealthActionTarget $target, ?string $label): array + private function backupHealthBackupSetActionPayload(ManagedEnvironment $tenant, BackupHealthActionTarget $target, ?string $label): array { if (! is_numeric($target->recordId)) { return [ @@ -508,7 +508,7 @@ private function backupHealthAttentionTitle(TenantBackupHealthAssessment $assess }; } - private function canOpenBackupSurfaces(Tenant $tenant): bool + private function canOpenBackupSurfaces(ManagedEnvironment $tenant): bool { $user = auth()->user(); @@ -531,7 +531,7 @@ private function recoveryAttentionTitle(?string $attentionState): string * @param array $recoveryEvidence * @return array{actionLabel: string, actionUrl: string|null, actionDisabled: bool, helperText: string|null} */ - private function recoveryActionPayload(Tenant $tenant, array $recoveryEvidence, string $label): array + private function recoveryActionPayload(ManagedEnvironment $tenant, array $recoveryEvidence, string $label): array { if (! $this->canOpenRestoreHistory($tenant)) { return [ @@ -578,7 +578,7 @@ private function recoveryActionPayload(Tenant $tenant, array $recoveryEvidence, } } - private function canOpenRestoreHistory(Tenant $tenant): bool + private function canOpenRestoreHistory(ManagedEnvironment $tenant): bool { $user = auth()->user(); @@ -587,7 +587,7 @@ private function canOpenRestoreHistory(Tenant $tenant): bool && $user->can(Capabilities::TENANT_VIEW, $tenant); } - private function restoreRunListUrl(Tenant $tenant, string $reason): string + private function restoreRunListUrl(ManagedEnvironment $tenant, string $reason): string { return RestoreRunResource::getUrl('index', [ 'recovery_posture_reason' => $reason, diff --git a/apps/platform/app/Filament/Widgets/Dashboard/RecentDriftFindings.php b/apps/platform/app/Filament/Widgets/Dashboard/RecentDriftFindings.php index 5dd413f8..96be9ef8 100644 --- a/apps/platform/app/Filament/Widgets/Dashboard/RecentDriftFindings.php +++ b/apps/platform/app/Filament/Widgets/Dashboard/RecentDriftFindings.php @@ -6,7 +6,7 @@ use App\Filament\Resources\FindingResource; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Badges\BadgeDomain; use App\Support\Badges\BadgeRenderer; use App\Support\OpsUx\ActiveRuns; @@ -28,7 +28,7 @@ public function table(Table $table): Table return $table ->heading('Recent Drift Findings') ->query($this->getQuery()) - ->poll(fn (): ?string => ($tenant instanceof Tenant) && ActiveRuns::existForTenant($tenant) ? '10s' : null) + ->poll(fn (): ?string => ($tenant instanceof ManagedEnvironment) && ActiveRuns::existForTenant($tenant) ? '10s' : null) ->defaultSort('created_at', 'desc') ->paginated(\App\Support\Filament\TablePaginationProfiles::widget()) ->columns([ @@ -70,7 +70,7 @@ public function table(Table $table): Table ->sortable() ->since(), ]) - ->recordUrl(fn (Finding $record): ?string => $tenant instanceof Tenant + ->recordUrl(fn (Finding $record): ?string => $tenant instanceof ManagedEnvironment ? FindingResource::getUrl('view', ['record' => $record], tenant: $tenant) : null) ->emptyStateHeading('No drift findings') @@ -83,11 +83,11 @@ public function table(Table $table): Table private function getQuery(): Builder { $tenant = Filament::getTenant(); - $tenantId = $tenant instanceof Tenant ? $tenant->getKey() : null; + $tenantId = $tenant instanceof ManagedEnvironment ? $tenant->getKey() : null; return Finding::query() ->withSubjectDisplayName() - ->when($tenantId, fn (Builder $query) => $query->where('tenant_id', $tenantId)) + ->when($tenantId, fn (Builder $query) => $query->where('managed_environment_id', $tenantId)) ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->latest('created_at'); } diff --git a/apps/platform/app/Filament/Widgets/Dashboard/RecentOperations.php b/apps/platform/app/Filament/Widgets/Dashboard/RecentOperations.php index 892b343a..5a02c444 100644 --- a/apps/platform/app/Filament/Widgets/Dashboard/RecentOperations.php +++ b/apps/platform/app/Filament/Widgets/Dashboard/RecentOperations.php @@ -5,7 +5,7 @@ namespace App\Filament\Widgets\Dashboard; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Badges\BadgeDomain; use App\Support\Badges\BadgeRenderer; use App\Support\OperationCatalog; @@ -29,7 +29,7 @@ public function table(Table $table): Table return $table ->heading('Recent Operations') ->query($this->getQuery()) - ->poll(fn (): ?string => ActiveRuns::pollingIntervalForTenant($tenant instanceof Tenant ? $tenant : null)) + ->poll(fn (): ?string => ActiveRuns::pollingIntervalForTenant($tenant instanceof ManagedEnvironment ? $tenant : null)) ->defaultSort('created_at', 'desc') ->paginated(\App\Support\Filament\TablePaginationProfiles::widget()) ->columns([ @@ -95,7 +95,7 @@ public function table(Table $table): Table ->sortable() ->since(), ]) - ->recordUrl(fn (OperationRun $record): ?string => $tenant instanceof Tenant + ->recordUrl(fn (OperationRun $record): ?string => $tenant instanceof ManagedEnvironment ? OperationRunLinks::view($record, $tenant) : null) ->emptyStateHeading('No operations yet') @@ -108,10 +108,10 @@ public function table(Table $table): Table private function getQuery(): Builder { $tenant = Filament::getTenant(); - $tenantId = $tenant instanceof Tenant ? $tenant->getKey() : null; + $tenantId = $tenant instanceof ManagedEnvironment ? $tenant->getKey() : null; return OperationRun::query() - ->when($tenantId, fn (Builder $query) => $query->where('tenant_id', $tenantId)) + ->when($tenantId, fn (Builder $query) => $query->where('managed_environment_id', $tenantId)) ->latest('created_at'); } } diff --git a/apps/platform/app/Filament/Widgets/Dashboard/RecoveryReadiness.php b/apps/platform/app/Filament/Widgets/Dashboard/RecoveryReadiness.php index 4dd73a29..784b46fe 100644 --- a/apps/platform/app/Filament/Widgets/Dashboard/RecoveryReadiness.php +++ b/apps/platform/app/Filament/Widgets/Dashboard/RecoveryReadiness.php @@ -8,7 +8,7 @@ use App\Filament\Resources\BackupSetResource; use App\Filament\Resources\RestoreRunResource; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Auth\Capabilities; use App\Support\BackupHealth\BackupHealthActionTarget; @@ -41,7 +41,7 @@ protected function getViewData(): array { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return [ 'pollingInterval' => null, 'backupPosture' => $this->emptyStatPayload('Backup posture'), @@ -87,7 +87,7 @@ private function emptyStatPayload(string $label): array ]; } - private function backupHealthAssessment(Tenant $tenant): TenantBackupHealthAssessment + private function backupHealthAssessment(ManagedEnvironment $tenant): TenantBackupHealthAssessment { /** @var TenantBackupHealthResolver $resolver */ $resolver = app(TenantBackupHealthResolver::class); @@ -98,7 +98,7 @@ private function backupHealthAssessment(Tenant $tenant): TenantBackupHealthAsses /** * @return array */ - private function recoveryEvidence(Tenant $tenant): array + private function recoveryEvidence(ManagedEnvironment $tenant): array { /** @var RestoreSafetyResolver $resolver */ $resolver = app(RestoreSafetyResolver::class); @@ -109,7 +109,7 @@ private function recoveryEvidence(Tenant $tenant): array /** * @return array{actionUrl: string|null, helperText: string|null} */ - private function resolveBackupHealthAction(Tenant $tenant, ?BackupHealthActionTarget $target): array + private function resolveBackupHealthAction(ManagedEnvironment $tenant, ?BackupHealthActionTarget $target): array { if (! $target instanceof BackupHealthActionTarget) { return ['actionUrl' => null, 'helperText' => null]; @@ -140,7 +140,7 @@ private function resolveBackupHealthAction(Tenant $tenant, ?BackupHealthActionTa /** * @return array{actionUrl: string|null, helperText: string|null} */ - private function resolveBackupSetAction(Tenant $tenant, BackupHealthActionTarget $target): array + private function resolveBackupSetAction(ManagedEnvironment $tenant, BackupHealthActionTarget $target): array { if (! is_numeric($target->recordId)) { return [ @@ -175,7 +175,7 @@ private function resolveBackupSetAction(Tenant $tenant, BackupHealthActionTarget * @param array $recoveryEvidence * @return array{actionUrl: string|null, helperText: string|null} */ - private function resolveRecoveryAction(Tenant $tenant, array $recoveryEvidence): array + private function resolveRecoveryAction(ManagedEnvironment $tenant, array $recoveryEvidence): array { if (! $this->canOpenRestoreHistory($tenant)) { return ['actionUrl' => null, 'helperText' => UiTooltips::INSUFFICIENT_PERMISSION]; @@ -211,7 +211,7 @@ private function resolveRecoveryAction(Tenant $tenant, array $recoveryEvidence): } } - private function canOpenBackupSurfaces(Tenant $tenant): bool + private function canOpenBackupSurfaces(ManagedEnvironment $tenant): bool { $user = auth()->user(); @@ -220,7 +220,7 @@ private function canOpenBackupSurfaces(Tenant $tenant): bool && $user->can(Capabilities::TENANT_VIEW, $tenant); } - private function canOpenRestoreHistory(Tenant $tenant): bool + private function canOpenRestoreHistory(ManagedEnvironment $tenant): bool { $user = auth()->user(); @@ -229,7 +229,7 @@ private function canOpenRestoreHistory(Tenant $tenant): bool && $user->can(Capabilities::TENANT_VIEW, $tenant); } - private function restoreRunListUrl(Tenant $tenant, string $reason): string + private function restoreRunListUrl(ManagedEnvironment $tenant, string $reason): string { return RestoreRunResource::getUrl('index', [ 'recovery_posture_reason' => $reason, diff --git a/apps/platform/app/Filament/Widgets/Dashboard/TenantDashboardContextChips.php b/apps/platform/app/Filament/Widgets/Dashboard/TenantDashboardContextChips.php index 204b71bf..4e6e3493 100644 --- a/apps/platform/app/Filament/Widgets/Dashboard/TenantDashboardContextChips.php +++ b/apps/platform/app/Filament/Widgets/Dashboard/TenantDashboardContextChips.php @@ -4,7 +4,7 @@ namespace App\Filament\Widgets\Dashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\TenantDashboard\TenantDashboardSummaryBuilder; use Filament\Facades\Filament; use Filament\Widgets\Widget; @@ -24,7 +24,7 @@ protected function getViewData(): array { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return [ 'context' => [ 'workspace' => __('localization.dashboard.overview.context_workspace'), diff --git a/apps/platform/app/Filament/Widgets/Dashboard/TenantDashboardOverview.php b/apps/platform/app/Filament/Widgets/Dashboard/TenantDashboardOverview.php index 72eb9436..9319c6d3 100644 --- a/apps/platform/app/Filament/Widgets/Dashboard/TenantDashboardOverview.php +++ b/apps/platform/app/Filament/Widgets/Dashboard/TenantDashboardOverview.php @@ -4,7 +4,7 @@ namespace App\Filament\Widgets\Dashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\TenantDashboard\TenantDashboardSummaryBuilder; use Filament\Facades\Filament; use Filament\Widgets\Widget; @@ -24,7 +24,7 @@ protected function getViewData(): array { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return [ 'context' => [ 'workspace' => __('localization.dashboard.overview.context_workspace'), diff --git a/apps/platform/app/Filament/Widgets/Inventory/InventoryKpiHeader.php b/apps/platform/app/Filament/Widgets/Inventory/InventoryKpiHeader.php index c0b6e3cf..0cd68e93 100644 --- a/apps/platform/app/Filament/Widgets/Inventory/InventoryKpiHeader.php +++ b/apps/platform/app/Filament/Widgets/Inventory/InventoryKpiHeader.php @@ -6,7 +6,7 @@ use App\Filament\Concerns\ResolvesPanelTenantContext; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Auth\Capabilities; use App\Support\Badges\BadgeDomain; @@ -37,7 +37,7 @@ protected function getPollingInterval(): ?string { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -49,7 +49,7 @@ public function onRunEnqueued(?int $tenantId = null): void { $tenant = static::resolveTenantContextForCurrentPanel(); - if ($tenantId !== null && $tenant instanceof Tenant && (int) $tenant->getKey() !== (int) $tenantId) { + if ($tenantId !== null && $tenant instanceof ManagedEnvironment && (int) $tenant->getKey() !== (int) $tenantId) { return; } } @@ -61,7 +61,7 @@ protected function getStats(): array { $tenant = static::resolveTenantContextForCurrentPanel(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return [ Stat::make('Total items', 0), Stat::make('Covered types', '—')->description('Select a tenant to load coverage truth.'), @@ -100,7 +100,7 @@ protected function getStats(): array ]; } - private function coverageBasisStat(TenantCoverageTruth $truth, Tenant $tenant): Stat + private function coverageBasisStat(TenantCoverageTruth $truth, ManagedEnvironment $tenant): Stat { $user = auth()->user(); diff --git a/apps/platform/app/Filament/Widgets/Operations/OperationsKpiHeader.php b/apps/platform/app/Filament/Widgets/Operations/OperationsKpiHeader.php index 26c84c93..ef37314a 100644 --- a/apps/platform/app/Filament/Widgets/Operations/OperationsKpiHeader.php +++ b/apps/platform/app/Filament/Widgets/Operations/OperationsKpiHeader.php @@ -5,7 +5,7 @@ namespace App\Filament\Widgets\Operations; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperateHub\OperateHubShell; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; @@ -25,7 +25,7 @@ protected function getPollingInterval(): ?string { $tenant = $this->activeTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -39,19 +39,19 @@ protected function getStats(): array { $tenant = $this->activeTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } $tenantId = (int) $tenant->getKey(); $totalRuns30Days = (int) OperationRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('created_at', '>=', now()->subDays(30)) ->count(); $activeRuns = (int) OperationRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->whereIn('status', [ OperationRunStatus::Queued->value, OperationRunStatus::Running->value, @@ -59,7 +59,7 @@ protected function getStats(): array ->count(); $failedOrPartial7Days = (int) OperationRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('status', OperationRunStatus::Completed->value) ->whereIn('outcome', [ OperationRunOutcome::Failed->value, @@ -70,7 +70,7 @@ protected function getStats(): array /** @var Collection $recentCompletedRuns */ $recentCompletedRuns = OperationRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('status', OperationRunStatus::Completed->value) ->whereNotNull('started_at') ->whereNotNull('completed_at') @@ -110,11 +110,11 @@ protected function getStats(): array ]; } - private function activeTenant(): ?Tenant + private function activeTenant(): ?ManagedEnvironment { $tenant = app(OperateHubShell::class)->activeEntitledTenant(request()); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } private static function formatDurationSeconds(int $seconds): string diff --git a/apps/platform/app/Filament/Widgets/Tenant/AdminRolesSummaryWidget.php b/apps/platform/app/Filament/Widgets/Tenant/AdminRolesSummaryWidget.php index e4ed7b7d..6934e65f 100644 --- a/apps/platform/app/Filament/Widgets/Tenant/AdminRolesSummaryWidget.php +++ b/apps/platform/app/Filament/Widgets/Tenant/AdminRolesSummaryWidget.php @@ -7,7 +7,7 @@ use App\Filament\Resources\StoredReportResource; use App\Jobs\ScanEntraAdminRolesJob; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Support\Auth\Capabilities; @@ -24,17 +24,17 @@ class AdminRolesSummaryWidget extends Widget protected string $view = 'filament.widgets.tenant.admin-roles-summary'; - public ?Tenant $record = null; + public ?ManagedEnvironment $record = null; - private function resolveTenant(): ?Tenant + private function resolveTenant(): ?ManagedEnvironment { $tenant = Filament::getTenant(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return $tenant; } - return $this->record instanceof Tenant ? $this->record : null; + return $this->record instanceof ManagedEnvironment ? $this->record : null; } public function scanNow(): void @@ -47,7 +47,7 @@ public function scanNow(): void $tenant = $this->resolveTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -66,7 +66,7 @@ public function scanNow(): void tenant: $tenant, type: 'entra.admin_roles.scan', identityInputs: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'trigger' => 'scan', ], context: [ @@ -119,7 +119,7 @@ protected function getViewData(): array { $tenant = $this->resolveTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return $this->emptyState(); } @@ -129,7 +129,7 @@ protected function getViewData(): array $canManage = $isTenantMember && $user->can(Capabilities::ENTRA_ROLES_MANAGE, $tenant); $report = StoredReport::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES) ->orderByDesc('created_at') ->orderByDesc('id') diff --git a/apps/platform/app/Filament/Widgets/Tenant/BaselineCompareCoverageBanner.php b/apps/platform/app/Filament/Widgets/Tenant/BaselineCompareCoverageBanner.php index 4046f85e..b4b2c5a1 100644 --- a/apps/platform/app/Filament/Widgets/Tenant/BaselineCompareCoverageBanner.php +++ b/apps/platform/app/Filament/Widgets/Tenant/BaselineCompareCoverageBanner.php @@ -5,7 +5,7 @@ namespace App\Filament\Widgets\Tenant; use App\Filament\Pages\BaselineCompareLanding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Baselines\TenantGovernanceAggregate; use App\Support\Baselines\TenantGovernanceAggregateResolver; use App\Support\OperationRunLinks; @@ -25,7 +25,7 @@ protected function getViewData(): array { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return [ 'shouldShow' => false, ]; @@ -56,7 +56,7 @@ protected function getViewData(): array ]; } - private function governanceAggregate(Tenant $tenant): TenantGovernanceAggregate + private function governanceAggregate(ManagedEnvironment $tenant): TenantGovernanceAggregate { /** @var TenantGovernanceAggregateResolver $resolver */ $resolver = app(TenantGovernanceAggregateResolver::class); diff --git a/apps/platform/app/Filament/Widgets/Tenant/RecentOperationsSummary.php b/apps/platform/app/Filament/Widgets/Tenant/RecentOperationsSummary.php index 5141a729..0dafd85a 100644 --- a/apps/platform/app/Filament/Widgets/Tenant/RecentOperationsSummary.php +++ b/apps/platform/app/Filament/Widgets/Tenant/RecentOperationsSummary.php @@ -5,7 +5,7 @@ namespace App\Filament\Widgets\Tenant; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunLinks; use Filament\Facades\Filament; use Filament\Widgets\Widget; @@ -17,17 +17,17 @@ class RecentOperationsSummary extends Widget protected string $view = 'filament.widgets.tenant.recent-operations-summary'; - public ?Tenant $record = null; + public ?ManagedEnvironment $record = null; - private function resolveTenant(): ?Tenant + private function resolveTenant(): ?ManagedEnvironment { $tenant = Filament::getTenant(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return $tenant; } - return $this->record instanceof Tenant ? $this->record : null; + return $this->record instanceof ManagedEnvironment ? $this->record : null; } /** @@ -37,7 +37,7 @@ protected function getViewData(): array { $tenant = $this->resolveTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return [ 'tenant' => null, 'runs' => collect(), @@ -49,7 +49,7 @@ protected function getViewData(): array /** @var Collection $runs */ $runs = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->orderByDesc('created_at') ->orderByDesc('id') ->limit(5) diff --git a/apps/platform/app/Filament/Widgets/Tenant/TenantArchivedBanner.php b/apps/platform/app/Filament/Widgets/Tenant/TenantArchivedBanner.php index 85415cd9..99e39eb4 100644 --- a/apps/platform/app/Filament/Widgets/Tenant/TenantArchivedBanner.php +++ b/apps/platform/app/Filament/Widgets/Tenant/TenantArchivedBanner.php @@ -4,7 +4,7 @@ namespace App\Filament\Widgets\Tenant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Tenants\TenantLifecyclePresentation; use Filament\Facades\Filament; use Filament\Widgets\Widget; @@ -23,8 +23,8 @@ protected function getViewData(): array $tenant = Filament::getTenant(); return [ - 'tenant' => $tenant instanceof Tenant ? $tenant : null, - 'presentation' => $tenant instanceof Tenant ? TenantLifecyclePresentation::fromTenant($tenant) : null, + 'tenant' => $tenant instanceof ManagedEnvironment ? $tenant : null, + 'presentation' => $tenant instanceof ManagedEnvironment ? TenantLifecyclePresentation::fromTenant($tenant) : null, ]; } } diff --git a/apps/platform/app/Filament/Widgets/Tenant/TenantReviewPackCard.php b/apps/platform/app/Filament/Widgets/Tenant/TenantReviewPackCard.php index 9eb73e28..14a0231b 100644 --- a/apps/platform/app/Filament/Widgets/Tenant/TenantReviewPackCard.php +++ b/apps/platform/app/Filament/Widgets/Tenant/TenantReviewPackCard.php @@ -8,7 +8,7 @@ use App\Filament\Pages\Reviews\CustomerReviewWorkspace; use App\Models\OperationRun; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\ReviewPackService; use App\Support\Auth\Capabilities; @@ -31,17 +31,17 @@ class TenantReviewPackCard extends Widget protected string $view = 'filament.widgets.tenant.tenant-review-pack-card'; - public ?Tenant $record = null; + public ?ManagedEnvironment $record = null; - private function resolveTenant(): ?Tenant + private function resolveTenant(): ?ManagedEnvironment { $tenant = Filament::getTenant(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return $tenant; } - return $this->record instanceof Tenant ? $this->record : null; + return $this->record instanceof ManagedEnvironment ? $this->record : null; } public function generatePack(bool $includePii = true, bool $includeOperations = true): void @@ -54,7 +54,7 @@ public function generatePack(bool $includePii = true, bool $includeOperations = $tenant = $this->resolveTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -91,7 +91,7 @@ public function generatePack(bool $includePii = true, bool $includeOperations = $activeRun = $service->checkActiveRun($tenant) ? OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->active() ->orderByDesc('id') @@ -155,7 +155,7 @@ protected function getViewData(): array { $tenant = $this->resolveTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return $this->emptyState(); } @@ -177,7 +177,7 @@ protected function getViewData(): array $latestPack = ReviewPack::query() ->with(['tenantReview', 'operationRun']) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->orderByDesc('created_at') ->orderByDesc('id') ->first(); diff --git a/apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php b/apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php index 952d6c9d..8f2da846 100644 --- a/apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php +++ b/apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php @@ -4,7 +4,7 @@ namespace App\Filament\Widgets\Tenant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Models\User; use App\Services\PortfolioTriage\TenantTriageReviewService; @@ -75,7 +75,7 @@ protected function getViewData(): array { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return ['context' => null, 'reviewState' => null]; } @@ -135,7 +135,7 @@ private function canShowReviewActions(): bool { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return false; } @@ -153,7 +153,7 @@ private function reviewModalDescription(string $targetManualState): \Closure return function () use ($targetManualState): string { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return 'This triage session is no longer available.'; } @@ -188,7 +188,7 @@ private function handleReviewMutation(string $targetManualState, TenantTriageRev { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -257,7 +257,7 @@ private function handleReviewMutation(string $targetManualState, TenantTriageRev /** * @return array|null */ - private function currentReviewStateFor(Tenant $tenant, string $concernFamily): ?array + private function currentReviewStateFor(ManagedEnvironment $tenant, string $concernFamily): ?array { $tenantId = (int) $tenant->getKey(); @@ -283,7 +283,7 @@ private function currentReviewStateFor(Tenant $tenant, string $concernFamily): ? /** * @return array{backupHealth: \App\Support\BackupHealth\TenantBackupHealthAssessment, recoveryEvidence: array} */ - private function concernTruthFor(Tenant $tenant): array + private function concernTruthFor(ManagedEnvironment $tenant): array { $tenantId = (int) $tenant->getKey(); @@ -300,7 +300,7 @@ private function concernTruthFor(Tenant $tenant): array return $this->cachedConcernTruth; } - private function clearConcernCachesFor(Tenant $tenant): void + private function clearConcernCachesFor(ManagedEnvironment $tenant): void { $tenantId = (int) $tenant->getKey(); @@ -323,7 +323,7 @@ private function concernFamilyLabel(string $concernFamily): string }; } - private function resolveArrivalContext(Tenant $tenant): ?PortfolioArrivalContext + private function resolveArrivalContext(ManagedEnvironment $tenant): ?PortfolioArrivalContext { $tenantId = (int) $tenant->getKey(); diff --git a/apps/platform/app/Filament/Widgets/Tenant/TenantVerificationReport.php b/apps/platform/app/Filament/Widgets/Tenant/TenantVerificationReport.php index dd17ba70..7a62fa39 100644 --- a/apps/platform/app/Filament/Widgets/Tenant/TenantVerificationReport.php +++ b/apps/platform/app/Filament/Widgets/Tenant/TenantVerificationReport.php @@ -8,7 +8,7 @@ use App\Filament\Support\VerificationReportChangeIndicator; use App\Filament\Support\VerificationReportViewer; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Tenants\TenantOperabilityService; use App\Services\Verification\StartVerification; @@ -30,17 +30,17 @@ class TenantVerificationReport extends Widget protected string $view = 'filament.widgets.tenant.tenant-verification-report'; - public ?Tenant $record = null; + public ?ManagedEnvironment $record = null; - private function resolveTenant(): ?Tenant + private function resolveTenant(): ?ManagedEnvironment { $tenant = Filament::getTenant(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return $tenant; } - return $this->record instanceof Tenant ? $this->record : null; + return $this->record instanceof ManagedEnvironment ? $this->record : null; } public function startVerification(StartVerification $verification): void @@ -53,7 +53,7 @@ public function startVerification(StartVerification $verification): void $tenant = $this->resolveTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -112,7 +112,7 @@ protected function getViewData(): array { $tenant = $this->resolveTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return [ 'tenant' => null, 'run' => null, @@ -127,7 +127,7 @@ protected function getViewData(): array } $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->orderByDesc('id') ->first(); diff --git a/apps/platform/app/Filament/Widgets/Workspace/WorkspaceNeedsAttention.php b/apps/platform/app/Filament/Widgets/Workspace/WorkspaceNeedsAttention.php index 4780d269..b02b4d8f 100644 --- a/apps/platform/app/Filament/Widgets/Workspace/WorkspaceNeedsAttention.php +++ b/apps/platform/app/Filament/Widgets/Workspace/WorkspaceNeedsAttention.php @@ -17,7 +17,7 @@ class WorkspaceNeedsAttention extends Widget /** * @var arrayforTenant($tenantIdentifier) ->first(); @@ -116,7 +116,7 @@ private function resolveTenant(string $tenantIdentifier, ?int $workspaceId): Ten $tenant->restore(); } - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { if ($tenant->workspace_id === null && $workspaceId !== null) { $tenant->forceFill(['workspace_id' => $workspaceId])->save(); } @@ -126,17 +126,17 @@ private function resolveTenant(string $tenantIdentifier, ?int $workspaceId): Ten abort_if($workspaceId === null, ResponseAlias::HTTP_FORBIDDEN, 'Missing workspace context'); - return Tenant::create([ - 'tenant_id' => $tenantIdentifier, - 'name' => 'New Tenant', + return ManagedEnvironment::create([ + 'managed_environment_id' => $tenantIdentifier, + 'name' => 'New ManagedEnvironment', 'workspace_id' => $workspaceId, ]); } - private function upsertProviderConnectionForConsent(Tenant $tenant, string $status, ?string $error): ProviderConnection + private function upsertProviderConnectionForConsent(ManagedEnvironment $tenant, string $status, ?string $error): ProviderConnection { $hasDefault = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('is_default', true) ->exists(); @@ -155,9 +155,9 @@ private function upsertProviderConnectionForConsent(Tenant $tenant, string $stat $connection = ProviderConnection::query()->updateOrCreate( [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) ($tenant->graphTenantId() ?? $tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->graphTenantId() ?? $tenant->managed_environment_id ?? $tenant->external_id), ], [ 'workspace_id' => (int) $tenant->workspace_id, @@ -217,10 +217,10 @@ private function verificationStateLabel(ProviderConnection $connection): string return ucfirst(str_replace('_', ' ', $verificationStatus?->value ?? 'unknown')); } - private function invalidateResumableOnboardingVerificationState(Tenant $tenant, ProviderConnection $connection): void + private function invalidateResumableOnboardingVerificationState(ManagedEnvironment $tenant, ProviderConnection $connection): void { TenantOnboardingSession::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->resumable() ->each(function (TenantOnboardingSession $draft) use ($connection): void { $state = is_array($draft->state) ? $draft->state : []; diff --git a/apps/platform/app/Http/Controllers/OpenFindingExceptionsQueueController.php b/apps/platform/app/Http/Controllers/OpenFindingExceptionsQueueController.php index ffc66127..185007a6 100644 --- a/apps/platform/app/Http/Controllers/OpenFindingExceptionsQueueController.php +++ b/apps/platform/app/Http/Controllers/OpenFindingExceptionsQueueController.php @@ -5,7 +5,7 @@ namespace App\Http\Controllers; use App\Filament\Pages\Monitoring\FindingExceptionsQueue; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\WorkspaceCapabilityResolver; @@ -16,7 +16,7 @@ final class OpenFindingExceptionsQueueController extends Controller { - public function __invoke(Request $request, Tenant $tenant): RedirectResponse + public function __invoke(Request $request, ManagedEnvironment $tenant): RedirectResponse { $user = auth()->user(); diff --git a/apps/platform/app/Http/Controllers/RbacDelegatedAuthController.php b/apps/platform/app/Http/Controllers/RbacDelegatedAuthController.php index c79e24b2..a9c01bf4 100644 --- a/apps/platform/app/Http/Controllers/RbacDelegatedAuthController.php +++ b/apps/platform/app/Http/Controllers/RbacDelegatedAuthController.php @@ -2,7 +2,7 @@ namespace App\Http\Controllers; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; @@ -17,8 +17,8 @@ public function start(Request $request): RedirectResponse { $tenantIdentifier = $request->string('tenant')->toString(); $tenant = $tenantIdentifier - ? Tenant::query()->forTenant($tenantIdentifier)->firstOrFail() - : Tenant::current(); + ? ManagedEnvironment::query()->forTenant($tenantIdentifier)->firstOrFail() + : ManagedEnvironment::current(); $targetTenant = $tenantIdentifier ?: $tenant->graphTenantId(); @@ -67,10 +67,10 @@ public function callback(Request $request): RedirectResponse abort_if(! $expectedState, Response::HTTP_FORBIDDEN, 'RBAC state missing'); abort_if($expectedState !== $request->string('state')->toString(), Response::HTTP_FORBIDDEN, 'Invalid RBAC state'); - abort_if(! $tenantId, Response::HTTP_BAD_REQUEST, 'Tenant context missing'); + abort_if(! $tenantId, Response::HTTP_BAD_REQUEST, 'ManagedEnvironment context missing'); - /** @var Tenant $tenant */ - $tenant = Tenant::query()->findOrFail($tenantId); + /** @var ManagedEnvironment $tenant */ + $tenant = ManagedEnvironment::query()->findOrFail($tenantId); $code = $request->string('code')->toString(); abort_if(empty($code), Response::HTTP_BAD_REQUEST, 'Authorization code missing'); @@ -103,7 +103,7 @@ private function exchangeAuthorizationCode(string $code): array { $response = Http::asForm()->post(sprintf( 'https://login.microsoftonline.com/%s/oauth2/v2.0/token', - config('graph.tenant_id', 'common') + config('graph.managed_environment_id', 'common') ), [ 'client_id' => config('graph.client_id'), 'client_secret' => config('graph.client_secret'), @@ -125,7 +125,7 @@ private function exchangeAuthorizationCode(string $code): array ]; } - public static function cacheKey(Tenant $tenant, ?int $userId = null, ?string $sessionId = null): string + public static function cacheKey(ManagedEnvironment $tenant, ?int $userId = null, ?string $sessionId = null): string { $suffix = $userId ? "user_{$userId}" : 'session_'.($sessionId ?: 'anon'); diff --git a/apps/platform/app/Http/Controllers/ReviewPackDownloadController.php b/apps/platform/app/Http/Controllers/ReviewPackDownloadController.php index 74bb0566..acf7e8e4 100644 --- a/apps/platform/app/Http/Controllers/ReviewPackDownloadController.php +++ b/apps/platform/app/Http/Controllers/ReviewPackDownloadController.php @@ -4,7 +4,7 @@ namespace App\Http\Controllers; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\ReviewPack; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; @@ -23,7 +23,7 @@ public function __invoke(Request $request, ReviewPack $reviewPack): StreamedResp $user = $request->user(); $tenant = $reviewPack->tenant; - if (! $user instanceof User || ! $tenant instanceof Tenant) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment) { throw new NotFoundHttpException; } diff --git a/apps/platform/app/Http/Controllers/SelectTenantController.php b/apps/platform/app/Http/Controllers/SelectTenantController.php index 25f7fe3f..58ae1f9d 100644 --- a/apps/platform/app/Http/Controllers/SelectTenantController.php +++ b/apps/platform/app/Http/Controllers/SelectTenantController.php @@ -5,7 +5,7 @@ namespace App\Http\Controllers; use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\UserTenantPreference; use App\Services\Tenants\TenantOperabilityService; @@ -33,15 +33,15 @@ public function __invoke(Request $request): RedirectResponse } $validated = $request->validate([ - 'tenant_id' => ['required', 'integer'], + 'managed_environment_id' => ['required', 'integer'], ]); - $tenant = Tenant::query() + $tenant = ManagedEnvironment::query() ->where('workspace_id', $workspaceId) - ->whereKey($validated['tenant_id']) + ->whereKey($validated['managed_environment_id']) ->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -70,7 +70,7 @@ public function __invoke(Request $request): RedirectResponse return redirect()->to(TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant)); } - private function persistLastTenant(User $user, Tenant $tenant): void + private function persistLastTenant(User $user, ManagedEnvironment $tenant): void { if (Schema::hasColumn('users', 'last_tenant_id')) { $user->forceFill(['last_tenant_id' => $tenant->getKey()])->save(); @@ -78,12 +78,12 @@ private function persistLastTenant(User $user, Tenant $tenant): void return; } - if (! Schema::hasTable('user_tenant_preferences')) { + if (! Schema::hasTable('user_managed_environment_preferences')) { return; } UserTenantPreference::query()->updateOrCreate( - ['user_id' => $user->getKey(), 'tenant_id' => $tenant->getKey()], + ['user_id' => $user->getKey(), 'managed_environment_id' => $tenant->getKey()], ['last_used_at' => now()] ); } diff --git a/apps/platform/app/Http/Controllers/TenantOnboardingController.php b/apps/platform/app/Http/Controllers/TenantOnboardingController.php index 641d484c..8cca10c4 100644 --- a/apps/platform/app/Http/Controllers/TenantOnboardingController.php +++ b/apps/platform/app/Http/Controllers/TenantOnboardingController.php @@ -3,7 +3,7 @@ namespace App\Http\Controllers; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\AuditLogger; use App\Services\Providers\AdminConsentUrlFactory; use App\Support\Providers\ProviderConnectionType; @@ -65,16 +65,15 @@ public function __invoke( return redirect()->away($url); } - private function resolveTenant(string $tenantIdentifier, ?int $workspaceId): Tenant + private function resolveTenant(string $tenantIdentifier, ?int $workspaceId): ManagedEnvironment { - $tenant = Tenant::query() + $tenant = ManagedEnvironment::query() ->where(function ($query) use ($tenantIdentifier): void { - $query->where('tenant_id', $tenantIdentifier) - ->orWhere('external_id', $tenantIdentifier); + $query->where('slug', $tenantIdentifier); }) ->first(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { if ($tenant->workspace_id === null && $workspaceId !== null) { $tenant->forceFill(['workspace_id' => $workspaceId])->save(); } @@ -84,26 +83,26 @@ private function resolveTenant(string $tenantIdentifier, ?int $workspaceId): Ten abort_if($workspaceId === null, ResponseAlias::HTTP_FORBIDDEN, 'Missing workspace context'); - return Tenant::create([ - 'tenant_id' => $tenantIdentifier, - 'name' => 'New Tenant', + return ManagedEnvironment::create([ + 'slug' => $tenantIdentifier, + 'name' => 'New ManagedEnvironment', 'workspace_id' => $workspaceId, ]); } - private function upsertPlatformConnection(Tenant $tenant): ProviderConnection + private function upsertPlatformConnection(ManagedEnvironment $tenant): ProviderConnection { $hasDefault = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('is_default', true) ->exists(); $connection = ProviderConnection::query()->updateOrCreate( [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) ($tenant->graphTenantId() ?? $tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->graphTenantId() ?? $tenant->managed_environment_id ?? $tenant->external_id), ], [ 'workspace_id' => (int) $tenant->workspace_id, diff --git a/apps/platform/app/Http/Middleware/EnsureWorkspaceSelected.php b/apps/platform/app/Http/Middleware/EnsureWorkspaceSelected.php index ca532fe2..8d0e100c 100644 --- a/apps/platform/app/Http/Middleware/EnsureWorkspaceSelected.php +++ b/apps/platform/app/Http/Middleware/EnsureWorkspaceSelected.php @@ -50,7 +50,7 @@ public function handle(Request $request, Closure $next): Response return $next($request); } - // Tenant-scoped routes are handled separately. + // ManagedEnvironment-scoped routes are handled separately. if (str_starts_with($path, '/admin/t/')) { return $next($request); } @@ -213,7 +213,7 @@ private function isChooserFirstPath(string $path): bool private function requestHasExplicitTenantContext(Request $request): bool { - if (filled($request->query('tenant')) || filled($request->query('tenant_id'))) { + if (filled($request->query('tenant')) || filled($request->query('managed_environment_id'))) { return true; } diff --git a/apps/platform/app/Jobs/AddPoliciesToBackupSetJob.php b/apps/platform/app/Jobs/AddPoliciesToBackupSetJob.php index 1c4fe7a2..b4745641 100644 --- a/apps/platform/app/Jobs/AddPoliciesToBackupSetJob.php +++ b/apps/platform/app/Jobs/AddPoliciesToBackupSetJob.php @@ -8,7 +8,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Intune\FoundationSnapshotService; use App\Services\Intune\PolicyCaptureOrchestrator; @@ -69,7 +69,7 @@ public function handle( return; } - $tenant = Tenant::query()->find($this->tenantId); + $tenant = ManagedEnvironment::query()->find($this->tenantId); $initiator = User::query()->find($this->userId); $policyIds = $this->normalizePolicyIds($this->policyIds); @@ -78,12 +78,12 @@ public function handle( $includeFoundations = (bool) ($this->options['include_foundations'] ?? false); try { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { $this->failRun( operationRunService: $operationRunService, tenant: null, code: 'tenant.not_found', - message: 'Tenant not found for run.', + message: 'ManagedEnvironment not found for run.', initiator: $initiator, ); @@ -91,7 +91,7 @@ public function handle( } $backupSet = BackupSet::withTrashed() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereKey($this->backupSetId) ->first(); @@ -198,7 +198,7 @@ public function handle( /** @var EloquentCollection $policies */ $policies = Policy::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereIn('id', $policyIds) ->get() ->keyBy('id'); @@ -405,7 +405,7 @@ public function handle( try { BackupItem::create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->getKey(), 'policy_id' => $policy->getKey(), 'policy_version_id' => $version->getKey(), @@ -513,7 +513,7 @@ public function handle( } catch (Throwable $throwable) { $this->failRun( operationRunService: $operationRunService, - tenant: $tenant instanceof Tenant ? $tenant : null, + tenant: $tenant instanceof ManagedEnvironment ? $tenant : null, code: 'exception.unhandled', message: $throwable->getMessage(), initiator: $initiator, @@ -539,7 +539,7 @@ private function normalizePolicyIds(array $policyIds): array private function failRun( OperationRunService $operationRunService, - ?Tenant $tenant, + ?ManagedEnvironment $tenant, string $code, string $message, ?User $initiator = null, @@ -577,7 +577,7 @@ private function captureFoundations( SnapshotValidator $snapshotValidator, VersionService $versionService, OperationRunService $operationRunService, - Tenant $tenant, + ManagedEnvironment $tenant, BackupSet $backupSet, ?string $createdBy = null, ): array { @@ -739,7 +739,7 @@ private function captureFoundations( * @param array $metadata */ private function createFoundationBackupItem( - Tenant $tenant, + ManagedEnvironment $tenant, BackupSet $backupSet, SnapshotValidator $snapshotValidator, string $foundationType, @@ -764,7 +764,7 @@ private function createFoundationBackupItem( } return BackupItem::create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->getKey(), 'policy_id' => $policy?->getKey(), 'policy_version_id' => $version?->getKey(), @@ -786,7 +786,7 @@ private function supportsFoundationVersioning(string $foundationType): bool * @param array $metadata */ private function resolveFoundationPolicy( - Tenant $tenant, + ManagedEnvironment $tenant, string $foundationType, string $sourceId, ?string $platform, @@ -800,7 +800,7 @@ private function resolveFoundationPolicy( ?? $sourceId; $policy = Policy::query()->firstOrNew([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => $sourceId, 'policy_type' => $foundationType, ]); diff --git a/apps/platform/app/Jobs/Alerts/EvaluateAlertsJob.php b/apps/platform/app/Jobs/Alerts/EvaluateAlertsJob.php index e319a6d4..16febdc6 100644 --- a/apps/platform/app/Jobs/Alerts/EvaluateAlertsJob.php +++ b/apps/platform/app/Jobs/Alerts/EvaluateAlertsJob.php @@ -202,7 +202,7 @@ private function resolveWindowStart(OperationRun $operationRun): CarbonImmutable { $previous = OperationRun::query() ->where('workspace_id', (int) $operationRun->workspace_id) - ->whereNull('tenant_id') + ->whereNull('managed_environment_id') ->where('type', 'alerts.evaluate') ->where('status', OperationRunStatus::Completed->value) ->whereNotNull('completed_at') @@ -259,7 +259,7 @@ private function highDriftEvents(int $workspaceId, CarbonImmutable $windowStart) foreach ($findings as $finding) { $events[] = [ 'event_type' => 'high_drift', - 'tenant_id' => (int) $finding->tenant_id, + 'managed_environment_id' => (int) $finding->managed_environment_id, 'severity' => (string) $finding->severity, 'fingerprint_key' => 'finding:'.(int) $finding->getKey(), 'title' => 'High drift finding detected', @@ -335,7 +335,7 @@ private function baselineHighDriftEvents(int $workspaceId, CarbonImmutable $wind $events[] = [ 'event_type' => AlertRule::EVENT_BASELINE_HIGH_DRIFT, - 'tenant_id' => (int) $finding->tenant_id, + 'managed_environment_id' => (int) $finding->managed_environment_id, 'severity' => $severity, 'fingerprint_key' => 'finding_fingerprint:'.$fingerprint, 'title' => 'Baseline drift detected', @@ -365,7 +365,7 @@ private function baselineCompareFailedEvents(int $workspaceId, CarbonImmutable $ { $failedRuns = OperationRun::query() ->where('workspace_id', $workspaceId) - ->whereNotNull('tenant_id') + ->whereNotNull('managed_environment_id') ->where('type', OperationRunType::BaselineCompare->value) ->where('status', OperationRunStatus::Completed->value) ->whereIn('outcome', [ @@ -380,7 +380,7 @@ private function baselineCompareFailedEvents(int $workspaceId, CarbonImmutable $ $events = []; foreach ($failedRuns as $failedRun) { - $tenantId = (int) ($failedRun->tenant_id ?? 0); + $tenantId = (int) ($failedRun->managed_environment_id ?? 0); if ($tenantId <= 0) { continue; @@ -388,7 +388,7 @@ private function baselineCompareFailedEvents(int $workspaceId, CarbonImmutable $ $events[] = [ 'event_type' => AlertRule::EVENT_BASELINE_COMPARE_FAILED, - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'severity' => 'high', 'fingerprint_key' => 'operation_run:'.(int) $failedRun->getKey(), 'title' => 'Baseline compare failed', @@ -411,13 +411,13 @@ private function slaDueEvents(int $workspaceId, CarbonImmutable $windowStart): a $newlyOverdueTenantIds = Finding::query() ->where('workspace_id', $workspaceId) - ->whereNotNull('tenant_id') + ->whereNotNull('managed_environment_id') ->whereNotNull('due_at') ->where('due_at', '>', $windowStart) ->where('due_at', '<=', $now) ->whereIn('status', Finding::openStatusesForQuery()) - ->orderBy('tenant_id') - ->pluck('tenant_id') + ->orderBy('managed_environment_id') + ->pluck('managed_environment_id') ->map(static fn (mixed $value): int => (int) $value) ->filter(static fn (int $tenantId): bool => $tenantId > 0) ->unique() @@ -453,16 +453,16 @@ private function slaDueEvents(int $workspaceId, CarbonImmutable $windowStart): a $overdueFindings = Finding::query() ->where('workspace_id', $workspaceId) - ->whereIn('tenant_id', $newlyOverdueTenantIds) + ->whereIn('managed_environment_id', $newlyOverdueTenantIds) ->whereNotNull('due_at') ->where('due_at', '<=', $now) ->whereIn('status', Finding::openStatusesForQuery()) - ->orderBy('tenant_id') + ->orderBy('managed_environment_id') ->orderBy('id') - ->get(['tenant_id', 'severity']); + ->get(['managed_environment_id', 'severity']); foreach ($overdueFindings as $finding) { - $tenantId = (int) ($finding->tenant_id ?? 0); + $tenantId = (int) ($finding->managed_environment_id ?? 0); if (! isset($summaryByTenant[$tenantId])) { continue; @@ -499,7 +499,7 @@ private function slaDueEvents(int $workspaceId, CarbonImmutable $windowStart): a $events[] = [ 'event_type' => AlertRule::EVENT_SLA_DUE, - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'severity' => (string) ($summary['severity'] ?? Finding::SEVERITY_HIGH), 'fingerprint_key' => sprintf('sla_due:tenant:%d:window:%s', $tenantId, $windowFingerprint), 'title' => 'SLA due findings detected', @@ -621,14 +621,14 @@ private function permissionMissingEvents(int $workspaceId, CarbonImmutable $wind foreach ($findings as $finding) { $events[] = [ 'event_type' => AlertRule::EVENT_PERMISSION_MISSING, - 'tenant_id' => (int) $finding->tenant_id, + 'managed_environment_id' => (int) $finding->managed_environment_id, 'severity' => (string) $finding->severity, 'fingerprint_key' => 'finding:'.(int) $finding->getKey(), 'title' => 'Missing permission detected', 'body' => sprintf( 'Permission "%s" is missing for tenant %d (severity: %s).', (string) ($finding->evidence_jsonb['permission_key'] ?? $finding->subject_external_id ?? 'unknown'), - (int) $finding->tenant_id, + (int) $finding->managed_environment_id, (string) $finding->severity, ), 'metadata' => [ @@ -662,7 +662,7 @@ private function entraAdminRolesHighEvents(int $workspaceId, CarbonImmutable $wi $events[] = [ 'event_type' => AlertRule::EVENT_ENTRA_ADMIN_ROLES_HIGH, - 'tenant_id' => (int) $finding->tenant_id, + 'managed_environment_id' => (int) $finding->managed_environment_id, 'severity' => (string) $finding->severity, 'fingerprint_key' => 'finding:'.(int) $finding->getKey(), 'title' => 'High-privilege Entra admin role detected', diff --git a/apps/platform/app/Jobs/ApplyBackupScheduleRetentionJob.php b/apps/platform/app/Jobs/ApplyBackupScheduleRetentionJob.php index 106ca162..e3a27d38 100644 --- a/apps/platform/app/Jobs/ApplyBackupScheduleRetentionJob.php +++ b/apps/platform/app/Jobs/ApplyBackupScheduleRetentionJob.php @@ -35,13 +35,13 @@ public function handle(AuditLogger $auditLogger, SettingsResolver $settingsResol $operationRun = OperationRun::query()->create([ 'workspace_id' => (int) $schedule->tenant->workspace_id, - 'tenant_id' => (int) $schedule->tenant_id, + 'managed_environment_id' => (int) $schedule->managed_environment_id, 'user_id' => null, 'initiator_name' => 'System', 'type' => OperationRunType::BackupScheduleRetention->value, 'status' => OperationRunStatus::Running->value, 'outcome' => OperationRunOutcome::Pending->value, - 'run_identity_hash' => hash('sha256', (string) $schedule->tenant_id.':'.OperationRunType::BackupScheduleRetention->value.':'.$schedule->id.':'.Str::uuid()->toString()), + 'run_identity_hash' => hash('sha256', (string) $schedule->managed_environment_id.':'.OperationRunType::BackupScheduleRetention->value.':'.$schedule->id.':'.Str::uuid()->toString()), 'context' => [ 'backup_schedule_id' => (int) $schedule->id, ], @@ -89,7 +89,7 @@ public function handle(AuditLogger $auditLogger, SettingsResolver $settingsResol /** @var Collection $keepBackupSetIds */ $keepBackupSetIds = OperationRun::query() - ->where('tenant_id', (int) $schedule->tenant_id) + ->where('managed_environment_id', (int) $schedule->managed_environment_id) ->whereIn('type', OperationCatalog::rawValuesForCanonical(OperationRunType::BackupScheduleExecute->value)) ->where('status', OperationRunStatus::Completed->value) ->where('context->backup_schedule_id', (int) $schedule->id) @@ -104,7 +104,7 @@ public function handle(AuditLogger $auditLogger, SettingsResolver $settingsResol /** @var Collection $allBackupSetIds */ $allBackupSetIds = OperationRun::query() - ->where('tenant_id', (int) $schedule->tenant_id) + ->where('managed_environment_id', (int) $schedule->managed_environment_id) ->whereIn('type', OperationCatalog::rawValuesForCanonical(OperationRunType::BackupScheduleExecute->value)) ->where('status', OperationRunStatus::Completed->value) ->where('context->backup_schedule_id', (int) $schedule->id) @@ -124,7 +124,7 @@ public function handle(AuditLogger $auditLogger, SettingsResolver $settingsResol if ($deleteBackupSetIds->isNotEmpty()) { BackupSet::query() - ->where('tenant_id', $schedule->tenant_id) + ->where('managed_environment_id', $schedule->managed_environment_id) ->whereIn('id', $deleteBackupSetIds->all()) ->whereNull('deleted_at') ->chunkById(200, function (Collection $sets) use (&$deletedCount): void { diff --git a/apps/platform/app/Jobs/BackfillWorkspaceIdsJob.php b/apps/platform/app/Jobs/BackfillWorkspaceIdsJob.php index 44b5bb4f..7e95eadc 100644 --- a/apps/platform/app/Jobs/BackfillWorkspaceIdsJob.php +++ b/apps/platform/app/Jobs/BackfillWorkspaceIdsJob.php @@ -57,10 +57,10 @@ public function handle(OperationRunService $operationRunService, WorkspaceAuditL while (true) { $ids = DB::table($this->table) - ->join('tenants', 'tenants.id', '=', sprintf('%s.tenant_id', $this->table)) + ->join('managed_environments', 'managed_environments.id', '=', sprintf('%s.managed_environment_id', $this->table)) ->whereNull(sprintf('%s.workspace_id', $this->table)) ->where(sprintf('%s.id', $this->table), '>', $cursor) - ->where('tenants.workspace_id', $this->workspaceId) + ->where('managed_environments.workspace_id', $this->workspaceId) ->orderBy(sprintf('%s.id', $this->table)) ->limit($batchSize) ->pluck(sprintf('%s.id', $this->table)) @@ -150,9 +150,9 @@ public function handle(OperationRunService $operationRunService, WorkspaceAuditL private function remainingRows(): int { return (int) DB::table($this->table) - ->join('tenants', 'tenants.id', '=', sprintf('%s.tenant_id', $this->table)) + ->join('managed_environments', 'managed_environments.id', '=', sprintf('%s.managed_environment_id', $this->table)) ->whereNull(sprintf('%s.workspace_id', $this->table)) - ->where('tenants.workspace_id', $this->workspaceId) + ->where('managed_environments.workspace_id', $this->workspaceId) ->count(); } diff --git a/apps/platform/app/Jobs/BulkPolicyExportJob.php b/apps/platform/app/Jobs/BulkPolicyExportJob.php index 0770f065..9f635afa 100644 --- a/apps/platform/app/Jobs/BulkPolicyExportJob.php +++ b/apps/platform/app/Jobs/BulkPolicyExportJob.php @@ -7,7 +7,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Support\OperationRunOutcome; @@ -44,9 +44,9 @@ public function middleware(): array public function handle(OperationRunService $operationRunService): void { - $tenant = Tenant::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new \RuntimeException('Tenant not found.'); + $tenant = ManagedEnvironment::query()->find($this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new \RuntimeException('ManagedEnvironment not found.'); } $user = User::query()->find($this->userId); @@ -64,7 +64,7 @@ public function handle(OperationRunService $operationRunService): void try { // Create Backup Set $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'name' => $this->backupName, // 'description' => $this->backupDescription, // Not in schema 'status' => 'completed', @@ -86,7 +86,7 @@ public function handle(OperationRunService $operationRunService): void try { $policy = Policy::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->find($policyId); if (! $policy) { @@ -199,7 +199,7 @@ public function handle(OperationRunService $operationRunService): void // Create Backup Item BackupItem::create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, // Added diff --git a/apps/platform/app/Jobs/BulkPolicySyncJob.php b/apps/platform/app/Jobs/BulkPolicySyncJob.php index ccefc56a..3c88c8bd 100644 --- a/apps/platform/app/Jobs/BulkPolicySyncJob.php +++ b/apps/platform/app/Jobs/BulkPolicySyncJob.php @@ -31,7 +31,7 @@ public function handle(PolicySyncService $syncService, OperationRunService $runs } (new SyncPoliciesJob( - tenantId: (int) $run->tenant_id, + tenantId: (int) $run->managed_environment_id, types: null, policyIds: $policyIds, operationRun: $run, diff --git a/apps/platform/app/Jobs/BulkPolicyUnignoreJob.php b/apps/platform/app/Jobs/BulkPolicyUnignoreJob.php index 1a27d2d6..96e10da9 100644 --- a/apps/platform/app/Jobs/BulkPolicyUnignoreJob.php +++ b/apps/platform/app/Jobs/BulkPolicyUnignoreJob.php @@ -5,7 +5,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Support\OperationRunOutcome; @@ -42,9 +42,9 @@ public function middleware(): array public function handle(OperationRunService $operationRunService): void { - $tenant = Tenant::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new \RuntimeException('Tenant not found.'); + $tenant = ManagedEnvironment::query()->find($this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new \RuntimeException('ManagedEnvironment not found.'); } $user = User::query()->find($this->userId); @@ -69,7 +69,7 @@ public function handle(OperationRunService $operationRunService): void try { $policy = Policy::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->find($policyId); if (! $policy) { diff --git a/apps/platform/app/Jobs/BulkRestoreRunForceDeleteJob.php b/apps/platform/app/Jobs/BulkRestoreRunForceDeleteJob.php index f2a79c58..64fd26dd 100644 --- a/apps/platform/app/Jobs/BulkRestoreRunForceDeleteJob.php +++ b/apps/platform/app/Jobs/BulkRestoreRunForceDeleteJob.php @@ -5,7 +5,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Support\OperationRunOutcome; @@ -40,9 +40,9 @@ public function middleware(): array public function handle(OperationRunService $operationRunService): void { - $tenant = Tenant::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new \RuntimeException('Tenant not found.'); + $tenant = ManagedEnvironment::query()->find($this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new \RuntimeException('ManagedEnvironment not found.'); } $user = User::query()->find($this->userId); @@ -74,7 +74,7 @@ public function handle(OperationRunService $operationRunService): void try { /** @var RestoreRun|null $restoreRun */ $restoreRun = RestoreRun::withTrashed() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereKey($restoreRunId) ->first(); diff --git a/apps/platform/app/Jobs/BulkRestoreRunRestoreJob.php b/apps/platform/app/Jobs/BulkRestoreRunRestoreJob.php index a07947be..0cec0df1 100644 --- a/apps/platform/app/Jobs/BulkRestoreRunRestoreJob.php +++ b/apps/platform/app/Jobs/BulkRestoreRunRestoreJob.php @@ -5,7 +5,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Support\OperationRunOutcome; @@ -40,9 +40,9 @@ public function middleware(): array public function handle(OperationRunService $operationRunService): void { - $tenant = Tenant::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new \RuntimeException('Tenant not found.'); + $tenant = ManagedEnvironment::query()->find($this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new \RuntimeException('ManagedEnvironment not found.'); } $user = User::query()->find($this->userId); @@ -74,7 +74,7 @@ public function handle(OperationRunService $operationRunService): void try { /** @var RestoreRun|null $restoreRun */ $restoreRun = RestoreRun::withTrashed() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereKey($restoreRunId) ->first(); diff --git a/apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php b/apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php index fcee2586..c3ec4d7c 100644 --- a/apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php +++ b/apps/platform/app/Jobs/CaptureBaselineSnapshotJob.php @@ -9,7 +9,7 @@ use App\Models\BaselineSnapshotItem; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Baselines\BaselineCaptureService; use App\Services\Baselines\BaselineContentCapturePhase; @@ -108,10 +108,10 @@ public function handle( throw new RuntimeException("BaselineProfile #{$profileId} not found."); } - $sourceTenant = Tenant::query()->find($sourceTenantId); + $sourceTenant = ManagedEnvironment::query()->find($sourceTenantId); - if (! $sourceTenant instanceof Tenant) { - throw new RuntimeException("Source Tenant #{$sourceTenantId} not found."); + if (! $sourceTenant instanceof ManagedEnvironment) { + throw new RuntimeException("Source ManagedEnvironment #{$sourceTenantId} not found."); } $initiator = $this->operationRun->user_id @@ -591,14 +591,14 @@ public function handle( * } */ private function collectInventorySubjects( - Tenant $sourceTenant, + ManagedEnvironment $sourceTenant, BaselineScope $scope, BaselineSnapshotIdentity $identity, ?int $latestInventorySyncRunId = null, ?array $policyTypes = null, ): array { $query = InventoryItem::query() - ->where('tenant_id', $sourceTenant->getKey()); + ->where('managed_environment_id', $sourceTenant->getKey()); if (is_int($latestInventorySyncRunId) && $latestInventorySyncRunId > 0) { $query->where('last_seen_operation_run_id', $latestInventorySyncRunId); @@ -1129,7 +1129,7 @@ private function blockedInventoryMessage(string $reasonCode, bool $changedAfterE private function auditStarted( AuditLogger $auditLogger, - Tenant $tenant, + ManagedEnvironment $tenant, BaselineProfile $profile, ?User $initiator, BaselineCaptureMode $captureMode, @@ -1162,7 +1162,7 @@ private function auditStarted( private function auditCompleted( AuditLogger $auditLogger, - Tenant $tenant, + ManagedEnvironment $tenant, BaselineProfile $profile, ?BaselineSnapshot $snapshot, ?User $initiator, diff --git a/apps/platform/app/Jobs/CompareBaselineToTenantJob.php b/apps/platform/app/Jobs/CompareBaselineToTenantJob.php index 24991080..8f434959 100644 --- a/apps/platform/app/Jobs/CompareBaselineToTenantJob.php +++ b/apps/platform/app/Jobs/CompareBaselineToTenantJob.php @@ -12,7 +12,7 @@ use App\Models\Finding; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Baselines\BaselineAutoCloseService; @@ -125,10 +125,10 @@ public function handle( throw new RuntimeException("BaselineProfile #{$profileId} not found."); } - $tenant = Tenant::query()->find($this->operationRun->tenant_id); + $tenant = ManagedEnvironment::query()->find($this->operationRun->managed_environment_id); - if (! $tenant instanceof Tenant) { - throw new RuntimeException("Tenant #{$this->operationRun->tenant_id} not found."); + if (! $tenant instanceof ManagedEnvironment) { + throw new RuntimeException("ManagedEnvironment #{$this->operationRun->managed_environment_id} not found."); } $workspace = Workspace::query()->whereKey((int) $tenant->workspace_id)->first(); @@ -906,7 +906,7 @@ private function resolveCapturedCurrentEvidenceByExternalId(array $phaseResult): private function completeWithCoverageWarning( OperationRunService $operationRunService, AuditLogger $auditLogger, - Tenant $tenant, + ManagedEnvironment $tenant, BaselineProfile $profile, ?User $initiator, ?OperationRun $inventorySyncRun, @@ -1335,12 +1335,12 @@ private function fallbackGapRecord(CompareSubjectResult $subjectResult, string $ * } */ private function loadCurrentInventory( - Tenant $tenant, + ManagedEnvironment $tenant, array $policyTypes, ?int $latestInventorySyncRunId = null, ): array { $query = InventoryItem::query() - ->where('tenant_id', $tenant->getKey()); + ->where('managed_environment_id', $tenant->getKey()); if (is_int($latestInventorySyncRunId) && $latestInventorySyncRunId > 0) { $query->where('last_seen_operation_run_id', $latestInventorySyncRunId); @@ -1420,10 +1420,10 @@ private function loadCurrentInventory( ]; } - private function resolveLatestInventorySyncRun(Tenant $tenant): ?OperationRun + private function resolveLatestInventorySyncRun(ManagedEnvironment $tenant): ?OperationRun { $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::InventorySync->value) ->where('status', OperationRunStatus::Completed->value) ->orderByDesc('completed_at') @@ -1878,7 +1878,7 @@ private function baselineProvenanceFromMetaJsonb(array $metaJsonb): array * @return array{processed_count: int, created_count: int, reopened_count: int, unchanged_count: int, seen_fingerprints: array} */ private function upsertFindings( - Tenant $tenant, + ManagedEnvironment $tenant, BaselineProfile $profile, string $scopeKey, array $driftResults, @@ -1913,7 +1913,7 @@ private function upsertFindings( $seenFingerprints[] = $fingerprint; $finding = Finding::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('fingerprint', $fingerprint) ->first(); @@ -1933,7 +1933,7 @@ private function upsertFindings( } $finding->forceFill([ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => $scopeKey, @@ -2005,7 +2005,7 @@ private function upsertFindings( private function observeFinding( Finding $finding, - Tenant $tenant, + ManagedEnvironment $tenant, CarbonImmutable $observedAt, int $currentOperationRunId, string $severity, @@ -2144,7 +2144,7 @@ private function severityForChangeType(array $severityMapping, string $changeTyp private function auditStarted( AuditLogger $auditLogger, - Tenant $tenant, + ManagedEnvironment $tenant, BaselineProfile $profile, ?User $initiator, BaselineCaptureMode $captureMode, @@ -2175,7 +2175,7 @@ private function auditStarted( private function auditCompleted( AuditLogger $auditLogger, - Tenant $tenant, + ManagedEnvironment $tenant, BaselineProfile $profile, ?User $initiator, BaselineCaptureMode $captureMode, diff --git a/apps/platform/app/Jobs/EntraGroupSyncJob.php b/apps/platform/app/Jobs/EntraGroupSyncJob.php index 5dbac095..49f28da6 100644 --- a/apps/platform/app/Jobs/EntraGroupSyncJob.php +++ b/apps/platform/app/Jobs/EntraGroupSyncJob.php @@ -4,7 +4,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Directory\EntraGroupSyncService; use App\Services\Intune\AuditLogger; use App\Services\OperationRunService; @@ -50,9 +50,9 @@ public function handle(EntraGroupSyncService $syncService, AuditLogger $auditLog return; } - $tenant = Tenant::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new RuntimeException('Tenant not found.'); + $tenant = ManagedEnvironment::query()->find($this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new RuntimeException('ManagedEnvironment not found.'); } /** @var OperationRunService $opService */ diff --git a/apps/platform/app/Jobs/FetchAssignmentsJob.php b/apps/platform/app/Jobs/FetchAssignmentsJob.php index 7323b25b..603a2536 100644 --- a/apps/platform/app/Jobs/FetchAssignmentsJob.php +++ b/apps/platform/app/Jobs/FetchAssignmentsJob.php @@ -4,7 +4,7 @@ use App\Models\BackupItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\AssignmentBackupService; use App\Services\OperationRunService; @@ -64,7 +64,7 @@ public static function dispatchTracked( ): OperationRun { $tenant = $backupItem->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new RuntimeException('BackupItem tenant context is required to dispatch assignment fetch job.'); } @@ -121,8 +121,8 @@ public function handle( $tenant = $backupItem->tenant; - if (! $tenant instanceof Tenant) { - Log::warning('FetchAssignmentsJob: Tenant not found for BackupItem', [ + if (! $tenant instanceof ManagedEnvironment) { + Log::warning('FetchAssignmentsJob: ManagedEnvironment not found for BackupItem', [ 'backup_item_id' => $this->backupItemId, ]); @@ -305,7 +305,7 @@ private static function operationRunIdentityInputs( string $policyExternalId, ): array { return [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'job_type' => self::OPERATION_TYPE, 'fingerprint' => AssignmentJobFingerprint::forFetch( backupItemId: $backupItemId, diff --git a/apps/platform/app/Jobs/GenerateEvidenceSnapshotJob.php b/apps/platform/app/Jobs/GenerateEvidenceSnapshotJob.php index f78ca1ea..e0236c9d 100644 --- a/apps/platform/app/Jobs/GenerateEvidenceSnapshotJob.php +++ b/apps/platform/app/Jobs/GenerateEvidenceSnapshotJob.php @@ -58,7 +58,7 @@ public function handle(EvidenceSnapshotService $service, OperationRunService $op ); $previousActive = EvidenceSnapshot::query() - ->where('tenant_id', (int) $snapshot->tenant_id) + ->where('managed_environment_id', (int) $snapshot->managed_environment_id) ->where('workspace_id', (int) $snapshot->workspace_id) ->where('status', EvidenceSnapshotStatus::Active->value) ->whereKeyNot((int) $snapshot->getKey()) @@ -68,7 +68,7 @@ public function handle(EvidenceSnapshotService $service, OperationRunService $op foreach ($payload['items'] as $item) { $snapshot->items()->create([ - 'tenant_id' => (int) $snapshot->tenant_id, + 'managed_environment_id' => (int) $snapshot->managed_environment_id, 'workspace_id' => (int) $snapshot->workspace_id, 'dimension_key' => $item['dimension_key'], 'state' => $item['state'], diff --git a/apps/platform/app/Jobs/GeneratePermissionPostureFindingsJob.php b/apps/platform/app/Jobs/GeneratePermissionPostureFindingsJob.php index 6d7850d9..a0ea56e9 100644 --- a/apps/platform/app/Jobs/GeneratePermissionPostureFindingsJob.php +++ b/apps/platform/app/Jobs/GeneratePermissionPostureFindingsJob.php @@ -4,7 +4,7 @@ namespace App\Jobs; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\OperationRunService; use App\Services\PermissionPosture\FindingGeneratorContract; use App\Support\OperationCatalog; @@ -31,10 +31,10 @@ public function handle( FindingGeneratorContract $generator, OperationRunService $operationRuns, ): void { - $tenant = Tenant::query()->find($this->tenantId); + $tenant = ManagedEnvironment::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new RuntimeException('Tenant not found: '.$this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new RuntimeException('ManagedEnvironment not found: '.$this->tenantId); } // FR-016: Skip if tenant has no active provider connection @@ -46,7 +46,7 @@ public function handle( tenant: $tenant, type: OperationCatalog::TYPE_PERMISSION_POSTURE_CHECK, inputs: [ - 'tenant_id' => $this->tenantId, + 'managed_environment_id' => $this->tenantId, 'trigger' => 'health_check', ], initiator: null, diff --git a/apps/platform/app/Jobs/GenerateReviewPackJob.php b/apps/platform/app/Jobs/GenerateReviewPackJob.php index 3ea447ea..7c6d8a4b 100644 --- a/apps/platform/app/Jobs/GenerateReviewPackJob.php +++ b/apps/platform/app/Jobs/GenerateReviewPackJob.php @@ -8,7 +8,7 @@ use App\Models\Finding; use App\Models\OperationRun; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Services\Intune\SecretClassificationService; use App\Services\OperationRunService; @@ -53,8 +53,8 @@ public function handle(OperationRunService $operationRunService): void $tenant = $reviewPack->tenant; - if (! $tenant instanceof Tenant) { - $this->markFailed($reviewPack, $operationRun, $operationRunService, 'tenant_not_found', 'Tenant not found'); + if (! $tenant instanceof ManagedEnvironment) { + $this->markFailed($reviewPack, $operationRun, $operationRunService, 'tenant_not_found', 'ManagedEnvironment not found'); return; } @@ -80,7 +80,7 @@ public function handle(OperationRunService $operationRunService): void } } - private function executeGeneration(ReviewPack $reviewPack, OperationRun $operationRun, Tenant $tenant, EvidenceSnapshot $snapshot, OperationRunService $operationRunService): void + private function executeGeneration(ReviewPack $reviewPack, OperationRun $operationRun, ManagedEnvironment $tenant, EvidenceSnapshot $snapshot, OperationRunService $operationRunService): void { $review = $reviewPack->tenantReview; @@ -218,7 +218,7 @@ private function executeReviewDerivedGeneration( ReviewPack $reviewPack, TenantReview $review, OperationRun $operationRun, - Tenant $tenant, + ManagedEnvironment $tenant, EvidenceSnapshot $snapshot, OperationRunService $operationRunService, ): void { @@ -327,7 +327,7 @@ private function executeReviewDerivedGeneration( summaryCounts: [ 'total' => $fileCount, 'processed' => $fileCount, - 'created' => $fileCount, + 'created' => 1, 'finding_count' => (int) ($summary['finding_count'] ?? 0), 'report_count' => (int) ($summary['report_count'] ?? 0), 'operation_count' => (int) ($summary['operation_count'] ?? 0), @@ -360,7 +360,7 @@ private function buildFileMap( array $permissionPosture, array $entraAdminRoles, $recentOperations, - Tenant $tenant, + ManagedEnvironment $tenant, EvidenceSnapshot $snapshot, array $dataFreshness, array $riskAcceptance, @@ -378,7 +378,7 @@ private function buildFileMap( // metadata.json $files['metadata.json'] = json_encode([ 'version' => '1.0', - 'tenant_id' => $tenant->external_id, + 'managed_environment_id' => $tenant->external_id, 'tenant_name' => $includePii ? $tenant->name : '[REDACTED]', 'generated_at' => now()->toIso8601String(), 'evidence_snapshot' => [ @@ -637,7 +637,7 @@ private function assembleZip(string $tempFile, array $fileMap, ?callable $afterW private function buildReviewDerivedFileMap( ReviewPack $reviewPack, TenantReview $review, - Tenant $tenant, + ManagedEnvironment $tenant, EvidenceSnapshot $snapshot, bool $includePii, bool $includeOperations, @@ -658,7 +658,7 @@ private function buildReviewDerivedFileMap( $files = [ 'metadata.json' => json_encode([ 'version' => '1.0', - 'tenant_id' => $tenant->external_id, + 'managed_environment_id' => $tenant->external_id, 'tenant_name' => $includePii ? $tenant->name : '[REDACTED]', 'generated_at' => $generatedAt->toIso8601String(), 'delivery_bundle' => $deliveryMetadata, @@ -806,7 +806,7 @@ private function deliveryBundleMetadata( */ private function buildExecutiveEntrypoint( TenantReview $review, - Tenant $tenant, + ManagedEnvironment $tenant, EvidenceSnapshot $snapshot, array $reviewSummary, bool $includePii, @@ -831,7 +831,7 @@ private function buildExecutiveEntrypoint( $lines = [ '# Executive summary', '', - 'Tenant: '.$this->plainText($tenantName, '[REDACTED]'), + 'ManagedEnvironment: '.$this->plainText($tenantName, '[REDACTED]'), 'Released review: #'.((int) $review->getKey()), 'Review status: '.$this->plainText($review->status, 'unknown'), 'Generated at: '.$generatedAt->toIso8601String(), diff --git a/apps/platform/app/Jobs/Operations/BackupSetDeleteWorkerJob.php b/apps/platform/app/Jobs/Operations/BackupSetDeleteWorkerJob.php index 3a70e09a..906fdaf5 100644 --- a/apps/platform/app/Jobs/Operations/BackupSetDeleteWorkerJob.php +++ b/apps/platform/app/Jobs/Operations/BackupSetDeleteWorkerJob.php @@ -59,7 +59,7 @@ public function handle(OperationRunService $runs, TargetScopeConcurrencyLimiter try { $backupSet = BackupSet::withTrashed() - ->where('tenant_id', $this->tenantId) + ->where('managed_environment_id', $this->tenantId) ->whereKey($this->backupSetId) ->first(); diff --git a/apps/platform/app/Jobs/Operations/BackupSetForceDeleteWorkerJob.php b/apps/platform/app/Jobs/Operations/BackupSetForceDeleteWorkerJob.php index 65d183dc..b022e930 100644 --- a/apps/platform/app/Jobs/Operations/BackupSetForceDeleteWorkerJob.php +++ b/apps/platform/app/Jobs/Operations/BackupSetForceDeleteWorkerJob.php @@ -59,7 +59,7 @@ public function handle(OperationRunService $runs, TargetScopeConcurrencyLimiter try { $backupSet = BackupSet::withTrashed() - ->where('tenant_id', $this->tenantId) + ->where('managed_environment_id', $this->tenantId) ->whereKey($this->backupSetId) ->first(); diff --git a/apps/platform/app/Jobs/Operations/BackupSetRestoreWorkerJob.php b/apps/platform/app/Jobs/Operations/BackupSetRestoreWorkerJob.php index 0d59c604..d5eef0b3 100644 --- a/apps/platform/app/Jobs/Operations/BackupSetRestoreWorkerJob.php +++ b/apps/platform/app/Jobs/Operations/BackupSetRestoreWorkerJob.php @@ -59,7 +59,7 @@ public function handle(OperationRunService $runs, TargetScopeConcurrencyLimiter try { $backupSet = BackupSet::withTrashed() - ->where('tenant_id', $this->tenantId) + ->where('managed_environment_id', $this->tenantId) ->whereKey($this->backupSetId) ->first(); diff --git a/apps/platform/app/Jobs/Operations/CapturePolicySnapshotWorkerJob.php b/apps/platform/app/Jobs/Operations/CapturePolicySnapshotWorkerJob.php index 8ce69427..2cb39074 100644 --- a/apps/platform/app/Jobs/Operations/CapturePolicySnapshotWorkerJob.php +++ b/apps/platform/app/Jobs/Operations/CapturePolicySnapshotWorkerJob.php @@ -69,7 +69,7 @@ public function handle( try { $policy = Policy::query() ->with('tenant') - ->where('tenant_id', $this->tenantId) + ->where('managed_environment_id', $this->tenantId) ->whereKey($this->policyId) ->first(); diff --git a/apps/platform/app/Jobs/Operations/CrossTenantPromotionExecutionJob.php b/apps/platform/app/Jobs/Operations/CrossTenantPromotionExecutionJob.php index 9cc02ae0..0ef3507f 100644 --- a/apps/platform/app/Jobs/Operations/CrossTenantPromotionExecutionJob.php +++ b/apps/platform/app/Jobs/Operations/CrossTenantPromotionExecutionJob.php @@ -12,7 +12,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Audit\WorkspaceAuditLogger; use App\Services\Intune\RestoreService; use App\Services\OperationRunService; @@ -75,7 +75,7 @@ public function handle( $tenant = $this->operationRun->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new RuntimeException('Promotion execution target tenant is missing.'); } @@ -183,7 +183,7 @@ public function getOperationRun(): ?OperationRun * @param list> $items * @return array{0: ?BackupSet, 1: list, 2: array, 3: list} */ - private function buildRestoreInputs(Tenant $tenant, OperationRun $operationRun, array $items): array + private function buildRestoreInputs(ManagedEnvironment $tenant, OperationRun $operationRun, array $items): array { $summary = [ 'processed' => 0, @@ -195,7 +195,7 @@ private function buildRestoreInputs(Tenant $tenant, OperationRun $operationRun, ]; $failures = []; $backupSet = BackupSet::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Cross-tenant promotion • Operation #'.$operationRun->getKey(), 'created_by' => $operationRun->user?->email, 'status' => 'completed', @@ -219,13 +219,13 @@ private function buildRestoreInputs(Tenant $tenant, OperationRun $operationRun, } $versionId = data_get($item, 'source.policy_version_id'); - $sourceTenantId = data_get($item, 'source.tenant_id'); + $sourceTenantId = data_get($item, 'source.managed_environment_id'); $version = is_numeric($versionId) && is_numeric($sourceTenantId) ? PolicyVersion::query() ->with('policy') ->whereKey((int) $versionId) - ->where('tenant_id', (int) $sourceTenantId) + ->where('managed_environment_id', (int) $sourceTenantId) ->first() : null; @@ -248,13 +248,13 @@ private function buildRestoreInputs(Tenant $tenant, OperationRun $operationRun, : (is_string($sourceExternalId) && trim($sourceExternalId) !== '' ? trim($sourceExternalId) : (string) $sourcePolicy->external_id); $targetPolicy = Policy::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('policy_type', (string) $sourcePolicy->policy_type) ->where('external_id', $policyIdentifier) ->first(); $backupItem = BackupItem::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'policy_id' => $targetPolicy?->getKey(), 'policy_identifier' => $policyIdentifier, @@ -266,7 +266,7 @@ private function buildRestoreInputs(Tenant $tenant, OperationRun $operationRun, 'source' => 'cross_tenant_promotion', 'display_name' => (string) $sourcePolicy->display_name, 'operation_run_id' => (int) $operationRun->getKey(), - 'source_tenant_id' => (int) $sourcePolicy->tenant_id, + 'source_tenant_id' => (int) $sourcePolicy->managed_environment_id, 'source_policy_id' => (int) $sourcePolicy->getKey(), 'source_policy_version_id' => (int) $version->getKey(), 'source_subject_key' => (string) ($item['subject_key'] ?? ''), diff --git a/apps/platform/app/Jobs/Operations/PolicyBulkDeleteWorkerJob.php b/apps/platform/app/Jobs/Operations/PolicyBulkDeleteWorkerJob.php index 9ade2b16..3e16594d 100644 --- a/apps/platform/app/Jobs/Operations/PolicyBulkDeleteWorkerJob.php +++ b/apps/platform/app/Jobs/Operations/PolicyBulkDeleteWorkerJob.php @@ -65,7 +65,7 @@ public function handle(OperationRunService $runs, TargetScopeConcurrencyLimiter try { $policy = Policy::query() - ->where('tenant_id', $this->tenantId) + ->where('managed_environment_id', $this->tenantId) ->whereKey($this->policyId) ->first(); diff --git a/apps/platform/app/Jobs/Operations/PolicyVersionForceDeleteWorkerJob.php b/apps/platform/app/Jobs/Operations/PolicyVersionForceDeleteWorkerJob.php index 5c13158f..ca23dd95 100644 --- a/apps/platform/app/Jobs/Operations/PolicyVersionForceDeleteWorkerJob.php +++ b/apps/platform/app/Jobs/Operations/PolicyVersionForceDeleteWorkerJob.php @@ -59,7 +59,7 @@ public function handle(OperationRunService $runs, TargetScopeConcurrencyLimiter try { $version = PolicyVersion::withTrashed() - ->where('tenant_id', $this->tenantId) + ->where('managed_environment_id', $this->tenantId) ->whereKey($this->policyVersionId) ->first(); diff --git a/apps/platform/app/Jobs/Operations/PolicyVersionPruneWorkerJob.php b/apps/platform/app/Jobs/Operations/PolicyVersionPruneWorkerJob.php index 67f22367..163e8e52 100644 --- a/apps/platform/app/Jobs/Operations/PolicyVersionPruneWorkerJob.php +++ b/apps/platform/app/Jobs/Operations/PolicyVersionPruneWorkerJob.php @@ -60,7 +60,7 @@ public function handle(OperationRunService $runs, TargetScopeConcurrencyLimiter try { $version = PolicyVersion::withTrashed() - ->where('tenant_id', $this->tenantId) + ->where('managed_environment_id', $this->tenantId) ->whereKey($this->policyVersionId) ->first(); @@ -92,7 +92,7 @@ public function handle(OperationRunService $runs, TargetScopeConcurrencyLimiter } $eligible = PolicyVersion::query() - ->where('tenant_id', $this->tenantId) + ->where('managed_environment_id', $this->tenantId) ->whereKey($version->id) ->pruneEligible($this->retentionDays) ->exists(); diff --git a/apps/platform/app/Jobs/Operations/PolicyVersionRestoreWorkerJob.php b/apps/platform/app/Jobs/Operations/PolicyVersionRestoreWorkerJob.php index 0dc9d848..d908d033 100644 --- a/apps/platform/app/Jobs/Operations/PolicyVersionRestoreWorkerJob.php +++ b/apps/platform/app/Jobs/Operations/PolicyVersionRestoreWorkerJob.php @@ -59,7 +59,7 @@ public function handle(OperationRunService $runs, TargetScopeConcurrencyLimiter try { $version = PolicyVersion::withTrashed() - ->where('tenant_id', $this->tenantId) + ->where('managed_environment_id', $this->tenantId) ->whereKey($this->policyVersionId) ->first(); diff --git a/apps/platform/app/Jobs/Operations/RestoreRunDeleteWorkerJob.php b/apps/platform/app/Jobs/Operations/RestoreRunDeleteWorkerJob.php index 2afaf1a6..cd28e758 100644 --- a/apps/platform/app/Jobs/Operations/RestoreRunDeleteWorkerJob.php +++ b/apps/platform/app/Jobs/Operations/RestoreRunDeleteWorkerJob.php @@ -59,7 +59,7 @@ public function handle(OperationRunService $runs, TargetScopeConcurrencyLimiter try { $restoreRun = RestoreRun::withTrashed() - ->where('tenant_id', $this->tenantId) + ->where('managed_environment_id', $this->tenantId) ->whereKey($this->restoreRunId) ->first(); diff --git a/apps/platform/app/Jobs/Operations/TenantSyncWorkerJob.php b/apps/platform/app/Jobs/Operations/TenantSyncWorkerJob.php index 5c6ddc0d..5bcca9ad 100644 --- a/apps/platform/app/Jobs/Operations/TenantSyncWorkerJob.php +++ b/apps/platform/app/Jobs/Operations/TenantSyncWorkerJob.php @@ -4,7 +4,7 @@ use App\Jobs\Middleware\EnsureQueuedExecutionLegitimate; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Intune\PolicySyncService; use App\Services\OperationRunService; @@ -60,9 +60,9 @@ public function handle( $lock = null; try { - $tenant = Tenant::query()->whereKey($this->tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey($this->tenantId)->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { $runs->incrementSummaryCounts($this->operationRun, [ 'processed' => 1, 'failed' => 1, @@ -70,7 +70,7 @@ public function handle( $runs->appendFailures($this->operationRun, [[ 'code' => 'tenant.not_found', - 'message' => 'Tenant '.$this->tenantId.' not found.', + 'message' => 'ManagedEnvironment '.$this->tenantId.' not found.', ]]); $runs->maybeCompleteBulkRun($this->operationRun); @@ -79,7 +79,7 @@ public function handle( } $lock = $limiter->acquireSlot($tenant->getKey(), [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ]); if (! $lock) { diff --git a/apps/platform/app/Jobs/ProviderComplianceSnapshotJob.php b/apps/platform/app/Jobs/ProviderComplianceSnapshotJob.php index c660d9c7..13fd34ea 100644 --- a/apps/platform/app/Jobs/ProviderComplianceSnapshotJob.php +++ b/apps/platform/app/Jobs/ProviderComplianceSnapshotJob.php @@ -6,7 +6,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Services\Providers\MicrosoftComplianceSnapshotService; @@ -50,9 +50,9 @@ public function handle( ProviderGateway $gateway, OperationRunService $runs, ): void { - $tenant = Tenant::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new RuntimeException('Tenant not found.'); + $tenant = ManagedEnvironment::query()->find($this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new RuntimeException('ManagedEnvironment not found.'); } $user = User::query()->find($this->userId); @@ -61,7 +61,7 @@ public function handle( } $connection = ProviderConnection::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->find($this->providerConnectionId); if (! $connection instanceof ProviderConnection) { diff --git a/apps/platform/app/Jobs/ProviderConnectionHealthCheckJob.php b/apps/platform/app/Jobs/ProviderConnectionHealthCheckJob.php index eb2614c6..afd0e9d0 100644 --- a/apps/platform/app/Jobs/ProviderConnectionHealthCheckJob.php +++ b/apps/platform/app/Jobs/ProviderConnectionHealthCheckJob.php @@ -6,7 +6,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; use App\Services\Intune\AuditLogger as TenantAuditLogger; @@ -60,9 +60,9 @@ public function handle( MicrosoftProviderHealthCheck $healthCheck, OperationRunService $runs, ): void { - $tenant = Tenant::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new RuntimeException('Tenant not found.'); + $tenant = ManagedEnvironment::query()->find($this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new RuntimeException('ManagedEnvironment not found.'); } $user = User::query()->find($this->userId); @@ -71,7 +71,7 @@ public function handle( } $connection = ProviderConnection::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->find($this->providerConnectionId); if (! $connection instanceof ProviderConnection) { @@ -402,7 +402,7 @@ private function applyHealthResult(ProviderConnection $connection, HealthResult /** * @param array $report */ - private function logVerificationCompletion(Tenant $tenant, User $actor, OperationRun $run, array $report): void + private function logVerificationCompletion(ManagedEnvironment $tenant, User $actor, OperationRun $run, array $report): void { $workspace = $tenant->workspace; @@ -430,7 +430,7 @@ private function logVerificationCompletion(Tenant $tenant, User $actor, Operatio } private function logVerificationResult( - Tenant $tenant, + ManagedEnvironment $tenant, User $actor, ProviderConnection $connection, OperationRun $run, @@ -474,7 +474,7 @@ private function logVerificationResult( } private function logConsentRevocation( - Tenant $tenant, + ManagedEnvironment $tenant, User $actor, ProviderConnection $connection, OperationRun $run, diff --git a/apps/platform/app/Jobs/ProviderInventorySyncJob.php b/apps/platform/app/Jobs/ProviderInventorySyncJob.php index 26975a1f..a0b92140 100644 --- a/apps/platform/app/Jobs/ProviderInventorySyncJob.php +++ b/apps/platform/app/Jobs/ProviderInventorySyncJob.php @@ -6,7 +6,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Services\Providers\MicrosoftProviderInventoryCollector; @@ -50,9 +50,9 @@ public function handle( ProviderGateway $gateway, OperationRunService $runs, ): void { - $tenant = Tenant::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new RuntimeException('Tenant not found.'); + $tenant = ManagedEnvironment::query()->find($this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new RuntimeException('ManagedEnvironment not found.'); } $user = User::query()->find($this->userId); @@ -61,7 +61,7 @@ public function handle( } $connection = ProviderConnection::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->find($this->providerConnectionId); if (! $connection instanceof ProviderConnection) { diff --git a/apps/platform/app/Jobs/RefreshTenantRbacHealthJob.php b/apps/platform/app/Jobs/RefreshTenantRbacHealthJob.php index 95fd4f3f..f9e82d81 100644 --- a/apps/platform/app/Jobs/RefreshTenantRbacHealthJob.php +++ b/apps/platform/app/Jobs/RefreshTenantRbacHealthJob.php @@ -4,7 +4,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Intune\RbacHealthService; use App\Services\OperationRunService; @@ -43,9 +43,9 @@ public function handle( RbacHealthService $rbacHealthService, OperationRunService $runs, ): void { - $tenant = Tenant::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new RuntimeException('Tenant not found.'); + $tenant = ManagedEnvironment::query()->find($this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new RuntimeException('ManagedEnvironment not found.'); } $user = User::query()->find($this->userId); diff --git a/apps/platform/app/Jobs/RemovePoliciesFromBackupSetJob.php b/apps/platform/app/Jobs/RemovePoliciesFromBackupSetJob.php index c39a01c7..8340330b 100644 --- a/apps/platform/app/Jobs/RemovePoliciesFromBackupSetJob.php +++ b/apps/platform/app/Jobs/RemovePoliciesFromBackupSetJob.php @@ -6,7 +6,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Intune\AuditLogger; use App\Services\OperationRunService; @@ -123,7 +123,7 @@ public function handle( 'item_count' => $backupSet->items()->count(), ]); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $auditLogger->log( tenant: $tenant, action: 'backup.items_removed', @@ -183,7 +183,7 @@ public function handle( } } catch (Throwable $throwable) { - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $auditLogger->log( tenant: $tenant, action: 'backup.items_removed', diff --git a/apps/platform/app/Jobs/RestoreAssignmentsJob.php b/apps/platform/app/Jobs/RestoreAssignmentsJob.php index 098ba257..ed419519 100644 --- a/apps/platform/app/Jobs/RestoreAssignmentsJob.php +++ b/apps/platform/app/Jobs/RestoreAssignmentsJob.php @@ -8,7 +8,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\AssignmentRestoreService; use App\Services\OperationRunService; @@ -70,7 +70,7 @@ public function __construct( public static function dispatchTracked( int $restoreRunId, - Tenant $tenant, + ManagedEnvironment $tenant, string $policyType, string $policyId, array $assignments, @@ -135,12 +135,12 @@ public function handle( OperationRunService $operationRunService, ): array { $restoreRun = RestoreRun::query()->find($this->restoreRunId); - $tenant = Tenant::query()->find($this->tenantId); + $tenant = ManagedEnvironment::query()->find($this->tenantId); - if (! $tenant instanceof Tenant || ! $restoreRun instanceof RestoreRun) { + if (! $tenant instanceof ManagedEnvironment || ! $restoreRun instanceof RestoreRun) { Log::warning('RestoreAssignmentsJob missing context', [ 'restore_run_id' => $this->restoreRunId, - 'tenant_id' => $this->tenantId, + 'managed_environment_id' => $this->tenantId, ]); return [ @@ -385,7 +385,7 @@ private static function operationRunIdentityInputs( array $foundationMapping = [], ): array { return [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'job_type' => self::OPERATION_TYPE, 'fingerprint' => AssignmentJobFingerprint::forRestore( restoreRunId: $restoreRunId, diff --git a/apps/platform/app/Jobs/RunBackupScheduleJob.php b/apps/platform/app/Jobs/RunBackupScheduleJob.php index 0563c7f0..4a408037 100644 --- a/apps/platform/app/Jobs/RunBackupScheduleJob.php +++ b/apps/platform/app/Jobs/RunBackupScheduleJob.php @@ -6,7 +6,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\BackupSchedule; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\BackupScheduling\PolicyTypeResolver; use App\Services\BackupScheduling\RunErrorMapper; use App\Services\BackupScheduling\ScheduleTimeService; @@ -111,12 +111,12 @@ public function handle( $tenant = $schedule->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { $this->markOperationRunFailed( run: $this->operationRun, summaryCounts: [], reasonCode: 'tenant_not_found', - reason: 'Tenant not found.', + reason: 'ManagedEnvironment not found.', ); return; diff --git a/apps/platform/app/Jobs/RunInventorySyncJob.php b/apps/platform/app/Jobs/RunInventorySyncJob.php index ce788057..df8fe32d 100644 --- a/apps/platform/app/Jobs/RunInventorySyncJob.php +++ b/apps/platform/app/Jobs/RunInventorySyncJob.php @@ -6,7 +6,7 @@ use App\Jobs\Middleware\EnsureQueuedExecutionLegitimate; use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Intune\AuditLogger; use App\Services\Inventory\InventorySyncService; @@ -69,9 +69,9 @@ public function handle(InventorySyncService $inventorySyncService, AuditLogger $ return; } - $tenant = Tenant::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new RuntimeException('Tenant not found.'); + $tenant = ManagedEnvironment::query()->find($this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new RuntimeException('ManagedEnvironment not found.'); } $user = User::query()->find($this->userId); diff --git a/apps/platform/app/Jobs/ScanEntraAdminRolesJob.php b/apps/platform/app/Jobs/ScanEntraAdminRolesJob.php index 6305db0e..ab4b4c1c 100644 --- a/apps/platform/app/Jobs/ScanEntraAdminRolesJob.php +++ b/apps/platform/app/Jobs/ScanEntraAdminRolesJob.php @@ -5,7 +5,7 @@ namespace App\Jobs; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\EntraAdminRoles\EntraAdminRolesFindingGenerator; use App\Services\EntraAdminRoles\EntraAdminRolesReportService; @@ -36,15 +36,15 @@ public function handle( EntraAdminRolesFindingGenerator $findingGenerator, OperationRunService $operationRuns, ): void { - $tenant = Tenant::query()->find($this->tenantId); + $tenant = ManagedEnvironment::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } // FR-018: Skip tenants without active provider connection $hasConnection = ProviderConnection::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('provider', 'microsoft') ->where('is_default', true) ->where('is_enabled', true) @@ -63,7 +63,7 @@ public function handle( tenant: $tenant, type: 'entra.admin_roles.scan', identityInputs: [ - 'tenant_id' => $this->tenantId, + 'managed_environment_id' => $this->tenantId, 'trigger' => 'scan', ], context: [ diff --git a/apps/platform/app/Jobs/SyncPoliciesJob.php b/apps/platform/app/Jobs/SyncPoliciesJob.php index 70d50f8a..7f924315 100644 --- a/apps/platform/app/Jobs/SyncPoliciesJob.php +++ b/apps/platform/app/Jobs/SyncPoliciesJob.php @@ -7,7 +7,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\NullGraphClient; use App\Services\Intune\PolicySyncService; @@ -76,7 +76,7 @@ public function handle(PolicySyncService $service, OperationRunService $operatio throw new \RuntimeException('Microsoft Graph is not enabled (GRAPH_ENABLED/GRAPH_TENANT_ID missing).'); } - $tenant = Tenant::findOrFail($this->tenantId); + $tenant = ManagedEnvironment::findOrFail($this->tenantId); if ($this->policyIds !== null) { $ids = collect($this->policyIds) @@ -92,7 +92,7 @@ public function handle(PolicySyncService $service, OperationRunService $operatio foreach ($ids as $policyId) { $policy = Policy::query() ->whereKey($policyId) - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->first(); if (! $policy) { diff --git a/apps/platform/app/Jobs/SyncRoleDefinitionsJob.php b/apps/platform/app/Jobs/SyncRoleDefinitionsJob.php index 9028db3a..ccd69f6d 100644 --- a/apps/platform/app/Jobs/SyncRoleDefinitionsJob.php +++ b/apps/platform/app/Jobs/SyncRoleDefinitionsJob.php @@ -4,7 +4,7 @@ use App\Jobs\Middleware\TrackOperationRun; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Directory\RoleDefinitionsSyncService; use App\Services\Intune\AuditLogger; use App\Services\OperationRunService; @@ -53,16 +53,16 @@ public function handle(RoleDefinitionsSyncService $syncService, AuditLogger $aud return; } - $tenant = Tenant::query()->find($this->tenantId); - if (! $tenant instanceof Tenant) { - throw new RuntimeException('Tenant not found.'); + $tenant = ManagedEnvironment::query()->find($this->tenantId); + if (! $tenant instanceof ManagedEnvironment) { + throw new RuntimeException('ManagedEnvironment not found.'); } $auditLogger->log( tenant: $tenant, action: 'directory_role_definitions.sync.started', context: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ], actorId: $this->operationRun->user_id, status: 'success', diff --git a/apps/platform/app/Livewire/BackupSetPolicyPickerTable.php b/apps/platform/app/Livewire/BackupSetPolicyPickerTable.php index e2777025..927274e8 100644 --- a/apps/platform/app/Livewire/BackupSetPolicyPickerTable.php +++ b/apps/platform/app/Livewire/BackupSetPolicyPickerTable.php @@ -5,7 +5,7 @@ use App\Jobs\AddPoliciesToBackupSetJob; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Services\Operations\BulkSelectionIdentity; @@ -60,7 +60,7 @@ public static function externalIdShort(?string $externalId): string public function table(Table $table): Table { $backupSet = BackupSet::query()->find($this->backupSetId); - $tenantId = $backupSet?->tenant_id ?? Tenant::currentOrFail()->getKey(); + $tenantId = $backupSet?->managed_environment_id ?? ManagedEnvironment::currentOrFail()->getKey(); $existingPolicyIds = $backupSet ? $backupSet->items()->pluck('policy_id')->filter()->all() : []; @@ -69,7 +69,7 @@ public function table(Table $table): Table ->queryStringIdentifier('backupSetPolicyPicker'.Str::studly((string) $this->backupSetId)) ->query( Policy::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->when($existingPolicyIds !== [], fn (Builder $query) => $query->whereNotIn('id', $existingPolicyIds)) ) ->deferLoading(! app()->runningUnitTests()) @@ -142,7 +142,7 @@ public function table(Table $table): Table SelectFilter::make('platform') ->label('Platform') ->options(fn (): array => Policy::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->whereNotNull('platform') ->distinct() ->orderBy('platform') @@ -226,12 +226,12 @@ public function table(Table $table): Table } try { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); } catch (\RuntimeException) { return false; } - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return false; } @@ -241,7 +241,7 @@ public function table(Table $table): Table return BackupSet::query() ->whereKey($this->backupSetId) - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->exists(); }) ->action(function (Collection $records): void { @@ -249,7 +249,7 @@ public function table(Table $table): Table $tenant = null; try { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); } catch (\RuntimeException) { $tenant = $backupSet->tenant; } @@ -264,7 +264,7 @@ public function table(Table $table): Table return; } - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { Notification::make() ->title('Not allowed') ->danger() @@ -273,7 +273,7 @@ public function table(Table $table): Table return; } - if ((int) $tenant->getKey() !== (int) $backupSet->tenant_id) { + if ((int) $tenant->getKey() !== (int) $backupSet->managed_environment_id) { Notification::make() ->title('Not allowed') ->danger() @@ -334,7 +334,7 @@ public function table(Table $table): Table tenant: $tenant, type: 'backup_set.update', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $user, $backupSet, $policyIds): void { diff --git a/apps/platform/app/Livewire/BulkOperationProgress.php b/apps/platform/app/Livewire/BulkOperationProgress.php index 817d86aa..863664c4 100644 --- a/apps/platform/app/Livewire/BulkOperationProgress.php +++ b/apps/platform/app/Livewire/BulkOperationProgress.php @@ -3,7 +3,7 @@ namespace App\Livewire; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OpsUx\ActiveRuns; use App\Support\OpsUx\OpsUxBrowserEvents; use Filament\Facades\Filament; @@ -38,7 +38,7 @@ public function mount(): void $this->runs = collect(); $tenant = Filament::getTenant(); - $this->tenantId = $tenant instanceof Tenant ? (int) $tenant->id : null; + $this->tenantId = $tenant instanceof ManagedEnvironment ? (int) $tenant->id : null; $this->refreshRuns(); } @@ -66,7 +66,7 @@ public function refreshRuns(): void // Best-effort: if we're mounted on a tenant page, capture it once. if ($tenantId === null) { $tenant = Filament::getTenant(); - $tenantId = $tenant instanceof Tenant ? (int) $tenant->id : null; + $tenantId = $tenant instanceof ManagedEnvironment ? (int) $tenant->id : null; $this->tenantId = $tenantId; } diff --git a/apps/platform/app/Livewire/EntraGroupCachePickerTable.php b/apps/platform/app/Livewire/EntraGroupCachePickerTable.php index 5cad1dd6..257eb9e6 100644 --- a/apps/platform/app/Livewire/EntraGroupCachePickerTable.php +++ b/apps/platform/app/Livewire/EntraGroupCachePickerTable.php @@ -4,7 +4,7 @@ use App\Filament\Resources\EntraGroupResource; use App\Models\EntraGroup; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunLinks; use Filament\Actions\Action; use Filament\Tables\Columns\TextColumn; @@ -25,12 +25,12 @@ public function mount(string $sourceGroupId): void public function table(Table $table): Table { - $tenantId = Tenant::current()?->getKey(); + $tenantId = ManagedEnvironment::current()?->getKey(); $query = EntraGroup::query(); if ($tenantId) { - $query->where('tenant_id', $tenantId); + $query->where('managed_environment_id', $tenantId); } else { $query->whereRaw('1 = 0'); } @@ -149,11 +149,11 @@ public function table(Table $table): Table Action::make('open_groups') ->label('Directory Groups') ->icon('heroicon-o-user-group') - ->url(fn (): string => EntraGroupResource::getUrl('index', tenant: Tenant::current())), + ->url(fn (): string => EntraGroupResource::getUrl('index', tenant: ManagedEnvironment::current())), Action::make('open_sync_runs') ->label('Operations') ->icon('heroicon-o-clock') - ->url(fn (): string => OperationRunLinks::index(Tenant::current())), + ->url(fn (): string => OperationRunLinks::index(ManagedEnvironment::current())), ]); } diff --git a/apps/platform/app/Livewire/InventoryItemDependencyEdgesTable.php b/apps/platform/app/Livewire/InventoryItemDependencyEdgesTable.php index 48603c5a..8d1455ff 100644 --- a/apps/platform/app/Livewire/InventoryItemDependencyEdgesTable.php +++ b/apps/platform/app/Livewire/InventoryItemDependencyEdgesTable.php @@ -5,7 +5,7 @@ namespace App\Livewire; use App\Models\InventoryItem; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Inventory\DependencyQueryService; @@ -245,22 +245,22 @@ private function resolveInventoryItem(): InventoryItem return $this->cachedInventoryItem = $inventoryItem; } - private function resolveCurrentTenant(): Tenant + private function resolveCurrentTenant(): ManagedEnvironment { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { $tenant = app(WorkspaceContext::class)->rememberedTenant(request()); } - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new NotFoundHttpException; } return $tenant; } - private function canViewInventoryItem(InventoryItem $inventoryItem, Tenant $tenant): bool + private function canViewInventoryItem(InventoryItem $inventoryItem, ManagedEnvironment $tenant): bool { $user = auth()->user(); @@ -270,7 +270,7 @@ private function canViewInventoryItem(InventoryItem $inventoryItem, Tenant $tena $capabilityResolver = app(CapabilityResolver::class); - return (int) $inventoryItem->tenant_id === (int) $tenant->getKey() + return (int) $inventoryItem->managed_environment_id === (int) $tenant->getKey() && $capabilityResolver->isMember($user, $tenant) && $capabilityResolver->can($user, $tenant, Capabilities::TENANT_VIEW); } diff --git a/apps/platform/app/Livewire/PolicyVersionAssignmentsWidget.php b/apps/platform/app/Livewire/PolicyVersionAssignmentsWidget.php index e904862d..f1b7b86f 100644 --- a/apps/platform/app/Livewire/PolicyVersionAssignmentsWidget.php +++ b/apps/platform/app/Livewire/PolicyVersionAssignmentsWidget.php @@ -3,7 +3,7 @@ namespace App\Livewire; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Directory\EntraGroupLabelResolver; use App\Support\References\ReferencePresentationVariant; use App\Support\References\ResolvedReferencePresenter; @@ -39,12 +39,12 @@ private function assignmentReferences(): array return []; } - $tenant = rescue(fn () => Tenant::current(), null); + $tenant = rescue(fn () => ManagedEnvironment::current(), null); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { $this->version->loadMissing('tenant'); - $tenant = $this->version->tenant instanceof Tenant + $tenant = $this->version->tenant instanceof ManagedEnvironment ? $this->version->tenant : null; } @@ -82,7 +82,7 @@ private function assignmentReferences(): array $groupDescriptions = []; - if ($tenant instanceof Tenant && $groupIds !== []) { + if ($tenant instanceof ManagedEnvironment && $groupIds !== []) { $resolver = app(EntraGroupLabelResolver::class); $groupDescriptions = $resolver->describeMany($tenant, $groupIds, $sourceNames); } else { @@ -114,7 +114,7 @@ private function assignmentReferences(): array $references[$index] = $presenter->present( $assignmentTargetResolver->resolve($target, [ - 'tenant_id' => $tenant?->getKey(), + 'managed_environment_id' => $tenant?->getKey(), 'target_type' => $type, 'target_id' => $targetId, 'group_descriptions' => $groupDescriptions, diff --git a/apps/platform/app/Models/AlertDelivery.php b/apps/platform/app/Models/AlertDelivery.php index 122a3a17..62c28a52 100644 --- a/apps/platform/app/Models/AlertDelivery.php +++ b/apps/platform/app/Models/AlertDelivery.php @@ -46,7 +46,7 @@ public function workspace(): BelongsTo public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function rule(): BelongsTo diff --git a/apps/platform/app/Models/AuditLog.php b/apps/platform/app/Models/AuditLog.php index 8a87adb7..11a2cbf1 100644 --- a/apps/platform/app/Models/AuditLog.php +++ b/apps/platform/app/Models/AuditLog.php @@ -38,9 +38,9 @@ class AuditLog extends Model protected static function booted(): void { static::creating(function (self $auditLog): void { - if ($auditLog->workspace_id === null && is_numeric($auditLog->tenant_id)) { - $workspaceId = Tenant::query() - ->whereKey((int) $auditLog->tenant_id) + if ($auditLog->workspace_id === null && is_numeric($auditLog->managed_environment_id)) { + $workspaceId = ManagedEnvironment::query() + ->whereKey((int) $auditLog->managed_environment_id) ->value('workspace_id'); if (is_numeric($workspaceId)) { @@ -69,7 +69,7 @@ protected static function booted(): void public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function workspace(): BelongsTo @@ -89,7 +89,7 @@ public function scopeForWorkspace(Builder $query, int $workspaceId): Builder public function scopeForTenant(Builder $query, int $tenantId): Builder { - return $query->where('tenant_id', $tenantId); + return $query->where('managed_environment_id', $tenantId); } public function scopeLatestFirst(Builder $query): Builder @@ -249,7 +249,7 @@ public function technicalMetadata(): array 'Target type' => $this->resource_type, 'Target id' => $this->resource_id, 'Operation run' => is_numeric($this->operation_run_id) ? (int) $this->operation_run_id : null, - 'Tenant scope' => is_numeric($this->tenant_id) ? (int) $this->tenant_id : null, + 'ManagedEnvironment scope' => is_numeric($this->managed_environment_id) ? (int) $this->managed_environment_id : null, 'Workspace scope' => is_numeric($this->workspace_id) ? (int) $this->workspace_id : null, ], static fn (mixed $value): bool => $value !== null && $value !== ''); } diff --git a/apps/platform/app/Models/BackupItem.php b/apps/platform/app/Models/BackupItem.php index 38966efb..c75e7547 100644 --- a/apps/platform/app/Models/BackupItem.php +++ b/apps/platform/app/Models/BackupItem.php @@ -27,7 +27,7 @@ class BackupItem extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function backupSet(): BelongsTo diff --git a/apps/platform/app/Models/BackupSchedule.php b/apps/platform/app/Models/BackupSchedule.php index ddd8a708..57a805ae 100644 --- a/apps/platform/app/Models/BackupSchedule.php +++ b/apps/platform/app/Models/BackupSchedule.php @@ -30,12 +30,12 @@ class BackupSchedule extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function operationRuns(): HasMany { - return $this->hasMany(OperationRun::class, 'tenant_id', 'tenant_id') + return $this->hasMany(OperationRun::class, 'managed_environment_id', 'managed_environment_id') ->whereIn('type', array_values(array_unique(array_merge( OperationCatalog::rawValuesForCanonical(OperationRunType::BackupScheduleExecute->value), OperationCatalog::rawValuesForCanonical(OperationRunType::BackupScheduleRetention->value), diff --git a/apps/platform/app/Models/BackupSet.php b/apps/platform/app/Models/BackupSet.php index ae6d569d..0077044e 100644 --- a/apps/platform/app/Models/BackupSet.php +++ b/apps/platform/app/Models/BackupSet.php @@ -24,7 +24,7 @@ class BackupSet extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function items(): HasMany diff --git a/apps/platform/app/Models/BaselineTenantAssignment.php b/apps/platform/app/Models/BaselineTenantAssignment.php index 0b341896..b344c9cd 100644 --- a/apps/platform/app/Models/BaselineTenantAssignment.php +++ b/apps/platform/app/Models/BaselineTenantAssignment.php @@ -26,7 +26,7 @@ public function workspace(): BelongsTo public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function baselineProfile(): BelongsTo @@ -58,7 +58,7 @@ public static function assignedTenantIdsForProfile(BaselineProfile|int $profile, return static::query() ->when($workspaceId !== null, fn (Builder $query): Builder => $query->inWorkspace($workspaceId)) ->forBaselineProfile($profile) - ->pluck('tenant_id') + ->pluck('managed_environment_id') ->map(static fn (mixed $tenantId): int => (int) $tenantId) ->filter(static fn (int $tenantId): bool => $tenantId > 0) ->values() diff --git a/apps/platform/app/Models/EntraGroup.php b/apps/platform/app/Models/EntraGroup.php index 963449a2..40101ae5 100644 --- a/apps/platform/app/Models/EntraGroup.php +++ b/apps/platform/app/Models/EntraGroup.php @@ -23,6 +23,6 @@ class EntraGroup extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } } diff --git a/apps/platform/app/Models/EntraRoleDefinition.php b/apps/platform/app/Models/EntraRoleDefinition.php index 956c4ab7..873e07a7 100644 --- a/apps/platform/app/Models/EntraRoleDefinition.php +++ b/apps/platform/app/Models/EntraRoleDefinition.php @@ -21,6 +21,6 @@ class EntraRoleDefinition extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } } diff --git a/apps/platform/app/Models/EvidenceSnapshot.php b/apps/platform/app/Models/EvidenceSnapshot.php index 67c15503..fe0d9f93 100644 --- a/apps/platform/app/Models/EvidenceSnapshot.php +++ b/apps/platform/app/Models/EvidenceSnapshot.php @@ -41,11 +41,11 @@ public function workspace(): BelongsTo } /** - * @return BelongsTo + * @return BelongsTo */ public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } /** @@ -94,7 +94,7 @@ public function tenantReviews(): HasMany */ public function scopeForTenant(Builder $query, int $tenantId): Builder { - return $query->where('tenant_id', $tenantId); + return $query->where('managed_environment_id', $tenantId); } /** diff --git a/apps/platform/app/Models/EvidenceSnapshotItem.php b/apps/platform/app/Models/EvidenceSnapshotItem.php index aec2a9e4..9ae70649 100644 --- a/apps/platform/app/Models/EvidenceSnapshotItem.php +++ b/apps/platform/app/Models/EvidenceSnapshotItem.php @@ -39,11 +39,11 @@ public function snapshot(): BelongsTo } /** - * @return BelongsTo + * @return BelongsTo */ public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } /** diff --git a/apps/platform/app/Models/Finding.php b/apps/platform/app/Models/Finding.php index d37c6a0f..71a1c59e 100644 --- a/apps/platform/app/Models/Finding.php +++ b/apps/platform/app/Models/Finding.php @@ -96,7 +96,7 @@ class Finding extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function baselineRun(): BelongsTo @@ -391,7 +391,7 @@ public function scopeWithSubjectDisplayName(Builder $query): Builder return $query->addSelect([ 'subject_display_name' => InventoryItem::query() ->select('display_name') - ->whereColumn('inventory_items.tenant_id', 'findings.tenant_id') + ->whereColumn('inventory_items.managed_environment_id', 'findings.managed_environment_id') ->whereColumn('inventory_items.external_id', 'findings.subject_external_id') ->limit(1), ]); diff --git a/apps/platform/app/Models/FindingException.php b/apps/platform/app/Models/FindingException.php index 726973ff..083e3552 100644 --- a/apps/platform/app/Models/FindingException.php +++ b/apps/platform/app/Models/FindingException.php @@ -70,11 +70,11 @@ public function workspace(): BelongsTo } /** - * @return BelongsTo + * @return BelongsTo */ public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } /** diff --git a/apps/platform/app/Models/FindingExceptionEvidenceReference.php b/apps/platform/app/Models/FindingExceptionEvidenceReference.php index fc61b3ac..b881f09e 100644 --- a/apps/platform/app/Models/FindingExceptionEvidenceReference.php +++ b/apps/platform/app/Models/FindingExceptionEvidenceReference.php @@ -36,10 +36,10 @@ public function exception(): BelongsTo } /** - * @return BelongsTo + * @return BelongsTo */ public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } } diff --git a/apps/platform/app/Models/InventoryItem.php b/apps/platform/app/Models/InventoryItem.php index 310359aa..986b127a 100644 --- a/apps/platform/app/Models/InventoryItem.php +++ b/apps/platform/app/Models/InventoryItem.php @@ -23,7 +23,7 @@ class InventoryItem extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function lastSeenRun(): BelongsTo diff --git a/apps/platform/app/Models/InventoryLink.php b/apps/platform/app/Models/InventoryLink.php index e3a71579..ea76cfd4 100644 --- a/apps/platform/app/Models/InventoryLink.php +++ b/apps/platform/app/Models/InventoryLink.php @@ -25,6 +25,6 @@ protected function casts(): array public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } } diff --git a/apps/platform/app/Models/Tenant.php b/apps/platform/app/Models/ManagedEnvironment.php similarity index 53% rename from apps/platform/app/Models/Tenant.php rename to apps/platform/app/Models/ManagedEnvironment.php index 7c342db9..c2779bfd 100644 --- a/apps/platform/app/Models/Tenant.php +++ b/apps/platform/app/Models/ManagedEnvironment.php @@ -17,7 +17,7 @@ use Illuminate\Support\Str; use RuntimeException; -class Tenant extends Model implements HasName +class ManagedEnvironment extends Model implements HasName { use HasFactory; use SoftDeletes; @@ -36,14 +36,136 @@ class Tenant extends Model implements HasName protected $casts = [ 'metadata' => 'array', - 'app_client_secret' => 'encrypted', 'is_current' => 'boolean', 'rbac_last_checked_at' => 'datetime', - 'rbac_last_setup_at' => 'datetime', - 'rbac_canary_results' => 'array', - 'rbac_last_warnings' => 'array', ]; + public function getExternalIdAttribute(): ?string + { + return $this->attributes['slug'] ?? null; + } + + public function setExternalIdAttribute(mixed $value): void + { + $this->attributes['slug'] = is_string($value) ? $value : null; + } + + public function getStatusAttribute(): ?string + { + return $this->attributes['lifecycle_status'] ?? null; + } + + public function setStatusAttribute(mixed $value): void + { + $this->attributes['lifecycle_status'] = is_string($value) ? $value : null; + } + + public function getEnvironmentAttribute(): ?string + { + return $this->attributes['kind'] ?? null; + } + + public function setEnvironmentAttribute(mixed $value): void + { + $this->attributes['kind'] = is_string($value) ? $value : null; + } + + public function getManagedEnvironmentIdAttribute(): ?string + { + return $this->attributes['slug'] ?? null; + } + + public function setManagedEnvironmentIdAttribute(mixed $value): void + { + $this->attributes['slug'] = is_string($value) ? $value : null; + } + + public function getAppClientIdAttribute(): ?string + { + return $this->legacyProviderClientId(); + } + + public function setAppClientIdAttribute(mixed $value): void + { + $this->setLegacyMetadataValue('app_client_id', $value); + } + + public function getAppClientSecretAttribute(): ?string + { + return $this->legacyMetadataValue('app_client_secret'); + } + + public function setAppClientSecretAttribute(mixed $value): void + { + $this->setLegacyMetadataValue('app_client_secret', $value); + } + + public function getAppCertificateThumbprintAttribute(): ?string + { + return $this->legacyMetadataValue('app_certificate_thumbprint'); + } + + public function setAppCertificateThumbprintAttribute(mixed $value): void + { + $this->setLegacyMetadataValue('app_certificate_thumbprint', $value); + } + + public function getAppNotesAttribute(): ?string + { + return $this->legacyMetadataValue('app_notes'); + } + + public function setAppNotesAttribute(mixed $value): void + { + $this->setLegacyMetadataValue('app_notes', $value); + } + + public function getAppStatusAttribute(): ?string + { + $metadata = $this->metadata; + + return is_array($metadata) && is_string($metadata['app_status'] ?? null) + ? $metadata['app_status'] + : null; + } + + public function setAppStatusAttribute(mixed $value): void + { + $metadata = $this->metadata; + $metadata = is_array($metadata) ? $metadata : []; + + if (is_string($value) && $value !== '') { + $metadata['app_status'] = $value; + } else { + unset($metadata['app_status']); + } + + $this->attributes['metadata'] = json_encode($metadata, JSON_THROW_ON_ERROR); + } + + public function getDomainAttribute(): ?string + { + $metadata = $this->metadata; + + return is_array($metadata) && is_string($metadata['domain'] ?? null) + ? $metadata['domain'] + : null; + } + + public function setDomainAttribute(mixed $value): void + { + $metadata = $this->metadata; + $metadata = is_array($metadata) ? $metadata : []; + + if (is_string($value) && $value !== '') { + $metadata['domain'] = $value; + } else { + unset($metadata['domain']); + } + + $this->attributes['metadata'] = json_encode($metadata, JSON_THROW_ON_ERROR); + } + public function getRbacCanaryResultsAttribute($value): array { if (is_string($value)) { @@ -74,13 +196,21 @@ public function getRbacLastWarningsAttribute($value): array protected static function booted(): void { - static::creating(function (Tenant $tenant) { - if (empty($tenant->external_id)) { - $tenant->external_id = $tenant->tenant_id ?? (string) Str::uuid(); + static::creating(function (ManagedEnvironment $tenant) { + if (empty($tenant->slug)) { + $tenant->slug = Str::slug((string) $tenant->name); + + if ($tenant->slug === '') { + $tenant->slug = (string) Str::uuid(); + } } - if (empty($tenant->status)) { - $tenant->status = self::STATUS_ACTIVE; + if (empty($tenant->kind)) { + $tenant->kind = 'managed_environment'; + } + + if (empty($tenant->lifecycle_status)) { + $tenant->lifecycle_status = self::STATUS_ACTIVE; } if ($tenant->workspace_id === null && app()->runningUnitTests() && ! static::$skipTestWorkspaceProvisioning) { @@ -93,23 +223,17 @@ protected static function booted(): void } }); - static::saving(function (Tenant $tenant) { - if (! empty($tenant->tenant_id)) { - $tenant->external_id = $tenant->tenant_id; - } - }); - - static::deleting(function (Tenant $tenant) { + static::deleting(function (ManagedEnvironment $tenant) { if ($tenant->isForceDeleting()) { return; } - $tenant->status = self::STATUS_ARCHIVED; + $tenant->lifecycle_status = self::STATUS_ARCHIVED; $tenant->saveQuietly(); }); - static::restored(function (Tenant $tenant) { - $tenant->forceFill(['status' => self::STATUS_ACTIVE])->saveQuietly(); + static::restored(function (ManagedEnvironment $tenant) { + $tenant->forceFill(['lifecycle_status' => self::STATUS_ACTIVE])->saveQuietly(); }); } @@ -117,7 +241,7 @@ public static function activeQuery(): Builder { return static::query() ->whereNull('deleted_at') - ->where('status', TenantLifecycle::Active->value); + ->where('lifecycle_status', TenantLifecycle::Active->value); } public static function skipTestWorkspaceProvisioning(bool $skip = true): void @@ -128,7 +252,7 @@ public static function skipTestWorkspaceProvisioning(bool $skip = true): void public function makeCurrent(): void { if (! $this->isSelectableAsContext()) { - throw new RuntimeException('Only active tenants can be made current.'); + throw new RuntimeException('Only active managed environments can be made current.'); } DB::transaction(function () { @@ -155,13 +279,12 @@ public static function current(): ?self if ($envTenantId) { $tenant = static::activeQuery() ->where(function (Builder $query) use ($envTenantId) { - $query->where('tenant_id', $envTenantId) - ->orWhere('external_id', $envTenantId); + $query->where('slug', $envTenantId); }) ->first(); if (! $tenant) { - throw new RuntimeException('Configured INTUNE_TENANT_ID tenant is missing or inactive.'); + throw new RuntimeException('Configured INTUNE_TENANT_ID managed environment is missing or inactive.'); } return $tenant; @@ -179,7 +302,7 @@ public static function currentOrFail(): self $tenant = static::current(); if (! $tenant) { - throw new RuntimeException('No current tenant selected.'); + throw new RuntimeException('No current managed environment selected.'); } return $tenant; @@ -187,7 +310,7 @@ public static function currentOrFail(): self public function getRouteKeyName(): string { - return 'external_id'; + return 'slug'; } public function resolveRouteBinding($value, $field = null): ?Model @@ -196,7 +319,7 @@ public function resolveRouteBinding($value, $field = null): ?Model $query = static::query(); - if ($field === 'external_id') { + if ($field === 'slug') { $query = $query->withTrashed(); } @@ -205,7 +328,7 @@ public function resolveRouteBinding($value, $field = null): ?Model public function memberships(): HasMany { - return $this->hasMany(TenantMembership::class); + return $this->hasMany(ManagedEnvironmentMembership::class); } public function workspace(): BelongsTo @@ -220,15 +343,15 @@ public function roleMappings(): HasMany public function getFilamentName(): string { - $environment = strtoupper((string) ($this->environment ?? 'other')); + $environment = strtoupper((string) ($this->kind ?? 'managed_environment')); - return "{$this->name} ({$environment})"; + return ($this->display_name ?: $this->name)." ({$environment})"; } public function users(): BelongsToMany { - return $this->belongsToMany(User::class, 'tenant_memberships') - ->using(TenantMembership::class) + return $this->belongsToMany(User::class, 'managed_environment_memberships') + ->using(ManagedEnvironmentMembership::class) ->withPivot(['id', 'role', 'source', 'source_ref', 'created_by_user_id']) ->withTimestamps(); } @@ -300,24 +423,47 @@ public function providerConnections(): HasMany public function providerCredentials(): HasManyThrough { - return $this->hasManyThrough(ProviderCredential::class, ProviderConnection::class, 'tenant_id', 'provider_connection_id'); + return $this->hasManyThrough(ProviderCredential::class, ProviderConnection::class, 'managed_environment_id', 'provider_connection_id'); } public function graphTenantId(): ?string { - return $this->tenant_id ?? $this->external_id; + $connection = $this->providerConnections() + ->where('provider', 'microsoft') + ->where('is_default', true) + ->first(); + + return is_string($connection?->entra_tenant_id) && $connection->entra_tenant_id !== '' + ? $connection->entra_tenant_id + : null; + } + + public function providerTenantContext(): string + { + return (string) ($this->graphTenantId() ?? $this->managed_environment_id ?? $this->external_id ?? $this->getKey()); } public function legacyProviderClientId(): ?string { - $clientId = trim((string) $this->app_client_id); + $clientId = trim((string) $this->providerConnections() + ->where('provider', 'microsoft') + ->where('is_default', true) + ->first()?->effectiveAppId()); - return $clientId !== '' ? $clientId : null; + if ($clientId !== '') { + return $clientId; + } + + return $this->legacyMetadataValue('app_client_id'); } public function hasLegacyProviderSecret(): bool { - return trim((string) $this->app_client_secret) !== ''; + return (bool) $this->providerConnections() + ->where('provider', 'microsoft') + ->where('is_default', true) + ->whereHas('credential') + ->exists(); } /** @@ -331,6 +477,29 @@ public function legacyProviderIdentity(): array ]; } + private function legacyMetadataValue(string $key): ?string + { + $metadata = $this->metadata; + + return is_array($metadata) && is_string($metadata[$key] ?? null) && $metadata[$key] !== '' + ? $metadata[$key] + : null; + } + + private function setLegacyMetadataValue(string $key, mixed $value): void + { + $metadata = $this->metadata; + $metadata = is_array($metadata) ? $metadata : []; + + if (is_string($value) && $value !== '') { + $metadata[$key] = $value; + } else { + unset($metadata[$key]); + } + + $this->attributes['metadata'] = json_encode($metadata, JSON_THROW_ON_ERROR); + } + /** * @deprecated Runtime provider calls must resolve ProviderConnection + ProviderGateway. * @@ -339,7 +508,7 @@ public function legacyProviderIdentity(): array public function graphOptions(): array { throw new \BadMethodCallException( - 'Tenant::graphOptions() has been removed. Resolve a ProviderConnection via ProviderConnectionResolver and build options via ProviderGateway (or use MicrosoftGraphOptionsResolver).' + 'ManagedEnvironment::graphOptions() has been removed. Resolve a ProviderConnection via ProviderConnectionResolver and build options via ProviderGateway (or use MicrosoftGraphOptionsResolver).' ); } @@ -353,9 +522,7 @@ public function scopeForTenant(Builder $query, self|int|string $tenant): Builder return $query->whereKey($tenant); } - return $query - ->where('tenant_id', $tenant) - ->orWhere('external_id', $tenant); + return $query->where('slug', $tenant); } public function isActive(): bool diff --git a/apps/platform/app/Models/TenantMembership.php b/apps/platform/app/Models/ManagedEnvironmentMembership.php similarity index 69% rename from apps/platform/app/Models/TenantMembership.php rename to apps/platform/app/Models/ManagedEnvironmentMembership.php index e3c063ee..47414aec 100644 --- a/apps/platform/app/Models/TenantMembership.php +++ b/apps/platform/app/Models/ManagedEnvironmentMembership.php @@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\Pivot; -class TenantMembership extends Pivot +class ManagedEnvironmentMembership extends Pivot { use HasUuids; @@ -14,7 +14,7 @@ class TenantMembership extends Pivot protected $keyType = 'string'; - protected $table = 'tenant_memberships'; + protected $table = 'managed_environment_memberships'; protected $guarded = []; @@ -25,7 +25,12 @@ class TenantMembership extends Pivot public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->managedEnvironment(); + } + + public function managedEnvironment(): BelongsTo + { + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function user(): BelongsTo diff --git a/apps/platform/app/Models/OperationRun.php b/apps/platform/app/Models/OperationRun.php index 980ff17e..a03bdaf0 100644 --- a/apps/platform/app/Models/OperationRun.php +++ b/apps/platform/app/Models/OperationRun.php @@ -43,13 +43,13 @@ protected static function booted(): void return; } - if ($operationRun->tenant_id === null) { + if ($operationRun->managed_environment_id === null) { return; } - $tenant = Tenant::query()->whereKey((int) $operationRun->tenant_id)->first(); + $tenant = ManagedEnvironment::query()->whereKey((int) $operationRun->managed_environment_id)->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -63,7 +63,7 @@ protected static function booted(): void public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class)->withTrashed(); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id')->withTrashed(); } public function workspace(): BelongsTo @@ -329,7 +329,7 @@ public static function latestBaselineCompareRunsForProfile( $runs = static::query() ->when($workspaceId !== null, fn (Builder $query): Builder => $query->where('workspace_id', $workspaceId)) - ->whereIn('tenant_id', $tenantIds) + ->whereIn('managed_environment_id', $tenantIds) ->baselineCompareForProfile($profile) ->when($completedOnly, fn (Builder $query): Builder => $query->where('status', OperationRunStatus::Completed->value)) ->orderByDesc('completed_at') @@ -337,7 +337,7 @@ public static function latestBaselineCompareRunsForProfile( ->get(); return $runs - ->unique(static fn (self $run): int => (int) $run->tenant_id) + ->unique(static fn (self $run): int => (int) $run->managed_environment_id) ->values(); } @@ -348,7 +348,7 @@ public static function latestCompletedCoverageBearingInventorySyncForTenant(int } return static::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->whereIn('type', OperationCatalog::rawValuesForCanonical(OperationRunType::InventorySync->value)) ->where('status', OperationRunStatus::Completed->value) ->whereNotNull('completed_at') diff --git a/apps/platform/app/Models/Policy.php b/apps/platform/app/Models/Policy.php index 7b77b362..648b95b7 100644 --- a/apps/platform/app/Models/Policy.php +++ b/apps/platform/app/Models/Policy.php @@ -35,7 +35,7 @@ class Policy extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function versions(): HasMany diff --git a/apps/platform/app/Models/PolicyVersion.php b/apps/platform/app/Models/PolicyVersion.php index 320d5ae5..3a6c8d54 100644 --- a/apps/platform/app/Models/PolicyVersion.php +++ b/apps/platform/app/Models/PolicyVersion.php @@ -42,7 +42,7 @@ public function previous(): ?self public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function policy(): BelongsTo diff --git a/apps/platform/app/Models/ProductUsageEvent.php b/apps/platform/app/Models/ProductUsageEvent.php index 01b75e53..ed164b06 100644 --- a/apps/platform/app/Models/ProductUsageEvent.php +++ b/apps/platform/app/Models/ProductUsageEvent.php @@ -38,11 +38,11 @@ public function workspace(): BelongsTo } /** - * @return BelongsTo + * @return BelongsTo */ public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class)->withTrashed(); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id')->withTrashed(); } /** diff --git a/apps/platform/app/Models/ProviderConnection.php b/apps/platform/app/Models/ProviderConnection.php index 78f646c3..351c01b3 100644 --- a/apps/platform/app/Models/ProviderConnection.php +++ b/apps/platform/app/Models/ProviderConnection.php @@ -36,7 +36,7 @@ class ProviderConnection extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function workspace(): BelongsTo @@ -53,7 +53,7 @@ public function makeDefault(): void { DB::transaction(function (): void { static::query() - ->where('tenant_id', $this->tenant_id) + ->where('managed_environment_id', $this->managed_environment_id) ->where('provider', $this->provider) ->where('is_default', true) ->whereKeyNot($this->getKey()) diff --git a/apps/platform/app/Models/RestoreRun.php b/apps/platform/app/Models/RestoreRun.php index ac73ec48..e574f1e4 100644 --- a/apps/platform/app/Models/RestoreRun.php +++ b/apps/platform/app/Models/RestoreRun.php @@ -32,7 +32,7 @@ class RestoreRun extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function backupSet(): BelongsTo diff --git a/apps/platform/app/Models/ReviewPack.php b/apps/platform/app/Models/ReviewPack.php index 63d168da..3a573d7e 100644 --- a/apps/platform/app/Models/ReviewPack.php +++ b/apps/platform/app/Models/ReviewPack.php @@ -48,11 +48,11 @@ public function workspace(): BelongsTo } /** - * @return BelongsTo + * @return BelongsTo */ public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } /** @@ -120,7 +120,7 @@ public function scopePastRetention(Builder $query): Builder */ public function scopeForTenant(Builder $query, int $tenantId): Builder { - return $query->where('tenant_id', $tenantId); + return $query->where('managed_environment_id', $tenantId); } /** diff --git a/apps/platform/app/Models/StoredReport.php b/apps/platform/app/Models/StoredReport.php index e3168fe7..c85ce470 100644 --- a/apps/platform/app/Models/StoredReport.php +++ b/apps/platform/app/Models/StoredReport.php @@ -20,7 +20,7 @@ class StoredReport extends Model protected $fillable = [ 'workspace_id', - 'tenant_id', + 'managed_environment_id', 'report_type', 'payload', 'fingerprint', @@ -44,6 +44,6 @@ public function workspace(): BelongsTo public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } } diff --git a/apps/platform/app/Models/SupportRequest.php b/apps/platform/app/Models/SupportRequest.php index eaf5fb5b..650cba8f 100644 --- a/apps/platform/app/Models/SupportRequest.php +++ b/apps/platform/app/Models/SupportRequest.php @@ -157,11 +157,11 @@ public function workspace(): BelongsTo } /** - * @return BelongsTo + * @return BelongsTo */ public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } /** diff --git a/apps/platform/app/Models/TenantOnboardingSession.php b/apps/platform/app/Models/TenantOnboardingSession.php index 171c3ea6..a7c5259d 100644 --- a/apps/platform/app/Models/TenantOnboardingSession.php +++ b/apps/platform/app/Models/TenantOnboardingSession.php @@ -24,7 +24,7 @@ class TenantOnboardingSession extends Model */ public const STATE_ALLOWED_KEYS = [ 'entra_tenant_id', - 'tenant_id', + 'managed_environment_id', 'tenant_name', 'environment', 'primary_domain', @@ -78,11 +78,11 @@ public function workspace(): BelongsTo } /** - * @return BelongsTo + * @return BelongsTo */ public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class)->withTrashed(); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id')->withTrashed(); } /** diff --git a/apps/platform/app/Models/TenantPermission.php b/apps/platform/app/Models/TenantPermission.php index 1c95fd01..5c1f0238 100644 --- a/apps/platform/app/Models/TenantPermission.php +++ b/apps/platform/app/Models/TenantPermission.php @@ -21,6 +21,6 @@ class TenantPermission extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } } diff --git a/apps/platform/app/Models/TenantReview.php b/apps/platform/app/Models/TenantReview.php index 5c524b55..02be9743 100644 --- a/apps/platform/app/Models/TenantReview.php +++ b/apps/platform/app/Models/TenantReview.php @@ -43,11 +43,11 @@ public function workspace(): BelongsTo } /** - * @return BelongsTo + * @return BelongsTo */ public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } /** @@ -128,7 +128,7 @@ public function reviewPacks(): HasMany */ public function scopeForTenant(Builder $query, int $tenantId): Builder { - return $query->where('tenant_id', $tenantId); + return $query->where('managed_environment_id', $tenantId); } /** diff --git a/apps/platform/app/Models/TenantReviewSection.php b/apps/platform/app/Models/TenantReviewSection.php index 4d8cba48..b5704e43 100644 --- a/apps/platform/app/Models/TenantReviewSection.php +++ b/apps/platform/app/Models/TenantReviewSection.php @@ -47,11 +47,11 @@ public function workspace(): BelongsTo } /** - * @return BelongsTo + * @return BelongsTo */ public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } /** diff --git a/apps/platform/app/Models/TenantRoleMapping.php b/apps/platform/app/Models/TenantRoleMapping.php index ff4b0e02..9ce5a1b7 100644 --- a/apps/platform/app/Models/TenantRoleMapping.php +++ b/apps/platform/app/Models/TenantRoleMapping.php @@ -22,6 +22,6 @@ class TenantRoleMapping extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } } diff --git a/apps/platform/app/Models/TenantSetting.php b/apps/platform/app/Models/TenantSetting.php index 9ee78cbb..40d16c64 100644 --- a/apps/platform/app/Models/TenantSetting.php +++ b/apps/platform/app/Models/TenantSetting.php @@ -27,7 +27,7 @@ public function workspace(): BelongsTo public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function updatedByUser(): BelongsTo diff --git a/apps/platform/app/Models/TenantTriageReview.php b/apps/platform/app/Models/TenantTriageReview.php index fa8961c6..5321d237 100644 --- a/apps/platform/app/Models/TenantTriageReview.php +++ b/apps/platform/app/Models/TenantTriageReview.php @@ -72,11 +72,11 @@ public function workspace(): BelongsTo } /** - * @return BelongsTo + * @return BelongsTo */ public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } /** @@ -102,7 +102,7 @@ public function scopeForWorkspace(Builder $query, int $workspaceId): Builder */ public function scopeForTenant(Builder $query, int $tenantId): Builder { - return $query->where('tenant_id', $tenantId); + return $query->where('managed_environment_id', $tenantId); } /** diff --git a/apps/platform/app/Models/User.php b/apps/platform/app/Models/User.php index f37f13a4..f94c1e76 100644 --- a/apps/platform/app/Models/User.php +++ b/apps/platform/app/Models/User.php @@ -72,8 +72,13 @@ public function canAccessPanel(Panel $panel): bool public function tenants(): BelongsToMany { - return $this->belongsToMany(Tenant::class, 'tenant_memberships') - ->using(TenantMembership::class) + return $this->managedEnvironments(); + } + + public function managedEnvironments(): BelongsToMany + { + return $this->belongsToMany(ManagedEnvironment::class, 'managed_environment_memberships') + ->using(ManagedEnvironmentMembership::class) ->withPivot(['id', 'role', 'source', 'source_ref', 'created_by_user_id']) ->withTimestamps(); } @@ -88,7 +93,12 @@ public function workspaces(): BelongsToMany public function tenantMemberships(): HasMany { - return $this->hasMany(TenantMembership::class); + return $this->managedEnvironmentMemberships(); + } + + public function managedEnvironmentMemberships(): HasMany + { + return $this->hasMany(ManagedEnvironmentMembership::class); } public function workspaceMemberships(): HasMany @@ -105,17 +115,17 @@ private function tenantPivotTableExists(): bool { static $exists; - return $exists ??= Schema::hasTable('tenant_memberships'); + return $exists ??= Schema::hasTable('managed_environment_memberships'); } private function tenantPreferencesTableExists(): bool { static $exists; - return $exists ??= Schema::hasTable('user_tenant_preferences'); + return $exists ??= Schema::hasTable('user_managed_environment_preferences'); } - public function tenantRoleValue(Tenant $tenant): ?string + public function tenantRoleValue(ManagedEnvironment $tenant): ?string { if (! $this->tenantPivotTableExists()) { return null; @@ -127,14 +137,14 @@ public function tenantRoleValue(Tenant $tenant): ?string return $resolver->getRole($this, $tenant)?->value; } - public function allowsTenantSync(Tenant $tenant): bool + public function allowsTenantSync(ManagedEnvironment $tenant): bool { return Gate::forUser($this)->allows(Capabilities::TENANT_SYNC, $tenant); } public function canAccessTenant(Model $tenant): bool { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return false; } @@ -158,7 +168,7 @@ public function getTenants(Panel $panel): array|Collection $operability = app(TenantOperabilityService::class); return $operability->filterSelectable($this->tenants() - ->when($workspaceId !== null, fn ($query) => $query->where('tenants.workspace_id', $workspaceId)) + ->when($workspaceId !== null, fn ($query) => $query->where('managed_environments.workspace_id', $workspaceId)) ->orderBy('name') ->get()); } @@ -175,7 +185,7 @@ public function getDefaultTenant(Panel $panel): ?Model $rememberedTenant = $workspaceContext->rememberedTenant(request()); - if ($rememberedTenant instanceof Tenant && $this->canAccessTenant($rememberedTenant)) { + if ($rememberedTenant instanceof ManagedEnvironment && $this->canAccessTenant($rememberedTenant)) { return $rememberedTenant; } @@ -185,24 +195,24 @@ public function getDefaultTenant(Panel $panel): ?Model $tenantId = $this->tenantPreferences() ->whereNotNull('last_used_at') ->orderByDesc('last_used_at') - ->value('tenant_id'); + ->value('managed_environment_id'); } if ($tenantId !== null) { $tenant = $this->tenants() - ->when($workspaceId !== null, fn ($query) => $query->where('tenants.workspace_id', $workspaceId)) + ->when($workspaceId !== null, fn ($query) => $query->where('managed_environments.workspace_id', $workspaceId)) ->whereKey($tenantId) ->first(); - if ($tenant instanceof Tenant && $operability->canSelectAsContext($tenant)) { + if ($tenant instanceof ManagedEnvironment && $operability->canSelectAsContext($tenant)) { return $tenant; } } return $this->tenants() - ->when($workspaceId !== null, fn ($query) => $query->where('tenants.workspace_id', $workspaceId)) + ->when($workspaceId !== null, fn ($query) => $query->where('managed_environments.workspace_id', $workspaceId)) ->orderBy('name') ->get() - ->first(fn (Tenant $tenant): bool => $operability->canSelectAsContext($tenant)); + ->first(fn (ManagedEnvironment $tenant): bool => $operability->canSelectAsContext($tenant)); } } diff --git a/apps/platform/app/Models/UserTenantPreference.php b/apps/platform/app/Models/UserTenantPreference.php index dab7b6c7..785c0e3e 100644 --- a/apps/platform/app/Models/UserTenantPreference.php +++ b/apps/platform/app/Models/UserTenantPreference.php @@ -9,6 +9,8 @@ class UserTenantPreference extends Model { protected $guarded = []; + protected $table = 'user_managed_environment_preferences'; + protected $casts = [ 'is_favorite' => 'boolean', 'last_used_at' => 'datetime', @@ -21,6 +23,11 @@ public function user(): BelongsTo public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->managedEnvironment(); + } + + public function managedEnvironment(): BelongsTo + { + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } } diff --git a/apps/platform/app/Models/VerificationCheckAcknowledgement.php b/apps/platform/app/Models/VerificationCheckAcknowledgement.php index 7166d81c..2e520c86 100644 --- a/apps/platform/app/Models/VerificationCheckAcknowledgement.php +++ b/apps/platform/app/Models/VerificationCheckAcknowledgement.php @@ -20,7 +20,7 @@ class VerificationCheckAcknowledgement extends Model public function tenant(): BelongsTo { - return $this->belongsTo(Tenant::class); + return $this->belongsTo(ManagedEnvironment::class, 'managed_environment_id'); } public function workspace(): BelongsTo diff --git a/apps/platform/app/Models/Workspace.php b/apps/platform/app/Models/Workspace.php index 4a424670..9151d5d2 100644 --- a/apps/platform/app/Models/Workspace.php +++ b/apps/platform/app/Models/Workspace.php @@ -35,11 +35,19 @@ public function users(): BelongsToMany } /** - * @return HasMany + * @return HasMany */ public function tenants(): HasMany { - return $this->hasMany(Tenant::class); + return $this->managedEnvironments(); + } + + /** + * @return HasMany + */ + public function managedEnvironments(): HasMany + { + return $this->hasMany(ManagedEnvironment::class); } /** diff --git a/apps/platform/app/Notifications/Findings/FindingEventNotification.php b/apps/platform/app/Notifications/Findings/FindingEventNotification.php index 804d7921..db3a9db6 100644 --- a/apps/platform/app/Notifications/Findings/FindingEventNotification.php +++ b/apps/platform/app/Notifications/Findings/FindingEventNotification.php @@ -5,7 +5,7 @@ namespace App\Notifications\Findings; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OpsUx\OperationUxPresenter; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Notification; @@ -19,7 +19,7 @@ final class FindingEventNotification extends Notification */ public function __construct( private readonly Finding $finding, - private readonly Tenant $tenant, + private readonly ManagedEnvironment $tenant, private readonly array $event, ) {} diff --git a/apps/platform/app/Observers/ProviderCredentialObserver.php b/apps/platform/app/Observers/ProviderCredentialObserver.php index 04835879..f0a54a5b 100644 --- a/apps/platform/app/Observers/ProviderCredentialObserver.php +++ b/apps/platform/app/Observers/ProviderCredentialObserver.php @@ -6,7 +6,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Intune\AuditLogger; @@ -22,7 +22,7 @@ public function created(ProviderCredential $credential): void $tenant = $connection->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -45,7 +45,7 @@ public function updated(ProviderCredential $credential): void $tenant = $connection->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -78,7 +78,7 @@ public function deleted(ProviderCredential $credential): void $tenant = $connection->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -136,7 +136,7 @@ private function changedFields(ProviderCredential $credential): array * @param array $changedFields */ private function audit( - Tenant $tenant, + ManagedEnvironment $tenant, ProviderConnection $connection, string $action, ProviderCredential $credential, diff --git a/apps/platform/app/Policies/BackupSchedulePolicy.php b/apps/platform/app/Policies/BackupSchedulePolicy.php index 6d69dd7d..f4dfa273 100644 --- a/apps/platform/app/Policies/BackupSchedulePolicy.php +++ b/apps/platform/app/Policies/BackupSchedulePolicy.php @@ -3,7 +3,7 @@ namespace App\Policies; use App\Models\BackupSchedule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Auth\Capabilities; use App\Support\OperateHub\OperateHubShell; @@ -16,11 +16,11 @@ class BackupSchedulePolicy { use HandlesAuthorization; - protected function isTenantMember(User $user, ?Tenant $tenant = null): bool + protected function isTenantMember(User $user, ?ManagedEnvironment $tenant = null): bool { $tenant ??= $this->resolvedTenant(); - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment && Gate::forUser($user)->allows(Capabilities::TENANT_VIEW, $tenant); } @@ -37,7 +37,7 @@ public function view(User $user, BackupSchedule $schedule): Response|bool return Response::denyAsNotFound(); } - return (int) $schedule->tenant_id === (int) $tenant->getKey() + return (int) $schedule->managed_environment_id === (int) $tenant->getKey() ? true : Response::denyAsNotFound(); } @@ -46,7 +46,7 @@ public function create(User $user): bool { $tenant = $this->resolvedTenant(); - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment && Gate::forUser($user)->allows(Capabilities::TENANT_BACKUP_SCHEDULES_MANAGE, $tenant); } @@ -78,7 +78,7 @@ protected function authorizeScheduleAction(User $user, BackupSchedule $schedule, return Response::denyAsNotFound(); } - if (! $tenant instanceof Tenant || (int) $schedule->tenant_id !== (int) $tenant->getKey()) { + if (! $tenant instanceof ManagedEnvironment || (int) $schedule->managed_environment_id !== (int) $tenant->getKey()) { return Response::denyAsNotFound(); } @@ -87,16 +87,16 @@ protected function authorizeScheduleAction(User $user, BackupSchedule $schedule, : Response::deny(); } - protected function resolvedTenant(): ?Tenant + protected function resolvedTenant(): ?ManagedEnvironment { if (Filament::getCurrentPanel()?->getId() === 'admin') { $tenant = app(OperateHubShell::class)->tenantOwnedPanelContext(request()); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } } diff --git a/apps/platform/app/Policies/EntraGroupPolicy.php b/apps/platform/app/Policies/EntraGroupPolicy.php index 2e8623ec..55c11afa 100644 --- a/apps/platform/app/Policies/EntraGroupPolicy.php +++ b/apps/platform/app/Policies/EntraGroupPolicy.php @@ -3,7 +3,7 @@ namespace App\Policies; use App\Models\EntraGroup; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\OperateHub\OperateHubShell; use Filament\Facades\Filament; @@ -37,23 +37,23 @@ public function view(User $user, EntraGroup $group): Response|bool return Response::denyAsNotFound(); } - if ((int) $group->tenant_id !== (int) $tenant->getKey()) { + if ((int) $group->managed_environment_id !== (int) $tenant->getKey()) { return Response::denyAsNotFound(); } return true; } - private function resolvedTenant(): ?Tenant + private function resolvedTenant(): ?ManagedEnvironment { if (Filament::getCurrentPanel()?->getId() === 'admin') { $tenant = app(OperateHubShell::class)->tenantOwnedPanelContext(request()); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } } diff --git a/apps/platform/app/Policies/EvidenceSnapshotPolicy.php b/apps/platform/app/Policies/EvidenceSnapshotPolicy.php index ecd8083b..e79506eb 100644 --- a/apps/platform/app/Policies/EvidenceSnapshotPolicy.php +++ b/apps/platform/app/Policies/EvidenceSnapshotPolicy.php @@ -5,7 +5,7 @@ namespace App\Policies; use App\Models\EvidenceSnapshot; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -17,9 +17,9 @@ class EvidenceSnapshotPolicy public function viewAny(User $user): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - if (! $tenant instanceof Tenant || ! $user->canAccessTenant($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $user->canAccessTenant($tenant)) { return false; } @@ -28,13 +28,13 @@ public function viewAny(User $user): bool public function view(User $user, EvidenceSnapshot $snapshot): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - if (! $tenant instanceof Tenant || ! $user->canAccessTenant($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $user->canAccessTenant($tenant)) { return false; } - if ((int) $snapshot->tenant_id !== (int) $tenant->getKey()) { + if ((int) $snapshot->managed_environment_id !== (int) $tenant->getKey()) { return false; } @@ -43,9 +43,9 @@ public function view(User $user, EvidenceSnapshot $snapshot): bool public function create(User $user): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - if (! $tenant instanceof Tenant || ! $user->canAccessTenant($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $user->canAccessTenant($tenant)) { return false; } @@ -54,13 +54,13 @@ public function create(User $user): bool public function delete(User $user, EvidenceSnapshot $snapshot): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - if (! $tenant instanceof Tenant || ! $user->canAccessTenant($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $user->canAccessTenant($tenant)) { return false; } - if ((int) $snapshot->tenant_id !== (int) $tenant->getKey()) { + if ((int) $snapshot->managed_environment_id !== (int) $tenant->getKey()) { return false; } diff --git a/apps/platform/app/Policies/FindingExceptionPolicy.php b/apps/platform/app/Policies/FindingExceptionPolicy.php index 9824ea25..9ab87474 100644 --- a/apps/platform/app/Policies/FindingExceptionPolicy.php +++ b/apps/platform/app/Policies/FindingExceptionPolicy.php @@ -5,7 +5,7 @@ namespace App\Policies; use App\Models\FindingException; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -24,7 +24,7 @@ public function viewAny(User $user): bool { $tenant = $this->resolvedTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return false; } @@ -39,7 +39,7 @@ public function view(User $user, FindingException $exception): Response|bool { $tenant = $this->authorizedTenantOrNull($user, $exception); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return Response::denyAsNotFound(); } @@ -60,7 +60,7 @@ private function authorizeCanonicalApproval(User $user, FindingException $except { $tenant = $exception->tenant; - if (! $tenant instanceof Tenant || ! $user->canAccessTenant($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $user->canAccessTenant($tenant)) { return Response::denyAsNotFound(); } @@ -88,11 +88,11 @@ private function authorizeCanonicalApproval(User $user, FindingException $except : Response::deny(); } - private function authorizedTenantOrNull(User $user, FindingException $exception): ?Tenant + private function authorizedTenantOrNull(User $user, FindingException $exception): ?ManagedEnvironment { $tenant = $this->resolvedTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -100,7 +100,7 @@ private function authorizedTenantOrNull(User $user, FindingException $exception) return null; } - if ((int) $exception->tenant_id !== (int) $tenant->getKey()) { + if ((int) $exception->managed_environment_id !== (int) $tenant->getKey()) { return null; } @@ -111,7 +111,7 @@ private function authorizedTenantOrNull(User $user, FindingException $exception) return $tenant; } - private function resolvedTenant(): ?Tenant + private function resolvedTenant(): ?ManagedEnvironment { if (Filament::getCurrentPanel()?->getId() === 'admin') { $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); @@ -126,13 +126,13 @@ private function resolvedTenant(): ?Tenant return null; } - $tenant = Tenant::query()->whereKey($tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey($tenantId)->first(); - return $tenant instanceof Tenant && (int) $tenant->workspace_id === $workspaceId ? $tenant : null; + return $tenant instanceof ManagedEnvironment && (int) $tenant->workspace_id === $workspaceId ? $tenant : null; } - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } } diff --git a/apps/platform/app/Policies/FindingPolicy.php b/apps/platform/app/Policies/FindingPolicy.php index 01144ad0..7ad2bf8d 100644 --- a/apps/platform/app/Policies/FindingPolicy.php +++ b/apps/platform/app/Policies/FindingPolicy.php @@ -3,7 +3,7 @@ namespace App\Policies; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -20,7 +20,7 @@ public function viewAny(User $user): bool { $tenant = $this->resolvedTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return false; } @@ -35,7 +35,7 @@ public function view(User $user, Finding $finding): Response|bool { $tenant = $this->authorizedTenantOrNull($user, $finding); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return Response::denyAsNotFound(); } @@ -89,7 +89,7 @@ private function canMutateWithAnyCapability(User $user, Finding $finding, array { $tenant = $this->authorizedTenantOrNull($user, $finding); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return Response::denyAsNotFound(); } @@ -105,11 +105,11 @@ private function canMutateWithAnyCapability(User $user, Finding $finding, array return Response::deny(); } - private function authorizedTenantOrNull(User $user, Finding $finding): ?Tenant + private function authorizedTenantOrNull(User $user, Finding $finding): ?ManagedEnvironment { $tenant = $this->resolvedTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -117,7 +117,7 @@ private function authorizedTenantOrNull(User $user, Finding $finding): ?Tenant return null; } - if ((int) $finding->tenant_id !== (int) $tenant->getKey()) { + if ((int) $finding->managed_environment_id !== (int) $tenant->getKey()) { return null; } @@ -128,16 +128,16 @@ private function authorizedTenantOrNull(User $user, Finding $finding): ?Tenant return $tenant; } - private function resolvedTenant(): ?Tenant + private function resolvedTenant(): ?ManagedEnvironment { if (Filament::getCurrentPanel()?->getId() === 'admin') { $tenant = app(OperateHubShell::class)->tenantOwnedPanelContext(request()); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - return $tenant instanceof Tenant ? $tenant : null; + return $tenant instanceof ManagedEnvironment ? $tenant : null; } } diff --git a/apps/platform/app/Policies/OperationRunPolicy.php b/apps/platform/app/Policies/OperationRunPolicy.php index d3446614..e2efb543 100644 --- a/apps/platform/app/Policies/OperationRunPolicy.php +++ b/apps/platform/app/Policies/OperationRunPolicy.php @@ -3,7 +3,7 @@ namespace App\Policies; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -48,11 +48,11 @@ public function view(User $user, OperationRun $run): Response|bool return Response::denyAsNotFound(); } - $tenantId = (int) ($run->tenant_id ?? 0); + $tenantId = (int) ($run->managed_environment_id ?? 0); if ($tenantId > 0) { $hasTenantEntitlement = $user->tenantMemberships() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->exists(); if (! $hasTenantEntitlement) { @@ -82,9 +82,9 @@ public function view(User $user, OperationRun $run): Response|bool } if ($tenantId > 0) { - $tenant = Tenant::query()->withTrashed()->whereKey($tenantId)->first(); + $tenant = ManagedEnvironment::query()->withTrashed()->whereKey($tenantId)->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return Response::denyAsNotFound(); } diff --git a/apps/platform/app/Policies/ProviderConnectionPolicy.php b/apps/platform/app/Policies/ProviderConnectionPolicy.php index 45751dda..6bf1e3d2 100644 --- a/apps/platform/app/Policies/ProviderConnectionPolicy.php +++ b/apps/platform/app/Policies/ProviderConnectionPolicy.php @@ -3,8 +3,8 @@ namespace App\Policies; use App\Models\ProviderConnection; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Support\Auth\Capabilities; @@ -26,13 +26,13 @@ public function viewAny(User $user): Response|bool return Response::denyAsNotFound(); } - $entitledTenants = Tenant::query() - ->select('tenants.*') - ->join('tenant_memberships as policy_memberships', function ($join) use ($user): void { - $join->on('policy_memberships.tenant_id', '=', 'tenants.id') + $entitledTenants = ManagedEnvironment::query() + ->select('managed_environments.*') + ->join('managed_environment_memberships as policy_memberships', function ($join) use ($user): void { + $join->on('policy_memberships.managed_environment_id', '=', 'managed_environments.id') ->where('policy_memberships.user_id', '=', (int) $user->getKey()); }) - ->where('tenants.workspace_id', (int) $workspace->getKey()) + ->where('managed_environments.workspace_id', (int) $workspace->getKey()) ->get(); if ($entitledTenants->isEmpty()) { @@ -58,7 +58,7 @@ public function view(User $user, ProviderConnection $connection): Response|bool $tenant = $this->tenantForConnection($connection); - if (! $tenant instanceof Tenant || (int) $tenant->workspace_id !== (int) $workspace->getKey()) { + if (! $tenant instanceof ManagedEnvironment || (int) $tenant->workspace_id !== (int) $workspace->getKey()) { return Response::denyAsNotFound(); } @@ -70,7 +70,7 @@ public function view(User $user, ProviderConnection $connection): Response|bool return false; } - if ((int) $connection->tenant_id !== (int) $tenant->getKey()) { + if ((int) $connection->managed_environment_id !== (int) $tenant->getKey()) { return Response::denyAsNotFound(); } @@ -91,7 +91,7 @@ public function create(User $user): Response|bool $tenant = $this->resolveCreateTenant($workspace); - if (! $tenant instanceof Tenant || ! $this->isTenantMember($user, $tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $this->isTenantMember($user, $tenant)) { return Response::denyAsNotFound(); } @@ -112,7 +112,7 @@ public function update(User $user, ProviderConnection $connection): Response|boo $tenant = $this->tenantForConnection($connection); - if (! $tenant instanceof Tenant || (int) $tenant->workspace_id !== (int) $workspace->getKey()) { + if (! $tenant instanceof ManagedEnvironment || (int) $tenant->workspace_id !== (int) $workspace->getKey()) { return Response::denyAsNotFound(); } @@ -124,7 +124,7 @@ public function update(User $user, ProviderConnection $connection): Response|boo return false; } - if ((int) $connection->tenant_id !== (int) $tenant->getKey()) { + if ((int) $connection->managed_environment_id !== (int) $tenant->getKey()) { return Response::denyAsNotFound(); } @@ -145,7 +145,7 @@ public function delete(User $user, ProviderConnection $connection): Response|boo $tenant = $this->tenantForConnection($connection); - if (! $tenant instanceof Tenant || (int) $tenant->workspace_id !== (int) $workspace->getKey()) { + if (! $tenant instanceof ManagedEnvironment || (int) $tenant->workspace_id !== (int) $workspace->getKey()) { return Response::denyAsNotFound(); } @@ -157,7 +157,7 @@ public function delete(User $user, ProviderConnection $connection): Response|boo return false; } - if ((int) $connection->tenant_id !== (int) $tenant->getKey()) { + if ((int) $connection->managed_environment_id !== (int) $tenant->getKey()) { return Response::denyAsNotFound(); } @@ -178,7 +178,7 @@ public function manageDedicated(User $user, ProviderConnection $connection): Res $tenant = $this->tenantForConnection($connection); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return Response::denyAsNotFound(); } @@ -207,7 +207,7 @@ private function currentWorkspace(User $user): ?Workspace if (! is_int($workspaceId)) { $filamentTenant = Filament::getTenant(); - if ($filamentTenant instanceof Tenant) { + if ($filamentTenant instanceof ManagedEnvironment) { $workspaceId = (int) $filamentTenant->workspace_id; } } @@ -229,15 +229,15 @@ private function currentWorkspace(User $user): ?Workspace return $workspace; } - private function resolveCreateTenant(Workspace $workspace): ?Tenant + private function resolveCreateTenant(Workspace $workspace): ?ManagedEnvironment { - $tenantExternalId = request()->query('tenant_id'); + $tenantExternalId = request()->query('managed_environment_id'); if (! is_string($tenantExternalId) || $tenantExternalId === '') { $lastTenantId = app(WorkspaceContext::class)->lastTenantId(request()); if (is_int($lastTenantId)) { - return Tenant::query() + return ManagedEnvironment::query() ->whereKey($lastTenantId) ->where('workspace_id', (int) $workspace->getKey()) ->first(); @@ -245,37 +245,37 @@ private function resolveCreateTenant(Workspace $workspace): ?Tenant $filamentTenant = Filament::getTenant(); - if ($filamentTenant instanceof Tenant && (int) $filamentTenant->workspace_id === (int) $workspace->getKey()) { + if ($filamentTenant instanceof ManagedEnvironment && (int) $filamentTenant->workspace_id === (int) $workspace->getKey()) { return $filamentTenant; } return null; } - return Tenant::query() - ->where('external_id', $tenantExternalId) + return ManagedEnvironment::query() + ->where('slug', $tenantExternalId) ->where('workspace_id', (int) $workspace->getKey()) ->first(); } - private function tenantForConnection(ProviderConnection $connection): ?Tenant + private function tenantForConnection(ProviderConnection $connection): ?ManagedEnvironment { - if ($connection->relationLoaded('tenant') && $connection->tenant instanceof Tenant) { + if ($connection->relationLoaded('tenant') && $connection->tenant instanceof ManagedEnvironment) { return $connection->tenant; } - if (is_int($connection->tenant_id) || is_numeric($connection->tenant_id)) { - return Tenant::query()->whereKey((int) $connection->tenant_id)->first(); + if (is_int($connection->managed_environment_id) || is_numeric($connection->managed_environment_id)) { + return ManagedEnvironment::query()->whereKey((int) $connection->managed_environment_id)->first(); } return null; } - private function isTenantMember(User $user, Tenant $tenant): bool + private function isTenantMember(User $user, ManagedEnvironment $tenant): bool { - return TenantMembership::query() + return ManagedEnvironmentMembership::query() ->where('user_id', (int) $user->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->exists(); } } diff --git a/apps/platform/app/Policies/ReviewPackPolicy.php b/apps/platform/app/Policies/ReviewPackPolicy.php index 84e2d4e4..6fcb9d9e 100644 --- a/apps/platform/app/Policies/ReviewPackPolicy.php +++ b/apps/platform/app/Policies/ReviewPackPolicy.php @@ -5,7 +5,7 @@ namespace App\Policies; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -17,9 +17,9 @@ class ReviewPackPolicy public function viewAny(User $user): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return false; } @@ -35,9 +35,9 @@ public function viewAny(User $user): bool public function view(User $user, ReviewPack $reviewPack): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return false; } @@ -45,7 +45,7 @@ public function view(User $user, ReviewPack $reviewPack): bool return false; } - if ((int) $reviewPack->tenant_id !== (int) $tenant->getKey()) { + if ((int) $reviewPack->managed_environment_id !== (int) $tenant->getKey()) { return false; } @@ -57,9 +57,9 @@ public function view(User $user, ReviewPack $reviewPack): bool public function create(User $user): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return false; } @@ -75,9 +75,9 @@ public function create(User $user): bool public function delete(User $user, ReviewPack $reviewPack): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return false; } @@ -85,7 +85,7 @@ public function delete(User $user, ReviewPack $reviewPack): bool return false; } - if ((int) $reviewPack->tenant_id !== (int) $tenant->getKey()) { + if ((int) $reviewPack->managed_environment_id !== (int) $tenant->getKey()) { return false; } diff --git a/apps/platform/app/Policies/TenantOnboardingSessionPolicy.php b/apps/platform/app/Policies/TenantOnboardingSessionPolicy.php index 638026e7..ee9c5876 100644 --- a/apps/platform/app/Policies/TenantOnboardingSessionPolicy.php +++ b/apps/platform/app/Policies/TenantOnboardingSessionPolicy.php @@ -4,7 +4,7 @@ namespace App\Policies; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -98,7 +98,7 @@ private function authorizeForDraft( $tenant = $tenantOnboardingSession->tenant; - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $viewability = app(TenantOperabilityService::class)->outcomeFor( tenant: $tenant, question: TenantOperabilityQuestion::TenantBoundViewability, diff --git a/apps/platform/app/Policies/TenantReviewPolicy.php b/apps/platform/app/Policies/TenantReviewPolicy.php index 697618ec..8211615d 100644 --- a/apps/platform/app/Policies/TenantReviewPolicy.php +++ b/apps/platform/app/Policies/TenantReviewPolicy.php @@ -4,7 +4,7 @@ namespace App\Policies; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Services\Auth\CapabilityResolver; @@ -18,9 +18,9 @@ class TenantReviewPolicy public function viewAny(User $user): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - if (! $tenant instanceof Tenant || ! $user->canAccessTenant($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $user->canAccessTenant($tenant)) { return false; } @@ -31,7 +31,7 @@ public function view(User $user, TenantReview $review): Response|bool { $tenant = $this->authorizedTenantOrNull($user, $review); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return Response::denyAsNotFound(); } @@ -42,9 +42,9 @@ public function view(User $user, TenantReview $review): Response|bool public function create(User $user): bool { - $tenant = Tenant::current(); + $tenant = ManagedEnvironment::current(); - if (! $tenant instanceof Tenant || ! $user->canAccessTenant($tenant)) { + if (! $tenant instanceof ManagedEnvironment || ! $user->canAccessTenant($tenant)) { return false; } @@ -80,7 +80,7 @@ private function authorizeManageAction(User $user, TenantReview $review): Respon { $tenant = $this->authorizedTenantOrNull($user, $review); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return Response::denyAsNotFound(); } @@ -89,11 +89,11 @@ private function authorizeManageAction(User $user, TenantReview $review): Respon : Response::deny(); } - private function authorizedTenantOrNull(User $user, TenantReview $review): ?Tenant + private function authorizedTenantOrNull(User $user, TenantReview $review): ?ManagedEnvironment { $tenant = $review->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } diff --git a/apps/platform/app/Providers/AppServiceProvider.php b/apps/platform/app/Providers/AppServiceProvider.php index e1c7f965..386103ba 100644 --- a/apps/platform/app/Providers/AppServiceProvider.php +++ b/apps/platform/app/Providers/AppServiceProvider.php @@ -8,7 +8,7 @@ use App\Models\OperationRun; use App\Models\ProviderCredential; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\UserTenantPreference; use App\Observers\ProviderCredentialObserver; @@ -64,6 +64,7 @@ use App\Support\References\Resolvers\PrincipalReferenceResolver; use App\Support\Ui\DerivedState\RequestScopedDerivedStateStore; use Filament\Events\TenantSet; +use Illuminate\Database\Eloquent\Model; use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Http\Request; use Illuminate\Support\Facades\Event; @@ -178,6 +179,8 @@ public function register(): void */ public function boot(): void { + $this->registerManagedEnvironmentRelationAliases(); + RateLimiter::for('entra-callback', function (Request $request) { return Limit::perMinute(20)->by((string) $request->ip()); }); @@ -188,7 +191,7 @@ public function boot(): void Event::listen(TenantSet::class, function (TenantSet $event): void { static $hasPreferencesTable; - $hasPreferencesTable ??= Schema::hasTable('user_tenant_preferences'); + $hasPreferencesTable ??= Schema::hasTable('user_managed_environment_preferences'); if (! $hasPreferencesTable) { return; @@ -197,7 +200,7 @@ public function boot(): void $tenant = $event->getTenant(); $user = $event->getUser(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -208,7 +211,7 @@ public function boot(): void UserTenantPreference::query()->updateOrCreate( [ 'user_id' => $user->getKey(), - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ], [ 'last_used_at' => now(), @@ -221,4 +224,28 @@ public function boot(): void Gate::policy(EntraGroup::class, EntraGroupPolicy::class); Gate::policy(OperationRun::class, OperationRunPolicy::class); } + + private function registerManagedEnvironmentRelationAliases(): void + { + foreach ($this->managedEnvironmentRelationAliasModels() as $modelClass) { + $modelClass::resolveRelationUsing('managedEnvironment', static function (Model $model) { + return $model->tenant(); + }); + } + } + + /** + * @return array> + */ + private function managedEnvironmentRelationAliasModels(): array + { + return collect(glob(app_path('Models/*.php')) ?: []) + ->map(static fn (string $path): string => 'App\\Models\\'.pathinfo($path, PATHINFO_FILENAME)) + ->filter(static fn (string $class): bool => class_exists($class)) + ->filter(static fn (string $class): bool => is_subclass_of($class, Model::class)) + ->filter(static fn (string $class): bool => method_exists($class, 'tenant')) + ->filter(static fn (string $class): bool => ! method_exists($class, 'managedEnvironment')) + ->values() + ->all(); + } } diff --git a/apps/platform/app/Providers/AuthServiceProvider.php b/apps/platform/app/Providers/AuthServiceProvider.php index e33818d7..272b151c 100644 --- a/apps/platform/app/Providers/AuthServiceProvider.php +++ b/apps/platform/app/Providers/AuthServiceProvider.php @@ -7,7 +7,7 @@ use App\Models\AlertRule; use App\Models\PlatformUser; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\TenantReview; use App\Models\User; @@ -47,8 +47,8 @@ public function boot(): void $workspaceResolver = app(WorkspaceCapabilityResolver::class); $defineTenantCapability = function (string $capability) use ($tenantResolver): void { - Gate::define($capability, function (User $user, ?Tenant $tenant = null) use ($tenantResolver, $capability): bool { - if (! $tenant instanceof Tenant) { + Gate::define($capability, function (User $user, ?ManagedEnvironment $tenant = null) use ($tenantResolver, $capability): bool { + if (! $tenant instanceof ManagedEnvironment) { return false; } diff --git a/apps/platform/app/Providers/Filament/TenantPanelProvider.php b/apps/platform/app/Providers/Filament/TenantPanelProvider.php index 7c5734f0..1cde9d4b 100644 --- a/apps/platform/app/Providers/Filament/TenantPanelProvider.php +++ b/apps/platform/app/Providers/Filament/TenantPanelProvider.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Auth\Login; use App\Filament\Pages\TenantDashboard; use App\Filament\Resources\TenantReviewResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Filament\PanelThemeAsset; use App\Support\Middleware\DenyNonMemberTenantAccess; use App\Support\OperationRunLinks; @@ -42,7 +42,7 @@ public function panel(Panel $panel): Panel ->brandLogoHeight('2rem') ->favicon(asset('favicon.ico')) ->font(null, provider: LocalFontProvider::class, preload: []) - ->tenant(Tenant::class, slugAttribute: 'external_id') + ->tenant(ManagedEnvironment::class, slugAttribute: 'slug') ->tenantRoutePrefix(null) ->tenantMenu(fn (): bool => filled(Filament::getTenant())) ->searchableTenantMenu() diff --git a/apps/platform/app/Services/AdapterRunReconciler.php b/apps/platform/app/Services/AdapterRunReconciler.php index 7eeb0025..cae33055 100644 --- a/apps/platform/app/Services/AdapterRunReconciler.php +++ b/apps/platform/app/Services/AdapterRunReconciler.php @@ -26,13 +26,13 @@ public function supportedTypes(): array } /** - * @param array{type?: string|null, tenant_id?: int|null, older_than_minutes?: int, limit?: int, dry_run?: bool} $options + * @param array{type?: string|null, managed_environment_id?: int|null, older_than_minutes?: int, limit?: int, dry_run?: bool} $options * @return array{candidates:int,reconciled:int,skipped:int,changes:array>} */ public function reconcile(array $options = []): array { $type = $options['type'] ?? null; - $tenantId = $options['tenant_id'] ?? null; + $tenantId = $options['managed_environment_id'] ?? null; $olderThanMinutes = max(1, (int) ($options['older_than_minutes'] ?? 10)); $limit = max(1, (int) ($options['limit'] ?? 50)); $dryRun = (bool) ($options['dry_run'] ?? true); @@ -60,7 +60,7 @@ public function reconcile(array $options = []): array ->limit($limit); if (is_int($tenantId) && $tenantId > 0) { - $query->where('tenant_id', $tenantId); + $query->where('managed_environment_id', $tenantId); } $candidates = $query->get(); @@ -110,7 +110,7 @@ private function reconcileOne(OperationRun $run, bool $dryRun): ?array } $restoreRun = RestoreRun::query() - ->where('tenant_id', $run->tenant_id) + ->where('managed_environment_id', $run->managed_environment_id) ->whereKey((int) $restoreRunId) ->first(); diff --git a/apps/platform/app/Services/Alerts/AlertDestinationTestMessageService.php b/apps/platform/app/Services/Alerts/AlertDestinationTestMessageService.php index 3bc5b79e..91827613 100644 --- a/apps/platform/app/Services/Alerts/AlertDestinationTestMessageService.php +++ b/apps/platform/app/Services/Alerts/AlertDestinationTestMessageService.php @@ -74,7 +74,7 @@ private function createTestDelivery(AlertDestination $destination): AlertDeliver { return AlertDelivery::create([ 'workspace_id' => (int) $destination->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'alert_rule_id' => null, 'alert_destination_id' => (int) $destination->getKey(), 'event_type' => AlertDelivery::EVENT_TYPE_TEST, diff --git a/apps/platform/app/Services/Alerts/AlertDispatchService.php b/apps/platform/app/Services/Alerts/AlertDispatchService.php index 63450355..8ac430be 100644 --- a/apps/platform/app/Services/Alerts/AlertDispatchService.php +++ b/apps/platform/app/Services/Alerts/AlertDispatchService.php @@ -6,7 +6,7 @@ use App\Models\AlertDelivery; use App\Models\AlertRule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use Carbon\CarbonImmutable; use Illuminate\Support\Arr; @@ -24,19 +24,19 @@ public function __construct( public function dispatchEvent(Workspace $workspace, array $event): int { $workspaceId = (int) $workspace->getKey(); - $tenantId = (int) ($event['tenant_id'] ?? 0); + $tenantId = (int) ($event['managed_environment_id'] ?? 0); $eventType = trim((string) ($event['event_type'] ?? '')); if ($workspaceId <= 0 || $tenantId <= 0 || $eventType === '') { return 0; } - $tenant = Tenant::query() + $tenant = ManagedEnvironment::query() ->whereKey($tenantId) ->where('workspace_id', $workspaceId) ->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return 0; } @@ -90,7 +90,7 @@ public function dispatchEvent(Workspace $workspace, array $event): int AlertDelivery::query()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'event_type' => $eventType, diff --git a/apps/platform/app/Services/Alerts/AlertFingerprintService.php b/apps/platform/app/Services/Alerts/AlertFingerprintService.php index 1ececb09..43d9bd8b 100644 --- a/apps/platform/app/Services/Alerts/AlertFingerprintService.php +++ b/apps/platform/app/Services/Alerts/AlertFingerprintService.php @@ -24,7 +24,7 @@ public function hash(AlertRule $rule, AlertDestination $destination, int $tenant 'workspace_id' => (int) $rule->workspace_id, 'rule_id' => (int) $rule->getKey(), 'destination_id' => (int) $destination->getKey(), - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'event_type' => trim((string) ($event['event_type'] ?? '')), 'severity' => strtolower(trim((string) ($event['severity'] ?? ''))), 'fingerprint_key' => $fingerprintKey, diff --git a/apps/platform/app/Services/AssignmentBackupService.php b/apps/platform/app/Services/AssignmentBackupService.php index a1a8e894..0b2e6a5d 100644 --- a/apps/platform/app/Services/AssignmentBackupService.php +++ b/apps/platform/app/Services/AssignmentBackupService.php @@ -3,7 +3,7 @@ namespace App\Services; use App\Models\BackupItem; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\AssignmentFetcher; use App\Services\Graph\AssignmentFilterResolver; use App\Services\Graph\GroupResolver; @@ -28,7 +28,7 @@ public function __construct( * Enrich a backup item with assignments and scope tag metadata. * * @param BackupItem $backupItem The backup item to enrich - * @param Tenant $tenant Tenant model with credentials + * @param ManagedEnvironment $tenant ManagedEnvironment model with credentials * @param string $policyType Policy type key (e.g. deviceConfiguration) * @param string $policyId Policy ID (external_id from Graph) * @param array $policyPayload Full policy payload from Graph @@ -37,7 +37,7 @@ public function __construct( */ public function enrichWithAssignments( BackupItem $backupItem, - Tenant $tenant, + ManagedEnvironment $tenant, string $policyType, string $policyId, array $policyPayload, @@ -110,7 +110,7 @@ public function enrichWithAssignments( $this->recordFetchOperationRun($backupItem, $tenant, $metadata); Log::warning('No assignments fetched for policy', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_id' => $policyId, 'backup_item_id' => $backupItem->id, ]); @@ -151,7 +151,7 @@ public function enrichWithAssignments( $this->recordFetchOperationRun($backupItem, $tenant, $metadata); Log::info('Assignments enriched for backup item', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_id' => $policyId, 'backup_item_id' => $backupItem->id, 'assignment_count' => count($assignments), @@ -164,7 +164,7 @@ public function enrichWithAssignments( /** * @param array $captureMetadata */ - public function recordFetchOperationRun(BackupItem $backupItem, Tenant $tenant, array $captureMetadata = []): void + public function recordFetchOperationRun(BackupItem $backupItem, ManagedEnvironment $tenant, array $captureMetadata = []): void { $run = $this->operationRunService->ensureRunWithIdentity( tenant: $tenant, @@ -218,7 +218,7 @@ public function recordFetchOperationRun(BackupItem $backupItem, Tenant $tenant, /** * Resolve scope tag IDs to display names. */ - private function resolveScopeTagNames(array $scopeTagIds, Tenant $tenant): array + private function resolveScopeTagNames(array $scopeTagIds, ManagedEnvironment $tenant): array { $scopeTags = $this->scopeTagResolver->resolve($scopeTagIds, $tenant); diff --git a/apps/platform/app/Services/AssignmentRestoreService.php b/apps/platform/app/Services/AssignmentRestoreService.php index dba2b134..87e18ae9 100644 --- a/apps/platform/app/Services/AssignmentRestoreService.php +++ b/apps/platform/app/Services/AssignmentRestoreService.php @@ -3,7 +3,7 @@ namespace App\Services; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\AssignmentFilterResolver; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphContractRegistry; @@ -30,7 +30,7 @@ public function __construct( * @return array{outcomes: array>, summary: array{success:int,failed:int,skipped:int}} */ public function restore( - Tenant $tenant, + ManagedEnvironment $tenant, string $policyType, string $policyId, array $assignments, diff --git a/apps/platform/app/Services/Audit/AuditEventBuilder.php b/apps/platform/app/Services/Audit/AuditEventBuilder.php index 6f1e1246..d1d84a49 100644 --- a/apps/platform/app/Services/Audit/AuditEventBuilder.php +++ b/apps/platform/app/Services/Audit/AuditEventBuilder.php @@ -11,7 +11,7 @@ use App\Models\BaselineProfile; use App\Models\Finding; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Audit\AuditActionId; use App\Support\Audit\AuditActorSnapshot; @@ -34,7 +34,7 @@ public function buildRecordAttributes( string $action, array $context = [], ?Workspace $workspace = null, - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?AuditActorSnapshot $actor = null, ?AuditTargetSnapshot $target = null, string|AuditOutcome|null $outcome = null, @@ -76,7 +76,7 @@ public function buildRecordAttributes( ); return [ - 'tenant_id' => $tenant?->getKey(), + 'managed_environment_id' => $tenant?->getKey(), 'workspace_id' => $workspace?->getKey() ?? $tenant?->workspace_id, 'actor_id' => is_numeric($resolvedActor->id) ? (int) $resolvedActor->id : null, 'actor_email' => $resolvedActor->email, @@ -103,8 +103,8 @@ public function buildRecordAttributes( public function fillMissingDerivedAttributes(array $attributes): array { $tenant = null; - if (is_numeric($attributes['tenant_id'] ?? null)) { - $tenant = Tenant::query()->whereKey((int) $attributes['tenant_id'])->first(); + if (is_numeric($attributes['managed_environment_id'] ?? null)) { + $tenant = ManagedEnvironment::query()->whereKey((int) $attributes['managed_environment_id'])->first(); } $workspace = null; @@ -201,7 +201,7 @@ private function resolveActorSnapshot( private function resolveTargetSnapshot( ?AuditTargetSnapshot $target, ?Workspace $workspace, - ?Tenant $tenant, + ?ManagedEnvironment $tenant, array $metadata, ): AuditTargetSnapshot { $type = $target?->type; @@ -243,7 +243,7 @@ private function inferTargetIdentity(?string $type, int|string|null $id, array $ 'restore_run_id' => 'restore_run', 'operation_run_id' => 'operation_run', 'workspace_id' => 'workspace', - 'tenant_id' => 'tenant', + 'managed_environment_id' => 'tenant', 'alert_rule_id' => 'alert_rule', 'alert_destination_id' => 'alert_destination', ] as $key => $resolvedType) { @@ -310,7 +310,7 @@ private function resolveTargetLabel( ?string $type, int|string|null $id, ?Workspace $workspace, - ?Tenant $tenant, + ?ManagedEnvironment $tenant, ): ?string { if (! filled($type) && ! filled($id)) { return null; @@ -320,7 +320,7 @@ private function resolveTargetLabel( return $workspace->name; } - if ($type === 'tenant' && $tenant instanceof Tenant) { + if ($type === 'tenant' && $tenant instanceof ManagedEnvironment) { return $tenant->name; } diff --git a/apps/platform/app/Services/Audit/AuditRecorder.php b/apps/platform/app/Services/Audit/AuditRecorder.php index 91f76e66..804195d7 100644 --- a/apps/platform/app/Services/Audit/AuditRecorder.php +++ b/apps/platform/app/Services/Audit/AuditRecorder.php @@ -5,7 +5,7 @@ namespace App\Services\Audit; use App\Models\AuditLog; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Audit\AuditActionId; use App\Support\Audit\AuditActorSnapshot; @@ -26,7 +26,7 @@ public function record( string|AuditActionId $action, array $context = [], ?Workspace $workspace = null, - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?AuditActorSnapshot $actor = null, ?AuditTargetSnapshot $target = null, string|AuditOutcome|null $outcome = null, @@ -59,7 +59,7 @@ public function record( if ($dedupeKey !== null && $dedupeKey !== '') { $existing = AuditLog::query() - ->where('tenant_id', $attributes['tenant_id']) + ->where('managed_environment_id', $attributes['managed_environment_id']) ->where('action', $attributes['action']) ->where('resource_type', $attributes['resource_type']) ->where('resource_id', $attributes['resource_id']) diff --git a/apps/platform/app/Services/Audit/WorkspaceAuditLogger.php b/apps/platform/app/Services/Audit/WorkspaceAuditLogger.php index 7fa5b15a..2d58c9d9 100644 --- a/apps/platform/app/Services/Audit/WorkspaceAuditLogger.php +++ b/apps/platform/app/Services/Audit/WorkspaceAuditLogger.php @@ -8,7 +8,7 @@ use App\Models\PlatformUser; use App\Models\RestoreRun; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\Audit\AuditActionId; @@ -39,7 +39,7 @@ public function log( ?string $targetLabel = null, ?string $summary = null, ?int $operationRunId = null, - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ): \App\Models\AuditLog { $resolvedActor = match (true) { $actor instanceof User => AuditActorSnapshot::human($actor), @@ -74,7 +74,7 @@ public function log( * @param array $context */ public function logTenantLifecycleAction( - Tenant $tenant, + ManagedEnvironment $tenant, string|AuditActionId $action, array $context = [], User|PlatformUser|null $actor = null, @@ -99,7 +99,7 @@ public function logTenantLifecycleAction( * @param array $bundle */ public function logSupportDiagnosticsOpened( - Tenant $tenant, + ManagedEnvironment $tenant, string $contextType, array $bundle, User|PlatformUser|null $actor = null, @@ -145,8 +145,8 @@ public function logSupportDiagnosticsOpened( */ public function logCrossTenantPromotionPreflightGenerated( Workspace $workspace, - Tenant $sourceTenant, - Tenant $targetTenant, + ManagedEnvironment $sourceTenant, + ManagedEnvironment $targetTenant, array $preflight, User|PlatformUser|null $actor = null, ): \App\Models\AuditLog { @@ -182,8 +182,8 @@ public function logCrossTenantPromotionPreflightGenerated( */ public function logCrossTenantPromotionExecutionQueued( Workspace $workspace, - Tenant $sourceTenant, - Tenant $targetTenant, + ManagedEnvironment $sourceTenant, + ManagedEnvironment $targetTenant, OperationRun $operationRun, array $plan, User|PlatformUser|null $actor = null, @@ -221,7 +221,7 @@ public function logCrossTenantPromotionExecutionQueued( public function logCrossTenantPromotionExecutionCompleted( OperationRun $operationRun, ?int $sourceTenantId, - Tenant $targetTenant, + ManagedEnvironment $targetTenant, array $summaryCounts, ?RestoreRun $restoreRun = null, ): \App\Models\AuditLog { @@ -264,7 +264,7 @@ public function logSupportRequestCreated( $tenant = $supportRequest->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new InvalidArgumentException('Support requests must belong to a tenant.'); } @@ -341,7 +341,7 @@ private function logSupportRequestExternalHandoff( $tenant = $supportRequest->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new InvalidArgumentException('Support requests must belong to a tenant.'); } diff --git a/apps/platform/app/Services/Auth/BreakGlassSession.php b/apps/platform/app/Services/Auth/BreakGlassSession.php index 63dd88ad..dd212af5 100644 --- a/apps/platform/app/Services/Auth/BreakGlassSession.php +++ b/apps/platform/app/Services/Auth/BreakGlassSession.php @@ -5,7 +5,7 @@ namespace App\Services\Auth; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\AuditLogger; use Carbon\CarbonImmutable; use Illuminate\Contracts\Session\Session; @@ -155,9 +155,9 @@ private function expire(PlatformUser $user): void private function audit(PlatformUser $user, string $action, string $status, array $metadata): void { - $tenant = Tenant::query()->where('external_id', 'platform')->first(); + $tenant = ManagedEnvironment::query()->where('slug', 'platform')->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } diff --git a/apps/platform/app/Services/Auth/CapabilityResolver.php b/apps/platform/app/Services/Auth/CapabilityResolver.php index c6534a06..9b03f56d 100644 --- a/apps/platform/app/Services/Auth/CapabilityResolver.php +++ b/apps/platform/app/Services/Auth/CapabilityResolver.php @@ -2,8 +2,8 @@ namespace App\Services\Auth; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Support\Auth\Capabilities; use App\Support\TenantRole; @@ -24,7 +24,7 @@ class CapabilityResolver /** * Get the user's role for a tenant */ - public function getRole(User $user, Tenant $tenant): ?TenantRole + public function getRole(User $user, ManagedEnvironment $tenant): ?TenantRole { $membership = $this->getMembership($user, $tenant); @@ -38,7 +38,7 @@ public function getRole(User $user, Tenant $tenant): ?TenantRole /** * Check if user can perform a capability on a tenant */ - public function can(User $user, Tenant $tenant, string $capability): bool + public function can(User $user, ManagedEnvironment $tenant, string $capability): bool { if (! Capabilities::isKnown($capability)) { throw new \InvalidArgumentException("Unknown capability: {$capability}"); @@ -67,7 +67,7 @@ public function can(User $user, Tenant $tenant, string $capability): bool return $allowed; } - private function isLocallyDeniedByBackupHealthBrowserFixture(User $user, Tenant $tenant, string $capability): bool + private function isLocallyDeniedByBackupHealthBrowserFixture(User $user, ManagedEnvironment $tenant, string $capability): bool { if (! app()->environment(['local', 'testing'])) { return false; @@ -100,7 +100,7 @@ private function isLocallyDeniedByBackupHealthBrowserFixture(User $user, Tenant return in_array($capability, $deniedCapabilities, true); } - private function logDenial(User $user, Tenant $tenant, string $capability): void + private function logDenial(User $user, ManagedEnvironment $tenant, string $capability): void { $key = implode(':', [(string) $user->getKey(), (string) $tenant->getKey(), $capability]); @@ -112,7 +112,7 @@ private function logDenial(User $user, Tenant $tenant, string $capability): void Log::warning('rbac.denied', [ 'capability' => $capability, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $user->getKey(), ]); } @@ -120,7 +120,7 @@ private function logDenial(User $user, Tenant $tenant, string $capability): void /** * Check if user has any membership for a tenant */ - public function isMember(User $user, Tenant $tenant): bool + public function isMember(User $user, ManagedEnvironment $tenant): bool { return $this->getMembership($user, $tenant) !== null; } @@ -128,14 +128,14 @@ public function isMember(User $user, Tenant $tenant): bool /** * Get membership details (cached per request) */ - private function getMembership(User $user, Tenant $tenant): ?array + private function getMembership(User $user, ManagedEnvironment $tenant): ?array { $cacheKey = "membership_{$user->id}_{$tenant->id}"; if (! array_key_exists($cacheKey, $this->resolvedMemberships)) { - $membership = TenantMembership::query() + $membership = ManagedEnvironmentMembership::query() ->where('user_id', $user->id) - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->first(['role', 'source', 'source_ref']); $this->resolvedMemberships[$cacheKey] = $membership?->toArray(); @@ -161,12 +161,12 @@ public function primeMemberships(User $user, array $tenantIds): void return; } - $memberships = TenantMembership::query() + $memberships = ManagedEnvironmentMembership::query() ->where('user_id', $user->id) - ->whereIn('tenant_id', $tenantIds) - ->get(['tenant_id', 'role', 'source', 'source_ref']); + ->whereIn('managed_environment_id', $tenantIds) + ->get(['managed_environment_id', 'role', 'source', 'source_ref']); - $byTenantId = $memberships->keyBy('tenant_id'); + $byTenantId = $memberships->keyBy('managed_environment_id'); foreach ($tenantIds as $tenantId) { $cacheKey = "membership_{$user->id}_{$tenantId}"; diff --git a/apps/platform/app/Services/Auth/TenantDiagnosticsService.php b/apps/platform/app/Services/Auth/TenantDiagnosticsService.php index db8b2707..4130c7a8 100644 --- a/apps/platform/app/Services/Auth/TenantDiagnosticsService.php +++ b/apps/platform/app/Services/Auth/TenantDiagnosticsService.php @@ -4,8 +4,8 @@ namespace App\Services\Auth; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Services\Intune\AuditLogger; use App\Support\Audit\AuditActionId; @@ -15,27 +15,27 @@ class TenantDiagnosticsService { public function __construct(public AuditLogger $auditLogger) {} - public function tenantHasNoOwners(Tenant $tenant): bool + public function tenantHasNoOwners(ManagedEnvironment $tenant): bool { - return ! TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + return ! ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('role', 'owner') ->exists(); } - public function userHasDuplicateMemberships(Tenant $tenant, User $user): bool + public function userHasDuplicateMemberships(ManagedEnvironment $tenant, User $user): bool { - return TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + return ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $user->getKey()) ->count() > 1; } - public function mergeDuplicateMembershipsForUser(Tenant $tenant, User $actor, User $member): void + public function mergeDuplicateMembershipsForUser(ManagedEnvironment $tenant, User $actor, User $member): void { DB::transaction(function () use ($tenant, $actor, $member): void { - $memberships = TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + $memberships = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $member->getKey()) ->orderBy('created_at') ->get(); @@ -48,12 +48,12 @@ public function mergeDuplicateMembershipsForUser(Tenant $tenant, User $actor, Us $roleToKeep = $this->highestRole($roles); $membershipToKeep = $memberships->firstWhere('role', $roleToKeep) ?? $memberships->first(); - if (! $membershipToKeep instanceof TenantMembership) { + if (! $membershipToKeep instanceof ManagedEnvironmentMembership) { return; } $idsToDelete = $memberships - ->reject(fn (TenantMembership $m): bool => $m->getKey() === $membershipToKeep->getKey()) + ->reject(fn (ManagedEnvironmentMembership $m): bool => $m->getKey() === $membershipToKeep->getKey()) ->pluck($membershipToKeep->getKeyName()) ->all(); @@ -61,7 +61,7 @@ public function mergeDuplicateMembershipsForUser(Tenant $tenant, User $actor, Us 'role' => $roleToKeep, ])->save(); - TenantMembership::query() + ManagedEnvironmentMembership::query() ->whereIn($membershipToKeep->getKeyName(), $idsToDelete) ->delete(); diff --git a/apps/platform/app/Services/Auth/TenantMembershipManager.php b/apps/platform/app/Services/Auth/TenantMembershipManager.php index dd4366fc..9d2d4b84 100644 --- a/apps/platform/app/Services/Auth/TenantMembershipManager.php +++ b/apps/platform/app/Services/Auth/TenantMembershipManager.php @@ -2,8 +2,8 @@ namespace App\Services\Auth; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Services\Intune\AuditLogger; use App\Support\Audit\AuditActionId; @@ -15,18 +15,18 @@ class TenantMembershipManager public function __construct(public AuditLogger $auditLogger) {} public function addMember( - Tenant $tenant, + ManagedEnvironment $tenant, User $actor, User $member, string $role, string $source = 'manual', ?string $sourceRef = null, - ): TenantMembership { + ): ManagedEnvironmentMembership { $this->assertValidRole($role); - return DB::transaction(function () use ($tenant, $actor, $member, $role, $source, $sourceRef): TenantMembership { - $existing = TenantMembership::query() - ->where('tenant_id', $tenant->getKey()) + return DB::transaction(function () use ($tenant, $actor, $member, $role, $source, $sourceRef): ManagedEnvironmentMembership { + $existing = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', $tenant->getKey()) ->where('user_id', $member->getKey()) ->first(); @@ -62,8 +62,8 @@ public function addMember( return $existing->refresh(); } - $membership = TenantMembership::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + $membership = ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $member->getKey(), 'role' => $role, 'source' => $source, @@ -93,15 +93,15 @@ public function addMember( }); } - public function changeRole(Tenant $tenant, User $actor, TenantMembership $membership, string $newRole): TenantMembership + public function changeRole(ManagedEnvironment $tenant, User $actor, ManagedEnvironmentMembership $membership, string $newRole): ManagedEnvironmentMembership { $this->assertValidRole($newRole); try { - return DB::transaction(function () use ($tenant, $actor, $membership, $newRole): TenantMembership { + return DB::transaction(function () use ($tenant, $actor, $membership, $newRole): ManagedEnvironmentMembership { $membership->refresh(); - if ($membership->tenant_id !== (int) $tenant->getKey()) { + if ($membership->managed_environment_id !== (int) $tenant->getKey()) { throw new DomainException('Membership belongs to a different tenant.'); } @@ -162,13 +162,13 @@ public function changeRole(Tenant $tenant, User $actor, TenantMembership $member } } - public function removeMember(Tenant $tenant, User $actor, TenantMembership $membership): void + public function removeMember(ManagedEnvironment $tenant, User $actor, ManagedEnvironmentMembership $membership): void { try { DB::transaction(function () use ($tenant, $actor, $membership): void { $membership->refresh(); - if ($membership->tenant_id !== (int) $tenant->getKey()) { + if ($membership->managed_environment_id !== (int) $tenant->getKey()) { throw new DomainException('Membership belongs to a different tenant.'); } @@ -221,7 +221,7 @@ public function removeMember(Tenant $tenant, User $actor, TenantMembership $memb } } - public function bootstrapRecover(Tenant $tenant, User $actor, User $member): TenantMembership + public function bootstrapRecover(ManagedEnvironment $tenant, User $actor, User $member): ManagedEnvironmentMembership { $membership = $this->addMember( tenant: $tenant, @@ -250,14 +250,14 @@ public function bootstrapRecover(Tenant $tenant, User $actor, User $member): Ten return $membership; } - private function guardLastOwnerRemoval(Tenant $tenant, TenantMembership $membership): void + private function guardLastOwnerRemoval(ManagedEnvironment $tenant, ManagedEnvironmentMembership $membership): void { if ($membership->role !== 'owner') { return; } - $owners = TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + $owners = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('role', 'owner') ->count(); @@ -266,7 +266,7 @@ private function guardLastOwnerRemoval(Tenant $tenant, TenantMembership $members } } - private function guardLastOwnerDemotion(Tenant $tenant, TenantMembership $membership, string $newRole): void + private function guardLastOwnerDemotion(ManagedEnvironment $tenant, ManagedEnvironmentMembership $membership, string $newRole): void { if ($membership->role !== 'owner') { return; @@ -276,8 +276,8 @@ private function guardLastOwnerDemotion(Tenant $tenant, TenantMembership $member return; } - $owners = TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + $owners = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('role', 'owner') ->count(); diff --git a/apps/platform/app/Services/BackupScheduling/BackupScheduleDispatcher.php b/apps/platform/app/Services/BackupScheduling/BackupScheduleDispatcher.php index ee158b4d..cc2de825 100644 --- a/apps/platform/app/Services/BackupScheduling/BackupScheduleDispatcher.php +++ b/apps/platform/app/Services/BackupScheduling/BackupScheduleDispatcher.php @@ -4,7 +4,7 @@ use App\Jobs\RunBackupScheduleJob; use App\Models\BackupSchedule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\AuditLogger; use App\Services\OperationRunService; use App\Support\OperationRunType; @@ -34,11 +34,11 @@ public function dispatchDue(?array $tenantIdentifiers = null): array $schedulesQuery = BackupSchedule::query() ->withoutTrashed() ->where('is_enabled', true) - ->whereHas('tenant', fn ($query) => $query->where('status', 'active')) + ->whereHas('tenant', fn ($query) => $query->where('lifecycle_status', ManagedEnvironment::STATUS_ACTIVE)) ->with('tenant'); if (is_array($tenantIdentifiers) && ! empty($tenantIdentifiers)) { - $schedulesQuery->whereIn('tenant_id', $this->resolveTenantIds($tenantIdentifiers)); + $schedulesQuery->whereIn('managed_environment_id', $this->resolveTenantIds($tenantIdentifiers)); } $createdRuns = 0; @@ -136,8 +136,8 @@ private function resolveTenantIds(array $tenantIdentifiers): array $tenantIds = []; foreach ($tenantIdentifiers as $identifier) { - $tenant = Tenant::query() - ->where('status', 'active') + $tenant = ManagedEnvironment::query() + ->where('lifecycle_status', ManagedEnvironment::STATUS_ACTIVE) ->forTenant($identifier) ->first(); diff --git a/apps/platform/app/Services/Baselines/BaselineAutoCloseService.php b/apps/platform/app/Services/Baselines/BaselineAutoCloseService.php index 987e7fb9..299bf594 100644 --- a/apps/platform/app/Services/Baselines/BaselineAutoCloseService.php +++ b/apps/platform/app/Services/Baselines/BaselineAutoCloseService.php @@ -6,7 +6,7 @@ use App\Models\Finding; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Services\Findings\FindingWorkflowService; use App\Services\Settings\SettingsResolver; @@ -21,7 +21,7 @@ public function __construct( private readonly ?FindingWorkflowService $findingWorkflowService = null, ) {} - public function shouldAutoClose(Tenant $tenant, OperationRun $run): bool + public function shouldAutoClose(ManagedEnvironment $tenant, OperationRun $run): bool { if ($run->status !== OperationRunStatus::Completed->value) { return false; @@ -70,7 +70,7 @@ public function shouldAutoClose(Tenant $tenant, OperationRun $run): bool * @param array $seenFingerprints */ public function resolveStaleFindings( - Tenant $tenant, + ManagedEnvironment $tenant, int $baselineProfileId, array $seenFingerprints, int $currentOperationRunId, @@ -80,7 +80,7 @@ public function resolveStaleFindings( $resolvedCount = 0; $query = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) @@ -115,7 +115,7 @@ public function resolveStaleFindings( return $resolvedCount; } - private function resolveWorkspace(Tenant $tenant): ?Workspace + private function resolveWorkspace(ManagedEnvironment $tenant): ?Workspace { $workspaceId = (int) ($tenant->workspace_id ?? 0); diff --git a/apps/platform/app/Services/Baselines/BaselineCaptureService.php b/apps/platform/app/Services/Baselines/BaselineCaptureService.php index a50b3f84..a0d1cfe9 100644 --- a/apps/platform/app/Services/Baselines/BaselineCaptureService.php +++ b/apps/platform/app/Services/Baselines/BaselineCaptureService.php @@ -7,7 +7,7 @@ use App\Jobs\CaptureBaselineSnapshotJob; use App\Models\BaselineProfile; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Support\Baselines\BaselineCaptureMode; @@ -35,7 +35,7 @@ public function __construct( */ public function startCapture( BaselineProfile $profile, - Tenant $sourceTenant, + ManagedEnvironment $sourceTenant, User $initiator, ): array { $precondition = $this->validatePreconditions($profile, $sourceTenant); @@ -117,7 +117,7 @@ public function startCapture( return ['ok' => true, 'run' => $run]; } - private function validatePreconditions(BaselineProfile $profile, Tenant $sourceTenant): ?string + private function validatePreconditions(BaselineProfile $profile, ManagedEnvironment $sourceTenant): ?string { if ($profile->status !== BaselineProfileStatus::Active) { return BaselineReasonCodes::CAPTURE_PROFILE_NOT_ACTIVE; @@ -151,7 +151,7 @@ private function validatePreconditions(BaselineProfile $profile, Tenant $sourceT * } */ public function latestInventoryEligibilityDecision( - Tenant $sourceTenant, + ManagedEnvironment $sourceTenant, BaselineScope $effectiveScope, ?array $truthfulTypes = null, ): array { @@ -162,7 +162,7 @@ public function latestInventoryEligibilityDecision( sort($effectiveTypes, SORT_STRING); $run = OperationRun::query() - ->where('tenant_id', (int) $sourceTenant->getKey()) + ->where('managed_environment_id', (int) $sourceTenant->getKey()) ->where('type', OperationRunType::InventorySync->value) ->where('status', OperationRunStatus::Completed->value) ->orderByDesc('completed_at') diff --git a/apps/platform/app/Services/Baselines/BaselineCompareService.php b/apps/platform/app/Services/Baselines/BaselineCompareService.php index e14f7543..a958413d 100644 --- a/apps/platform/app/Services/Baselines/BaselineCompareService.php +++ b/apps/platform/app/Services/Baselines/BaselineCompareService.php @@ -9,7 +9,7 @@ use App\Models\BaselineSnapshot; use App\Models\BaselineTenantAssignment; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\OperationRunService; @@ -41,13 +41,13 @@ public function __construct( * @return array{ok: bool, run?: OperationRun, reason_code?: string, reason_translation?: array} */ public function startCompare( - Tenant $tenant, + ManagedEnvironment $tenant, User $initiator, ?int $baselineSnapshotId = null, ): array { $assignment = BaselineTenantAssignment::query() ->where('workspace_id', $tenant->workspace_id) - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->first(); if (! $assignment instanceof BaselineTenantAssignment) { @@ -68,13 +68,13 @@ public function startCompare( */ public function startCompareForProfile( BaselineProfile $profile, - Tenant $tenant, + ManagedEnvironment $tenant, User $initiator, ?int $baselineSnapshotId = null, ): array { $assignment = BaselineTenantAssignment::query() ->where('workspace_id', (int) $profile->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('baseline_profile_id', (int) $profile->getKey()) ->first(); @@ -202,7 +202,7 @@ public function startCompareForVisibleAssignments(BaselineProfile $profile, User foreach ($assignments as $assignment) { $tenant = $assignment->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { continue; } diff --git a/apps/platform/app/Services/Baselines/BaselineContentCapturePhase.php b/apps/platform/app/Services/Baselines/BaselineContentCapturePhase.php index a925e02c..0d1658f8 100644 --- a/apps/platform/app/Services/Baselines/BaselineContentCapturePhase.php +++ b/apps/platform/app/Services/Baselines/BaselineContentCapturePhase.php @@ -6,7 +6,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\PolicyCaptureOrchestrator; use App\Support\Baselines\BaselineEvidenceResumeToken; use App\Support\Baselines\PolicyVersionCapturePurpose; @@ -43,7 +43,7 @@ public function __construct( * } */ public function capture( - Tenant $tenant, + ManagedEnvironment $tenant, array $subjects, PolicyVersionCapturePurpose $purpose, array $budgets, @@ -131,7 +131,7 @@ public function capture( } $policy = Policy::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('policy_type', $policyType) ->where('external_id', $externalId) ->first(); diff --git a/apps/platform/app/Services/Baselines/BaselineEvidenceCaptureResumeService.php b/apps/platform/app/Services/Baselines/BaselineEvidenceCaptureResumeService.php index 1bf95509..a3eb45b2 100644 --- a/apps/platform/app/Services/Baselines/BaselineEvidenceCaptureResumeService.php +++ b/apps/platform/app/Services/Baselines/BaselineEvidenceCaptureResumeService.php @@ -7,7 +7,7 @@ use App\Jobs\CaptureBaselineSnapshotJob; use App\Jobs\CompareBaselineToTenantJob; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\WorkspaceCapabilityResolver; @@ -44,15 +44,15 @@ public function resume(OperationRun $priorRun, User $initiator): array return ['ok' => false, 'reason_code' => 'baseline.resume.run_not_completed']; } - $tenantId = (int) ($priorRun->tenant_id ?? 0); + $tenantId = (int) ($priorRun->managed_environment_id ?? 0); if ($tenantId <= 0) { return ['ok' => false, 'reason_code' => 'baseline.resume.missing_tenant']; } - $tenant = Tenant::query()->whereKey($tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey($tenantId)->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return ['ok' => false, 'reason_code' => 'baseline.resume.tenant_not_found']; } diff --git a/apps/platform/app/Services/Baselines/CurrentStateEvidenceProvider.php b/apps/platform/app/Services/Baselines/CurrentStateEvidenceProvider.php index 13677088..15ad010b 100644 --- a/apps/platform/app/Services/Baselines/CurrentStateEvidenceProvider.php +++ b/apps/platform/app/Services/Baselines/CurrentStateEvidenceProvider.php @@ -4,7 +4,7 @@ namespace App\Services\Baselines; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\Evidence\ResolvedEvidence; use Carbon\CarbonImmutable; @@ -17,7 +17,7 @@ public function name(): string; * @return array keyed by "policy_type|subject_external_id" */ public function resolve( - Tenant $tenant, + ManagedEnvironment $tenant, array $subjects, ?CarbonImmutable $since = null, ?int $latestInventorySyncRunId = null, diff --git a/apps/platform/app/Services/Baselines/CurrentStateHashResolver.php b/apps/platform/app/Services/Baselines/CurrentStateHashResolver.php index 584dda1d..dfca7036 100644 --- a/apps/platform/app/Services/Baselines/CurrentStateHashResolver.php +++ b/apps/platform/app/Services/Baselines/CurrentStateHashResolver.php @@ -4,7 +4,7 @@ namespace App\Services\Baselines; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\Evidence\ContentEvidenceProvider; use App\Services\Baselines\Evidence\MetaEvidenceProvider; use App\Services\Baselines\Evidence\ResolvedEvidence; @@ -36,7 +36,7 @@ public function __construct( * @return array keyed by "policy_type|subject_external_id" */ public function resolveForSubjects( - Tenant $tenant, + ManagedEnvironment $tenant, array $subjects, ?CarbonImmutable $since = null, ?int $latestInventorySyncRunId = null, diff --git a/apps/platform/app/Services/Baselines/Evidence/BaselinePolicyVersionResolver.php b/apps/platform/app/Services/Baselines/Evidence/BaselinePolicyVersionResolver.php index b40cb129..dd186bf2 100644 --- a/apps/platform/app/Services/Baselines/Evidence/BaselinePolicyVersionResolver.php +++ b/apps/platform/app/Services/Baselines/Evidence/BaselinePolicyVersionResolver.php @@ -6,7 +6,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Baselines\BaselineSubjectKey; use Carbon\CarbonImmutable; use Throwable; @@ -14,14 +14,14 @@ final class BaselinePolicyVersionResolver { /** - * Cached map of (tenant_id, policy_type) => subject_key => policy_id. + * Cached map of (managed_environment_id, policy_type) => subject_key => policy_id. * * @var array>> */ private array $policyIdIndex = []; public function resolve( - Tenant $tenant, + ManagedEnvironment $tenant, string $policyType, string $subjectKey, ?string $observedAt, @@ -51,7 +51,7 @@ public function resolve( $rangeEnd = $observedAtCarbon->addSecond(); $versionId = PolicyVersion::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('policy_id', $policyId) ->whereNull('deleted_at') ->where('captured_at', '>=', $rangeStart) @@ -104,7 +104,7 @@ private function resolvePolicyId(int $tenantId, string $policyType, string $subj private function buildIndex(int $tenantId, string $policyType): array { $policies = Policy::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('policy_type', $policyType) ->get(['id', 'display_name', 'external_id']); diff --git a/apps/platform/app/Services/Baselines/Evidence/ContentEvidenceProvider.php b/apps/platform/app/Services/Baselines/Evidence/ContentEvidenceProvider.php index a56af626..b5947e12 100644 --- a/apps/platform/app/Services/Baselines/Evidence/ContentEvidenceProvider.php +++ b/apps/platform/app/Services/Baselines/Evidence/ContentEvidenceProvider.php @@ -6,7 +6,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\CurrentStateEvidenceProvider; use App\Services\Drift\DriftHasher; use App\Services\Drift\Normalizers\AssignmentsNormalizer; @@ -54,7 +54,7 @@ public function fromPolicyVersion( ); } - public function resolve(Tenant $tenant, array $subjects, ?CarbonImmutable $since = null, ?int $latestInventorySyncRunId = null): array + public function resolve(ManagedEnvironment $tenant, array $subjects, ?CarbonImmutable $since = null, ?int $latestInventorySyncRunId = null): array { if ($subjects === []) { return []; @@ -83,7 +83,7 @@ public function resolve(Tenant $tenant, array $subjects, ?CarbonImmutable $since } $policies = Policy::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereIn('policy_type', $policyTypes) ->whereIn('external_id', $externalIds) ->get(['id', 'policy_type', 'external_id']); @@ -128,7 +128,7 @@ public function resolve(Tenant $tenant, array $subjects, ?CarbonImmutable $since 'policy_versions.version_number', ]) ->selectRaw('ROW_NUMBER() OVER (PARTITION BY policy_id ORDER BY captured_at DESC, version_number DESC, id DESC) as rn') - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereIn('policy_id', $policyIds) ->whereNull('deleted_at'); diff --git a/apps/platform/app/Services/Baselines/Evidence/MetaEvidenceProvider.php b/apps/platform/app/Services/Baselines/Evidence/MetaEvidenceProvider.php index 09ef0729..dabf5c56 100644 --- a/apps/platform/app/Services/Baselines/Evidence/MetaEvidenceProvider.php +++ b/apps/platform/app/Services/Baselines/Evidence/MetaEvidenceProvider.php @@ -5,7 +5,7 @@ namespace App\Services\Baselines\Evidence; use App\Models\InventoryItem; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\BaselineSnapshotIdentity; use App\Services\Baselines\CurrentStateEvidenceProvider; use Carbon\CarbonImmutable; @@ -22,7 +22,7 @@ public function name(): string return 'inventory'; } - public function resolve(Tenant $tenant, array $subjects, ?CarbonImmutable $since = null, ?int $latestInventorySyncRunId = null): array + public function resolve(ManagedEnvironment $tenant, array $subjects, ?CarbonImmutable $since = null, ?int $latestInventorySyncRunId = null): array { if ($subjects === []) { return []; @@ -51,7 +51,7 @@ public function resolve(Tenant $tenant, array $subjects, ?CarbonImmutable $since } $query = InventoryItem::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereIn('policy_type', $policyTypes) ->whereIn('external_id', $externalIds); diff --git a/apps/platform/app/Services/Baselines/Evidence/ResolvedEvidence.php b/apps/platform/app/Services/Baselines/Evidence/ResolvedEvidence.php index 9f573838..c999bdc1 100644 --- a/apps/platform/app/Services/Baselines/Evidence/ResolvedEvidence.php +++ b/apps/platform/app/Services/Baselines/Evidence/ResolvedEvidence.php @@ -46,7 +46,7 @@ public function provenance(): array } /** - * Tenant-scoped provenance including additional metadata (e.g. policy_version_id). + * ManagedEnvironment-scoped provenance including additional metadata (e.g. policy_version_id). * * Do NOT use this for workspace-owned baseline snapshot items. * diff --git a/apps/platform/app/Services/Directory/EntraGroupLabelResolver.php b/apps/platform/app/Services/Directory/EntraGroupLabelResolver.php index f694bb2d..603a459a 100644 --- a/apps/platform/app/Services/Directory/EntraGroupLabelResolver.php +++ b/apps/platform/app/Services/Directory/EntraGroupLabelResolver.php @@ -3,12 +3,12 @@ namespace App\Services\Directory; use App\Models\EntraGroup; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Support\Str; class EntraGroupLabelResolver { - public function lookupOne(Tenant $tenant, string $groupId): ?string + public function lookupOne(ManagedEnvironment $tenant, string $groupId): ?string { $labels = $this->lookupMany($tenant, [$groupId]); $lookupId = Str::isUuid($groupId) ? strtolower($groupId) : $groupId; @@ -16,7 +16,7 @@ public function lookupOne(Tenant $tenant, string $groupId): ?string return $labels[$lookupId] ?? null; } - public function resolveOne(Tenant $tenant, string $groupId): string + public function resolveOne(ManagedEnvironment $tenant, string $groupId): string { $labels = $this->resolveMany($tenant, [$groupId]); @@ -27,7 +27,7 @@ public function resolveOne(Tenant $tenant, string $groupId): string * @param array $groupIds * @return array */ - public function resolveMany(Tenant $tenant, array $groupIds): array + public function resolveMany(ManagedEnvironment $tenant, array $groupIds): array { $groupIds = array_values(array_unique(array_filter($groupIds, fn ($id) => is_string($id) && $id !== ''))); @@ -52,7 +52,7 @@ public function resolveMany(Tenant $tenant, array $groupIds): array * @param array $fallbackLabels * @return array */ - public function describeMany(Tenant $tenant, array $groupIds, array $fallbackLabels = []): array + public function describeMany(ManagedEnvironment $tenant, array $groupIds, array $fallbackLabels = []): array { $groupIds = array_values(array_unique(array_filter($groupIds, fn ($id) => is_string($id) && $id !== ''))); @@ -80,7 +80,7 @@ public function describeMany(Tenant $tenant, array $groupIds, array $fallbackLab * @param array $groupIds * @return array Map of groupId (lowercased UUID) => display_name */ - public function lookupMany(Tenant $tenant, array $groupIds): array + public function lookupMany(ManagedEnvironment $tenant, array $groupIds): array { $uuids = []; @@ -103,7 +103,7 @@ public function lookupMany(Tenant $tenant, array $groupIds): array } return EntraGroup::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereIn('entra_id', $uuids) ->pluck('display_name', 'entra_id') ->mapWithKeys(fn (string $displayName, string $entraId) => [strtolower($entraId) => $displayName]) diff --git a/apps/platform/app/Services/Directory/EntraGroupSyncService.php b/apps/platform/app/Services/Directory/EntraGroupSyncService.php index 1033344b..7b50db7d 100644 --- a/apps/platform/app/Services/Directory/EntraGroupSyncService.php +++ b/apps/platform/app/Services/Directory/EntraGroupSyncService.php @@ -5,7 +5,7 @@ use App\Jobs\EntraGroupSyncJob; use App\Models\EntraGroup; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphContractRegistry; @@ -26,7 +26,7 @@ public function __construct( private readonly ProviderOperationStartGate $providerStarts, ) {} - public function startManualSync(Tenant $tenant, User $user): ProviderOperationStartResult + public function startManualSync(ManagedEnvironment $tenant, User $user): ProviderOperationStartResult { $selectionKey = EntraGroupSelection::allGroupsV1(); @@ -70,7 +70,7 @@ public function startManualSync(Tenant $tenant, User $user): ProviderOperationSt * error_summary:?string * } */ - public function sync(Tenant $tenant, string $selectionKey, ?int $providerConnectionId = null): array + public function sync(ManagedEnvironment $tenant, string $selectionKey, ?int $providerConnectionId = null): array { $nowUtc = CarbonImmutable::now('UTC'); @@ -167,7 +167,7 @@ public function sync(Tenant $tenant, string $selectionKey, ?int $providerConnect ]; EntraGroup::query()->updateOrCreate([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'entra_id' => $entraId, ], $values); @@ -191,7 +191,7 @@ public function sync(Tenant $tenant, string $selectionKey, ?int $providerConnect $cutoff = $nowUtc->subDays($retentionDays); EntraGroup::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereNotNull('last_seen_at') ->where('last_seen_at', '<', $cutoff) ->delete(); diff --git a/apps/platform/app/Services/Directory/RoleDefinitionsSyncService.php b/apps/platform/app/Services/Directory/RoleDefinitionsSyncService.php index 2499d461..77912f44 100644 --- a/apps/platform/app/Services/Directory/RoleDefinitionsSyncService.php +++ b/apps/platform/app/Services/Directory/RoleDefinitionsSyncService.php @@ -5,7 +5,7 @@ use App\Jobs\SyncRoleDefinitionsJob; use App\Models\EntraRoleDefinition; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphContractRegistry; @@ -26,7 +26,7 @@ public function __construct( private readonly ProviderOperationStartGate $providerStarts, ) {} - public function startManualSync(Tenant $tenant, User $user): ProviderOperationStartResult + public function startManualSync(ManagedEnvironment $tenant, User $user): ProviderOperationStartResult { $selectionKey = 'role_definitions_v1'; @@ -67,7 +67,7 @@ public function startManualSync(Tenant $tenant, User $user): ProviderOperationSt * error_summary:?string * } */ - public function sync(Tenant $tenant, ?int $providerConnectionId = null): array + public function sync(ManagedEnvironment $tenant, ?int $providerConnectionId = null): array { $nowUtc = CarbonImmutable::now('UTC'); @@ -159,7 +159,7 @@ public function sync(Tenant $tenant, ?int $providerConnectionId = null): array ]; EntraRoleDefinition::query()->updateOrCreate([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'entra_id' => $entraId, ], $values); @@ -183,7 +183,7 @@ public function sync(Tenant $tenant, ?int $providerConnectionId = null): array $cutoff = $nowUtc->subDays($retentionDays); EntraRoleDefinition::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereNotNull('last_seen_at') ->where('last_seen_at', '<', $cutoff) ->delete(); diff --git a/apps/platform/app/Services/Drift/DriftFindingDiffBuilder.php b/apps/platform/app/Services/Drift/DriftFindingDiffBuilder.php index 73f4d638..5d724a66 100644 --- a/apps/platform/app/Services/Drift/DriftFindingDiffBuilder.php +++ b/apps/platform/app/Services/Drift/DriftFindingDiffBuilder.php @@ -3,7 +3,7 @@ namespace App\Services\Drift; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Directory\EntraGroupLabelResolver; use App\Services\Drift\Normalizers\AssignmentsNormalizer; use App\Services\Drift\Normalizers\ScopeTagsNormalizer; @@ -74,7 +74,7 @@ public function buildSettingsDiff(?PolicyVersion $baselineVersion, ?PolicyVersio /** * @return array */ - public function buildAssignmentsDiff(Tenant $tenant, ?PolicyVersion $baselineVersion, ?PolicyVersion $currentVersion, int $limit = 200): array + public function buildAssignmentsDiff(ManagedEnvironment $tenant, ?PolicyVersion $baselineVersion, ?PolicyVersion $currentVersion, int $limit = 200): array { $baseline = $baselineVersion ? $this->assignmentsNormalizer->normalizeForDiff($baselineVersion->assignments) : []; $current = $currentVersion ? $this->assignmentsNormalizer->normalizeForDiff($currentVersion->assignments) : []; @@ -317,7 +317,7 @@ private function fingerprintBucket(?PolicyVersion $version, string $bucket): arr * @param array> $changed * @return array */ - private function groupDescriptionsForDiff(Tenant $tenant, array $added, array $removed, array $changed): array + private function groupDescriptionsForDiff(ManagedEnvironment $tenant, array $added, array $removed, array $changed): array { $groupIds = []; @@ -367,14 +367,14 @@ private function groupDescriptionsForDiff(Tenant $tenant, array $added, array $r * @param array $groupDescriptions * @return array */ - private function targetReference(Tenant $tenant, array $assignment, array $groupDescriptions): array + private function targetReference(ManagedEnvironment $tenant, array $assignment, array $groupDescriptions): array { $targetType = is_string($assignment['target_type'] ?? null) ? (string) $assignment['target_type'] : ''; $targetId = is_string($assignment['target_id'] ?? null) ? (string) $assignment['target_id'] : ''; return $this->resolvedReferencePresenter->present( $this->assignmentTargetReferenceResolver->resolve([], [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'target_type' => $targetType, 'target_id' => $targetId, 'group_descriptions' => $groupDescriptions, diff --git a/apps/platform/app/Services/Entitlements/WorkspaceCommercialLifecycleResolver.php b/apps/platform/app/Services/Entitlements/WorkspaceCommercialLifecycleResolver.php index 711d7227..e28665ae 100644 --- a/apps/platform/app/Services/Entitlements/WorkspaceCommercialLifecycleResolver.php +++ b/apps/platform/app/Services/Entitlements/WorkspaceCommercialLifecycleResolver.php @@ -5,7 +5,7 @@ namespace App\Services\Entitlements; use App\Models\AuditLog; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Models\WorkspaceSetting; use App\Support\Audit\AuditActionId; @@ -188,7 +188,7 @@ public function actionDecision(Workspace $workspace, string $actionKey, ?array $ /** * @return array */ - public function reviewPackStartDecisionForTenant(Tenant $tenant): array + public function reviewPackStartDecisionForTenant(ManagedEnvironment $tenant): array { $tenant->loadMissing('workspace'); diff --git a/apps/platform/app/Services/Entitlements/WorkspaceEntitlementResolver.php b/apps/platform/app/Services/Entitlements/WorkspaceEntitlementResolver.php index 05f4bcc9..c74078fa 100644 --- a/apps/platform/app/Services/Entitlements/WorkspaceEntitlementResolver.php +++ b/apps/platform/app/Services/Entitlements/WorkspaceEntitlementResolver.php @@ -4,7 +4,7 @@ namespace App\Services\Entitlements; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Models\WorkspaceSetting; use App\Services\Settings\SettingsResolver; @@ -154,7 +154,7 @@ private function resolveManagedTenantActivationLimitDecision(Workspace $workspac ? 'workspace_override' : 'plan_profile_default'; - $currentUsage = Tenant::activeQuery() + $currentUsage = ManagedEnvironment::activeQuery() ->where('workspace_id', (int) $workspace->getKey()) ->count(); diff --git a/apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesFindingGenerator.php b/apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesFindingGenerator.php index 733e4f68..820cbcdc 100644 --- a/apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesFindingGenerator.php +++ b/apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesFindingGenerator.php @@ -7,7 +7,7 @@ use App\Models\AlertRule; use App\Models\Finding; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Findings\FindingSlaPolicy; use App\Services\Findings\FindingWorkflowService; use Carbon\CarbonImmutable; @@ -29,7 +29,7 @@ public function __construct( * Generate/upsert/auto-resolve findings based on report payload data. */ public function generate( - Tenant $tenant, + ManagedEnvironment $tenant, array $reportPayload, ?OperationRun $operationRun = null, ): EntraAdminRolesFindingResult { @@ -145,7 +145,7 @@ private function buildRoleDefMap(array $roleDefinitions): array } private function upsertFinding( - Tenant $tenant, + ManagedEnvironment $tenant, string $fingerprint, string $severity, array $evidence, @@ -157,7 +157,7 @@ private function upsertFinding( $slaPolicy = $this->resolveSlaPolicy(); $existing = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->where('fingerprint', $fingerprint) ->first(); @@ -197,7 +197,7 @@ private function upsertFinding( $slaDays = $slaPolicy->daysForSeverity($severity, $tenant); Finding::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES, 'source' => 'entra.admin_roles', 'scope_key' => hash('sha256', 'entra_admin_roles:'.$tenant->getKey()), @@ -224,7 +224,7 @@ private function upsertFinding( * @return int Number of resolved findings (0 or 1) */ private function handleGaAggregate( - Tenant $tenant, + ManagedEnvironment $tenant, int $gaCount, array $gaPrincipals, array &$currentFingerprints, @@ -247,7 +247,7 @@ private function handleGaAggregate( ]; $existing = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->where('fingerprint', $gaFingerprint) ->first(); @@ -286,7 +286,7 @@ private function handleGaAggregate( $slaDays = $slaPolicy->daysForSeverity(Finding::SEVERITY_HIGH, $tenant); Finding::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES, 'source' => 'entra.admin_roles', 'scope_key' => hash('sha256', 'entra_admin_roles_ga_count:'.$tenant->getKey()), @@ -309,7 +309,7 @@ private function handleGaAggregate( } else { // Auto-resolve aggregate if threshold met $existing = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->where('fingerprint', $gaFingerprint) ->whereIn('status', Finding::openStatusesForQuery()) @@ -332,10 +332,10 @@ private function handleGaAggregate( /** * Resolve open findings whose fingerprint is not in the current scan. */ - private function resolveStaleFindings(Tenant $tenant, array $currentFingerprints, CarbonImmutable $observedAt): int + private function resolveStaleFindings(ManagedEnvironment $tenant, array $currentFingerprints, CarbonImmutable $observedAt): int { $staleFindings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->whereIn('status', Finding::openStatusesForQuery()) ->whereNotIn('fingerprint', $currentFingerprints) @@ -380,7 +380,7 @@ private function resolveSlaPolicy(): FindingSlaPolicy return $this->slaPolicy ?? app(FindingSlaPolicy::class); } - private function observeFinding(Finding $finding, Tenant $tenant, CarbonImmutable $observedAt, string $severity): void + private function observeFinding(Finding $finding, ManagedEnvironment $tenant, CarbonImmutable $observedAt, string $severity): void { if ($finding->first_seen_at === null) { $finding->first_seen_at = $observedAt; @@ -409,11 +409,11 @@ private function observeFinding(Finding $finding, Tenant $tenant, CarbonImmutabl } } - private function produceAlertEvent(Tenant $tenant, string $fingerprint, array $evidence): void + private function produceAlertEvent(ManagedEnvironment $tenant, string $fingerprint, array $evidence): void { $this->alertEvents[] = [ 'event_type' => AlertRule::EVENT_ENTRA_ADMIN_ROLES_HIGH, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => $evidence['severity'] ?? Finding::SEVERITY_HIGH, 'fingerprint_key' => 'entra_admin_role:'.$fingerprint, 'title' => 'High-privilege Entra admin role detected', @@ -446,12 +446,12 @@ private function buildEvidence(array $assignment, ?array $roleDef, array $princi ]; } - private function individualFingerprint(Tenant $tenant, string $templateId, string $principalId, string $scopeId): string + private function individualFingerprint(ManagedEnvironment $tenant, string $templateId, string $principalId, string $scopeId): string { return substr(hash('sha256', "entra_admin_role:{$tenant->getKey()}:{$templateId}:{$principalId}:{$scopeId}"), 0, 64); } - private function gaAggregateFingerprint(Tenant $tenant): string + private function gaAggregateFingerprint(ManagedEnvironment $tenant): string { return substr(hash('sha256', "entra_admin_role_ga_count:{$tenant->getKey()}"), 0, 64); } diff --git a/apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesReportService.php b/apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesReportService.php index 39b7684a..6ad6ead7 100644 --- a/apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesReportService.php +++ b/apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesReportService.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Providers\MicrosoftGraphOptionsResolver; use App\Support\ProductTelemetry\ProductTelemetryRecorder; @@ -26,7 +26,7 @@ public function __construct( /** * Fetch Graph data and produce a stored report for the given tenant. */ - public function generate(Tenant $tenant, ?OperationRun $operationRun = null): EntraAdminRolesReportResult + public function generate(ManagedEnvironment $tenant, ?OperationRun $operationRun = null): EntraAdminRolesReportResult { $graphOptions = $this->graphOptionsResolver->resolveForTenant($tenant); @@ -37,7 +37,7 @@ public function generate(Tenant $tenant, ?OperationRun $operationRun = null): En $fingerprint = $this->computeFingerprint($roleDefinitions, $roleAssignments); $latestReport = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES) ->orderByDesc('created_at') ->orderByDesc('id') @@ -53,7 +53,7 @@ public function generate(Tenant $tenant, ?OperationRun $operationRun = null): En } $report = StoredReport::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'payload' => $payload, 'fingerprint' => $fingerprint, @@ -207,7 +207,7 @@ private function recordStoredReportTelemetry(StoredReport $report, ?OperationRun $this->productTelemetryRecorder->record( eventName: ProductUsageEventCatalog::STORED_REPORT_CREATED, workspaceId: (int) $report->workspace_id, - tenantId: (int) $report->tenant_id, + tenantId: (int) $report->managed_environment_id, userId: (int) $operationRun->user_id, subjectType: 'stored_report', subjectId: (int) $report->getKey(), diff --git a/apps/platform/app/Services/Evidence/Contracts/EvidenceSourceProvider.php b/apps/platform/app/Services/Evidence/Contracts/EvidenceSourceProvider.php index d3e85302..6e9cbaa5 100644 --- a/apps/platform/app/Services/Evidence/Contracts/EvidenceSourceProvider.php +++ b/apps/platform/app/Services/Evidence/Contracts/EvidenceSourceProvider.php @@ -4,7 +4,7 @@ namespace App\Services\Evidence\Contracts; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; interface EvidenceSourceProvider { @@ -26,5 +26,5 @@ public function key(): string; * sort_order: int * } */ - public function collect(Tenant $tenant): array; + public function collect(ManagedEnvironment $tenant): array; } diff --git a/apps/platform/app/Services/Evidence/EvidenceSnapshotResolver.php b/apps/platform/app/Services/Evidence/EvidenceSnapshotResolver.php index cd221148..961ea881 100644 --- a/apps/platform/app/Services/Evidence/EvidenceSnapshotResolver.php +++ b/apps/platform/app/Services/Evidence/EvidenceSnapshotResolver.php @@ -14,7 +14,7 @@ public function resolve(EvidenceResolutionRequest $request): EvidenceResolutionR $query = EvidenceSnapshot::query() ->with('items') ->where('workspace_id', $request->workspaceId) - ->where('tenant_id', $request->tenantId) + ->where('managed_environment_id', $request->tenantId) ->where('status', 'active') ->where(function ($query): void { $query->whereNull('expires_at')->orWhere('expires_at', '>', now()); diff --git a/apps/platform/app/Services/Evidence/EvidenceSnapshotService.php b/apps/platform/app/Services/Evidence/EvidenceSnapshotService.php index 945fc1dd..28d46823 100644 --- a/apps/platform/app/Services/Evidence/EvidenceSnapshotService.php +++ b/apps/platform/app/Services/Evidence/EvidenceSnapshotService.php @@ -6,7 +6,7 @@ use App\Jobs\GenerateEvidenceSnapshotJob; use App\Models\EvidenceSnapshot; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; use App\Services\Evidence\Contracts\EvidenceSourceProvider; @@ -30,7 +30,7 @@ public function __construct( private readonly EvidenceCompletenessEvaluator $completenessEvaluator, ) {} - public function generate(Tenant $tenant, User $user, bool $allowStale = false): EvidenceSnapshot + public function generate(ManagedEnvironment $tenant, User $user, bool $allowStale = false): EvidenceSnapshot { $fingerprint = $this->computeFingerprint($tenant); $existing = $this->findExistingSnapshot($tenant, $fingerprint); @@ -43,11 +43,11 @@ public function generate(Tenant $tenant, User $user, bool $allowStale = false): tenant: $tenant, type: OperationRunType::EvidenceSnapshotGenerate->value, identityInputs: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'fingerprint' => $fingerprint, ], context: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'allow_stale' => $allowStale, 'fingerprint' => $fingerprint, @@ -56,7 +56,7 @@ public function generate(Tenant $tenant, User $user, bool $allowStale = false): ); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'operation_run_id' => (int) $operationRun->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), @@ -99,7 +99,7 @@ public function refresh(EvidenceSnapshot $snapshot, User $user): EvidenceSnapsho { $tenant = $snapshot->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new InvalidArgumentException('Snapshot tenant could not be resolved.'); } @@ -136,7 +136,7 @@ public function expire(EvidenceSnapshot $snapshot, User $user, string $reason): $tenant = $snapshot->tenant; - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $this->auditLogger->log( workspace: $tenant->workspace, action: AuditActionId::EvidenceSnapshotExpired, @@ -175,7 +175,7 @@ public function providers(): array /** * @return array{items: list>, fingerprint: string, completeness: string, summary: array} */ - public function buildSnapshotPayload(Tenant $tenant): array + public function buildSnapshotPayload(ManagedEnvironment $tenant): array { $items = []; $fingerprintPayload = []; @@ -249,7 +249,7 @@ public function buildSnapshotPayload(Tenant $tenant): array ]; } - public function computeFingerprint(Tenant $tenant): string + public function computeFingerprint(ManagedEnvironment $tenant): string { return $this->buildSnapshotPayload($tenant)['fingerprint']; } @@ -273,19 +273,19 @@ private function validatedReason(mixed $reason, string $field): string return $resolved; } - public function checkActiveRun(Tenant $tenant): bool + public function checkActiveRun(ManagedEnvironment $tenant): bool { return $this->operationRuns->findCanonicalRunWithIdentity( tenant: $tenant, type: OperationRunType::EvidenceSnapshotGenerate->value, identityInputs: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'fingerprint' => $this->computeFingerprint($tenant), ], ) !== null; } - private function findExistingSnapshot(Tenant $tenant, string $fingerprint): ?EvidenceSnapshot + private function findExistingSnapshot(ManagedEnvironment $tenant, string $fingerprint): ?EvidenceSnapshot { return EvidenceSnapshot::query() ->forTenant((int) $tenant->getKey()) diff --git a/apps/platform/app/Services/Evidence/Sources/BaselineDriftPostureSource.php b/apps/platform/app/Services/Evidence/Sources/BaselineDriftPostureSource.php index 044a4218..284603ea 100644 --- a/apps/platform/app/Services/Evidence/Sources/BaselineDriftPostureSource.php +++ b/apps/platform/app/Services/Evidence/Sources/BaselineDriftPostureSource.php @@ -5,7 +5,7 @@ namespace App\Services\Evidence\Sources; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Evidence\Contracts\EvidenceSourceProvider; use App\Support\Evidence\EvidenceCompletenessState; @@ -16,10 +16,10 @@ public function key(): string return 'baseline_drift_posture'; } - public function collect(Tenant $tenant): array + public function collect(ManagedEnvironment $tenant): array { $findings = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->latest('updated_at') ->get(); diff --git a/apps/platform/app/Services/Evidence/Sources/EntraAdminRolesSource.php b/apps/platform/app/Services/Evidence/Sources/EntraAdminRolesSource.php index 3b5933e3..8711f594 100644 --- a/apps/platform/app/Services/Evidence/Sources/EntraAdminRolesSource.php +++ b/apps/platform/app/Services/Evidence/Sources/EntraAdminRolesSource.php @@ -5,7 +5,7 @@ namespace App\Services\Evidence\Sources; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Evidence\Contracts\EvidenceSourceProvider; use App\Support\Evidence\EvidenceCompletenessState; @@ -16,10 +16,10 @@ public function key(): string return 'entra_admin_roles'; } - public function collect(Tenant $tenant): array + public function collect(ManagedEnvironment $tenant): array { $report = StoredReport::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES) ->latest('id') ->first(); diff --git a/apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php b/apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php index 90b7b300..1c674533 100644 --- a/apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php +++ b/apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php @@ -5,7 +5,7 @@ namespace App\Services\Evidence\Sources; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Evidence\Contracts\EvidenceSourceProvider; use App\Services\Findings\FindingRiskGovernanceResolver; use App\Support\Findings\FindingOutcomeSemantics; @@ -26,10 +26,10 @@ public function key(): string return 'findings_summary'; } - public function collect(Tenant $tenant): array + public function collect(ManagedEnvironment $tenant): array { $findings = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->with('findingException.currentDecision') ->orderByDesc('updated_at') ->get(); diff --git a/apps/platform/app/Services/Evidence/Sources/OperationsSummarySource.php b/apps/platform/app/Services/Evidence/Sources/OperationsSummarySource.php index b9a30274..27c1999a 100644 --- a/apps/platform/app/Services/Evidence/Sources/OperationsSummarySource.php +++ b/apps/platform/app/Services/Evidence/Sources/OperationsSummarySource.php @@ -5,7 +5,7 @@ namespace App\Services\Evidence\Sources; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Evidence\Contracts\EvidenceSourceProvider; use App\Support\Evidence\EvidenceCompletenessState; use App\Support\OperationRunOutcome; @@ -17,10 +17,10 @@ public function key(): string return 'operations_summary'; } - public function collect(Tenant $tenant): array + public function collect(ManagedEnvironment $tenant): array { $runs = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('created_at', '>=', now()->subDays(30)) ->latest('created_at') ->get(); diff --git a/apps/platform/app/Services/Evidence/Sources/PermissionPostureSource.php b/apps/platform/app/Services/Evidence/Sources/PermissionPostureSource.php index f926c34e..77c41d60 100644 --- a/apps/platform/app/Services/Evidence/Sources/PermissionPostureSource.php +++ b/apps/platform/app/Services/Evidence/Sources/PermissionPostureSource.php @@ -5,7 +5,7 @@ namespace App\Services\Evidence\Sources; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Evidence\Contracts\EvidenceSourceProvider; use App\Support\Evidence\EvidenceCompletenessState; @@ -16,10 +16,10 @@ public function key(): string return 'permission_posture'; } - public function collect(Tenant $tenant): array + public function collect(ManagedEnvironment $tenant): array { $report = StoredReport::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_PERMISSION_POSTURE) ->latest('id') ->first(); diff --git a/apps/platform/app/Services/Findings/FindingAssignmentHygieneService.php b/apps/platform/app/Services/Findings/FindingAssignmentHygieneService.php index 1a4e508d..1e68fd82 100644 --- a/apps/platform/app/Services/Findings/FindingAssignmentHygieneService.php +++ b/apps/platform/app/Services/Findings/FindingAssignmentHygieneService.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -32,15 +32,15 @@ public function __construct( ) {} /** - * @return array + * @return array */ public function visibleTenants(Workspace $workspace, User $user): array { $authorizedTenants = $user->tenants() - ->where('tenants.workspace_id', (int) $workspace->getKey()) - ->where('tenants.status', 'active') - ->orderBy('tenants.name') - ->get(['tenants.id', 'tenants.name', 'tenants.external_id', 'tenants.workspace_id']) + ->where('managed_environments.workspace_id', (int) $workspace->getKey()) + ->where('managed_environments.lifecycle_status', 'active') + ->orderBy('managed_environments.name') + ->get(['managed_environments.id', 'managed_environments.name', 'managed_environments.slug', 'managed_environments.workspace_id']) ->all(); if ($authorizedTenants === []) { @@ -49,12 +49,12 @@ public function visibleTenants(Workspace $workspace, User $user): array $this->capabilityResolver->primeMemberships( $user, - array_map(static fn (Tenant $tenant): int => (int) $tenant->getKey(), $authorizedTenants), + array_map(static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $authorizedTenants), ); return array_values(array_filter( $authorizedTenants, - fn (Tenant $tenant): bool => $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW), + fn (ManagedEnvironment $tenant): bool => $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW), )); } @@ -120,11 +120,11 @@ private function issueQueryForVisibleTenantIds( 'assigneeUser' => static fn ($relation) => $relation->withTrashed(), ]) ->withSubjectDisplayName() - ->join('tenants', 'tenants.id', '=', 'findings.tenant_id') + ->join('managed_environments', 'managed_environments.id', '=', 'findings.managed_environment_id') ->leftJoin('users as hygiene_assignee_lookup', 'hygiene_assignee_lookup.id', '=', 'findings.assignee_user_id') - ->leftJoin('tenant_memberships as hygiene_assignee_membership', function ($join): void { + ->leftJoin('managed_environment_memberships as hygiene_assignee_membership', function ($join): void { $join - ->on('hygiene_assignee_membership.tenant_id', '=', 'findings.tenant_id') + ->on('hygiene_assignee_membership.managed_environment_id', '=', 'findings.managed_environment_id') ->on('hygiene_assignee_membership.user_id', '=', 'findings.assignee_user_id'); }) ->leftJoinSub( @@ -133,12 +133,12 @@ private function issueQueryForVisibleTenantIds( function ($join): void { $join ->on('hygiene_workflow_audit.workspace_id', '=', 'findings.workspace_id') - ->on('hygiene_workflow_audit.tenant_id', '=', 'findings.tenant_id') + ->on('hygiene_workflow_audit.managed_environment_id', '=', 'findings.managed_environment_id') ->whereRaw('hygiene_workflow_audit.resource_id = '.$this->castFindingIdToAuditResourceId()); }, ) ->where('findings.workspace_id', (int) $workspace->getKey()) - ->whereIn('findings.tenant_id', $visibleTenantIds === [] ? [-1] : $visibleTenantIds) + ->whereIn('findings.managed_environment_id', $visibleTenantIds === [] ? [-1] : $visibleTenantIds) ->whereIn('findings.status', Finding::openStatusesForQuery()) ->where(function (Builder $builder) use ($brokenAssignmentExpression, $staleInProgressExpression, $staleBindings): void { $builder @@ -161,7 +161,7 @@ function ($join): void { ->orderByRaw("{$lastWorkflowActivityExpression} asc") ->orderByRaw('case when findings.due_at is null then 1 else 0 end asc') ->orderBy('findings.due_at') - ->orderBy('tenants.name') + ->orderBy('managed_environments.name') ->orderByDesc('findings.id'); } @@ -200,7 +200,7 @@ public function summaryForVisibleTenantIds(Workspace $workspace, array $visibleT public function visibleTenantIds(Workspace $workspace, User $user): array { return array_map( - static fn (Tenant $tenant): int => (int) $tenant->getKey(), + static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $this->visibleTenants($workspace, $user), ); } @@ -286,10 +286,10 @@ private function applyReasonFilter( private function latestMeaningfulWorkflowAuditSubquery(): Builder { return AuditLog::query() - ->selectRaw('workspace_id, tenant_id, resource_id, max(recorded_at) as latest_workflow_activity_at') + ->selectRaw('workspace_id, managed_environment_id, resource_id, max(recorded_at) as latest_workflow_activity_at') ->where('resource_type', 'finding') ->whereIn('action', FindingWorkflowService::meaningfulActivityActionValues()) - ->groupBy('workspace_id', 'tenant_id', 'resource_id'); + ->groupBy('workspace_id', 'managed_environment_id', 'resource_id'); } private function brokenAssignmentExpression(): string diff --git a/apps/platform/app/Services/Findings/FindingExceptionService.php b/apps/platform/app/Services/Findings/FindingExceptionService.php index 936f853e..a989368f 100644 --- a/apps/platform/app/Services/Findings/FindingExceptionService.php +++ b/apps/platform/app/Services/Findings/FindingExceptionService.php @@ -7,8 +7,8 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\FindingExceptionDecision; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -41,7 +41,7 @@ public function __construct( * evidence_references?: mixed * } $payload */ - public function request(Finding $finding, Tenant $tenant, User $actor, array $payload): FindingException + public function request(Finding $finding, ManagedEnvironment $tenant, User $actor, array $payload): FindingException { $this->authorizeRequest($finding, $tenant, $actor); @@ -74,7 +74,7 @@ public function request(Finding $finding, Tenant $tenant, User $actor, array $pa $exception ??= new FindingException([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), ]); @@ -105,7 +105,7 @@ public function request(Finding $finding, Tenant $tenant, User $actor, array $pa $decision = $exception->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $actor->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_REQUESTED, 'reason' => $requestReason, @@ -206,7 +206,7 @@ public function approve(FindingException $exception, User $actor, array $payload $decision = $lockedException->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $actor->getKey(), 'decision_type' => $isRenewalApproval ? FindingExceptionDecision::TYPE_RENEWED @@ -328,7 +328,7 @@ public function reject(FindingException $exception, User $actor, array $payload) $decision = $lockedException->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $actor->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_REJECTED, 'reason' => $rejectionReason, @@ -431,7 +431,7 @@ public function renew(FindingException $exception, User $actor, array $payload): $decision = $lockedException->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $actor->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_RENEWAL_REQUESTED, 'reason' => $requestReason, @@ -520,7 +520,7 @@ public function revoke(FindingException $exception, User $actor, array $payload) $decision = $lockedException->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $actor->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_REVOKED, 'reason' => $revocationReason, @@ -563,7 +563,7 @@ public function revoke(FindingException $exception, User $actor, array $payload) return $revokedException; } - private function authorizeRequest(Finding $finding, Tenant $tenant, User $actor): void + private function authorizeRequest(Finding $finding, ManagedEnvironment $tenant, User $actor): void { if (! $actor->canAccessTenant($tenant)) { throw new NotFoundHttpException; @@ -578,7 +578,7 @@ private function authorizeRequest(Finding $finding, Tenant $tenant, User $actor) throw new AuthorizationException('Missing capability for exception request.'); } - private function authorizeApproval(FindingException $exception, Tenant $tenant, Workspace $workspace, User $actor): void + private function authorizeApproval(FindingException $exception, ManagedEnvironment $tenant, Workspace $workspace, User $actor): void { if (! $actor->canAccessTenant($tenant)) { throw new NotFoundHttpException; @@ -588,7 +588,7 @@ private function authorizeApproval(FindingException $exception, Tenant $tenant, throw new NotFoundHttpException; } - if ((int) $exception->workspace_id !== (int) $workspace->getKey() || (int) $exception->tenant_id !== (int) $tenant->getKey()) { + if ((int) $exception->workspace_id !== (int) $workspace->getKey() || (int) $exception->managed_environment_id !== (int) $tenant->getKey()) { throw new NotFoundHttpException; } @@ -599,13 +599,13 @@ private function authorizeApproval(FindingException $exception, Tenant $tenant, throw new AuthorizationException('Missing capability for exception approval.'); } - private function authorizeManagement(FindingException $exception, Tenant $tenant, User $actor): void + private function authorizeManagement(FindingException $exception, ManagedEnvironment $tenant, User $actor): void { if (! $actor->canAccessTenant($tenant)) { throw new NotFoundHttpException; } - if ((int) $exception->workspace_id !== (int) $tenant->workspace_id || (int) $exception->tenant_id !== (int) $tenant->getKey()) { + if ((int) $exception->workspace_id !== (int) $tenant->workspace_id || (int) $exception->managed_environment_id !== (int) $tenant->getKey()) { throw new NotFoundHttpException; } @@ -616,18 +616,18 @@ private function authorizeManagement(FindingException $exception, Tenant $tenant throw new AuthorizationException('Missing capability for exception management.'); } - private function tenantForException(FindingException $exception): Tenant + private function tenantForException(FindingException $exception): ManagedEnvironment { $tenant = $exception->tenant; - if (! $tenant instanceof Tenant) { - $tenant = Tenant::query()->findOrFail((int) $exception->tenant_id); + if (! $tenant instanceof ManagedEnvironment) { + $tenant = ManagedEnvironment::query()->findOrFail((int) $exception->managed_environment_id); } return $tenant; } - private function workspaceForTenant(Tenant $tenant): Workspace + private function workspaceForTenant(ManagedEnvironment $tenant): Workspace { $workspace = $tenant->workspace; @@ -638,9 +638,9 @@ private function workspaceForTenant(Tenant $tenant): Workspace return $workspace; } - private function assertFindingOwnedByTenant(Finding $finding, Tenant $tenant): void + private function assertFindingOwnedByTenant(Finding $finding, ManagedEnvironment $tenant): void { - if ((int) $finding->tenant_id !== (int) $tenant->getKey()) { + if ((int) $finding->managed_environment_id !== (int) $tenant->getKey()) { throw new NotFoundHttpException; } @@ -649,7 +649,7 @@ private function assertFindingOwnedByTenant(Finding $finding, Tenant $tenant): v } } - private function validatedTenantMemberId(Tenant $tenant, mixed $userId, string $field, bool $required = false): ?int + private function validatedTenantMemberId(ManagedEnvironment $tenant, mixed $userId, string $field, bool $required = false): ?int { $label = $this->fieldLabel($field); @@ -667,8 +667,8 @@ private function validatedTenantMemberId(Tenant $tenant, mixed $userId, string $ $resolvedUserId = (int) $userId; - $isMember = TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + $isMember = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', $resolvedUserId) ->exists(); @@ -822,7 +822,7 @@ private function replaceEvidenceReferences(FindingException $exception, array $r foreach ($references as $reference) { $exception->evidenceReferences()->create([ 'workspace_id' => (int) $exception->workspace_id, - 'tenant_id' => (int) $exception->tenant_id, + 'managed_environment_id' => (int) $exception->managed_environment_id, 'source_type' => $reference['source_type'], 'source_id' => $reference['source_id'], 'source_fingerprint' => $reference['source_fingerprint'], diff --git a/apps/platform/app/Services/Findings/FindingNotificationService.php b/apps/platform/app/Services/Findings/FindingNotificationService.php index bff3f137..4d546ed8 100644 --- a/apps/platform/app/Services/Findings/FindingNotificationService.php +++ b/apps/platform/app/Services/Findings/FindingNotificationService.php @@ -6,7 +6,7 @@ use App\Models\AlertRule; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Notifications\Findings\FindingEventNotification; @@ -37,7 +37,7 @@ public function dispatch(Finding $finding, string $eventType, array $context = [ $finding = $this->reloadFinding($finding); $tenant = $finding->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return $this->dispatchResult( eventType: $eventType, fingerprintKey: '', @@ -108,7 +108,7 @@ private function resolveRecipient(Finding $finding, string $eventType, array $co */ private function buildEventEnvelope( Finding $finding, - Tenant $tenant, + ManagedEnvironment $tenant, string $eventType, ?string $recipientReason, array $context, @@ -122,7 +122,7 @@ private function buildEventEnvelope( return [ 'event_type' => $eventType, 'workspace_id' => (int) $finding->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'severity' => $severity, 'title' => $title, @@ -145,7 +145,7 @@ private function buildEventEnvelope( /** * @param array $event */ - private function dispatchDirectNotification(Finding $finding, Tenant $tenant, array $event, ?int $userId): string + private function dispatchDirectNotification(Finding $finding, ManagedEnvironment $tenant, array $event, ?int $userId): string { if (! is_int($userId) || $userId <= 0) { return 'no_recipient'; @@ -285,7 +285,7 @@ private function eventLabel(string $eventType): string }; } - private function eventBody(string $eventType, Tenant $tenant, string $summary, string $severityLabel): string + private function eventBody(string $eventType, ManagedEnvironment $tenant, string $summary, string $severityLabel): string { return match ($eventType) { AlertRule::EVENT_FINDINGS_ASSIGNED => sprintf( diff --git a/apps/platform/app/Services/Findings/FindingSlaPolicy.php b/apps/platform/app/Services/Findings/FindingSlaPolicy.php index 7fb904f2..ccd81b55 100644 --- a/apps/platform/app/Services/Findings/FindingSlaPolicy.php +++ b/apps/platform/app/Services/Findings/FindingSlaPolicy.php @@ -5,7 +5,7 @@ namespace App\Services\Findings; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Services\Settings\SettingsResolver; use Carbon\CarbonImmutable; @@ -17,17 +17,17 @@ public function __construct( private readonly SettingsResolver $settingsResolver, ) {} - public function daysForFinding(Finding $finding, Tenant $tenant): int + public function daysForFinding(Finding $finding, ManagedEnvironment $tenant): int { return $this->daysForSeverity((string) $finding->severity, $tenant); } - public function daysForSeverity(string $severity, Tenant $tenant): int + public function daysForSeverity(string $severity, ManagedEnvironment $tenant): int { $workspace = $tenant->workspace; if (! $workspace instanceof Workspace) { - throw new InvalidArgumentException('Tenant workspace is required to resolve findings SLA.'); + throw new InvalidArgumentException('ManagedEnvironment workspace is required to resolve findings SLA.'); } $policy = $this->settingsResolver->resolveValue($workspace, 'findings', 'sla_days'); @@ -43,7 +43,7 @@ public function daysForSeverity(string $severity, Tenant $tenant): int return (int) $days; } - public function dueAtForSeverity(string $severity, Tenant $tenant, ?CarbonImmutable $from = null): CarbonImmutable + public function dueAtForSeverity(string $severity, ManagedEnvironment $tenant, ?CarbonImmutable $from = null): CarbonImmutable { $from ??= CarbonImmutable::now(); diff --git a/apps/platform/app/Services/Findings/FindingWorkflowService.php b/apps/platform/app/Services/Findings/FindingWorkflowService.php index 2230bc1e..10a34f71 100644 --- a/apps/platform/app/Services/Findings/FindingWorkflowService.php +++ b/apps/platform/app/Services/Findings/FindingWorkflowService.php @@ -6,8 +6,8 @@ use App\Models\Finding; use App\Models\AlertRule; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Intune\AuditLogger; @@ -44,7 +44,7 @@ public static function meaningfulActivityActionValues(): array ]; } - public function triage(Finding $finding, Tenant $tenant, User $actor): Finding + public function triage(Finding $finding, ManagedEnvironment $tenant, User $actor): Finding { $this->authorize($finding, $tenant, $actor, [Capabilities::TENANT_FINDINGS_TRIAGE]); @@ -76,7 +76,7 @@ public function triage(Finding $finding, Tenant $tenant, User $actor): Finding ); } - public function startProgress(Finding $finding, Tenant $tenant, User $actor): Finding + public function startProgress(Finding $finding, ManagedEnvironment $tenant, User $actor): Finding { $this->authorize($finding, $tenant, $actor, [Capabilities::TENANT_FINDINGS_TRIAGE]); @@ -106,7 +106,7 @@ public function startProgress(Finding $finding, Tenant $tenant, User $actor): Fi public function assign( Finding $finding, - Tenant $tenant, + ManagedEnvironment $tenant, User $actor, ?int $assigneeUserId = null, ?int $ownerUserId = null, @@ -164,7 +164,7 @@ public function assign( return $updatedFinding; } - public function claim(Finding $finding, Tenant $tenant, User $actor): Finding + public function claim(Finding $finding, ManagedEnvironment $tenant, User $actor): Finding { $this->authorize($finding, $tenant, $actor, [Capabilities::TENANT_FINDINGS_ASSIGN]); @@ -260,7 +260,7 @@ public function responsibilityChangeSummary( }; } - public function resolve(Finding $finding, Tenant $tenant, User $actor, string $reason): Finding + public function resolve(Finding $finding, ManagedEnvironment $tenant, User $actor, string $reason): Finding { $this->authorize($finding, $tenant, $actor, [Capabilities::TENANT_FINDINGS_RESOLVE]); @@ -290,7 +290,7 @@ public function resolve(Finding $finding, Tenant $tenant, User $actor, string $r ); } - public function close(Finding $finding, Tenant $tenant, User $actor, string $reason): Finding + public function close(Finding $finding, ManagedEnvironment $tenant, User $actor, string $reason): Finding { $this->authorize($finding, $tenant, $actor, [Capabilities::TENANT_FINDINGS_CLOSE]); @@ -317,21 +317,21 @@ public function close(Finding $finding, Tenant $tenant, User $actor, string $rea ); } - public function riskAccept(Finding $finding, Tenant $tenant, User $actor, string $reason): Finding + public function riskAccept(Finding $finding, ManagedEnvironment $tenant, User $actor, string $reason): Finding { $this->authorize($finding, $tenant, $actor, [Capabilities::TENANT_FINDINGS_RISK_ACCEPT]); return $this->riskAcceptWithoutAuthorization($finding, $tenant, $actor, $reason); } - public function riskAcceptFromException(Finding $finding, Tenant $tenant, User $actor, string $reason): Finding + public function riskAcceptFromException(Finding $finding, ManagedEnvironment $tenant, User $actor, string $reason): Finding { $this->assertFindingOwnedByTenant($finding, $tenant); return $this->riskAcceptWithoutAuthorization($finding, $tenant, $actor, $reason); } - private function riskAcceptWithoutAuthorization(Finding $finding, Tenant $tenant, User $actor, string $reason): Finding + private function riskAcceptWithoutAuthorization(Finding $finding, ManagedEnvironment $tenant, User $actor, string $reason): Finding { if (! $finding->hasOpenStatus() && (string) $finding->status !== Finding::STATUS_RISK_ACCEPTED) { throw new InvalidArgumentException('Only open findings can be marked as risk accepted.'); @@ -360,7 +360,7 @@ private function riskAcceptWithoutAuthorization(Finding $finding, Tenant $tenant ); } - public function reopen(Finding $finding, Tenant $tenant, User $actor, string $reason): Finding + public function reopen(Finding $finding, ManagedEnvironment $tenant, User $actor, string $reason): Finding { $this->authorize($finding, $tenant, $actor, [Capabilities::TENANT_FINDINGS_TRIAGE]); @@ -402,7 +402,7 @@ public function reopen(Finding $finding, Tenant $tenant, User $actor, string $re public function resolveBySystem( Finding $finding, - Tenant $tenant, + ManagedEnvironment $tenant, string $reason, CarbonImmutable $resolvedAt, ?int $operationRunId = null, @@ -444,7 +444,7 @@ public function resolveBySystem( public function reopenBySystem( Finding $finding, - Tenant $tenant, + ManagedEnvironment $tenant, CarbonImmutable $reopenedAt, ?int $operationRunId = null, ?callable $mutate = null, @@ -525,7 +525,7 @@ public function lastMeaningfulActivityAt(Finding $finding, mixed $latestWorkflow /** * @param array $capabilities */ - private function authorize(Finding $finding, Tenant $tenant, User $actor, array $capabilities): void + private function authorize(Finding $finding, ManagedEnvironment $tenant, User $actor, array $capabilities): void { if (! $actor->canAccessTenant($tenant)) { throw new NotFoundHttpException; @@ -542,9 +542,9 @@ private function authorize(Finding $finding, Tenant $tenant, User $actor, array throw new AuthorizationException('Missing capability for finding workflow action.'); } - private function assertFindingOwnedByTenant(Finding $finding, Tenant $tenant): void + private function assertFindingOwnedByTenant(Finding $finding, ManagedEnvironment $tenant): void { - if ((int) $finding->tenant_id !== (int) $tenant->getKey()) { + if ((int) $finding->managed_environment_id !== (int) $tenant->getKey()) { throw new NotFoundHttpException; } @@ -553,7 +553,7 @@ private function assertFindingOwnedByTenant(Finding $finding, Tenant $tenant): v } } - private function assertTenantMemberOrNull(Tenant $tenant, ?int $userId, string $field): void + private function assertTenantMemberOrNull(ManagedEnvironment $tenant, ?int $userId, string $field): void { if ($userId === null) { return; @@ -563,8 +563,8 @@ private function assertTenantMemberOrNull(Tenant $tenant, ?int $userId, string $ throw new InvalidArgumentException(sprintf('%s must be a positive user id.', $field)); } - $isMember = TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + $isMember = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', $userId) ->exists(); @@ -625,7 +625,7 @@ private function normalizeActivityTimestamp(mixed $value): ?CarbonImmutable */ private function mutateAndAudit( Finding $finding, - Tenant $tenant, + ManagedEnvironment $tenant, ?User $actor, string|AuditActionId $action, array $context, diff --git a/apps/platform/app/Services/Graph/AssignmentFetcher.php b/apps/platform/app/Services/Graph/AssignmentFetcher.php index 395002d0..7fe2a182 100644 --- a/apps/platform/app/Services/Graph/AssignmentFetcher.php +++ b/apps/platform/app/Services/Graph/AssignmentFetcher.php @@ -29,7 +29,7 @@ public function fetch( ): array { if (! $this->supportsStandardAssignments($policyType, $policyOdataType)) { Log::debug('Standard assignment fetch is not applicable for policy type', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_type' => $policyType, 'policy_id' => $policyId, ]); @@ -42,7 +42,7 @@ public function fetch( $resource = $contract['resource'] ?? null; $requestOptions = array_merge($options, ['tenant' => $tenantId]); $context = [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_type' => $policyType, 'policy_id' => $policyId, ]; @@ -84,7 +84,7 @@ public function fetch( if (! empty($assignments)) { Log::debug('Fetched assignments via primary endpoint', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_type' => $policyType, 'policy_id' => $policyId, 'count' => count($assignments), @@ -104,7 +104,7 @@ public function fetch( if ($lastSuccessfulAssignments !== null && $policyType === 'appProtectionPolicy') { Log::debug('Assignments fetched via primary endpoint(s)', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_type' => $policyType, 'policy_id' => $policyId, 'count' => count($lastSuccessfulAssignments), @@ -115,21 +115,21 @@ public function fetch( // Try fallback with $expand Log::debug('Primary endpoint returned empty, trying fallback', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_type' => $policyType, 'policy_id' => $policyId, ]); if (! is_string($resource) || $resource === '') { Log::debug('Assignments resource not configured for policy type', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_type' => $policyType, 'policy_id' => $policyId, ]); if ($throwOnFailure && $primaryException) { Log::warning('Failed to fetch assignments', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_type' => $policyType, 'policy_id' => $policyId, 'error' => $primaryException->getMessage(), @@ -166,7 +166,7 @@ public function fetch( if (! empty($assignments)) { Log::debug('Fetched assignments via fallback endpoint', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_type' => $policyType, 'policy_id' => $policyId, 'count' => count($assignments), @@ -177,7 +177,7 @@ public function fetch( // Both methods returned empty Log::debug('No assignments found for policy', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_type' => $policyType, 'policy_id' => $policyId, ]); @@ -186,7 +186,7 @@ public function fetch( $exception = $fallbackException ?? $primaryException; Log::warning('Failed to fetch assignments', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_type' => $policyType, 'policy_id' => $policyId, 'error' => $exception->getMessage(), diff --git a/apps/platform/app/Services/Graph/AssignmentFilterResolver.php b/apps/platform/app/Services/Graph/AssignmentFilterResolver.php index 57f5375a..8541a25c 100644 --- a/apps/platform/app/Services/Graph/AssignmentFilterResolver.php +++ b/apps/platform/app/Services/Graph/AssignmentFilterResolver.php @@ -2,7 +2,7 @@ namespace App\Services\Graph; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\MicrosoftGraphOptionsResolver; use Illuminate\Support\Facades\Cache; @@ -17,7 +17,7 @@ public function __construct( * @param array $filterIds * @return array */ - public function resolve(array $filterIds, ?Tenant $tenant = null): array + public function resolve(array $filterIds, ?ManagedEnvironment $tenant = null): array { if (empty($filterIds)) { return []; @@ -33,7 +33,7 @@ public function resolve(array $filterIds, ?Tenant $tenant = null): array /** * @return array */ - private function fetchAllFilters(?Tenant $tenant = null): array + private function fetchAllFilters(?ManagedEnvironment $tenant = null): array { $cacheKey = $tenant ? "assignment_filters:tenant:{$tenant->id}" : 'assignment_filters:all'; diff --git a/apps/platform/app/Services/Graph/GraphClientInterface.php b/apps/platform/app/Services/Graph/GraphClientInterface.php index f3c67713..6efab40f 100644 --- a/apps/platform/app/Services/Graph/GraphClientInterface.php +++ b/apps/platform/app/Services/Graph/GraphClientInterface.php @@ -15,7 +15,7 @@ interface GraphClientInterface * - `top`: `int` Optional `$top`. * - `platform`: `string` Optional platform filter (contract-specific). * - * Tenant/auth context options (typically resolved by `MicrosoftGraphOptionsResolver`): + * ManagedEnvironment/auth context options (typically resolved by `MicrosoftGraphOptionsResolver`): * - `tenant`, `client_id`, `client_secret`, `scope`, `token_url`, `access_token`, `client_request_id` * * @param string $policyType Graph policy type identifier diff --git a/apps/platform/app/Services/Graph/GroupResolver.php b/apps/platform/app/Services/Graph/GroupResolver.php index 55e4f330..192dcb9d 100644 --- a/apps/platform/app/Services/Graph/GroupResolver.php +++ b/apps/platform/app/Services/Graph/GroupResolver.php @@ -82,7 +82,7 @@ private function fetchAndResolveGroups(array $groupIds, string $tenantId, array } Log::debug('Resolved group IDs', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'requested' => count($groupIds), 'resolved' => count($resolvedIds), 'orphaned' => count($groupIds) - count($resolvedIds), @@ -91,7 +91,7 @@ private function fetchAndResolveGroups(array $groupIds, string $tenantId, array return $result; } catch (GraphException $e) { Log::warning('Failed to resolve group IDs', [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'group_ids' => $groupIds, 'error' => $e->getMessage(), 'context' => $e->context, diff --git a/apps/platform/app/Services/Graph/MicrosoftGraphClient.php b/apps/platform/app/Services/Graph/MicrosoftGraphClient.php index 8add21de..05093756 100644 --- a/apps/platform/app/Services/Graph/MicrosoftGraphClient.php +++ b/apps/platform/app/Services/Graph/MicrosoftGraphClient.php @@ -41,7 +41,7 @@ public function __construct( $this->baseUrl = rtrim(config('graph.base_url', 'https://graph.microsoft.com'), '/') .'/'.trim(config('graph.version', 'beta'), '/'); $this->tokenUrlTemplate = config('graph.token_url', 'https://login.microsoftonline.com/%s/oauth2/v2.0/token'); - $this->tenantId = config('graph.tenant_id', ''); + $this->tenantId = config('graph.managed_environment_id', ''); $this->clientId = config('graph.client_id', ''); $this->clientSecret = config('graph.client_secret', ''); $this->defaultScopes = $this->normalizeScopes(config('graph.scope', self::DEFAULT_SCOPE)); diff --git a/apps/platform/app/Services/Graph/ScopeTagResolver.php b/apps/platform/app/Services/Graph/ScopeTagResolver.php index dcf9ec7b..6f5493f3 100644 --- a/apps/platform/app/Services/Graph/ScopeTagResolver.php +++ b/apps/platform/app/Services/Graph/ScopeTagResolver.php @@ -2,7 +2,7 @@ namespace App\Services\Graph; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\ProviderConnectionResolver; use App\Services\Providers\ProviderGateway; use Illuminate\Support\Facades\Cache; @@ -21,10 +21,10 @@ public function __construct( * Filters to requested IDs in memory. * * @param array $scopeTagIds Array of scope tag IDs to resolve - * @param Tenant|null $tenant Optional tenant model with credentials + * @param ManagedEnvironment|null $tenant Optional tenant model with credentials * @return array Array of scope tag objects with id and displayName */ - public function resolve(array $scopeTagIds, ?Tenant $tenant = null): array + public function resolve(array $scopeTagIds, ?ManagedEnvironment $tenant = null): array { if (empty($scopeTagIds)) { return []; @@ -42,9 +42,9 @@ public function resolve(array $scopeTagIds, ?Tenant $tenant = null): array /** * Fetch all scope tags from Graph API (cached for 1 hour). */ - private function fetchAllScopeTags(?Tenant $tenant = null): array + private function fetchAllScopeTags(?ManagedEnvironment $tenant = null): array { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } @@ -56,7 +56,7 @@ private function fetchAllScopeTags(?Tenant $tenant = null): array if (! $resolution->resolved || $resolution->connection === null) { \Log::warning('Scope tag fetch blocked: provider connection unavailable', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'reason_code' => $resolution->effectiveReasonCode(), ]); @@ -75,7 +75,7 @@ private function fetchAllScopeTags(?Tenant $tenant = null): array // Check for 403 Forbidden (missing permissions) if (! $graphResponse->success && $graphResponse->status === 403) { \Log::warning('Scope tag fetch failed: Missing permissions', [ - 'tenant_id' => $tenant?->id, + 'managed_environment_id' => $tenant?->id, 'status' => 403, 'required_permissions' => ['DeviceManagementRBAC.Read.All', 'DeviceManagementRBAC.ReadWrite.All'], 'message' => 'App registration needs DeviceManagementRBAC permissions to read scope tags', @@ -87,7 +87,7 @@ private function fetchAllScopeTags(?Tenant $tenant = null): array } catch (\Exception $e) { // Fail soft - return empty array on any error \Log::warning('Scope tag fetch exception', [ - 'tenant_id' => $tenant?->id, + 'managed_environment_id' => $tenant?->id, 'error' => $e->getMessage(), ]); diff --git a/apps/platform/app/Services/Hardening/IntuneRbacWriteGate.php b/apps/platform/app/Services/Hardening/IntuneRbacWriteGate.php index edff4a73..e7af82c2 100644 --- a/apps/platform/app/Services/Hardening/IntuneRbacWriteGate.php +++ b/apps/platform/app/Services/Hardening/IntuneRbacWriteGate.php @@ -4,16 +4,16 @@ use App\Contracts\Hardening\WriteGateInterface; use App\Exceptions\Hardening\ProviderAccessHardeningRequired; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Support\Facades\Log; class IntuneRbacWriteGate implements WriteGateInterface { - public function evaluate(Tenant $tenant, string $operationType): void + public function evaluate(ManagedEnvironment $tenant, string $operationType): void { if (! $this->isEnabled()) { Log::warning('Intune write gate is disabled — write operation proceeding without RBAC verification.', [ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'operation_type' => $operationType, ]); @@ -53,7 +53,7 @@ public function evaluate(Tenant $tenant, string $operationType): void } } - public function wouldBlock(Tenant $tenant): bool + public function wouldBlock(ManagedEnvironment $tenant): bool { try { $this->evaluate($tenant, 'ui_check'); @@ -69,7 +69,7 @@ private function isEnabled(): bool return (bool) config('tenantpilot.hardening.intune_write_gate.enabled', true); } - private function isStale(Tenant $tenant): bool + private function isStale(ManagedEnvironment $tenant): bool { $lastCheckedAt = $tenant->rbac_last_checked_at; diff --git a/apps/platform/app/Services/Intune/AuditLogger.php b/apps/platform/app/Services/Intune/AuditLogger.php index 3a6ff446..dd5d2f58 100644 --- a/apps/platform/app/Services/Intune/AuditLogger.php +++ b/apps/platform/app/Services/Intune/AuditLogger.php @@ -4,7 +4,7 @@ namespace App\Services\Intune; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Audit\AuditRecorder; use App\Support\Audit\AuditActionId; use App\Support\Audit\AuditActorSnapshot; @@ -20,7 +20,7 @@ public function __construct( ) {} public function log( - Tenant $tenant, + ManagedEnvironment $tenant, string|AuditActionId $action, array $context = [], ?int $actorId = null, @@ -45,7 +45,7 @@ public function log( $context['metadata'] = $metadata; if ($workspaceId === null) { - throw new InvalidArgumentException('Tenant-scoped audit events require tenant workspace_id.'); + throw new InvalidArgumentException('ManagedEnvironment-scoped audit events require tenant workspace_id.'); } return $this->auditRecorder->record( diff --git a/apps/platform/app/Services/Intune/BackupService.php b/apps/platform/app/Services/Intune/BackupService.php index 0042fa9f..ad49d4fa 100644 --- a/apps/platform/app/Services/Intune/BackupService.php +++ b/apps/platform/app/Services/Intune/BackupService.php @@ -6,7 +6,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\AssignmentBackupService; use Carbon\CarbonImmutable; use Illuminate\Support\Facades\DB; @@ -29,7 +29,7 @@ public function __construct( * @param array $policyIds */ public function createBackupSet( - Tenant $tenant, + ManagedEnvironment $tenant, array $policyIds, ?string $actorEmail = null, ?string $actorName = null, @@ -41,14 +41,14 @@ public function createBackupSet( $this->assertActiveTenant($tenant); $policies = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->whereIn('id', $policyIds) ->currentBackupEligible() ->get(); $backupSet = DB::transaction(function () use ($tenant, $policies, $actorEmail, $name, $includeAssignments, $includeScopeTags, $includeFoundations) { $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => $name ?? CarbonImmutable::now()->format('Y-m-d H:i:s').' backup', 'created_by' => $actorEmail, 'status' => 'running', @@ -148,7 +148,7 @@ public function createBackupSet( * @param array $policyIds */ public function addPoliciesToSet( - Tenant $tenant, + ManagedEnvironment $tenant, BackupSet $backupSet, array $policyIds, ?string $actorEmail = null, @@ -159,7 +159,7 @@ public function addPoliciesToSet( ): BackupSet { $this->assertActiveTenant($tenant); - if ($backupSet->trashed() || $backupSet->tenant_id !== $tenant->id) { + if ($backupSet->trashed() || $backupSet->managed_environment_id !== $tenant->id) { throw new \RuntimeException('Backup set is archived or does not belong to the current tenant.'); } @@ -182,7 +182,7 @@ public function addPoliciesToSet( } $policies = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->whereIn('id', $policyIds) ->currentBackupEligible() ->get(); @@ -261,7 +261,7 @@ private function resolveStatus(int $itemsCreated, array $failures): string * @return array{0:?BackupItem,1:?array{policy_id:int,reason:string,status:int|string|null}} */ private function snapshotPolicy( - Tenant $tenant, + ManagedEnvironment $tenant, BackupSet $backupSet, Policy $policy, ?string $actorEmail = null, @@ -320,7 +320,7 @@ private function snapshotPolicy( * @param array{ids:array,names:array}|null $scopeTags */ private function createBackupItemFromVersion( - Tenant $tenant, + ManagedEnvironment $tenant, BackupSet $backupSet, Policy $policy, PolicyVersion $version, @@ -351,7 +351,7 @@ private function createBackupItemFromVersion( } return BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_version_id' => $version->id, @@ -369,7 +369,7 @@ private function createBackupItemFromVersion( * @param array $metadata */ private function createFoundationBackupItem( - Tenant $tenant, + ManagedEnvironment $tenant, BackupSet $backupSet, string $foundationType, ?string $platform, @@ -393,7 +393,7 @@ private function createFoundationBackupItem( } return BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy?->getKey(), 'policy_version_id' => $version?->getKey(), @@ -408,7 +408,7 @@ private function createFoundationBackupItem( /** * @return array{created:int,restored:int,failures:array} */ - private function captureFoundations(Tenant $tenant, BackupSet $backupSet): array + private function captureFoundations(ManagedEnvironment $tenant, BackupSet $backupSet): array { $types = config('tenantpilot.foundation_types', []); $created = 0; @@ -517,7 +517,7 @@ private function supportsFoundationVersioning(string $foundationType): bool * @param array $metadata */ private function resolveFoundationPolicy( - Tenant $tenant, + ManagedEnvironment $tenant, string $foundationType, string $sourceId, ?string $platform, @@ -531,7 +531,7 @@ private function resolveFoundationPolicy( ?? $sourceId; $policy = Policy::query()->firstOrNew([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => $sourceId, 'policy_type' => $foundationType, ]); @@ -556,10 +556,10 @@ private function resolveFoundationPolicy( return $policy; } - private function assertActiveTenant(Tenant $tenant): void + private function assertActiveTenant(ManagedEnvironment $tenant): void { if (! $tenant->isActive()) { - throw new \RuntimeException('Tenant is archived or inactive.'); + throw new \RuntimeException('ManagedEnvironment is archived or inactive.'); } } } diff --git a/apps/platform/app/Services/Intune/ConfigurationPolicyTemplateResolver.php b/apps/platform/app/Services/Intune/ConfigurationPolicyTemplateResolver.php index e81a8b84..705e2475 100644 --- a/apps/platform/app/Services/Intune/ConfigurationPolicyTemplateResolver.php +++ b/apps/platform/app/Services/Intune/ConfigurationPolicyTemplateResolver.php @@ -2,7 +2,7 @@ namespace App\Services\Intune; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphContractRegistry; use App\Services\Providers\MicrosoftGraphOptionsResolver; @@ -36,7 +36,7 @@ public function __construct( * @param array $graphOptions * @return array{success:bool,template_id:?string,template_reference:?array,reason:?string,warnings:array} */ - public function resolveTemplateReference(Tenant $tenant, array $templateReference, array $graphOptions = []): array + public function resolveTemplateReference(ManagedEnvironment $tenant, array $templateReference, array $graphOptions = []): array { $warnings = []; @@ -151,7 +151,7 @@ public function resolveTemplateReference(Tenant $tenant, array $templateReferenc * @param array $graphOptions * @return array{success:bool,template:?array,reason:?string} */ - public function getTemplate(Tenant $tenant, string $templateId, array $graphOptions = []): array + public function getTemplate(ManagedEnvironment $tenant, string $templateId, array $graphOptions = []): array { $tenantKey = $this->tenantKey($tenant, $graphOptions); @@ -185,7 +185,7 @@ public function getTemplate(Tenant $tenant, string $templateId, array $graphOpti * @param array $graphOptions * @return array{success:bool,templates:array,reason:?string} */ - public function listTemplatesByFamily(Tenant $tenant, string $templateFamily, array $graphOptions = []): array + public function listTemplatesByFamily(ManagedEnvironment $tenant, string $templateFamily, array $graphOptions = []): array { $tenantKey = $this->tenantKey($tenant, $graphOptions); $cacheKey = strtolower($templateFamily); @@ -227,7 +227,7 @@ public function listTemplatesByFamily(Tenant $tenant, string $templateFamily, ar * @param array $graphOptions * @return array{success:bool,definition_ids:array,reason:?string} */ - public function fetchTemplateSettingDefinitionIds(Tenant $tenant, string $templateId, array $graphOptions = []): array + public function fetchTemplateSettingDefinitionIds(ManagedEnvironment $tenant, string $templateId, array $graphOptions = []): array { $tenantKey = $this->tenantKey($tenant, $graphOptions); @@ -386,7 +386,7 @@ private function extractString(array $payload, array $keys): ?string /** * @param array $graphOptions */ - private function tenantKey(Tenant $tenant, array $graphOptions): string + private function tenantKey(ManagedEnvironment $tenant, array $graphOptions): string { $tenantId = $graphOptions['tenant'] ?? $tenant->graphTenantId() ?? (string) $tenant->getKey(); diff --git a/apps/platform/app/Services/Intune/FoundationMappingService.php b/apps/platform/app/Services/Intune/FoundationMappingService.php index 037c0fb6..b3c2c751 100644 --- a/apps/platform/app/Services/Intune/FoundationMappingService.php +++ b/apps/platform/app/Services/Intune/FoundationMappingService.php @@ -3,7 +3,7 @@ namespace App\Services\Intune; use App\Models\BackupItem; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphContractRegistry; use App\Services\Providers\MicrosoftGraphOptionsResolver; @@ -22,7 +22,7 @@ public function __construct( * @param Collection $items * @return array{entries: array>, mapping: array, failed: int, skipped: int} */ - public function map(Tenant $tenant, Collection $items, bool $execute = false): array + public function map(ManagedEnvironment $tenant, Collection $items, bool $execute = false): array { $entries = []; $mapping = []; @@ -240,7 +240,7 @@ private function isBuiltInScopeTag(string $foundationType, BackupItem $item): bo * @return array{success: bool, target_id: ?string, target_name: ?string, reason: ?string} */ private function createFoundation( - Tenant $tenant, + ManagedEnvironment $tenant, string $foundationType, BackupItem $item, string $targetName diff --git a/apps/platform/app/Services/Intune/FoundationSnapshotService.php b/apps/platform/app/Services/Intune/FoundationSnapshotService.php index 1030845f..1878f581 100644 --- a/apps/platform/app/Services/Intune/FoundationSnapshotService.php +++ b/apps/platform/app/Services/Intune/FoundationSnapshotService.php @@ -2,7 +2,7 @@ namespace App\Services\Intune; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphContractRegistry; use App\Services\Providers\MicrosoftGraphOptionsResolver; @@ -18,7 +18,7 @@ public function __construct( /** * @return array{items: array, failures: array} */ - public function fetchAll(Tenant $tenant, string $foundationType): array + public function fetchAll(ManagedEnvironment $tenant, string $foundationType): array { $resource = $this->contracts->resourcePath($foundationType); diff --git a/apps/platform/app/Services/Intune/PolicyCaptureOrchestrator.php b/apps/platform/app/Services/Intune/PolicyCaptureOrchestrator.php index 213555cc..f657aa4d 100644 --- a/apps/platform/app/Services/Intune/PolicyCaptureOrchestrator.php +++ b/apps/platform/app/Services/Intune/PolicyCaptureOrchestrator.php @@ -4,7 +4,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\AssignmentFetcher; use App\Services\Graph\AssignmentFilterResolver; use App\Services\Graph\GraphException; @@ -39,7 +39,7 @@ public function __construct( */ public function capture( Policy $policy, - Tenant $tenant, + ManagedEnvironment $tenant, bool $includeAssignments = false, bool $includeScopeTags = false, ?string $createdBy = null, @@ -119,7 +119,7 @@ public function capture( : (is_numeric($e->getCode()) ? (int) $e->getCode() : null); Log::warning('Failed to fetch assignments during capture', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'error' => $e->getMessage(), ]); @@ -198,7 +198,7 @@ public function capture( $existingVersion->update($updates); Log::info('Backfilled existing PolicyVersion with capture data', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_id' => $existingVersion->id, 'version_number' => $existingVersion->version_number, @@ -218,7 +218,7 @@ public function capture( } Log::info('Reusing existing PolicyVersion', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_id' => $existingVersion->id, 'version_number' => $existingVersion->version_number, @@ -255,7 +255,7 @@ public function capture( ); Log::info('Policy captured via orchestrator', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_id' => $version->id, 'version_number' => $version->version_number, @@ -279,7 +279,7 @@ public function capture( */ public function ensureVersionHasAssignments( PolicyVersion $version, - Tenant $tenant, + ManagedEnvironment $tenant, Policy $policy, bool $includeAssignments = false, bool $includeScopeTags = false @@ -465,7 +465,7 @@ private function extractAssignmentFilterIds(array $assignments): array * @param array $scopeTagIds * @return array{ids:array,names:array} */ - private function resolveScopeTags(Tenant $tenant, array $scopeTagIds): array + private function resolveScopeTags(ManagedEnvironment $tenant, array $scopeTagIds): array { $scopeTags = $this->scopeTagResolver->resolve($scopeTagIds, $tenant); diff --git a/apps/platform/app/Services/Intune/PolicySnapshotService.php b/apps/platform/app/Services/Intune/PolicySnapshotService.php index 479f6cea..19f7bba6 100644 --- a/apps/platform/app/Services/Intune/PolicySnapshotService.php +++ b/apps/platform/app/Services/Intune/PolicySnapshotService.php @@ -4,7 +4,7 @@ use App\Models\Policy; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphContractRegistry; use App\Services\Graph\GraphErrorMapper; @@ -34,9 +34,9 @@ public function __construct( * * @return array{payload:array,metadata:array,warnings:array}|array{failure:array} */ - public function fetch(Tenant $tenant, Policy $policy, ?string $actorEmail = null): array + public function fetch(ManagedEnvironment $tenant, Policy $policy, ?string $actorEmail = null): array { - $tenantIdentifier = $tenant->tenant_id ?? $tenant->external_id; + $tenantIdentifier = $tenant->managed_environment_id ?? $tenant->external_id; $connection = null; $graphOptions = []; @@ -747,7 +747,7 @@ private function extractDefinitionIds(array $settings): array return array_unique($definitionIds); } - private function resolveProviderConnection(Tenant $tenant): ProviderConnection + private function resolveProviderConnection(ManagedEnvironment $tenant): ProviderConnection { $resolution = $this->providerConnections()->resolveDefault($tenant, 'microsoft'); diff --git a/apps/platform/app/Services/Intune/PolicySyncService.php b/apps/platform/app/Services/Intune/PolicySyncService.php index 69dc25ba..8a7e6896 100644 --- a/apps/platform/app/Services/Intune/PolicySyncService.php +++ b/apps/platform/app/Services/Intune/PolicySyncService.php @@ -5,7 +5,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphErrorMapper; use App\Services\Graph\GraphLogger; @@ -34,7 +34,7 @@ public function __construct( * * @return array IDs of policies synced or created */ - public function syncPolicies(Tenant $tenant, ?array $supportedTypes = null): array + public function syncPolicies(ManagedEnvironment $tenant, ?array $supportedTypes = null): array { $result = $this->syncPoliciesWithReport($tenant, $supportedTypes); @@ -47,10 +47,10 @@ public function syncPolicies(Tenant $tenant, ?array $supportedTypes = null): arr * @param array|null $supportedTypes * @return array{synced: array, failures: array} */ - public function syncPoliciesWithReport(Tenant $tenant, ?array $supportedTypes = null): array + public function syncPoliciesWithReport(ManagedEnvironment $tenant, ?array $supportedTypes = null): array { if (! $tenant->isActive()) { - throw new \RuntimeException('Tenant is archived or inactive.'); + throw new \RuntimeException('ManagedEnvironment is archived or inactive.'); } $types = $supportedTypes ?? config('tenantpilot.supported_policy_types', []); @@ -91,7 +91,7 @@ public function syncPoliciesWithReport(Tenant $tenant, ?array $supportedTypes = } catch (Throwable $throwable) { throw GraphErrorMapper::fromThrowable($throwable, [ 'policy_type' => $policyType, - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'tenant_identifier' => $tenantIdentifier, 'provider_connection_id' => (int) $connection->getKey(), ]); @@ -99,7 +99,7 @@ public function syncPoliciesWithReport(Tenant $tenant, ?array $supportedTypes = $this->graphLogger->logResponse('list_policies', $response, [ 'policy_type' => $policyType, - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'tenant' => $tenantIdentifier, ]); @@ -157,7 +157,7 @@ public function syncPoliciesWithReport(Tenant $tenant, ?array $supportedTypes = ); $policy = Policy::query()->firstOrNew([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => $externalId, 'policy_type' => $policyType, ]); @@ -355,7 +355,7 @@ private function isEnrollmentNotificationItem(array $policyData): bool ], true); } - private function reclassifyEnrollmentConfigurationPoliciesIfNeeded(Tenant $tenant, string $externalId, string $policyType): void + private function reclassifyEnrollmentConfigurationPoliciesIfNeeded(ManagedEnvironment $tenant, string $externalId, string $policyType): void { $enrollmentTypes = [ 'enrollmentRestriction', @@ -370,7 +370,7 @@ private function reclassifyEnrollmentConfigurationPoliciesIfNeeded(Tenant $tenan } $existingCorrect = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('external_id', $externalId) ->where('policy_type', $policyType) ->first(); @@ -387,7 +387,7 @@ private function reclassifyEnrollmentConfigurationPoliciesIfNeeded(Tenant $tenan } $existingWrong = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('external_id', $externalId) ->whereIn('policy_type', $enrollmentTypes) ->where('policy_type', '!=', $policyType) @@ -417,7 +417,7 @@ private function reclassifyEnrollmentConfigurationPoliciesIfNeeded(Tenant $tenan ->update(['policy_type' => $policyType]); } - private function reclassifyConfigurationPoliciesIfNeeded(Tenant $tenant, string $externalId, string $policyType): void + private function reclassifyConfigurationPoliciesIfNeeded(ManagedEnvironment $tenant, string $externalId, string $policyType): void { $configurationTypes = ['settingsCatalogPolicy', 'endpointSecurityPolicy', 'securityBaselinePolicy']; @@ -426,7 +426,7 @@ private function reclassifyConfigurationPoliciesIfNeeded(Tenant $tenant, string } $existingCorrect = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('external_id', $externalId) ->where('policy_type', $policyType) ->first(); @@ -443,7 +443,7 @@ private function reclassifyConfigurationPoliciesIfNeeded(Tenant $tenant, string } $existingWrong = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('external_id', $externalId) ->whereIn('policy_type', $configurationTypes) ->where('policy_type', '!=', $policyType) @@ -476,12 +476,12 @@ private function reclassifyConfigurationPoliciesIfNeeded(Tenant $tenant, string /** * @param array $policyTypes */ - private function markSiblingPoliciesProviderMissing(Tenant $tenant, string $externalId, array $policyTypes, string $exceptPolicyType): void + private function markSiblingPoliciesProviderMissing(ManagedEnvironment $tenant, string $externalId, array $policyTypes, string $exceptPolicyType): void { $timestamp = now(); Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('external_id', $externalId) ->whereIn('policy_type', $policyTypes) ->where('policy_type', '!=', $exceptPolicyType) @@ -503,7 +503,7 @@ private function markSiblingPoliciesProviderMissing(Tenant $tenant, string $exte * @param array $policyTypes * @param array> $observedExternalIdsByPolicyType */ - private function markProviderMissingPolicies(Tenant $tenant, array $policyTypes, array $observedExternalIdsByPolicyType): void + private function markProviderMissingPolicies(ManagedEnvironment $tenant, array $policyTypes, array $observedExternalIdsByPolicyType): void { foreach ($policyTypes as $policyType) { if (! is_string($policyType) || $policyType === '') { @@ -516,7 +516,7 @@ private function markProviderMissingPolicies(Tenant $tenant, array $policyTypes, ))); $query = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', $policyType) ->whereNull('missing_from_provider_at'); @@ -541,7 +541,7 @@ private function markProviderMissingPolicies(Tenant $tenant, array $policyTypes, } private function auditProviderPresenceTransition( - Tenant $tenant, + ManagedEnvironment $tenant, Policy $policy, AuditActionId $action, mixed $transitionAt = null, @@ -577,10 +577,10 @@ private function auditLogger(): AuditLogger /** * Re-fetch a single policy from Graph and update local metadata. */ - public function syncPolicy(Tenant $tenant, Policy $policy): void + public function syncPolicy(ManagedEnvironment $tenant, Policy $policy): void { if (! $tenant->isActive()) { - throw new RuntimeException('Tenant is archived or inactive.'); + throw new RuntimeException('ManagedEnvironment is archived or inactive.'); } $resolution = $this->providerConnections()->resolveDefault($tenant, 'microsoft'); @@ -615,14 +615,14 @@ public function syncPolicy(Tenant $tenant, Policy $policy): void throw GraphErrorMapper::fromThrowable($throwable, [ 'policy_type' => $policy->policy_type, 'policy_id' => $policy->external_id, - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'tenant_identifier' => $tenantIdentifier, 'provider_connection_id' => (int) $connection->getKey(), ]); } $this->graphLogger->logResponse('get_policy', $response, [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'tenant' => $tenantIdentifier, 'policy_type' => $policy->policy_type, 'policy_id' => $policy->external_id, @@ -666,7 +666,7 @@ public function syncPolicy(Tenant $tenant, Policy $policy): void * @return array */ private function blockedFailuresForTypes( - Tenant $tenant, + ManagedEnvironment $tenant, array $types, string $reasonCode, ?string $reasonMessage = null, diff --git a/apps/platform/app/Services/Intune/RbacHealthService.php b/apps/platform/app/Services/Intune/RbacHealthService.php index 5b55496e..a372c5aa 100644 --- a/apps/platform/app/Services/Intune/RbacHealthService.php +++ b/apps/platform/app/Services/Intune/RbacHealthService.php @@ -3,7 +3,7 @@ namespace App\Services\Intune; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphContractRegistry; use App\Services\Providers\ProviderConnectionResolver; @@ -30,7 +30,7 @@ public function __construct( * reason_translation: array|null * } */ - public function check(Tenant $tenant): array + public function check(ManagedEnvironment $tenant): array { if (! $tenant->isActive()) { return $this->record($tenant, 'error', RbacReason::MissingArtifacts->value, false); @@ -117,7 +117,7 @@ public function check(Tenant $tenant): array * reason_translation: array|null * } */ - private function record(Tenant $tenant, string $status, ?string $reason, bool $usedArtifacts): array + private function record(ManagedEnvironment $tenant, string $status, ?string $reason, bool $usedArtifacts): array { $reasonTranslation = is_string($reason) && $reason !== '' ? RbacReason::tryFrom($reason)?->toReasonResolutionEnvelope('detail')->toArray() @@ -163,7 +163,7 @@ private function groupHasServicePrincipal(string $groupId, string $spId, array $ return collect($members)->contains(fn ($member) => ($member['id'] ?? null) === $spId); } - private function matchesScope(array $assignment, Tenant $tenant): bool + private function matchesScope(array $assignment, ManagedEnvironment $tenant): bool { $scopes = $assignment['resourceScopes'] ?? []; $expected = ($tenant->rbac_scope_mode === 'scope_group' && filled($tenant->rbac_scope_id)) @@ -173,7 +173,7 @@ private function matchesScope(array $assignment, Tenant $tenant): bool return $scopes === $expected; } - private function matchesRole(array $assignment, Tenant $tenant, array $context): bool + private function matchesRole(array $assignment, ManagedEnvironment $tenant, array $context): bool { $roleDefinitionId = data_get($assignment, 'roleDefinition.id') ?? data_get($assignment, 'roleDefinitionId'); $expectedId = $tenant->rbac_role_definition_id; @@ -185,7 +185,7 @@ private function matchesRole(array $assignment, Tenant $tenant, array $context): return strcasecmp($expectedId, $roleDefinitionId) === 0; } - private function assignmentIncludesGroup(array $assignment, Tenant $tenant): bool + private function assignmentIncludesGroup(array $assignment, ManagedEnvironment $tenant): bool { $bindingBase = sprintf('https://graph.microsoft.com/%s', trim(config('graph.version', 'beta'), '/')); $expected = "{$bindingBase}/groups/{$tenant->rbac_group_id}"; @@ -202,7 +202,7 @@ private function assignmentIncludesGroup(array $assignment, Tenant $tenant): boo return collect($members)->contains($expected); } - private function resolveProviderConnection(Tenant $tenant): ProviderConnection + private function resolveProviderConnection(ManagedEnvironment $tenant): ProviderConnection { $resolution = $this->providerConnections()->resolveDefault($tenant, 'microsoft'); diff --git a/apps/platform/app/Services/Intune/RbacOnboardingService.php b/apps/platform/app/Services/Intune/RbacOnboardingService.php index db4a2895..2e61b1cb 100644 --- a/apps/platform/app/Services/Intune/RbacOnboardingService.php +++ b/apps/platform/app/Services/Intune/RbacOnboardingService.php @@ -3,7 +3,7 @@ namespace App\Services\Intune; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphContractRegistry; @@ -33,10 +33,10 @@ public function __construct( * @param array{role_definition_id:?string,role_display_name?:?string,scope?:string,scope_group_id?:?string,group_mode?:string,group_name?:?string,existing_group_id?:?string} $input * @return array{status:string,message?:string,warnings:array,service_principal_id:?string,group_id:?string,role_definition_id:?string,role_display_name:?string,role_assignment_id:?string,steps:array} */ - public function run(Tenant $tenant, array $input, ?User $actor = null, ?string $accessToken = null): array + public function run(ManagedEnvironment $tenant, array $input, ?User $actor = null, ?string $accessToken = null): array { if (! $tenant->isActive()) { - return $this->failure($tenant, 'Tenant is not active', $actor); + return $this->failure($tenant, 'ManagedEnvironment is not active', $actor); } if (empty($accessToken)) { @@ -645,7 +645,7 @@ private function trimBindingId(string $binding): string /** * @param array{group_id:?string,role_assignment_id:?string,role_definition_id:?string,role_display_name:?string,scope_mode:?string,scope_id:?string,warnings?:array,canaries?:array,executed_by?:?int} $artifacts */ - private function persistArtifacts(Tenant $tenant, array $artifacts): void + private function persistArtifacts(ManagedEnvironment $tenant, array $artifacts): void { $canaries = $artifacts['canaries'] ?? []; @@ -707,7 +707,7 @@ private function persistArtifacts(Tenant $tenant, array $artifacts): void /** * @return array{canaries: array, warnings: array} */ - private function postCheck(Tenant $tenant, array $context, string $scopeMode, ?User $actor = null): array + private function postCheck(ManagedEnvironment $tenant, array $context, string $scopeMode, ?User $actor = null): array { $this->audit($tenant, 'rbac.verify.started', ['scope_mode' => $scopeMode], 'success', $actor); @@ -758,7 +758,7 @@ private function mailNickname(string $groupName): string return $nickname ?: 'tenantpilot_intune_rbac'; } - private function failure(Tenant $tenant, string $message, ?User $actor = null): array + private function failure(ManagedEnvironment $tenant, string $message, ?User $actor = null): array { $this->audit($tenant, 'rbac.setup.failed', ['error' => $message], 'error', $actor); @@ -784,7 +784,7 @@ private function providerGateway(): ProviderGateway return $this->providerGateway ?? app(ProviderGateway::class); } - private function audit(Tenant $tenant, string $action, array $context, string $status, ?User $actor = null): void + private function audit(ManagedEnvironment $tenant, string $action, array $context, string $status, ?User $actor = null): void { $this->auditLogger->log( tenant: $tenant, diff --git a/apps/platform/app/Services/Intune/RestoreDiffGenerator.php b/apps/platform/app/Services/Intune/RestoreDiffGenerator.php index 200eb65b..27927ddd 100644 --- a/apps/platform/app/Services/Intune/RestoreDiffGenerator.php +++ b/apps/platform/app/Services/Intune/RestoreDiffGenerator.php @@ -5,7 +5,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Illuminate\Support\Collection; @@ -20,9 +20,9 @@ public function __construct( * @param array|null $selectedItemIds * @return array{summary: array, diffs: array>} */ - public function generate(Tenant $tenant, BackupSet $backupSet, ?array $selectedItemIds = null): array + public function generate(ManagedEnvironment $tenant, BackupSet $backupSet, ?array $selectedItemIds = null): array { - if ($backupSet->tenant_id !== $tenant->id) { + if ($backupSet->managed_environment_id !== $tenant->id) { throw new \InvalidArgumentException('Backup set does not belong to the provided tenant.'); } @@ -172,20 +172,20 @@ private function loadItems(BackupSet $backupSet, ?array $selectedItemIds): Colle * @param array $policyIds * @return array */ - private function latestVersionsByPolicyId(Tenant $tenant, array $policyIds): array + private function latestVersionsByPolicyId(ManagedEnvironment $tenant, array $policyIds): array { if ($policyIds === []) { return []; } $latestVersionsQuery = PolicyVersion::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->whereIn('policy_id', $policyIds) ->selectRaw('policy_id, max(version_number) as version_number') ->groupBy('policy_id'); return PolicyVersion::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->joinSub($latestVersionsQuery, 'latest_versions', function ($join): void { $join->on('policy_versions.policy_id', '=', 'latest_versions.policy_id') ->on('policy_versions.version_number', '=', 'latest_versions.version_number'); diff --git a/apps/platform/app/Services/Intune/RestoreRiskChecker.php b/apps/platform/app/Services/Intune/RestoreRiskChecker.php index ec01d719..632358d5 100644 --- a/apps/platform/app/Services/Intune/RestoreRiskChecker.php +++ b/apps/platform/app/Services/Intune/RestoreRiskChecker.php @@ -6,7 +6,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GroupResolver; use App\Services\Providers\MicrosoftGraphOptionsResolver; use Carbon\CarbonImmutable; @@ -26,9 +26,9 @@ public function __construct( * @param array $groupMapping * @return array{summary: array{blocking: int, warning: int, safe: int, has_blockers: bool}, results: array}>} */ - public function check(Tenant $tenant, BackupSet $backupSet, ?array $selectedItemIds = null, array $groupMapping = []): array + public function check(ManagedEnvironment $tenant, BackupSet $backupSet, ?array $selectedItemIds = null, array $groupMapping = []): array { - if ($backupSet->tenant_id !== $tenant->id) { + if ($backupSet->managed_environment_id !== $tenant->id) { throw new \InvalidArgumentException('Backup set does not belong to the provided tenant.'); } @@ -95,7 +95,7 @@ private function loadItems(BackupSet $backupSet, ?array $selectedItemIds): Colle * @param array $groupMapping * @return array{code: string, severity: string, title: string, message: string, meta: array}|null */ - private function checkOrphanedGroups(Tenant $tenant, Collection $policyItems, array $groupMapping): ?array + private function checkOrphanedGroups(ManagedEnvironment $tenant, Collection $policyItems, array $groupMapping): ?array { [$groupIds, $sourceNames] = $this->extractGroupIds($policyItems); @@ -239,7 +239,7 @@ private function checkPreviewOnlyPolicies(Collection $items): ?array * @param Collection $policyItems * @return array{code: string, severity: string, title: string, message: string, meta: array}|null */ - private function checkEndpointSecurityTemplates(Tenant $tenant, Collection $policyItems): ?array + private function checkEndpointSecurityTemplates(ManagedEnvironment $tenant, Collection $policyItems): ?array { $issues = []; $hasRestoreEnabled = false; @@ -407,7 +407,7 @@ private function isMetadataOnlySnapshot(BackupItem $item): bool * @param Collection $policyItems * @return array{code: string, severity: string, title: string, message: string, meta: array}|null */ - private function checkMissingPolicies(Tenant $tenant, Collection $policyItems): ?array + private function checkMissingPolicies(ManagedEnvironment $tenant, Collection $policyItems): ?array { $pairs = []; @@ -442,7 +442,7 @@ private function checkMissingPolicies(Tenant $tenant, Collection $policyItems): $types = array_values(array_unique(array_column($pairs, 'type'))); $existing = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->whereIn('external_id', $identifiers) ->whereIn('policy_type', $types) ->get(['id', 'external_id', 'policy_type']) @@ -495,7 +495,7 @@ private function checkMissingPolicies(Tenant $tenant, Collection $policyItems): * @param Collection $policyItems * @return array{code: string, severity: string, title: string, message: string, meta: array}|null */ - private function checkStalePolicies(Tenant $tenant, Collection $policyItems): ?array + private function checkStalePolicies(ManagedEnvironment $tenant, Collection $policyItems): ?array { $itemsByPolicyId = []; @@ -530,7 +530,7 @@ private function checkStalePolicies(Tenant $tenant, Collection $policyItems): ?a } $latestVersions = PolicyVersion::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->whereIn('policy_id', array_keys($itemsByPolicyId)) ->selectRaw('policy_id, max(captured_at) as latest_captured_at') ->groupBy('policy_id') diff --git a/apps/platform/app/Services/Intune/RestoreService.php b/apps/platform/app/Services/Intune/RestoreService.php index f8b08ae8..0ba2c600 100644 --- a/apps/platform/app/Services/Intune/RestoreService.php +++ b/apps/platform/app/Services/Intune/RestoreService.php @@ -9,7 +9,7 @@ use App\Models\PolicyVersion; use App\Models\ProviderConnection; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\AssignmentRestoreService; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphContractRegistry; @@ -49,7 +49,7 @@ public function __construct( * * @param array|null $selectedItemIds */ - public function preview(Tenant $tenant, BackupSet $backupSet, ?array $selectedItemIds = null): array + public function preview(ManagedEnvironment $tenant, BackupSet $backupSet, ?array $selectedItemIds = null): array { $this->assertActiveContext($tenant, $backupSet); @@ -76,7 +76,7 @@ public function preview(Tenant $tenant, BackupSet $backupSet, ?array $selectedIt $policyPreview = $policyItems->map(function (BackupItem $item) use ($tenant, $notificationTemplateIds) { $existing = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('external_id', $item->policy_identifier) ->where('policy_type', $item->policy_type) ->first(); @@ -121,14 +121,14 @@ public function preview(Tenant $tenant, BackupSet $backupSet, ?array $selectedIt * @param array|null $selectedItemIds */ public function executeFromPolicyVersion( - Tenant $tenant, + ManagedEnvironment $tenant, PolicyVersion $version, bool $dryRun = true, ?string $actorEmail = null, ?string $actorName = null, array $groupMapping = [], ): RestoreRun { - if ($version->tenant_id !== $tenant->id) { + if ($version->managed_environment_id !== $tenant->id) { throw new \InvalidArgumentException('Policy version does not belong to the provided tenant.'); } @@ -139,7 +139,7 @@ public function executeFromPolicyVersion( } $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => sprintf( 'Policy Version Restore • %s • v%d', $policy->display_name, @@ -206,7 +206,7 @@ public function executeFromPolicyVersion( } $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_version_id' => $version->id, @@ -232,7 +232,7 @@ public function executeFromPolicyVersion( public function executeForRun( RestoreRun $restoreRun, - Tenant $tenant, + ManagedEnvironment $tenant, BackupSet $backupSet, ?string $actorEmail = null, ?string $actorName = null, @@ -240,7 +240,7 @@ public function executeForRun( ): RestoreRun { $this->assertActiveContext($tenant, $backupSet); - if ($restoreRun->tenant_id !== $tenant->id) { + if ($restoreRun->managed_environment_id !== $tenant->id) { throw new \InvalidArgumentException('Restore run does not belong to the provided tenant.'); } @@ -280,7 +280,7 @@ private function backupItemIntegrityWarning(BackupItem $item): ?string } public function execute( - Tenant $tenant, + ManagedEnvironment $tenant, BackupSet $backupSet, ?array $selectedItemIds = null, bool $dryRun = true, @@ -296,7 +296,7 @@ public function execute( $selectedItemIds = null; } - $tenantIdentifier = $tenant->tenant_id ?? $tenant->external_id; + $tenantIdentifier = $tenant->managed_environment_id ?? $tenant->external_id; $baseGraphOptions = []; if (! $dryRun) { @@ -317,7 +317,7 @@ public function execute( ]; if ($existingRun !== null) { - if ($existingRun->tenant_id !== $tenant->id) { + if ($existingRun->managed_environment_id !== $tenant->id) { throw new \InvalidArgumentException('Restore run does not belong to the provided tenant.'); } @@ -344,7 +344,7 @@ public function execute( $restoreRun = $existingRun->refresh(); } else { $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'requested_by' => $actorEmail, 'is_dry_run' => $dryRun, @@ -954,7 +954,7 @@ public function execute( $appliedPolicyId = $item->policy_identifier; $policy = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('external_id', $appliedPolicyId) ->where('policy_type', $item->policy_type) ->first(); @@ -1627,7 +1627,7 @@ private function isEmptyGuid(string $value): bool * @param array> $entries */ private function auditFoundationMapping( - Tenant $tenant, + ManagedEnvironment $tenant, RestoreRun $restoreRun, array $entries, ?string $actorEmail, @@ -1682,7 +1682,7 @@ private function auditFoundationMapping( * @param array> $outcomes */ private function auditComplianceActionMapping( - Tenant $tenant, + ManagedEnvironment $tenant, RestoreRun $restoreRun, string $policyId, string $policyType, @@ -2078,7 +2078,7 @@ private function createSettingsCatalogPolicy( * @return array */ private function prepareEndpointSecurityPolicyForCreate( - Tenant $tenant, + ManagedEnvironment $tenant, array $originalPayload, array $settings, array $graphOptions, @@ -2598,7 +2598,7 @@ private function stripOdataAndReadOnly(array $payload): array * @return array{outcomes: array>, summary: array{success:int,failed:int,skipped:int}} */ private function applyGroupPolicyDefinitionValues( - Tenant $tenant, + ManagedEnvironment $tenant, string $tenantIdentifier, string $policyId, array $definitionValues, @@ -2913,7 +2913,7 @@ private function buildScopeTagsForVersion( ]; } - private function resolveProviderConnection(Tenant $tenant, ?int $providerConnectionId = null): ProviderConnection + private function resolveProviderConnection(ManagedEnvironment $tenant, ?int $providerConnectionId = null): ProviderConnection { if ($providerConnectionId !== null) { $connection = ProviderConnection::query()->find($providerConnectionId); @@ -2955,10 +2955,10 @@ private function providerGateway(): ProviderGateway return $this->providerGateway ?? app(ProviderGateway::class); } - private function assertActiveContext(Tenant $tenant, BackupSet $backupSet): void + private function assertActiveContext(ManagedEnvironment $tenant, BackupSet $backupSet): void { if (! $tenant->isActive()) { - throw new \RuntimeException('Tenant is archived or inactive.'); + throw new \RuntimeException('ManagedEnvironment is archived or inactive.'); } if ($backupSet->trashed()) { diff --git a/apps/platform/app/Services/Intune/TenantConfigService.php b/apps/platform/app/Services/Intune/TenantConfigService.php index 25bc78ab..2fbceeec 100644 --- a/apps/platform/app/Services/Intune/TenantConfigService.php +++ b/apps/platform/app/Services/Intune/TenantConfigService.php @@ -2,7 +2,7 @@ namespace App\Services\Intune; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphErrorMapper; use App\Services\Providers\MicrosoftGraphOptionsResolver; @@ -20,7 +20,7 @@ public function __construct( /** * @return array{success:bool,error_message:?string,requires_consent:bool} */ - public function testConnectivity(Tenant $tenant): array + public function testConnectivity(ManagedEnvironment $tenant): array { try { $options = $this->graphOptions($tenant); @@ -35,7 +35,7 @@ public function testConnectivity(Tenant $tenant): array if ($options['tenant'] === null) { return [ 'success' => false, - 'error_message' => 'Tenant ID is missing', + 'error_message' => 'ManagedEnvironment ID is missing', 'requires_consent' => false, ]; } @@ -68,7 +68,7 @@ public function testConnectivity(Tenant $tenant): array /** * @return array */ - public function graphOptions(Tenant $tenant): array + public function graphOptions(ManagedEnvironment $tenant): array { return $this->graphOptionsResolver->resolveForTenant($tenant); } diff --git a/apps/platform/app/Services/Intune/TenantPermissionService.php b/apps/platform/app/Services/Intune/TenantPermissionService.php index a44420bd..21fd67b6 100644 --- a/apps/platform/app/Services/Intune/TenantPermissionService.php +++ b/apps/platform/app/Services/Intune/TenantPermissionService.php @@ -2,7 +2,7 @@ namespace App\Services\Intune; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantPermission; use App\Services\Graph\GraphClientInterface; use App\Services\Providers\MicrosoftGraphOptionsResolver; @@ -30,10 +30,10 @@ public function getRequiredPermissions(): array /** * @return array|null,last_checked_at:?\Illuminate\Support\Carbon}> */ - public function getGrantedPermissions(Tenant $tenant): array + public function getGrantedPermissions(ManagedEnvironment $tenant): array { return TenantPermission::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->get() ->keyBy('permission_key') ->map(fn (TenantPermission $permission) => [ @@ -58,7 +58,7 @@ public function getGrantedPermissions(Tenant $tenant): array * } */ public function compare( - Tenant $tenant, + ManagedEnvironment $tenant, ?array $grantedStatuses = null, bool $persist = true, bool $liveCheck = false, @@ -166,7 +166,7 @@ public function compare( $canPersist = false; } else { $hasStoredStatuses = TenantPermission::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->exists(); $canPersist = ! $hasStoredStatuses; @@ -191,7 +191,7 @@ public function compare( if ($canPersist) { TenantPermission::updateOrCreate( [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'permission_key' => $key, 'workspace_id' => $tenantWorkspaceId, ], @@ -332,7 +332,7 @@ private function configuredGrantedKeys(): array return config('intune_permissions.granted_stub', []); } - private function resolveTenantWorkspaceId(Tenant $tenant): ?int + private function resolveTenantWorkspaceId(ManagedEnvironment $tenant): ?int { $workspaceId = $tenant->getAttribute('workspace_id'); @@ -344,7 +344,7 @@ private function resolveTenantWorkspaceId(Tenant $tenant): ?int return null; } - $workspaceId = Tenant::query() + $workspaceId = ManagedEnvironment::query() ->whereKey($tenant->getKey()) ->value('workspace_id'); @@ -360,7 +360,7 @@ private function resolveTenantWorkspaceId(Tenant $tenant): ?int * * @return array|null}> */ - private function fetchLivePermissions(Tenant $tenant, ?array $graphOptions = null): array + private function fetchLivePermissions(ManagedEnvironment $tenant, ?array $graphOptions = null): array { try { $graphOptions ??= $this->graphOptionsResolver->resolveForTenant($tenant); @@ -415,7 +415,7 @@ private function fetchLivePermissions(Tenant $tenant, ?array $graphOptions = nul } catch (\Throwable $e) { // Log error but don't fail - fall back to config \Log::warning('Failed to fetch live permissions from Graph', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'error' => $e->getMessage(), ]); @@ -431,10 +431,10 @@ private function fetchLivePermissions(Tenant $tenant, ?array $graphOptions = nul } } - private function lastRefreshedAtIso(Tenant $tenant): ?string + private function lastRefreshedAtIso(ManagedEnvironment $tenant): ?string { $lastCheckedAt = TenantPermission::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->max('last_checked_at'); if ($lastCheckedAt instanceof DateTimeInterface) { diff --git a/apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php b/apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php index 3656aedc..374976a2 100644 --- a/apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php +++ b/apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php @@ -2,7 +2,7 @@ namespace App\Services\Intune; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Verification\VerificationReportOverall; use Carbon\CarbonInterface; use Illuminate\Support\Carbon; @@ -32,7 +32,7 @@ public function __construct(private readonly TenantPermissionService $permission * @param array $filters * @return ViewModel */ - public function build(Tenant $tenant, array $filters = []): array + public function build(ManagedEnvironment $tenant, array $filters = []): array { $comparison = $this->permissionService->compare( $tenant, diff --git a/apps/platform/app/Services/Intune/VersionService.php b/apps/platform/app/Services/Intune/VersionService.php index 1f34b6ec..b545b63c 100644 --- a/apps/platform/app/Services/Intune/VersionService.php +++ b/apps/platform/app/Services/Intune/VersionService.php @@ -4,7 +4,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\AssignmentFetcher; use App\Services\Graph\AssignmentFilterResolver; use App\Services\Graph\GraphException; @@ -66,7 +66,7 @@ public function captureVersion( $versionNumber = $this->nextVersionNumber($policy); $version = PolicyVersion::create([ - 'tenant_id' => $policy->tenant_id, + 'managed_environment_id' => $policy->managed_environment_id, 'policy_id' => $policy->id, 'version_number' => $versionNumber, 'policy_type' => $policy->policy_type, @@ -202,7 +202,7 @@ private function isUniqueViolation(QueryException $exception): bool } public function captureFromGraph( - Tenant $tenant, + ManagedEnvironment $tenant, Policy $policy, ?string $createdBy = null, array $metadata = [], @@ -377,7 +377,7 @@ private function extractAssignmentFilterIds(array $assignments): array * @param array $scopeTagIds * @return array{ids:array,names:array} */ - private function resolveScopeTags(Tenant $tenant, array $scopeTagIds): array + private function resolveScopeTags(ManagedEnvironment $tenant, array $scopeTagIds): array { $scopeTags = $this->scopeTagResolver->resolve($scopeTagIds, $tenant); diff --git a/apps/platform/app/Services/Inventory/DependencyExtractionService.php b/apps/platform/app/Services/Inventory/DependencyExtractionService.php index 6f7d4b61..e2f79170 100644 --- a/apps/platform/app/Services/Inventory/DependencyExtractionService.php +++ b/apps/platform/app/Services/Inventory/DependencyExtractionService.php @@ -28,7 +28,7 @@ public function extractForPolicyData(InventoryItem $item, array $policyData): ar // Prevent PostgreSQL cardinality violation on upsert by deduplicating payload rows. $edges = $edges ->unique(fn (array $e) => implode('|', [ - (string) ($e['tenant_id'] ?? ''), + (string) ($e['managed_environment_id'] ?? ''), (string) ($e['source_type'] ?? ''), (string) ($e['source_id'] ?? ''), (string) ($e['target_type'] ?? ''), @@ -48,7 +48,7 @@ public function extractForPolicyData(InventoryItem $item, array $policyData): ar RelationshipType::DependsOn->value => 7, ]; - /** @var Collection $sorted */ + /** @var Collection $sorted */ $sorted = $edges->sortBy(fn ($e) => $priorities[$e['relationship_type']] ?? 99)->values(); $limited = $sorted->take(50); @@ -71,7 +71,7 @@ public function extractForPolicyData(InventoryItem $item, array $policyData): ar if (! empty($payload)) { InventoryLink::query()->upsert( $payload, - ['tenant_id', 'source_type', 'source_id', 'target_type', 'target_id', 'relationship_type'], + ['managed_environment_id', 'source_type', 'source_id', 'target_type', 'target_id', 'relationship_type'], ['metadata', 'updated_at'] ); } @@ -119,7 +119,7 @@ private function extractAssignments(InventoryItem $item, array $policyData, arra if (is_string($filterId) && $filterId !== '') { $edges[] = [ - 'tenant_id' => (int) $item->tenant_id, + 'managed_environment_id' => (int) $item->managed_environment_id, 'source_type' => 'inventory_item', 'source_id' => (string) $item->external_id, 'target_type' => 'foundation_object', @@ -139,7 +139,7 @@ private function extractAssignments(InventoryItem $item, array $policyData, arra $relationshipType = RelationshipType::AssignedToExclude->value; } $edges[] = [ - 'tenant_id' => (int) $item->tenant_id, + 'managed_environment_id' => (int) $item->managed_environment_id, 'source_type' => 'inventory_item', 'source_id' => (string) $item->external_id, 'target_type' => 'foundation_object', @@ -189,7 +189,7 @@ private function extractScopedBy(InventoryItem $item, array $policyData): Collec foreach ($scopeTags as $tagId) { if (is_string($tagId) && $tagId !== '') { $edges[] = [ - 'tenant_id' => (int) $item->tenant_id, + 'managed_environment_id' => (int) $item->managed_environment_id, 'source_type' => 'inventory_item', 'source_id' => (string) $item->external_id, 'target_type' => 'foundation_object', diff --git a/apps/platform/app/Services/Inventory/DependencyQueryService.php b/apps/platform/app/Services/Inventory/DependencyQueryService.php index 089d0477..3c1cae76 100644 --- a/apps/platform/app/Services/Inventory/DependencyQueryService.php +++ b/apps/platform/app/Services/Inventory/DependencyQueryService.php @@ -11,7 +11,7 @@ class DependencyQueryService public function getOutboundEdges(InventoryItem $item, ?string $relationshipType = null, int $limit = 50): EloquentCollection { $query = InventoryLink::query() - ->where('tenant_id', $item->tenant_id) + ->where('managed_environment_id', $item->managed_environment_id) ->where('source_type', 'inventory_item') ->where('source_id', $item->external_id) ->orderByDesc('created_at'); @@ -26,7 +26,7 @@ public function getOutboundEdges(InventoryItem $item, ?string $relationshipType public function getInboundEdges(InventoryItem $item, ?string $relationshipType = null, int $limit = 50): EloquentCollection { $query = InventoryLink::query() - ->where('tenant_id', $item->tenant_id) + ->where('managed_environment_id', $item->managed_environment_id) ->where('target_type', 'inventory_item') ->where('target_id', $item->external_id) ->orderByDesc('created_at'); diff --git a/apps/platform/app/Services/Inventory/DependencyTargets/DependencyTargetDto.php b/apps/platform/app/Services/Inventory/DependencyTargets/DependencyTargetDto.php index 52a38ff1..ef48f080 100644 --- a/apps/platform/app/Services/Inventory/DependencyTargets/DependencyTargetDto.php +++ b/apps/platform/app/Services/Inventory/DependencyTargets/DependencyTargetDto.php @@ -3,7 +3,7 @@ namespace App\Services\Inventory\DependencyTargets; use App\Filament\Resources\InventoryItemResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; class DependencyTargetDto { @@ -69,7 +69,7 @@ public static function unresolvedFoundation(string $label, string $foundationTyp ); } - public static function resolvedFoundation(string $label, string $foundationType, string $targetId, string $displayName, ?int $inventoryItemId, Tenant $tenant): self + public static function resolvedFoundation(string $label, string $foundationType, string $targetId, string $displayName, ?int $inventoryItemId, ManagedEnvironment $tenant): self { $maskedId = static::mask($targetId); $url = $inventoryItemId ? InventoryItemResource::getUrl('view', ['record' => $inventoryItemId], panel: 'tenant', tenant: $tenant) : null; diff --git a/apps/platform/app/Services/Inventory/DependencyTargets/DependencyTargetResolver.php b/apps/platform/app/Services/Inventory/DependencyTargets/DependencyTargetResolver.php index 8acc2d62..0956f20f 100644 --- a/apps/platform/app/Services/Inventory/DependencyTargets/DependencyTargetResolver.php +++ b/apps/platform/app/Services/Inventory/DependencyTargets/DependencyTargetResolver.php @@ -3,7 +3,7 @@ namespace App\Services\Inventory\DependencyTargets; use App\Models\InventoryItem; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Arr; use Illuminate\Support\Collection; @@ -16,7 +16,7 @@ public function __construct(private readonly FoundationTypeMap $foundationTypeMa * @param Collection $edges * @return Collection> */ - public function attachRenderedTargets(Collection $edges, Tenant $tenant): Collection + public function attachRenderedTargets(Collection $edges, ManagedEnvironment $tenant): Collection { $edgeRows = $edges ->map(fn ($edge) => $edge instanceof Model ? $edge->toArray() : (array) $edge) @@ -129,7 +129,7 @@ public function attachRenderedTargets(Collection $edges, Tenant $tenant): Collec * @param array> $targetIdsByFoundationType * @return array> */ - private function resolveFoundationTargetsFromDb(Tenant $tenant, array $targetIdsByFoundationType): array + private function resolveFoundationTargetsFromDb(ManagedEnvironment $tenant, array $targetIdsByFoundationType): array { $resolvableTypes = $this->foundationTypeMap->resolvableFoundationTypes(); $policyTypeToFoundationType = $this->foundationTypeMap->policyTypeToFoundationType(); @@ -164,10 +164,10 @@ private function resolveFoundationTargetsFromDb(Tenant $tenant, array $targetIds } $items = InventoryItem::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereIn('policy_type', $policyTypes) ->whereIn('external_id', $allExternalIds) - ->get(['id', 'tenant_id', 'policy_type', 'external_id', 'display_name']); + ->get(['id', 'managed_environment_id', 'policy_type', 'external_id', 'display_name']); $resolved = []; diff --git a/apps/platform/app/Services/Inventory/InventoryMissingService.php b/apps/platform/app/Services/Inventory/InventoryMissingService.php index be223509..cb165a3c 100644 --- a/apps/platform/app/Services/Inventory/InventoryMissingService.php +++ b/apps/platform/app/Services/Inventory/InventoryMissingService.php @@ -4,7 +4,7 @@ use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\BackupScheduling\PolicyTypeResolver; use App\Support\OperationCatalog; use App\Support\OperationRunType; @@ -21,14 +21,14 @@ public function __construct( * @param array $selectionPayload * @return array{latestRun: OperationRun|null, missing: Collection, lowConfidence: bool} */ - public function missingForSelection(Tenant $tenant, array $selectionPayload): array + public function missingForSelection(ManagedEnvironment $tenant, array $selectionPayload): array { $normalized = $this->selectionHasher->normalize($selectionPayload); $normalized['policy_types'] = $this->policyTypeResolver->filterRuntime($normalized['policy_types']); $selectionHash = $this->selectionHasher->hash($normalized); $latestRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereIn('type', OperationCatalog::rawValuesForCanonical(OperationRunType::InventorySync->value)) ->where('status', 'completed') ->where('context->selection_hash', $selectionHash) @@ -45,7 +45,7 @@ public function missingForSelection(Tenant $tenant, array $selectionPayload): ar } $missingQuery = InventoryItem::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereIn('policy_type', $normalized['policy_types']) ->where(function ($query) use ($latestRun): void { $query diff --git a/apps/platform/app/Services/Inventory/InventorySyncService.php b/apps/platform/app/Services/Inventory/InventorySyncService.php index 2c034038..5fa51b63 100644 --- a/apps/platform/app/Services/Inventory/InventorySyncService.php +++ b/apps/platform/app/Services/Inventory/InventorySyncService.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\BackupScheduling\PolicyTypeResolver; use App\Services\Graph\GraphContractRegistry; use App\Services\Graph\GraphResponse; @@ -45,7 +45,7 @@ public function __construct( * * @param array $selectionPayload */ - public function syncNow(Tenant $tenant, array $selectionPayload): OperationRun + public function syncNow(ManagedEnvironment $tenant, array $selectionPayload): OperationRun { $computed = $this->normalizeAndHashSelection($selectionPayload); $normalizedSelection = $computed['selection']; @@ -53,7 +53,7 @@ public function syncNow(Tenant $tenant, array $selectionPayload): OperationRun $operationRun = OperationRun::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => null, 'initiator_name' => 'System', 'type' => OperationRunType::InventorySync->value, @@ -191,7 +191,7 @@ function (string $policyType, bool $success, ?string $errorCode, int $itemCount) * @param null|callable(string $policyType, bool $success, ?string $errorCode, int $itemCount): void $onPolicyTypeProcessed * @return array{status: string, had_errors: bool, error_codes: list, error_context: array|null, items_observed_count: int, items_upserted_count: int, errors_count: int} */ - public function executeSelection(OperationRun $operationRun, Tenant $tenant, array $selectionPayload, ?callable $onPolicyTypeProcessed = null): array + public function executeSelection(OperationRun $operationRun, ManagedEnvironment $tenant, array $selectionPayload, ?callable $onPolicyTypeProcessed = null): array { $computed = $this->normalizeAndHashSelection($selectionPayload); $normalizedSelection = $computed['selection']; @@ -260,7 +260,7 @@ public function normalizeAndHashSelection(array $selectionPayload): array * @param null|callable(string $policyType, bool $success, ?string $errorCode, int $itemCount): void $onPolicyTypeProcessed * @return array{status: string, had_errors: bool, error_codes: list, error_context: array|null, items_observed_count: int, items_upserted_count: int, errors_count: int} */ - private function executeSelectionUnderLock(OperationRun $operationRun, Tenant $tenant, array $normalizedSelection, ?callable $onPolicyTypeProcessed = null): array + private function executeSelectionUnderLock(OperationRun $operationRun, ManagedEnvironment $tenant, array $normalizedSelection, ?callable $onPolicyTypeProcessed = null): array { $observed = 0; $upserted = 0; @@ -361,7 +361,7 @@ private function executeSelectionUnderLock(OperationRun $operationRun, Tenant $t $item = InventoryItem::query()->updateOrCreate( [ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_type' => $policyType, 'external_id' => $externalId, ], @@ -664,14 +664,14 @@ private function rbacMeta(string $policyType, array $policyData): array } private function resolveFoundationPolicyAnchor( - Tenant $tenant, + ManagedEnvironment $tenant, string $foundationType, string $sourceId, ?string $platform, ?string $displayName, ): Policy { $policy = Policy::query()->firstOrNew([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => $sourceId, 'policy_type' => $foundationType, ]); @@ -696,7 +696,7 @@ private function resolveFoundationPolicyAnchor( return $policy; } - private function selectionLockKey(Tenant $tenant, string $selectionHash): string + private function selectionLockKey(ManagedEnvironment $tenant, string $selectionHash): string { return sprintf('%s:tenant:%s:selection:%s', OperationRunType::InventorySync->value, (string) $tenant->getKey(), $selectionHash); } @@ -744,7 +744,7 @@ private function listPoliciesWithRetry(string $policyType, array $options, Provi /** * @throws RuntimeException */ - private function resolveProviderConnection(Tenant $tenant): ProviderConnection + private function resolveProviderConnection(ManagedEnvironment $tenant): ProviderConnection { $resolution = $this->providerConnections->resolveDefault($tenant, 'microsoft'); diff --git a/apps/platform/app/Services/Onboarding/OnboardingLifecycleService.php b/apps/platform/app/Services/Onboarding/OnboardingLifecycleService.php index 3207449e..cfe78815 100644 --- a/apps/platform/app/Services/Onboarding/OnboardingLifecycleService.php +++ b/apps/platform/app/Services/Onboarding/OnboardingLifecycleService.php @@ -7,7 +7,7 @@ use App\Filament\Support\VerificationReportViewer; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Services\Tenants\TenantOperabilityService; use App\Support\Onboarding\OnboardingCheckpoint; @@ -113,7 +113,7 @@ public function recordCompletedCheckpointTelemetryIfNeeded(TenantOnboardingSessi } $workspaceId = (int) ($draft->workspace_id ?? 0); - $tenantId = (int) ($draft->tenant_id ?? 0); + $tenantId = (int) ($draft->managed_environment_id ?? 0); $userId = (int) ($draft->updated_by_user_id ?? 0); if ($workspaceId <= 0 || $tenantId <= 0 || $userId <= 0) { @@ -347,8 +347,8 @@ public function verificationRun(TenantOnboardingSession $draft): ?OperationRun ->whereKey($runId) ->where('workspace_id', (int) $draft->workspace_id); - if ($draft->tenant_id !== null) { - $query->where('tenant_id', (int) $draft->tenant_id); + if ($draft->managed_environment_id !== null) { + $query->where('managed_environment_id', (int) $draft->managed_environment_id); } return $query->first(); @@ -452,28 +452,28 @@ public function canResumeDraft(TenantOnboardingSession $draft): bool $tenant = $draft->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return true; } return $this->tenantOperabilityService->canResumeOnboarding($tenant); } - public function syncLinkedTenantAfterCancellation(TenantOnboardingSession $draft): ?Tenant + public function syncLinkedTenantAfterCancellation(TenantOnboardingSession $draft): ?ManagedEnvironment { $tenant = $draft->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } - if ($tenant->trashed() || $tenant->status !== Tenant::STATUS_ONBOARDING || ! $draft->isCancelled()) { + if ($tenant->trashed() || $tenant->status !== ManagedEnvironment::STATUS_ONBOARDING || ! $draft->isCancelled()) { return null; } $hasOtherResumableDrafts = TenantOnboardingSession::query() ->where('workspace_id', (int) $draft->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereKeyNot((int) $draft->getKey()) ->resumable() ->exists(); @@ -482,14 +482,14 @@ public function syncLinkedTenantAfterCancellation(TenantOnboardingSession $draft return null; } - $tenant->forceFill(['status' => Tenant::STATUS_DRAFT])->save(); + $tenant->forceFill(['status' => ManagedEnvironment::STATUS_DRAFT])->save(); return $tenant->fresh(); } private function hasTenantIdentity(TenantOnboardingSession $draft): bool { - if ($draft->tenant_id !== null) { + if ($draft->managed_environment_id !== null) { return true; } @@ -505,14 +505,14 @@ private function selectedProviderConnectionId(TenantOnboardingSession $draft): ? $providerConnectionId = $this->normalizeInteger($state['provider_connection_id'] ?? $state['selected_provider_connection_id'] ?? null); - if ($providerConnectionId === null || $draft->tenant_id === null) { + if ($providerConnectionId === null || $draft->managed_environment_id === null) { return null; } $exists = ProviderConnection::query() ->whereKey($providerConnectionId) ->where('workspace_id', (int) $draft->workspace_id) - ->where('tenant_id', (int) $draft->tenant_id) + ->where('managed_environment_id', (int) $draft->managed_environment_id) ->exists(); return $exists ? $providerConnectionId : null; diff --git a/apps/platform/app/Services/OperationRunService.php b/apps/platform/app/Services/OperationRunService.php index 892c0f79..cfb9efb0 100644 --- a/apps/platform/app/Services/OperationRunService.php +++ b/apps/platform/app/Services/OperationRunService.php @@ -3,7 +3,7 @@ namespace App\Services; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Notifications\OperationRunCompleted as OperationRunCompletedNotification; @@ -112,7 +112,7 @@ public function failStaleRunningRun( } public function ensureRun( - Tenant $tenant, + ManagedEnvironment $tenant, string $type, array $inputs, ?User $initiator = null @@ -121,7 +121,7 @@ public function ensureRun( $workspaceId = (int) ($tenant->workspace_id ?? 0); if ($workspaceId <= 0) { - throw new InvalidArgumentException('Tenant must belong to a workspace to start an operation run.'); + throw new InvalidArgumentException('ManagedEnvironment must belong to a workspace to start an operation run.'); } $hash = $this->calculateHash($tenant->id, $type, $inputs); @@ -129,7 +129,7 @@ public function ensureRun( // Idempotency Check (Fast Path) // We check specific status to match the partial unique index $existing = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('workspace_id', $workspaceId) ->where('run_identity_hash', $hash) ->whereIn('status', OperationRunStatus::values()) @@ -144,7 +144,7 @@ public function ensureRun( try { $run = OperationRun::create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $initiator?->id, 'initiator_name' => $initiator?->name ?? 'System', 'type' => $type, @@ -166,7 +166,7 @@ public function ensureRun( } $existing = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('workspace_id', $workspaceId) ->where('run_identity_hash', $hash) ->whereIn('status', [OperationRunStatus::Queued->value, OperationRunStatus::Running->value]) @@ -181,7 +181,7 @@ public function ensureRun( } public function ensureRunWithIdentity( - Tenant $tenant, + ManagedEnvironment $tenant, string $type, array $identityInputs, array $context, @@ -191,7 +191,7 @@ public function ensureRunWithIdentity( $workspaceId = (int) ($tenant->workspace_id ?? 0); if ($workspaceId <= 0) { - throw new InvalidArgumentException('Tenant must belong to a workspace to start an operation run.'); + throw new InvalidArgumentException('ManagedEnvironment must belong to a workspace to start an operation run.'); } $hash = $this->calculateHash($tenant->id, $type, $identityInputs); @@ -199,7 +199,7 @@ public function ensureRunWithIdentity( // Idempotency Check (Fast Path) // We check specific status to match the partial unique index $existing = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('workspace_id', $workspaceId) ->where('run_identity_hash', $hash) ->whereIn('status', OperationRunStatus::values()) @@ -214,7 +214,7 @@ public function ensureRunWithIdentity( try { $run = OperationRun::create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $initiator?->id, 'initiator_name' => $initiator?->name ?? 'System', 'type' => $type, @@ -236,7 +236,7 @@ public function ensureRunWithIdentity( } $existing = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('workspace_id', $workspaceId) ->where('run_identity_hash', $hash) ->whereIn('status', [OperationRunStatus::Queued->value, OperationRunStatus::Running->value]) @@ -251,7 +251,7 @@ public function ensureRunWithIdentity( } public function ensureRunWithIdentityCooldown( - Tenant $tenant, + ManagedEnvironment $tenant, string $type, array $identityInputs, array $context, @@ -279,7 +279,7 @@ public function ensureRunWithIdentityCooldown( } public function findCanonicalRunWithIdentity( - Tenant $tenant, + ManagedEnvironment $tenant, string $type, array $identityInputs, int $cooldownMinutes = 15, @@ -287,13 +287,13 @@ public function findCanonicalRunWithIdentity( $workspaceId = (int) ($tenant->workspace_id ?? 0); if ($workspaceId <= 0) { - throw new InvalidArgumentException('Tenant must belong to a workspace to resolve operation run identity.'); + throw new InvalidArgumentException('ManagedEnvironment must belong to a workspace to resolve operation run identity.'); } $hash = $this->calculateHash((int) $tenant->getKey(), $type, $identityInputs); $activeRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', $workspaceId) ->where('run_identity_hash', $hash) ->whereIn('status', [OperationRunStatus::Queued->value, OperationRunStatus::Running->value]) @@ -308,7 +308,7 @@ public function findCanonicalRunWithIdentity( $cutoff = now()->subMinutes($cooldownMinutes); return OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', $workspaceId) ->where('run_identity_hash', $hash) ->where('status', OperationRunStatus::Completed->value) @@ -320,7 +320,7 @@ public function findCanonicalRunWithIdentity( } public function ensureRunWithIdentityStrict( - Tenant $tenant, + ManagedEnvironment $tenant, string $type, array $identityInputs, array $context, @@ -330,13 +330,13 @@ public function ensureRunWithIdentityStrict( $workspaceId = (int) ($tenant->workspace_id ?? 0); if ($workspaceId <= 0) { - throw new InvalidArgumentException('Tenant must belong to a workspace to start an operation run.'); + throw new InvalidArgumentException('ManagedEnvironment must belong to a workspace to start an operation run.'); } $hash = $this->calculateHash($tenant->id, $type, $identityInputs); $existing = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('workspace_id', $workspaceId) ->where('type', $type) ->where('run_identity_hash', $hash) @@ -349,7 +349,7 @@ public function ensureRunWithIdentityStrict( try { $run = OperationRun::create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $initiator?->id, 'initiator_name' => $initiator?->name ?? 'System', 'type' => $type, @@ -368,7 +368,7 @@ public function ensureRunWithIdentityStrict( } $existing = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('workspace_id', $workspaceId) ->where('type', $type) ->where('run_identity_hash', $hash) @@ -393,7 +393,7 @@ public function ensureRunWithIdentityStrict( * @param array $extraContext */ public function enqueueBulkOperation( - Tenant $tenant, + ManagedEnvironment $tenant, string $type, array $targetScope, array $selectionIdentity, @@ -406,7 +406,7 @@ public function enqueueBulkOperation( $entraTenantId = $targetScope['entra_tenant_id'] ?? null; - if (is_string($entraTenantId) && $entraTenantId !== '' && $entraTenantId !== (string) $tenant->graphTenantId()) { + if (is_string($entraTenantId) && $entraTenantId !== '' && $entraTenantId !== $tenant->providerTenantContext()) { throw new InvalidArgumentException('Bulk enqueue target_scope entra_tenant_id must match the current tenant.'); } @@ -456,7 +456,7 @@ public function ensureWorkspaceRunWithIdentity( $existing = OperationRun::query() ->where('workspace_id', (int) $workspace->getKey()) - ->whereNull('tenant_id') + ->whereNull('managed_environment_id') ->where('run_identity_hash', $hash) ->whereIn('status', OperationRunStatus::values()) ->where('status', '!=', OperationRunStatus::Completed->value) @@ -469,7 +469,7 @@ public function ensureWorkspaceRunWithIdentity( try { return OperationRun::create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'user_id' => $initiator?->id, 'initiator_name' => $initiator?->name ?? 'System', 'type' => $type, @@ -485,7 +485,7 @@ public function ensureWorkspaceRunWithIdentity( $existing = OperationRun::query() ->where('workspace_id', (int) $workspace->getKey()) - ->whereNull('tenant_id') + ->whereNull('managed_environment_id') ->where('run_identity_hash', $hash) ->whereIn('status', [OperationRunStatus::Queued->value, OperationRunStatus::Running->value]) ->first(); @@ -1053,14 +1053,14 @@ private function recordOperationStartedTelemetry(OperationRun $run, ?User $initi return; } - if (! is_numeric($run->workspace_id) || ! is_numeric($run->tenant_id)) { + if (! is_numeric($run->workspace_id) || ! is_numeric($run->managed_environment_id)) { return; } $this->productTelemetryRecorder->record( eventName: ProductUsageEventCatalog::OPERATIONS_STARTED, workspaceId: (int) $run->workspace_id, - tenantId: (int) $run->tenant_id, + tenantId: (int) $run->managed_environment_id, userId: (int) $initiator->getKey(), subjectType: 'operation_run', subjectId: (int) $run->getKey(), diff --git a/apps/platform/app/Services/Operations/OperationLifecycleReconciler.php b/apps/platform/app/Services/Operations/OperationLifecycleReconciler.php index 257b0fbf..84ca7c38 100644 --- a/apps/platform/app/Services/Operations/OperationLifecycleReconciler.php +++ b/apps/platform/app/Services/Operations/OperationLifecycleReconciler.php @@ -57,7 +57,7 @@ public function reconcile(array $options = []): array ]) ->when( $tenantIds !== [], - fn (Builder $query): Builder => $query->whereIn('tenant_id', $tenantIds), + fn (Builder $query): Builder => $query->whereIn('managed_environment_id', $tenantIds), ) ->when( $workspaceIds !== [], diff --git a/apps/platform/app/Services/Operations/QueuedExecutionLegitimacyGate.php b/apps/platform/app/Services/Operations/QueuedExecutionLegitimacyGate.php index 43ab5459..c5fa3834 100644 --- a/apps/platform/app/Services/Operations/QueuedExecutionLegitimacyGate.php +++ b/apps/platform/app/Services/Operations/QueuedExecutionLegitimacyGate.php @@ -8,7 +8,7 @@ use App\Exceptions\Hardening\ProviderAccessHardeningRequired; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Auth\WorkspaceCapabilityResolver; @@ -47,7 +47,7 @@ public function evaluate(OperationRun $run): QueuedExecutionLegitimacyDecision $context = $this->buildContext($run); $checks = QueuedExecutionLegitimacyDecision::defaultChecks(); - if ($context->tenant instanceof Tenant) { + if ($context->tenant instanceof ManagedEnvironment) { $checks['workspace_scope'] = ((int) $context->tenant->workspace_id === $context->workspaceId) ? 'passed' : 'failed'; if ($checks['workspace_scope'] === 'failed') { @@ -55,7 +55,7 @@ public function evaluate(OperationRun $run): QueuedExecutionLegitimacyDecision } $checks['tenant_scope'] = 'passed'; - } elseif ($run->tenant_id !== null) { + } elseif ($run->managed_environment_id !== null) { $checks['tenant_scope'] = 'failed'; return QueuedExecutionLegitimacyDecision::deny($context, $checks, ExecutionDenialReasonCode::TenantMissing); @@ -68,7 +68,7 @@ public function evaluate(OperationRun $run): QueuedExecutionLegitimacyDecision return QueuedExecutionLegitimacyDecision::deny($context, $checks, ExecutionDenialReasonCode::InitiatorMissing); } - if ($context->tenant instanceof Tenant && ! $this->capabilityResolver->isMember($context->initiator, $context->tenant)) { + if ($context->tenant instanceof ManagedEnvironment && ! $this->capabilityResolver->isMember($context->initiator, $context->tenant)) { $checks['tenant_scope'] = 'failed'; return QueuedExecutionLegitimacyDecision::deny($context, $checks, ExecutionDenialReasonCode::InitiatorNotEntitled); @@ -112,7 +112,7 @@ public function evaluate(OperationRun $run): QueuedExecutionLegitimacyDecision } } - if ($context->tenant instanceof Tenant) { + if ($context->tenant instanceof ManagedEnvironment) { $operabilityQuestion = $this->questionForContext($context); $operability = $this->tenantOperabilityService->outcomeFor( tenant: $context->tenant, @@ -170,7 +170,7 @@ public function buildContext(OperationRun $run): QueuedExecutionContext providerConnectionId: $providerConnectionId, targetScope: [ 'workspace_id' => $workspaceId, - 'tenant_id' => $run->tenant_id !== null ? (int) $run->tenant_id : null, + 'managed_environment_id' => $run->managed_environment_id !== null ? (int) $run->managed_environment_id : null, 'provider_connection_id' => $providerConnectionId, ], prerequisiteClasses: $this->prerequisiteClassesFor($operationType, $providerConnectionId), @@ -194,8 +194,8 @@ private function evaluateExecutionPrerequisites(QueuedExecutionContext $context, $validProviderConnection = ProviderConnection::query() ->whereKey($context->providerConnectionId) ->when( - $context->tenant instanceof Tenant, - fn ($query) => $query->where('tenant_id', (int) $context->tenant->getKey()), + $context->tenant instanceof ManagedEnvironment, + fn ($query) => $query->where('managed_environment_id', (int) $context->tenant->getKey()), ) ->exists(); @@ -211,7 +211,7 @@ private function evaluateExecutionPrerequisites(QueuedExecutionContext $context, } } - if ($this->requiresWriteGate($context) && $context->tenant instanceof Tenant) { + if ($this->requiresWriteGate($context) && $context->tenant instanceof ManagedEnvironment) { try { $this->writeGate->evaluate($context->tenant, $context->operationType); } catch (ProviderAccessHardeningRequired $exception) { @@ -264,7 +264,7 @@ private function initiatorHasRequiredCapability(QueuedExecutionContext $context) ); } - if (! $context->tenant instanceof Tenant) { + if (! $context->tenant instanceof ManagedEnvironment) { return false; } diff --git a/apps/platform/app/Services/PermissionPosture/FindingGeneratorContract.php b/apps/platform/app/Services/PermissionPosture/FindingGeneratorContract.php index 6e97031a..dce86bc6 100644 --- a/apps/platform/app/Services/PermissionPosture/FindingGeneratorContract.php +++ b/apps/platform/app/Services/PermissionPosture/FindingGeneratorContract.php @@ -5,12 +5,12 @@ namespace App\Services\PermissionPosture; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; interface FindingGeneratorContract { /** * @param array{overall_status: string, permissions: array, status: string, ...}>, ...} $permissionComparison */ - public function generate(Tenant $tenant, array $permissionComparison, ?OperationRun $operationRun = null): PostureResult; + public function generate(ManagedEnvironment $tenant, array $permissionComparison, ?OperationRun $operationRun = null): PostureResult; } diff --git a/apps/platform/app/Services/PermissionPosture/PermissionPostureFindingGenerator.php b/apps/platform/app/Services/PermissionPosture/PermissionPostureFindingGenerator.php index 2796956f..9020568b 100644 --- a/apps/platform/app/Services/PermissionPosture/PermissionPostureFindingGenerator.php +++ b/apps/platform/app/Services/PermissionPosture/PermissionPostureFindingGenerator.php @@ -8,7 +8,7 @@ use App\Models\Finding; use App\Models\OperationRun; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Findings\FindingSlaPolicy; use App\Services\Findings\FindingWorkflowService; use App\Support\ProductTelemetry\ProductTelemetryRecorder; @@ -31,7 +31,7 @@ public function __construct( /** * @param array{overall_status: string, permissions: array, status: string, ...}>, ...} $permissionComparison */ - public function generate(Tenant $tenant, array $permissionComparison, ?OperationRun $operationRun = null): PostureResult + public function generate(ManagedEnvironment $tenant, array $permissionComparison, ?OperationRun $operationRun = null): PostureResult { $permissions = $permissionComparison['permissions'] ?? []; $permissions = is_array($permissions) ? $permissions : []; @@ -122,7 +122,7 @@ public function getAlertEvents(): array private array $alertEvents = []; private function handleMissingPermission( - Tenant $tenant, + ManagedEnvironment $tenant, string $key, string $type, array $features, @@ -134,7 +134,7 @@ private function handleMissingPermission( $severity = $this->deriveSeverity(count($features)); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->where('fingerprint', $fingerprint) ->first(); @@ -174,7 +174,7 @@ private function handleMissingPermission( $slaDays = $this->slaPolicy->daysForSeverity($severity, $tenant); Finding::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_PERMISSION_POSTURE, 'source' => 'permission_check', 'scope_key' => hash('sha256', 'permission_posture:'.$tenant->getKey()), @@ -196,7 +196,7 @@ private function handleMissingPermission( } private function handleErrorPermission( - Tenant $tenant, + ManagedEnvironment $tenant, string $key, string $type, array $features, @@ -210,7 +210,7 @@ private function handleErrorPermission( $severity = Finding::SEVERITY_LOW; $existing = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->where('fingerprint', $fingerprint) ->first(); @@ -249,7 +249,7 @@ private function handleErrorPermission( $slaDays = $this->slaPolicy->daysForSeverity($severity, $tenant); Finding::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_PERMISSION_POSTURE, 'source' => 'permission_check', 'scope_key' => hash('sha256', 'permission_posture_error:'.$tenant->getKey()), @@ -268,12 +268,12 @@ private function handleErrorPermission( ]); } - private function resolveExistingFinding(Tenant $tenant, string $key, string $reason, CarbonImmutable $observedAt): bool + private function resolveExistingFinding(ManagedEnvironment $tenant, string $key, string $reason, CarbonImmutable $observedAt): bool { $fingerprint = $this->fingerprint($tenant, $key); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->where('fingerprint', $fingerprint) ->whereIn('status', Finding::openStatusesForQuery()) @@ -297,10 +297,10 @@ private function resolveExistingFinding(Tenant $tenant, string $key, string $rea * Resolve any open permission_posture findings whose permission_key is not * in the current comparison (handles registry removals). */ - private function resolveStaleFindings(Tenant $tenant, array $processedPermissionKeys, CarbonImmutable $observedAt): int + private function resolveStaleFindings(ManagedEnvironment $tenant, array $processedPermissionKeys, CarbonImmutable $observedAt): int { $staleFindings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->whereIn('status', Finding::openStatusesForQuery()) ->get(); @@ -349,7 +349,7 @@ private function resolveObservedAt(array $comparison, ?OperationRun $operationRu return CarbonImmutable::now(); } - private function observeFinding(Finding $finding, Tenant $tenant, CarbonImmutable $observedAt, string $severity): void + private function observeFinding(Finding $finding, ManagedEnvironment $tenant, CarbonImmutable $observedAt, string $severity): void { if ($finding->first_seen_at === null) { $finding->first_seen_at = $observedAt; @@ -380,7 +380,7 @@ private function observeFinding(Finding $finding, Tenant $tenant, CarbonImmutabl * @param array> $permissions */ private function createStoredReport( - Tenant $tenant, + ManagedEnvironment $tenant, array $permissionComparison, array $permissions, int $postureScore, @@ -394,7 +394,7 @@ private function createStoredReport( } return StoredReport::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => [ 'posture_score' => $postureScore, @@ -423,7 +423,7 @@ private function recordStoredReportTelemetry(StoredReport $report, ?OperationRun $this->productTelemetryRecorder->record( eventName: ProductUsageEventCatalog::STORED_REPORT_CREATED, workspaceId: (int) $report->workspace_id, - tenantId: (int) $report->tenant_id, + tenantId: (int) $report->managed_environment_id, userId: (int) $operationRun->user_id, subjectType: 'stored_report', subjectId: (int) $report->getKey(), @@ -437,16 +437,16 @@ private function recordStoredReportTelemetry(StoredReport $report, ?OperationRun /** * @return array */ - private function buildAlertEvent(Tenant $tenant, string $key, string $type, array $features): array + private function buildAlertEvent(ManagedEnvironment $tenant, string $key, string $type, array $features): array { $event = [ 'event_type' => AlertRule::EVENT_PERMISSION_MISSING, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => $this->deriveSeverity(count($features)), 'fingerprint_key' => 'permission_missing:'.$tenant->getKey().':'.$key, 'title' => 'Missing permission: '.$key, 'body' => sprintf( - 'Tenant %s is missing %s. Blocked features: %s.', + 'ManagedEnvironment %s is missing %s. Blocked features: %s.', $tenant->name ?? (string) $tenant->getKey(), $key, implode(', ', $features) ?: 'none', @@ -488,12 +488,12 @@ private function deriveSeverity(int $featureCount): string }; } - private function fingerprint(Tenant $tenant, string $permissionKey): string + private function fingerprint(ManagedEnvironment $tenant, string $permissionKey): string { return substr(hash('sha256', 'permission_posture:'.$tenant->getKey().':'.$permissionKey), 0, 64); } - private function errorFingerprint(Tenant $tenant, string $permissionKey): string + private function errorFingerprint(ManagedEnvironment $tenant, string $permissionKey): string { return substr(hash('sha256', 'permission_posture:'.$tenant->getKey().':'.$permissionKey.':error'), 0, 64); } diff --git a/apps/platform/app/Services/PortfolioCompare/CrossTenantPromotionExecutionService.php b/apps/platform/app/Services/PortfolioCompare/CrossTenantPromotionExecutionService.php index 8e99e28d..470b5ae3 100644 --- a/apps/platform/app/Services/PortfolioCompare/CrossTenantPromotionExecutionService.php +++ b/apps/platform/app/Services/PortfolioCompare/CrossTenantPromotionExecutionService.php @@ -96,11 +96,11 @@ public function start( 'workspace_required_capability' => Capabilities::WORKSPACE_BASELINES_MANAGE, 'target_scope' => [ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $selection->targetTenant->getKey(), + 'managed_environment_id' => (int) $selection->targetTenant->getKey(), 'provider_connection_id' => $providerConnection instanceof ProviderConnection ? (int) $providerConnection->getKey() : null, 'entra_tenant_id' => $providerConnection instanceof ProviderConnection ? (string) $providerConnection->entra_tenant_id - : (string) ($selection->targetTenant->tenant_id ?? $selection->targetTenant->external_id ?? $selection->targetTenant->getKey()), + : (string) ($selection->targetTenant->managed_environment_id ?? $selection->targetTenant->external_id ?? $selection->targetTenant->getKey()), ], 'promotion_execution' => [ 'queued_at' => $now->toIso8601String(), @@ -152,7 +152,7 @@ public function start( private function defaultProviderConnection(int $tenantId): ?ProviderConnection { return ProviderConnection::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('provider', 'microsoft') ->where('is_default', true) ->orderBy('id') diff --git a/apps/platform/app/Services/PortfolioTriage/TenantTriageReviewService.php b/apps/platform/app/Services/PortfolioTriage/TenantTriageReviewService.php index e37f3ad7..091c37f7 100644 --- a/apps/platform/app/Services/PortfolioTriage/TenantTriageReviewService.php +++ b/apps/platform/app/Services/PortfolioTriage/TenantTriageReviewService.php @@ -4,7 +4,7 @@ namespace App\Services\PortfolioTriage; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; @@ -25,7 +25,7 @@ public function __construct( * @param array|null $recoveryEvidence */ public function markReviewed( - Tenant $tenant, + ManagedEnvironment $tenant, string $concernFamily, ?TenantBackupHealthAssessment $backupHealth = null, ?array $recoveryEvidence = null, @@ -45,7 +45,7 @@ public function markReviewed( * @param array|null $recoveryEvidence */ public function markFollowUpNeeded( - Tenant $tenant, + ManagedEnvironment $tenant, string $concernFamily, ?TenantBackupHealthAssessment $backupHealth = null, ?array $recoveryEvidence = null, @@ -65,7 +65,7 @@ public function markFollowUpNeeded( * @param array|null $recoveryEvidence */ private function store( - Tenant $tenant, + ManagedEnvironment $tenant, string $concernFamily, string $manualState, ?TenantBackupHealthAssessment $backupHealth, @@ -77,7 +77,7 @@ private function store( } if (! is_numeric($tenant->workspace_id) || (int) $tenant->workspace_id <= 0) { - throw new InvalidArgumentException('Tenant must belong to a workspace.'); + throw new InvalidArgumentException('ManagedEnvironment must belong to a workspace.'); } $currentConcern = $this->fingerprints->forConcernFamily($concernFamily, $backupHealth, $recoveryEvidence); @@ -110,7 +110,7 @@ private function store( return TenantTriageReview::query()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'concern_family' => $currentConcern['concern_family'], 'current_state' => $manualState, 'reviewed_at' => $now, diff --git a/apps/platform/app/Services/Providers/CredentialManager.php b/apps/platform/app/Services/Providers/CredentialManager.php index db9d2f30..b12b61e2 100644 --- a/apps/platform/app/Services/Providers/CredentialManager.php +++ b/apps/platform/app/Services/Providers/CredentialManager.php @@ -44,10 +44,10 @@ public function getClientCredentials(ProviderConnection $connection): array throw new RuntimeException('Provider credential payload is missing required keys.'); } - $tenantId = $payload['tenant_id'] ?? null; + $tenantId = $payload['managed_environment_id'] ?? null; if (is_string($tenantId) && $tenantId !== '' && $tenantId !== $connection->entra_tenant_id) { - throw new InvalidArgumentException('Provider credential tenant_id does not match the connection entra_tenant_id.'); + throw new InvalidArgumentException('Provider credential managed_environment_id does not match the connection entra_tenant_id.'); } return [ diff --git a/apps/platform/app/Services/Providers/MicrosoftGraphOptionsResolver.php b/apps/platform/app/Services/Providers/MicrosoftGraphOptionsResolver.php index c0da8067..d2fa750b 100644 --- a/apps/platform/app/Services/Providers/MicrosoftGraphOptionsResolver.php +++ b/apps/platform/app/Services/Providers/MicrosoftGraphOptionsResolver.php @@ -3,7 +3,7 @@ namespace App\Services\Providers; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Providers\ProviderReasonCodes; final class MicrosoftGraphOptionsResolver @@ -16,7 +16,7 @@ public function __construct( /** * @return array */ - public function resolveForTenant(Tenant $tenant, array $overrides = []): array + public function resolveForTenant(ManagedEnvironment $tenant, array $overrides = []): array { $resolution = $this->connections->resolveDefault($tenant, 'microsoft'); @@ -34,7 +34,7 @@ public function resolveForTenant(Tenant $tenant, array $overrides = []): array /** * @return array */ - public function resolveForConnection(Tenant $tenant, int|ProviderConnection $connection, array $overrides = []): array + public function resolveForConnection(ManagedEnvironment $tenant, int|ProviderConnection $connection, array $overrides = []): array { $providerConnection = $connection instanceof ProviderConnection ? $connection diff --git a/apps/platform/app/Services/Providers/PlatformProviderIdentityResolver.php b/apps/platform/app/Services/Providers/PlatformProviderIdentityResolver.php index 5a696eda..ec1916ef 100644 --- a/apps/platform/app/Services/Providers/PlatformProviderIdentityResolver.php +++ b/apps/platform/app/Services/Providers/PlatformProviderIdentityResolver.php @@ -20,7 +20,7 @@ public function resolve( $targetTenant = trim($tenantContext); $clientId = trim((string) config('graph.client_id')); $clientSecret = trim((string) config('graph.client_secret')); - $authorityTenant = trim((string) config('graph.tenant_id', 'organizations')); + $authorityTenant = trim((string) config('graph.managed_environment_id', 'organizations')); $redirectUri = trim((string) route('admin.consent.callback')); if ($targetTenant === '') { diff --git a/apps/platform/app/Services/Providers/ProviderConfigurationRequiredException.php b/apps/platform/app/Services/Providers/ProviderConfigurationRequiredException.php index 24ef8836..6bf51c37 100644 --- a/apps/platform/app/Services/Providers/ProviderConfigurationRequiredException.php +++ b/apps/platform/app/Services/Providers/ProviderConfigurationRequiredException.php @@ -2,7 +2,7 @@ namespace App\Services\Providers; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use RuntimeException; final class ProviderConfigurationRequiredException extends RuntimeException @@ -17,7 +17,7 @@ public function __construct( parent::__construct($message); } - public static function forTenant(Tenant $tenant, string $provider, ProviderConnectionResolution $resolution): self + public static function forTenant(ManagedEnvironment $tenant, string $provider, ProviderConnectionResolution $resolution): self { return new self( tenantId: (int) $tenant->getKey(), diff --git a/apps/platform/app/Services/Providers/ProviderConnectionClassifier.php b/apps/platform/app/Services/Providers/ProviderConnectionClassifier.php index 3d26b9d6..4dd3cf2b 100644 --- a/apps/platform/app/Services/Providers/ProviderConnectionClassifier.php +++ b/apps/platform/app/Services/Providers/ProviderConnectionClassifier.php @@ -4,7 +4,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Providers\ProviderConnectionType; final class ProviderConnectionClassifier @@ -17,7 +17,7 @@ public function classify( $tenant = $connection->tenant; $credential = $connection->credential; - $legacyIdentity = $tenant instanceof Tenant ? $tenant->legacyProviderIdentity() : ['client_id' => null, 'has_secret' => false]; + $legacyIdentity = $tenant instanceof ManagedEnvironment ? $tenant->legacyProviderIdentity() : ['client_id' => null, 'has_secret' => false]; $tenantClientId = trim((string) ($legacyIdentity['client_id'] ?? '')); $credentialClientId = $this->credentialClientId($credential); $currentConnectionType = $connection->connection_type instanceof ProviderConnectionType diff --git a/apps/platform/app/Services/Providers/ProviderConnectionResolver.php b/apps/platform/app/Services/Providers/ProviderConnectionResolver.php index 84891935..eecd73fc 100644 --- a/apps/platform/app/Services/Providers/ProviderConnectionResolver.php +++ b/apps/platform/app/Services/Providers/ProviderConnectionResolver.php @@ -3,7 +3,7 @@ namespace App\Services\Providers; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Providers\ProviderConsentStatus; use App\Support\Providers\ProviderReasonCodes; use App\Support\Providers\TargetScope\ProviderConnectionTargetScopeNormalizer; @@ -15,10 +15,10 @@ public function __construct( private readonly ProviderConnectionTargetScopeNormalizer $targetScopeNormalizer, ) {} - public function resolveDefault(Tenant $tenant, string $provider): ProviderConnectionResolution + public function resolveDefault(ManagedEnvironment $tenant, string $provider): ProviderConnectionResolution { $defaults = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', $provider) ->where('is_default', true) ->orderBy('id') @@ -45,9 +45,9 @@ public function resolveDefault(Tenant $tenant, string $provider): ProviderConnec return $this->validateConnection($tenant, $provider, $connection); } - public function validateConnection(Tenant $tenant, string $provider, ProviderConnection $connection): ProviderConnectionResolution + public function validateConnection(ManagedEnvironment $tenant, string $provider, ProviderConnection $connection): ProviderConnectionResolution { - if ((int) $connection->tenant_id !== (int) $tenant->getKey() || (string) $connection->provider !== $provider) { + if ((int) $connection->managed_environment_id !== (int) $tenant->getKey() || (string) $connection->provider !== $provider) { return ProviderConnectionResolution::blocked( ProviderReasonCodes::ProviderConnectionInvalid, 'Provider connection does not match tenant/provider scope.', diff --git a/apps/platform/app/Services/Providers/ProviderOperationStartGate.php b/apps/platform/app/Services/Providers/ProviderOperationStartGate.php index d7dcf852..45725662 100644 --- a/apps/platform/app/Services/Providers/ProviderOperationStartGate.php +++ b/apps/platform/app/Services/Providers/ProviderOperationStartGate.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Support\Auth\Capabilities; @@ -34,7 +34,7 @@ public function __construct( * @param array $extraContext */ public function start( - Tenant $tenant, + ManagedEnvironment $tenant, ?ProviderConnection $connection, string $operationType, callable $dispatcher, @@ -95,7 +95,7 @@ public function start( ->firstOrFail(); $activeRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->active() ->where('context->provider_connection_id', (int) $lockedConnection->getKey()) ->orderByDesc('id') @@ -167,7 +167,7 @@ public function start( * @param array $extraContext */ private function startBlocked( - Tenant $tenant, + ManagedEnvironment $tenant, string $operationType, string $provider, string $module, diff --git a/apps/platform/app/Services/ReviewPackService.php b/apps/platform/app/Services/ReviewPackService.php index 4e2b0d28..a5293138 100644 --- a/apps/platform/app/Services/ReviewPackService.php +++ b/apps/platform/app/Services/ReviewPackService.php @@ -10,7 +10,7 @@ use App\Models\EvidenceSnapshot; use App\Models\OperationRun; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; @@ -54,7 +54,7 @@ public function __construct( * * @param array $options */ - public function generate(Tenant $tenant, User $user, array $options = []): ReviewPack + public function generate(ManagedEnvironment $tenant, User $user, array $options = []): ReviewPack { $this->assertReviewPackGenerationAllowed($tenant); @@ -92,7 +92,7 @@ public function generate(Tenant $tenant, User $user, array $options = []): Revie } $reviewPack = ReviewPack::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'operation_run_id' => (int) $operationRun->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -143,7 +143,7 @@ public function generateFromReview(TenantReview $review, User $user, array $opti $tenant = $review->tenant; $snapshot = $review->evidenceSnapshot; - if (! $tenant instanceof Tenant || ! $snapshot instanceof EvidenceSnapshot) { + if (! $tenant instanceof ManagedEnvironment || ! $snapshot instanceof EvidenceSnapshot) { throw new \InvalidArgumentException('Review exports require an anchored evidence snapshot.'); } @@ -184,7 +184,7 @@ public function generateFromReview(TenantReview $review, User $user, array $opti } $reviewPack = ReviewPack::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'operation_run_id' => (int) $operationRun->getKey(), @@ -236,7 +236,7 @@ public function generateFromReview(TenantReview $review, User $user, array $opti * * @param array $options */ - public function computeFingerprint(Tenant $tenant, array $options): string + public function computeFingerprint(ManagedEnvironment $tenant, array $options): string { return $this->computeFingerprintForSnapshot($this->resolveSnapshot($tenant), $this->normalizeOptions($options)); } @@ -260,7 +260,7 @@ public function generateDownloadUrl(ReviewPack $pack, array $parameters = []): s /** * @return array */ - public function reviewPackGenerationDecisionForTenant(Tenant $tenant): array + public function reviewPackGenerationDecisionForTenant(ManagedEnvironment $tenant): array { $tenant->loadMissing('workspace'); $decision = $this->workspaceCommercialLifecycleResolver->actionDecision( @@ -285,7 +285,7 @@ private function recordReviewPackRequestTelemetry(ReviewPack $reviewPack, User $ $this->productTelemetryRecorder->record( eventName: ProductUsageEventCatalog::REVIEW_PACK_REQUESTED, workspaceId: (int) $reviewPack->workspace_id, - tenantId: (int) $reviewPack->tenant_id, + tenantId: (int) $reviewPack->managed_environment_id, userId: (int) $user->getKey(), subjectType: 'review_pack', subjectId: (int) $reviewPack->getKey(), @@ -301,7 +301,7 @@ private function recordReviewPackRequestTelemetry(ReviewPack $reviewPack, User $ /** * Find an existing ready, non-expired pack with the same fingerprint. */ - public function findExistingPack(Tenant $tenant, string $fingerprint): ?ReviewPack + public function findExistingPack(ManagedEnvironment $tenant, string $fingerprint): ?ReviewPack { return ReviewPack::query() ->forTenant((int) $tenant->getKey()) @@ -324,10 +324,10 @@ public function findExistingPackForReview(TenantReview $review, string $fingerpr /** * Check if a generation run is currently active for this tenant. */ - public function checkActiveRun(Tenant $tenant): bool + public function checkActiveRun(ManagedEnvironment $tenant): bool { return OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->active() ->exists(); @@ -336,7 +336,7 @@ public function checkActiveRun(Tenant $tenant): bool public function checkActiveRunForReview(TenantReview $review): bool { return OperationRun::query() - ->where('tenant_id', (int) $review->tenant_id) + ->where('managed_environment_id', (int) $review->managed_environment_id) ->where('type', OperationRunType::ReviewPackGenerate->value) ->whereJsonContains('context->tenant_review_id', (int) $review->getKey()) ->active() @@ -355,7 +355,7 @@ private function normalizeOptions(array $options): array ]; } - private function assertReviewPackGenerationAllowed(Tenant $tenant): void + private function assertReviewPackGenerationAllowed(ManagedEnvironment $tenant): void { $decision = $this->reviewPackGenerationDecisionForTenant($tenant); @@ -369,7 +369,7 @@ private function assertReviewPackGenerationAllowed(Tenant $tenant): void private function computeFingerprintForSnapshot(EvidenceSnapshot $snapshot, array $options): string { $data = [ - 'tenant_id' => (int) $snapshot->tenant_id, + 'managed_environment_id' => (int) $snapshot->managed_environment_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'evidence_fingerprint' => (string) $snapshot->fingerprint, 'include_pii' => (bool) ($options['include_pii'] ?? true), @@ -393,7 +393,7 @@ public function computeFingerprintForReview(TenantReview $review, array $options return hash('sha256', json_encode($data, JSON_THROW_ON_ERROR)); } - private function resolveSnapshot(Tenant $tenant): EvidenceSnapshot + private function resolveSnapshot(ManagedEnvironment $tenant): EvidenceSnapshot { $result = $this->snapshotResolver->resolve(new EvidenceResolutionRequest( workspaceId: (int) $tenant->workspace_id, @@ -408,10 +408,10 @@ private function resolveSnapshot(Tenant $tenant): EvidenceSnapshot return $result->snapshot; } - private function findPackForRun(Tenant $tenant, OperationRun $operationRun): ?ReviewPack + private function findPackForRun(ManagedEnvironment $tenant, OperationRun $operationRun): ?ReviewPack { return ReviewPack::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('operation_run_id', (int) $operationRun->getKey()) ->latest('id') ->first(); @@ -421,7 +421,7 @@ private function logReviewExport(TenantReview $review, User $user, ReviewPack $r { $tenant = $review->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } @@ -439,7 +439,7 @@ private function logReviewExport(TenantReview $review, User $user, ReviewPack $r actor: $user, resourceType: 'tenant_review', resourceId: (string) $review->getKey(), - targetLabel: sprintf('Tenant review #%d', (int) $review->getKey()), + targetLabel: sprintf('ManagedEnvironment review #%d', (int) $review->getKey()), operationRunId: $reviewPack->operation_run_id, tenant: $tenant, ); diff --git a/apps/platform/app/Services/Settings/SettingsResolver.php b/apps/platform/app/Services/Settings/SettingsResolver.php index 327079cb..3108f476 100644 --- a/apps/platform/app/Services/Settings/SettingsResolver.php +++ b/apps/platform/app/Services/Settings/SettingsResolver.php @@ -4,7 +4,7 @@ namespace App\Services\Settings; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantSetting; use App\Models\Workspace; use App\Models\WorkspaceSetting; @@ -24,9 +24,9 @@ public function __construct(private SettingsRegistry $registry) {} /** * @return array{domain: string, key: string, value: mixed, source: 'system_default'|'workspace_override'|'tenant_override', system_default: mixed, workspace_value: mixed, tenant_value: mixed} */ - public function resolveDetailed(Workspace $workspace, string $domain, string $key, ?Tenant $tenant = null): array + public function resolveDetailed(Workspace $workspace, string $domain, string $key, ?ManagedEnvironment $tenant = null): array { - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $this->assertTenantBelongsToWorkspace($workspace, $tenant); } @@ -39,7 +39,7 @@ public function resolveDetailed(Workspace $workspace, string $domain, string $ke $definition = $this->registry->require($domain, $key); $workspaceValue = $this->workspaceOverrideValue($workspace, $domain, $key); - $tenantValue = $tenant instanceof Tenant + $tenantValue = $tenant instanceof ManagedEnvironment ? $this->tenantOverrideValue($workspace, $tenant, $domain, $key) : null; @@ -69,7 +69,7 @@ public function resolveDetailed(Workspace $workspace, string $domain, string $ke ]; } - public function resolveValue(Workspace $workspace, string $domain, string $key, ?Tenant $tenant = null): mixed + public function resolveValue(Workspace $workspace, string $domain, string $key, ?ManagedEnvironment $tenant = null): mixed { return $this->resolveDetailed($workspace, $domain, $key, $tenant)['value']; } @@ -112,11 +112,11 @@ private function workspaceOverrideValue(Workspace $workspace, string $domain, st return $this->decodeStoredValue($setting->getAttribute('value')); } - private function tenantOverrideValue(Workspace $workspace, Tenant $tenant, string $domain, string $key): mixed + private function tenantOverrideValue(Workspace $workspace, ManagedEnvironment $tenant, string $domain, string $key): mixed { $setting = TenantSetting::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('domain', $domain) ->where('key', $key) ->first(['value']); @@ -139,14 +139,14 @@ private function decodeStoredValue(mixed $value): mixed return json_last_error() === JSON_ERROR_NONE ? $decoded : $value; } - private function assertTenantBelongsToWorkspace(Workspace $workspace, Tenant $tenant): void + private function assertTenantBelongsToWorkspace(Workspace $workspace, ManagedEnvironment $tenant): void { if ((int) $tenant->workspace_id !== (int) $workspace->getKey()) { - throw new NotFoundHttpException('Tenant is outside the selected workspace scope.'); + throw new NotFoundHttpException('ManagedEnvironment is outside the selected workspace scope.'); } } - private function cacheKey(Workspace $workspace, string $domain, string $key, ?Tenant $tenant): string + private function cacheKey(Workspace $workspace, string $domain, string $key, ?ManagedEnvironment $tenant): string { return implode(':', [ (string) $workspace->getKey(), diff --git a/apps/platform/app/Services/Settings/SettingsWriter.php b/apps/platform/app/Services/Settings/SettingsWriter.php index 2c75ba68..a63f71f6 100644 --- a/apps/platform/app/Services/Settings/SettingsWriter.php +++ b/apps/platform/app/Services/Settings/SettingsWriter.php @@ -5,7 +5,7 @@ namespace App\Services\Settings; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantSetting; use App\Models\User; use App\Models\Workspace; @@ -281,7 +281,7 @@ public function resetWorkspaceSetting(User $actor, Workspace $workspace, string ); } - public function updateTenantSetting(User $actor, Workspace $workspace, Tenant $tenant, string $domain, string $key, mixed $value): TenantSetting + public function updateTenantSetting(User $actor, Workspace $workspace, ManagedEnvironment $tenant, string $domain, string $key, mixed $value): TenantSetting { $this->authorizeManage($actor, $workspace); $this->assertTenantBelongsToWorkspace($workspace, $tenant); @@ -291,7 +291,7 @@ public function updateTenantSetting(User $actor, Workspace $workspace, Tenant $t $setting = TenantSetting::query()->updateOrCreate([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'domain' => $domain, 'key' => $key, ], [ @@ -304,7 +304,7 @@ public function updateTenantSetting(User $actor, Workspace $workspace, Tenant $t return $setting; } - public function resetTenantSetting(User $actor, Workspace $workspace, Tenant $tenant, string $domain, string $key): void + public function resetTenantSetting(User $actor, Workspace $workspace, ManagedEnvironment $tenant, string $domain, string $key): void { $this->authorizeManage($actor, $workspace); $this->assertTenantBelongsToWorkspace($workspace, $tenant); @@ -313,7 +313,7 @@ public function resetTenantSetting(User $actor, Workspace $workspace, Tenant $te TenantSetting::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('domain', $domain) ->where('key', $key) ->delete(); @@ -399,10 +399,10 @@ private function authorizeCommercialLifecycleManage(PlatformUser $actor): void } } - private function assertTenantBelongsToWorkspace(Workspace $workspace, Tenant $tenant): void + private function assertTenantBelongsToWorkspace(Workspace $workspace, ManagedEnvironment $tenant): void { if ((int) $tenant->workspace_id !== (int) $workspace->getKey()) { - throw new NotFoundHttpException('Tenant is outside the selected workspace scope.'); + throw new NotFoundHttpException('ManagedEnvironment is outside the selected workspace scope.'); } } diff --git a/apps/platform/app/Services/System/AllowedTenantUniverse.php b/apps/platform/app/Services/System/AllowedTenantUniverse.php index 3b0587c8..ac0f662e 100644 --- a/apps/platform/app/Services/System/AllowedTenantUniverse.php +++ b/apps/platform/app/Services/System/AllowedTenantUniverse.php @@ -4,7 +4,7 @@ namespace App\Services\System; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Builder; use Illuminate\Validation\ValidationException; @@ -14,35 +14,35 @@ class AllowedTenantUniverse public function query(): Builder { - return Tenant::query() - ->where('external_id', '!=', self::PLATFORM_TENANT_EXTERNAL_ID); + return ManagedEnvironment::query() + ->where('slug', '!=', self::PLATFORM_TENANT_EXTERNAL_ID); } - public function isAllowed(Tenant $tenant): bool + public function isAllowed(ManagedEnvironment $tenant): bool { return (string) $tenant->external_id !== self::PLATFORM_TENANT_EXTERNAL_ID; } - public function ensureAllowed(Tenant $tenant): void + public function ensureAllowed(ManagedEnvironment $tenant): void { if ($this->isAllowed($tenant)) { return; } throw ValidationException::withMessages([ - 'tenant_id' => 'This tenant is not eligible for System runbooks.', + 'managed_environment_id' => 'This tenant is not eligible for System runbooks.', ]); } - public function resolveAllowed(int|string|null $tenantId): ?Tenant + public function resolveAllowed(int|string|null $tenantId): ?ManagedEnvironment { if (! is_numeric($tenantId)) { return null; } - $tenant = Tenant::query()->whereKey((int) $tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey((int) $tenantId)->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -51,19 +51,19 @@ public function resolveAllowed(int|string|null $tenantId): ?Tenant return $tenant; } - public function resolveAllowedOrFail(int|string|null $tenantId): Tenant + public function resolveAllowedOrFail(int|string|null $tenantId): ManagedEnvironment { if (! is_numeric($tenantId) || (int) $tenantId <= 0) { throw ValidationException::withMessages([ - 'tenant_id' => 'Select a tenant.', + 'managed_environment_id' => 'Select a tenant.', ]); } - $tenant = Tenant::query()->whereKey((int) $tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey((int) $tenantId)->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw ValidationException::withMessages([ - 'tenant_id' => 'Select a valid tenant.', + 'managed_environment_id' => 'Select a valid tenant.', ]); } diff --git a/apps/platform/app/Services/SystemConsole/OperationRunTriageService.php b/apps/platform/app/Services/SystemConsole/OperationRunTriageService.php index 0150831e..97fac7d4 100644 --- a/apps/platform/app/Services/SystemConsole/OperationRunTriageService.php +++ b/apps/platform/app/Services/SystemConsole/OperationRunTriageService.php @@ -76,7 +76,7 @@ public function retry(OperationRun $run, PlatformUser $actor): OperationRun $retryRun = OperationRun::query()->create([ 'workspace_id' => (int) $run->workspace_id, - 'tenant_id' => $run->tenant_id !== null ? (int) $run->tenant_id : null, + 'managed_environment_id' => $run->managed_environment_id !== null ? (int) $run->managed_environment_id : null, 'user_id' => null, 'initiator_name' => $actor->name ?? 'Platform operator', 'type' => $run->canonicalOperationType(), diff --git a/apps/platform/app/Services/SystemConsole/SystemConsoleAuditLogger.php b/apps/platform/app/Services/SystemConsole/SystemConsoleAuditLogger.php index 5e617345..3ef1f064 100644 --- a/apps/platform/app/Services/SystemConsole/SystemConsoleAuditLogger.php +++ b/apps/platform/app/Services/SystemConsole/SystemConsoleAuditLogger.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Auth\BreakGlassSession; use App\Services\Intune\AuditLogger; use App\Support\Audit\AuditActorType; @@ -28,9 +28,9 @@ public function log( array $metadata = [], ?OperationRun $run = null, ): void { - $tenant = Tenant::query()->where('external_id', 'platform')->first(); + $tenant = ManagedEnvironment::query()->where('slug', 'platform')->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return; } diff --git a/apps/platform/app/Services/TenantReviews/TenantReviewFingerprint.php b/apps/platform/app/Services/TenantReviews/TenantReviewFingerprint.php index 88aa495c..d3e43e4e 100644 --- a/apps/platform/app/Services/TenantReviews/TenantReviewFingerprint.php +++ b/apps/platform/app/Services/TenantReviews/TenantReviewFingerprint.php @@ -5,17 +5,17 @@ namespace App\Services\TenantReviews; use App\Models\EvidenceSnapshot; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Support\Arr; final class TenantReviewFingerprint { - public function forSnapshot(Tenant $tenant, EvidenceSnapshot $snapshot): string + public function forSnapshot(ManagedEnvironment $tenant, EvidenceSnapshot $snapshot): string { $summary = is_array($snapshot->summary) ? $snapshot->summary : []; $payload = [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'snapshot_fingerprint' => (string) $snapshot->fingerprint, diff --git a/apps/platform/app/Services/TenantReviews/TenantReviewLifecycleService.php b/apps/platform/app/Services/TenantReviews/TenantReviewLifecycleService.php index 5ba5382f..14f8663f 100644 --- a/apps/platform/app/Services/TenantReviews/TenantReviewLifecycleService.php +++ b/apps/platform/app/Services/TenantReviews/TenantReviewLifecycleService.php @@ -6,7 +6,7 @@ use App\Models\EvidenceSnapshot; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; @@ -32,7 +32,7 @@ public function publish(TenantReview $review, User $user, string $reason): Tenan $tenant = $review->tenant; $reason = $this->validatedReason($reason, 'publish_reason'); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new InvalidArgumentException('Review tenant could not be resolved.'); } @@ -66,7 +66,7 @@ public function publish(TenantReview $review, User $user, string $reason): Tenan actor: $user, resourceType: 'tenant_review', resourceId: (string) $review->getKey(), - targetLabel: sprintf('Tenant review #%d', (int) $review->getKey()), + targetLabel: sprintf('ManagedEnvironment review #%d', (int) $review->getKey()), tenant: $tenant, ); @@ -81,7 +81,7 @@ public function archive(TenantReview $review, User $user, string $reason): Tenan $tenant = $review->tenant; $reason = $this->validatedReason($reason, 'archive_reason'); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new InvalidArgumentException('Review tenant could not be resolved.'); } @@ -110,7 +110,7 @@ public function archive(TenantReview $review, User $user, string $reason): Tenan actor: $user, resourceType: 'tenant_review', resourceId: (string) $review->getKey(), - targetLabel: sprintf('Tenant review #%d', (int) $review->getKey()), + targetLabel: sprintf('ManagedEnvironment review #%d', (int) $review->getKey()), tenant: $tenant, ); @@ -124,7 +124,7 @@ public function createNextReview(TenantReview $review, User $user, ?EvidenceSnap $review->loadMissing(['tenant', 'evidenceSnapshot']); $tenant = $review->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new InvalidArgumentException('Review tenant could not be resolved.'); } @@ -162,7 +162,7 @@ public function createNextReview(TenantReview $review, User $user, ?EvidenceSnap actor: $user, resourceType: 'tenant_review', resourceId: (string) $nextReview->getKey(), - targetLabel: sprintf('Tenant review #%d', (int) $nextReview->getKey()), + targetLabel: sprintf('ManagedEnvironment review #%d', (int) $nextReview->getKey()), tenant: $tenant, ); diff --git a/apps/platform/app/Services/TenantReviews/TenantReviewRegisterService.php b/apps/platform/app/Services/TenantReviews/TenantReviewRegisterService.php index 89096c28..1e70d629 100644 --- a/apps/platform/app/Services/TenantReviews/TenantReviewRegisterService.php +++ b/apps/platform/app/Services/TenantReviews/TenantReviewRegisterService.php @@ -4,7 +4,7 @@ namespace App\Services\TenantReviews; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Models\Workspace; @@ -17,18 +17,18 @@ final class TenantReviewRegisterService { /** - * @return array + * @return array */ public function authorizedTenants(User $user, Workspace $workspace): array { $roles = RoleCapabilityMap::rolesWithCapability(Capabilities::TENANT_REVIEW_VIEW); return $user->tenants() - ->where('tenants.workspace_id', (int) $workspace->getKey()) + ->where('managed_environments.workspace_id', (int) $workspace->getKey()) ->wherePivotIn('role', $roles) - ->orderBy('tenants.name') + ->orderBy('managed_environments.name') ->get() - ->keyBy(static fn (Tenant $tenant): int => (int) $tenant->getKey()) + ->keyBy(static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey()) ->all(); } @@ -39,7 +39,7 @@ public function query(User $user, Workspace $workspace): Builder return TenantReview::query() ->with(['tenant', 'evidenceSnapshot', 'currentExportReviewPack']) ->forWorkspace((int) $workspace->getKey()) - ->whereIn('tenant_id', $tenantIds === [] ? [-1] : $tenantIds) + ->whereIn('managed_environment_id', $tenantIds === [] ? [-1] : $tenantIds) ->latest('generated_at') ->latest('id'); } @@ -51,13 +51,13 @@ public function latestPublishedQuery(User $user, Workspace $workspace): Builder $rankedReviews = TenantReview::query() ->select([ 'tenant_reviews.id', - 'tenant_reviews.tenant_id', + 'tenant_reviews.managed_environment_id', 'tenant_reviews.published_at', 'tenant_reviews.generated_at', ]) - ->selectRaw('ROW_NUMBER() OVER (PARTITION BY tenant_id ORDER BY published_at DESC, generated_at DESC, id DESC) as rn') + ->selectRaw('ROW_NUMBER() OVER (PARTITION BY managed_environment_id ORDER BY published_at DESC, generated_at DESC, id DESC) as rn') ->forWorkspace((int) $workspace->getKey()) - ->whereIn('tenant_id', $tenantIds === [] ? [-1] : $tenantIds) + ->whereIn('managed_environment_id', $tenantIds === [] ? [-1] : $tenantIds) ->published(); $latestPublishedIds = DB::query() @@ -78,7 +78,7 @@ public function customerWorkspaceTenantQuery(User $user, Workspace $workspace): { $tenantIds = array_keys($this->authorizedTenants($user, $workspace)); - return Tenant::query() + return ManagedEnvironment::query() ->where('workspace_id', (int) $workspace->getKey()) ->whereIn('id', $tenantIds === [] ? [-1] : $tenantIds) ->whereHas('tenantReviews', fn ($query) => $query->published()) diff --git a/apps/platform/app/Services/TenantReviews/TenantReviewService.php b/apps/platform/app/Services/TenantReviews/TenantReviewService.php index e31a70b8..f90450c1 100644 --- a/apps/platform/app/Services/TenantReviews/TenantReviewService.php +++ b/apps/platform/app/Services/TenantReviews/TenantReviewService.php @@ -7,7 +7,7 @@ use App\Jobs\ComposeTenantReviewJob; use App\Models\EvidenceSnapshot; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; @@ -27,7 +27,7 @@ public function __construct( private readonly TenantReviewFingerprint $fingerprint, ) {} - public function create(Tenant $tenant, EvidenceSnapshot $snapshot, User $user): TenantReview + public function create(ManagedEnvironment $tenant, EvidenceSnapshot $snapshot, User $user): TenantReview { return $this->queueComposition( tenant: $tenant, @@ -42,7 +42,7 @@ public function refresh(TenantReview $review, User $user, ?EvidenceSnapshot $sna { $tenant = $review->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw new InvalidArgumentException('Review tenant could not be resolved.'); } @@ -84,7 +84,7 @@ public function compose(TenantReview $review): TenantReview foreach ($payload['sections'] as $section) { $review->sections()->create([ 'workspace_id' => (int) $review->workspace_id, - 'tenant_id' => (int) $review->tenant_id, + 'managed_environment_id' => (int) $review->managed_environment_id, 'section_key' => $section['section_key'], 'title' => $section['title'], 'sort_order' => $section['sort_order'], @@ -101,7 +101,7 @@ public function compose(TenantReview $review): TenantReview return $review->refresh()->load(['tenant', 'evidenceSnapshot', 'sections', 'operationRun', 'initiator', 'publisher', 'currentExportReviewPack']); } - public function resolveLatestSnapshot(Tenant $tenant): ?EvidenceSnapshot + public function resolveLatestSnapshot(ManagedEnvironment $tenant): ?EvidenceSnapshot { return EvidenceSnapshot::query() ->forTenant((int) $tenant->getKey()) @@ -111,7 +111,7 @@ public function resolveLatestSnapshot(Tenant $tenant): ?EvidenceSnapshot ->first(); } - public function activeCompositionRun(Tenant $tenant, ?EvidenceSnapshot $snapshot = null): ?OperationRun + public function activeCompositionRun(ManagedEnvironment $tenant, ?EvidenceSnapshot $snapshot = null): ?OperationRun { $snapshot ??= $this->resolveLatestSnapshot($tenant); @@ -123,7 +123,7 @@ public function activeCompositionRun(Tenant $tenant, ?EvidenceSnapshot $snapshot tenant: $tenant, type: OperationRunType::TenantReviewCompose->value, identityInputs: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'snapshot_id' => (int) $snapshot->getKey(), 'fingerprint' => $this->fingerprint->forSnapshot($tenant, $snapshot), ], @@ -131,7 +131,7 @@ public function activeCompositionRun(Tenant $tenant, ?EvidenceSnapshot $snapshot } private function queueComposition( - Tenant $tenant, + ManagedEnvironment $tenant, ?EvidenceSnapshot $snapshot, User $user, ?TenantReview $existingReview, @@ -141,7 +141,7 @@ private function queueComposition( throw new InvalidArgumentException('An eligible evidence snapshot is required.'); } - if ((int) $snapshot->tenant_id !== (int) $tenant->getKey()) { + if ((int) $snapshot->managed_environment_id !== (int) $tenant->getKey()) { throw new InvalidArgumentException('Evidence snapshot does not belong to the target tenant.'); } @@ -160,12 +160,12 @@ private function queueComposition( tenant: $tenant, type: OperationRunType::TenantReviewCompose->value, identityInputs: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'snapshot_id' => (int) $snapshot->getKey(), 'fingerprint' => $fingerprint, ], context: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'review_fingerprint' => $fingerprint, @@ -178,7 +178,7 @@ private function queueComposition( ); $review ??= TenantReview::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'operation_run_id' => (int) $operationRun->getKey(), @@ -233,7 +233,7 @@ private function queueComposition( actor: $user, resourceType: 'tenant_review', resourceId: (string) $review->getKey(), - targetLabel: sprintf('Tenant review #%d', (int) $review->getKey()), + targetLabel: sprintf('ManagedEnvironment review #%d', (int) $review->getKey()), operationRunId: (int) $operationRun->getKey(), tenant: $tenant, ); @@ -241,7 +241,7 @@ private function queueComposition( return $review->load(['tenant', 'evidenceSnapshot', 'sections', 'operationRun', 'initiator', 'publisher']); } - private function findExistingMutableReview(Tenant $tenant, string $fingerprint): ?TenantReview + private function findExistingMutableReview(ManagedEnvironment $tenant, string $fingerprint): ?TenantReview { return TenantReview::query() ->forTenant((int) $tenant->getKey()) diff --git a/apps/platform/app/Services/Tenants/TenantActionPolicySurface.php b/apps/platform/app/Services/Tenants/TenantActionPolicySurface.php index a7cd7ee0..9562d56e 100644 --- a/apps/platform/app/Services/Tenants/TenantActionPolicySurface.php +++ b/apps/platform/app/Services/Tenants/TenantActionPolicySurface.php @@ -4,7 +4,7 @@ namespace App\Services\Tenants; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Services\Onboarding\OnboardingLifecycleService; @@ -27,7 +27,7 @@ public function __construct( private readonly WorkspaceContext $workspaceContext, ) {} - public function buildContext(Tenant $tenant, TenantActionSurface $surface, ?User $user = null): TenantActionContext + public function buildContext(ManagedEnvironment $tenant, TenantActionSurface $surface, ?User $user = null): TenantActionContext { $user ??= auth()->user(); $draft = $user instanceof User ? $this->relatedOnboardingDraft($tenant, $user) : null; @@ -66,7 +66,7 @@ public function buildContext(Tenant $tenant, TenantActionSurface $surface, ?User /** * @return list */ - public function catalogForTenant(Tenant $tenant, TenantActionSurface $surface, ?User $user = null): array + public function catalogForTenant(ManagedEnvironment $tenant, TenantActionSurface $surface, ?User $user = null): array { $context = $this->buildContext($tenant, $surface, $user); $actions = [ @@ -93,12 +93,12 @@ public function catalogForTenant(Tenant $tenant, TenantActionSurface $surface, ? return array_values(array_filter($actions, static fn (mixed $action): bool => $action instanceof TenantActionDescriptor && $action->visible)); } - public function lifecycleActionForTenant(Tenant $tenant): ?TenantActionDescriptor + public function lifecycleActionForTenant(ManagedEnvironment $tenant): ?TenantActionDescriptor { return $this->lifecycleActionForContext($this->buildContext($tenant, TenantActionSurface::ContextMenu)); } - public function relatedOnboardingActionForTenant(Tenant $tenant, TenantActionSurface $surface, ?User $user = null): ?TenantActionDescriptor + public function relatedOnboardingActionForTenant(ManagedEnvironment $tenant, TenantActionSurface $surface, ?User $user = null): ?TenantActionDescriptor { return $this->relatedOnboardingActionForContext($this->buildContext($tenant, $surface, $user)); } @@ -130,7 +130,7 @@ public function onboardingEntryDescriptor(int $resumableDraftCount): TenantActio }; } - public function relatedOnboardingDraft(Tenant $tenant, ?User $user = null): ?TenantOnboardingSession + public function relatedOnboardingDraft(ManagedEnvironment $tenant, ?User $user = null): ?TenantOnboardingSession { $user ??= auth()->user(); @@ -140,7 +140,7 @@ public function relatedOnboardingDraft(Tenant $tenant, ?User $user = null): ?Ten return TenantOnboardingSession::query() ->where('workspace_id', (int) $tenant->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->orderByDesc('updated_at') ->get() ->first(fn (TenantOnboardingSession $draft): bool => Gate::forUser($user)->allows('view', $draft)); @@ -225,7 +225,7 @@ private function lifecycleActionForContext( destructive: true, requiresConfirmation: true, auditActionId: AuditActionId::TenantRestored, - successNotificationTitle: 'Tenant restored', + successNotificationTitle: 'ManagedEnvironment restored', successNotificationBody: 'The tenant is available again in normal tenant management flows and can be selected as active context.', modalHeading: 'Restore tenant', modalDescription: 'Restore this archived tenant so it can be selected again in normal tenant management flows.', @@ -250,7 +250,7 @@ private function lifecycleActionForContext( destructive: true, requiresConfirmation: true, auditActionId: AuditActionId::TenantArchived, - successNotificationTitle: 'Tenant archived', + successNotificationTitle: 'ManagedEnvironment archived', successNotificationBody: 'The tenant remains available for inspection and audit history, but it is no longer selectable as active context.', modalHeading: 'Archive tenant', modalDescription: 'Archive this tenant to retain it for inspection and audit history while removing it from active management flows.', diff --git a/apps/platform/app/Services/Tenants/TenantOperabilityService.php b/apps/platform/app/Services/Tenants/TenantOperabilityService.php index 5eb866bc..a0d34df4 100644 --- a/apps/platform/app/Services/Tenants/TenantOperabilityService.php +++ b/apps/platform/app/Services/Tenants/TenantOperabilityService.php @@ -4,7 +4,7 @@ namespace App\Services\Tenants; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Services\Auth\CapabilityResolver; @@ -25,7 +25,7 @@ public function __construct( private readonly CapabilityResolver $capabilityResolver, ) {} - public function decisionFor(Tenant $tenant): TenantOperabilityDecision + public function decisionFor(ManagedEnvironment $tenant): TenantOperabilityDecision { return TenantOperabilityDecision::fromOutcomes([ TenantOperabilityQuestion::SelectorEligibility->value => $this->evaluate( @@ -127,14 +127,14 @@ public function evaluate(TenantOperabilityContext $context, TenantOperabilityQue } public function outcomeFor( - Tenant $tenant, + ManagedEnvironment $tenant, TenantOperabilityQuestion $question, ?User $actor = null, ?int $workspaceId = null, TenantInteractionLane $lane = TenantInteractionLane::AdministrativeManagement, ?TenantOnboardingSession $onboardingDraft = null, ?string $requiredCapability = null, - ?Tenant $selectedTenant = null, + ?ManagedEnvironment $selectedTenant = null, ?string $linkedRecordType = null, ?int $linkedRecordId = null, ): TenantOperabilityOutcome { @@ -154,12 +154,12 @@ public function outcomeFor( ); } - public function lifecycleFor(Tenant $tenant): TenantLifecycle + public function lifecycleFor(ManagedEnvironment $tenant): TenantLifecycle { return $this->decisionFor($tenant)->lifecycle; } - public function canSelectAsContext(Tenant $tenant): bool + public function canSelectAsContext(ManagedEnvironment $tenant): bool { return $this->outcomeFor( tenant: $tenant, @@ -168,7 +168,7 @@ public function canSelectAsContext(Tenant $tenant): bool )->allowed; } - public function canViewTenantSurface(Tenant $tenant): bool + public function canViewTenantSurface(ManagedEnvironment $tenant): bool { return $this->outcomeFor( tenant: $tenant, @@ -177,7 +177,7 @@ public function canViewTenantSurface(Tenant $tenant): bool )->allowed; } - public function canResumeOnboarding(Tenant $tenant): bool + public function canResumeOnboarding(ManagedEnvironment $tenant): bool { return $this->outcomeFor( tenant: $tenant, @@ -186,7 +186,7 @@ public function canResumeOnboarding(Tenant $tenant): bool )->allowed; } - public function canArchive(Tenant $tenant): bool + public function canArchive(ManagedEnvironment $tenant): bool { return $this->outcomeFor( tenant: $tenant, @@ -195,7 +195,7 @@ public function canArchive(Tenant $tenant): bool )->allowed; } - public function canRestore(Tenant $tenant): bool + public function canRestore(ManagedEnvironment $tenant): bool { return $this->outcomeFor( tenant: $tenant, @@ -204,12 +204,12 @@ public function canRestore(Tenant $tenant): bool )->allowed; } - public function primaryManagementActionKey(Tenant $tenant, bool $preferOnboarding = false): ?string + public function primaryManagementActionKey(ManagedEnvironment $tenant, bool $preferOnboarding = false): ?string { return $this->decisionFor($tenant)->primaryManagementActionKey($preferOnboarding); } - public function canReferenceInWorkspaceMonitoring(Tenant $tenant): bool + public function canReferenceInWorkspaceMonitoring(ManagedEnvironment $tenant): bool { return $this->outcomeFor( tenant: $tenant, @@ -224,13 +224,13 @@ public function presentReason(TenantOperabilityOutcome $outcome): ?ReasonResolut } /** - * @param Collection $tenants - * @return Collection + * @param Collection $tenants + * @return Collection */ public function filterSelectable(Collection $tenants): Collection { return $tenants - ->filter(fn (mixed $tenant): bool => $tenant instanceof Tenant && $this->canSelectAsContext($tenant)) + ->filter(fn (mixed $tenant): bool => $tenant instanceof ManagedEnvironment && $this->canSelectAsContext($tenant)) ->values(); } @@ -240,7 +240,7 @@ public function applySelectableScope(Builder $query, ?string $table = null): Bui return $query ->whereNull("{$prefix}deleted_at") - ->where("{$prefix}status", TenantLifecycle::Active->value); + ->where("{$prefix}lifecycle_status", TenantLifecycle::Active->value); } public function applyAdministrativeDiscoverabilityScope(Builder $query, ?string $table = null): Builder @@ -250,7 +250,7 @@ public function applyAdministrativeDiscoverabilityScope(Builder $query, ?string return $query ->withTrashed() ->where(function (Builder $builder) use ($prefix): void { - $builder->whereIn("{$prefix}status", TenantLifecycle::values()) + $builder->whereIn("{$prefix}lifecycle_status", TenantLifecycle::values()) ->orWhereNotNull("{$prefix}deleted_at"); }); } diff --git a/apps/platform/app/Services/Verification/StartVerification.php b/apps/platform/app/Services/Verification/StartVerification.php index 6a13bfd9..5da9961d 100644 --- a/apps/platform/app/Services/Verification/StartVerification.php +++ b/apps/platform/app/Services/Verification/StartVerification.php @@ -7,7 +7,7 @@ use App\Jobs\ProviderConnectionHealthCheckJob; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Providers\ProviderConnectionResolver; use App\Services\Providers\ProviderIdentityResolver; @@ -34,7 +34,7 @@ public function __construct( * @param array $extraContext */ public function providerConnectionCheck( - Tenant $tenant, + ManagedEnvironment $tenant, ProviderConnection $connection, User $initiator, array $extraContext = [], @@ -53,7 +53,7 @@ public function providerConnectionCheck( * @param array $extraContext */ public function providerConnectionCheckForTenant( - Tenant $tenant, + ManagedEnvironment $tenant, User $initiator, array $extraContext = [], ): ProviderOperationStartResult { @@ -93,7 +93,7 @@ public function providerConnectionCheckForTenant( * @param array $extraContext */ public function providerConnectionCheckUsingConnection( - Tenant $tenant, + ManagedEnvironment $tenant, ProviderConnection $connection, User $initiator, array $extraContext = [], @@ -139,7 +139,7 @@ public function providerConnectionCheckUsingConnection( return $result; } - private function dispatchConnectionHealthCheck(OperationRun $run, Tenant $tenant, User $initiator): mixed + private function dispatchConnectionHealthCheck(OperationRun $run, ManagedEnvironment $tenant, User $initiator): mixed { $context = is_array($run->context ?? null) ? $run->context : []; $providerConnectionId = $context['provider_connection_id'] ?? null; diff --git a/apps/platform/app/Services/Verification/VerificationCheckAcknowledgementService.php b/apps/platform/app/Services/Verification/VerificationCheckAcknowledgementService.php index 6f140004..6d890d21 100644 --- a/apps/platform/app/Services/Verification/VerificationCheckAcknowledgementService.php +++ b/apps/platform/app/Services/Verification/VerificationCheckAcknowledgementService.php @@ -5,7 +5,7 @@ namespace App\Services\Verification; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\VerificationCheckAcknowledgement; use App\Services\Audit\WorkspaceAuditLogger; @@ -27,7 +27,7 @@ public function __construct( ) {} public function acknowledge( - Tenant $tenant, + ManagedEnvironment $tenant, OperationRun $run, string $checkKey, string $ackReason, @@ -40,7 +40,7 @@ public function acknowledge( Gate::forUser($actor)->authorize(Capabilities::TENANT_VERIFICATION_ACKNOWLEDGE, $tenant); - if ((int) $run->tenant_id !== (int) $tenant->getKey()) { + if ((int) $run->managed_environment_id !== (int) $tenant->getKey()) { throw new NotFoundHttpException; } @@ -94,7 +94,7 @@ public function acknowledge( try { $ack = VerificationCheckAcknowledgement::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'operation_run_id' => (int) $run->getKey(), 'check_key' => $checkKey, @@ -124,7 +124,7 @@ public function acknowledge( workspace: $workspace, action: AuditActionId::VerificationCheckAcknowledged->value, context: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'operation_run_id' => (int) $run->getKey(), 'report_id' => (int) $run->getKey(), 'flow' => (string) $run->type, diff --git a/apps/platform/app/Support/Ai/AiDecisionAuditMetadataFactory.php b/apps/platform/app/Support/Ai/AiDecisionAuditMetadataFactory.php index ba5ed5c3..c5d8687d 100644 --- a/apps/platform/app/Support/Ai/AiDecisionAuditMetadataFactory.php +++ b/apps/platform/app/Support/Ai/AiDecisionAuditMetadataFactory.php @@ -20,7 +20,7 @@ public function make(AiExecutionRequest $request, AiExecutionDecision $decision) 'data_classifications' => $decision->dataClassifications, 'source_family' => $decision->sourceFamily, 'workspace_id' => $request->workspace?->getKey(), - 'tenant_id' => $request->tenant?->getKey(), + 'managed_environment_id' => $request->tenant?->getKey(), 'context_fingerprint' => $this->normalizedFingerprint($request->contextFingerprint), 'matched_operational_control_scope' => $decision->matchedOperationalControlScope, ], static fn (mixed $value): bool => $value !== null); diff --git a/apps/platform/app/Support/Ai/AiExecutionRequest.php b/apps/platform/app/Support/Ai/AiExecutionRequest.php index 747c6d74..26786bf7 100644 --- a/apps/platform/app/Support/Ai/AiExecutionRequest.php +++ b/apps/platform/app/Support/Ai/AiExecutionRequest.php @@ -5,7 +5,7 @@ namespace App\Support\Ai; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; @@ -16,7 +16,7 @@ */ public function __construct( public ?Workspace $workspace, - public ?Tenant $tenant, + public ?ManagedEnvironment $tenant, public User|PlatformUser|null $actor, public string $useCaseKey, public string $requestedProviderClass, diff --git a/apps/platform/app/Support/Audit/AuditActionId.php b/apps/platform/app/Support/Audit/AuditActionId.php index 2e9b4863..730d958c 100644 --- a/apps/platform/app/Support/Audit/AuditActionId.php +++ b/apps/platform/app/Support/Audit/AuditActionId.php @@ -190,13 +190,13 @@ private static function labels(): array self::WorkspaceMembershipRoleChange->value => 'Workspace member role change', self::WorkspaceMembershipRemove->value => 'Workspace member removal', self::WorkspaceMembershipLastOwnerBlocked->value => 'Workspace last-owner protection', - self::TenantArchived->value => 'Tenant archived', - self::TenantRestored->value => 'Tenant restored', - self::TenantReturnedToDraft->value => 'Tenant returned to draft', - self::TenantMembershipAdd->value => 'Tenant member add', - self::TenantMembershipRoleChange->value => 'Tenant member role change', - self::TenantMembershipRemove->value => 'Tenant member removal', - self::TenantMembershipLastOwnerBlocked->value => 'Tenant last-owner protection', + self::TenantArchived->value => 'ManagedEnvironment archived', + self::TenantRestored->value => 'ManagedEnvironment restored', + self::TenantReturnedToDraft->value => 'ManagedEnvironment returned to draft', + self::TenantMembershipAdd->value => 'ManagedEnvironment member add', + self::TenantMembershipRoleChange->value => 'ManagedEnvironment member role change', + self::TenantMembershipRemove->value => 'ManagedEnvironment member removal', + self::TenantMembershipLastOwnerBlocked->value => 'ManagedEnvironment last-owner protection', self::PolicyProviderMissingDetected->value => 'Policy provider missing detected', self::PolicyProviderMissingCleared->value => 'Policy provider missing cleared', self::ManagedTenantOnboardingStart->value => 'Managed tenant onboarding start', @@ -262,13 +262,13 @@ private static function labels(): array self::EvidenceSnapshotRefreshed->value => 'Evidence snapshot refreshed', self::EvidenceSnapshotExpired->value => 'Evidence snapshot expired', self::EvidenceSnapshotOpened->value => 'Evidence snapshot opened', - self::TenantReviewCreated->value => 'Tenant review created', - self::TenantReviewRefreshed->value => 'Tenant review refreshed', - self::TenantReviewPublished->value => 'Tenant review published', - self::TenantReviewArchived->value => 'Tenant review archived', - self::TenantReviewOpened->value => 'Tenant review opened', - self::TenantReviewExported->value => 'Tenant review exported', - self::TenantReviewSuccessorCreated->value => 'Tenant review next cycle created', + self::TenantReviewCreated->value => 'ManagedEnvironment review created', + self::TenantReviewRefreshed->value => 'ManagedEnvironment review refreshed', + self::TenantReviewPublished->value => 'ManagedEnvironment review published', + self::TenantReviewArchived->value => 'ManagedEnvironment review archived', + self::TenantReviewOpened->value => 'ManagedEnvironment review opened', + self::TenantReviewExported->value => 'ManagedEnvironment review exported', + self::TenantReviewSuccessorCreated->value => 'ManagedEnvironment review next cycle created', self::CustomerReviewWorkspaceOpened->value => 'Customer review workspace opened', self::ReviewPackDownloaded->value => 'Review pack downloaded', self::TenantTriageReviewMarkedReviewed->value => 'Triage review marked reviewed', @@ -330,13 +330,13 @@ private static function summaries(): array self::WorkspaceMembershipRoleChange->value => 'Workspace member role changed', self::WorkspaceMembershipRemove->value => 'Workspace member removed', self::WorkspaceMembershipLastOwnerBlocked->value => 'Workspace last-owner protection triggered', - self::TenantArchived->value => 'Tenant archived', - self::TenantRestored->value => 'Tenant restored', - self::TenantReturnedToDraft->value => 'Tenant returned to draft', - self::TenantMembershipAdd->value => 'Tenant member added', - self::TenantMembershipRoleChange->value => 'Tenant member role changed', - self::TenantMembershipRemove->value => 'Tenant member removed', - self::TenantMembershipLastOwnerBlocked->value => 'Tenant last-owner protection triggered', + self::TenantArchived->value => 'ManagedEnvironment archived', + self::TenantRestored->value => 'ManagedEnvironment restored', + self::TenantReturnedToDraft->value => 'ManagedEnvironment returned to draft', + self::TenantMembershipAdd->value => 'ManagedEnvironment member added', + self::TenantMembershipRoleChange->value => 'ManagedEnvironment member role changed', + self::TenantMembershipRemove->value => 'ManagedEnvironment member removed', + self::TenantMembershipLastOwnerBlocked->value => 'ManagedEnvironment last-owner protection triggered', self::PolicyProviderMissingDetected->value => 'Policy marked provider missing', self::PolicyProviderMissingCleared->value => 'Policy provider presence restored', self::WorkspaceSettingUpdated->value => 'Workspace setting updated', @@ -372,13 +372,13 @@ private static function summaries(): array self::EvidenceSnapshotRefreshed->value => 'Evidence snapshot refreshed', self::EvidenceSnapshotExpired->value => 'Evidence snapshot expired', self::EvidenceSnapshotOpened->value => 'Evidence snapshot opened', - self::TenantReviewCreated->value => 'Tenant review created', - self::TenantReviewRefreshed->value => 'Tenant review refreshed', - self::TenantReviewPublished->value => 'Tenant review published', - self::TenantReviewArchived->value => 'Tenant review archived', - self::TenantReviewOpened->value => 'Tenant review opened', - self::TenantReviewExported->value => 'Tenant review exported', - self::TenantReviewSuccessorCreated->value => 'Tenant review next cycle created', + self::TenantReviewCreated->value => 'ManagedEnvironment review created', + self::TenantReviewRefreshed->value => 'ManagedEnvironment review refreshed', + self::TenantReviewPublished->value => 'ManagedEnvironment review published', + self::TenantReviewArchived->value => 'ManagedEnvironment review archived', + self::TenantReviewOpened->value => 'ManagedEnvironment review opened', + self::TenantReviewExported->value => 'ManagedEnvironment review exported', + self::TenantReviewSuccessorCreated->value => 'ManagedEnvironment review next cycle created', self::CustomerReviewWorkspaceOpened->value => 'Customer review workspace opened', self::ReviewPackDownloaded->value => 'Review pack downloaded', self::SupportDiagnosticsOpened->value => 'Support diagnostics opened', diff --git a/apps/platform/app/Support/Auth/Capabilities.php b/apps/platform/app/Support/Auth/Capabilities.php index 6fee6e05..1eb49347 100644 --- a/apps/platform/app/Support/Auth/Capabilities.php +++ b/apps/platform/app/Support/Auth/Capabilities.php @@ -100,7 +100,7 @@ class Capabilities // Verification public const TENANT_VERIFICATION_ACKNOWLEDGE = 'tenant_verification.acknowledge'; - // Tenant memberships + // ManagedEnvironment memberships public const TENANT_MEMBERSHIP_VIEW = 'tenant_membership.view'; public const TENANT_MEMBERSHIP_MANAGE = 'tenant_membership.manage'; @@ -145,7 +145,7 @@ class Capabilities public const REVIEW_PACK_MANAGE = 'review_pack.manage'; - // Tenant reviews + // ManagedEnvironment reviews public const TENANT_REVIEW_VIEW = 'tenant_review.view'; public const TENANT_REVIEW_MANAGE = 'tenant_review.manage'; diff --git a/apps/platform/app/Support/BackupHealth/TenantBackupHealthResolver.php b/apps/platform/app/Support/BackupHealth/TenantBackupHealthResolver.php index 92a0b777..5e83766c 100644 --- a/apps/platform/app/Support/BackupHealth/TenantBackupHealthResolver.php +++ b/apps/platform/app/Support/BackupHealth/TenantBackupHealthResolver.php @@ -6,7 +6,7 @@ use App\Models\BackupSchedule; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\BackupQuality\BackupQualityResolver; use Carbon\CarbonImmutable; use Carbon\CarbonInterface; @@ -20,9 +20,9 @@ public function __construct( private readonly BackupQualityResolver $backupQualityResolver, ) {} - public function assess(Tenant|int $tenant): TenantBackupHealthAssessment + public function assess(ManagedEnvironment|int $tenant): TenantBackupHealthAssessment { - $tenantId = $tenant instanceof Tenant + $tenantId = $tenant instanceof ManagedEnvironment ? (int) $tenant->getKey() : (int) $tenant; @@ -30,7 +30,7 @@ public function assess(Tenant|int $tenant): TenantBackupHealthAssessment } /** - * @param iterable $tenants + * @param iterable $tenants * @return array */ public function assessMany(iterable $tenants): array @@ -76,16 +76,16 @@ private function latestRelevantBackupSets(array $tenantIds): array $latestBackupSetIds = BackupSet::query() ->withTrashed() - ->whereIn('tenant_id', $tenantIds) + ->whereIn('managed_environment_id', $tenantIds) ->whereNotNull('completed_at') - ->orderBy('tenant_id') + ->orderBy('managed_environment_id') ->orderByDesc('completed_at') ->orderByDesc('id') ->get([ 'id', - 'tenant_id', + 'managed_environment_id', ]) - ->unique('tenant_id') + ->unique('managed_environment_id') ->pluck('id') ->all(); @@ -99,7 +99,7 @@ private function latestRelevantBackupSets(array $tenantIds): array ->with([ 'items' => fn ($query) => $query->select([ 'id', - 'tenant_id', + 'managed_environment_id', 'backup_set_id', 'payload', 'metadata', @@ -108,7 +108,7 @@ private function latestRelevantBackupSets(array $tenantIds): array ]) ->get([ 'id', - 'tenant_id', + 'managed_environment_id', 'workspace_id', 'name', 'status', @@ -119,7 +119,7 @@ private function latestRelevantBackupSets(array $tenantIds): array 'metadata', 'deleted_at', ]) - ->keyBy(static fn (BackupSet $backupSet): int => (int) $backupSet->tenant_id) + ->keyBy(static fn (BackupSet $backupSet): int => (int) $backupSet->managed_environment_id) ->all(); } @@ -150,20 +150,20 @@ private function scheduleFollowUpEvaluations(array $tenantIds, CarbonImmutable $ } $schedulesByTenant = BackupSchedule::query() - ->whereIn('tenant_id', $tenantIds) + ->whereIn('managed_environment_id', $tenantIds) ->where('is_enabled', true) - ->orderBy('tenant_id') + ->orderBy('managed_environment_id') ->orderBy('next_run_at') ->orderBy('id') ->get([ 'id', - 'tenant_id', + 'managed_environment_id', 'last_run_status', 'last_run_at', 'next_run_at', 'created_at', ]) - ->groupBy('tenant_id'); + ->groupBy('managed_environment_id'); $evaluations = []; @@ -354,7 +354,7 @@ private function assessmentForResolvedInputs( } /** - * @param iterable $tenants + * @param iterable $tenants * @return array */ private function normalizeTenantIds(iterable $tenants): array @@ -362,7 +362,7 @@ private function normalizeTenantIds(iterable $tenants): array $tenantIds = []; foreach ($tenants as $tenant) { - $tenantId = $tenant instanceof Tenant + $tenantId = $tenant instanceof ManagedEnvironment ? (int) $tenant->getKey() : (int) $tenant; diff --git a/apps/platform/app/Support/Baselines/BaselineCompareMatrixBuilder.php b/apps/platform/app/Support/Baselines/BaselineCompareMatrixBuilder.php index 71e124b2..bd19b69a 100644 --- a/apps/platform/app/Support/Baselines/BaselineCompareMatrixBuilder.php +++ b/apps/platform/app/Support/Baselines/BaselineCompareMatrixBuilder.php @@ -10,7 +10,7 @@ use App\Models\BaselineTenantAssignment; use App\Models\Finding; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Baselines\BaselineSnapshotTruthResolver; @@ -113,7 +113,7 @@ public function build(BaselineProfile $profile, User $user, array $filters = []) Finding::SEVERITY_CRITICAL, ]), 'tenantSortOptions' => [ - 'tenant_name' => 'Tenant name', + 'tenant_name' => 'ManagedEnvironment name', 'deviation_count' => 'Deviation count', 'freshness_urgency' => 'Freshness urgency', ], @@ -176,7 +176,7 @@ public function build(BaselineProfile $profile, User $user, array $filters = []) } $tenantIds = $visibleTenants - ->map(static fn (Tenant $tenant): int => (int) $tenant->getKey()) + ->map(static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey()) ->values() ->all(); @@ -184,14 +184,14 @@ public function build(BaselineProfile $profile, User $user, array $filters = []) profile: $profile, tenantIds: $tenantIds, workspaceId: (int) $profile->workspace_id, - )->keyBy(static fn (OperationRun $run): int => (int) $run->tenant_id); + )->keyBy(static fn (OperationRun $run): int => (int) $run->managed_environment_id); $completedRuns = OperationRun::latestBaselineCompareRunsForProfile( profile: $profile, tenantIds: $tenantIds, workspaceId: (int) $profile->workspace_id, completedOnly: true, - )->keyBy(static fn (OperationRun $run): int => (int) $run->tenant_id); + )->keyBy(static fn (OperationRun $run): int => (int) $run->managed_environment_id); $findingMap = $this->findingMap($profile, $tenantIds, $completedRuns); $rows = []; @@ -348,16 +348,16 @@ private function normalizeStringList(mixed $value): array /** * @param Collection $assignments - * @return Collection + * @return Collection */ private function visibleTenants(Collection $assignments, User $user): Collection { return $assignments - ->map(static fn (BaselineTenantAssignment $assignment): ?Tenant => $assignment->tenant) - ->filter(fn (?Tenant $tenant): bool => $tenant instanceof Tenant + ->map(static fn (BaselineTenantAssignment $assignment): ?ManagedEnvironment => $assignment->tenant) + ->filter(fn (?ManagedEnvironment $tenant): bool => $tenant instanceof ManagedEnvironment && $this->capabilityResolver->isMember($user, $tenant) && $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_VIEW)) - ->sortBy(static fn (Tenant $tenant): string => Str::lower((string) $tenant->name)) + ->sortBy(static fn (ManagedEnvironment $tenant): string => Str::lower((string) $tenant->name)) ->values(); } @@ -380,7 +380,7 @@ private function findingMap(BaselineProfile $profile, array $tenantIds, Collecti { $findings = Finding::query() ->baselineCompareForProfile($profile) - ->whereIn('tenant_id', $tenantIds) + ->whereIn('managed_environment_id', $tenantIds) ->orderByDesc('last_seen_at') ->orderByDesc('id') ->get(); @@ -392,7 +392,7 @@ private function findingMap(BaselineProfile $profile, array $tenantIds, Collecti continue; } - $tenantId = (int) $finding->tenant_id; + $tenantId = (int) $finding->managed_environment_id; $subjectKey = $this->subjectKeyForFinding($finding); if ($subjectKey === null) { @@ -449,7 +449,7 @@ private function subjectDisplayName(BaselineSnapshotItem $item): ?string private function cellFor( BaselineSnapshotItem $item, - Tenant $tenant, + ManagedEnvironment $tenant, BaselineSnapshot $referenceSnapshot, ?OperationRun $latestRun, ?OperationRun $completedRun, @@ -660,7 +660,7 @@ private function subjectSummary(array $subject, array $cells): array } /** - * @param Collection $visibleTenants + * @param Collection $visibleTenants * @param Collection $latestRuns * @param Collection $completedRuns * @param list> $rows @@ -920,7 +920,7 @@ private function compactResults(array $rows, array $tenantSummaries): array return [ 'tenantId' => $tenantId, - 'tenantName' => (string) ($tenantSummary['tenantName'] ?? 'Tenant'), + 'tenantName' => (string) ($tenantSummary['tenantName'] ?? 'ManagedEnvironment'), 'subjectKey' => (string) ($subject['subjectKey'] ?? ''), 'displayName' => $subject['displayName'] ?? $subject['subjectKey'] ?? 'Subject', 'policyType' => (string) ($subject['policyType'] ?? ''), diff --git a/apps/platform/app/Support/Baselines/BaselineCompareStats.php b/apps/platform/app/Support/Baselines/BaselineCompareStats.php index ae5c8a9b..ccf4a829 100644 --- a/apps/platform/app/Support/Baselines/BaselineCompareStats.php +++ b/apps/platform/app/Support/Baselines/BaselineCompareStats.php @@ -10,7 +10,7 @@ use App\Models\Finding; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\BaselineSnapshotTruthResolver; use App\Support\OperationCatalog; use App\Support\OperationRunStatus; @@ -89,21 +89,24 @@ private function __construct( public readonly int $highSeverityActiveFindingsCount = 0, ) {} - public static function forTenant(?Tenant $tenant): self + public static function forTenant(?ManagedEnvironment $tenant): self { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return self::empty('no_tenant', 'No tenant selected.'); } + $findingAttentionCounts = self::findingAttentionCounts($tenant); + $assignment = BaselineTenantAssignment::query() ->with('baselineProfile') - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->first(); if (! $assignment instanceof BaselineTenantAssignment) { return self::empty( 'no_assignment', 'This tenant has no baseline assignment. A workspace manager can assign a baseline profile to this tenant.', + findingAttentionCounts: $findingAttentionCounts, ); } @@ -113,6 +116,7 @@ public static function forTenant(?Tenant $tenant): self return self::empty( 'no_assignment', 'The assigned baseline profile no longer exists.', + findingAttentionCounts: $findingAttentionCounts, ); } @@ -138,6 +142,7 @@ public static function forTenant(?Tenant $tenant): self return self::empty( 'invalid_scope', 'The assigned baseline scope is invalid or no longer supported. A workspace manager must review the baseline definition.', + findingAttentionCounts: $findingAttentionCounts, ); } @@ -162,11 +167,16 @@ public static function forTenant(?Tenant $tenant): self failureReason: null, reasonCode: $snapshotReasonCode, reasonMessage: $snapshotReasonMessage, + overdueOpenFindingsCount: $findingAttentionCounts['overdue_open_findings_count'], + expiringGovernanceCount: $findingAttentionCounts['expiring_governance_count'], + lapsedGovernanceCount: $findingAttentionCounts['lapsed_governance_count'], + activeNonNewFindingsCount: $findingAttentionCounts['active_non_new_findings_count'], + highSeverityActiveFindingsCount: $findingAttentionCounts['high_severity_active_findings_count'], ); } $latestRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereIn('type', OperationCatalog::rawValuesForCanonical(OperationRunType::BaselineCompare->value)) ->latest('id') ->first(); @@ -177,7 +187,6 @@ public static function forTenant(?Tenant $tenant): self $rbacRoleDefinitionSummary = self::rbacRoleDefinitionSummaryForRun($latestRun); $evidenceGapDetails = self::evidenceGapDetailsForRun($latestRun); $baselineCompareDiagnostics = self::baselineCompareDiagnosticsForRun($latestRun); - $findingAttentionCounts = self::findingAttentionCounts($tenant); $evidenceGapSummary = is_array($evidenceGapDetails['summary'] ?? null) ? $evidenceGapDetails['summary'] : []; $evidenceGapStructuralCount = is_numeric($evidenceGapSummary['structural_count'] ?? null) ? (int) $evidenceGapSummary['structural_count'] @@ -287,7 +296,7 @@ public static function forTenant(?Tenant $tenant): self // Single grouped query instead of 4 separate COUNT queries $severityRows = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) @@ -421,14 +430,14 @@ public static function forTenant(?Tenant $tenant): self /** * Create a DTO for widget consumption (only open/new findings). */ - public static function forWidget(?Tenant $tenant): self + public static function forWidget(?ManagedEnvironment $tenant): self { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return self::empty('no_tenant', null); } $assignment = BaselineTenantAssignment::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->with('baselineProfile') ->first(); @@ -445,7 +454,7 @@ public static function forWidget(?Tenant $tenant): self $scopeKey = 'baseline_profile:'.$profile->getKey(); $severityRows = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) @@ -457,7 +466,7 @@ public static function forWidget(?Tenant $tenant): self $totalFindings = (int) $severityRows->sum(); $latestRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereIn('type', OperationCatalog::rawValuesForCanonical(OperationRunType::BaselineCompare->value)) ->where('context->baseline_profile_id', (string) $profile->getKey()) ->whereNotNull('completed_at') @@ -490,7 +499,7 @@ public static function forWidget(?Tenant $tenant): self /** * @return array{policy_count: int, subject_count: int} */ - private static function duplicateNameStats(Tenant $tenant, BaselineScope $effectiveScope): array + private static function duplicateNameStats(ManagedEnvironment $tenant, BaselineScope $effectiveScope): array { $policyTypes = $effectiveScope->allTypes(); @@ -510,7 +519,7 @@ private static function duplicateNameStats(Tenant $tenant, BaselineScope $effect $countsByKey = []; $query = InventoryItem::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereIn('policy_type', $policyTypes) ->whereNotNull('display_name') ->select(['id', 'policy_type', 'display_name']); @@ -568,10 +577,10 @@ private static function duplicateNameStats(Tenant $tenant, BaselineScope $effect return $stats; } - private static function latestInventorySyncRunId(Tenant $tenant): ?int + private static function latestInventorySyncRunId(ManagedEnvironment $tenant): ?int { $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::InventorySync->value) ->where('status', OperationRunStatus::Completed->value) ->orderByDesc('completed_at') @@ -757,19 +766,19 @@ private static function rbacRoleDefinitionSummaryForRun(?OperationRun $run): ?ar * high_severity_active_findings_count: int * } */ - private static function findingAttentionCounts(Tenant $tenant): array + private static function findingAttentionCounts(ManagedEnvironment $tenant): array { $tenantId = (int) $tenant->getKey(); $overdueOpenFindingsCount = Finding::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->whereIn('status', Finding::openStatusesForQuery()) ->whereNotNull('due_at') ->where('due_at', '<', now()) ->count(); $expiringGovernanceCount = Finding::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('status', Finding::STATUS_RISK_ACCEPTED) ->whereHas('findingException', function ($query): void { $query->where('current_validity_state', \App\Models\FindingException::VALIDITY_EXPIRING); @@ -777,7 +786,7 @@ private static function findingAttentionCounts(Tenant $tenant): array ->count(); $lapsedGovernanceCount = Finding::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('status', Finding::STATUS_RISK_ACCEPTED) ->where(function ($query): void { $query @@ -794,7 +803,7 @@ private static function findingAttentionCounts(Tenant $tenant): array ->count(); $activeNonNewFindingsCount = Finding::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->whereIn('status', [ Finding::STATUS_TRIAGED, Finding::STATUS_IN_PROGRESS, @@ -803,7 +812,7 @@ private static function findingAttentionCounts(Tenant $tenant): array ->count(); $highSeverityActiveFindingsCount = Finding::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->whereIn('status', Finding::openStatusesForQuery()) ->whereIn('severity', [ Finding::SEVERITY_HIGH, @@ -836,7 +845,7 @@ public function summaryAssessment(): BaselineCompareSummaryAssessment return $assessor->assess($this); } - public function toTenantGovernanceAggregate(Tenant $tenant): TenantGovernanceAggregate + public function toTenantGovernanceAggregate(ManagedEnvironment $tenant): TenantGovernanceAggregate { $summaryAssessment = $this->summaryAssessment(); @@ -889,6 +898,7 @@ private static function empty( ?int $profileId = null, ?int $duplicateNamePoliciesCount = null, ?int $duplicateNameSubjectsCount = null, + array $findingAttentionCounts = [], ): self { return new self( state: $state, @@ -904,6 +914,11 @@ private static function empty( lastComparedHuman: null, lastComparedIso: null, failureReason: null, + overdueOpenFindingsCount: (int) ($findingAttentionCounts['overdue_open_findings_count'] ?? 0), + expiringGovernanceCount: (int) ($findingAttentionCounts['expiring_governance_count'] ?? 0), + lapsedGovernanceCount: (int) ($findingAttentionCounts['lapsed_governance_count'] ?? 0), + activeNonNewFindingsCount: (int) ($findingAttentionCounts['active_non_new_findings_count'] ?? 0), + highSeverityActiveFindingsCount: (int) ($findingAttentionCounts['high_severity_active_findings_count'] ?? 0), ); } diff --git a/apps/platform/app/Support/Baselines/Compare/CompareOrchestrationContext.php b/apps/platform/app/Support/Baselines/Compare/CompareOrchestrationContext.php index e58ef552..b8853529 100644 --- a/apps/platform/app/Support/Baselines/Compare/CompareOrchestrationContext.php +++ b/apps/platform/app/Support/Baselines/Compare/CompareOrchestrationContext.php @@ -48,7 +48,7 @@ public function inventorySyncRunId(): ?int /** * @return array{ * workspace_id: int, - * tenant_id: int, + * managed_environment_id: int, * baseline_profile_id: int, * baseline_snapshot_id: int, * operation_run_id: int, @@ -69,7 +69,7 @@ public function toArray(): array { return [ 'workspace_id' => $this->workspaceId, - 'tenant_id' => $this->tenantId, + 'managed_environment_id' => $this->tenantId, 'baseline_profile_id' => $this->baselineProfileId, 'baseline_snapshot_id' => $this->baselineSnapshotId, 'operation_run_id' => $this->operationRunId, diff --git a/apps/platform/app/Support/Baselines/Compare/CompareStrategy.php b/apps/platform/app/Support/Baselines/Compare/CompareStrategy.php index 4196b733..3a0abda3 100644 --- a/apps/platform/app/Support/Baselines/Compare/CompareStrategy.php +++ b/apps/platform/app/Support/Baselines/Compare/CompareStrategy.php @@ -4,7 +4,7 @@ namespace App\Support\Baselines\Compare; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\Evidence\ResolvedEvidence; interface CompareStrategy @@ -25,7 +25,7 @@ public function capabilities(): array; */ public function compare( CompareOrchestrationContext $context, - Tenant $tenant, + ManagedEnvironment $tenant, array $baselineItems, array $currentItems, array $resolvedCurrentEvidence, diff --git a/apps/platform/app/Support/Baselines/Compare/IntuneCompareStrategy.php b/apps/platform/app/Support/Baselines/Compare/IntuneCompareStrategy.php index ff2f1b29..c70ab151 100644 --- a/apps/platform/app/Support/Baselines/Compare/IntuneCompareStrategy.php +++ b/apps/platform/app/Support/Baselines/Compare/IntuneCompareStrategy.php @@ -6,7 +6,7 @@ use App\Models\Finding; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\Evidence\BaselinePolicyVersionResolver; use App\Services\Baselines\Evidence\ContentEvidenceProvider; use App\Services\Baselines\Evidence\EvidenceProvenance; @@ -65,7 +65,7 @@ public function capabilities(): array public function compare( CompareOrchestrationContext $context, - Tenant $tenant, + ManagedEnvironment $tenant, array $baselineItems, array $currentItems, array $resolvedCurrentEvidence, @@ -622,7 +622,7 @@ private function operatorLabel(?array $baselineItem, ?array $currentItem): strin return is_string($displayName) && trim($displayName) !== '' ? trim($displayName) : 'Unknown subject'; } - private function effectiveBaselineHash(Tenant $tenant, array $baselineItem, ?int $baselinePolicyVersionId): string + private function effectiveBaselineHash(ManagedEnvironment $tenant, array $baselineItem, ?int $baselinePolicyVersionId): string { $storedHash = (string) ($baselineItem['baseline_hash'] ?? ''); @@ -631,7 +631,7 @@ private function effectiveBaselineHash(Tenant $tenant, array $baselineItem, ?int } $baselineVersion = PolicyVersion::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->find($baselinePolicyVersionId); if (! $baselineVersion instanceof PolicyVersion) { @@ -644,7 +644,7 @@ private function effectiveBaselineHash(Tenant $tenant, array $baselineItem, ?int )->hash; } - private function resolveBaselinePolicyVersionId(Tenant $tenant, array $baselineItem, array $baselineProvenance): ?int + private function resolveBaselinePolicyVersionId(ManagedEnvironment $tenant, array $baselineItem, array $baselineProvenance): ?int { $metaJsonb = is_array($baselineItem['meta_jsonb'] ?? null) ? $baselineItem['meta_jsonb'] : []; $versionReferenceId = data_get($metaJsonb, 'version_reference.policy_version_id'); @@ -682,17 +682,17 @@ private function currentPolicyVersionIdFromEvidence(ResolvedEvidence $evidence): return is_numeric($policyVersionId) ? (int) $policyVersionId : null; } - private function selectSummaryKind(Tenant $tenant, string $policyType, ?int $baselinePolicyVersionId, ?int $currentPolicyVersionId): string + private function selectSummaryKind(ManagedEnvironment $tenant, string $policyType, ?int $baselinePolicyVersionId, ?int $currentPolicyVersionId): string { if ($baselinePolicyVersionId === null || $currentPolicyVersionId === null) { return 'policy_snapshot'; } $baselineVersion = PolicyVersion::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->find($baselinePolicyVersionId); $currentVersion = PolicyVersion::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->find($currentPolicyVersionId); if (! $baselineVersion instanceof PolicyVersion || ! $currentVersion instanceof PolicyVersion) { @@ -827,7 +827,7 @@ private function buildDriftEvidenceContract( } private function buildRoleDefinitionEvidencePayload( - Tenant $tenant, + ManagedEnvironment $tenant, ?int $baselinePolicyVersionId, ?int $currentPolicyVersionId, array $baselineMeta, @@ -885,14 +885,14 @@ private function buildRoleDefinitionEvidencePayload( ]; } - private function resolveRoleDefinitionVersion(Tenant $tenant, ?int $policyVersionId): ?PolicyVersion + private function resolveRoleDefinitionVersion(ManagedEnvironment $tenant, ?int $policyVersionId): ?PolicyVersion { if ($policyVersionId === null) { return null; } return PolicyVersion::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->find($policyVersionId); } @@ -957,7 +957,7 @@ private function fidelityFromPolicyVersionRefs(?int $baselinePolicyVersionId, ?i return 'meta'; } - private function resolveRoleDefinitionDiff(Tenant $tenant, int $baselinePolicyVersionId, int $currentPolicyVersionId): ?array + private function resolveRoleDefinitionDiff(ManagedEnvironment $tenant, int $baselinePolicyVersionId, int $currentPolicyVersionId): ?array { $baselineVersion = $this->resolveRoleDefinitionVersion($tenant, $baselinePolicyVersionId); $currentVersion = $this->resolveRoleDefinitionVersion($tenant, $currentPolicyVersionId); diff --git a/apps/platform/app/Support/Baselines/TenantGovernanceAggregate.php b/apps/platform/app/Support/Baselines/TenantGovernanceAggregate.php index 67f398d0..26d443dc 100644 --- a/apps/platform/app/Support/Baselines/TenantGovernanceAggregate.php +++ b/apps/platform/app/Support/Baselines/TenantGovernanceAggregate.php @@ -32,23 +32,23 @@ public function __construct( public BaselineCompareSummaryAssessment $summaryAssessment, ) { if ($this->tenantId <= 0) { - throw new InvalidArgumentException('Tenant governance aggregates require a positive tenant id.'); + throw new InvalidArgumentException('ManagedEnvironment governance aggregates require a positive tenant id.'); } if ($this->workspaceId <= 0) { - throw new InvalidArgumentException('Tenant governance aggregates require a positive workspace id.'); + throw new InvalidArgumentException('ManagedEnvironment governance aggregates require a positive workspace id.'); } if (trim($this->compareState) === '') { - throw new InvalidArgumentException('Tenant governance aggregates require a compare state.'); + throw new InvalidArgumentException('ManagedEnvironment governance aggregates require a compare state.'); } if (trim($this->headline) === '') { - throw new InvalidArgumentException('Tenant governance aggregates require a headline.'); + throw new InvalidArgumentException('ManagedEnvironment governance aggregates require a headline.'); } if (trim($this->nextActionLabel) === '') { - throw new InvalidArgumentException('Tenant governance aggregates require a next-action label.'); + throw new InvalidArgumentException('ManagedEnvironment governance aggregates require a next-action label.'); } if (! in_array($this->nextActionTarget, [ @@ -57,7 +57,7 @@ public function __construct( BaselineCompareSummaryAssessment::NEXT_TARGET_RUN, BaselineCompareSummaryAssessment::NEXT_TARGET_NONE, ], true)) { - throw new InvalidArgumentException('Tenant governance aggregates require a supported next-action target.'); + throw new InvalidArgumentException('ManagedEnvironment governance aggregates require a supported next-action target.'); } } diff --git a/apps/platform/app/Support/Baselines/TenantGovernanceAggregateResolver.php b/apps/platform/app/Support/Baselines/TenantGovernanceAggregateResolver.php index 80265e0d..f524790f 100644 --- a/apps/platform/app/Support/Baselines/TenantGovernanceAggregateResolver.php +++ b/apps/platform/app/Support/Baselines/TenantGovernanceAggregateResolver.php @@ -4,7 +4,7 @@ namespace App\Support\Baselines; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Ui\DerivedState\DerivedStateFamily; use App\Support\Ui\DerivedState\DerivedStateKey; use App\Support\Ui\DerivedState\RequestScopedDerivedStateStore; @@ -17,9 +17,9 @@ public function __construct( private readonly RequestScopedDerivedStateStore $derivedStateStore, ) {} - public function forTenant(?Tenant $tenant, bool $fresh = false): ?TenantGovernanceAggregate + public function forTenant(?ManagedEnvironment $tenant, bool $fresh = false): ?TenantGovernanceAggregate { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -31,9 +31,9 @@ public function forTenant(?Tenant $tenant, bool $fresh = false): ?TenantGovernan ); } - public function fromStats(?Tenant $tenant, BaselineCompareStats $stats, bool $fresh = false): ?TenantGovernanceAggregate + public function fromStats(?ManagedEnvironment $tenant, BaselineCompareStats $stats, bool $fresh = false): ?TenantGovernanceAggregate { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -44,7 +44,7 @@ public function fromStats(?Tenant $tenant, BaselineCompareStats $stats, bool $fr ); } - private function resolveAggregate(Tenant $tenant, callable $resolver, bool $fresh = false): TenantGovernanceAggregate + private function resolveAggregate(ManagedEnvironment $tenant, callable $resolver, bool $fresh = false): TenantGovernanceAggregate { $key = DerivedStateKey::fromModel( DerivedStateFamily::TenantGovernanceAggregate, diff --git a/apps/platform/app/Support/Concerns/DerivesWorkspaceIdFromTenant.php b/apps/platform/app/Support/Concerns/DerivesWorkspaceIdFromTenant.php index b19a7e1e..d5789fe1 100644 --- a/apps/platform/app/Support/Concerns/DerivesWorkspaceIdFromTenant.php +++ b/apps/platform/app/Support/Concerns/DerivesWorkspaceIdFromTenant.php @@ -4,7 +4,7 @@ namespace App\Support\Concerns; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\WorkspaceIsolation\WorkspaceIsolationViolation; use Illuminate\Database\Eloquent\Model; @@ -60,7 +60,7 @@ class_basename($model), private static function resolveTenantId(Model $model): int { - $tenantId = $model->getAttribute('tenant_id'); + $tenantId = $model->getAttribute('managed_environment_id'); if (! is_numeric($tenantId)) { throw WorkspaceIsolationViolation::missingTenantId(class_basename($model)); @@ -71,11 +71,11 @@ private static function resolveTenantId(Model $model): int private static function ensureTenantIdIsImmutable(Model $model, int $tenantId): void { - if (! $model->exists || ! $model->isDirty('tenant_id')) { + if (! $model->exists || ! $model->isDirty('managed_environment_id')) { return; } - $originalTenantId = $model->getOriginal('tenant_id'); + $originalTenantId = $model->getOriginal('managed_environment_id'); if (! is_numeric($originalTenantId)) { return; @@ -98,11 +98,11 @@ private static function resolveTenantWorkspaceId(Model $model, int $tenantId): i { $tenant = $model->relationLoaded('tenant') ? $model->getRelation('tenant') : null; - if (! $tenant instanceof Tenant || (int) $tenant->getKey() !== $tenantId) { - $tenant = Tenant::query()->withTrashed()->find($tenantId); + if (! $tenant instanceof ManagedEnvironment || (int) $tenant->getKey() !== $tenantId) { + $tenant = ManagedEnvironment::query()->withTrashed()->find($tenantId); } - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw WorkspaceIsolationViolation::tenantNotFound(class_basename($model), $tenantId); } diff --git a/apps/platform/app/Support/Concerns/DerivesWorkspaceIdFromTenantWhenPresent.php b/apps/platform/app/Support/Concerns/DerivesWorkspaceIdFromTenantWhenPresent.php index 378fb67a..5e4bc1bc 100644 --- a/apps/platform/app/Support/Concerns/DerivesWorkspaceIdFromTenantWhenPresent.php +++ b/apps/platform/app/Support/Concerns/DerivesWorkspaceIdFromTenantWhenPresent.php @@ -4,16 +4,16 @@ namespace App\Support\Concerns; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\WorkspaceIsolation\WorkspaceIsolationViolation; use Illuminate\Database\Eloquent\Model; /** - * Like DerivesWorkspaceIdFromTenant, but allows tenant_id to be null. + * Like DerivesWorkspaceIdFromTenant, but allows managed_environment_id to be null. * - * When tenant_id IS present the trait enforces the same workspace-derivation + * When managed_environment_id IS present the trait enforces the same workspace-derivation * and immutability rules as DerivesWorkspaceIdFromTenant. - * When tenant_id IS NULL the caller MUST supply workspace_id explicitly. + * When managed_environment_id IS NULL the caller MUST supply workspace_id explicitly. */ trait DerivesWorkspaceIdFromTenantWhenPresent { @@ -30,7 +30,7 @@ public static function bootDerivesWorkspaceIdFromTenantWhenPresent(): void private static function enforceWorkspaceBindingOptional(Model $model): void { - $tenantId = $model->getAttribute('tenant_id'); + $tenantId = $model->getAttribute('managed_environment_id'); if ($tenantId === null || $tenantId === '') { self::requireExplicitWorkspaceId($model); @@ -90,11 +90,11 @@ class_basename($model).' (tenantless record requires explicit workspace_id)', private static function ensureTenantIdIsImmutableOptional(Model $model, int $tenantId): void { - if (! $model->exists || ! $model->isDirty('tenant_id')) { + if (! $model->exists || ! $model->isDirty('managed_environment_id')) { return; } - $originalTenantId = $model->getOriginal('tenant_id'); + $originalTenantId = $model->getOriginal('managed_environment_id'); if (! is_numeric($originalTenantId)) { return; @@ -117,11 +117,11 @@ private static function resolveTenantWorkspaceIdOptional(Model $model, int $tena { $tenant = $model->relationLoaded('tenant') ? $model->getRelation('tenant') : null; - if (! $tenant instanceof Tenant || (int) $tenant->getKey() !== $tenantId) { - $tenant = Tenant::query()->find($tenantId); + if (! $tenant instanceof ManagedEnvironment || (int) $tenant->getKey() !== $tenantId) { + $tenant = ManagedEnvironment::query()->find($tenantId); } - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { throw WorkspaceIsolationViolation::tenantNotFound(class_basename($model), $tenantId); } diff --git a/apps/platform/app/Support/CustomerHealth/WorkspaceHealthSummaryQuery.php b/apps/platform/app/Support/CustomerHealth/WorkspaceHealthSummaryQuery.php index 62068b69..6ed3e281 100644 --- a/apps/platform/app/Support/CustomerHealth/WorkspaceHealthSummaryQuery.php +++ b/apps/platform/app/Support/CustomerHealth/WorkspaceHealthSummaryQuery.php @@ -11,7 +11,7 @@ use App\Models\ProductUsageEvent; use App\Models\ProviderConnection; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\Workspace; use App\Support\Onboarding\OnboardingLifecycleState; @@ -68,15 +68,15 @@ public function summaries(SystemConsoleWindow|string|null $window = null, ?Carbo ->map(static fn (mixed $workspaceId): int => (int) $workspaceId) ->all(); - $activeTenants = Tenant::query() + $activeTenants = ManagedEnvironment::query() ->whereIn('workspace_id', $workspaceIds) ->whereNull('deleted_at') - ->where('status', '!=', Tenant::STATUS_ARCHIVED) + ->where('lifecycle_status', '!=', ManagedEnvironment::STATUS_ARCHIVED) ->orderBy('name') ->orderBy('id') - ->get(['id', 'workspace_id', 'external_id', 'name', 'status']); + ->get(['id', 'workspace_id', 'slug', 'name', 'lifecycle_status']); - $tenantsByWorkspace = $activeTenants->groupBy(static fn (Tenant $tenant): int => (int) $tenant->workspace_id); + $tenantsByWorkspace = $activeTenants->groupBy(static fn (ManagedEnvironment $tenant): int => (int) $tenant->workspace_id); $latestOnboardingSessions = TenantOnboardingSession::query() ->whereIn('workspace_id', $workspaceIds) @@ -85,7 +85,7 @@ public function summaries(SystemConsoleWindow|string|null $window = null, ?Carbo }) ->orderByDesc('updated_at') ->orderByDesc('id') - ->get(['id', 'workspace_id', 'tenant_id', 'lifecycle_state', 'updated_at', 'created_at']) + ->get(['id', 'workspace_id', 'managed_environment_id', 'lifecycle_state', 'updated_at', 'created_at']) ->groupBy(static fn (TenantOnboardingSession $session): int => (int) $session->workspace_id) ->map(static fn (Collection $sessions): ?TenantOnboardingSession => $sessions->first()); @@ -100,7 +100,7 @@ public function summaries(SystemConsoleWindow|string|null $window = null, ?Carbo ->get([ 'id', 'workspace_id', - 'tenant_id', + 'managed_environment_id', 'is_enabled', 'consent_status', 'verification_status', @@ -224,7 +224,7 @@ public function summaries(SystemConsoleWindow|string|null $window = null, ?Carbo }) ->orderByDesc('created_at') ->orderByDesc('id') - ->get(['id', 'workspace_id', 'tenant_id', 'status', 'expires_at', 'created_at']) + ->get(['id', 'workspace_id', 'managed_environment_id', 'status', 'expires_at', 'created_at']) ->groupBy(static fn (ReviewPack $reviewPack): int => (int) $reviewPack->workspace_id) ->map(static fn (Collection $reviewPacks): ?ReviewPack => $reviewPacks->first()); @@ -266,7 +266,7 @@ public function summaries(SystemConsoleWindow|string|null $window = null, ?Carbo $now, ): array { $workspaceId = (int) $workspace->getKey(); - /** @var Collection $workspaceTenants */ + /** @var Collection $workspaceTenants */ $workspaceTenants = $tenantsByWorkspace->get($workspaceId, collect()); /** @var TenantOnboardingSession|null $latestOnboardingSession */ $latestOnboardingSession = $latestOnboardingSessions->get($workspaceId); @@ -420,7 +420,7 @@ private function resolveWindow(SystemConsoleWindow|string|null $window): SystemC } /** - * @param Collection $tenants + * @param Collection $tenants * @param Collection $providerConnections * @return array */ @@ -471,7 +471,7 @@ private function buildDimensions( } /** - * @param Collection $tenants + * @param Collection $tenants */ private function onboardingReadinessLevel(Collection $tenants, ?TenantOnboardingSession $latestOnboardingSession): string { @@ -491,7 +491,7 @@ private function onboardingReadinessLevel(Collection $tenants, ?TenantOnboarding return 'unknown'; } - if ($tenants->contains(static fn (Tenant $tenant): bool => (string) $tenant->status === Tenant::STATUS_ACTIVE)) { + if ($tenants->contains(static fn (ManagedEnvironment $tenant): bool => (string) $tenant->status === ManagedEnvironment::STATUS_ACTIVE)) { return 'ok'; } @@ -660,7 +660,7 @@ private function dominantDimensionKeys(array $dimensions): array } /** - * @param Collection $tenants + * @param Collection $tenants * @param list $dominantDimensionKeys * @return array{label: string, url: string} */ @@ -675,10 +675,10 @@ private function nextLink(Workspace $workspace, Collection $tenants, array $domi ]; } - /** @var Tenant|null $tenant */ + /** @var ManagedEnvironment|null $tenant */ $tenant = $tenants->first(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return [ 'label' => 'Review health details', 'url' => $this->withWindowQuery(SystemDirectoryLinks::tenantDetail($tenant), $window), @@ -756,11 +756,11 @@ private function normalizeBackedEnumValue(mixed $value): string private function constrainToActiveTenantTruth(Builder $query): void { $query - ->whereNull('tenant_id') + ->whereNull('managed_environment_id') ->orWhereHas('tenant', function (Builder $tenantQuery): void { $tenantQuery ->whereNull('deleted_at') - ->where('status', '!=', Tenant::STATUS_ARCHIVED); + ->where('lifecycle_status', '!=', ManagedEnvironment::STATUS_ARCHIVED); }); } -} \ No newline at end of file +} diff --git a/apps/platform/app/Support/Filament/CanonicalAdminTenantFilterState.php b/apps/platform/app/Support/Filament/CanonicalAdminTenantFilterState.php index 8833c349..a628e84d 100644 --- a/apps/platform/app/Support/Filament/CanonicalAdminTenantFilterState.php +++ b/apps/platform/app/Support/Filament/CanonicalAdminTenantFilterState.php @@ -4,7 +4,7 @@ namespace App\Support\Filament; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperateHub\OperateHubShell; use Illuminate\Http\Request; use Illuminate\Session\Store; @@ -20,7 +20,7 @@ public function currentFilterValue( string $filtersSessionKey, ?array $tableFilters = null, ?Request $request = null, - ?string $tenantFilterName = 'tenant_id', + ?string $tenantFilterName = 'managed_environment_id', ): ?string { if ($tenantFilterName === null) { return null; @@ -49,7 +49,7 @@ public function sync( string $filtersSessionKey, array $tenantSensitiveFilters = [], ?Request $request = null, - ?string $tenantFilterName = 'tenant_id', + ?string $tenantFilterName = 'managed_environment_id', string $tenantAttribute = 'id', ): void { $session = $this->session($request); @@ -61,7 +61,7 @@ public function sync( } $activeTenant = $this->operateHubShell->activeEntitledTenant($request); - $resolvedTenantId = $activeTenant instanceof Tenant ? (string) $activeTenant->getKey() : null; + $resolvedTenantId = $activeTenant instanceof ManagedEnvironment ? (string) $activeTenant->getKey() : null; $stateKey = $this->stateKey($filtersSessionKey); $previousTenantId = $session->get($stateKey); diff --git a/apps/platform/app/Support/Governance/PlatformVocabularyGlossary.php b/apps/platform/app/Support/Governance/PlatformVocabularyGlossary.php index 70719749..c977f4b1 100644 --- a/apps/platform/app/Support/Governance/PlatformVocabularyGlossary.php +++ b/apps/platform/app/Support/Governance/PlatformVocabularyGlossary.php @@ -515,7 +515,7 @@ private function configuredReasonNamespaces(): array 'owner_namespace' => 'tenant_operability', 'boundary_classification' => self::BOUNDARY_PLATFORM_CORE, 'owner_layer' => self::OWNER_PLATFORM_CORE, - 'compatibility_notes' => 'Tenant operability reasons are platform-core guardrails for workspace and tenant context.', + 'compatibility_notes' => 'ManagedEnvironment operability reasons are platform-core guardrails for workspace and tenant context.', ], 'execution_denial' => [ 'owner_namespace' => 'execution_denial', diff --git a/apps/platform/app/Support/GovernanceDecisions/GovernanceDecisionRegisterBuilder.php b/apps/platform/app/Support/GovernanceDecisions/GovernanceDecisionRegisterBuilder.php index 144bf266..5adaf425 100644 --- a/apps/platform/app/Support/GovernanceDecisions/GovernanceDecisionRegisterBuilder.php +++ b/apps/platform/app/Support/GovernanceDecisions/GovernanceDecisionRegisterBuilder.php @@ -6,7 +6,7 @@ use App\Models\FindingException; use App\Models\FindingExceptionDecision; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use Carbon\CarbonInterface; use Illuminate\Support\Collection; @@ -25,7 +25,7 @@ ]; /** - * @param array $visibleTenants + * @param array $visibleTenants * @return array{ * rows: list>, * counts: array{open: int, recently_closed: int}, @@ -34,7 +34,7 @@ public function build(Workspace $workspace, array $visibleTenants, string $registerState = 'open'): array { $visibleTenantIds = array_values(array_map( - static fn (Tenant $tenant): int => (int) $tenant->getKey(), + static fn (ManagedEnvironment $tenant): int => (int) $tenant->getKey(), $visibleTenants, )); @@ -50,7 +50,7 @@ public function build(Workspace $workspace, array $visibleTenants, string $regis $rows = FindingException::query() ->where('workspace_id', (int) $workspace->getKey()) - ->whereIn('tenant_id', $visibleTenantIds) + ->whereIn('managed_environment_id', $visibleTenantIds) ->with(['tenant:id,name', 'owner:id,name', 'currentDecision']) ->get() ->map(fn (FindingException $exception): ?array => $this->buildRow($exception)) diff --git a/apps/platform/app/Support/GovernanceInbox/GovernanceInboxSectionBuilder.php b/apps/platform/app/Support/GovernanceInbox/GovernanceInboxSectionBuilder.php index bc91953a..38ecbc51 100644 --- a/apps/platform/app/Support/GovernanceInbox/GovernanceInboxSectionBuilder.php +++ b/apps/platform/app/Support/GovernanceInbox/GovernanceInboxSectionBuilder.php @@ -16,7 +16,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Models\User; use App\Models\Workspace; @@ -54,9 +54,9 @@ public function __construct( ) {} /** - * @param array $authorizedTenants - * @param array $visibleFindingTenants - * @param array $reviewTenants + * @param array $authorizedTenants + * @param array $visibleFindingTenants + * @param array $reviewTenants * @return array{ * sections: list>, * available_families: list, @@ -72,7 +72,7 @@ public function build( array $reviewTenants, bool $canViewAlerts, bool $canViewFindingExceptions = false, - ?Tenant $selectedTenant = null, + ?ManagedEnvironment $selectedTenant = null, ?string $selectedFamily = null, ?CanonicalNavigationContext $navigationContext = null, ): array { @@ -209,13 +209,13 @@ public function build( } /** - * @param array $authorizedTenants + * @param array $authorizedTenants * @return array */ private function findingExceptionsSection( Workspace $workspace, array $authorizedTenants, - ?Tenant $selectedTenant, + ?ManagedEnvironment $selectedTenant, ?CanonicalNavigationContext $navigationContext, ): array { $baseQuery = $this->findingExceptionsQuery($workspace, $authorizedTenants, $selectedTenant); @@ -255,15 +255,15 @@ private function findingExceptionsSection( $navigationContext?->toQuery() ?? [], ), 'entries' => $entries, - 'empty_state' => $selectedTenant instanceof Tenant + 'empty_state' => $selectedTenant instanceof ManagedEnvironment ? 'No finding exceptions match this tenant filter right now.' : 'No finding exceptions need review right now.', ]; } /** - * @param array $tenants - * @return array + * @param array $tenants + * @return array */ private function indexTenants(array $tenants): array { @@ -277,13 +277,13 @@ private function indexTenants(array $tenants): array } /** - * @param array $visibleFindingTenants + * @param array $visibleFindingTenants * @return array */ private function assignedFindingsSection( User $user, array $visibleFindingTenants, - ?Tenant $selectedTenant, + ?ManagedEnvironment $selectedTenant, ?CanonicalNavigationContext $navigationContext, ): array { $baseQuery = $this->assignedFindingsQuery($user, $visibleFindingTenants, $selectedTenant); @@ -314,19 +314,19 @@ private function assignedFindingsSection( $navigationContext?->toQuery() ?? [], ), 'entries' => $entries, - 'empty_state' => $selectedTenant instanceof Tenant + 'empty_state' => $selectedTenant instanceof ManagedEnvironment ? 'No assigned findings match this tenant filter right now.' : 'No assigned findings are visible right now.', ]; } /** - * @param array $visibleFindingTenants + * @param array $visibleFindingTenants * @return array */ private function intakeFindingsSection( array $visibleFindingTenants, - ?Tenant $selectedTenant, + ?ManagedEnvironment $selectedTenant, ?CanonicalNavigationContext $navigationContext, ): array { $baseQuery = $this->intakeFindingsQuery($visibleFindingTenants, $selectedTenant); @@ -357,20 +357,20 @@ private function intakeFindingsSection( $navigationContext?->toQuery() ?? [], ), 'entries' => $entries, - 'empty_state' => $selectedTenant instanceof Tenant + 'empty_state' => $selectedTenant instanceof ManagedEnvironment ? 'No intake findings match this tenant filter right now.' : 'No intake findings are visible right now.', ]; } /** - * @param array $authorizedTenants + * @param array $authorizedTenants * @return array */ private function operationsSection( Workspace $workspace, array $authorizedTenants, - ?Tenant $selectedTenant, + ?ManagedEnvironment $selectedTenant, ?CanonicalNavigationContext $navigationContext, ): array { $terminalQuery = $this->terminalOperationsQuery($workspace, $authorizedTenants, $selectedTenant); @@ -407,20 +407,20 @@ private function operationsSection( problemClass: $dominantProblemClass, ), 'entries' => $entries, - 'empty_state' => $selectedTenant instanceof Tenant + 'empty_state' => $selectedTenant instanceof ManagedEnvironment ? 'No stale or terminal follow-up operations match this tenant filter right now.' : 'No stale or terminal follow-up operations are visible right now.', ]; } /** - * @param array $authorizedTenants + * @param array $authorizedTenants * @return array */ private function alertsSection( Workspace $workspace, array $authorizedTenants, - ?Tenant $selectedTenant, + ?ManagedEnvironment $selectedTenant, ?CanonicalNavigationContext $navigationContext, ): array { $baseQuery = $this->alertsQuery($workspace, $authorizedTenants, $selectedTenant); @@ -446,7 +446,7 @@ private function alertsSection( [ 'tableFilters' => array_filter([ 'status' => ['value' => AlertDelivery::STATUS_FAILED], - 'tenant_id' => $selectedTenant instanceof Tenant + 'managed_environment_id' => $selectedTenant instanceof ManagedEnvironment ? ['value' => (string) $selectedTenant->getKey()] : null, ], static fn (mixed $value): bool => $value !== null), @@ -454,24 +454,24 @@ private function alertsSection( ), ), 'entries' => $entries, - 'empty_state' => $selectedTenant instanceof Tenant + 'empty_state' => $selectedTenant instanceof ManagedEnvironment ? 'No failed alert deliveries match this tenant filter right now.' : 'No failed alert deliveries are visible right now.', ]; } /** - * @param array $reviewTenants + * @param array $reviewTenants * @return array */ private function reviewFollowUpSection( User $user, Workspace $workspace, array $reviewTenants, - ?Tenant $selectedTenant, + ?ManagedEnvironment $selectedTenant, ?CanonicalNavigationContext $navigationContext, ): array { - $tenantIds = $selectedTenant instanceof Tenant + $tenantIds = $selectedTenant instanceof ManagedEnvironment ? [(int) $selectedTenant->getKey()] : array_keys($reviewTenants); $backupHealthByTenant = $this->backupHealthResolver->assessMany($tenantIds); @@ -485,7 +485,7 @@ private function reviewFollowUpSection( $latestPublishedReviews = $this->tenantReviewRegisterService ->latestPublishedQuery($user, $workspace) ->get() - ->keyBy('tenant_id') + ->keyBy('managed_environment_id') ->all(); $rawEntries = []; @@ -494,7 +494,7 @@ private function reviewFollowUpSection( $tenant = $reviewTenants[$tenantId] ?? null; $rows = $resolved['rows'][$tenantId] ?? null; - if (! $tenant instanceof Tenant || ! is_array($rows)) { + if (! $tenant instanceof ManagedEnvironment || ! is_array($rows)) { continue; } @@ -548,29 +548,29 @@ private function reviewFollowUpSection( 'count' => count($rawEntries), 'summary' => $this->reviewSummary($followUpCount, $changedCount), 'dominant_action_label' => 'Open customer review workspace', - 'dominant_action_url' => $selectedTenant instanceof Tenant + 'dominant_action_url' => $selectedTenant instanceof ManagedEnvironment ? $this->appendQuery(CustomerReviewWorkspace::tenantPrefilterUrl($selectedTenant), $navigationContext?->toQuery() ?? []) : $this->appendQuery(CustomerReviewWorkspace::getUrl(panel: 'admin'), $navigationContext?->toQuery() ?? []), 'entries' => array_slice($rawEntries, 0, self::PREVIEW_LIMIT), - 'empty_state' => $selectedTenant instanceof Tenant + 'empty_state' => $selectedTenant instanceof ManagedEnvironment ? 'No review follow-up is visible for this tenant filter right now.' : 'No review follow-up is visible right now.', ]; } /** - * @param array $visibleFindingTenants + * @param array $visibleFindingTenants */ - private function assignedFindingsQuery(User $user, array $visibleFindingTenants, ?Tenant $selectedTenant): \Illuminate\Database\Eloquent\Builder + private function assignedFindingsQuery(User $user, array $visibleFindingTenants, ?ManagedEnvironment $selectedTenant): \Illuminate\Database\Eloquent\Builder { - $tenantIds = $selectedTenant instanceof Tenant + $tenantIds = $selectedTenant instanceof ManagedEnvironment ? [(int) $selectedTenant->getKey()] : array_keys($visibleFindingTenants); return Finding::query() ->with(['tenant', 'ownerUser:id,name', 'assigneeUser:id,name']) ->withSubjectDisplayName() - ->whereIn('tenant_id', $tenantIds === [] ? [-1] : $tenantIds) + ->whereIn('managed_environment_id', $tenantIds === [] ? [-1] : $tenantIds) ->where('assignee_user_id', (int) $user->getKey()) ->whereIn('status', Finding::openStatusesForQuery()); } @@ -588,18 +588,18 @@ private function orderedAssignedFindingsQuery(\Illuminate\Database\Eloquent\Buil } /** - * @param array $visibleFindingTenants + * @param array $visibleFindingTenants */ - private function intakeFindingsQuery(array $visibleFindingTenants, ?Tenant $selectedTenant): \Illuminate\Database\Eloquent\Builder + private function intakeFindingsQuery(array $visibleFindingTenants, ?ManagedEnvironment $selectedTenant): \Illuminate\Database\Eloquent\Builder { - $tenantIds = $selectedTenant instanceof Tenant + $tenantIds = $selectedTenant instanceof ManagedEnvironment ? [(int) $selectedTenant->getKey()] : array_keys($visibleFindingTenants); return Finding::query() ->with(['tenant', 'ownerUser:id,name', 'assigneeUser:id,name']) ->withSubjectDisplayName() - ->whereIn('tenant_id', $tenantIds === [] ? [-1] : $tenantIds) + ->whereIn('managed_environment_id', $tenantIds === [] ? [-1] : $tenantIds) ->whereNull('assignee_user_id') ->whereIn('status', Finding::openStatusesForQuery()); } @@ -622,27 +622,27 @@ private function orderedIntakeFindingsQuery(\Illuminate\Database\Eloquent\Builde } /** - * @param array $authorizedTenants + * @param array $authorizedTenants */ - private function terminalOperationsQuery(Workspace $workspace, array $authorizedTenants, ?Tenant $selectedTenant): \Illuminate\Database\Eloquent\Builder + private function terminalOperationsQuery(Workspace $workspace, array $authorizedTenants, ?ManagedEnvironment $selectedTenant): \Illuminate\Database\Eloquent\Builder { return $this->operationsBaseQuery($workspace, $authorizedTenants, $selectedTenant) ->terminalFollowUp(); } /** - * @param array $authorizedTenants + * @param array $authorizedTenants */ - private function staleOperationsQuery(Workspace $workspace, array $authorizedTenants, ?Tenant $selectedTenant): \Illuminate\Database\Eloquent\Builder + private function staleOperationsQuery(Workspace $workspace, array $authorizedTenants, ?ManagedEnvironment $selectedTenant): \Illuminate\Database\Eloquent\Builder { return $this->operationsBaseQuery($workspace, $authorizedTenants, $selectedTenant) ->activeStaleAttention(); } /** - * @param array $authorizedTenants + * @param array $authorizedTenants */ - private function operationsBaseQuery(Workspace $workspace, array $authorizedTenants, ?Tenant $selectedTenant): \Illuminate\Database\Eloquent\Builder + private function operationsBaseQuery(Workspace $workspace, array $authorizedTenants, ?ManagedEnvironment $selectedTenant): \Illuminate\Database\Eloquent\Builder { $tenantIds = array_keys($authorizedTenants); @@ -650,22 +650,22 @@ private function operationsBaseQuery(Workspace $workspace, array $authorizedTena ->with('tenant') ->where('workspace_id', (int) $workspace->getKey()) ->where(function ($query) use ($selectedTenant, $tenantIds): void { - if ($selectedTenant instanceof Tenant) { - $query->where('tenant_id', (int) $selectedTenant->getKey()); + if ($selectedTenant instanceof ManagedEnvironment) { + $query->where('managed_environment_id', (int) $selectedTenant->getKey()); return; } $query - ->whereIn('tenant_id', $tenantIds === [] ? [-1] : $tenantIds) - ->orWhereNull('tenant_id'); + ->whereIn('managed_environment_id', $tenantIds === [] ? [-1] : $tenantIds) + ->orWhereNull('managed_environment_id'); }); } /** - * @param array $authorizedTenants + * @param array $authorizedTenants */ - private function alertsQuery(Workspace $workspace, array $authorizedTenants, ?Tenant $selectedTenant): \Illuminate\Database\Eloquent\Builder + private function alertsQuery(Workspace $workspace, array $authorizedTenants, ?ManagedEnvironment $selectedTenant): \Illuminate\Database\Eloquent\Builder { $tenantIds = array_keys($authorizedTenants); @@ -674,24 +674,24 @@ private function alertsQuery(Workspace $workspace, array $authorizedTenants, ?Te ->where('workspace_id', (int) $workspace->getKey()) ->where('status', AlertDelivery::STATUS_FAILED) ->where(function ($query) use ($selectedTenant, $tenantIds): void { - if ($selectedTenant instanceof Tenant) { - $query->where('tenant_id', (int) $selectedTenant->getKey()); + if ($selectedTenant instanceof ManagedEnvironment) { + $query->where('managed_environment_id', (int) $selectedTenant->getKey()); return; } $query - ->whereIn('tenant_id', $tenantIds === [] ? [-1] : $tenantIds) - ->orWhereNull('tenant_id'); + ->whereIn('managed_environment_id', $tenantIds === [] ? [-1] : $tenantIds) + ->orWhereNull('managed_environment_id'); }); } /** - * @param array $authorizedTenants + * @param array $authorizedTenants */ - private function findingExceptionsQuery(Workspace $workspace, array $authorizedTenants, ?Tenant $selectedTenant): \Illuminate\Database\Eloquent\Builder + private function findingExceptionsQuery(Workspace $workspace, array $authorizedTenants, ?ManagedEnvironment $selectedTenant): \Illuminate\Database\Eloquent\Builder { - $tenantIds = $selectedTenant instanceof Tenant + $tenantIds = $selectedTenant instanceof ManagedEnvironment ? [(int) $selectedTenant->getKey()] : array_keys($authorizedTenants); @@ -703,7 +703,7 @@ private function findingExceptionsQuery(Workspace $workspace, array $authorizedT 'finding' => fn ($query) => $query->withSubjectDisplayName(), ]) ->where('workspace_id', (int) $workspace->getKey()) - ->whereIn('tenant_id', $tenantIds === [] ? [-1] : $tenantIds) + ->whereIn('managed_environment_id', $tenantIds === [] ? [-1] : $tenantIds) ->where(function ($query): void { $query ->where('status', FindingException::STATUS_PENDING) @@ -757,7 +757,7 @@ private function findingEntry(Finding $finding, string $familyKey, ?CanonicalNav 'family_key' => $familyKey, 'source_model' => Finding::class, 'source_key' => (string) $finding->getKey(), - 'tenant_id' => $finding->tenant ? (int) $finding->tenant->getKey() : null, + 'managed_environment_id' => $finding->tenant ? (int) $finding->tenant->getKey() : null, 'tenant_label' => $finding->tenant?->name, 'headline' => $finding->resolvedSubjectDisplayName() ?? 'Finding #'.$finding->getKey(), 'subline' => $sublineParts === [] ? null : implode(' • ', $sublineParts), @@ -784,7 +784,7 @@ private function operationEntry(OperationRun $run, ?CanonicalNavigationContext $ 'family_key' => 'stale_operations', 'source_model' => OperationRun::class, 'source_key' => (string) $run->getKey(), - 'tenant_id' => $run->tenant ? (int) $run->tenant->getKey() : null, + 'managed_environment_id' => $run->tenant ? (int) $run->tenant->getKey() : null, 'tenant_label' => $run->tenant?->name, 'headline' => $problemClass === OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP ? 'Terminal follow-up operation' @@ -821,7 +821,7 @@ private function alertEntry(AlertDelivery $delivery, ?CanonicalNavigationContext 'family_key' => 'alert_delivery_failures', 'source_model' => AlertDelivery::class, 'source_key' => (string) $delivery->getKey(), - 'tenant_id' => $delivery->tenant ? (int) $delivery->tenant->getKey() : null, + 'managed_environment_id' => $delivery->tenant ? (int) $delivery->tenant->getKey() : null, 'tenant_label' => $delivery->tenant?->name, 'headline' => $headline, 'subline' => $sublineParts === [] ? null : implode(' • ', $sublineParts), @@ -855,7 +855,7 @@ private function findingExceptionEntry(FindingException $exception, ?CanonicalNa 'family_key' => 'finding_exceptions', 'source_model' => FindingException::class, 'source_key' => (string) $exception->getKey(), - 'tenant_id' => $exception->tenant ? (int) $exception->tenant->getKey() : null, + 'managed_environment_id' => $exception->tenant ? (int) $exception->tenant->getKey() : null, 'tenant_label' => $exception->tenant?->name, 'headline' => $findingLabel, 'subline' => $sublineParts === [] ? null : implode(' • ', $sublineParts), @@ -886,7 +886,7 @@ private function findingExceptionEntry(FindingException $exception, ?CanonicalNa * @return array */ private function reviewEntry( - Tenant $tenant, + ManagedEnvironment $tenant, string $family, array $row, mixed $latestPublishedReview, @@ -915,7 +915,7 @@ private function reviewEntry( 'family_key' => 'review_follow_up', 'source_model' => TenantTriageReview::class, 'source_key' => (string) $tenant->getKey().':'.$family, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'tenant_label' => $tenant->name, 'headline' => $headline, 'subline' => $sublineParts === [] ? null : implode(' • ', $sublineParts), diff --git a/apps/platform/app/Support/Inventory/TenantCoverageTruth.php b/apps/platform/app/Support/Inventory/TenantCoverageTruth.php index 777e1c4f..963f5f67 100644 --- a/apps/platform/app/Support/Inventory/TenantCoverageTruth.php +++ b/apps/platform/app/Support/Inventory/TenantCoverageTruth.php @@ -26,11 +26,11 @@ public function __construct( public array $rows, ) { if ($this->tenantId <= 0) { - throw new InvalidArgumentException('Tenant coverage truth requires a positive tenant id.'); + throw new InvalidArgumentException('ManagedEnvironment coverage truth requires a positive tenant id.'); } if ($this->supportedTypeCount < 0 || $this->observedItemTotal < 0) { - throw new InvalidArgumentException('Tenant coverage truth counts must be zero or greater.'); + throw new InvalidArgumentException('ManagedEnvironment coverage truth counts must be zero or greater.'); } } diff --git a/apps/platform/app/Support/Inventory/TenantCoverageTruthResolver.php b/apps/platform/app/Support/Inventory/TenantCoverageTruthResolver.php index b3e4fe18..698743df 100644 --- a/apps/platform/app/Support/Inventory/TenantCoverageTruthResolver.php +++ b/apps/platform/app/Support/Inventory/TenantCoverageTruthResolver.php @@ -6,7 +6,7 @@ use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Inventory\CoverageCapabilitiesResolver; use Illuminate\Support\Collection; @@ -16,9 +16,9 @@ public function __construct( private readonly CoverageCapabilitiesResolver $coverageCapabilities, ) {} - public function resolve(Tenant|int $tenant): TenantCoverageTruth + public function resolve(ManagedEnvironment|int $tenant): TenantCoverageTruth { - $tenantId = $tenant instanceof Tenant + $tenantId = $tenant instanceof ManagedEnvironment ? (int) $tenant->getKey() : (int) $tenant; @@ -27,7 +27,7 @@ public function resolve(Tenant|int $tenant): TenantCoverageTruth /** @var array $countsByType */ $countsByType = InventoryItem::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->selectRaw('policy_type, COUNT(*) as aggregate') ->groupBy('policy_type') ->pluck('aggregate', 'policy_type') diff --git a/apps/platform/app/Support/Links/RequiredPermissionsLinks.php b/apps/platform/app/Support/Links/RequiredPermissionsLinks.php index 8afdd1a6..52065c0d 100644 --- a/apps/platform/app/Support/Links/RequiredPermissionsLinks.php +++ b/apps/platform/app/Support/Links/RequiredPermissionsLinks.php @@ -3,7 +3,7 @@ namespace App\Support\Links; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\AdminConsentUrlFactory; final class RequiredPermissionsLinks @@ -13,7 +13,7 @@ final class RequiredPermissionsLinks /** * @param array $filters */ - public static function requiredPermissions(Tenant $tenant, array $filters = []): string + public static function requiredPermissions(ManagedEnvironment $tenant, array $filters = []): string { $base = sprintf('/admin/tenants/%s/required-permissions', urlencode((string) $tenant->external_id)); @@ -26,10 +26,10 @@ public static function requiredPermissions(Tenant $tenant, array $filters = []): return $query !== '' ? "{$base}?{$query}" : $base; } - public static function adminConsentUrl(Tenant $tenant): ?string + public static function adminConsentUrl(ManagedEnvironment $tenant): ?string { $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->orderByDesc('is_default') ->orderBy('id') @@ -51,7 +51,7 @@ public static function adminConsentGuideUrl(): string return self::ADMIN_CONSENT_GUIDE_URL; } - public static function adminConsentPrimaryUrl(Tenant $tenant): string + public static function adminConsentPrimaryUrl(ManagedEnvironment $tenant): string { return self::adminConsentUrl($tenant) ?? self::adminConsentGuideUrl(); } diff --git a/apps/platform/app/Support/Livewire/TrustedState/TrustedStatePolicy.php b/apps/platform/app/Support/Livewire/TrustedState/TrustedStatePolicy.php index 28e97fca..f4443a63 100644 --- a/apps/platform/app/Support/Livewire/TrustedState/TrustedStatePolicy.php +++ b/apps/platform/app/Support/Livewire/TrustedState/TrustedStatePolicy.php @@ -198,15 +198,15 @@ public function firstSlice(): array $this->field( name: 'managedTenant', stateClass: TrustedStateClass::ServerDerivedAuthority, - phpType: '?Tenant', + phpType: '?ManagedEnvironment', sourceOfTruth: 'explicit_scoped_query', usedForProtectedAction: true, revalidationRequired: true, implementationMarkers: [ - 'public ?Tenant $managedTenant = null;', + 'public ?ManagedEnvironment $managedTenant = null;', 'currentManagedTenantRecord()', ], - notes: 'Tenant model instances are display helpers only and must be re-derived from draft or scoped tenant queries.', + notes: 'ManagedEnvironment model instances are display helpers only and must be re-derived from draft or scoped tenant queries.', ), ], 'forbidden_public_authority_fields' => [ @@ -216,7 +216,7 @@ public function firstSlice(): array ], ], self::TENANT_REQUIRED_PERMISSIONS => [ - 'component_name' => 'Tenant required permissions', + 'component_name' => 'ManagedEnvironment required permissions', 'plane' => 'admin_tenant', 'route_anchor' => 'tenant', 'authority_sources' => [ @@ -311,7 +311,7 @@ public function firstSlice(): array $this->field( name: 'scopedTenant', stateClass: TrustedStateClass::ServerDerivedAuthority, - phpType: '?Tenant', + phpType: '?ManagedEnvironment', sourceOfTruth: 'explicit_scoped_query', usedForProtectedAction: true, revalidationRequired: true, @@ -320,7 +320,7 @@ public function firstSlice(): array 'trustedScopedTenant()', 'currentWorkspaceId(request())', ], - notes: 'Tenant scope remains route- and workspace-derived even when mutable filters change.', + notes: 'ManagedEnvironment scope remains route- and workspace-derived even when mutable filters change.', ), ], 'forbidden_public_authority_fields' => [ diff --git a/apps/platform/app/Support/Livewire/TrustedState/TrustedStateResolver.php b/apps/platform/app/Support/Livewire/TrustedState/TrustedStateResolver.php index fcde24a2..5869e17c 100644 --- a/apps/platform/app/Support/Livewire/TrustedState/TrustedStateResolver.php +++ b/apps/platform/app/Support/Livewire/TrustedState/TrustedStateResolver.php @@ -4,7 +4,7 @@ namespace App\Support\Livewire\TrustedState; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -40,14 +40,14 @@ public function resolveOnboardingDraft( public function resolveAllowedTenantProposal( int|string|null $tenantId, AllowedTenantUniverse $allowedTenantUniverse, - ): ?Tenant { + ): ?ManagedEnvironment { return $allowedTenantUniverse->resolveAllowed($tenantId); } public function resolveAllowedTenantProposalOrFail( int|string|null $tenantId, AllowedTenantUniverse $allowedTenantUniverse, - ): Tenant { + ): ManagedEnvironment { return $allowedTenantUniverse->resolveAllowedOrFail($tenantId); } } diff --git a/apps/platform/app/Support/Middleware/DenyNonMemberTenantAccess.php b/apps/platform/app/Support/Middleware/DenyNonMemberTenantAccess.php index d3b021a3..9b959b82 100644 --- a/apps/platform/app/Support/Middleware/DenyNonMemberTenantAccess.php +++ b/apps/platform/app/Support/Middleware/DenyNonMemberTenantAccess.php @@ -2,7 +2,7 @@ namespace App\Support\Middleware; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use Closure; @@ -18,7 +18,7 @@ public function handle(Request $request, Closure $next): Response { $tenant = $request->route()?->parameter('tenant'); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return $next($request); } diff --git a/apps/platform/app/Support/Middleware/EnsureFilamentTenantSelected.php b/apps/platform/app/Support/Middleware/EnsureFilamentTenantSelected.php index 1ba351be..9657d9f3 100644 --- a/apps/platform/app/Support/Middleware/EnsureFilamentTenantSelected.php +++ b/apps/platform/app/Support/Middleware/EnsureFilamentTenantSelected.php @@ -6,7 +6,7 @@ use App\Filament\Resources\AlertDeliveryResource; use App\Filament\Resources\AlertDestinationResource; use App\Filament\Resources\AlertRuleResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceMembership; use App\Services\Auth\WorkspaceRoleCapabilityMap; @@ -37,13 +37,13 @@ public function handle(Request $request, Closure $next): Response $workspaceId = $workspaceContext->currentWorkspaceId($request); $existingTenant = Filament::getTenant(); - if ($existingTenant instanceof Tenant && $workspaceId !== null && (int) $existingTenant->workspace_id !== (int) $workspaceId) { + if ($existingTenant instanceof ManagedEnvironment && $workspaceId !== null && (int) $existingTenant->workspace_id !== (int) $workspaceId) { Filament::setTenant(null, true); $existingTenant = null; } $user = $request->user(); - if ($existingTenant instanceof Tenant && $user instanceof User && ! $user->canAccessTenant($existingTenant)) { + if ($existingTenant instanceof ManagedEnvironment && $user instanceof User && ! $user->canAccessTenant($existingTenant)) { Filament::setTenant(null, true); } @@ -244,7 +244,7 @@ private function isCanonicalWorkspaceRecordViewerPath(string $path): bool private function requestHasExplicitTenantHint(Request $request): bool { - return filled($request->query('tenant')) || filled($request->query('tenant_id')); + return filled($request->query('tenant')) || filled($request->query('managed_environment_id')); } private function adminPathRequiresTenantSelection(string $path): bool diff --git a/apps/platform/app/Support/Navigation/CanonicalNavigationContext.php b/apps/platform/app/Support/Navigation/CanonicalNavigationContext.php index 6d87dfba..919da6f4 100644 --- a/apps/platform/app/Support/Navigation/CanonicalNavigationContext.php +++ b/apps/platform/app/Support/Navigation/CanonicalNavigationContext.php @@ -7,7 +7,7 @@ use App\Filament\Pages\BaselineCompareMatrix; use App\Filament\Resources\TenantResource\Pages\ListTenants; use App\Models\BaselineProfile; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Filament\Facades\Filament; use Illuminate\Http\Request; @@ -53,7 +53,7 @@ public static function fromRequest(Request $request): ?self return null; } - $tenantId = $payload['tenant_id'] ?? null; + $tenantId = $payload['managed_environment_id'] ?? null; return new self( sourceSurface: $sourceSurface, @@ -134,7 +134,7 @@ public function navQuery(): array public static function forBaselineCompareMatrix( BaselineProfile $profile, array $filters = [], - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?string $subjectKey = null, ): self { $parameters = array_filter([ @@ -163,7 +163,7 @@ private function navPayload(): array return array_filter([ 'source_surface' => $this->sourceSurface, 'canonical_route_name' => $this->canonicalRouteName, - 'tenant_id' => $this->tenantId, + 'managed_environment_id' => $this->tenantId, 'family_key' => $this->familyKey, 'back_label' => $this->backLinkLabel, 'back_url' => $this->backLinkUrl, diff --git a/apps/platform/app/Support/Navigation/RelatedNavigationResolver.php b/apps/platform/app/Support/Navigation/RelatedNavigationResolver.php index 9a86ed8f..142c17bc 100644 --- a/apps/platform/app/Support/Navigation/RelatedNavigationResolver.php +++ b/apps/platform/app/Support/Navigation/RelatedNavigationResolver.php @@ -24,7 +24,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -113,7 +113,7 @@ public function primaryListActionFresh(string $sourceType, Model $record): ?Rela /** * @return array */ - public function operationLinks(OperationRun $run, ?Tenant $tenant): array + public function operationLinks(OperationRun $run, ?ManagedEnvironment $tenant): array { $entries = array_filter( $this->detailEntryObjects(CrossResourceNavigationMatrix::SOURCE_OPERATION_RUN, $run), @@ -126,7 +126,7 @@ public function operationLinks(OperationRun $run, ?Tenant $tenant): array $links[$entry->actionLabel] = (string) $entry->targetUrl; } - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $links = [OperationRunLinks::collectionLabel() => OperationRunLinks::index($tenant)] + $links; } else { $links = [OperationRunLinks::collectionLabel() => OperationRunLinks::index()] + $links; @@ -138,7 +138,7 @@ public function operationLinks(OperationRun $run, ?Tenant $tenant): array /** * @return array */ - public function operationLinksFresh(OperationRun $run, ?Tenant $tenant): array + public function operationLinksFresh(OperationRun $run, ?ManagedEnvironment $tenant): array { $entries = array_filter( $this->detailEntryObjects(CrossResourceNavigationMatrix::SOURCE_OPERATION_RUN, $run, fresh: true), @@ -151,7 +151,7 @@ public function operationLinksFresh(OperationRun $run, ?Tenant $tenant): array $links[$entry->actionLabel] = (string) $entry->targetUrl; } - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return [OperationRunLinks::collectionLabel() => OperationRunLinks::index($tenant)] + $links; } @@ -242,39 +242,39 @@ public function auditTargetLink(AuditLog $record): ?array && AlertDestinationResource::canView($alertDestination) ? ['label' => 'Open alert destination', 'url' => AlertDestinationResource::getUrl('view', ['record' => $resourceId], panel: 'admin')] : null, - 'backup_set' => $tenant instanceof Tenant + 'backup_set' => $tenant instanceof ManagedEnvironment && $this->capabilityResolver->isMember($user, $tenant) && $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_VIEW) && BackupSet::query() ->whereKey($resourceId) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->exists() ? ['label' => 'Open backup set', 'url' => BackupSetResource::getUrl('view', ['record' => $resourceId], panel: 'tenant', tenant: $tenant)] : null, - 'restore_run' => $tenant instanceof Tenant + 'restore_run' => $tenant instanceof ManagedEnvironment && $this->capabilityResolver->isMember($user, $tenant) && $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_VIEW) && RestoreRun::query() ->whereKey($resourceId) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->exists() ? ['label' => 'Open restore run', 'url' => RestoreRunResource::getUrl('view', ['record' => $resourceId], panel: 'tenant', tenant: $tenant)] : null, - 'finding' => $tenant instanceof Tenant + 'finding' => $tenant instanceof ManagedEnvironment && $this->capabilityResolver->isMember($user, $tenant) && $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW) && Finding::query() ->whereKey($resourceId) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->exists() ? ['label' => 'Open finding', 'url' => FindingResource::getUrl('view', ['record' => $resourceId], panel: 'tenant', tenant: $tenant)] : null, - 'finding_exception' => $tenant instanceof Tenant + 'finding_exception' => $tenant instanceof ManagedEnvironment && $this->capabilityResolver->isMember($user, $tenant) && $this->capabilityResolver->can($user, $tenant, Capabilities::FINDING_EXCEPTION_VIEW) && ($findingException = FindingException::query() ->whereKey($resourceId) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->first()) instanceof FindingException ? ['label' => 'Open finding exception', 'url' => FindingExceptionResource::getUrl('view', ['record' => $findingException], panel: 'tenant', tenant: $tenant)] : null, @@ -420,7 +420,7 @@ private function resolveFindingRule(NavigationMatrixRule $rule, Finding $finding 'current_policy_version' => $this->policyVersionEntry( rule: $rule, policyVersionId: $this->findingPolicyVersionId($finding), - tenantId: (int) $finding->tenant_id, + tenantId: (int) $finding->managed_environment_id, ), 'parent_policy' => $this->parentPolicyEntryForFinding($rule, $finding), 'baseline_profile' => $this->baselineProfileEntry( @@ -489,12 +489,12 @@ private function resolveOperationRunRule(NavigationMatrixRule $rule, OperationRu 'backup_set' => $this->backupSetEntry( rule: $rule, backupSetId: is_numeric($context['backup_set_id'] ?? null) ? (int) $context['backup_set_id'] : null, - tenantId: is_numeric($run->tenant_id ?? null) ? (int) $run->tenant_id : null, + tenantId: is_numeric($run->managed_environment_id ?? null) ? (int) $run->managed_environment_id : null, ), 'restore_run' => $this->restoreRunEntry( rule: $rule, restoreRunId: is_numeric($context['restore_run_id'] ?? null) ? (int) $context['restore_run_id'] : null, - tenantId: is_numeric($run->tenant_id ?? null) ? (int) $run->tenant_id : null, + tenantId: is_numeric($run->managed_environment_id ?? null) ? (int) $run->managed_environment_id : null, ), 'baseline_profile' => $this->baselineProfileEntry( rule: $rule, @@ -637,7 +637,7 @@ private function snapshotPolicyVersionEntry(NavigationMatrixRule $rule, Baseline private function backupSetRunEntry(NavigationMatrixRule $rule, BackupSet $backupSet): ?RelatedContextEntry { $candidate = OperationRun::query() - ->where('tenant_id', (int) $backupSet->tenant_id) + ->where('managed_environment_id', (int) $backupSet->managed_environment_id) ->where('context->backup_set_id', (int) $backupSet->getKey()) ->orderByDesc('completed_at') ->orderByDesc('id') @@ -663,7 +663,7 @@ private function operationRunPolicyEntry(NavigationMatrixRule $rule, OperationRu $policy = Policy::query() ->whereKey((int) $policyId) - ->where('tenant_id', (int) $run->tenant_id) + ->where('managed_environment_id', (int) $run->managed_environment_id) ->first(); return $this->policyEntry($rule, $policy); @@ -680,7 +680,7 @@ private function parentPolicyEntryForFinding(NavigationMatrixRule $rule, Finding $version = PolicyVersion::query() ->with('policy') ->whereKey($policyVersionId) - ->where('tenant_id', (int) $finding->tenant_id) + ->where('managed_environment_id', (int) $finding->managed_environment_id) ->first(); if (! $version instanceof PolicyVersion) { @@ -812,7 +812,7 @@ private function policyEntry(NavigationMatrixRule $rule, ?Policy $policy): ?Rela descriptor: new ReferenceDescriptor( referenceClass: ReferenceClass::Policy, rawIdentifier: (string) $policy->getKey(), - tenantId: is_numeric($policy->tenant_id ?? null) ? (int) $policy->tenant_id : null, + tenantId: is_numeric($policy->managed_environment_id ?? null) ? (int) $policy->managed_environment_id : null, sourceType: $rule->sourceType, sourceSurface: $rule->sourceSurface, fallbackLabel: (string) ($policy->display_name ?: 'Policy'), @@ -863,7 +863,7 @@ private function restoreRunEntry( $restoreRun = RestoreRun::query() ->with('tenant') ->whereKey($restoreRunId) - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->first(); if (! $restoreRun instanceof RestoreRun) { @@ -883,16 +883,16 @@ private function restoreRunEntry( targetKind: $rule->targetType, priority: $rule->priority, actionLabel: $this->labels->actionLabel($rule->relationKey), - contextBadge: 'Tenant', + contextBadge: 'ManagedEnvironment', ); } private function operationsEntry( NavigationMatrixRule $rule, - ?Tenant $tenant, + ?ManagedEnvironment $tenant, ?CanonicalNavigationContext $context = null, ): ?RelatedContextEntry { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -909,7 +909,7 @@ private function operationsEntry( targetKind: $rule->targetType, priority: $rule->priority, actionLabel: $this->labels->actionLabel($rule->relationKey), - contextBadge: 'Tenant context', + contextBadge: 'ManagedEnvironment context', ); } @@ -960,11 +960,11 @@ private function canOpenWorkspaceBaselines(int $workspaceId): bool && $this->workspaceCapabilityResolver->can($user, $workspace, Capabilities::WORKSPACE_BASELINES_VIEW); } - private function canOpenTenantRecord(?Tenant $tenant, string $capability): bool + private function canOpenTenantRecord(?ManagedEnvironment $tenant, string $capability): bool { $user = auth()->user(); - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment && $user instanceof User && $this->capabilityResolver->isMember($user, $tenant) && $this->capabilityResolver->can($user, $tenant, $capability); @@ -974,7 +974,7 @@ private function canOpenPolicyVersion(PolicyVersion $version): bool { $tenant = $version->tenant; - if (! $tenant instanceof Tenant || ! $this->canOpenTenantRecord($tenant, Capabilities::TENANT_VIEW)) { + if (! $tenant instanceof ManagedEnvironment || ! $this->canOpenTenantRecord($tenant, Capabilities::TENANT_VIEW)) { return false; } @@ -1008,9 +1008,9 @@ private function contextForFinding(Finding $finding, string $surface): Canonical tenantId: $tenant?->getKey(), backLinkLabel: $backLabel, backLinkUrl: $backUrl, - filterPayload: $tenant instanceof Tenant ? [ + filterPayload: $tenant instanceof ManagedEnvironment ? [ 'tableFilters' => [ - 'tenant_id' => ['value' => (string) $tenant->getKey()], + 'managed_environment_id' => ['value' => (string) $tenant->getKey()], ], ] : [], ); @@ -1030,9 +1030,9 @@ private function contextForPolicyVersion(PolicyVersion $version, string $surface tenantId: $tenant?->getKey(), backLinkLabel: $backLabel, backLinkUrl: $backUrl, - filterPayload: $tenant instanceof Tenant ? [ + filterPayload: $tenant instanceof ManagedEnvironment ? [ 'tableFilters' => [ - 'tenant_id' => ['value' => (string) $tenant->getKey()], + 'managed_environment_id' => ['value' => (string) $tenant->getKey()], ], ] : [], ); @@ -1067,9 +1067,9 @@ private function contextForBackupSet(BackupSet $backupSet, string $surface): Can tenantId: $tenant?->getKey(), backLinkLabel: $backLabel, backLinkUrl: $backUrl, - filterPayload: $tenant instanceof Tenant ? [ + filterPayload: $tenant instanceof ManagedEnvironment ? [ 'tableFilters' => [ - 'tenant_id' => ['value' => (string) $tenant->getKey()], + 'managed_environment_id' => ['value' => (string) $tenant->getKey()], ], ] : [], ); @@ -1085,9 +1085,9 @@ private function contextForOperationRun(OperationRun $run): CanonicalNavigationC tenantId: $tenant?->getKey(), backLinkLabel: 'Back to operations', backLinkUrl: OperationRunLinks::index($tenant), - filterPayload: $tenant instanceof Tenant ? [ + filterPayload: $tenant instanceof ManagedEnvironment ? [ 'tableFilters' => [ - 'tenant_id' => ['value' => (string) $tenant->getKey()], + 'managed_environment_id' => ['value' => (string) $tenant->getKey()], ], ] : [], ); @@ -1097,6 +1097,6 @@ private function activeTenantId(): ?int { $tenant = Filament::getTenant(); - return $tenant instanceof Tenant ? (int) $tenant->getKey() : null; + return $tenant instanceof ManagedEnvironment ? (int) $tenant->getKey() : null; } } diff --git a/apps/platform/app/Support/OperateHub/OperateHubShell.php b/apps/platform/app/Support/OperateHub/OperateHubShell.php index 042f9b73..b4be9d68 100644 --- a/apps/platform/app/Support/OperateHub/OperateHubShell.php +++ b/apps/platform/app/Support/OperateHub/OperateHubShell.php @@ -5,7 +5,7 @@ namespace App\Support\OperateHub; use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -31,8 +31,8 @@ public function scopeLabel(?Request $request = null): string { $activeTenant = $this->activeEntitledTenant($request); - if ($activeTenant instanceof Tenant) { - return 'Tenant scope: '.$activeTenant->name; + if ($activeTenant instanceof ManagedEnvironment) { + return 'ManagedEnvironment scope: '.$activeTenant->name; } return 'All tenants'; @@ -45,7 +45,7 @@ public function returnAffordance(?Request $request = null): ?array { $activeTenant = $this->activeEntitledTenant($request); - if ($activeTenant instanceof Tenant) { + if ($activeTenant instanceof ManagedEnvironment) { return [ 'label' => 'Back to '.$activeTenant->name, 'url' => TenantDashboard::getUrl(panel: 'tenant', tenant: $activeTenant), @@ -83,12 +83,12 @@ public function headerActions( return $actions; } - public function activeEntitledTenant(?Request $request = null): ?Tenant + public function activeEntitledTenant(?Request $request = null): ?ManagedEnvironment { return $this->resolvedContext($request)->tenant; } - public function tenantOwnedPanelContext(?Request $request = null): ?Tenant + public function tenantOwnedPanelContext(?Request $request = null): ?ManagedEnvironment { return $this->activeEntitledTenant($request); } @@ -123,7 +123,7 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo $workspaceSource = match (true) { $workspace instanceof Workspace && $sessionWorkspace instanceof Workspace && $workspace->is($sessionWorkspace) => 'session_workspace', - $workspace instanceof Workspace && $routeTenantCandidate instanceof Tenant && (int) $routeTenantCandidate->workspace_id === (int) $workspace->getKey() => 'route', + $workspace instanceof Workspace && $routeTenantCandidate instanceof ManagedEnvironment && (int) $routeTenantCandidate->workspace_id === (int) $workspace->getKey() => 'route', default => 'none', }; @@ -142,7 +142,7 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo $routeTenant = $this->resolveValidatedRouteTenant($routeTenantCandidate, $workspace, $request, $pageCategory); - if ($routeTenant['tenant'] instanceof Tenant) { + if ($routeTenant['tenant'] instanceof ManagedEnvironment) { return new ResolvedShellContext( workspace: $workspace, tenant: $routeTenant['tenant'], @@ -171,7 +171,7 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo $queryHintTenant = $this->resolveValidatedQueryHintTenant($request, $workspace, $pageCategory); - if ($queryHintTenant['tenant'] instanceof Tenant) { + if ($queryHintTenant['tenant'] instanceof ManagedEnvironment) { return new ResolvedShellContext( workspace: $workspace, tenant: $queryHintTenant['tenant'], @@ -200,7 +200,7 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo $tenant = $this->resolveValidatedFilamentTenant($request, $pageCategory, $workspace); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return new ResolvedShellContext( workspace: $workspace, tenant: $tenant, @@ -215,7 +215,7 @@ private function buildResolvedContext(?Request $request = null): ResolvedShellCo if ($pageCategory->allowsRememberedTenantRestore()) { $rememberedTenant = $this->workspaceContext->rememberedTenant($request); - if ($rememberedTenant instanceof Tenant) { + if ($rememberedTenant instanceof ManagedEnvironment) { return new ResolvedShellContext( workspace: $workspace, tenant: $rememberedTenant, @@ -261,10 +261,10 @@ private function resolveValidatedFilamentTenant( ?Request $request = null, ?TenantPageCategory $pageCategory = null, ?Workspace $workspace = null, - ): ?Tenant { + ): ?ManagedEnvironment { $tenant = Filament::getTenant(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -281,14 +281,14 @@ private function resolveValidatedFilamentTenant( } private function resolveValidatedRouteTenant( - ?Tenant $tenant, + ?ManagedEnvironment $tenant, Workspace $workspace, ?Request $request = null, ?TenantPageCategory $pageCategory = null, ): array { $pageCategory ??= $this->pageCategory($request); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return ['tenant' => null, 'reason' => null]; } @@ -302,7 +302,7 @@ private function resolveValidatedRouteTenant( } private function resolveWorkspaceForPageCategory( - ?Tenant $tenant, + ?ManagedEnvironment $tenant, TenantPageCategory $pageCategory, ?Request $request = null, ): ?Workspace { @@ -324,7 +324,7 @@ private function resolveValidatedQueryHintTenant( $queryTenant = $this->resolveQueryTenantHint($request); - if (! $queryTenant instanceof Tenant) { + if (! $queryTenant instanceof ManagedEnvironment) { return ['tenant' => null, 'reason' => null]; } @@ -337,7 +337,7 @@ private function resolveValidatedQueryHintTenant( return ['tenant' => $queryTenant, 'reason' => null]; } - private function resolveRouteTenantCandidate(?Request $request = null, ?TenantPageCategory $pageCategory = null): ?Tenant + private function resolveRouteTenantCandidate(?Request $request = null, ?TenantPageCategory $pageCategory = null): ?ManagedEnvironment { $route = $request?->route(); $pageCategory ??= $this->pageCategory($request); @@ -357,7 +357,7 @@ private function resolveRouteTenantCandidate(?Request $request = null, ?TenantPa return $this->resolveTenantIdentifier($route->parameter('record')); } - private function resolveQueryTenantHint(?Request $request = null): ?Tenant + private function resolveQueryTenantHint(?Request $request = null): ?ManagedEnvironment { $queryTenant = $request?->query('tenant'); @@ -365,7 +365,7 @@ private function resolveQueryTenantHint(?Request $request = null): ?Tenant return $this->resolveTenantIdentifier($queryTenant); } - $queryTenantId = $request?->query('tenant_id'); + $queryTenantId = $request?->query('managed_environment_id'); if (filled($queryTenantId)) { return $this->resolveTenantIdentifier($queryTenantId); @@ -376,7 +376,7 @@ private function resolveQueryTenantHint(?Request $request = null): ?Tenant private function hasExplicitQueryTenantHint(?Request $request = null): bool { - return filled($request?->query('tenant')) || filled($request?->query('tenant_id')); + return filled($request?->query('tenant')) || filled($request?->query('managed_environment_id')); } private function requiresStrictQueryTenantHintResolution(?Request $request = null): bool @@ -398,9 +398,9 @@ private function requiresStrictQueryTenantHintResolution(?Request $request = nul return preg_match('#^/admin/(inventory|policies|policy-versions|backup-sets|backup-schedules|findings|finding-exceptions)(/|$)#', $path) === 1; } - private function resolveTenantIdentifier(mixed $tenantIdentifier): ?Tenant + private function resolveTenantIdentifier(mixed $tenantIdentifier): ?ManagedEnvironment { - if ($tenantIdentifier instanceof Tenant) { + if ($tenantIdentifier instanceof ManagedEnvironment) { return $tenantIdentifier; } @@ -410,12 +410,12 @@ private function resolveTenantIdentifier(mixed $tenantIdentifier): ?Tenant return null; } - $tenantKeyColumn = (new Tenant)->getQualifiedKeyName(); + $tenantKeyColumn = (new ManagedEnvironment)->getQualifiedKeyName(); - return Tenant::query() + return ManagedEnvironment::query() ->withTrashed() ->where(static function ($query) use ($tenantIdentifier, $tenantKeyColumn): void { - $query->where('external_id', $tenantIdentifier); + $query->where('slug', $tenantIdentifier); if (ctype_digit($tenantIdentifier)) { $query->orWhere($tenantKeyColumn, (int) $tenantIdentifier); @@ -425,7 +425,7 @@ private function resolveTenantIdentifier(mixed $tenantIdentifier): ?Tenant } private function tenantValidationReason( - Tenant $tenant, + ManagedEnvironment $tenant, Workspace $workspace, ?Request $request = null, ?TenantPageCategory $pageCategory = null, @@ -456,7 +456,7 @@ private function tenantValidationReason( actor: $user, workspaceId: (int) $workspace->getKey(), lane: $pageCategory->lane(), - selectedTenant: Filament::getTenant() instanceof Tenant ? Filament::getTenant() : null, + selectedTenant: Filament::getTenant() instanceof ManagedEnvironment ? Filament::getTenant() : null, )->allowed; if ($allowed) { diff --git a/apps/platform/app/Support/OperateHub/ResolvedShellContext.php b/apps/platform/app/Support/OperateHub/ResolvedShellContext.php index 7fc6d28b..6727e1c0 100644 --- a/apps/platform/app/Support/OperateHub/ResolvedShellContext.php +++ b/apps/platform/app/Support/OperateHub/ResolvedShellContext.php @@ -4,7 +4,7 @@ namespace App\Support\OperateHub; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Tenants\TenantPageCategory; @@ -12,7 +12,7 @@ { public function __construct( public ?Workspace $workspace, - public ?Tenant $tenant, + public ?ManagedEnvironment $tenant, public TenantPageCategory $pageCategory, public string $state, public string $displayMode, @@ -30,7 +30,7 @@ public function hasWorkspace(): bool public function hasTenant(): bool { - return $this->tenant instanceof Tenant; + return $this->tenant instanceof ManagedEnvironment; } public function showsRecoveryNotice(): bool diff --git a/apps/platform/app/Support/OperationCatalog.php b/apps/platform/app/Support/OperationCatalog.php index 65925c3f..933f1e09 100644 --- a/apps/platform/app/Support/OperationCatalog.php +++ b/apps/platform/app/Support/OperationCatalog.php @@ -265,7 +265,7 @@ private static function canonicalDefinitions(): array 'restore_run.delete' => new CanonicalOperationType('restore_run.delete', 'intune', null, 'Delete restore runs'), 'restore_run.restore' => new CanonicalOperationType('restore_run.restore', 'intune', null, 'Restore restore runs'), 'restore_run.force_delete' => new CanonicalOperationType('restore_run.force_delete', 'intune', null, 'Force delete restore runs'), - 'tenant.sync' => new CanonicalOperationType('tenant.sync', 'platform_foundation', null, 'Tenant sync'), + 'tenant.sync' => new CanonicalOperationType('tenant.sync', 'platform_foundation', null, 'ManagedEnvironment sync'), 'policy_version.prune' => new CanonicalOperationType('policy_version.prune', 'intune', null, 'Prune policy versions'), 'policy_version.restore' => new CanonicalOperationType('policy_version.restore', 'intune', null, 'Restore policy versions'), 'policy_version.force_delete' => new CanonicalOperationType('policy_version.force_delete', 'intune', null, 'Delete policy versions'), diff --git a/apps/platform/app/Support/OperationRunLinks.php b/apps/platform/app/Support/OperationRunLinks.php index 3f259427..4603fb99 100644 --- a/apps/platform/app/Support/OperationRunLinks.php +++ b/apps/platform/app/Support/OperationRunLinks.php @@ -17,7 +17,7 @@ use App\Models\EvidenceSnapshot; use App\Models\OperationRun; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Support\Navigation\CanonicalNavigationContext; @@ -76,7 +76,7 @@ public static function identifier(OperationRun|int $run): string } public static function index( - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?CanonicalNavigationContext $context = null, ?string $activeTab = null, bool $allTenants = false, @@ -85,8 +85,8 @@ public static function index( ): string { $parameters = $context?->toQuery() ?? []; - if ($tenant instanceof Tenant) { - $parameters['tenant_id'] = (int) $tenant->getKey(); + if ($tenant instanceof ManagedEnvironment) { + $parameters['managed_environment_id'] = (int) $tenant->getKey(); } elseif ($allTenants) { $parameters['tenant_scope'] = 'all'; } @@ -124,7 +124,7 @@ public static function tenantlessView(OperationRun|int $run, ?CanonicalNavigatio )); } - public static function view(OperationRun|int $run, Tenant $tenant, ?CanonicalNavigationContext $context = null): string + public static function view(OperationRun|int $run, ManagedEnvironment $tenant, ?CanonicalNavigationContext $context = null): string { return self::tenantlessView($run, $context); } @@ -132,7 +132,7 @@ public static function view(OperationRun|int $run, Tenant $tenant, ?CanonicalNav /** * @return array */ - public static function related(OperationRun $run, ?Tenant $tenant): array + public static function related(OperationRun $run, ?ManagedEnvironment $tenant): array { $context = is_array($run->context) ? $run->context : []; @@ -140,7 +140,7 @@ public static function related(OperationRun $run, ?Tenant $tenant): array $links[self::collectionLabel()] = self::index($tenant); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return $links; } @@ -221,7 +221,7 @@ public static function related(OperationRun $run, ?Tenant $tenant): array ->first(); if ($review instanceof TenantReview) { - $links['Tenant Review'] = TenantReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant); + $links['ManagedEnvironment Review'] = TenantReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant); } } diff --git a/apps/platform/app/Support/Operations/ExecutionDenialReasonCode.php b/apps/platform/app/Support/Operations/ExecutionDenialReasonCode.php index ad9b8151..8ec38461 100644 --- a/apps/platform/app/Support/Operations/ExecutionDenialReasonCode.php +++ b/apps/platform/app/Support/Operations/ExecutionDenialReasonCode.php @@ -53,10 +53,10 @@ public function operatorLabel(): string { return match ($this) { self::WorkspaceMismatch => 'Workspace context changed', - self::TenantNotEntitled => 'Tenant access removed', + self::TenantNotEntitled => 'ManagedEnvironment access removed', self::MissingCapability => 'Permission required', - self::TenantNotOperable => 'Tenant not ready', - self::TenantMissing => 'Tenant record unavailable', + self::TenantNotOperable => 'ManagedEnvironment not ready', + self::TenantMissing => 'ManagedEnvironment record unavailable', self::InitiatorMissing => 'Initiator no longer available', self::InitiatorNotEntitled => 'Initiator lost tenant access', self::ProviderConnectionInvalid => 'Provider connection needs review', diff --git a/apps/platform/app/Support/Operations/QueuedExecutionContext.php b/apps/platform/app/Support/Operations/QueuedExecutionContext.php index 1e3cf105..a1ef63c8 100644 --- a/apps/platform/app/Support/Operations/QueuedExecutionContext.php +++ b/apps/platform/app/Support/Operations/QueuedExecutionContext.php @@ -5,13 +5,13 @@ namespace App\Support\Operations; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; final readonly class QueuedExecutionContext { /** - * @param array{workspace_id:int,tenant_id:int|null,provider_connection_id:int|null} $targetScope + * @param array{workspace_id:int,managed_environment_id:int|null,provider_connection_id:int|null} $targetScope * @param list $prerequisiteClasses * @param array $metadata */ @@ -19,15 +19,15 @@ public function __construct( public OperationRun $run, public string $operationType, public int $workspaceId, - public ?Tenant $tenant, + public ?ManagedEnvironment $tenant, public ?User $initiator, public ExecutionAuthorityMode $authorityMode, public ?string $requiredCapability, - public ?string $workspaceRequiredCapability, public ?int $providerConnectionId, public array $targetScope, public array $prerequisiteClasses = [], public array $metadata = [], + public ?string $workspaceRequiredCapability = null, ) {} /** diff --git a/apps/platform/app/Support/Operations/QueuedExecutionLegitimacyDecision.php b/apps/platform/app/Support/Operations/QueuedExecutionLegitimacyDecision.php index 3f86dfcb..442e7ca6 100644 --- a/apps/platform/app/Support/Operations/QueuedExecutionLegitimacyDecision.php +++ b/apps/platform/app/Support/Operations/QueuedExecutionLegitimacyDecision.php @@ -8,7 +8,7 @@ { /** * @param array{identity_type:string,user_id:int|null}|null $initiator - * @param array{workspace_id:int,tenant_id:int|null,provider_connection_id:int|null} $targetScope + * @param array{workspace_id:int,managed_environment_id:int|null,provider_connection_id:int|null} $targetScope * @param array{workspace_scope:string,tenant_scope:string,capability:string,tenant_operability:string,execution_prerequisites:string} $checks * @param array $metadata */ diff --git a/apps/platform/app/Support/OpsUx/ActiveRuns.php b/apps/platform/app/Support/OpsUx/ActiveRuns.php index e45e5d8a..c1a73656 100644 --- a/apps/platform/app/Support/OpsUx/ActiveRuns.php +++ b/apps/platform/app/Support/OpsUx/ActiveRuns.php @@ -5,7 +5,7 @@ namespace App\Support\OpsUx; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use Illuminate\Database\Eloquent\Builder; @@ -18,7 +18,7 @@ final class ActiveRuns public static function queryForTenantId(?int $tenantId): Builder { return OperationRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->active() ->orderByDesc('created_at'); } @@ -26,7 +26,7 @@ public static function queryForTenantId(?int $tenantId): Builder public static function shellVisibleQueryForTenantId(?int $tenantId): Builder { return OperationRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where(function (Builder $query): void { $query ->where(function (Builder $activeQuery): void { @@ -106,7 +106,7 @@ public static function shellVisibleCountForTenantId(?int $tenantId): int return self::shellVisibleQueryForTenantId($tenantId)->count(); } - public static function existForTenant(Tenant $tenant): bool + public static function existForTenant(ManagedEnvironment $tenant): bool { return self::existForTenantId((int) $tenant->getKey()); } @@ -118,14 +118,14 @@ public static function existForTenantId(?int $tenantId): bool } return OperationRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->healthyActive() ->exists(); } - public static function pollingIntervalForTenant(?Tenant $tenant): ?string + public static function pollingIntervalForTenant(?ManagedEnvironment $tenant): ?string { - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment ? self::pollingIntervalForTenantId((int) $tenant->getKey()) : null; } diff --git a/apps/platform/app/Support/OpsUx/AssignmentJobFingerprint.php b/apps/platform/app/Support/OpsUx/AssignmentJobFingerprint.php index d79f47f2..dd0acb81 100644 --- a/apps/platform/app/Support/OpsUx/AssignmentJobFingerprint.php +++ b/apps/platform/app/Support/OpsUx/AssignmentJobFingerprint.php @@ -32,7 +32,7 @@ public static function forRestore( ): string { return self::hash('assignments.restore', [ 'restore_run_id' => $restoreRunId, - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'policy_type' => trim($policyType), 'policy_id' => trim($policyId), 'assignments' => self::normalizeAssignments($assignments), diff --git a/apps/platform/app/Support/OpsUx/OperationRunUrl.php b/apps/platform/app/Support/OpsUx/OperationRunUrl.php index 256a5754..a48602db 100644 --- a/apps/platform/app/Support/OpsUx/OperationRunUrl.php +++ b/apps/platform/app/Support/OpsUx/OperationRunUrl.php @@ -5,17 +5,17 @@ namespace App\Support\OpsUx; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunLinks; final class OperationRunUrl { - public static function view(OperationRun $run, Tenant $tenant): string + public static function view(OperationRun $run, ManagedEnvironment $tenant): string { return OperationRunLinks::view($run, $tenant); } - public static function index(Tenant $tenant): string + public static function index(ManagedEnvironment $tenant): string { return OperationRunLinks::index($tenant); } diff --git a/apps/platform/app/Support/OpsUx/OperationUxPresenter.php b/apps/platform/app/Support/OpsUx/OperationUxPresenter.php index 758770c0..dfb6bdad 100644 --- a/apps/platform/app/Support/OpsUx/OperationUxPresenter.php +++ b/apps/platform/app/Support/OpsUx/OperationUxPresenter.php @@ -9,7 +9,7 @@ use App\Models\Finding; use App\Models\OperationRun; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationCatalog; use App\Support\OperationRunLinks; use App\Support\Operations\OperationRunFreshnessState; @@ -91,7 +91,7 @@ public static function scopeBusyToast( * @param array $event * @return array */ - public static function findingDatabaseNotificationMessage(Finding $finding, Tenant $tenant, array $event): array + public static function findingDatabaseNotificationMessage(Finding $finding, ManagedEnvironment $tenant, array $event): array { return self::databaseNotificationMessage( title: self::findingNotificationTitle($event), @@ -135,10 +135,10 @@ public static function queuedDatabaseNotificationMessage(OperationRun $run, obje * Note: We intentionally return the built Filament notification builder to * keep DB formatting consistent with existing Notification classes. */ - public static function terminalDatabaseNotification(OperationRun $run, ?Tenant $tenant = null): FilamentNotification + public static function terminalDatabaseNotification(OperationRun $run, ?ManagedEnvironment $tenant = null): FilamentNotification { $payload = self::terminalNotificationPayload($run); - $actionUrl = $tenant instanceof Tenant + $actionUrl = $tenant instanceof ManagedEnvironment ? OperationRunUrl::view($run, $tenant) : OperationRunLinks::tenantlessView($run); @@ -605,7 +605,7 @@ private static function operationRunPrimaryAction(OperationRun $run, object $not ]; } - if ($run->tenant instanceof Tenant) { + if ($run->tenant instanceof ManagedEnvironment) { return [ 'label' => OperationRunLinks::openLabel(), 'url' => OperationRunLinks::view($run, $run->tenant), diff --git a/apps/platform/app/Support/OpsUx/RunDurationInsights.php b/apps/platform/app/Support/OpsUx/RunDurationInsights.php index 05842a28..7305c395 100644 --- a/apps/platform/app/Support/OpsUx/RunDurationInsights.php +++ b/apps/platform/app/Support/OpsUx/RunDurationInsights.php @@ -79,7 +79,7 @@ public static function expectedSeconds(OperationRun $run): ?int return $catalog; } - $tenantId = (int) ($run->tenant_id ?? 0); + $tenantId = (int) ($run->managed_environment_id ?? 0); $type = (string) ($run->type ?? ''); if ($tenantId <= 0 || $type === '') { @@ -90,7 +90,7 @@ public static function expectedSeconds(OperationRun $run): ?int return Cache::remember($cacheKey, now()->addMinutes(10), function () use ($tenantId, $type): ?int { $durations = OperationRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('type', $type) ->whereNotNull('started_at') ->whereNotNull('completed_at') diff --git a/apps/platform/app/Support/PortfolioCompare/CrossTenantComparePreviewBuilder.php b/apps/platform/app/Support/PortfolioCompare/CrossTenantComparePreviewBuilder.php index 6232faa7..c0317bc3 100644 --- a/apps/platform/app/Support/PortfolioCompare/CrossTenantComparePreviewBuilder.php +++ b/apps/platform/app/Support/PortfolioCompare/CrossTenantComparePreviewBuilder.php @@ -5,7 +5,7 @@ namespace App\Support\PortfolioCompare; use App\Models\InventoryItem; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\CurrentStateHashResolver; use App\Services\Baselines\Evidence\EvidenceProvenance; use App\Services\Baselines\Evidence\ResolvedEvidence; @@ -100,7 +100,7 @@ public function build(CrossTenantCompareSelection $selection): array } /** - * @param Tenant $tenant + * @param ManagedEnvironment $tenant * @param list $policyTypes * @return array{ * preview_subjects: list>, @@ -108,10 +108,10 @@ public function build(CrossTenantCompareSelection $selection): array * subjects: array> * } */ - private function indexTenantSubjects(Tenant $tenant, array $policyTypes): array + private function indexTenantSubjects(ManagedEnvironment $tenant, array $policyTypes): array { $inventoryItems = InventoryItem::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->when( $policyTypes !== [], fn ($query) => $query->whereIn('policy_type', $policyTypes), @@ -203,8 +203,8 @@ private function indexTenantSubjects(Tenant $tenant, array $policyTypes): array */ private function buildPreviewSubject( array $sourceSubject, - Tenant $sourceTenant, - Tenant $targetTenant, + ManagedEnvironment $sourceTenant, + ManagedEnvironment $targetTenant, array $targetIndex, array $sourceEvidence, array $targetEvidence, @@ -306,7 +306,7 @@ private function buildPreviewSubject( * @param list $subjects * @return array */ - private function resolvedEvidenceMap(Tenant $tenant, array $subjects): array + private function resolvedEvidenceMap(ManagedEnvironment $tenant, array $subjects): array { return $this->currentStateHashResolver->resolveForSubjects($tenant, $subjects); } @@ -315,7 +315,7 @@ private function resolvedEvidenceMap(Tenant $tenant, array $subjects): array * @param array|null $subject * @return array */ - private function subjectSidePayload(Tenant $tenant, ?array $subject, ?ResolvedEvidence $evidence): array + private function subjectSidePayload(ManagedEnvironment $tenant, ?array $subject, ?ResolvedEvidence $evidence): array { return [ 'tenantId' => (int) $tenant->getKey(), @@ -339,7 +339,7 @@ private function subjectSidePayload(Tenant $tenant, ?array $subject, ?ResolvedEv * lastSeenAt: ?string * } */ - private function inventorySubjectRecord(Tenant $tenant, InventoryItem $inventoryItem, string $policyType, ?string $subjectKey): array + private function inventorySubjectRecord(ManagedEnvironment $tenant, InventoryItem $inventoryItem, string $policyType, ?string $subjectKey): array { $displayName = is_string($inventoryItem->display_name ?? null) ? trim((string) $inventoryItem->display_name) : ''; $displayName = $displayName !== '' diff --git a/apps/platform/app/Support/PortfolioCompare/CrossTenantCompareSelection.php b/apps/platform/app/Support/PortfolioCompare/CrossTenantCompareSelection.php index 46a59b5a..cba26913 100644 --- a/apps/platform/app/Support/PortfolioCompare/CrossTenantCompareSelection.php +++ b/apps/platform/app/Support/PortfolioCompare/CrossTenantCompareSelection.php @@ -4,14 +4,14 @@ namespace App\Support\PortfolioCompare; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use InvalidArgumentException; final readonly class CrossTenantCompareSelection { - public Tenant $sourceTenant; + public ManagedEnvironment $sourceTenant; - public Tenant $targetTenant; + public ManagedEnvironment $targetTenant; /** * @var list @@ -22,8 +22,8 @@ * @param list $policyTypes */ public function __construct( - Tenant $sourceTenant, - Tenant $targetTenant, + ManagedEnvironment $sourceTenant, + ManagedEnvironment $targetTenant, array $policyTypes = [], ) { $this->sourceTenant = $sourceTenant; diff --git a/apps/platform/app/Support/PortfolioCompare/CrossTenantPromotionExecutionPlanner.php b/apps/platform/app/Support/PortfolioCompare/CrossTenantPromotionExecutionPlanner.php index 35da13ed..fe8e99f1 100644 --- a/apps/platform/app/Support/PortfolioCompare/CrossTenantPromotionExecutionPlanner.php +++ b/apps/platform/app/Support/PortfolioCompare/CrossTenantPromotionExecutionPlanner.php @@ -161,14 +161,14 @@ private function executionItem(array $subject): ?array 'execution_action' => $action, 'readiness_reason_codes' => $this->stringList(data_get($subject, 'preflight.reasonCodes', [])), 'source' => [ - 'tenant_id' => $this->intValue(data_get($subject, 'source.tenantId')), + 'managed_environment_id' => $this->intValue(data_get($subject, 'source.tenantId')), 'inventory_item_id' => $this->intValue(data_get($subject, 'source.inventoryItemId')), 'subject_external_id' => $this->nullableString(data_get($subject, 'source.subjectExternalId')), 'policy_version_id' => (int) $policyVersionId, 'evidence_hash' => $this->nullableString(data_get($subject, 'source.evidence.hash')), ], 'target' => [ - 'tenant_id' => $this->intValue(data_get($subject, 'target.tenantId')), + 'managed_environment_id' => $this->intValue(data_get($subject, 'target.tenantId')), 'inventory_item_id' => $this->intValue(data_get($subject, 'target.inventoryItemId')), 'subject_external_id' => $this->nullableString(data_get($subject, 'target.subjectExternalId')), ], diff --git a/apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContext.php b/apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContext.php index ea249816..650b3d70 100644 --- a/apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContext.php +++ b/apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContext.php @@ -40,7 +40,7 @@ public function sourceLabel(): string { return match ($this->sourceSurface) { PortfolioArrivalContextToken::SOURCE_WORKSPACE_OVERVIEW => 'Workspace overview triage', - PortfolioArrivalContextToken::SOURCE_TENANT_REGISTRY => 'Tenant registry triage', + PortfolioArrivalContextToken::SOURCE_TENANT_REGISTRY => 'ManagedEnvironment registry triage', default => 'Portfolio triage', }; } diff --git a/apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextResolver.php b/apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextResolver.php index 9c8e7958..5aca8808 100644 --- a/apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextResolver.php +++ b/apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextResolver.php @@ -8,7 +8,7 @@ use App\Filament\Resources\RestoreRunResource; use App\Filament\Resources\TenantResource; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -34,7 +34,7 @@ public function __construct( private WorkspaceContext $workspaceContext, ) {} - public function resolve(Request $request, Tenant $tenant): ?PortfolioArrivalContext + public function resolve(Request $request, ManagedEnvironment $tenant): ?PortfolioArrivalContext { if ($request->attributes->has(self::REQUEST_CACHE_HIT_KEY)) { $cached = $request->attributes->get(self::REQUEST_CACHE_KEY); @@ -72,7 +72,7 @@ public function resolve(Request $request, Tenant $tenant): ?PortfolioArrivalCont * returnFilters: array|null * }|null $state */ - public function resolveState(Tenant $tenant, ?array $state): ?PortfolioArrivalContext + public function resolveState(ManagedEnvironment $tenant, ?array $state): ?PortfolioArrivalContext { return $this->resolveStateWithTruth($tenant, $state); } @@ -90,7 +90,7 @@ public function resolveState(Tenant $tenant, ?array $state): ?PortfolioArrivalCo * @param array|null $recoveryEvidence */ public function resolveStateWithTruth( - Tenant $tenant, + ManagedEnvironment $tenant, ?array $state, ?TenantBackupHealthAssessment $backupHealth = null, ?array $recoveryEvidence = null, @@ -114,7 +114,7 @@ public function resolveStateWithTruth( * returnFilters: array|null * } $state */ - private function matchesRequestScope(Tenant $tenant, Request $request, array $state): bool + private function matchesRequestScope(ManagedEnvironment $tenant, Request $request, array $state): bool { if (! $this->matchesTenantScope($tenant, $state)) { return false; @@ -137,7 +137,7 @@ private function matchesRequestScope(Tenant $tenant, Request $request, array $st * returnFilters: array|null * } $state */ - private function matchesTenantScope(Tenant $tenant, array $state): bool + private function matchesTenantScope(ManagedEnvironment $tenant, array $state): bool { $tenantRouteKey = $state['tenantRouteKey']; @@ -175,7 +175,7 @@ private function matchesTenantScope(Tenant $tenant, array $state): bool * @param array|null $recoveryEvidence */ private function buildContext( - Tenant $tenant, + ManagedEnvironment $tenant, array $state, ?TenantBackupHealthAssessment $backupHealth = null, ?array $recoveryEvidence = null, @@ -274,7 +274,7 @@ private function claimBoundary( * } */ private function nextStepTarget( - Tenant $tenant, + ManagedEnvironment $tenant, string $concernFamily, string $concernState, ?string $concernReason, @@ -305,7 +305,7 @@ private function nextStepTarget( * helperText: string|null * } */ - private function backupNextStepTarget(Tenant $tenant, string $concernState, ?string $concernReason): array + private function backupNextStepTarget(ManagedEnvironment $tenant, string $concernState, ?string $concernReason): array { $label = 'Open backup sets'; @@ -343,7 +343,7 @@ private function backupNextStepTarget(Tenant $tenant, string $concernState, ?str * } */ private function recoveryNextStepTarget( - Tenant $tenant, + ManagedEnvironment $tenant, string $concernState, ?string $concernReason, array $recoveryEvidence, @@ -395,7 +395,7 @@ private function recoveryNextStepTarget( ], true) && $latestRunId !== null) { if (RestoreRun::query() ->whereKey($latestRunId) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->exists()) { return [ 'kind' => 'restore_run_detail', @@ -536,7 +536,7 @@ private function currentTruthDelta( return $parts !== [] ? implode(' ', $parts) : null; } - private function canOpenTenantFollowUp(Tenant $tenant): bool + private function canOpenTenantFollowUp(ManagedEnvironment $tenant): bool { $user = auth()->user(); diff --git a/apps/platform/app/Support/PortfolioTriage/TenantTriageReviewStateResolver.php b/apps/platform/app/Support/PortfolioTriage/TenantTriageReviewStateResolver.php index 99a52281..bb748300 100644 --- a/apps/platform/app/Support/PortfolioTriage/TenantTriageReviewStateResolver.php +++ b/apps/platform/app/Support/PortfolioTriage/TenantTriageReviewStateResolver.php @@ -55,13 +55,13 @@ public function resolveMany( $activeReviews = TenantTriageReview::query() ->with('reviewer:id,name,email') ->forWorkspace($workspaceId) - ->whereIn('tenant_id', $tenantIds) + ->whereIn('managed_environment_id', $tenantIds) ->active() ->orderByDesc('reviewed_at') ->orderByDesc('id') ->get() ->groupBy([ - 'tenant_id', + 'managed_environment_id', 'concern_family', ]); @@ -131,7 +131,7 @@ private function resolveFamily( if ($currentConcern === null) { return [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'concern_family' => $concernFamily, 'current_concern_present' => false, 'current_state' => null, @@ -153,7 +153,7 @@ private function resolveFamily( }; return [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'concern_family' => $concernFamily, 'current_concern_present' => true, 'current_state' => $currentConcern['concern_state'], diff --git a/apps/platform/app/Support/ProductKnowledge/ContextualHelpResolver.php b/apps/platform/app/Support/ProductKnowledge/ContextualHelpResolver.php index 320ac80e..b284a457 100644 --- a/apps/platform/app/Support/ProductKnowledge/ContextualHelpResolver.php +++ b/apps/platform/app/Support/ProductKnowledge/ContextualHelpResolver.php @@ -5,7 +5,7 @@ namespace App\Support\ProductKnowledge; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Ai\AiDataClassification; use App\Support\Governance\PlatformVocabularyGlossary; use App\Support\Links\RequiredPermissionsLinks; @@ -258,7 +258,7 @@ private function providerReasonEnvelope(array $context): ?ReasonResolutionEnvelo $connection = $context['connection'] ?? null; $surface = $this->stringOrNull($context['surface'] ?? null) ?? 'detail'; - if (! $tenant instanceof Tenant || ! is_string($reasonCode) || trim($reasonCode) === '') { + if (! $tenant instanceof ManagedEnvironment || ! is_string($reasonCode) || trim($reasonCode) === '') { return null; } @@ -409,7 +409,7 @@ private function resolveLink(array $link, mixed $tenant): ?array 'resolver' => $this->stringOrNull($link['resolver'] ?? null), ]; - if (! $tenant instanceof Tenant || $resolved['resolver'] === null) { + if (! $tenant instanceof ManagedEnvironment || $resolved['resolver'] === null) { return $resolved; } diff --git a/apps/platform/app/Support/ProductTelemetry/ProductTelemetryRecorder.php b/apps/platform/app/Support/ProductTelemetry/ProductTelemetryRecorder.php index bbd6b41d..230e6ae1 100644 --- a/apps/platform/app/Support/ProductTelemetry/ProductTelemetryRecorder.php +++ b/apps/platform/app/Support/ProductTelemetry/ProductTelemetryRecorder.php @@ -31,7 +31,7 @@ public function record( return ProductUsageEvent::query()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'user_id' => $userId, 'event_name' => $eventName, 'feature_area' => $this->catalog->featureArea($eventName), diff --git a/apps/platform/app/Support/Providers/ProviderNextStepsRegistry.php b/apps/platform/app/Support/Providers/ProviderNextStepsRegistry.php index 4e8ca724..46415098 100644 --- a/apps/platform/app/Support/Providers/ProviderNextStepsRegistry.php +++ b/apps/platform/app/Support/Providers/ProviderNextStepsRegistry.php @@ -3,7 +3,7 @@ namespace App\Support\Providers; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\ReasonTranslation\ReasonPresenter; final class ProviderNextStepsRegistry @@ -15,7 +15,7 @@ public function __construct( /** * @return array */ - public function forReason(Tenant $tenant, string $reasonCode, ?ProviderConnection $connection = null): array + public function forReason(ManagedEnvironment $tenant, string $reasonCode, ?ProviderConnection $connection = null): array { $envelope = $this->reasonPresenter->forProviderReason($tenant, $reasonCode, $connection, 'helper_copy'); diff --git a/apps/platform/app/Support/Providers/ProviderReasonTranslator.php b/apps/platform/app/Support/Providers/ProviderReasonTranslator.php index d91d095a..61cddb13 100644 --- a/apps/platform/app/Support/Providers/ProviderReasonTranslator.php +++ b/apps/platform/app/Support/Providers/ProviderReasonTranslator.php @@ -6,7 +6,7 @@ use App\Filament\Resources\ProviderConnectionResource; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Links\RequiredPermissionsLinks; use App\Support\ReasonTranslation\Contracts\TranslatesReasonCode; use App\Support\ReasonTranslation\NextStepOption; @@ -43,7 +43,7 @@ public function translate(string $reasonCode, string $surface = 'detail', array $tenant = $context['tenant'] ?? null; $connection = $context['connection'] ?? null; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { $nextSteps = $this->fallbackNextSteps($normalizedCode); } else { $nextSteps = $this->nextStepsFor($tenant, $normalizedCode, $connection instanceof ProviderConnection ? $connection : null); @@ -281,7 +281,7 @@ private function fallbackNextSteps(string $reasonCode): array * @return array */ private function nextStepsFor( - Tenant $tenant, + ManagedEnvironment $tenant, string $reasonCode, ?ProviderConnection $connection = null, ): array { diff --git a/apps/platform/app/Support/Rbac/TenantAccessContext.php b/apps/platform/app/Support/Rbac/TenantAccessContext.php index 07350f13..b5d70d63 100644 --- a/apps/platform/app/Support/Rbac/TenantAccessContext.php +++ b/apps/platform/app/Support/Rbac/TenantAccessContext.php @@ -4,7 +4,7 @@ namespace App\Support\Rbac; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; /** @@ -17,7 +17,7 @@ { public function __construct( public ?User $user, - public ?Tenant $tenant, + public ?ManagedEnvironment $tenant, public bool $isMember, public bool $hasCapability, ) {} diff --git a/apps/platform/app/Support/Rbac/UiEnforcement.php b/apps/platform/app/Support/Rbac/UiEnforcement.php index 96a97c54..bd42a1f4 100644 --- a/apps/platform/app/Support/Rbac/UiEnforcement.php +++ b/apps/platform/app/Support/Rbac/UiEnforcement.php @@ -4,7 +4,7 @@ namespace App\Support\Rbac; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -553,14 +553,14 @@ private function resolveTenantIdsFromRecords(Collection $records): array $tenantIds = []; foreach ($records as $record) { - if ($record instanceof Tenant) { + if ($record instanceof ManagedEnvironment) { $tenantIds[] = (int) $record->getKey(); continue; } if ($record instanceof Model) { - $tenantId = $record->getAttribute('tenant_id'); + $tenantId = $record->getAttribute('managed_environment_id'); if ($tenantId !== null) { $tenantIds[] = (int) $tenantId; @@ -570,7 +570,7 @@ private function resolveTenantIdsFromRecords(Collection $records): array if (method_exists($record, 'relationLoaded') && $record->relationLoaded('tenant')) { $relatedTenant = $record->getRelation('tenant'); - if ($relatedTenant instanceof Tenant) { + if ($relatedTenant instanceof ManagedEnvironment) { $tenantIds[] = (int) $relatedTenant->getKey(); continue; @@ -581,7 +581,7 @@ private function resolveTenantIdsFromRecords(Collection $records): array if ($tenantIds === []) { $tenant = Filament::getTenant(); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $tenantIds[] = (int) $tenant->getKey(); } } @@ -589,9 +589,9 @@ private function resolveTenantIdsFromRecords(Collection $records): array return array_values(array_unique($tenantIds)); } - private function makeTenantStub(int $tenantId): Tenant + private function makeTenantStub(int $tenantId): ManagedEnvironment { - $tenant = new Tenant; + $tenant = new ManagedEnvironment; $tenant->forceFill(['id' => $tenantId]); $tenant->exists = true; @@ -605,10 +605,10 @@ private function resolveContextWithRecord(?Model $record = null): TenantAccessCo { $user = auth()->user(); - // For table actions, resolve the record and use it as tenant if it's a Tenant + // For table actions, resolve the record and use it as tenant if it's a ManagedEnvironment $tenant = $this->resolveTenantWithRecord($record); - if (! $user instanceof User || ! $tenant instanceof Tenant) { + if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment) { return new TenantAccessContext( user: null, tenant: null, @@ -639,14 +639,14 @@ private function resolveContextWithRecord(?Model $record = null): TenantAccessCo * Resolve the tenant for this action with an optional record. * * Priority: - * 1. If $record is passed and is a Tenant, use it + * 1. If $record is passed and is a ManagedEnvironment, use it * 2. If $this->record is set (for forTableAction), resolve it * 3. Fall back to Filament::getTenant() */ - private function resolveTenantWithRecord(?Model $record = null): ?Tenant + private function resolveTenantWithRecord(?Model $record = null): ?ManagedEnvironment { - // If a record is passed directly (from closure parameter), check if it's a Tenant - if ($record instanceof Tenant) { + // If a record is passed directly (from closure parameter), check if it's a ManagedEnvironment + if ($record instanceof ManagedEnvironment) { return $record; } @@ -655,7 +655,7 @@ private function resolveTenantWithRecord(?Model $record = null): ?Tenant if ($record instanceof Model && method_exists($record, 'relationLoaded') && $record->relationLoaded('tenant')) { $relatedTenant = $record->getRelation('tenant'); - if ($relatedTenant instanceof Tenant) { + if ($relatedTenant instanceof ManagedEnvironment) { return $relatedTenant; } } @@ -663,14 +663,14 @@ private function resolveTenantWithRecord(?Model $record = null): ?Tenant if ($this->action instanceof Action) { $actionRecord = $this->action->getRecord(withDefault: false); - if ($actionRecord instanceof Tenant) { + if ($actionRecord instanceof ManagedEnvironment) { return $actionRecord; } if ($actionRecord instanceof Model && method_exists($actionRecord, 'relationLoaded') && $actionRecord->relationLoaded('tenant')) { $relatedTenant = $actionRecord->getRelation('tenant'); - if ($relatedTenant instanceof Tenant) { + if ($relatedTenant instanceof ManagedEnvironment) { return $relatedTenant; } } @@ -682,7 +682,7 @@ private function resolveTenantWithRecord(?Model $record = null): ?Tenant ? ($this->record)() : $this->record; - if ($resolved instanceof Tenant) { + if ($resolved instanceof ManagedEnvironment) { return $resolved; } } diff --git a/apps/platform/app/Support/ReasonTranslation/ReasonPresenter.php b/apps/platform/app/Support/ReasonTranslation/ReasonPresenter.php index 3ef1f029..eeb1432a 100644 --- a/apps/platform/app/Support/ReasonTranslation/ReasonPresenter.php +++ b/apps/platform/app/Support/ReasonTranslation/ReasonPresenter.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Operations\ExecutionDenialReasonCode; use App\Support\Operations\LifecycleReconciliationReason; use App\Support\Providers\ProviderReasonCodes; @@ -125,7 +125,7 @@ private function isDirectlyTranslatableOperationReason(string $reasonCode): bool } public function forProviderReason( - Tenant $tenant, + ManagedEnvironment $tenant, string $reasonCode, ?ProviderConnection $connection = null, string $surface = 'detail', diff --git a/apps/platform/app/Support/References/Resolvers/AssignmentTargetReferenceResolver.php b/apps/platform/app/Support/References/Resolvers/AssignmentTargetReferenceResolver.php index aecd00e0..7a9a8db9 100644 --- a/apps/platform/app/Support/References/Resolvers/AssignmentTargetReferenceResolver.php +++ b/apps/platform/app/Support/References/Resolvers/AssignmentTargetReferenceResolver.php @@ -59,7 +59,7 @@ public function resolve(array $target, array $context = []): ResolvedReference return $this->registry->resolve(new ReferenceDescriptor( referenceClass: ReferenceClass::Group, rawIdentifier: $targetId, - tenantId: is_numeric($context['tenant_id'] ?? null) ? (int) $context['tenant_id'] : null, + tenantId: is_numeric($context['managed_environment_id'] ?? null) ? (int) $context['managed_environment_id'] : null, fallbackLabel: is_string($groupDescription['display_name'] ?? null) ? $groupDescription['display_name'] : (is_string($target['group_display_name'] ?? null) ? $target['group_display_name'] : null), diff --git a/apps/platform/app/Support/References/Resolvers/BackupSetReferenceResolver.php b/apps/platform/app/Support/References/Resolvers/BackupSetReferenceResolver.php index 69c09201..935a7445 100644 --- a/apps/platform/app/Support/References/Resolvers/BackupSetReferenceResolver.php +++ b/apps/platform/app/Support/References/Resolvers/BackupSetReferenceResolver.php @@ -6,7 +6,7 @@ use App\Filament\Resources\BackupSetResource; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -41,7 +41,7 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference $backupSet = BackupSet::query() ->with('tenant') ->whereKey($backupSetId) - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->first(); if (! $backupSet instanceof BackupSet) { @@ -60,16 +60,16 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference targetKind: ReferenceClass::BackupSet->value, url: BackupSetResource::getUrl('view', ['record' => $backupSet], panel: 'tenant', tenant: $backupSet->tenant), actionLabel: 'View backup set', - contextBadge: 'Tenant', + contextBadge: 'ManagedEnvironment', ), ); } - private function canOpenTenantRecord(?Tenant $tenant, string $capability): bool + private function canOpenTenantRecord(?ManagedEnvironment $tenant, string $capability): bool { $user = auth()->user(); - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment && $user instanceof User && $this->capabilityResolver->isMember($user, $tenant) && $this->capabilityResolver->can($user, $tenant, $capability); diff --git a/apps/platform/app/Support/References/Resolvers/EntraGroupReferenceResolver.php b/apps/platform/app/Support/References/Resolvers/EntraGroupReferenceResolver.php index b565eec3..331344ac 100644 --- a/apps/platform/app/Support/References/Resolvers/EntraGroupReferenceResolver.php +++ b/apps/platform/app/Support/References/Resolvers/EntraGroupReferenceResolver.php @@ -6,7 +6,7 @@ use App\Filament\Resources\EntraGroupResource; use App\Models\EntraGroup; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Directory\EntraGroupLabelResolver; @@ -39,9 +39,9 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference return $this->unresolved($descriptor, primaryLabel: 'Group'); } - $tenant = Tenant::query()->whereKey($tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey($tenantId)->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return $this->unresolved($descriptor, primaryLabel: 'Group'); } @@ -49,7 +49,7 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference $resolvedFromCache = $descriptor->contextValue('resolved_from_cache'); $group = EntraGroup::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('entra_id', strtolower($descriptor->rawIdentifier)) ->first(); @@ -71,7 +71,7 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference targetKind: ReferenceClass::Group->value, url: EntraGroupResource::scopedUrl('view', ['record' => $group], $group->tenant), actionLabel: 'View group', - contextBadge: 'Tenant', + contextBadge: 'ManagedEnvironment', ), ); } @@ -85,11 +85,11 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference return $this->unresolved($descriptor, primaryLabel: 'Group'); } - private function canOpenTenantRecord(?Tenant $tenant, string $capability): bool + private function canOpenTenantRecord(?ManagedEnvironment $tenant, string $capability): bool { $user = auth()->user(); - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment && $user instanceof User && $this->capabilityResolver->isMember($user, $tenant) && $this->capabilityResolver->can($user, $tenant, $capability); diff --git a/apps/platform/app/Support/References/Resolvers/EntraRoleDefinitionReferenceResolver.php b/apps/platform/app/Support/References/Resolvers/EntraRoleDefinitionReferenceResolver.php index 4621086f..94f15485 100644 --- a/apps/platform/app/Support/References/Resolvers/EntraRoleDefinitionReferenceResolver.php +++ b/apps/platform/app/Support/References/Resolvers/EntraRoleDefinitionReferenceResolver.php @@ -31,7 +31,7 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference } $roleDefinition = EntraRoleDefinition::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('entra_id', $descriptor->rawIdentifier) ->first(); diff --git a/apps/platform/app/Support/References/Resolvers/OperationRunReferenceResolver.php b/apps/platform/app/Support/References/Resolvers/OperationRunReferenceResolver.php index 1d83d80f..57affcee 100644 --- a/apps/platform/app/Support/References/Resolvers/OperationRunReferenceResolver.php +++ b/apps/platform/app/Support/References/Resolvers/OperationRunReferenceResolver.php @@ -60,7 +60,7 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference targetKind: ReferenceClass::OperationRun->value, url: OperationRunLinks::tenantlessView($run, $navigationContext), actionLabel: OperationRunLinks::openLabel(), - contextBadge: $run->tenant_id ? 'Tenant context' : 'Workspace', + contextBadge: $run->managed_environment_id ? 'ManagedEnvironment context' : 'Workspace', ), ); } diff --git a/apps/platform/app/Support/References/Resolvers/PolicyReferenceResolver.php b/apps/platform/app/Support/References/Resolvers/PolicyReferenceResolver.php index 8f49103f..e2542f2f 100644 --- a/apps/platform/app/Support/References/Resolvers/PolicyReferenceResolver.php +++ b/apps/platform/app/Support/References/Resolvers/PolicyReferenceResolver.php @@ -6,7 +6,7 @@ use App\Filament\Resources\PolicyResource; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -41,7 +41,7 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference $policy = Policy::query() ->with('tenant') ->whereKey($policyId) - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->first(); if (! $policy instanceof Policy) { @@ -60,16 +60,16 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference targetKind: ReferenceClass::Policy->value, url: PolicyResource::getUrl('view', ['record' => $policy], tenant: $policy->tenant), actionLabel: __('localization.policy.versions.related_action_view_policy'), - contextBadge: 'Tenant', + contextBadge: 'ManagedEnvironment', ), ); } - private function canOpenTenantRecord(?Tenant $tenant, string $capability): bool + private function canOpenTenantRecord(?ManagedEnvironment $tenant, string $capability): bool { $user = auth()->user(); - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment && $user instanceof User && $this->capabilityResolver->isMember($user, $tenant) && $this->capabilityResolver->can($user, $tenant, $capability); diff --git a/apps/platform/app/Support/References/Resolvers/PolicyVersionReferenceResolver.php b/apps/platform/app/Support/References/Resolvers/PolicyVersionReferenceResolver.php index bdef664c..3d50015a 100644 --- a/apps/platform/app/Support/References/Resolvers/PolicyVersionReferenceResolver.php +++ b/apps/platform/app/Support/References/Resolvers/PolicyVersionReferenceResolver.php @@ -6,7 +6,7 @@ use App\Filament\Resources\PolicyVersionResource; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -41,7 +41,7 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference $version = PolicyVersion::query() ->with(['policy', 'tenant']) ->whereKey($policyVersionId) - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->first(); if (! $version instanceof PolicyVersion) { @@ -67,7 +67,7 @@ public function resolve(ReferenceDescriptor $descriptor): ResolvedReference targetKind: ReferenceClass::PolicyVersion->value, url: PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $version->tenant), actionLabel: __('localization.policy.versions.related_action_view_policy_version'), - contextBadge: 'Tenant', + contextBadge: 'ManagedEnvironment', ), ); } @@ -76,7 +76,7 @@ private function canOpenPolicyVersion(PolicyVersion $version): bool { $tenant = $version->tenant; - if (! $tenant instanceof Tenant || ! $this->canOpenTenantRecord($tenant, Capabilities::TENANT_VIEW)) { + if (! $tenant instanceof ManagedEnvironment || ! $this->canOpenTenantRecord($tenant, Capabilities::TENANT_VIEW)) { return false; } @@ -91,11 +91,11 @@ private function canOpenPolicyVersion(PolicyVersion $version): bool return true; } - private function canOpenTenantRecord(?Tenant $tenant, string $capability): bool + private function canOpenTenantRecord(?ManagedEnvironment $tenant, string $capability): bool { $user = auth()->user(); - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment && $user instanceof User && $this->capabilityResolver->isMember($user, $tenant) && $this->capabilityResolver->can($user, $tenant, $capability); diff --git a/apps/platform/app/Support/RestoreRunIdempotency.php b/apps/platform/app/Support/RestoreRunIdempotency.php index 5035dbc3..afd599c1 100644 --- a/apps/platform/app/Support/RestoreRunIdempotency.php +++ b/apps/platform/app/Support/RestoreRunIdempotency.php @@ -13,7 +13,7 @@ final class RestoreRunIdempotency public static function buildKey(int $tenantId, string $operationType, string|int|null $targetId = null, array $context = []): string { $payload = [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'operation_type' => trim($operationType), 'target_id' => $targetId === null ? null : (string) $targetId, 'context' => self::canonicalize($context), @@ -25,7 +25,7 @@ public static function buildKey(int $tenantId, string $operationType, string|int public static function findActiveRestoreRun(int $tenantId, string $idempotencyKey): ?RestoreRun { return RestoreRun::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('idempotency_key', $idempotencyKey) ->whereIn('status', ['queued', 'running']) ->latest('id') diff --git a/apps/platform/app/Support/RestoreSafety/RestoreSafetyCopy.php b/apps/platform/app/Support/RestoreSafety/RestoreSafetyCopy.php index 71dff1d7..c811e99a 100644 --- a/apps/platform/app/Support/RestoreSafety/RestoreSafetyCopy.php +++ b/apps/platform/app/Support/RestoreSafety/RestoreSafetyCopy.php @@ -58,9 +58,9 @@ public static function recoveryBoundary(?string $boundary): string { return match ($boundary) { 'preview_only_no_execution_proven' => 'No execution was performed from this record.', - 'execution_failed_no_recovery_claim' => 'Tenant recovery is not proven.', - 'run_completed_not_recovery_proven' => 'Tenant-wide recovery is not proven.', - default => 'Tenant-wide recovery is not proven.', + 'execution_failed_no_recovery_claim' => 'ManagedEnvironment recovery is not proven.', + 'run_completed_not_recovery_proven' => 'ManagedEnvironment-wide recovery is not proven.', + default => 'ManagedEnvironment-wide recovery is not proven.', }; } diff --git a/apps/platform/app/Support/RestoreSafety/RestoreSafetyResolver.php b/apps/platform/app/Support/RestoreSafety/RestoreSafetyResolver.php index 97416dea..32845d54 100644 --- a/apps/platform/app/Support/RestoreSafety/RestoreSafetyResolver.php +++ b/apps/platform/app/Support/RestoreSafety/RestoreSafetyResolver.php @@ -7,7 +7,7 @@ use App\Contracts\Hardening\WriteGateInterface; use App\Exceptions\Hardening\ProviderAccessHardeningRequired; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\BackupHealth\TenantBackupHealthAssessment; @@ -266,7 +266,7 @@ public function checksIntegrityFromData(array $data): ChecksIntegrityState /** * @param array $data */ - public function executionReadiness(Tenant $tenant, User $user, array $data, bool $dryRun = false): ExecutionReadinessState + public function executionReadiness(ManagedEnvironment $tenant, User $user, array $data, bool $dryRun = false): ExecutionReadinessState { $blockingReasons = []; @@ -309,7 +309,7 @@ public function executionReadiness(Tenant $tenant, User $user, array $data, bool /** * @param array $data */ - public function safetyAssessment(Tenant $tenant, User $user, array $data): RestoreSafetyAssessment + public function safetyAssessment(ManagedEnvironment $tenant, User $user, array $data): RestoreSafetyAssessment { $previewIntegrity = $this->previewIntegrityFromData($data); $checksIntegrity = $this->checksIntegrityFromData($data); @@ -382,7 +382,7 @@ public function safetyAssessment(Tenant $tenant, User $user, array $data): Resto /** * @param array $data */ - public function executionSafetySnapshot(Tenant $tenant, User $user, array $data): RestoreExecutionSafetySnapshot + public function executionSafetySnapshot(ManagedEnvironment $tenant, User $user, array $data): RestoreExecutionSafetySnapshot { $scope = $this->scopeFingerprintFromData($data); $assessment = $this->safetyAssessment($tenant, $user, $data); @@ -496,7 +496,7 @@ public function resultAttentionForRun(RestoreRun $restoreRun): RestoreResultAtte * reason: string * } */ - public function dashboardRecoveryEvidence(Tenant $tenant): array + public function dashboardRecoveryEvidence(ManagedEnvironment $tenant): array { $backupHealth = $this->backupHealthResolver->assess($tenant); $relevantRestoreHistory = $this->latestRelevantRestoreHistory($tenant); @@ -508,7 +508,7 @@ public function dashboardRecoveryEvidence(Tenant $tenant): array } /** - * @param iterable $tenants + * @param iterable $tenants * @param array|null $backupHealthAssessments * @return arraybackupHealthResolver->assessMany($tenantIds); - $candidatesByTenant = $this->dashboardRecoveryCandidatesForTenants($tenantIds)->groupBy('tenant_id'); + $candidatesByTenant = $this->dashboardRecoveryCandidatesForTenants($tenantIds)->groupBy('managed_environment_id'); $evidence = []; foreach ($tenantIds as $tenantId) { @@ -613,7 +613,7 @@ public function invalidationReasonsForBasis( /** * @return array{run: ?RestoreRun, attention: ?RestoreResultAttention} */ - private function latestRelevantRestoreHistory(Tenant $tenant): array + private function latestRelevantRestoreHistory(ManagedEnvironment $tenant): array { return $this->latestRelevantRestoreHistoryFromCandidates($this->dashboardRecoveryCandidates($tenant)); } @@ -654,12 +654,12 @@ private function dashboardRecoveryCandidatesForTenants(array $tenantIds) } $candidateIds = RestoreRun::query() - ->whereIn('tenant_id', $tenantIds) - ->orderBy('tenant_id') + ->whereIn('managed_environment_id', $tenantIds) + ->orderBy('managed_environment_id') ->orderByRaw('COALESCE(completed_at, started_at, created_at) DESC') ->orderByDesc('id') - ->get(['id', 'tenant_id']) - ->groupBy('tenant_id') + ->get(['id', 'managed_environment_id']) + ->groupBy('managed_environment_id') ->flatMap(static fn ($runs): array => $runs->take(self::DASHBOARD_RECOVERY_CANDIDATE_LIMIT)->pluck('id')->all()) ->values() ->all(); @@ -671,7 +671,7 @@ private function dashboardRecoveryCandidatesForTenants(array $tenantIds) return RestoreRun::query() ->whereIn('id', $candidateIds) ->with('operationRun:id,outcome,context') - ->orderBy('tenant_id') + ->orderBy('managed_environment_id') ->orderByRaw('COALESCE(completed_at, started_at, created_at) DESC') ->orderByDesc('id') ->get(); @@ -680,10 +680,10 @@ private function dashboardRecoveryCandidatesForTenants(array $tenantIds) /** * @return \Illuminate\Database\Eloquent\Collection */ - private function dashboardRecoveryCandidates(Tenant $tenant) + private function dashboardRecoveryCandidates(ManagedEnvironment $tenant) { return RestoreRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->with('operationRun:id,outcome') ->orderByRaw('COALESCE(completed_at, started_at, created_at) DESC') ->orderByDesc('id') @@ -842,7 +842,7 @@ private function normalizeIds(array $ids): array } /** - * @param iterable $tenants + * @param iterable $tenants * @return array */ private function normalizeTenantIds(iterable $tenants): array @@ -850,7 +850,7 @@ private function normalizeTenantIds(iterable $tenants): array $tenantIds = []; foreach ($tenants as $tenant) { - $tenantId = $tenant instanceof Tenant + $tenantId = $tenant instanceof ManagedEnvironment ? (int) $tenant->getKey() : (int) $tenant; diff --git a/apps/platform/app/Support/SupportDiagnostics/SupportDiagnosticBundleBuilder.php b/apps/platform/app/Support/SupportDiagnostics/SupportDiagnosticBundleBuilder.php index 0ab64eac..57248ae3 100644 --- a/apps/platform/app/Support/SupportDiagnostics/SupportDiagnosticBundleBuilder.php +++ b/apps/platform/app/Support/SupportDiagnostics/SupportDiagnosticBundleBuilder.php @@ -15,7 +15,7 @@ use App\Models\ProviderConnection; use App\Models\ReviewPack; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Models\Workspace; @@ -55,7 +55,7 @@ public function __construct( /** * @return array */ - public function forTenant(Tenant $tenant, ?User $actor = null): array + public function forTenant(ManagedEnvironment $tenant, ?User $actor = null): array { $tenant->loadMissing('workspace'); @@ -98,13 +98,13 @@ public function forOperationRun(OperationRun $run, ?User $actor = null): array $workspace = $run->workspace; $tenant = $run->tenant; - $providerConnection = $tenant instanceof Tenant + $providerConnection = $tenant instanceof ManagedEnvironment ? $this->operationProviderConnection($run, $tenant) : null; - $findings = $tenant instanceof Tenant ? $this->operationFindings($run, $tenant) : collect(); - $storedReports = $tenant instanceof Tenant ? $this->tenantStoredReports($tenant) : collect(); - $tenantReview = $tenant instanceof Tenant ? $this->operationTenantReview($run, $tenant) : null; - $reviewPack = $tenant instanceof Tenant ? $this->operationReviewPack($run, $tenant, $tenantReview) : null; + $findings = $tenant instanceof ManagedEnvironment ? $this->operationFindings($run, $tenant) : collect(); + $storedReports = $tenant instanceof ManagedEnvironment ? $this->tenantStoredReports($tenant) : collect(); + $tenantReview = $tenant instanceof ManagedEnvironment ? $this->operationTenantReview($run, $tenant) : null; + $reviewPack = $tenant instanceof ManagedEnvironment ? $this->operationReviewPack($run, $tenant, $tenantReview) : null; $auditLogs = $this->operationAuditLogs($run); $runSummary = $this->runSummaryBuilder->build($run); $runSummaryArray = $runSummary?->toArray(); @@ -151,7 +151,7 @@ public function forOperationRun(OperationRun $run, ?User $actor = null): array * notes: list * } */ - public function aiSupportDiagnosticsSummaryDraftSource(Tenant $tenant, ?User $actor = null): array + public function aiSupportDiagnosticsSummaryDraftSource(ManagedEnvironment $tenant, ?User $actor = null): array { $bundle = $this->forTenant($tenant, $actor); @@ -174,7 +174,7 @@ public function aiSupportDiagnosticsSummaryDraftSource(Tenant $tenant, ?User $ac private function bundle( string $contextType, ?Workspace $workspace, - ?Tenant $tenant, + ?ManagedEnvironment $tenant, ?ProviderConnection $providerConnection, ?OperationRun $operationRun, string $headline, @@ -190,7 +190,7 @@ private function bundle( 'context' => [ 'type' => $contextType, 'workspace_id' => $workspace instanceof Workspace ? (int) $workspace->getKey() : null, - 'tenant_id' => $tenant instanceof Tenant ? (int) $tenant->getKey() : null, + 'managed_environment_id' => $tenant instanceof ManagedEnvironment ? (int) $tenant->getKey() : null, 'operation_run_id' => $operationRun instanceof OperationRun ? (int) $operationRun->getKey() : null, 'tenant_label' => $tenant?->name, 'workspace_label' => $workspace?->name, @@ -199,7 +199,7 @@ private function bundle( 'record_id' => (string) $workspace->getKey(), 'label' => $workspace->name, ] : null, - 'tenant' => $tenant instanceof Tenant ? $this->tenantReference($tenant) : null, + 'tenant' => $tenant instanceof ManagedEnvironment ? $this->tenantReference($tenant) : null, 'operation_run' => $operationRun instanceof OperationRun ? $this->operationReference($operationRun, $tenant) : null, 'headline' => $headline, 'dominant_issue' => $dominantIssue, @@ -231,12 +231,12 @@ private function bundle( * @return array|null */ private function contextualHelp( - ?Tenant $tenant, + ?ManagedEnvironment $tenant, ?ProviderConnection $providerConnection, ?OperationRun $operationRun, array $sections, ): ?array { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -280,10 +280,10 @@ private function supportDiagnosticReasonCode(?ProviderConnection $providerConnec return null; } - private function tenantProviderConnection(Tenant $tenant): ?ProviderConnection + private function tenantProviderConnection(ManagedEnvironment $tenant): ?ProviderConnection { return ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->orderByDesc('is_default') ->orderByDesc('last_health_check_at') @@ -291,7 +291,7 @@ private function tenantProviderConnection(Tenant $tenant): ?ProviderConnection ->first(); } - private function operationProviderConnection(OperationRun $run, Tenant $tenant): ?ProviderConnection + private function operationProviderConnection(OperationRun $run, ManagedEnvironment $tenant): ?ProviderConnection { $context = is_array($run->context) ? $run->context : []; $providerConnectionId = data_get($context, 'provider_connection_id'); @@ -300,7 +300,7 @@ private function operationProviderConnection(OperationRun $run, Tenant $tenant): $connection = ProviderConnection::query() ->whereKey((int) $providerConnectionId) ->where('workspace_id', (int) $tenant->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->first(); if ($connection instanceof ProviderConnection) { @@ -311,10 +311,10 @@ private function operationProviderConnection(OperationRun $run, Tenant $tenant): return $this->tenantProviderConnection($tenant); } - private function tenantOperationRun(Tenant $tenant): ?OperationRun + private function tenantOperationRun(ManagedEnvironment $tenant): ?OperationRun { return OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->orderByRaw('completed_at IS NULL') ->orderByDesc('completed_at') @@ -326,10 +326,10 @@ private function tenantOperationRun(Tenant $tenant): ?OperationRun /** * @return Collection */ - private function tenantFindings(Tenant $tenant): Collection + private function tenantFindings(ManagedEnvironment $tenant): Collection { return Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->whereIn('status', Finding::openStatusesForQuery()) ->orderByRaw("CASE severity WHEN 'critical' THEN 0 WHEN 'high' THEN 1 WHEN 'medium' THEN 2 WHEN 'low' THEN 3 ELSE 4 END") @@ -342,10 +342,10 @@ private function tenantFindings(Tenant $tenant): Collection /** * @return Collection */ - private function operationFindings(OperationRun $run, Tenant $tenant): Collection + private function operationFindings(OperationRun $run, ManagedEnvironment $tenant): Collection { $runBound = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->where(function (Builder $query) use ($run): void { $query @@ -364,10 +364,10 @@ private function operationFindings(OperationRun $run, Tenant $tenant): Collectio /** * @return Collection */ - private function tenantStoredReports(Tenant $tenant): Collection + private function tenantStoredReports(ManagedEnvironment $tenant): Collection { return StoredReport::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->orderByDesc('updated_at') ->orderByDesc('id') @@ -375,20 +375,20 @@ private function tenantStoredReports(Tenant $tenant): Collection ->get(); } - private function tenantReview(Tenant $tenant): ?TenantReview + private function tenantReview(ManagedEnvironment $tenant): ?TenantReview { return TenantReview::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->orderByDesc('generated_at') ->orderByDesc('id') ->first(); } - private function operationTenantReview(OperationRun $run, Tenant $tenant): ?TenantReview + private function operationTenantReview(OperationRun $run, ManagedEnvironment $tenant): ?TenantReview { $review = TenantReview::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->where('operation_run_id', (int) $run->getKey()) ->orderByDesc('generated_at') @@ -398,12 +398,12 @@ private function operationTenantReview(OperationRun $run, Tenant $tenant): ?Tena return $review instanceof TenantReview ? $review : $this->tenantReview($tenant); } - private function tenantReviewPack(Tenant $tenant, ?TenantReview $tenantReview): ?ReviewPack + private function tenantReviewPack(ManagedEnvironment $tenant, ?TenantReview $tenantReview): ?ReviewPack { if ($tenantReview instanceof TenantReview && is_numeric($tenantReview->current_export_review_pack_id)) { $pack = ReviewPack::query() ->whereKey((int) $tenantReview->current_export_review_pack_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->first(); @@ -413,17 +413,17 @@ private function tenantReviewPack(Tenant $tenant, ?TenantReview $tenantReview): } return ReviewPack::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->orderByDesc('generated_at') ->orderByDesc('id') ->first(); } - private function operationReviewPack(OperationRun $run, Tenant $tenant, ?TenantReview $tenantReview): ?ReviewPack + private function operationReviewPack(OperationRun $run, ManagedEnvironment $tenant, ?TenantReview $tenantReview): ?ReviewPack { $pack = ReviewPack::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->where('operation_run_id', (int) $run->getKey()) ->orderByDesc('generated_at') @@ -436,10 +436,10 @@ private function operationReviewPack(OperationRun $run, Tenant $tenant, ?TenantR /** * @return Collection */ - private function tenantAuditLogs(Tenant $tenant): Collection + private function tenantAuditLogs(ManagedEnvironment $tenant): Collection { return AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->latestFirst() ->limit(5) @@ -529,10 +529,10 @@ private function providerIssue(ProviderConnection $connection): ?string return null; } - private function overviewSection(?Workspace $workspace, ?Tenant $tenant, ?OperationRun $operationRun): array + private function overviewSection(?Workspace $workspace, ?ManagedEnvironment $tenant, ?OperationRun $operationRun): array { $references = array_values(array_filter([ - $tenant instanceof Tenant ? $this->tenantReference($tenant) : null, + $tenant instanceof ManagedEnvironment ? $this->tenantReference($tenant) : null, $operationRun instanceof OperationRun ? $this->operationReference($operationRun, $tenant) : null, ])); @@ -540,14 +540,14 @@ private function overviewSection(?Workspace $workspace, ?Tenant $tenant, ?Operat key: 'overview', label: 'Overview', availability: $references === [] ? 'missing' : 'available', - summary: $tenant instanceof Tenant + summary: $tenant instanceof ManagedEnvironment ? 'Workspace and tenant scope resolved before support diagnostics were composed.' : 'Workspace scope resolved; no tenant context is attached to this operation.', references: $references, ); } - private function providerConnectionSection(?ProviderConnection $connection, ?Tenant $tenant, ?OperationRun $run = null): array + private function providerConnectionSection(?ProviderConnection $connection, ?ManagedEnvironment $tenant, ?OperationRun $run = null): array { if (! $connection instanceof ProviderConnection) { return $this->section( @@ -601,7 +601,7 @@ private function providerConnectionSection(?ProviderConnection $connection, ?Ten ); } - private function operationContextSection(?OperationRun $operationRun, ?Tenant $tenant, ?array $runSummary = null): array + private function operationContextSection(?OperationRun $operationRun, ?ManagedEnvironment $tenant, ?array $runSummary = null): array { if (! $operationRun instanceof OperationRun) { return $this->section( @@ -630,7 +630,7 @@ private function operationContextSection(?OperationRun $operationRun, ?Tenant $t ); } - private function findingsSection(Collection $findings, ?Tenant $tenant): array + private function findingsSection(Collection $findings, ?ManagedEnvironment $tenant): array { if ($findings->isEmpty()) { return $this->section( @@ -656,7 +656,7 @@ private function findingsSection(Collection $findings, ?Tenant $tenant): array record: $finding, label: sprintf('%s finding #%d', ucfirst(str_replace('_', ' ', (string) $finding->severity)), (int) $finding->getKey()), actionLabel: 'Open finding', - url: $tenant instanceof Tenant + url: $tenant instanceof ManagedEnvironment ? FindingResource::getUrl('view', ['record' => $finding], panel: 'tenant', tenant: $tenant) : null, freshnessAt: $finding->last_seen_at, @@ -714,23 +714,23 @@ private function storedReportsSection(Collection $reports): array ); } - private function tenantReviewSection(?TenantReview $review, ?Tenant $tenant): array + private function tenantReviewSection(?TenantReview $review, ?ManagedEnvironment $tenant): array { if (! $review instanceof TenantReview) { return $this->section( key: 'tenant_review', - label: 'Tenant review', + label: 'ManagedEnvironment review', availability: 'missing', summary: 'No tenant review was found for this support context.', references: [ - $this->missingReference('tenant_review', 'Tenant review not yet observed', 'Open tenant review'), + $this->missingReference('tenant_review', 'ManagedEnvironment review not yet observed', 'Open tenant review'), ], ); } return $this->section( key: 'tenant_review', - label: 'Tenant review', + label: 'ManagedEnvironment review', availability: 'available', summary: sprintf('Latest tenant review is %s with %s completeness.', (string) $review->status, (string) $review->completeness_state), freshnessNote: $this->freshnessNote($review->generated_at, 'Generated'), @@ -738,9 +738,9 @@ private function tenantReviewSection(?TenantReview $review, ?Tenant $tenant): ar $this->modelReference( type: 'tenant_review', record: $review, - label: 'Tenant review #'.$review->getKey(), + label: 'ManagedEnvironment review #'.$review->getKey(), actionLabel: 'Open tenant review', - url: $tenant instanceof Tenant + url: $tenant instanceof ManagedEnvironment ? TenantReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant) : null, freshnessAt: $review->generated_at, @@ -749,7 +749,7 @@ private function tenantReviewSection(?TenantReview $review, ?Tenant $tenant): ar ); } - private function reviewPackSection(?ReviewPack $pack, ?Tenant $tenant): array + private function reviewPackSection(?ReviewPack $pack, ?ManagedEnvironment $tenant): array { if (! $pack instanceof ReviewPack) { return $this->section( @@ -775,7 +775,7 @@ private function reviewPackSection(?ReviewPack $pack, ?Tenant $tenant): array record: $pack, label: 'Review pack #'.$pack->getKey(), actionLabel: 'Open review pack', - url: $tenant instanceof Tenant + url: $tenant instanceof ManagedEnvironment ? ReviewPackResource::getUrl('view', ['record' => $pack], panel: 'tenant', tenant: $tenant) : null, freshnessAt: $pack->generated_at, @@ -898,7 +898,7 @@ private function sortReferences(array $references): array return array_values($references); } - private function tenantReference(Tenant $tenant): array + private function tenantReference(ManagedEnvironment $tenant): array { return [ 'type' => 'tenant', @@ -912,7 +912,7 @@ private function tenantReference(Tenant $tenant): array ]; } - private function operationReference(OperationRun $run, ?Tenant $tenant): array + private function operationReference(OperationRun $run, ?ManagedEnvironment $tenant): array { return $this->modelReference( type: 'operation_run', @@ -927,9 +927,9 @@ private function operationReference(OperationRun $run, ?Tenant $tenant): array /** * @return list> */ - private function operationRelatedReferences(OperationRun $run, ?Tenant $tenant): array + private function operationRelatedReferences(OperationRun $run, ?ManagedEnvironment $tenant): array { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return []; } diff --git a/apps/platform/app/Support/SupportRequests/ExternalSupportDeskHandoffService.php b/apps/platform/app/Support/SupportRequests/ExternalSupportDeskHandoffService.php index 7e37e657..e51c84b5 100644 --- a/apps/platform/app/Support/SupportRequests/ExternalSupportDeskHandoffService.php +++ b/apps/platform/app/Support/SupportRequests/ExternalSupportDeskHandoffService.php @@ -169,9 +169,9 @@ private function payloadFor(SupportRequest $supportRequest): array 'primary_context_type' => $supportRequest->primary_context_type, 'primary_context_id' => $supportRequest->primary_context_type === SupportRequest::PRIMARY_CONTEXT_OPERATION_RUN ? $supportRequest->operation_run_id - : $supportRequest->tenant_id, + : $supportRequest->managed_environment_id, 'workspace_id' => $supportRequest->workspace_id, - 'tenant_id' => $supportRequest->tenant_id, + 'managed_environment_id' => $supportRequest->managed_environment_id, 'operation_run_id' => $supportRequest->operation_run_id, ], 'context_envelope' => $supportRequest->context_envelope, diff --git a/apps/platform/app/Support/SupportRequests/SupportRequestContextBuilder.php b/apps/platform/app/Support/SupportRequests/SupportRequestContextBuilder.php index 555cd2a2..9f4d6c54 100644 --- a/apps/platform/app/Support/SupportRequests/SupportRequestContextBuilder.php +++ b/apps/platform/app/Support/SupportRequests/SupportRequestContextBuilder.php @@ -5,7 +5,7 @@ namespace App\Support\SupportRequests; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\SupportDiagnostics\SupportDiagnosticBundleBuilder; @@ -22,7 +22,7 @@ public function __construct( /** * @return array */ - public function forTenant(Tenant $tenant, User $actor, bool $attachDiagnosticSnapshot): array + public function forTenant(ManagedEnvironment $tenant, User $actor, bool $attachDiagnosticSnapshot): array { return $this->buildEnvelope( bundle: $this->supportDiagnosticBundleBuilder->forTenant($tenant, $actor), @@ -59,7 +59,7 @@ private function buildEnvelope(array $bundle, bool $attachDiagnosticSnapshot): a 'primary_context' => [ 'type' => (string) data_get($bundle, 'context.type'), 'workspace_id' => data_get($bundle, 'context.workspace_id'), - 'tenant_id' => data_get($bundle, 'context.tenant_id'), + 'managed_environment_id' => data_get($bundle, 'context.managed_environment_id'), 'operation_run_id' => data_get($bundle, 'context.operation_run_id'), 'workspace_label' => data_get($bundle, 'context.workspace_label'), 'tenant_label' => data_get($bundle, 'context.tenant_label'), diff --git a/apps/platform/app/Support/SupportRequests/SupportRequestSubmissionService.php b/apps/platform/app/Support/SupportRequests/SupportRequestSubmissionService.php index 2083c91c..e90f6cf1 100644 --- a/apps/platform/app/Support/SupportRequests/SupportRequestSubmissionService.php +++ b/apps/platform/app/Support/SupportRequests/SupportRequestSubmissionService.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Audit\WorkspaceAuditLogger; use App\Services\Auth\CapabilityResolver; @@ -27,7 +27,7 @@ public function __construct( /** * @param array $data */ - public function submitForTenant(Tenant $tenant, User $actor, array $data): SupportRequest + public function submitForTenant(ManagedEnvironment $tenant, User $actor, array $data): SupportRequest { $this->authorizeCreation($tenant, $actor); @@ -49,7 +49,7 @@ public function submitForOperationRun(OperationRun $run, User $actor, array $dat $tenant = $run->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -64,7 +64,7 @@ public function submitForOperationRun(OperationRun $run, User $actor, array $dat ); } - private function authorizeCreation(Tenant $tenant, User $actor): void + private function authorizeCreation(ManagedEnvironment $tenant, User $actor): void { if (! $this->capabilityResolver->isMember($actor, $tenant)) { abort(404); @@ -79,7 +79,7 @@ private function authorizeCreation(Tenant $tenant, User $actor): void * @param array $data */ private function submit( - Tenant $tenant, + ManagedEnvironment $tenant, User $actor, array $data, string $primaryContextType, @@ -108,7 +108,7 @@ private function submit( ): SupportRequest { $supportRequest = SupportRequest::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'operation_run_id' => $operationRun instanceof OperationRun ? (int) $operationRun->getKey() : null, 'initiated_by_user_id' => (int) $actor->getKey(), 'internal_reference' => $this->supportRequestReferenceGenerator->generate(), @@ -216,13 +216,13 @@ private function finalizeExternalHandoff(SupportRequest $supportRequest, User $a * has_failure: bool * }|null */ - public function latestTenantHandoffSummary(Tenant $tenant, User $actor): ?array + public function latestTenantHandoffSummary(ManagedEnvironment $tenant, User $actor): ?array { $this->authorizeCreation($tenant, $actor); $supportRequest = SupportRequest::query() ->where('workspace_id', (int) $tenant->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('primary_context_type', SupportRequest::PRIMARY_CONTEXT_TENANT) ->latest('created_at') ->latest('id') @@ -253,7 +253,7 @@ public function latestOperationRunHandoffSummary(OperationRun $run, User $actor) $tenant = $run->tenant; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { abort(404); } @@ -261,7 +261,7 @@ public function latestOperationRunHandoffSummary(OperationRun $run, User $actor) $supportRequest = SupportRequest::query() ->where('workspace_id', (int) $run->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('primary_context_type', SupportRequest::PRIMARY_CONTEXT_OPERATION_RUN) ->where('operation_run_id', (int) $run->getKey()) ->latest('created_at') @@ -294,7 +294,7 @@ private function summaryFor(SupportRequest $supportRequest): array 'primary_context_type' => (string) $supportRequest->primary_context_type, 'primary_context_id' => $supportRequest->primary_context_type === SupportRequest::PRIMARY_CONTEXT_OPERATION_RUN ? (is_numeric($supportRequest->operation_run_id) ? (int) $supportRequest->operation_run_id : null) - : (is_numeric($supportRequest->tenant_id) ? (int) $supportRequest->tenant_id : null), + : (is_numeric($supportRequest->managed_environment_id) ? (int) $supportRequest->managed_environment_id : null), 'submitted_at' => $supportRequest->created_at?->toIso8601String(), 'external_handoff_mode' => (string) ($supportRequest->external_handoff_mode ?? SupportRequest::EXTERNAL_HANDOFF_MODE_INTERNAL_ONLY), 'external_ticket_reference' => $this->normalizeNullableString($supportRequest->external_ticket_reference), diff --git a/apps/platform/app/Support/System/SystemDirectoryLinks.php b/apps/platform/app/Support/System/SystemDirectoryLinks.php index 68669899..2ace3d12 100644 --- a/apps/platform/app/Support/System/SystemDirectoryLinks.php +++ b/apps/platform/app/Support/System/SystemDirectoryLinks.php @@ -8,7 +8,7 @@ use App\Filament\System\Pages\Directory\ViewTenant; use App\Filament\System\Pages\Directory\ViewWorkspace; use App\Filament\System\Pages\Directory\Workspaces; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; final class SystemDirectoryLinks @@ -30,7 +30,7 @@ public static function tenantsIndex(): string return Tenants::getUrl(panel: 'system'); } - public static function tenantDetail(Tenant|string|int $tenant): string + public static function tenantDetail(ManagedEnvironment|string|int $tenant): string { $tenantRouteKey = self::tenantRouteKey($tenant); @@ -44,16 +44,16 @@ public static function adminWorkspace(Workspace|int $workspace): string return route('filament.admin.resources.workspaces.view', ['record' => $workspaceId]); } - public static function adminTenant(Tenant|string|int $tenant): string + public static function adminTenant(ManagedEnvironment|string|int $tenant): string { $tenantRouteKey = self::tenantRouteKey($tenant); return route('filament.admin.resources.tenants.view', ['record' => $tenantRouteKey]); } - private static function tenantRouteKey(Tenant|string|int $tenant): string + private static function tenantRouteKey(ManagedEnvironment|string|int $tenant): string { - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { return (string) $tenant->getRouteKey(); } diff --git a/apps/platform/app/Support/TenantDashboard/TenantDashboardSummaryBuilder.php b/apps/platform/app/Support/TenantDashboard/TenantDashboardSummaryBuilder.php index 7516fbac..e31c54f4 100644 --- a/apps/platform/app/Support/TenantDashboard/TenantDashboardSummaryBuilder.php +++ b/apps/platform/app/Support/TenantDashboard/TenantDashboardSummaryBuilder.php @@ -19,7 +19,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Services\Intune\TenantRequiredPermissionsViewModelBuilder; @@ -53,11 +53,26 @@ public function __construct( private readonly TenantRequiredPermissionsViewModelBuilder $tenantRequiredPermissionsViewModelBuilder, ) {} - public function build(Tenant $tenant, ?User $user = null): TenantDashboardSummary + public function build(ManagedEnvironment $tenant, ?User $user = null): TenantDashboardSummary { $tenant->loadMissing('workspace', 'providerConnections'); $user = $user ?? auth()->user(); + $request = app()->bound('request') ? request() : null; + $cacheKey = sprintf( + 'tenant_dashboard.summary.%d.%s', + (int) $tenant->getKey(), + $user instanceof User ? (string) $user->getKey() : 'guest', + ); + + if ($request?->attributes->has($cacheKey)) { + $cached = $request->attributes->get($cacheKey); + + if ($cached instanceof TenantDashboardSummary) { + return $cached; + } + } + $primaryProviderConnection = $this->primaryProviderConnection($tenant); $aggregate = $this->tenantGovernanceAggregateResolver->forTenant($tenant); @@ -85,7 +100,7 @@ public function build(Tenant $tenant, ?User $user = null): TenantDashboardSummar exceptionStats: $exceptionStats, ); - return new TenantDashboardSummary( + $summary = new TenantDashboardSummary( context: [ 'workspace' => (string) ($tenant->workspace?->name ?? $this->overviewText('context_workspace')), 'tenant' => (string) $tenant->name, @@ -130,9 +145,13 @@ public function build(Tenant $tenant, ?User $user = null): TenantDashboardSummar recentOperations: $this->recentOperationCards($tenant, $recentOperations), pollingInterval: ActiveRuns::pollingIntervalForTenant($tenant), ); + + $request?->attributes->set($cacheKey, $summary); + + return $summary; } - private function primaryProviderConnection(Tenant $tenant): ?ProviderConnection + private function primaryProviderConnection(ManagedEnvironment $tenant): ?ProviderConnection { $connections = $tenant->providerConnections; @@ -221,30 +240,30 @@ private function latestActivityTimestamp( return $candidates[0]; } - private function latestTenantReview(Tenant $tenant): ?TenantReview + private function latestTenantReview(ManagedEnvironment $tenant): ?TenantReview { return TenantReview::query() ->with(['tenant', 'evidenceSnapshot', 'currentExportReviewPack']) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->latest('generated_at') ->latest('id') ->first(); } - private function latestReviewPack(Tenant $tenant): ?ReviewPack + private function latestReviewPack(ManagedEnvironment $tenant): ?ReviewPack { return ReviewPack::query() ->with(['tenant', 'tenantReview']) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->latest('generated_at') ->latest('id') ->first(); } - private function latestEvidenceSnapshot(Tenant $tenant): ?EvidenceSnapshot + private function latestEvidenceSnapshot(ManagedEnvironment $tenant): ?EvidenceSnapshot { return EvidenceSnapshot::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->latest('generated_at') ->latest('id') ->first(); @@ -253,10 +272,10 @@ private function latestEvidenceSnapshot(Tenant $tenant): ?EvidenceSnapshot /** * @return array{active:int,expiring:int,expired:int,pending:int,total:int} */ - private function exceptionStats(Tenant $tenant): array + private function exceptionStats(ManagedEnvironment $tenant): array { $counts = FindingException::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->selectRaw('count(*) as total') ->selectRaw("count(*) filter (where status = 'active') as active") @@ -277,10 +296,10 @@ private function exceptionStats(Tenant $tenant): array /** * @return list */ - private function recentOperations(Tenant $tenant): array + private function recentOperations(ManagedEnvironment $tenant): array { return OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->latest('created_at') ->latest('id') ->limit(4) @@ -341,7 +360,7 @@ private function posture( * @param array $requiredPermissions * @return list> */ - private function kpis(Tenant $tenant, ?User $user, TenantGovernanceAggregate $aggregate, array $requiredPermissions): array + private function kpis(ManagedEnvironment $tenant, ?User $user, TenantGovernanceAggregate $aggregate, array $requiredPermissions): array { $counts = is_array($requiredPermissions['overview']['counts'] ?? null) ? $requiredPermissions['overview']['counts'] @@ -352,7 +371,7 @@ private function kpis(Tenant $tenant, ?User $user, TenantGovernanceAggregate $ag $operationsFollowUpChart = $this->operationsFollowUpChart($tenant); $operationsNeedingFollowUp = (int) OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where(function ($query): void { $query->terminalFollowUp()->orWhere(fn ($inner) => $inner->activeStaleAttention()); }) @@ -500,11 +519,11 @@ private function trendDirectionIcon(bool $hasAttention): string /** * @return list|null */ - private function highSeverityFindingsChart(Tenant $tenant): ?array + private function highSeverityFindingsChart(ManagedEnvironment $tenant): ?array { $window = $this->sevenDayWindow(); $byDay = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereIn('severity', Finding::highSeverityValues()) ->where(function (Builder $query) use ($window): void { $query @@ -526,11 +545,11 @@ private function highSeverityFindingsChart(Tenant $tenant): ?array /** * @return list|null */ - private function operationsFollowUpChart(Tenant $tenant): ?array + private function operationsFollowUpChart(ManagedEnvironment $tenant): ?array { $window = $this->sevenDayWindow(); $byDay = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->dashboardNeedsFollowUp() ->where(function (Builder $query) use ($window): void { $query @@ -583,7 +602,7 @@ private function normalizeSevenDayChart(array $byDay, Carbon $windowStart): ?arr * @return list> */ private function recommendedActions( - Tenant $tenant, + ManagedEnvironment $tenant, ?User $user, TenantGovernanceAggregate $aggregate, TenantBackupHealthAssessment $backupHealth, @@ -683,7 +702,7 @@ private function recommendedActions( } $terminalFollowUpRuns = (int) OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->terminalFollowUp() ->count(); @@ -729,7 +748,7 @@ private function recommendedActions( * @return list> */ private function governanceStatus( - Tenant $tenant, + ManagedEnvironment $tenant, ?User $user, TenantGovernanceAggregate $aggregate, TenantBackupHealthAssessment $backupHealth, @@ -802,7 +821,7 @@ private function governanceStatus( * @return list> */ private function readinessCards( - Tenant $tenant, + ManagedEnvironment $tenant, ?User $user, ?ProviderConnection $primaryProviderConnection, array $requiredPermissions, @@ -822,7 +841,7 @@ private function readinessCards( /** * @return array */ - private function currentReviewCard(Tenant $tenant, ?User $user, ?TenantReview $latestReview): array + private function currentReviewCard(ManagedEnvironment $tenant, ?User $user, ?TenantReview $latestReview): array { $timestamp = $latestReview?->published_at ?? $latestReview?->generated_at ?? $latestReview?->updated_at; @@ -851,7 +870,7 @@ private function currentReviewCard(Tenant $tenant, ?User $user, ?TenantReview $l * @param array{active:int,expiring:int,expired:int,pending:int,total:int} $exceptionStats * @return array */ - private function riskExceptionsCard(Tenant $tenant, ?User $user, array $exceptionStats): array + private function riskExceptionsCard(ManagedEnvironment $tenant, ?User $user, array $exceptionStats): array { return [ 'key' => 'risk_exceptions', @@ -873,7 +892,7 @@ private function riskExceptionsCard(Tenant $tenant, ?User $user, array $exceptio * @return array */ private function providerHealthCard( - Tenant $tenant, + ManagedEnvironment $tenant, ?User $user, ?ProviderConnection $primaryProviderConnection, array $requiredPermissions, @@ -911,7 +930,7 @@ private function providerHealthCard( * @return array */ private function customerSafeOutputCard( - Tenant $tenant, + ManagedEnvironment $tenant, ?User $user, ?ReviewPack $latestReviewPack, ?EvidenceSnapshot $latestEvidenceSnapshot, @@ -940,7 +959,7 @@ private function customerSafeOutputCard( * @param list $recentOperations * @return list> */ - private function recentOperationCards(Tenant $tenant, array $recentOperations): array + private function recentOperationCards(ManagedEnvironment $tenant, array $recentOperations): array { return collect($recentOperations) ->map(function (OperationRun $operation) use ($tenant): array { @@ -1058,7 +1077,7 @@ private function recommendedActionIcon(string $key): string * @param array $parameters * @return array{actionLabel:string,actionUrl:?string,actionDisabled:bool,helperText:?string} */ - private function tenantFindingsAction(Tenant $tenant, ?User $user, string $label, array $parameters = []): array + private function tenantFindingsAction(ManagedEnvironment $tenant, ?User $user, string $label, array $parameters = []): array { $canOpen = $this->canOpenTenantCapability($tenant, $user, Capabilities::TENANT_FINDINGS_VIEW); @@ -1072,7 +1091,7 @@ private function tenantFindingsAction(Tenant $tenant, ?User $user, string $label /** * @return array{actionLabel:string,actionUrl:?string,actionDisabled:bool,helperText:?string} */ - private function riskExceptionsAction(Tenant $tenant, ?User $user, string $label): array + private function riskExceptionsAction(ManagedEnvironment $tenant, ?User $user, string $label): array { $canOpen = $this->canOpenTenantCapability($tenant, $user, Capabilities::FINDING_EXCEPTION_VIEW); @@ -1086,7 +1105,7 @@ private function riskExceptionsAction(Tenant $tenant, ?User $user, string $label /** * @return array{actionLabel:string,actionUrl:?string,actionDisabled:bool,helperText:?string} */ - private function tenantReviewAction(Tenant $tenant, ?User $user, string $label, ?TenantReview $review = null): array + private function tenantReviewAction(ManagedEnvironment $tenant, ?User $user, string $label, ?TenantReview $review = null): array { $canOpen = $this->canOpenTenantCapability($tenant, $user, Capabilities::TENANT_REVIEW_VIEW); @@ -1108,7 +1127,7 @@ private function tenantReviewAction(Tenant $tenant, ?User $user, string $label, /** * @return array{actionLabel:string,actionUrl:?string,actionDisabled:bool,helperText:?string} */ - private function continueReviewAction(Tenant $tenant, ?User $user, TenantReview $review): array + private function continueReviewAction(ManagedEnvironment $tenant, ?User $user, TenantReview $review): array { $canContinue = $this->canOpenTenantCapability($tenant, $user, Capabilities::TENANT_REVIEW_MANAGE); @@ -1122,7 +1141,7 @@ private function continueReviewAction(Tenant $tenant, ?User $user, TenantReview /** * @return array{actionLabel:string,actionUrl:?string,actionDisabled:bool,helperText:?string} */ - private function evidenceAction(Tenant $tenant, ?User $user, string $label, ?EvidenceSnapshot $snapshot = null): array + private function evidenceAction(ManagedEnvironment $tenant, ?User $user, string $label, ?EvidenceSnapshot $snapshot = null): array { $canOpen = $this->canOpenTenantCapability($tenant, $user, Capabilities::EVIDENCE_VIEW); @@ -1144,7 +1163,7 @@ private function evidenceAction(Tenant $tenant, ?User $user, string $label, ?Evi /** * @return array{actionLabel:string,actionUrl:?string,actionDisabled:bool,helperText:?string} */ - private function customerWorkspaceAction(Tenant $tenant, ?User $user, ?ReviewPack $reviewPack): array + private function customerWorkspaceAction(ManagedEnvironment $tenant, ?User $user, ?ReviewPack $reviewPack): array { $canOpenWorkspace = $user instanceof User && $user->canAccessTenant($tenant) @@ -1176,7 +1195,7 @@ private function customerWorkspaceAction(Tenant $tenant, ?User $user, ?ReviewPac /** * @return array{actionLabel:string,actionUrl:?string,actionDisabled:bool,helperText:?string} */ - private function requiredPermissionsAction(Tenant $tenant, ?User $user, string $label): array + private function requiredPermissionsAction(ManagedEnvironment $tenant, ?User $user, string $label): array { $canOpen = $user instanceof User && $user->canAccessTenant($tenant); @@ -1190,7 +1209,7 @@ private function requiredPermissionsAction(Tenant $tenant, ?User $user, string $ /** * @return array{actionLabel:string,actionUrl:?string,actionDisabled:bool,helperText:?string} */ - private function operationsAction(Tenant $tenant, ?User $user, string $label, ?string $activeTab = null, ?string $problemClass = null): array + private function operationsAction(ManagedEnvironment $tenant, ?User $user, string $label, ?string $activeTab = null, ?string $problemClass = null): array { $canOpen = $user instanceof User && $user->canAccessTenant($tenant); @@ -1204,7 +1223,7 @@ private function operationsAction(Tenant $tenant, ?User $user, string $label, ?s /** * @return array{actionLabel:string,actionUrl:?string,actionDisabled:bool,helperText:?string} */ - private function baselineCompareAction(Tenant $tenant, ?User $user, string $label): array + private function baselineCompareAction(ManagedEnvironment $tenant, ?User $user, string $label): array { $canOpen = $this->canOpenTenantCapability($tenant, $user, Capabilities::TENANT_VIEW); @@ -1218,7 +1237,7 @@ private function baselineCompareAction(Tenant $tenant, ?User $user, string $labe /** * @return array{actionLabel:string,actionUrl:?string,actionDisabled:bool,helperText:?string} */ - private function backupHealthAction(Tenant $tenant, ?User $user, string $label, TenantBackupHealthAssessment $backupHealth): array + private function backupHealthAction(ManagedEnvironment $tenant, ?User $user, string $label, TenantBackupHealthAssessment $backupHealth): array { $canOpen = $this->canOpenTenantCapability($tenant, $user, Capabilities::TENANT_VIEW); @@ -1265,14 +1284,14 @@ private function actionPayload(string $label, ?string $url, ?string $helperText) ]; } - private function canOpenTenantCapability(Tenant $tenant, ?User $user, string $capability): bool + private function canOpenTenantCapability(ManagedEnvironment $tenant, ?User $user, string $capability): bool { return $user instanceof User && $user->canAccessTenant($tenant) && $user->can($capability, $tenant); } - private function reviewSurfaceActionLabel(Tenant $tenant, ?User $user, ?TenantReview $review): string + private function reviewSurfaceActionLabel(ManagedEnvironment $tenant, ?User $user, ?TenantReview $review): string { if (! $review instanceof TenantReview) { return $this->overviewText('action_open_reviews'); diff --git a/apps/platform/app/Support/Tenants/ReferencedTenantLifecyclePresentation.php b/apps/platform/app/Support/Tenants/ReferencedTenantLifecyclePresentation.php index da9e0777..b2b76965 100644 --- a/apps/platform/app/Support/Tenants/ReferencedTenantLifecyclePresentation.php +++ b/apps/platform/app/Support/Tenants/ReferencedTenantLifecyclePresentation.php @@ -4,7 +4,7 @@ namespace App\Support\Tenants; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; final readonly class ReferencedTenantLifecyclePresentation { @@ -16,12 +16,12 @@ public function __construct( public ?string $contextNote, ) {} - public static function forOperationRun(Tenant $tenant): self + public static function forOperationRun(ManagedEnvironment $tenant): self { return self::fromTenant($tenant, 'operation_run'); } - public static function fromTenant(Tenant $tenant, string $viewerContext): self + public static function fromTenant(ManagedEnvironment $tenant, string $viewerContext): self { $presentation = TenantLifecyclePresentation::fromTenant($tenant); @@ -34,11 +34,11 @@ public static function fromTenant(Tenant $tenant, string $viewerContext): self ); } - public static function forInvalid(string $viewerContext, ?Tenant $tenant = null, ?string $normalizedValue = null): self + public static function forInvalid(string $viewerContext, ?ManagedEnvironment $tenant = null, ?string $normalizedValue = null): self { return new self( viewerContext: $viewerContext, - tenantId: $tenant instanceof Tenant ? (int) $tenant->getKey() : null, + tenantId: $tenant instanceof ManagedEnvironment ? (int) $tenant->getKey() : null, tenantName: $tenant?->name, presentation: TenantLifecyclePresentation::invalid($normalizedValue), contextNote: 'Some tenant follow-up actions may be unavailable from this canonical workspace view.', diff --git a/apps/platform/app/Support/Tenants/TenantActionContext.php b/apps/platform/app/Support/Tenants/TenantActionContext.php index 67e95b78..823dfa3f 100644 --- a/apps/platform/app/Support/Tenants/TenantActionContext.php +++ b/apps/platform/app/Support/Tenants/TenantActionContext.php @@ -4,14 +4,14 @@ namespace App\Support\Tenants; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; final readonly class TenantActionContext { public function __construct( - public Tenant $tenant, + public ManagedEnvironment $tenant, public TenantLifecycle $lifecycle, public TenantActionSurface $surface, public ?User $actor, diff --git a/apps/platform/app/Support/Tenants/TenantLifecycle.php b/apps/platform/app/Support/Tenants/TenantLifecycle.php index b1acfd4d..5bff1f99 100644 --- a/apps/platform/app/Support/Tenants/TenantLifecycle.php +++ b/apps/platform/app/Support/Tenants/TenantLifecycle.php @@ -4,7 +4,7 @@ namespace App\Support\Tenants; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use BackedEnum; use Stringable; @@ -26,13 +26,13 @@ public static function values(): array ); } - public static function fromTenant(Tenant $tenant): self + public static function fromTenant(ManagedEnvironment $tenant): self { if ($tenant->trashed()) { return self::Archived; } - return self::fromValue($tenant->status); + return self::fromValue($tenant->lifecycle_status); } public static function fromValue(mixed $value, self $default = self::Active): self diff --git a/apps/platform/app/Support/Tenants/TenantLifecyclePresentation.php b/apps/platform/app/Support/Tenants/TenantLifecyclePresentation.php index 85d6cdb6..217c65ac 100644 --- a/apps/platform/app/Support/Tenants/TenantLifecyclePresentation.php +++ b/apps/platform/app/Support/Tenants/TenantLifecyclePresentation.php @@ -4,7 +4,7 @@ namespace App\Support\Tenants; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Badges\BadgeSpec; final readonly class TenantLifecyclePresentation @@ -21,13 +21,13 @@ private function __construct( public ?TenantLifecycle $lifecycle, ) {} - public static function fromTenant(Tenant $tenant): self + public static function fromTenant(ManagedEnvironment $tenant): self { if ($tenant->trashed()) { return self::forLifecycle(TenantLifecycle::Archived); } - return self::fromValue($tenant->status); + return self::fromValue($tenant->lifecycle_status); } public static function fromValue(mixed $value): self diff --git a/apps/platform/app/Support/Tenants/TenantOperabilityContext.php b/apps/platform/app/Support/Tenants/TenantOperabilityContext.php index cc6cc745..18e1a7b7 100644 --- a/apps/platform/app/Support/Tenants/TenantOperabilityContext.php +++ b/apps/platform/app/Support/Tenants/TenantOperabilityContext.php @@ -4,14 +4,14 @@ namespace App\Support\Tenants; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; final readonly class TenantOperabilityContext { public function __construct( - public Tenant $tenant, + public ManagedEnvironment $tenant, public ?User $actor, public ?int $workspaceId, public TenantInteractionLane $lane, @@ -20,18 +20,18 @@ public function __construct( public ?int $linkedRecordId = null, public ?TenantOnboardingSession $onboardingDraft = null, public ?string $requiredCapability = null, - public ?Tenant $selectedTenant = null, + public ?ManagedEnvironment $selectedTenant = null, ) {} public static function forTenant( - Tenant $tenant, + ManagedEnvironment $tenant, ?User $actor = null, ?int $workspaceId = null, TenantInteractionLane $lane = TenantInteractionLane::AdministrativeManagement, ?TenantPageCategory $pageCategory = null, ?TenantOnboardingSession $onboardingDraft = null, ?string $requiredCapability = null, - ?Tenant $selectedTenant = null, + ?ManagedEnvironment $selectedTenant = null, ?string $linkedRecordType = null, ?int $linkedRecordId = null, ): self { diff --git a/apps/platform/app/Support/Tenants/TenantOperabilityReasonCode.php b/apps/platform/app/Support/Tenants/TenantOperabilityReasonCode.php index 83e06549..39193e14 100644 --- a/apps/platform/app/Support/Tenants/TenantOperabilityReasonCode.php +++ b/apps/platform/app/Support/Tenants/TenantOperabilityReasonCode.php @@ -27,12 +27,12 @@ public function operatorLabel(): string { return match ($this) { self::WorkspaceMismatch => 'Workspace context changed', - self::TenantNotEntitled => 'Tenant access removed', + self::TenantNotEntitled => 'ManagedEnvironment access removed', self::MissingCapability => 'Permission required', self::WrongLane => 'Available from a different surface', - self::SelectorIneligibleLifecycle => 'Tenant unavailable in the current lifecycle', - self::TenantNotArchived => 'Tenant is not archived', - self::TenantAlreadyArchived => 'Tenant already archived', + self::SelectorIneligibleLifecycle => 'ManagedEnvironment unavailable in the current lifecycle', + self::TenantNotArchived => 'ManagedEnvironment is not archived', + self::TenantAlreadyArchived => 'ManagedEnvironment already archived', self::OnboardingNotResumable => 'Onboarding cannot be resumed', self::CanonicalViewFollowupOnly => 'Follow-up requires tenant context', self::RememberedContextStale => 'Saved tenant context is stale', diff --git a/apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceDiscovery.php b/apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceDiscovery.php index a1e30e28..31dd18ce 100644 --- a/apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceDiscovery.php +++ b/apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceDiscovery.php @@ -100,7 +100,7 @@ className: $className, */ private function panelScopesFor(string $className, array $adminScopedClasses): array { - $scopes = [ActionSurfacePanelScope::Tenant]; + $scopes = [ActionSurfacePanelScope::ManagedEnvironment]; if ( in_array($className, $adminScopedClasses, true) diff --git a/apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php b/apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php index 8f6df367..2355be35 100644 --- a/apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php +++ b/apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php @@ -60,9 +60,9 @@ public static function baseline(): self // Baseline allowlist for legacy surfaces. Keep shrinking this list. // Declared system table pages are discovered directly; deferred system tooling stays out of scope by not opting in. 'App\\Filament\\Pages\\Auth\\Login' => 'Auth entry page is out-of-scope for action-surface retrofits in spec 082.', - 'App\\Filament\\Pages\\ChooseTenant' => 'Tenant chooser has no contract-style table action surface.', + 'App\\Filament\\Pages\\ChooseTenant' => 'ManagedEnvironment chooser has no contract-style table action surface.', 'App\\Filament\\Pages\\ChooseWorkspace' => 'Workspace chooser has no contract-style table action surface.', - 'App\\Filament\\Pages\\Tenancy\\RegisterTenant' => 'Tenant onboarding route is covered by onboarding/RBAC specs.', + 'App\\Filament\\Pages\\Tenancy\\RegisterTenant' => 'ManagedEnvironment onboarding route is covered by onboarding/RBAC specs.', 'App\\Filament\\Pages\\TenantDashboard' => 'Dashboard retrofit deferred; widget and summary surfaces are excluded from this contract.', 'App\\Filament\\Pages\\Workspaces\\ManagedTenantOnboardingWizard' => 'Onboarding wizard has dedicated conformance tests in spec 172 (OnboardingVerificationTest, OnboardingVerificationClustersTest, OnboardingVerificationV1_5UxTest) and remains exempt from blanket discovery.', 'App\\Filament\\Pages\\Workspaces\\ManagedTenantsLanding' => 'Managed-tenant landing retrofit deferred to workspace feature track.', @@ -159,7 +159,7 @@ public static function spec192RecordPageInventory(): array ViewTenantReview::class => [ 'surfaceKey' => 'tenant_review_view', 'classification' => 'remediation_required', - 'canonicalNoun' => 'Tenant review', + 'canonicalNoun' => 'ManagedEnvironment review', 'panelScope' => 'tenant', 'ownerScope' => 'tenant-owned', 'routeKind' => 'view', @@ -175,7 +175,7 @@ public static function spec192RecordPageInventory(): array EditTenant::class => [ 'surfaceKey' => 'tenant_edit', 'classification' => 'remediation_required', - 'canonicalNoun' => 'Tenant', + 'canonicalNoun' => 'ManagedEnvironment', 'panelScope' => 'admin', 'ownerScope' => 'tenant-owned', 'routeKind' => 'edit', @@ -191,12 +191,12 @@ public static function spec192RecordPageInventory(): array ViewTenant::class => [ 'surfaceKey' => 'tenant_view', 'classification' => 'workflow_heavy_special_type', - 'canonicalNoun' => 'Tenant', + 'canonicalNoun' => 'ManagedEnvironment', 'panelScope' => 'admin', 'ownerScope' => 'tenant-owned', 'routeKind' => 'view', 'requiresHeaderRemediation' => false, - 'exceptionReason' => 'Tenant detail remains a workflow-heavy hub for external links, verification/setup, and lifecycle operations. It may show one dominant next step, but it must never silently fall back to a flat multi-button strip.', + 'exceptionReason' => 'ManagedEnvironment detail remains a workflow-heavy hub for external links, verification/setup, and lifecycle operations. It may show one dominant next step, but it must never silently fall back to a flat multi-button strip.', 'maxVisiblePrimaryActions' => 1, 'allowsNoPrimaryAction' => true, 'requiresGroupedSecondaryActions' => true, @@ -497,7 +497,7 @@ public static function spec193MonitoringSurfaceInventory(): array TenantDiagnostics::class => [ 'surfaceKey' => 'tenant_diagnostics', 'classification' => 'special_type_acceptable', - 'canonicalNoun' => 'Tenant diagnostics', + 'canonicalNoun' => 'ManagedEnvironment diagnostics', 'panelScope' => 'tenant', 'ownerScope' => 'tenant-owned', 'surfaceKind' => 'diagnostic_exception', @@ -505,7 +505,7 @@ public static function spec193MonitoringSurfaceInventory(): array 'sharedPattern' => 'none', 'requiresHeaderRemediation' => false, 'requiresExplicitDeclaration' => true, - 'exceptionReason' => 'Tenant diagnostics is already the focused diagnostic surface for the active tenant and may expose repair actions only when a real defect exists.', + 'exceptionReason' => 'ManagedEnvironment diagnostics is already the focused diagnostic surface for the active tenant and may expose repair actions only when a real defect exists.', 'browserSmokeRequired' => true, ], ]; @@ -711,7 +711,7 @@ public static function spec195ResidualSurfaceInventory(): array ], SystemDirectoryViewTenant::class => [ 'surfaceKey' => 'system_directory_view_tenant', - 'surfaceName' => 'System Directory View Tenant', + 'surfaceName' => 'System Directory View ManagedEnvironment', 'pageClass' => SystemDirectoryViewTenant::class, 'panelPlane' => 'system', 'surfaceKind' => 'read_mostly_context', @@ -820,7 +820,7 @@ public static function spec195ResidualSurfaceInventory(): array ], ChooseTenant::class => [ 'surfaceKey' => 'choose_tenant', - 'surfaceName' => 'Choose Tenant', + 'surfaceName' => 'Choose ManagedEnvironment', 'pageClass' => ChooseTenant::class, 'panelPlane' => 'tenant', 'surfaceKind' => 'selector', @@ -846,14 +846,14 @@ public static function spec195ResidualSurfaceInventory(): array ], RegisterTenant::class => [ 'surfaceKey' => 'register_tenant', - 'surfaceName' => 'Register Tenant', + 'surfaceName' => 'Register ManagedEnvironment', 'pageClass' => RegisterTenant::class, 'panelPlane' => 'admin', 'surfaceKind' => 'wizard', 'discoveryState' => 'primary_discovered_baseline_exempt', 'closureDecision' => 'separately_governed', 'reasonCategory' => 'registration_form_with_dedicated_rbac', - 'explicitReason' => 'Tenant registration is a dedicated creation workflow with its own visibility rules, bootstrap membership side effects, and audit logging.', + 'explicitReason' => 'ManagedEnvironment registration is a dedicated creation workflow with its own visibility rules, bootstrap membership side effects, and audit logging.', 'evidence' => [ [ 'kind' => 'authorization_test', @@ -872,7 +872,7 @@ public static function spec195ResidualSurfaceInventory(): array ], ManagedTenantOnboardingWizard::class => [ 'surfaceKey' => 'managed_tenant_onboarding_wizard', - 'surfaceName' => 'Managed Tenant Onboarding Wizard', + 'surfaceName' => 'Managed ManagedEnvironment Onboarding Wizard', 'pageClass' => ManagedTenantOnboardingWizard::class, 'panelPlane' => 'admin', 'surfaceKind' => 'wizard', @@ -924,7 +924,7 @@ public static function spec195ResidualSurfaceInventory(): array ], TenantDashboard::class => [ 'surfaceKey' => 'tenant_dashboard', - 'surfaceName' => 'Tenant Dashboard', + 'surfaceName' => 'ManagedEnvironment Dashboard', 'pageClass' => TenantDashboard::class, 'panelPlane' => 'tenant', 'surfaceKind' => 'dashboard_shell', diff --git a/apps/platform/app/Support/Ui/ActionSurface/Enums/ActionSurfacePanelScope.php b/apps/platform/app/Support/Ui/ActionSurface/Enums/ActionSurfacePanelScope.php index 45bde369..f2ffce1e 100644 --- a/apps/platform/app/Support/Ui/ActionSurface/Enums/ActionSurfacePanelScope.php +++ b/apps/platform/app/Support/Ui/ActionSurface/Enums/ActionSurfacePanelScope.php @@ -6,6 +6,6 @@ enum ActionSurfacePanelScope: string { - case Tenant = 'tenant'; + case ManagedEnvironment = 'tenant'; case Admin = 'admin'; } diff --git a/apps/platform/app/Support/Ui/DerivedState/DerivedStateKey.php b/apps/platform/app/Support/Ui/DerivedState/DerivedStateKey.php index a2d66c72..0956410e 100644 --- a/apps/platform/app/Support/Ui/DerivedState/DerivedStateKey.php +++ b/apps/platform/app/Support/Ui/DerivedState/DerivedStateKey.php @@ -48,7 +48,7 @@ public static function fromModel( recordKey: (string) $record->getKey(), variant: $variant, workspaceId: $workspaceId ?? self::normalizeScopeId($record->getAttribute('workspace_id')), - tenantId: $tenantId ?? self::normalizeScopeId($record->getAttribute('tenant_id')), + tenantId: $tenantId ?? self::normalizeScopeId($record->getAttribute('managed_environment_id')), contextHash: self::hashContext($context), ); } @@ -60,7 +60,7 @@ public static function fromModel( * record_key: string, * variant: string, * workspace_id: ?int, - * tenant_id: ?int, + * managed_environment_id: ?int, * context_hash: ?string * } */ @@ -72,7 +72,7 @@ public function toArray(): array 'record_key' => $this->recordKey, 'variant' => $this->variant, 'workspace_id' => $this->workspaceId, - 'tenant_id' => $this->tenantId, + 'managed_environment_id' => $this->tenantId, 'context_hash' => $this->contextHash, ]; } diff --git a/apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionCatalog.php b/apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionCatalog.php index 4d42629f..cfb733b8 100644 --- a/apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionCatalog.php +++ b/apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionCatalog.php @@ -311,7 +311,7 @@ public static function rules(): array canonicalLabel: 'Archive', modalHeading: 'Archive tenant', modalDescription: 'Archive this tenant. TenantPilot keeps it available for inspection and audit history but removes it from active management flows.', - successTitle: 'Tenant archived', + successTitle: 'ManagedEnvironment archived', auditVerb: 'archive tenant', serviceOwner: 'TenantResource', surfaceKeys: ['tenant_index_row', 'view_tenant', 'edit_tenant'], @@ -325,7 +325,7 @@ public static function rules(): array canonicalLabel: 'Restore', modalHeading: 'Restore tenant', modalDescription: 'Restore this tenant so it becomes available again in normal management flows.', - successTitle: 'Tenant restored', + successTitle: 'ManagedEnvironment restored', auditVerb: 'restore tenant', serviceOwner: 'TenantResource', surfaceKeys: ['tenant_index_row', 'view_tenant', 'edit_tenant'], diff --git a/apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php b/apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php index 4cf29593..c7a2fb8f 100644 --- a/apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php +++ b/apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php @@ -409,7 +409,7 @@ private function buildEvidenceSnapshotEnvelope(EvidenceSnapshot $snapshot): Arti artifactFamily: 'evidence_snapshot', artifactKey: 'evidence_snapshot:'.$snapshot->getKey(), workspaceId: (int) $snapshot->workspace_id, - tenantId: $snapshot->tenant_id !== null ? (int) $snapshot->tenant_id : null, + tenantId: $snapshot->managed_environment_id !== null ? (int) $snapshot->managed_environment_id : null, executionOutcome: null, artifactExistence: $artifactExistence, contentState: $contentState, @@ -612,7 +612,7 @@ private function buildTenantReviewEnvelope(TenantReview $review): ArtifactTruthE artifactFamily: 'tenant_review', artifactKey: 'tenant_review:'.$review->getKey(), workspaceId: (int) $review->workspace_id, - tenantId: $review->tenant_id !== null ? (int) $review->tenant_id : null, + tenantId: $review->managed_environment_id !== null ? (int) $review->managed_environment_id : null, executionOutcome: null, artifactExistence: $artifactExistence, contentState: $contentState, @@ -799,7 +799,7 @@ private function buildReviewPackEnvelope(ReviewPack $pack): ArtifactTruthEnvelop artifactFamily: 'review_pack', artifactKey: 'review_pack:'.$pack->getKey(), workspaceId: (int) $pack->workspace_id, - tenantId: $pack->tenant_id !== null ? (int) $pack->tenant_id : null, + tenantId: $pack->managed_environment_id !== null ? (int) $pack->managed_environment_id : null, executionOutcome: null, artifactExistence: $artifactExistence, contentState: $contentState, @@ -882,7 +882,7 @@ private function buildStoredReportEnvelope(StoredReport $report): ArtifactTruthE $report->loadMissing('tenant'); $latestReport = StoredReport::query() - ->where('tenant_id', (int) $report->tenant_id) + ->where('managed_environment_id', (int) $report->managed_environment_id) ->where('report_type', $report->report_type) ->orderByDesc('created_at') ->orderByDesc('id') @@ -897,7 +897,7 @@ private function buildStoredReportEnvelope(StoredReport $report): ArtifactTruthE artifactFamily: 'stored_report', artifactKey: 'stored_report:'.$report->getKey(), workspaceId: (int) $report->workspace_id, - tenantId: (int) $report->tenant_id, + tenantId: (int) $report->managed_environment_id, executionOutcome: null, artifactExistence: $artifactExistence, contentState: 'trusted', @@ -955,7 +955,7 @@ private function buildFindingExceptionDecisionEnvelope(FindingExceptionDecision artifactFamily: 'finding_exception_decision', artifactKey: 'finding_exception_decision:'.$decision->getKey(), workspaceId: (int) $decision->workspace_id, - tenantId: $decision->tenant_id !== null ? (int) $decision->tenant_id : null, + tenantId: $decision->managed_environment_id !== null ? (int) $decision->managed_environment_id : null, executionOutcome: null, artifactExistence: $artifactExistence, contentState: 'trusted', @@ -1045,7 +1045,7 @@ private function buildOperationRunEnvelope(OperationRun $run): ArtifactTruthEnve artifactFamily: 'artifact_run', artifactKey: 'artifact_run:'.$run->getKey(), workspaceId: (int) $run->workspace_id, - tenantId: $run->tenant_id !== null ? (int) $run->tenant_id : null, + tenantId: $run->managed_environment_id !== null ? (int) $run->managed_environment_id : null, executionOutcome: $run->outcome !== null ? (string) $run->outcome : null, artifactExistence: $artifactEnvelope->artifactExistence, contentState: $artifactEnvelope->contentState, @@ -1093,7 +1093,7 @@ private function buildOperationRunEnvelope(OperationRun $run): ArtifactTruthEnve artifactFamily: 'artifact_run', artifactKey: 'artifact_run:'.$run->getKey(), workspaceId: (int) $run->workspace_id, - tenantId: $run->tenant_id !== null ? (int) $run->tenant_id : null, + tenantId: $run->managed_environment_id !== null ? (int) $run->managed_environment_id : null, executionOutcome: $run->outcome !== null ? (string) $run->outcome : null, artifactExistence: $artifactExistence, contentState: $contentState, diff --git a/apps/platform/app/Support/Verification/PreviousVerificationReportResolver.php b/apps/platform/app/Support/Verification/PreviousVerificationReportResolver.php index c0c779a4..f1fa60ef 100644 --- a/apps/platform/app/Support/Verification/PreviousVerificationReportResolver.php +++ b/apps/platform/app/Support/Verification/PreviousVerificationReportResolver.php @@ -20,7 +20,7 @@ public static function resolvePreviousReportId(OperationRun $run): ?int $providerConnectionId = self::providerConnectionId($run); $query = OperationRun::query() - ->where('tenant_id', (int) $run->tenant_id) + ->where('managed_environment_id', (int) $run->managed_environment_id) ->where('workspace_id', (int) $run->workspace_id) ->where('type', (string) $run->type) ->where('run_identity_hash', (string) $run->run_identity_hash) diff --git a/apps/platform/app/Support/Verification/TenantPermissionCheckClusters.php b/apps/platform/app/Support/Verification/TenantPermissionCheckClusters.php index 2108e44d..23eea9a8 100644 --- a/apps/platform/app/Support/Verification/TenantPermissionCheckClusters.php +++ b/apps/platform/app/Support/Verification/TenantPermissionCheckClusters.php @@ -4,7 +4,7 @@ namespace App\Support\Verification; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Links\RequiredPermissionsLinks; use App\Support\OpsUx\RunFailureSanitizer; use App\Support\Providers\ProviderNextStepsRegistry; @@ -26,7 +26,7 @@ final class TenantPermissionCheckClusters * @param array{fresh?:bool,reason_code?:string,message?:string}|null $inventory * @return array> */ - public static function buildChecks(Tenant $tenant, array $permissions, ?array $inventory = null): array + public static function buildChecks(ManagedEnvironment $tenant, array $permissions, ?array $inventory = null): array { $inventory = is_array($inventory) ? $inventory : []; @@ -176,7 +176,7 @@ private static function matches(array $definition, array $row): bool * @return array */ private static function buildCheck( - Tenant $tenant, + ManagedEnvironment $tenant, string $key, string $title, array $clusterRows, @@ -398,7 +398,7 @@ private static function inventoryMessage(string $reasonCode): string /** * @return array */ - private static function nextSteps(Tenant $tenant, string $reasonCode): array + private static function nextSteps(ManagedEnvironment $tenant, string $reasonCode): array { $steps = app(ProviderNextStepsRegistry::class)->forReason($tenant, $reasonCode); diff --git a/apps/platform/app/Support/Verification/VerificationAssistViewModelBuilder.php b/apps/platform/app/Support/Verification/VerificationAssistViewModelBuilder.php index fcaae033..668ba69e 100644 --- a/apps/platform/app/Support/Verification/VerificationAssistViewModelBuilder.php +++ b/apps/platform/app/Support/Verification/VerificationAssistViewModelBuilder.php @@ -5,7 +5,7 @@ namespace App\Support\Verification; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\TenantRequiredPermissionsViewModelBuilder; use App\Support\Links\RequiredPermissionsLinks; use App\Support\Providers\ProviderNextStepsRegistry; @@ -22,7 +22,7 @@ public function __construct( * @param array|null $verificationReport * @return array{is_visible:bool,reason:'permission_blocked'|'permission_attention'|'hidden_ready'|'hidden_irrelevant'} */ - public function visibility(Tenant $tenant, ?array $verificationReport): array + public function visibility(ManagedEnvironment $tenant, ?array $verificationReport): array { return $this->deriveVisibility( $verificationReport, @@ -57,7 +57,7 @@ public function visibility(Tenant $tenant, ?array $verificationReport): array * } */ public function build( - Tenant $tenant, + ManagedEnvironment $tenant, ?array $verificationReport, ?ProviderConnection $providerConnection = null, ?string $verificationStatus = null, @@ -151,7 +151,7 @@ public function build( /** * @return array */ - private function requiredPermissionsViewModel(Tenant $tenant): array + private function requiredPermissionsViewModel(ManagedEnvironment $tenant): array { return $this->requiredPermissionsViewModelBuilder->build($tenant, [ 'status' => 'all', @@ -308,7 +308,7 @@ private function reportHasRelevantPermissionIssue(?array $verificationReport): b * @param array $registrySteps * @return array{label:string,url:?string,opens_in_new_tab:bool,available:bool} */ - private function grantAdminConsentAction(Tenant $tenant, array $counts, array $registrySteps): array + private function grantAdminConsentAction(ManagedEnvironment $tenant, array $counts, array $registrySteps): array { $available = ($counts['missing_application'] + $counts['missing_delegated']) > 0; diff --git a/apps/platform/app/Support/WorkspaceIsolation/TenantOwnedModelFamilies.php b/apps/platform/app/Support/WorkspaceIsolation/TenantOwnedModelFamilies.php index 3b94bde8..8d910b2b 100644 --- a/apps/platform/app/Support/WorkspaceIsolation/TenantOwnedModelFamilies.php +++ b/apps/platform/app/Support/WorkspaceIsolation/TenantOwnedModelFamilies.php @@ -154,7 +154,7 @@ public static function firstSlice(): array 'search_posture' => 'disabled', 'action_surface' => 'declared', 'action_surface_reason' => 'TenantReviewResource declares its action surface contract directly.', - 'notes' => 'Tenant reviews stay out of global search and are surfaced through tenant detail plus the canonical register.', + 'notes' => 'ManagedEnvironment reviews stay out of global search and are surfaced through tenant detail plus the canonical register.', ], 'StoredReport' => [ 'table' => 'stored_reports', diff --git a/apps/platform/app/Support/WorkspaceIsolation/TenantOwnedQueryScope.php b/apps/platform/app/Support/WorkspaceIsolation/TenantOwnedQueryScope.php index d1796b34..39c2dd37 100644 --- a/apps/platform/app/Support/WorkspaceIsolation/TenantOwnedQueryScope.php +++ b/apps/platform/app/Support/WorkspaceIsolation/TenantOwnedQueryScope.php @@ -4,14 +4,14 @@ namespace App\Support\WorkspaceIsolation; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Builder; final class TenantOwnedQueryScope { - public function apply(Builder $query, ?Tenant $tenant, string $relationship = 'tenant'): Builder + public function apply(Builder $query, ?ManagedEnvironment $tenant, string $relationship = 'tenant'): Builder { - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return $this->empty($query); } diff --git a/apps/platform/app/Support/WorkspaceIsolation/WorkspaceIsolationViolation.php b/apps/platform/app/Support/WorkspaceIsolation/WorkspaceIsolationViolation.php index 9f3507d4..e6338b42 100644 --- a/apps/platform/app/Support/WorkspaceIsolation/WorkspaceIsolationViolation.php +++ b/apps/platform/app/Support/WorkspaceIsolation/WorkspaceIsolationViolation.php @@ -10,23 +10,23 @@ class WorkspaceIsolationViolation extends RuntimeException { public static function missingTenantId(string $modelClass): self { - return new self(sprintf('%s must include a tenant_id.', $modelClass)); + return new self(sprintf('%s must include a managed_environment_id.', $modelClass)); } public static function tenantNotFound(string $modelClass, int $tenantId): self { - return new self(sprintf('%s references missing tenant_id %d.', $modelClass, $tenantId)); + return new self(sprintf('%s references missing managed_environment_id %d.', $modelClass, $tenantId)); } public static function tenantWorkspaceMissing(string $modelClass, int $tenantId): self { - return new self(sprintf('%s tenant_id %d has no workspace_id mapping.', $modelClass, $tenantId)); + return new self(sprintf('%s managed_environment_id %d has no workspace_id mapping.', $modelClass, $tenantId)); } public static function workspaceMismatch(string $modelClass, int $tenantId, int $expectedWorkspaceId, int $actualWorkspaceId): self { return new self(sprintf( - '%s tenant_id %d requires workspace_id %d, received %d.', + '%s managed_environment_id %d requires workspace_id %d, received %d.', $modelClass, $tenantId, $expectedWorkspaceId, @@ -37,7 +37,7 @@ public static function workspaceMismatch(string $modelClass, int $tenantId, int public static function tenantImmutable(string $modelClass, int $originalTenantId, int $updatedTenantId): self { return new self(sprintf( - '%s tenant_id is immutable (%d -> %d).', + '%s managed_environment_id is immutable (%d -> %d).', $modelClass, $originalTenantId, $updatedTenantId, diff --git a/apps/platform/app/Support/Workspaces/WorkspaceContext.php b/apps/platform/app/Support/Workspaces/WorkspaceContext.php index 88311596..10a27986 100644 --- a/apps/platform/app/Support/Workspaces/WorkspaceContext.php +++ b/apps/platform/app/Support/Workspaces/WorkspaceContext.php @@ -2,7 +2,7 @@ namespace App\Support\Workspaces; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -55,7 +55,7 @@ public function currentWorkspace(?Request $request = null): ?Workspace return $workspace; } - public function currentWorkspaceOrTenantWorkspace(?Tenant $tenant = null, ?Request $request = null): ?Workspace + public function currentWorkspaceOrTenantWorkspace(?ManagedEnvironment $tenant = null, ?Request $request = null): ?Workspace { $workspace = $this->currentWorkspace($request); @@ -63,7 +63,7 @@ public function currentWorkspaceOrTenantWorkspace(?Tenant $tenant = null, ?Reque return $workspace; } - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -104,7 +104,7 @@ public function rememberLastTenantId(int $workspaceId, int $tenantId, ?Request $ $session->put(self::LAST_TENANT_IDS_SESSION_KEY, $map); } - public function rememberTenantContext(Tenant $tenant, ?Request $request = null): bool + public function rememberTenantContext(ManagedEnvironment $tenant, ?Request $request = null): bool { $workspaceId = $this->currentWorkspaceId($request); @@ -178,7 +178,7 @@ public function clearRememberedTenantContext(?Request $request = null): void $this->clearLastTenantId($request); } - public function rememberedTenant(?Request $request = null): ?Tenant + public function rememberedTenant(?Request $request = null): ?ManagedEnvironment { $workspaceId = $this->currentWorkspaceId($request); @@ -192,12 +192,12 @@ public function rememberedTenant(?Request $request = null): ?Tenant return null; } - $tenant = Tenant::query() + $tenant = ManagedEnvironment::query() ->withTrashed() ->whereKey($rememberedTenantId) ->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { $this->clearRememberedTenantContext($request); return null; @@ -312,7 +312,7 @@ public function currentWorkspaceForMemberOrFail(User $user, ?Request $request = return $workspace; } - public function ensureTenantAccessibleInCurrentWorkspace(Tenant $tenant, User $user, ?Request $request = null): Tenant + public function ensureTenantAccessibleInCurrentWorkspace(ManagedEnvironment $tenant, User $user, ?Request $request = null): ManagedEnvironment { $workspace = $this->currentWorkspaceForMemberOrFail($user, $request); @@ -328,7 +328,7 @@ private function isWorkspaceSelectable(Workspace $workspace): bool return empty($workspace->archived_at); } - private function userCanAccessTenant(Tenant $tenant, ?Request $request = null): bool + private function userCanAccessTenant(ManagedEnvironment $tenant, ?Request $request = null): bool { $user = $request?->user(); diff --git a/apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php b/apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php index 45353a61..0634de7d 100644 --- a/apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php +++ b/apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php @@ -15,7 +15,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Models\User; use App\Models\Workspace; @@ -198,16 +198,16 @@ public function build(Workspace $workspace, User $user): array } /** - * @return Collection + * @return Collection */ private function accessibleTenants(Workspace $workspace, User $user): Collection { - return Tenant::query() + return ManagedEnvironment::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('status', 'active') - ->whereIn('id', $user->tenantMemberships()->select('tenant_id')) + ->where('lifecycle_status', ManagedEnvironment::STATUS_ACTIVE) + ->whereIn('id', $user->tenantMemberships()->select('managed_environment_id')) ->orderBy('name') - ->get(['id', 'name', 'external_id', 'workspace_id']); + ->get(['id', 'name', 'slug', 'workspace_id']); } /** @@ -292,13 +292,13 @@ private function findingsHygieneSignal(Workspace $workspace, array $visibleTenan } /** - * @param Collection $accessibleTenants + * @param Collection $accessibleTenants * @return array */ private function visibleFindingTenantIds(Collection $accessibleTenants, User $user): array { return $accessibleTenants - ->filter(fn (Tenant $tenant): bool => $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW)) + ->filter(fn (ManagedEnvironment $tenant): bool => $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW)) ->pluck('id') ->map(static fn (mixed $id): int => (int) $id) ->values() @@ -337,7 +337,7 @@ private function findingsHygieneDescription(int $brokenAssignmentCount, int $sta } /** - * @param Collection $accessibleTenants + * @param Collection $accessibleTenants * @return list> */ private function tenantContexts(Collection $accessibleTenants, int $workspaceId, bool $canViewAlerts): array @@ -363,9 +363,9 @@ private function tenantContexts(Collection $accessibleTenants, int $workspaceId, $accessibleTenantIds, ) ->terminalFollowUp() - ->selectRaw('tenant_id, count(*) as aggregate_count') - ->groupBy('tenant_id') - ->pluck('aggregate_count', 'tenant_id') + ->selectRaw('managed_environment_id, count(*) as aggregate_count') + ->groupBy('managed_environment_id') + ->pluck('aggregate_count', 'managed_environment_id') ->map(static fn (mixed $count): int => (int) $count) ->all(); @@ -375,9 +375,9 @@ private function tenantContexts(Collection $accessibleTenants, int $workspaceId, $accessibleTenantIds, ) ->activeStaleAttention() - ->selectRaw('tenant_id, count(*) as aggregate_count') - ->groupBy('tenant_id') - ->pluck('aggregate_count', 'tenant_id') + ->selectRaw('managed_environment_id, count(*) as aggregate_count') + ->groupBy('managed_environment_id') + ->pluck('aggregate_count', 'managed_environment_id') ->map(static fn (mixed $count): int => (int) $count) ->all(); @@ -387,9 +387,9 @@ private function tenantContexts(Collection $accessibleTenants, int $workspaceId, $accessibleTenantIds, ) ->healthyActive() - ->selectRaw('tenant_id, count(*) as aggregate_count') - ->groupBy('tenant_id') - ->pluck('aggregate_count', 'tenant_id') + ->selectRaw('managed_environment_id, count(*) as aggregate_count') + ->groupBy('managed_environment_id') + ->pluck('aggregate_count', 'managed_environment_id') ->map(static fn (mixed $count): int => (int) $count) ->all(); @@ -401,15 +401,15 @@ private function tenantContexts(Collection $accessibleTenants, int $workspaceId, ) ->where('created_at', '>=', now()->subDays(7)) ->where('status', AlertDelivery::STATUS_FAILED) - ->selectRaw('tenant_id, count(*) as aggregate_count') - ->groupBy('tenant_id') - ->pluck('aggregate_count', 'tenant_id') + ->selectRaw('managed_environment_id, count(*) as aggregate_count') + ->groupBy('managed_environment_id') + ->pluck('aggregate_count', 'managed_environment_id') ->map(static fn (mixed $count): int => (int) $count) ->all() : []; return $accessibleTenants - ->map(function (Tenant $tenant) use ( + ->map(function (ManagedEnvironment $tenant) use ( $terminalFollowUpCounts, $staleAttentionCounts, $activeOperationCounts, @@ -479,7 +479,7 @@ private function tenantContexts(Collection $accessibleTenants, int $workspaceId, ->all(); } - private function governanceAggregate(Tenant $tenant): TenantGovernanceAggregate + private function governanceAggregate(ManagedEnvironment $tenant): TenantGovernanceAggregate { /** @var TenantGovernanceAggregate $aggregate */ $aggregate = $this->tenantGovernanceAggregateResolver->forTenant($tenant); @@ -529,7 +529,7 @@ private function attentionItems( $tenant = $context['tenant'] ?? null; $aggregate = $context['aggregate'] ?? null; - if (! $tenant instanceof Tenant || ! $aggregate instanceof TenantGovernanceAggregate) { + if (! $tenant instanceof ManagedEnvironment || ! $aggregate instanceof TenantGovernanceAggregate) { return []; } @@ -786,7 +786,7 @@ private function attentionPriority(array $item): int * @param array $context * @return array|null */ - private function backupHealthAttentionItem(Tenant $tenant, array $context, User $user): ?array + private function backupHealthAttentionItem(ManagedEnvironment $tenant, array $context, User $user): ?array { $assessment = $context['backup_health_assessment'] ?? null; @@ -839,7 +839,7 @@ private function backupHealthAttentionItem(Tenant $tenant, array $context, User * @param array $context * @return array|null */ - private function recoveryEvidenceAttentionItem(Tenant $tenant, array $context, User $user): ?array + private function recoveryEvidenceAttentionItem(ManagedEnvironment $tenant, array $context, User $user): ?array { $recoveryEvidence = $context['recovery_evidence'] ?? null; @@ -925,7 +925,7 @@ private function recoveryAttentionTitle(?string $attentionState): string * @return array */ private function makeAttentionItem( - Tenant $tenant, + ManagedEnvironment $tenant, string $key, string $family, string $urgency, @@ -939,7 +939,7 @@ private function makeAttentionItem( ): array { $item = [ 'key' => $key, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'tenant_label' => (string) $tenant->name, 'tenant_route_key' => $this->tenantRouteKey($tenant), 'family' => $family, @@ -983,7 +983,7 @@ private function summaryMetrics( value: $accessibleTenantCount, category: 'scope', description: $accessibleTenantCount > 0 - ? 'Tenant drill-down stays explicit from this workspace home.' + ? 'ManagedEnvironment drill-down stays explicit from this workspace home.' : 'No tenant memberships are available in this workspace yet.', color: $accessibleTenantCount > 0 ? 'primary' : 'warning', destination: $accessibleTenantCount > 0 @@ -1088,7 +1088,7 @@ private function triageReviewProgress(int $workspaceId, array $tenantContexts): foreach ($tenantContexts as $context) { $tenant = $context['tenant'] ?? null; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { continue; } @@ -1276,7 +1276,7 @@ private function attentionMetricDestination(array $tenantContexts, User $user, s $tenant = $affectedContexts[0]['tenant'] ?? null; - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return null; } @@ -1319,7 +1319,7 @@ private function recentOperations( return [ 'id' => (int) $run->getKey(), 'title' => OperationCatalog::label((string) $run->type), - 'tenant_label' => $run->tenant instanceof Tenant ? (string) $run->tenant->name : null, + 'tenant_label' => $run->tenant instanceof ManagedEnvironment ? (string) $run->tenant->name : null, 'status_label' => $statusSpec->label, 'status_color' => $statusSpec->color, 'outcome_label' => $outcomeSpec->label, @@ -1410,10 +1410,10 @@ private function scopeToAuthorizedTenants(Builder $query, int $workspaceId, arra return $query ->where('workspace_id', $workspaceId) ->where(function (Builder $query) use ($accessibleTenantIds): void { - $query->whereNull('tenant_id'); + $query->whereNull('managed_environment_id'); if ($accessibleTenantIds !== []) { - $query->orWhereIn('tenant_id', $accessibleTenantIds); + $query->orWhereIn('managed_environment_id', $accessibleTenantIds); } }); } @@ -1425,7 +1425,7 @@ private function scopeToVisibleTenants(Builder $query, int $workspaceId, array $ { return $query ->where('workspace_id', $workspaceId) - ->whereIn('tenant_id', $accessibleTenantIds === [] ? [0] : $accessibleTenantIds); + ->whereIn('managed_environment_id', $accessibleTenantIds === [] ? [0] : $accessibleTenantIds); } /** @@ -1509,7 +1509,7 @@ private function canManageWorkspaces(Workspace $workspace, User $user): bool return $role !== null && in_array($role->value, $roles, true); } - private function tenantRouteKey(Tenant $tenant): string + private function tenantRouteKey(ManagedEnvironment $tenant): string { return filled($tenant->external_id) ? (string) $tenant->external_id @@ -1558,7 +1558,7 @@ private function switchWorkspaceTarget(string $label = 'Switch workspace'): arra * @return array */ private function tenantDashboardTarget( - Tenant $tenant, + ManagedEnvironment $tenant, User $user, string $label = 'Open tenant dashboard', ?array $arrivalState = null, @@ -1587,7 +1587,7 @@ private function tenantDashboardTarget( * @param array{family: string, state: string|null, reason: string|null} $reasonContext * @return array|null */ - private function workspaceOverviewArrivalState(Tenant $tenant, array $reasonContext): ?array + private function workspaceOverviewArrivalState(ManagedEnvironment $tenant, array $reasonContext): ?array { $family = is_string($reasonContext['family'] ?? null) ? $reasonContext['family'] : null; $state = is_string($reasonContext['state'] ?? null) ? $reasonContext['state'] : null; @@ -1610,7 +1610,7 @@ private function workspaceOverviewArrivalState(Tenant $tenant, array $reasonCont * @param array $context * @return array|null */ - private function workspaceOverviewArrivalStateFromContext(Tenant $tenant, array $context): ?array + private function workspaceOverviewArrivalStateFromContext(ManagedEnvironment $tenant, array $context): ?array { if (($context['has_backup_attention'] ?? false) === true) { return $this->workspaceOverviewArrivalState($tenant, [ @@ -1635,7 +1635,7 @@ private function workspaceOverviewArrivalStateFromContext(Tenant $tenant, array * @param array $filters * @return array */ - private function findingsTarget(Tenant $tenant, User $user, array $filters, string $label = 'Open findings'): array + private function findingsTarget(ManagedEnvironment $tenant, User $user, array $filters, string $label = 'Open findings'): array { if ($this->canOpenFindings($user, $tenant)) { return $this->destination( @@ -1662,7 +1662,7 @@ private function findingsTarget(Tenant $tenant, User $user, array $filters, stri /** * @return array */ - private function baselineCompareTarget(Tenant $tenant, User $user, string $label = 'Open Baseline Compare'): array + private function baselineCompareTarget(ManagedEnvironment $tenant, User $user, string $label = 'Open Baseline Compare'): array { if (! $this->canTenantView($user, $tenant)) { return $this->disabledDestination( @@ -1684,7 +1684,7 @@ private function baselineCompareTarget(Tenant $tenant, User $user, string $label * @return array */ private function operationsIndexTarget( - ?Tenant $tenant, + ?ManagedEnvironment $tenant, CanonicalNavigationContext $navigationContext, ?string $activeTab = null, ?string $problemClass = null, @@ -1696,7 +1696,7 @@ private function operationsIndexTarget( label: $label, tenant: $tenant, filters: array_filter([ - 'tenant_id' => $tenant?->getKey(), + 'managed_environment_id' => $tenant?->getKey(), 'activeTab' => $activeTab, 'problemClass' => $problemClass, ], static fn (mixed $value): bool => $value !== null && $value !== ''), @@ -1708,7 +1708,7 @@ private function operationsIndexTarget( */ private function operationDetailTarget(OperationRun $run, CanonicalNavigationContext $navigationContext): array { - $tenant = $run->tenant instanceof Tenant ? $run->tenant : null; + $tenant = $run->tenant instanceof ManagedEnvironment ? $run->tenant : null; return $this->destination( kind: 'operation_detail', @@ -1743,17 +1743,17 @@ private function alertsOverviewUrl(CanonicalNavigationContext $navigationContext return $this->appendQuery(route('filament.admin.alerts'), $navigationContext->toQuery()); } - private function canTenantView(User $user, Tenant $tenant): bool + private function canTenantView(User $user, ManagedEnvironment $tenant): bool { return $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_VIEW); } - private function canAccessTenantDashboard(User $user, Tenant $tenant): bool + private function canAccessTenantDashboard(User $user, ManagedEnvironment $tenant): bool { return $this->capabilityResolver->isMember($user, $tenant); } - private function canOpenFindings(User $user, Tenant $tenant): bool + private function canOpenFindings(User $user, ManagedEnvironment $tenant): bool { return $this->capabilityResolver->can($user, $tenant, Capabilities::TENANT_FINDINGS_VIEW); } @@ -1766,13 +1766,13 @@ private function destination( string $kind, string $url, string $label, - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, array $filters = [], ): array { return [ 'kind' => $kind, 'url' => $url, - 'tenant_route_key' => $tenant instanceof Tenant ? $this->tenantRouteKey($tenant) : null, + 'tenant_route_key' => $tenant instanceof ManagedEnvironment ? $this->tenantRouteKey($tenant) : null, 'label' => $label, 'disabled' => false, 'helper_text' => null, @@ -1787,13 +1787,13 @@ private function destination( private function disabledDestination( string $kind, string $label, - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, array $filters = [], ): array { return [ 'kind' => $kind, 'url' => null, - 'tenant_route_key' => $tenant instanceof Tenant ? $this->tenantRouteKey($tenant) : null, + 'tenant_route_key' => $tenant instanceof ManagedEnvironment ? $this->tenantRouteKey($tenant) : null, 'label' => $label, 'disabled' => true, 'helper_text' => UiTooltips::INSUFFICIENT_PERMISSION, diff --git a/apps/platform/app/Support/Workspaces/WorkspaceRedirectResolver.php b/apps/platform/app/Support/Workspaces/WorkspaceRedirectResolver.php index 066829b1..486445f0 100644 --- a/apps/platform/app/Support/Workspaces/WorkspaceRedirectResolver.php +++ b/apps/platform/app/Support/Workspaces/WorkspaceRedirectResolver.php @@ -7,7 +7,7 @@ use App\Filament\Pages\ChooseTenant; use App\Filament\Pages\ChooseWorkspace; use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Tenants\TenantOperabilityService; @@ -15,10 +15,10 @@ /** * Resolves the explicit post-selection destination after a workspace is set. * - * Tenant-count branching stays available for chooser-driven flows: + * ManagedEnvironment-count branching stays available for chooser-driven flows: * - 0 tenants → Managed Tenants index - * - 1 tenant → Tenant Dashboard directly - * - >1 tenants → Choose Tenant page + * - 1 tenant → ManagedEnvironment Dashboard directly + * - >1 tenants → Choose ManagedEnvironment page */ final class WorkspaceRedirectResolver { @@ -91,7 +91,7 @@ private function intendedUrlMatchesWorkspace(string $intendedUrl, Workspace $wor parse_str((string) (parse_url($intendedUrl, PHP_URL_QUERY) ?? ''), $query); - $tenantIdentifier = $query['tenant'] ?? $query['tenant_id'] ?? null; + $tenantIdentifier = $query['tenant'] ?? $query['managed_environment_id'] ?? null; if ($tenantIdentifier !== null && ! $this->tenantIdentifierMatchesWorkspace((string) $tenantIdentifier, $workspace, $user)) { return false; @@ -102,10 +102,10 @@ private function intendedUrlMatchesWorkspace(string $intendedUrl, Workspace $wor private function tenantIdentifierMatchesWorkspace(string $identifier, Workspace $workspace, User $user): bool { - $tenant = Tenant::query() + $tenant = ManagedEnvironment::query() ->withTrashed() ->where(static function ($query) use ($identifier): void { - $query->where('external_id', $identifier); + $query->where('slug', $identifier); if (ctype_digit($identifier)) { $query->orWhereKey((int) $identifier); @@ -113,7 +113,7 @@ private function tenantIdentifierMatchesWorkspace(string $identifier, Workspace }) ->first(); - return $tenant instanceof Tenant + return $tenant instanceof ManagedEnvironment && (int) $tenant->workspace_id === (int) $workspace->getKey() && $user->canAccessTenant($tenant); } diff --git a/apps/platform/database/factories/AlertDeliveryFactory.php b/apps/platform/database/factories/AlertDeliveryFactory.php index b09ff2cc..751aabbd 100644 --- a/apps/platform/database/factories/AlertDeliveryFactory.php +++ b/apps/platform/database/factories/AlertDeliveryFactory.php @@ -5,7 +5,7 @@ use App\Models\AlertDelivery; use App\Models\AlertDestination; use App\Models\AlertRule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use Illuminate\Database\Eloquent\Factories\Factory; @@ -19,19 +19,19 @@ class AlertDeliveryFactory extends Factory public function definition(): array { return [ - // tenant_id and alert_rule_id are nullable; test() state sets them to null. + // managed_environment_id and alert_rule_id are nullable; test() state sets them to null. // Default definition creates a tenant-scoped delivery. - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'workspace_id' => function (array $attributes): int { - $tenantId = $attributes['tenant_id'] ?? null; + $tenantId = $attributes['managed_environment_id'] ?? null; if (! is_numeric($tenantId)) { return (int) Workspace::factory()->create()->getKey(); } - $tenant = Tenant::query()->whereKey((int) $tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey((int) $tenantId)->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return (int) Workspace::factory()->create()->getKey(); } @@ -84,7 +84,7 @@ public function definition(): array public function test(): static { return $this->state(fn (array $attributes): array => [ - 'tenant_id' => null, + 'managed_environment_id' => null, 'alert_rule_id' => null, 'event_type' => AlertDelivery::EVENT_TYPE_TEST, 'severity' => null, diff --git a/apps/platform/database/factories/BackupItemFactory.php b/apps/platform/database/factories/BackupItemFactory.php index 5dbae1b6..43120bf5 100644 --- a/apps/platform/database/factories/BackupItemFactory.php +++ b/apps/platform/database/factories/BackupItemFactory.php @@ -4,7 +4,7 @@ use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -20,7 +20,7 @@ class BackupItemFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'backup_set_id' => BackupSet::factory(), 'policy_id' => Policy::factory(), 'policy_identifier' => fake()->uuid(), diff --git a/apps/platform/database/factories/BackupSetFactory.php b/apps/platform/database/factories/BackupSetFactory.php index b66a49f2..1b42f30d 100644 --- a/apps/platform/database/factories/BackupSetFactory.php +++ b/apps/platform/database/factories/BackupSetFactory.php @@ -3,7 +3,7 @@ namespace Database\Factories; use App\Models\BackupItem; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -19,7 +19,7 @@ class BackupSetFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'name' => fake()->words(3, true), 'created_by' => fake()->email(), 'status' => 'completed', diff --git a/apps/platform/database/factories/BaselineTenantAssignmentFactory.php b/apps/platform/database/factories/BaselineTenantAssignmentFactory.php index 287d2d4e..9a8981a9 100644 --- a/apps/platform/database/factories/BaselineTenantAssignmentFactory.php +++ b/apps/platform/database/factories/BaselineTenantAssignmentFactory.php @@ -4,7 +4,7 @@ use App\Models\BaselineProfile; use App\Models\BaselineTenantAssignment; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use Illuminate\Database\Eloquent\Factories\Factory; @@ -22,7 +22,7 @@ public function definition(): array { return [ 'workspace_id' => Workspace::factory(), - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'baseline_profile_id' => BaselineProfile::factory(), 'override_scope_jsonb' => null, 'assigned_by_user_id' => null, diff --git a/apps/platform/database/factories/EntraGroupFactory.php b/apps/platform/database/factories/EntraGroupFactory.php index ffc04a64..e0ce4eec 100644 --- a/apps/platform/database/factories/EntraGroupFactory.php +++ b/apps/platform/database/factories/EntraGroupFactory.php @@ -3,7 +3,7 @@ namespace Database\Factories; use App\Models\EntraGroup; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -16,7 +16,7 @@ class EntraGroupFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'entra_id' => fake()->uuid(), 'display_name' => fake()->company(), 'group_types' => [], diff --git a/apps/platform/database/factories/EntraRoleDefinitionFactory.php b/apps/platform/database/factories/EntraRoleDefinitionFactory.php index 9117c6f7..698ee597 100644 --- a/apps/platform/database/factories/EntraRoleDefinitionFactory.php +++ b/apps/platform/database/factories/EntraRoleDefinitionFactory.php @@ -3,7 +3,7 @@ namespace Database\Factories; use App\Models\EntraRoleDefinition; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -21,7 +21,7 @@ class EntraRoleDefinitionFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'entra_id' => fake()->uuid(), 'display_name' => fake()->jobTitle(), 'is_built_in' => false, diff --git a/apps/platform/database/factories/FindingFactory.php b/apps/platform/database/factories/FindingFactory.php index cb753f6d..8a1dfad3 100644 --- a/apps/platform/database/factories/FindingFactory.php +++ b/apps/platform/database/factories/FindingFactory.php @@ -3,7 +3,7 @@ namespace Database\Factories; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -21,7 +21,7 @@ public function definition(): array $seenAt = now(); return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'scope_key' => hash('sha256', fake()->uuid()), 'baseline_operation_run_id' => null, diff --git a/apps/platform/database/factories/InventoryItemFactory.php b/apps/platform/database/factories/InventoryItemFactory.php index e8d3d7f4..b90c8d91 100644 --- a/apps/platform/database/factories/InventoryItemFactory.php +++ b/apps/platform/database/factories/InventoryItemFactory.php @@ -2,7 +2,7 @@ namespace Database\Factories; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -18,7 +18,7 @@ class InventoryItemFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'policy_type' => 'deviceConfiguration', 'external_id' => fake()->uuid(), 'display_name' => fake()->words(3, true), diff --git a/apps/platform/database/factories/InventoryLinkFactory.php b/apps/platform/database/factories/InventoryLinkFactory.php index e508e371..7f87c17e 100644 --- a/apps/platform/database/factories/InventoryLinkFactory.php +++ b/apps/platform/database/factories/InventoryLinkFactory.php @@ -3,7 +3,7 @@ namespace Database\Factories; use App\Models\InventoryLink; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -16,7 +16,7 @@ class InventoryLinkFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'source_type' => 'inventory_item', 'source_id' => $this->faker->uuid(), 'target_type' => 'foundation_object', diff --git a/apps/platform/database/factories/TenantFactory.php b/apps/platform/database/factories/ManagedEnvironmentFactory.php similarity index 67% rename from apps/platform/database/factories/TenantFactory.php rename to apps/platform/database/factories/ManagedEnvironmentFactory.php index cb97d604..6d44961c 100644 --- a/apps/platform/database/factories/TenantFactory.php +++ b/apps/platform/database/factories/ManagedEnvironmentFactory.php @@ -2,20 +2,20 @@ namespace Database\Factories; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use Illuminate\Database\Eloquent\Factories\Factory; /** - * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Tenant> + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\ManagedEnvironment> */ -class TenantFactory extends Factory +class ManagedEnvironmentFactory extends Factory { protected bool $provisionsWorkspace = true; public function configure(): static { - return $this->afterCreating(function (Tenant $tenant): void { + return $this->afterCreating(function (ManagedEnvironment $tenant): void { if (! $this->provisionsWorkspace || $tenant->workspace_id !== null) { return; } @@ -37,25 +37,19 @@ public function definition(): array { return [ 'name' => fake()->company(), - 'external_id' => fake()->uuid(), - 'tenant_id' => fake()->uuid(), - 'app_client_id' => fake()->uuid(), - 'app_client_secret' => null, // Skip encryption in tests - 'app_certificate_thumbprint' => null, - 'app_notes' => null, - 'status' => 'active', - 'environment' => 'other', + 'display_name' => null, + 'slug' => fake()->unique()->slug(3), + 'kind' => 'managed_environment', + 'lifecycle_status' => 'active', 'is_current' => false, 'metadata' => [], - 'rbac_status' => 'ok', - 'rbac_last_checked_at' => now(), ]; } public function draft(): static { return $this->state(fn (): array => [ - 'status' => Tenant::STATUS_DRAFT, + 'lifecycle_status' => ManagedEnvironment::STATUS_DRAFT, 'is_current' => false, ]); } @@ -63,7 +57,7 @@ public function draft(): static public function onboarding(): static { return $this->state(fn (): array => [ - 'status' => Tenant::STATUS_ONBOARDING, + 'lifecycle_status' => ManagedEnvironment::STATUS_ONBOARDING, 'is_current' => false, ]); } @@ -71,7 +65,7 @@ public function onboarding(): static public function active(): static { return $this->state(fn (): array => [ - 'status' => Tenant::STATUS_ACTIVE, + 'lifecycle_status' => ManagedEnvironment::STATUS_ACTIVE, 'deleted_at' => null, ]); } @@ -79,7 +73,7 @@ public function active(): static public function archived(): static { return $this->state(fn (): array => [ - 'status' => Tenant::STATUS_ARCHIVED, + 'lifecycle_status' => ManagedEnvironment::STATUS_ARCHIVED, 'deleted_at' => now(), 'is_current' => false, ]); @@ -87,13 +81,13 @@ public function archived(): static public function minimal(): static { - Tenant::skipTestWorkspaceProvisioning(); + ManagedEnvironment::skipTestWorkspaceProvisioning(); $factory = clone $this; $factory->provisionsWorkspace = false; return $factory - ->afterCreating(function (Tenant $tenant): void { + ->afterCreating(function (ManagedEnvironment $tenant): void { if ($tenant->workspace_id !== null) { $workspaceId = (int) $tenant->workspace_id; @@ -101,7 +95,7 @@ public function minimal(): static Workspace::query()->whereKey($workspaceId)->delete(); } - Tenant::skipTestWorkspaceProvisioning(false); + ManagedEnvironment::skipTestWorkspaceProvisioning(false); }); } } diff --git a/apps/platform/database/factories/OperationRunFactory.php b/apps/platform/database/factories/OperationRunFactory.php index 99d04611..99b42a87 100644 --- a/apps/platform/database/factories/OperationRunFactory.php +++ b/apps/platform/database/factories/OperationRunFactory.php @@ -3,7 +3,7 @@ namespace Database\Factories; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\OperationRunOutcome; @@ -21,17 +21,17 @@ class OperationRunFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory()->for(Workspace::factory()), + 'managed_environment_id' => ManagedEnvironment::factory()->for(Workspace::factory()), 'workspace_id' => function (array $attributes): int { - $tenantId = $attributes['tenant_id'] ?? null; + $tenantId = $attributes['managed_environment_id'] ?? null; if (! is_numeric($tenantId)) { return (int) Workspace::factory()->create()->getKey(); } - $tenant = Tenant::query()->whereKey((int) $tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey((int) $tenantId)->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return (int) Workspace::factory()->create()->getKey(); } @@ -74,10 +74,10 @@ public function withUser(?User $user = null): static ]); } - public function forTenant(Tenant $tenant): static + public function forTenant(ManagedEnvironment $tenant): static { return $this->state(fn (): array => [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); } @@ -85,7 +85,7 @@ public function forTenant(Tenant $tenant): static public function tenantlessForWorkspace(Workspace $workspace): static { return $this->state(fn (): array => [ - 'tenant_id' => null, + 'managed_environment_id' => null, 'workspace_id' => (int) $workspace->getKey(), ]); } diff --git a/apps/platform/database/factories/PolicyFactory.php b/apps/platform/database/factories/PolicyFactory.php index 7ec96b2d..919cb1af 100644 --- a/apps/platform/database/factories/PolicyFactory.php +++ b/apps/platform/database/factories/PolicyFactory.php @@ -2,7 +2,7 @@ namespace Database\Factories; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -18,7 +18,7 @@ class PolicyFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'external_id' => fake()->uuid(), 'display_name' => fake()->words(3, true), 'policy_type' => 'settingsCatalogPolicy', diff --git a/apps/platform/database/factories/PolicyVersionFactory.php b/apps/platform/database/factories/PolicyVersionFactory.php index be386d1e..237a5726 100644 --- a/apps/platform/database/factories/PolicyVersionFactory.php +++ b/apps/platform/database/factories/PolicyVersionFactory.php @@ -3,7 +3,7 @@ namespace Database\Factories; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Baselines\PolicyVersionCapturePurpose; use Illuminate\Database\Eloquent\Factories\Factory; @@ -20,7 +20,7 @@ class PolicyVersionFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'policy_id' => Policy::factory(), 'version_number' => 1, 'policy_type' => 'settingsCatalogPolicy', diff --git a/apps/platform/database/factories/ProductUsageEventFactory.php b/apps/platform/database/factories/ProductUsageEventFactory.php index 54162c64..fd030d05 100644 --- a/apps/platform/database/factories/ProductUsageEventFactory.php +++ b/apps/platform/database/factories/ProductUsageEventFactory.php @@ -5,7 +5,7 @@ namespace Database\Factories; use App\Models\ProductUsageEvent; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\ProductTelemetry\ProductUsageEventCatalog; @@ -27,17 +27,17 @@ public function definition(): array $eventName = ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED; return [ - 'tenant_id' => Tenant::factory()->for(Workspace::factory()), + 'managed_environment_id' => ManagedEnvironment::factory()->for(Workspace::factory()), 'workspace_id' => function (array $attributes): int { - $tenantId = $attributes['tenant_id'] ?? null; + $tenantId = $attributes['managed_environment_id'] ?? null; if (! is_numeric($tenantId)) { return (int) Workspace::factory()->create()->getKey(); } - $tenant = Tenant::query()->whereKey((int) $tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey((int) $tenantId)->first(); - if (! $tenant instanceof Tenant || $tenant->workspace_id === null) { + if (! $tenant instanceof ManagedEnvironment || $tenant->workspace_id === null) { return (int) Workspace::factory()->create()->getKey(); } diff --git a/apps/platform/database/factories/ProviderConnectionFactory.php b/apps/platform/database/factories/ProviderConnectionFactory.php index f41c6a34..04c29f78 100644 --- a/apps/platform/database/factories/ProviderConnectionFactory.php +++ b/apps/platform/database/factories/ProviderConnectionFactory.php @@ -4,7 +4,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Providers\ProviderConnectionType; use App\Support\Providers\ProviderConsentStatus; @@ -23,17 +23,17 @@ class ProviderConnectionFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory()->for(Workspace::factory()), + 'managed_environment_id' => ManagedEnvironment::factory()->for(Workspace::factory()), 'workspace_id' => function (array $attributes): int { - $tenantId = $attributes['tenant_id'] ?? null; + $tenantId = $attributes['managed_environment_id'] ?? null; if (! is_numeric($tenantId)) { return (int) Workspace::factory()->create()->getKey(); } - $tenant = Tenant::query()->whereKey((int) $tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey((int) $tenantId)->first(); - if (! $tenant instanceof Tenant) { + if (! $tenant instanceof ManagedEnvironment) { return (int) Workspace::factory()->create()->getKey(); } diff --git a/apps/platform/database/factories/RestoreRunFactory.php b/apps/platform/database/factories/RestoreRunFactory.php index 713c6a2a..3172e45a 100644 --- a/apps/platform/database/factories/RestoreRunFactory.php +++ b/apps/platform/database/factories/RestoreRunFactory.php @@ -3,7 +3,7 @@ namespace Database\Factories; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -19,7 +19,7 @@ class RestoreRunFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'backup_set_id' => BackupSet::factory(), 'status' => 'completed', 'is_dry_run' => false, diff --git a/apps/platform/database/factories/ReviewPackFactory.php b/apps/platform/database/factories/ReviewPackFactory.php index de77f572..538e2cbd 100644 --- a/apps/platform/database/factories/ReviewPackFactory.php +++ b/apps/platform/database/factories/ReviewPackFactory.php @@ -5,7 +5,7 @@ namespace Database\Factories; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\ReviewPackStatus; @@ -24,17 +24,17 @@ class ReviewPackFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory()->for(Workspace::factory()), + 'managed_environment_id' => ManagedEnvironment::factory()->for(Workspace::factory()), 'workspace_id' => function (array $attributes): int { - $tenantId = $attributes['tenant_id'] ?? null; + $tenantId = $attributes['managed_environment_id'] ?? null; if (! is_numeric($tenantId)) { return (int) Workspace::factory()->create()->getKey(); } - $tenant = Tenant::query()->whereKey((int) $tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey((int) $tenantId)->first(); - if (! $tenant instanceof Tenant || $tenant->workspace_id === null) { + if (! $tenant instanceof ManagedEnvironment || $tenant->workspace_id === null) { return (int) Workspace::factory()->create()->getKey(); } diff --git a/apps/platform/database/factories/StoredReportFactory.php b/apps/platform/database/factories/StoredReportFactory.php index 1ca051f5..e40784c2 100644 --- a/apps/platform/database/factories/StoredReportFactory.php +++ b/apps/platform/database/factories/StoredReportFactory.php @@ -5,7 +5,7 @@ namespace Database\Factories; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -21,7 +21,7 @@ class StoredReportFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => [ 'posture_score' => 86, diff --git a/apps/platform/database/factories/SupportRequestFactory.php b/apps/platform/database/factories/SupportRequestFactory.php index b49a4951..f3103a97 100644 --- a/apps/platform/database/factories/SupportRequestFactory.php +++ b/apps/platform/database/factories/SupportRequestFactory.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Str; @@ -26,7 +26,7 @@ class SupportRequestFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'initiated_by_user_id' => User::factory(), 'internal_reference' => 'SR-'.strtoupper((string) Str::ulid()), 'primary_context_type' => SupportRequest::PRIMARY_CONTEXT_TENANT, @@ -76,7 +76,7 @@ public function canonicalContextOnly(): static public function forOperationRun(OperationRun $operationRun): static { return $this->state(fn (): array => [ - 'tenant_id' => (int) $operationRun->tenant_id, + 'managed_environment_id' => (int) $operationRun->managed_environment_id, 'workspace_id' => (int) $operationRun->workspace_id, 'operation_run_id' => (int) $operationRun->getKey(), 'primary_context_type' => SupportRequest::PRIMARY_CONTEXT_OPERATION_RUN, @@ -86,7 +86,7 @@ public function forOperationRun(OperationRun $operationRun): static 'attachment_mode' => SupportRequest::ATTACHMENT_MODE_DIAGNOSTIC_SNAPSHOT_ATTACHED, 'primary_context' => [ 'type' => SupportRequest::PRIMARY_CONTEXT_OPERATION_RUN, - 'tenant_id' => (int) $operationRun->tenant_id, + 'managed_environment_id' => (int) $operationRun->managed_environment_id, 'operation_run_id' => (int) $operationRun->getKey(), ], 'canonical_context' => [ diff --git a/apps/platform/database/factories/TenantOnboardingSessionFactory.php b/apps/platform/database/factories/TenantOnboardingSessionFactory.php index 1f06c031..a574817d 100644 --- a/apps/platform/database/factories/TenantOnboardingSessionFactory.php +++ b/apps/platform/database/factories/TenantOnboardingSessionFactory.php @@ -4,7 +4,7 @@ namespace Database\Factories; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -26,7 +26,7 @@ public function definition(): array return [ 'workspace_id' => Workspace::factory(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'entra_tenant_id' => $entraTenantId, 'current_step' => 'identify', 'state' => [ @@ -54,15 +54,15 @@ public function forWorkspace(Workspace $workspace): static ]); } - public function forTenant(Tenant $tenant): static + public function forTenant(ManagedEnvironment $tenant): static { return $this->state(fn (array $attributes): array => [ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'state' => array_merge(is_array($attributes['state'] ?? null) ? $attributes['state'] : [], [ - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'environment' => (string) ($tenant->environment ?? 'prod'), ]), @@ -148,7 +148,7 @@ public function cancelled(): static ]); } - public function resumableForTenant(Tenant $tenant): static + public function resumableForTenant(ManagedEnvironment $tenant): static { return $this->forTenant($tenant)->state(fn (): array => [ 'completed_at' => null, diff --git a/apps/platform/database/factories/TenantReviewFactory.php b/apps/platform/database/factories/TenantReviewFactory.php index fe0bd8ba..6412f67d 100644 --- a/apps/platform/database/factories/TenantReviewFactory.php +++ b/apps/platform/database/factories/TenantReviewFactory.php @@ -5,7 +5,7 @@ namespace Database\Factories; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Models\Workspace; @@ -26,17 +26,17 @@ class TenantReviewFactory extends Factory public function definition(): array { return [ - 'tenant_id' => Tenant::factory()->for(Workspace::factory()), + 'managed_environment_id' => ManagedEnvironment::factory()->for(Workspace::factory()), 'workspace_id' => function (array $attributes): int { - $tenantId = $attributes['tenant_id'] ?? null; + $tenantId = $attributes['managed_environment_id'] ?? null; if (! is_numeric($tenantId)) { return (int) Workspace::factory()->create()->getKey(); } - $tenant = Tenant::query()->whereKey((int) $tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey((int) $tenantId)->first(); - if (! $tenant instanceof Tenant || $tenant->workspace_id === null) { + if (! $tenant instanceof ManagedEnvironment || $tenant->workspace_id === null) { return (int) Workspace::factory()->create()->getKey(); } diff --git a/apps/platform/database/factories/TenantReviewSectionFactory.php b/apps/platform/database/factories/TenantReviewSectionFactory.php index 2d15ef36..30f65dd8 100644 --- a/apps/platform/database/factories/TenantReviewSectionFactory.php +++ b/apps/platform/database/factories/TenantReviewSectionFactory.php @@ -29,10 +29,10 @@ public function definition(): array return (int) $review->workspace_id; }, - 'tenant_id' => function (array $attributes): int { + 'managed_environment_id' => function (array $attributes): int { $review = TenantReview::query()->whereKey((int) $attributes['tenant_review_id'])->firstOrFail(); - return (int) $review->tenant_id; + return (int) $review->managed_environment_id; }, 'section_key' => Str::snake(fake()->words(2, true)), 'title' => fake()->sentence(3), diff --git a/apps/platform/database/factories/TenantSettingFactory.php b/apps/platform/database/factories/TenantSettingFactory.php index 547970da..a10fe363 100644 --- a/apps/platform/database/factories/TenantSettingFactory.php +++ b/apps/platform/database/factories/TenantSettingFactory.php @@ -2,7 +2,7 @@ namespace Database\Factories; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantSetting; use App\Models\User; use Illuminate\Database\Eloquent\Factories\Factory; @@ -21,7 +21,7 @@ public function definition(): array { return [ 'workspace_id' => null, - 'tenant_id' => Tenant::factory(), + 'managed_environment_id' => ManagedEnvironment::factory(), 'domain' => 'backup', 'key' => 'retention_keep_last_default', 'value' => 45, diff --git a/apps/platform/database/factories/TenantTriageReviewFactory.php b/apps/platform/database/factories/TenantTriageReviewFactory.php index 52580288..483616e7 100644 --- a/apps/platform/database/factories/TenantTriageReviewFactory.php +++ b/apps/platform/database/factories/TenantTriageReviewFactory.php @@ -4,7 +4,7 @@ namespace Database\Factories; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Models\User; use App\Models\Workspace; @@ -32,17 +32,17 @@ public function definition(): array ]; return [ - 'tenant_id' => Tenant::factory()->for(Workspace::factory()), + 'managed_environment_id' => ManagedEnvironment::factory()->for(Workspace::factory()), 'workspace_id' => function (array $attributes): int { - $tenantId = $attributes['tenant_id'] ?? null; + $tenantId = $attributes['managed_environment_id'] ?? null; if (! is_numeric($tenantId)) { return (int) Workspace::factory()->create()->getKey(); } - $tenant = Tenant::query()->whereKey((int) $tenantId)->first(); + $tenant = ManagedEnvironment::query()->whereKey((int) $tenantId)->first(); - if (! $tenant instanceof Tenant || ! is_numeric($tenant->workspace_id)) { + if (! $tenant instanceof ManagedEnvironment || ! is_numeric($tenant->workspace_id)) { return (int) Workspace::factory()->create()->getKey(); } diff --git a/apps/platform/database/factories/VerificationCheckAcknowledgementFactory.php b/apps/platform/database/factories/VerificationCheckAcknowledgementFactory.php index 17cec3a9..726b86f5 100644 --- a/apps/platform/database/factories/VerificationCheckAcknowledgementFactory.php +++ b/apps/platform/database/factories/VerificationCheckAcknowledgementFactory.php @@ -20,8 +20,8 @@ public function definition(): array 'operation_run_id' => function (): int { return (int) OperationRun::factory()->create()->getKey(); }, - 'tenant_id' => function (array $attributes): int { - return (int) OperationRun::query()->whereKey((int) $attributes['operation_run_id'])->value('tenant_id'); + 'managed_environment_id' => function (array $attributes): int { + return (int) OperationRun::query()->whereKey((int) $attributes['operation_run_id'])->value('managed_environment_id'); }, 'workspace_id' => function (array $attributes): int { return (int) OperationRun::query()->whereKey((int) $attributes['operation_run_id'])->value('workspace_id'); diff --git a/apps/platform/database/migrations/2025_12_10_000100_create_tenants_table.php b/apps/platform/database/migrations/2025_12_10_000100_create_tenants_table.php index 0e4feb7f..94f040a7 100644 --- a/apps/platform/database/migrations/2025_12_10_000100_create_tenants_table.php +++ b/apps/platform/database/migrations/2025_12_10_000100_create_tenants_table.php @@ -8,10 +8,13 @@ { public function up(): void { - Schema::create('tenants', function (Blueprint $table) { + Schema::create('managed_environments', function (Blueprint $table) { $table->id(); $table->string('name'); - $table->string('external_id')->unique(); + $table->string('display_name')->nullable(); + $table->string('slug')->unique(); + $table->string('kind')->default('managed_environment'); + $table->string('lifecycle_status')->default('active'); $table->json('metadata')->nullable(); $table->timestamps(); }); @@ -19,6 +22,6 @@ public function up(): void public function down(): void { - Schema::dropIfExists('tenants'); + Schema::dropIfExists('managed_environments'); } }; diff --git a/apps/platform/database/migrations/2025_12_10_000110_create_policies_table.php b/apps/platform/database/migrations/2025_12_10_000110_create_policies_table.php index fdbc9a79..58ac332a 100644 --- a/apps/platform/database/migrations/2025_12_10_000110_create_policies_table.php +++ b/apps/platform/database/migrations/2025_12_10_000110_create_policies_table.php @@ -10,7 +10,7 @@ public function up(): void { Schema::create('policies', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->string('external_id'); $table->string('policy_type'); $table->string('platform')->nullable(); @@ -19,8 +19,8 @@ public function up(): void $table->json('metadata')->nullable(); $table->timestamps(); - $table->unique(['tenant_id', 'external_id', 'policy_type']); - $table->index(['tenant_id', 'policy_type', 'platform']); + $table->unique(['managed_environment_id', 'external_id', 'policy_type']); + $table->index(['managed_environment_id', 'policy_type', 'platform']); $table->index('last_synced_at'); }); } diff --git a/apps/platform/database/migrations/2025_12_10_000120_create_policy_versions_table.php b/apps/platform/database/migrations/2025_12_10_000120_create_policy_versions_table.php index ff9ec1fb..3579b50e 100644 --- a/apps/platform/database/migrations/2025_12_10_000120_create_policy_versions_table.php +++ b/apps/platform/database/migrations/2025_12_10_000120_create_policy_versions_table.php @@ -10,7 +10,7 @@ public function up(): void { Schema::create('policy_versions', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('policy_id')->constrained()->cascadeOnDelete(); $table->unsignedBigInteger('version_number'); $table->string('policy_type'); @@ -22,7 +22,7 @@ public function up(): void $table->timestamps(); $table->unique(['policy_id', 'version_number']); - $table->index(['tenant_id', 'policy_type']); + $table->index(['managed_environment_id', 'policy_type']); $table->index('captured_at'); }); } diff --git a/apps/platform/database/migrations/2025_12_10_000130_create_backup_sets_table.php b/apps/platform/database/migrations/2025_12_10_000130_create_backup_sets_table.php index 698d1ed0..e6c065b0 100644 --- a/apps/platform/database/migrations/2025_12_10_000130_create_backup_sets_table.php +++ b/apps/platform/database/migrations/2025_12_10_000130_create_backup_sets_table.php @@ -10,7 +10,7 @@ public function up(): void { Schema::create('backup_sets', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->string('name'); $table->string('created_by')->nullable(); $table->string('status')->default('pending'); @@ -19,7 +19,7 @@ public function up(): void $table->json('metadata')->nullable(); $table->timestamps(); - $table->index(['tenant_id', 'status']); + $table->index(['managed_environment_id', 'status']); $table->index('completed_at'); }); } diff --git a/apps/platform/database/migrations/2025_12_10_000140_create_backup_items_table.php b/apps/platform/database/migrations/2025_12_10_000140_create_backup_items_table.php index 258698a1..43a8d856 100644 --- a/apps/platform/database/migrations/2025_12_10_000140_create_backup_items_table.php +++ b/apps/platform/database/migrations/2025_12_10_000140_create_backup_items_table.php @@ -10,7 +10,7 @@ public function up(): void { Schema::create('backup_items', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('backup_set_id')->constrained()->cascadeOnDelete(); $table->foreignId('policy_id')->nullable()->constrained()->nullOnDelete(); $table->string('policy_identifier'); @@ -22,7 +22,7 @@ public function up(): void $table->timestamps(); $table->unique(['backup_set_id', 'policy_identifier', 'policy_type']); - $table->index(['tenant_id', 'policy_type']); + $table->index(['managed_environment_id', 'policy_type']); $table->index('captured_at'); }); } diff --git a/apps/platform/database/migrations/2025_12_10_000150_create_restore_runs_table.php b/apps/platform/database/migrations/2025_12_10_000150_create_restore_runs_table.php index eb9f3940..5d695ca3 100644 --- a/apps/platform/database/migrations/2025_12_10_000150_create_restore_runs_table.php +++ b/apps/platform/database/migrations/2025_12_10_000150_create_restore_runs_table.php @@ -10,7 +10,7 @@ public function up(): void { Schema::create('restore_runs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('backup_set_id')->constrained()->cascadeOnDelete(); $table->string('requested_by')->nullable(); $table->boolean('is_dry_run')->default(true); @@ -24,7 +24,7 @@ public function up(): void $table->json('metadata')->nullable(); $table->timestamps(); - $table->index(['tenant_id', 'status']); + $table->index(['managed_environment_id', 'status']); $table->index('started_at'); $table->index('completed_at'); }); diff --git a/apps/platform/database/migrations/2025_12_10_000160_create_audit_logs_table.php b/apps/platform/database/migrations/2025_12_10_000160_create_audit_logs_table.php index 23f8a296..107d78bc 100644 --- a/apps/platform/database/migrations/2025_12_10_000160_create_audit_logs_table.php +++ b/apps/platform/database/migrations/2025_12_10_000160_create_audit_logs_table.php @@ -10,7 +10,7 @@ public function up(): void { Schema::create('audit_logs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->unsignedBigInteger('actor_id')->nullable(); $table->string('actor_email')->nullable(); $table->string('actor_name')->nullable(); @@ -22,8 +22,8 @@ public function up(): void $table->timestamp('recorded_at')->useCurrent(); $table->timestamps(); - $table->index(['tenant_id', 'action']); - $table->index(['tenant_id', 'resource_type']); + $table->index(['managed_environment_id', 'action']); + $table->index(['managed_environment_id', 'resource_type']); $table->index('recorded_at'); }); } diff --git a/apps/platform/database/migrations/2025_12_11_121623_add_app_fields_to_tenants_table.php b/apps/platform/database/migrations/2025_12_11_121623_add_app_fields_to_tenants_table.php index a7185397..07c8e71d 100644 --- a/apps/platform/database/migrations/2025_12_11_121623_add_app_fields_to_tenants_table.php +++ b/apps/platform/database/migrations/2025_12_11_121623_add_app_fields_to_tenants_table.php @@ -1,8 +1,6 @@ string('tenant_id')->nullable()->after('name'); - $table->string('domain')->nullable()->after('tenant_id'); - $table->string('app_client_id')->nullable()->after('domain'); - $table->text('app_client_secret')->nullable()->after('app_client_id'); - $table->string('app_certificate_thumbprint')->nullable()->after('app_client_secret'); - $table->string('app_status')->default('unknown')->after('app_certificate_thumbprint'); - $table->text('app_notes')->nullable()->after('app_status'); - - $table->unique('tenant_id'); - }); - - Schema::table('tenants', function (Blueprint $table) { - $table->index('domain'); - $table->index('app_status'); - }); - - DB::table('tenants') - ->whereNull('tenant_id') - ->update(['tenant_id' => DB::raw('external_id')]); + // Provider-specific identity fields intentionally no longer live on + // ManagedEnvironment. ProviderConnection carries Microsoft identity. + Schema::hasTable('managed_environments'); } /** @@ -39,17 +20,6 @@ public function up(): void */ public function down(): void { - Schema::table('tenants', function (Blueprint $table) { - $table->dropUnique(['tenant_id']); - $table->dropColumn([ - 'tenant_id', - 'domain', - 'app_client_id', - 'app_client_secret', - 'app_certificate_thumbprint', - 'app_status', - 'app_notes', - ]); - }); + Schema::hasTable('managed_environments'); } }; diff --git a/apps/platform/database/migrations/2025_12_11_122423_create_tenant_permissions_table.php b/apps/platform/database/migrations/2025_12_11_122423_create_tenant_permissions_table.php index a1b47a95..5c6dcfb6 100644 --- a/apps/platform/database/migrations/2025_12_11_122423_create_tenant_permissions_table.php +++ b/apps/platform/database/migrations/2025_12_11_122423_create_tenant_permissions_table.php @@ -13,15 +13,15 @@ public function up(): void { Schema::create('tenant_permissions', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->string('permission_key'); $table->string('status')->default('missing'); $table->timestamp('last_checked_at')->nullable(); $table->json('details')->nullable(); $table->timestamps(); - $table->unique(['tenant_id', 'permission_key']); - $table->index(['tenant_id', 'status']); + $table->unique(['managed_environment_id', 'permission_key']); + $table->index(['managed_environment_id', 'status']); }); } diff --git a/apps/platform/database/migrations/2025_12_11_130000_add_soft_deletes_and_status_housekeeping.php b/apps/platform/database/migrations/2025_12_11_130000_add_soft_deletes_and_status_housekeeping.php index 45c4361a..340caadb 100644 --- a/apps/platform/database/migrations/2025_12_11_130000_add_soft_deletes_and_status_housekeeping.php +++ b/apps/platform/database/migrations/2025_12_11_130000_add_soft_deletes_and_status_housekeeping.php @@ -24,10 +24,9 @@ public function up(): void $table->softDeletes(); }); - Schema::table('tenants', function (Blueprint $table) { - $table->string('status')->default('active')->after('app_status'); + Schema::table('managed_environments', function (Blueprint $table) { $table->softDeletes(); - $table->index('status'); + $table->index('lifecycle_status'); }); } @@ -49,10 +48,9 @@ public function down(): void $table->dropSoftDeletes(); }); - Schema::table('tenants', function (Blueprint $table) { - $table->dropColumn('status'); + Schema::table('managed_environments', function (Blueprint $table) { $table->dropSoftDeletes(); - $table->dropIndex(['status']); + $table->dropIndex(['lifecycle_status']); }); } }; diff --git a/apps/platform/database/migrations/2025_12_11_192942_add_is_current_to_tenants.php b/apps/platform/database/migrations/2025_12_11_192942_add_is_current_to_tenants.php index 6e16d4b9..a4d24a84 100644 --- a/apps/platform/database/migrations/2025_12_11_192942_add_is_current_to_tenants.php +++ b/apps/platform/database/migrations/2025_12_11_192942_add_is_current_to_tenants.php @@ -12,47 +12,33 @@ */ public function up(): void { - Schema::table('tenants', function (Blueprint $table) { - $table->boolean('is_current')->default(false)->after('status'); + Schema::table('managed_environments', function (Blueprint $table) { + $table->boolean('is_current')->default(false)->after('lifecycle_status'); }); - DB::table('tenants')->update(['is_current' => false]); + DB::table('managed_environments')->update(['is_current' => false]); - $preferredCurrentId = DB::table('tenants') + $preferredCurrentId = DB::table('managed_environments') ->whereNull('deleted_at') - ->where('status', 'active') - ->where('app_status', 'ok') + ->where('lifecycle_status', 'active') ->orderBy('created_at') ->value('id'); if ($preferredCurrentId === null) { - $preferredCurrentId = DB::table('tenants') + $preferredCurrentId = DB::table('managed_environments') ->whereNull('deleted_at') - ->where('status', 'active') - ->where('tenant_id', '<>', 'local-tenant') - ->orderBy('created_at') - ->value('id'); - } - - if ($preferredCurrentId === null) { - $preferredCurrentId = DB::table('tenants') - ->whereNull('deleted_at') - ->where('status', 'active') + ->where('lifecycle_status', 'active') ->orderBy('created_at') ->value('id'); } if ($preferredCurrentId !== null) { - DB::table('tenants') + DB::table('managed_environments') ->where('id', $preferredCurrentId) ->update(['is_current' => true]); } - DB::table('tenants') - ->where('tenant_id', 'local-tenant') - ->update(['status' => 'archived', 'is_current' => false]); - - DB::statement('CREATE UNIQUE INDEX tenants_current_unique ON tenants (is_current) WHERE is_current = true AND deleted_at IS NULL'); + DB::statement('CREATE UNIQUE INDEX tenants_current_unique ON managed_environments (is_current) WHERE is_current = true AND deleted_at IS NULL'); } /** @@ -62,7 +48,7 @@ public function down(): void { DB::statement('DROP INDEX IF EXISTS tenants_current_unique'); - Schema::table('tenants', function (Blueprint $table) { + Schema::table('managed_environments', function (Blueprint $table) { $table->dropColumn('is_current'); }); } diff --git a/apps/platform/database/migrations/2025_12_12_150000_add_rbac_fields_to_tenants.php b/apps/platform/database/migrations/2025_12_12_150000_add_rbac_fields_to_tenants.php index b572f232..9648d218 100644 --- a/apps/platform/database/migrations/2025_12_12_150000_add_rbac_fields_to_tenants.php +++ b/apps/platform/database/migrations/2025_12_12_150000_add_rbac_fields_to_tenants.php @@ -8,8 +8,8 @@ { public function up(): void { - Schema::table('tenants', function (Blueprint $table) { - $table->string('rbac_group_id')->nullable()->after('app_notes'); + Schema::table('managed_environments', function (Blueprint $table) { + $table->string('rbac_group_id')->nullable()->after('metadata'); $table->string('rbac_role_assignment_id')->nullable()->after('rbac_group_id'); $table->string('rbac_role_key')->nullable()->after('rbac_role_assignment_id'); $table->string('rbac_scope_mode')->nullable()->after('rbac_role_key'); @@ -21,7 +21,7 @@ public function up(): void public function down(): void { - Schema::table('tenants', function (Blueprint $table) { + Schema::table('managed_environments', function (Blueprint $table) { $table->dropIndex('tenants_rbac_artifacts_idx'); $table->dropColumn([ 'rbac_group_id', diff --git a/apps/platform/database/migrations/2025_12_12_151000_add_rbac_status_fields_to_tenants.php b/apps/platform/database/migrations/2025_12_12_151000_add_rbac_status_fields_to_tenants.php index 7f059180..36f90856 100644 --- a/apps/platform/database/migrations/2025_12_12_151000_add_rbac_status_fields_to_tenants.php +++ b/apps/platform/database/migrations/2025_12_12_151000_add_rbac_status_fields_to_tenants.php @@ -8,7 +8,7 @@ { public function up(): void { - Schema::table('tenants', function (Blueprint $table) { + Schema::table('managed_environments', function (Blueprint $table) { $table->string('rbac_status')->nullable()->after('rbac_scope_id'); $table->string('rbac_status_reason')->nullable()->after('rbac_status'); $table->timestamp('rbac_last_checked_at')->nullable()->after('rbac_status_reason'); @@ -17,7 +17,7 @@ public function up(): void public function down(): void { - Schema::table('tenants', function (Blueprint $table) { + Schema::table('managed_environments', function (Blueprint $table) { $table->dropColumn([ 'rbac_status', 'rbac_status_reason', diff --git a/apps/platform/database/migrations/2025_12_12_160000_add_rbac_summary_to_tenants.php b/apps/platform/database/migrations/2025_12_12_160000_add_rbac_summary_to_tenants.php index f37a8e2c..dadb34e9 100644 --- a/apps/platform/database/migrations/2025_12_12_160000_add_rbac_summary_to_tenants.php +++ b/apps/platform/database/migrations/2025_12_12_160000_add_rbac_summary_to_tenants.php @@ -8,7 +8,7 @@ { public function up(): void { - Schema::table('tenants', function (Blueprint $table) { + Schema::table('managed_environments', function (Blueprint $table) { $table->unsignedBigInteger('rbac_last_setup_by')->nullable()->after('rbac_last_checked_at'); $table->timestamp('rbac_last_setup_at')->nullable()->after('rbac_last_setup_by'); $table->json('rbac_canary_results')->nullable()->after('rbac_last_setup_at'); @@ -18,7 +18,7 @@ public function up(): void public function down(): void { - Schema::table('tenants', function (Blueprint $table) { + Schema::table('managed_environments', function (Blueprint $table) { $table->dropColumn([ 'rbac_last_setup_by', 'rbac_last_setup_at', diff --git a/apps/platform/database/migrations/2025_12_12_170500_add_rbac_role_definition_columns_to_tenants.php b/apps/platform/database/migrations/2025_12_12_170500_add_rbac_role_definition_columns_to_tenants.php index 71d77b27..f40d9c16 100644 --- a/apps/platform/database/migrations/2025_12_12_170500_add_rbac_role_definition_columns_to_tenants.php +++ b/apps/platform/database/migrations/2025_12_12_170500_add_rbac_role_definition_columns_to_tenants.php @@ -8,7 +8,7 @@ { public function up(): void { - Schema::table('tenants', function (Blueprint $table) { + Schema::table('managed_environments', function (Blueprint $table) { $table->string('rbac_role_definition_id')->nullable()->after('rbac_role_assignment_id'); $table->string('rbac_role_display_name')->nullable()->after('rbac_role_definition_id'); }); @@ -16,7 +16,7 @@ public function up(): void public function down(): void { - Schema::table('tenants', function (Blueprint $table) { + Schema::table('managed_environments', function (Blueprint $table) { $table->dropColumn(['rbac_role_definition_id', 'rbac_role_display_name']); }); } diff --git a/apps/platform/database/migrations/2025_12_23_215901_create_bulk_operation_runs_table.php b/apps/platform/database/migrations/2025_12_23_215901_create_bulk_operation_runs_table.php index 18e05473..c902be78 100644 --- a/apps/platform/database/migrations/2025_12_23_215901_create_bulk_operation_runs_table.php +++ b/apps/platform/database/migrations/2025_12_23_215901_create_bulk_operation_runs_table.php @@ -14,7 +14,7 @@ public function up(): void { Schema::create('bulk_operation_runs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('user_id')->constrained()->cascadeOnDelete(); $table->string('resource', 50); $table->string('action', 50); @@ -31,7 +31,7 @@ public function up(): void }); Schema::table('bulk_operation_runs', function (Blueprint $table) { - $table->index(['tenant_id', 'resource', 'status'], 'bulk_runs_tenant_resource_status'); + $table->index(['managed_environment_id', 'resource', 'status'], 'bulk_runs_tenant_resource_status'); $table->index(['user_id', 'created_at'], 'bulk_runs_user_created'); }); diff --git a/apps/platform/database/migrations/2026_01_04_135956_add_environment_to_tenants_table.php b/apps/platform/database/migrations/2026_01_04_135956_add_environment_to_tenants_table.php index 8576c8c0..04dcd685 100644 --- a/apps/platform/database/migrations/2026_01_04_135956_add_environment_to_tenants_table.php +++ b/apps/platform/database/migrations/2026_01_04_135956_add_environment_to_tenants_table.php @@ -8,17 +8,11 @@ { public function up(): void { - Schema::table('tenants', function (Blueprint $table) { - $table->string('environment')->default('other')->after('status'); - $table->index('environment'); - }); + Schema::hasTable('managed_environments'); } public function down(): void { - Schema::table('tenants', function (Blueprint $table) { - $table->dropIndex(['environment']); - $table->dropColumn('environment'); - }); + Schema::hasTable('managed_environments'); } }; diff --git a/apps/platform/database/migrations/2026_01_04_135957_create_tenant_user_table.php b/apps/platform/database/migrations/2026_01_04_135957_create_tenant_user_table.php index c0b5dcf8..8bf5f906 100644 --- a/apps/platform/database/migrations/2026_01_04_135957_create_tenant_user_table.php +++ b/apps/platform/database/migrations/2026_01_04_135957_create_tenant_user_table.php @@ -9,18 +9,18 @@ { public function up(): void { - Schema::create('tenant_user', function (Blueprint $table) { - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + Schema::create('managed_environment_user', function (Blueprint $table) { + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('user_id')->constrained()->cascadeOnDelete(); $table->string('role')->default('owner'); $table->timestamps(); - $table->unique(['tenant_id', 'user_id']); + $table->unique(['managed_environment_id', 'user_id']); }); $now = now(); - $tenantIds = DB::table('tenants') + $tenantIds = DB::table('managed_environments') ->whereNull('deleted_at') ->pluck('id'); @@ -35,7 +35,7 @@ public function up(): void foreach ($tenantIds as $tenantId) { foreach ($userIds as $userId) { $rows[] = [ - 'tenant_id' => $tenantId, + 'managed_environment_id' => $tenantId, 'user_id' => $userId, 'role' => 'owner', 'created_at' => $now, @@ -43,19 +43,19 @@ public function up(): void ]; if (count($rows) >= 500) { - DB::table('tenant_user')->insertOrIgnore($rows); + DB::table('managed_environment_user')->insertOrIgnore($rows); $rows = []; } } } if ($rows !== []) { - DB::table('tenant_user')->insertOrIgnore($rows); + DB::table('managed_environment_user')->insertOrIgnore($rows); } } public function down(): void { - Schema::dropIfExists('tenant_user'); + Schema::dropIfExists('managed_environment_user'); } }; diff --git a/apps/platform/database/migrations/2026_01_04_135957_create_user_tenant_preferences_table.php b/apps/platform/database/migrations/2026_01_04_135957_create_user_tenant_preferences_table.php index e460b08e..e86dd9be 100644 --- a/apps/platform/database/migrations/2026_01_04_135957_create_user_tenant_preferences_table.php +++ b/apps/platform/database/migrations/2026_01_04_135957_create_user_tenant_preferences_table.php @@ -8,21 +8,21 @@ { public function up(): void { - Schema::create('user_tenant_preferences', function (Blueprint $table) { + Schema::create('user_managed_environment_preferences', function (Blueprint $table) { $table->id(); $table->foreignId('user_id')->constrained()->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->boolean('is_favorite')->default(false); $table->timestamp('last_used_at')->nullable(); $table->timestamps(); - $table->unique(['user_id', 'tenant_id']); + $table->unique(['user_id', 'managed_environment_id']); $table->index(['user_id', 'last_used_at']); }); } public function down(): void { - Schema::dropIfExists('user_tenant_preferences'); + Schema::dropIfExists('user_managed_environment_preferences'); } }; diff --git a/apps/platform/database/migrations/2026_01_05_011014_create_backup_schedules_table.php b/apps/platform/database/migrations/2026_01_05_011014_create_backup_schedules_table.php index 08bdf6ee..03c2f5b5 100644 --- a/apps/platform/database/migrations/2026_01_05_011014_create_backup_schedules_table.php +++ b/apps/platform/database/migrations/2026_01_05_011014_create_backup_schedules_table.php @@ -13,7 +13,7 @@ public function up(): void { Schema::create('backup_schedules', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->string('name'); $table->boolean('is_enabled')->default(true); $table->string('timezone')->default('UTC'); @@ -28,7 +28,7 @@ public function up(): void $table->dateTime('next_run_at')->nullable(); $table->timestamps(); - $table->index(['tenant_id', 'is_enabled']); + $table->index(['managed_environment_id', 'is_enabled']); $table->index('next_run_at'); }); } diff --git a/apps/platform/database/migrations/2026_01_05_011034_create_backup_schedule_runs_table.php b/apps/platform/database/migrations/2026_01_05_011034_create_backup_schedule_runs_table.php index edc10211..a9399fc7 100644 --- a/apps/platform/database/migrations/2026_01_05_011034_create_backup_schedule_runs_table.php +++ b/apps/platform/database/migrations/2026_01_05_011034_create_backup_schedule_runs_table.php @@ -14,7 +14,7 @@ public function up(): void Schema::create('backup_schedule_runs', function (Blueprint $table) { $table->id(); $table->foreignId('backup_schedule_id')->constrained('backup_schedules')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->dateTime('scheduled_for'); $table->dateTime('started_at')->nullable(); $table->dateTime('finished_at')->nullable(); @@ -27,7 +27,7 @@ public function up(): void $table->unique(['backup_schedule_id', 'scheduled_for']); $table->index(['backup_schedule_id', 'scheduled_for']); - $table->index(['tenant_id', 'created_at']); + $table->index(['managed_environment_id', 'created_at']); }); } diff --git a/apps/platform/database/migrations/2026_01_06_211013_add_user_id_to_backup_schedule_runs_table.php b/apps/platform/database/migrations/2026_01_06_211013_add_user_id_to_backup_schedule_runs_table.php index b01bc378..b73ee927 100644 --- a/apps/platform/database/migrations/2026_01_06_211013_add_user_id_to_backup_schedule_runs_table.php +++ b/apps/platform/database/migrations/2026_01_06_211013_add_user_id_to_backup_schedule_runs_table.php @@ -14,7 +14,7 @@ public function up(): void Schema::table('backup_schedule_runs', function (Blueprint $table) { $table->foreignId('user_id') ->nullable() - ->after('tenant_id') + ->after('managed_environment_id') ->constrained() ->nullOnDelete(); diff --git a/apps/platform/database/migrations/2026_01_07_142719_create_inventory_sync_runs_table.php b/apps/platform/database/migrations/2026_01_07_142719_create_inventory_sync_runs_table.php index 9f632718..07d7972e 100644 --- a/apps/platform/database/migrations/2026_01_07_142719_create_inventory_sync_runs_table.php +++ b/apps/platform/database/migrations/2026_01_07_142719_create_inventory_sync_runs_table.php @@ -11,7 +11,7 @@ public function up(): void Schema::create('inventory_sync_runs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained(); + $table->foreignId('managed_environment_id')->constrained(); $table->string('selection_hash', 64); $table->jsonb('selection_payload')->nullable(); @@ -30,9 +30,9 @@ public function up(): void $table->timestamps(); - $table->index(['tenant_id', 'selection_hash']); - $table->index(['tenant_id', 'status']); - $table->index(['tenant_id', 'finished_at']); + $table->index(['managed_environment_id', 'selection_hash']); + $table->index(['managed_environment_id', 'status']); + $table->index(['managed_environment_id', 'finished_at']); }); } diff --git a/apps/platform/database/migrations/2026_01_07_142720_create_inventory_items_table.php b/apps/platform/database/migrations/2026_01_07_142720_create_inventory_items_table.php index 5946a89c..7620d8e1 100644 --- a/apps/platform/database/migrations/2026_01_07_142720_create_inventory_items_table.php +++ b/apps/platform/database/migrations/2026_01_07_142720_create_inventory_items_table.php @@ -10,7 +10,7 @@ public function up(): void { Schema::create('inventory_items', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained(); + $table->foreignId('managed_environment_id')->constrained(); $table->string('policy_type'); $table->string('external_id'); $table->string('display_name')->nullable(); @@ -24,9 +24,9 @@ public function up(): void ->nullOnDelete(); $table->timestamps(); - $table->unique(['tenant_id', 'policy_type', 'external_id']); - $table->index(['tenant_id', 'policy_type']); - $table->index(['tenant_id', 'category']); + $table->unique(['managed_environment_id', 'policy_type', 'external_id']); + $table->index(['managed_environment_id', 'policy_type']); + $table->index(['managed_environment_id', 'category']); $table->index('last_seen_at'); }); } diff --git a/apps/platform/database/migrations/2026_01_07_150000_create_inventory_links_table.php b/apps/platform/database/migrations/2026_01_07_150000_create_inventory_links_table.php index ea1a6d72..282cc830 100644 --- a/apps/platform/database/migrations/2026_01_07_150000_create_inventory_links_table.php +++ b/apps/platform/database/migrations/2026_01_07_150000_create_inventory_links_table.php @@ -10,7 +10,7 @@ public function up(): void { Schema::create('inventory_links', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->string('source_type'); $table->uuid('source_id'); $table->string('target_type'); @@ -20,7 +20,7 @@ public function up(): void $table->timestamps(); $table->unique([ - 'tenant_id', + 'managed_environment_id', 'source_type', 'source_id', 'target_type', @@ -28,8 +28,8 @@ public function up(): void 'relationship_type', ], 'inventory_links_unique'); - $table->index(['tenant_id', 'source_type', 'source_id']); - $table->index(['tenant_id', 'target_type', 'target_id']); + $table->index(['managed_environment_id', 'source_type', 'source_id']); + $table->index(['managed_environment_id', 'target_type', 'target_id']); }); } diff --git a/apps/platform/database/migrations/2026_01_09_010348_add_user_id_to_inventory_sync_runs_table.php b/apps/platform/database/migrations/2026_01_09_010348_add_user_id_to_inventory_sync_runs_table.php index 38e4a69a..e43a9925 100644 --- a/apps/platform/database/migrations/2026_01_09_010348_add_user_id_to_inventory_sync_runs_table.php +++ b/apps/platform/database/migrations/2026_01_09_010348_add_user_id_to_inventory_sync_runs_table.php @@ -16,9 +16,9 @@ public function up(): void ->nullable() ->constrained() ->nullOnDelete() - ->after('tenant_id'); + ->after('managed_environment_id'); - $table->index(['tenant_id', 'user_id']); + $table->index(['managed_environment_id', 'user_id']); }); } @@ -28,7 +28,7 @@ public function up(): void public function down(): void { Schema::table('inventory_sync_runs', function (Blueprint $table) { - $table->dropIndex(['tenant_id', 'user_id']); + $table->dropIndex(['managed_environment_id', 'user_id']); $table->dropConstrainedForeignId('user_id'); }); } diff --git a/apps/platform/database/migrations/2026_01_11_120001_add_idempotency_key_to_bulk_operation_runs_table.php b/apps/platform/database/migrations/2026_01_11_120001_add_idempotency_key_to_bulk_operation_runs_table.php index 9f9926be..1fa2d096 100644 --- a/apps/platform/database/migrations/2026_01_11_120001_add_idempotency_key_to_bulk_operation_runs_table.php +++ b/apps/platform/database/migrations/2026_01_11_120001_add_idempotency_key_to_bulk_operation_runs_table.php @@ -14,10 +14,10 @@ public function up(): void }); Schema::table('bulk_operation_runs', function (Blueprint $table) { - $table->index(['tenant_id', 'idempotency_key'], 'bulk_runs_tenant_idempotency'); + $table->index(['managed_environment_id', 'idempotency_key'], 'bulk_runs_tenant_idempotency'); }); - DB::statement("CREATE UNIQUE INDEX bulk_runs_idempotency_active ON bulk_operation_runs (tenant_id, idempotency_key) WHERE idempotency_key IS NOT NULL AND status IN ('pending', 'running')"); + DB::statement("CREATE UNIQUE INDEX bulk_runs_idempotency_active ON bulk_operation_runs (managed_environment_id, idempotency_key) WHERE idempotency_key IS NOT NULL AND status IN ('pending', 'running')"); } public function down(): void diff --git a/apps/platform/database/migrations/2026_01_11_120002_add_idempotency_key_to_restore_runs_table.php b/apps/platform/database/migrations/2026_01_11_120002_add_idempotency_key_to_restore_runs_table.php index 4c5cbc1a..fb2e9969 100644 --- a/apps/platform/database/migrations/2026_01_11_120002_add_idempotency_key_to_restore_runs_table.php +++ b/apps/platform/database/migrations/2026_01_11_120002_add_idempotency_key_to_restore_runs_table.php @@ -14,10 +14,10 @@ public function up(): void }); Schema::table('restore_runs', function (Blueprint $table) { - $table->index(['tenant_id', 'idempotency_key'], 'restore_runs_tenant_idempotency'); + $table->index(['managed_environment_id', 'idempotency_key'], 'restore_runs_tenant_idempotency'); }); - DB::statement("CREATE UNIQUE INDEX restore_runs_idempotency_active ON restore_runs (tenant_id, idempotency_key) WHERE idempotency_key IS NOT NULL AND status IN ('queued', 'running')"); + DB::statement("CREATE UNIQUE INDEX restore_runs_idempotency_active ON restore_runs (managed_environment_id, idempotency_key) WHERE idempotency_key IS NOT NULL AND status IN ('queued', 'running')"); } public function down(): void diff --git a/apps/platform/database/migrations/2026_01_11_120003_create_entra_groups_table.php b/apps/platform/database/migrations/2026_01_11_120003_create_entra_groups_table.php index 8aa06a7a..2cc4501c 100644 --- a/apps/platform/database/migrations/2026_01_11_120003_create_entra_groups_table.php +++ b/apps/platform/database/migrations/2026_01_11_120003_create_entra_groups_table.php @@ -11,7 +11,7 @@ public function up(): void Schema::create('entra_groups', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->uuid('entra_id'); $table->string('display_name'); @@ -23,9 +23,9 @@ public function up(): void $table->timestamps(); - $table->unique(['tenant_id', 'entra_id']); - $table->index(['tenant_id', 'display_name']); - $table->index(['tenant_id', 'last_seen_at']); + $table->unique(['managed_environment_id', 'entra_id']); + $table->index(['managed_environment_id', 'display_name']); + $table->index(['managed_environment_id', 'last_seen_at']); }); } diff --git a/apps/platform/database/migrations/2026_01_11_120004_create_entra_group_sync_runs_table.php b/apps/platform/database/migrations/2026_01_11_120004_create_entra_group_sync_runs_table.php index 72606ed5..ac2ec6c3 100644 --- a/apps/platform/database/migrations/2026_01_11_120004_create_entra_group_sync_runs_table.php +++ b/apps/platform/database/migrations/2026_01_11_120004_create_entra_group_sync_runs_table.php @@ -11,7 +11,7 @@ public function up(): void Schema::create('entra_group_sync_runs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->string('selection_key'); $table->string('slot_key')->nullable(); @@ -37,10 +37,10 @@ public function up(): void $table->timestamps(); - $table->index(['tenant_id', 'selection_key']); - $table->index(['tenant_id', 'status']); - $table->index(['tenant_id', 'finished_at']); - $table->unique(['tenant_id', 'selection_key', 'slot_key']); + $table->index(['managed_environment_id', 'selection_key']); + $table->index(['managed_environment_id', 'status']); + $table->index(['managed_environment_id', 'finished_at']); + $table->unique(['managed_environment_id', 'selection_key', 'slot_key']); }); } diff --git a/apps/platform/database/migrations/2026_01_13_223311_create_findings_table.php b/apps/platform/database/migrations/2026_01_13_223311_create_findings_table.php index 5307a511..b43a0ea6 100644 --- a/apps/platform/database/migrations/2026_01_13_223311_create_findings_table.php +++ b/apps/platform/database/migrations/2026_01_13_223311_create_findings_table.php @@ -14,7 +14,7 @@ public function up(): void Schema::create('findings', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained(); + $table->foreignId('managed_environment_id')->constrained(); $table->string('finding_type'); $table->string('scope_key'); @@ -37,12 +37,12 @@ public function up(): void $table->timestamps(); - $table->unique(['tenant_id', 'fingerprint']); + $table->unique(['managed_environment_id', 'fingerprint']); - $table->index(['tenant_id', 'status']); - $table->index(['tenant_id', 'scope_key']); - $table->index(['tenant_id', 'baseline_run_id']); - $table->index(['tenant_id', 'current_run_id']); + $table->index(['managed_environment_id', 'status']); + $table->index(['managed_environment_id', 'scope_key']); + $table->index(['managed_environment_id', 'baseline_run_id']); + $table->index(['managed_environment_id', 'current_run_id']); }); } diff --git a/apps/platform/database/migrations/2026_01_16_180642_create_operation_runs_table.php b/apps/platform/database/migrations/2026_01_16_180642_create_operation_runs_table.php index 880db59b..63906130 100644 --- a/apps/platform/database/migrations/2026_01_16_180642_create_operation_runs_table.php +++ b/apps/platform/database/migrations/2026_01_16_180642_create_operation_runs_table.php @@ -14,7 +14,7 @@ public function up(): void { Schema::create('operation_runs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete(); $table->string('initiator_name'); $table->string('type'); @@ -28,12 +28,12 @@ public function up(): void $table->timestamp('completed_at')->nullable(); $table->timestamps(); - $table->index(['tenant_id', 'type', 'created_at']); - $table->index(['tenant_id', 'created_at']); + $table->index(['managed_environment_id', 'type', 'created_at']); + $table->index(['managed_environment_id', 'created_at']); }); // Partial unique index for idempotency - DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique ON operation_runs (tenant_id, run_identity_hash) WHERE status IN ('queued', 'running')"); + DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique ON operation_runs (managed_environment_id, run_identity_hash) WHERE status IN ('queued', 'running')"); } /** diff --git a/apps/platform/database/migrations/2026_01_18_000001_drop_bulk_operation_runs_table.php b/apps/platform/database/migrations/2026_01_18_000001_drop_bulk_operation_runs_table.php index 1fe3e608..efd09d28 100644 --- a/apps/platform/database/migrations/2026_01_18_000001_drop_bulk_operation_runs_table.php +++ b/apps/platform/database/migrations/2026_01_18_000001_drop_bulk_operation_runs_table.php @@ -16,7 +16,7 @@ public function down(): void { Schema::create('bulk_operation_runs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('user_id')->constrained()->cascadeOnDelete(); $table->string('resource', 50); $table->string('action', 50); @@ -34,12 +34,12 @@ public function down(): void }); Schema::table('bulk_operation_runs', function (Blueprint $table) { - $table->index(['tenant_id', 'resource', 'status'], 'bulk_runs_tenant_resource_status'); + $table->index(['managed_environment_id', 'resource', 'status'], 'bulk_runs_tenant_resource_status'); $table->index(['user_id', 'created_at'], 'bulk_runs_user_created'); - $table->index(['tenant_id', 'idempotency_key'], 'bulk_runs_tenant_idempotency'); + $table->index(['managed_environment_id', 'idempotency_key'], 'bulk_runs_tenant_idempotency'); }); DB::statement("CREATE INDEX bulk_runs_status_active ON bulk_operation_runs (status) WHERE status IN ('pending', 'running')"); - DB::statement("CREATE UNIQUE INDEX bulk_runs_idempotency_active ON bulk_operation_runs (tenant_id, idempotency_key) WHERE idempotency_key IS NOT NULL AND status IN ('pending', 'running')"); + DB::statement("CREATE UNIQUE INDEX bulk_runs_idempotency_active ON bulk_operation_runs (managed_environment_id, idempotency_key) WHERE idempotency_key IS NOT NULL AND status IN ('pending', 'running')"); } }; diff --git a/apps/platform/database/migrations/2026_01_24_000001_create_provider_connections_table.php b/apps/platform/database/migrations/2026_01_24_000001_create_provider_connections_table.php index bd715300..dde7932d 100644 --- a/apps/platform/database/migrations/2026_01_24_000001_create_provider_connections_table.php +++ b/apps/platform/database/migrations/2026_01_24_000001_create_provider_connections_table.php @@ -11,7 +11,7 @@ public function up(): void { Schema::create('provider_connections', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->string('provider'); $table->string('entra_tenant_id'); $table->string('display_name'); @@ -25,13 +25,13 @@ public function up(): void $table->jsonb('metadata')->default('{}'); $table->timestamps(); - $table->unique(['tenant_id', 'provider', 'entra_tenant_id']); + $table->unique(['managed_environment_id', 'provider', 'entra_tenant_id']); - $table->index(['tenant_id', 'provider', 'status']); - $table->index(['tenant_id', 'provider', 'health_status']); + $table->index(['managed_environment_id', 'provider', 'status']); + $table->index(['managed_environment_id', 'provider', 'health_status']); }); - DB::statement('CREATE UNIQUE INDEX provider_connections_default_unique ON provider_connections (tenant_id, provider) WHERE is_default = true'); + DB::statement('CREATE UNIQUE INDEX provider_connections_default_unique ON provider_connections (managed_environment_id, provider) WHERE is_default = true'); } public function down(): void diff --git a/apps/platform/database/migrations/2026_01_25_022729_create_tenant_memberships_table.php b/apps/platform/database/migrations/2026_01_25_022729_create_tenant_memberships_table.php index 4d93d9b1..d8a5b74f 100644 --- a/apps/platform/database/migrations/2026_01_25_022729_create_tenant_memberships_table.php +++ b/apps/platform/database/migrations/2026_01_25_022729_create_tenant_memberships_table.php @@ -11,9 +11,9 @@ */ public function up(): void { - Schema::create('tenant_memberships', function (Blueprint $table) { + Schema::create('managed_environment_memberships', function (Blueprint $table) { $table->uuid('id')->primary(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('user_id')->constrained()->cascadeOnDelete(); $table->enum('role', ['owner', 'manager', 'operator', 'readonly']); $table->enum('source', ['manual', 'entra_group', 'entra_app_role', 'break_glass'])->default('manual'); @@ -21,8 +21,8 @@ public function up(): void $table->foreignId('created_by_user_id')->nullable()->constrained('users')->nullOnDelete(); $table->timestamps(); - $table->unique(['tenant_id', 'user_id']); - $table->index(['tenant_id', 'role']); + $table->unique(['managed_environment_id', 'user_id']); + $table->index(['managed_environment_id', 'role']); }); } @@ -31,6 +31,6 @@ public function up(): void */ public function down(): void { - Schema::dropIfExists('tenant_memberships'); + Schema::dropIfExists('managed_environment_memberships'); } }; diff --git a/apps/platform/database/migrations/2026_01_25_022733_create_tenant_role_mappings_table.php b/apps/platform/database/migrations/2026_01_25_022733_create_tenant_role_mappings_table.php index 867db2b2..b5868634 100644 --- a/apps/platform/database/migrations/2026_01_25_022733_create_tenant_role_mappings_table.php +++ b/apps/platform/database/migrations/2026_01_25_022733_create_tenant_role_mappings_table.php @@ -13,14 +13,14 @@ public function up(): void { Schema::create('tenant_role_mappings', function (Blueprint $table) { $table->uuid('id')->primary(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->enum('mapping_type', ['entra_group', 'entra_app_role']); $table->string('external_id'); $table->enum('role', ['owner', 'manager', 'operator', 'readonly']); $table->boolean('is_enabled')->default(true); $table->timestamps(); - $table->unique(['tenant_id', 'mapping_type', 'external_id']); + $table->unique(['managed_environment_id', 'mapping_type', 'external_id']); }); } diff --git a/apps/platform/database/migrations/2026_01_25_023708_backfill_tenant_memberships_from_tenant_user.php b/apps/platform/database/migrations/2026_01_25_023708_backfill_tenant_memberships_from_tenant_user.php index 359aad8e..3827b503 100644 --- a/apps/platform/database/migrations/2026_01_25_023708_backfill_tenant_memberships_from_tenant_user.php +++ b/apps/platform/database/migrations/2026_01_25_023708_backfill_tenant_memberships_from_tenant_user.php @@ -12,25 +12,25 @@ */ public function up(): void { - if (! Schema::hasTable('tenant_user')) { + if (! Schema::hasTable('managed_environment_user')) { return; } - if (! Schema::hasTable('tenant_memberships')) { + if (! Schema::hasTable('managed_environment_memberships')) { return; } - if (DB::table('tenant_memberships')->exists()) { + if (DB::table('managed_environment_memberships')->exists()) { return; } $now = now(); $rows = []; - foreach (DB::table('tenant_user')->select(['tenant_id', 'user_id', 'role'])->cursor() as $pivot) { + foreach (DB::table('managed_environment_user')->select(['managed_environment_id', 'user_id', 'role'])->cursor() as $pivot) { $rows[] = [ 'id' => (string) Str::uuid(), - 'tenant_id' => (int) $pivot->tenant_id, + 'managed_environment_id' => (int) $pivot->managed_environment_id, 'user_id' => (int) $pivot->user_id, 'role' => is_string($pivot->role) && $pivot->role !== '' ? $pivot->role : 'owner', 'source' => 'manual', @@ -41,13 +41,13 @@ public function up(): void ]; if (count($rows) >= 500) { - DB::table('tenant_memberships')->insertOrIgnore($rows); + DB::table('managed_environment_memberships')->insertOrIgnore($rows); $rows = []; } } if ($rows !== []) { - DB::table('tenant_memberships')->insertOrIgnore($rows); + DB::table('managed_environment_memberships')->insertOrIgnore($rows); } } diff --git a/apps/platform/database/migrations/2026_01_31_230304_add_workspace_id_to_tenants_table.php b/apps/platform/database/migrations/2026_01_31_230304_add_workspace_id_to_tenants_table.php index 75d448b5..01248412 100644 --- a/apps/platform/database/migrations/2026_01_31_230304_add_workspace_id_to_tenants_table.php +++ b/apps/platform/database/migrations/2026_01_31_230304_add_workspace_id_to_tenants_table.php @@ -14,24 +14,19 @@ public function up(): void { $driver = DB::getDriverName(); - Schema::table('tenants', function (Blueprint $table) use ($driver): void { - $column = $table->foreignId('workspace_id')->nullable(); - - if ($driver !== 'sqlite') { - $column - ->after('id') - ->constrained('workspaces') - ->nullOnDelete(); - } - - $table->index('workspace_id'); - }); + if (! Schema::hasColumn('managed_environments', 'workspace_id')) { + Schema::table('managed_environments', function (Blueprint $table): void { + $table->foreignId('workspace_id')->nullable()->constrained()->cascadeOnDelete(); + $table->index(['workspace_id', 'lifecycle_status']); + $table->index(['workspace_id', 'kind']); + }); + } if ($driver === 'sqlite') { // SQLite table rebuilds can drop/flatten the partial index defined in // 2025_12_11_192942_add_is_current_to_tenants.php. Recreate it here. DB::statement('DROP INDEX IF EXISTS tenants_current_unique'); - DB::statement('CREATE UNIQUE INDEX tenants_current_unique ON tenants (is_current) WHERE is_current = 1 AND deleted_at IS NULL'); + DB::statement('CREATE UNIQUE INDEX tenants_current_unique ON managed_environments (is_current) WHERE is_current = 1 AND deleted_at IS NULL'); } } @@ -40,8 +35,6 @@ public function up(): void */ public function down(): void { - Schema::table('tenants', function (Blueprint $table) { - $table->dropConstrainedForeignId('workspace_id'); - }); + Schema::hasTable('managed_environments'); } }; diff --git a/apps/platform/database/migrations/2026_02_01_002054_add_workspace_id_to_audit_logs_table.php b/apps/platform/database/migrations/2026_02_01_002054_add_workspace_id_to_audit_logs_table.php index 530422cf..cd87ec4f 100644 --- a/apps/platform/database/migrations/2026_02_01_002054_add_workspace_id_to_audit_logs_table.php +++ b/apps/platform/database/migrations/2026_02_01_002054_add_workspace_id_to_audit_logs_table.php @@ -22,6 +22,8 @@ public function up(): void foreach ([ 'audit_logs_tenant_id_action_index', 'audit_logs_tenant_id_resource_type_index', + 'audit_logs_managed_environment_id_action_index', + 'audit_logs_managed_environment_id_resource_type_index', 'audit_logs_recorded_at_index', ] as $indexName) { DB::statement("DROP INDEX IF EXISTS {$indexName}"); @@ -29,7 +31,7 @@ public function up(): void Schema::create('audit_logs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->nullable()->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->nullable()->constrained()->cascadeOnDelete(); $table->foreignId('workspace_id')->nullable()->constrained()->nullOnDelete(); $table->unsignedBigInteger('actor_id')->nullable(); $table->string('actor_email')->nullable(); @@ -42,8 +44,8 @@ public function up(): void $table->timestamp('recorded_at')->useCurrent(); $table->timestamps(); - $table->index(['tenant_id', 'action']); - $table->index(['tenant_id', 'resource_type']); + $table->index(['managed_environment_id', 'action']); + $table->index(['managed_environment_id', 'resource_type']); $table->index(['workspace_id', 'action']); $table->index(['workspace_id', 'resource_type']); $table->index('recorded_at'); @@ -53,7 +55,7 @@ public function up(): void foreach ($rows as $row) { DB::table('audit_logs')->insert([ 'id' => $row->id, - 'tenant_id' => $row->tenant_id, + 'managed_environment_id' => $row->managed_environment_id, 'workspace_id' => null, 'actor_id' => $row->actor_id, 'actor_email' => $row->actor_email, @@ -76,10 +78,10 @@ public function up(): void return; } - DB::statement('ALTER TABLE audit_logs ALTER COLUMN tenant_id DROP NOT NULL'); + DB::statement('ALTER TABLE audit_logs ALTER COLUMN managed_environment_id DROP NOT NULL'); Schema::table('audit_logs', function (Blueprint $table) { - $table->foreignId('workspace_id')->nullable()->constrained()->nullOnDelete()->after('tenant_id'); + $table->foreignId('workspace_id')->nullable()->constrained()->nullOnDelete()->after('managed_environment_id'); $table->index(['workspace_id', 'action']); $table->index(['workspace_id', 'resource_type']); @@ -101,6 +103,8 @@ public function down(): void foreach ([ 'audit_logs_tenant_id_action_index', 'audit_logs_tenant_id_resource_type_index', + 'audit_logs_managed_environment_id_action_index', + 'audit_logs_managed_environment_id_resource_type_index', 'audit_logs_recorded_at_index', 'audit_logs_workspace_id_action_index', 'audit_logs_workspace_id_resource_type_index', @@ -110,7 +114,7 @@ public function down(): void Schema::create('audit_logs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->unsignedBigInteger('actor_id')->nullable(); $table->string('actor_email')->nullable(); $table->string('actor_name')->nullable(); @@ -122,16 +126,16 @@ public function down(): void $table->timestamp('recorded_at')->useCurrent(); $table->timestamps(); - $table->index(['tenant_id', 'action']); - $table->index(['tenant_id', 'resource_type']); + $table->index(['managed_environment_id', 'action']); + $table->index(['managed_environment_id', 'resource_type']); $table->index('recorded_at'); }); - DB::table('audit_logs_new')->whereNotNull('tenant_id')->orderBy('id')->chunkById(500, function ($rows): void { + DB::table('audit_logs_new')->whereNotNull('managed_environment_id')->orderBy('id')->chunkById(500, function ($rows): void { foreach ($rows as $row) { DB::table('audit_logs')->insert([ 'id' => $row->id, - 'tenant_id' => $row->tenant_id, + 'managed_environment_id' => $row->managed_environment_id, 'actor_id' => $row->actor_id, 'actor_email' => $row->actor_email, 'actor_name' => $row->actor_name, @@ -159,6 +163,6 @@ public function down(): void $table->dropIndex(['workspace_id', 'resource_type']); }); - DB::statement('ALTER TABLE audit_logs ALTER COLUMN tenant_id SET NOT NULL'); + DB::statement('ALTER TABLE audit_logs ALTER COLUMN managed_environment_id SET NOT NULL'); } }; diff --git a/apps/platform/database/migrations/2026_02_01_085446_backfill_default_workspace_and_memberships.php b/apps/platform/database/migrations/2026_02_01_085446_backfill_default_workspace_and_memberships.php index 0b7334ef..64847ca0 100644 --- a/apps/platform/database/migrations/2026_02_01_085446_backfill_default_workspace_and_memberships.php +++ b/apps/platform/database/migrations/2026_02_01_085446_backfill_default_workspace_and_memberships.php @@ -30,8 +30,8 @@ public function up(): void ]); } - if (Schema::hasTable('tenants') && Schema::hasColumn('tenants', 'workspace_id')) { - DB::table('tenants') + if (Schema::hasTable('managed_environments') && Schema::hasColumn('managed_environments', 'workspace_id')) { + DB::table('managed_environments') ->whereNull('workspace_id') ->update([ 'workspace_id' => $defaultWorkspaceId, @@ -52,8 +52,8 @@ public function up(): void $userRoleRanks = collect(); - if (Schema::hasTable('tenant_memberships')) { - $userRoleRanks = DB::table('tenant_memberships') + if (Schema::hasTable('managed_environment_memberships')) { + $userRoleRanks = DB::table('managed_environment_memberships') ->select([ 'user_id', DB::raw("MAX(CASE role WHEN 'owner' THEN 4 WHEN 'manager' THEN 3 WHEN 'operator' THEN 2 WHEN 'readonly' THEN 1 ELSE 0 END) AS role_rank"), diff --git a/apps/platform/database/migrations/2026_02_03_090449_create_tenant_onboarding_sessions_table.php b/apps/platform/database/migrations/2026_02_03_090449_create_tenant_onboarding_sessions_table.php index 4bf5b549..7e9477df 100644 --- a/apps/platform/database/migrations/2026_02_03_090449_create_tenant_onboarding_sessions_table.php +++ b/apps/platform/database/migrations/2026_02_03_090449_create_tenant_onboarding_sessions_table.php @@ -18,7 +18,7 @@ public function up(): void Schema::create('managed_tenant_onboarding_sessions', function (Blueprint $table) { $table->id(); $table->foreignId('workspace_id')->constrained()->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->string('current_step')->nullable(); $table->json('state')->nullable(); @@ -28,8 +28,8 @@ public function up(): void $table->timestamp('completed_at')->nullable(); $table->timestamps(); - $table->unique(['workspace_id', 'tenant_id']); - $table->index(['tenant_id']); + $table->unique(['workspace_id', 'managed_environment_id']); + $table->index(['managed_environment_id']); }); } diff --git a/apps/platform/database/migrations/2026_02_03_090522_enforce_tenant_workspace_binding.php b/apps/platform/database/migrations/2026_02_03_090522_enforce_tenant_workspace_binding.php index 87fc2784..9ea4a611 100644 --- a/apps/platform/database/migrations/2026_02_03_090522_enforce_tenant_workspace_binding.php +++ b/apps/platform/database/migrations/2026_02_03_090522_enforce_tenant_workspace_binding.php @@ -17,28 +17,28 @@ public function up(): void return; } - if (! Schema::hasColumn('tenants', 'workspace_id')) { + if (! Schema::hasColumn('managed_environments', 'workspace_id')) { return; } DB::transaction(function (): void { - $tenantIds = DB::table('tenants')->whereNull('workspace_id')->pluck('id'); + $tenantIds = DB::table('managed_environments')->whereNull('workspace_id')->pluck('id'); foreach ($tenantIds as $tenantId) { - $workspaceId = DB::table('tenant_memberships') - ->join('workspace_memberships', 'workspace_memberships.user_id', '=', 'tenant_memberships.user_id') - ->where('tenant_memberships.tenant_id', $tenantId) - ->orderByRaw("CASE tenant_memberships.role WHEN 'owner' THEN 0 WHEN 'manager' THEN 1 WHEN 'operator' THEN 2 ELSE 3 END") + $workspaceId = DB::table('managed_environment_memberships') + ->join('workspace_memberships', 'workspace_memberships.user_id', '=', 'managed_environment_memberships.user_id') + ->where('managed_environment_memberships.managed_environment_id', $tenantId) + ->orderByRaw("CASE managed_environment_memberships.role WHEN 'owner' THEN 0 WHEN 'manager' THEN 1 WHEN 'operator' THEN 2 ELSE 3 END") ->value('workspace_memberships.workspace_id'); if ($workspaceId !== null) { - DB::table('tenants') + DB::table('managed_environments') ->where('id', $tenantId) ->update(['workspace_id' => (int) $workspaceId]); } } - $remaining = (int) DB::table('tenants')->whereNull('workspace_id')->count(); + $remaining = (int) DB::table('managed_environments')->whereNull('workspace_id')->count(); if ($remaining === 0) { return; @@ -51,14 +51,14 @@ public function up(): void 'updated_at' => now(), ]); - $users = DB::table('tenant_memberships') - ->join('tenants', 'tenants.id', '=', 'tenant_memberships.tenant_id') - ->whereNull('tenants.workspace_id') + $users = DB::table('managed_environment_memberships') + ->join('managed_environments', 'managed_environments.id', '=', 'managed_environment_memberships.managed_environment_id') + ->whereNull('managed_environments.workspace_id') ->select([ - 'tenant_memberships.user_id', - DB::raw("MIN(CASE tenant_memberships.role WHEN 'owner' THEN 0 WHEN 'manager' THEN 1 WHEN 'operator' THEN 2 ELSE 3 END) AS role_rank"), + 'managed_environment_memberships.user_id', + DB::raw("MIN(CASE managed_environment_memberships.role WHEN 'owner' THEN 0 WHEN 'manager' THEN 1 WHEN 'operator' THEN 2 ELSE 3 END) AS role_rank"), ]) - ->groupBy('tenant_memberships.user_id') + ->groupBy('managed_environment_memberships.user_id') ->get(); $roleFromRank = static fn (int $rank): string => match ($rank) { @@ -84,19 +84,19 @@ public function up(): void DB::table('workspace_memberships')->insertOrIgnore($membershipRows); } - DB::table('tenants') + DB::table('managed_environments') ->whereNull('workspace_id') ->update(['workspace_id' => (int) $legacyWorkspaceId]); }); if ($driver === 'pgsql') { - DB::statement('ALTER TABLE tenants ALTER COLUMN workspace_id SET NOT NULL'); + DB::statement('ALTER TABLE managed_environments ALTER COLUMN workspace_id SET NOT NULL'); return; } if ($driver === 'mysql') { - DB::statement('ALTER TABLE tenants MODIFY workspace_id BIGINT UNSIGNED NOT NULL'); + DB::statement('ALTER TABLE managed_environments MODIFY workspace_id BIGINT UNSIGNED NOT NULL'); } } @@ -111,18 +111,18 @@ public function down(): void return; } - if (! Schema::hasColumn('tenants', 'workspace_id')) { + if (! Schema::hasColumn('managed_environments', 'workspace_id')) { return; } if ($driver === 'pgsql') { - DB::statement('ALTER TABLE tenants ALTER COLUMN workspace_id DROP NOT NULL'); + DB::statement('ALTER TABLE managed_environments ALTER COLUMN workspace_id DROP NOT NULL'); return; } if ($driver === 'mysql') { - DB::statement('ALTER TABLE tenants MODIFY workspace_id BIGINT UNSIGNED NULL'); + DB::statement('ALTER TABLE managed_environments MODIFY workspace_id BIGINT UNSIGNED NULL'); } } }; diff --git a/apps/platform/database/migrations/2026_02_03_150001_create_managed_tenant_onboarding_sessions_table.php b/apps/platform/database/migrations/2026_02_03_150001_create_managed_tenant_onboarding_sessions_table.php index c0d70941..d367be73 100644 --- a/apps/platform/database/migrations/2026_02_03_150001_create_managed_tenant_onboarding_sessions_table.php +++ b/apps/platform/database/migrations/2026_02_03_150001_create_managed_tenant_onboarding_sessions_table.php @@ -17,7 +17,7 @@ public function up(): void Schema::create('managed_tenant_onboarding_sessions', function (Blueprint $table) { $table->id(); $table->foreignId('workspace_id')->constrained()->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->string('current_step')->nullable(); $table->json('state')->nullable(); @@ -28,8 +28,8 @@ public function up(): void $table->timestamp('completed_at')->nullable(); $table->timestamps(); - $table->unique(['workspace_id', 'tenant_id']); - $table->index(['tenant_id']); + $table->unique(['workspace_id', 'managed_environment_id']); + $table->index(['managed_environment_id']); }); } diff --git a/apps/platform/database/migrations/2026_02_04_090010_update_tenant_onboarding_sessions_constraints.php b/apps/platform/database/migrations/2026_02_04_090010_update_tenant_onboarding_sessions_constraints.php index 57a70786..88e90fba 100644 --- a/apps/platform/database/migrations/2026_02_04_090010_update_tenant_onboarding_sessions_constraints.php +++ b/apps/platform/database/migrations/2026_02_04_090010_update_tenant_onboarding_sessions_constraints.php @@ -23,6 +23,8 @@ public function up(): void foreach ([ 'managed_tenant_onboarding_sessions_workspace_id_tenant_id_unique', 'managed_tenant_onboarding_sessions_tenant_id_index', + 'managed_tenant_onboarding_sessions_workspace_id_managed_environment_id_unique', + 'managed_tenant_onboarding_sessions_managed_environment_id_index', ] as $indexName) { DB::statement("DROP INDEX IF EXISTS {$indexName}"); } @@ -30,7 +32,7 @@ public function up(): void Schema::create('managed_tenant_onboarding_sessions', function (Blueprint $table) { $table->id(); $table->foreignId('workspace_id')->constrained()->cascadeOnDelete(); - $table->foreignId('tenant_id')->nullable()->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->nullable()->constrained()->cascadeOnDelete(); $table->string('entra_tenant_id'); $table->string('current_step')->nullable(); $table->json('state')->nullable(); @@ -39,7 +41,7 @@ public function up(): void $table->timestamp('completed_at')->nullable(); $table->timestamps(); - $table->index('tenant_id'); + $table->index('managed_environment_id'); $table->index('entra_tenant_id'); }); @@ -53,13 +55,13 @@ public function up(): void $entraTenantId = $row->entra_tenant_id ?? null; if (! is_string($entraTenantId) || trim($entraTenantId) === '') { - $entraTenantId = $state['entra_tenant_id'] ?? $state['tenant_id'] ?? null; + $entraTenantId = $state['entra_tenant_id'] ?? $state['managed_environment_id'] ?? null; } if (! is_string($entraTenantId) || trim($entraTenantId) === '') { - $entraTenantId = DB::table('tenants') - ->where('id', $row->tenant_id) - ->value('tenant_id'); + $entraTenantId = DB::table('managed_environments') + ->where('id', $row->managed_environment_id) + ->value('slug'); } $entraTenantId = is_string($entraTenantId) ? trim($entraTenantId) : ''; @@ -71,7 +73,7 @@ public function up(): void DB::table('managed_tenant_onboarding_sessions')->insert([ 'id' => $row->id, 'workspace_id' => $row->workspace_id, - 'tenant_id' => $row->tenant_id, + 'managed_environment_id' => $row->managed_environment_id, 'entra_tenant_id' => $entraTenantId, 'current_step' => $row->current_step, 'state' => $row->state, @@ -87,7 +89,7 @@ public function up(): void Schema::drop('managed_tenant_onboarding_sessions_old'); DB::statement('CREATE UNIQUE INDEX managed_tenant_onboarding_sessions_active_workspace_entra_unique ON managed_tenant_onboarding_sessions (workspace_id, entra_tenant_id) WHERE completed_at IS NULL'); - DB::statement('CREATE UNIQUE INDEX managed_tenant_onboarding_sessions_active_tenant_unique ON managed_tenant_onboarding_sessions (tenant_id) WHERE completed_at IS NULL AND tenant_id IS NOT NULL'); + DB::statement('CREATE UNIQUE INDEX managed_tenant_onboarding_sessions_active_tenant_unique ON managed_tenant_onboarding_sessions (managed_environment_id) WHERE completed_at IS NULL AND managed_environment_id IS NOT NULL'); Schema::enableForeignKeyConstraints(); @@ -96,24 +98,24 @@ public function up(): void if (! Schema::hasColumn('managed_tenant_onboarding_sessions', 'entra_tenant_id')) { Schema::table('managed_tenant_onboarding_sessions', function (Blueprint $table) { - $table->string('entra_tenant_id')->nullable()->after('tenant_id'); + $table->string('entra_tenant_id')->nullable()->after('managed_environment_id'); }); } $this->backfillEntraTenantId($driver); if ($driver === 'pgsql') { - DB::statement('ALTER TABLE managed_tenant_onboarding_sessions ALTER COLUMN tenant_id DROP NOT NULL'); + DB::statement('ALTER TABLE managed_tenant_onboarding_sessions ALTER COLUMN managed_environment_id DROP NOT NULL'); DB::statement('ALTER TABLE managed_tenant_onboarding_sessions ALTER COLUMN entra_tenant_id SET NOT NULL'); } Schema::table('managed_tenant_onboarding_sessions', function (Blueprint $table) { - $table->dropUnique(['workspace_id', 'tenant_id']); + $table->dropUnique(['workspace_id', 'managed_environment_id']); $table->index('entra_tenant_id'); }); DB::statement('CREATE UNIQUE INDEX IF NOT EXISTS managed_tenant_onboarding_sessions_active_workspace_entra_unique ON managed_tenant_onboarding_sessions (workspace_id, entra_tenant_id) WHERE completed_at IS NULL'); - DB::statement('CREATE UNIQUE INDEX IF NOT EXISTS managed_tenant_onboarding_sessions_active_tenant_unique ON managed_tenant_onboarding_sessions (tenant_id) WHERE completed_at IS NULL AND tenant_id IS NOT NULL'); + DB::statement('CREATE UNIQUE INDEX IF NOT EXISTS managed_tenant_onboarding_sessions_active_tenant_unique ON managed_tenant_onboarding_sessions (managed_environment_id) WHERE completed_at IS NULL AND managed_environment_id IS NOT NULL'); } public function down(): void @@ -133,6 +135,7 @@ public function down(): void 'managed_tenant_onboarding_sessions_active_workspace_entra_unique', 'managed_tenant_onboarding_sessions_active_tenant_unique', 'managed_tenant_onboarding_sessions_tenant_id_index', + 'managed_tenant_onboarding_sessions_managed_environment_id_index', 'managed_tenant_onboarding_sessions_entra_tenant_id_index', ] as $indexName) { DB::statement("DROP INDEX IF EXISTS {$indexName}"); @@ -141,7 +144,7 @@ public function down(): void Schema::create('managed_tenant_onboarding_sessions', function (Blueprint $table) { $table->id(); $table->foreignId('workspace_id')->constrained()->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->string('current_step')->nullable(); $table->json('state')->nullable(); $table->foreignId('started_by_user_id')->nullable()->constrained('users')->nullOnDelete(); @@ -149,19 +152,19 @@ public function down(): void $table->timestamp('completed_at')->nullable(); $table->timestamps(); - $table->unique(['workspace_id', 'tenant_id']); - $table->index(['tenant_id']); + $table->unique(['workspace_id', 'managed_environment_id']); + $table->index(['managed_environment_id']); }); DB::table('managed_tenant_onboarding_sessions_new') - ->whereNotNull('tenant_id') + ->whereNotNull('managed_environment_id') ->orderBy('id') ->chunkById(500, function ($rows): void { foreach ($rows as $row) { DB::table('managed_tenant_onboarding_sessions')->insert([ 'id' => $row->id, 'workspace_id' => $row->workspace_id, - 'tenant_id' => $row->tenant_id, + 'managed_environment_id' => $row->managed_environment_id, 'current_step' => $row->current_step, 'state' => $row->state, 'started_by_user_id' => $row->started_by_user_id, @@ -190,7 +193,7 @@ public function down(): void Schema::table('managed_tenant_onboarding_sessions', function (Blueprint $table) { $table->dropIndex(['entra_tenant_id']); $table->dropColumn('entra_tenant_id'); - $table->unique(['workspace_id', 'tenant_id']); + $table->unique(['workspace_id', 'managed_environment_id']); }); } } @@ -200,15 +203,15 @@ private function backfillEntraTenantId(string $driver): void if ($driver === 'pgsql') { DB::statement(<<<'SQL' UPDATE managed_tenant_onboarding_sessions - SET entra_tenant_id = COALESCE(managed_tenant_onboarding_sessions.entra_tenant_id, tenants.tenant_id, managed_tenant_onboarding_sessions.state->>'tenant_id') - FROM tenants + SET entra_tenant_id = COALESCE(managed_tenant_onboarding_sessions.entra_tenant_id, managed_tenant_onboarding_sessions.state->>'entra_tenant_id', managed_tenant_onboarding_sessions.state->>'managed_environment_id', managed_environments.slug) + FROM managed_environments WHERE managed_tenant_onboarding_sessions.entra_tenant_id IS NULL - AND managed_tenant_onboarding_sessions.tenant_id = tenants.id + AND managed_tenant_onboarding_sessions.managed_environment_id = managed_environments.id SQL); DB::statement(<<<'SQL' UPDATE managed_tenant_onboarding_sessions - SET entra_tenant_id = state->>'tenant_id' + SET entra_tenant_id = state->>'managed_environment_id' WHERE entra_tenant_id IS NULL SQL); @@ -223,13 +226,13 @@ private function backfillEntraTenantId(string $driver): void $state = is_string($row->state) ? json_decode($row->state, true) : null; $state = is_array($state) ? $state : []; - $entraTenantId = $state['entra_tenant_id'] ?? $state['tenant_id'] ?? null; + $entraTenantId = $state['entra_tenant_id'] ?? $state['managed_environment_id'] ?? null; - if (! is_string($entraTenantId) || trim($entraTenantId) === '') { - $entraTenantId = DB::table('tenants') - ->where('id', $row->tenant_id) - ->value('tenant_id'); - } + if (! is_string($entraTenantId) || trim($entraTenantId) === '') { + $entraTenantId = DB::table('managed_environments') + ->where('id', $row->managed_environment_id) + ->value('slug'); + } $entraTenantId = is_string($entraTenantId) ? trim($entraTenantId) : ''; diff --git a/apps/platform/database/migrations/2026_02_04_090020_make_provider_connections_workspace_owned.php b/apps/platform/database/migrations/2026_02_04_090020_make_provider_connections_workspace_owned.php index aae81e4c..d2bd4d2c 100644 --- a/apps/platform/database/migrations/2026_02_04_090020_make_provider_connections_workspace_owned.php +++ b/apps/platform/database/migrations/2026_02_04_090020_make_provider_connections_workspace_owned.php @@ -25,9 +25,9 @@ public function up(): void DB::statement(<<<'SQL' UPDATE provider_connections SET workspace_id = ( - SELECT tenants.workspace_id - FROM tenants - WHERE tenants.id = provider_connections.tenant_id + SELECT managed_environments.workspace_id + FROM managed_environments + WHERE managed_environments.id = provider_connections.managed_environment_id ) WHERE workspace_id IS NULL SQL); @@ -97,10 +97,10 @@ private function backfillWorkspaceId(string $driver): void if ($driver === 'pgsql') { DB::statement(<<<'SQL' UPDATE provider_connections - SET workspace_id = tenants.workspace_id - FROM tenants + SET workspace_id = managed_environments.workspace_id + FROM managed_environments WHERE provider_connections.workspace_id IS NULL - AND provider_connections.tenant_id = tenants.id + AND provider_connections.managed_environment_id = managed_environments.id SQL); return; @@ -111,15 +111,15 @@ private function backfillWorkspaceId(string $driver): void ->orderBy('id') ->chunkById(500, function ($rows): void { foreach ($rows as $row) { - $workspaceId = DB::table('tenants') - ->where('id', $row->tenant_id) + $workspaceId = DB::table('managed_environments') + ->where('id', $row->managed_environment_id) ->value('workspace_id'); if ($workspaceId === null) { - $workspaceId = DB::table('tenant_memberships') - ->join('workspace_memberships', 'workspace_memberships.user_id', '=', 'tenant_memberships.user_id') - ->where('tenant_memberships.tenant_id', (int) $row->tenant_id) - ->orderByRaw("CASE tenant_memberships.role WHEN 'owner' THEN 0 WHEN 'manager' THEN 1 WHEN 'operator' THEN 2 ELSE 3 END") + $workspaceId = DB::table('managed_environment_memberships') + ->join('workspace_memberships', 'workspace_memberships.user_id', '=', 'managed_environment_memberships.user_id') + ->where('managed_environment_memberships.managed_environment_id', (int) $row->managed_environment_id) + ->orderByRaw("CASE managed_environment_memberships.role WHEN 'owner' THEN 0 WHEN 'manager' THEN 1 WHEN 'operator' THEN 2 ELSE 3 END") ->value('workspace_memberships.workspace_id'); } diff --git a/apps/platform/database/migrations/2026_02_04_090030_add_workspace_id_to_operation_runs_table.php b/apps/platform/database/migrations/2026_02_04_090030_add_workspace_id_to_operation_runs_table.php index 47909a6c..c7c406e0 100644 --- a/apps/platform/database/migrations/2026_02_04_090030_add_workspace_id_to_operation_runs_table.php +++ b/apps/platform/database/migrations/2026_02_04_090030_add_workspace_id_to_operation_runs_table.php @@ -22,6 +22,8 @@ public function up(): void foreach ([ 'operation_runs_active_unique', + 'operation_runs_managed_environment_id_type_created_at_index', + 'operation_runs_managed_environment_id_created_at_index', 'operation_runs_tenant_id_type_created_at_index', 'operation_runs_tenant_id_created_at_index', ] as $indexName) { @@ -31,7 +33,7 @@ public function up(): void Schema::create('operation_runs', function (Blueprint $table) { $table->id(); $table->foreignId('workspace_id')->constrained()->cascadeOnDelete(); - $table->foreignId('tenant_id')->nullable()->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->nullable()->constrained()->cascadeOnDelete(); $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete(); $table->string('initiator_name'); $table->string('type'); @@ -47,22 +49,22 @@ public function up(): void $table->index(['workspace_id', 'type', 'created_at']); $table->index(['workspace_id', 'created_at']); - $table->index(['tenant_id', 'type', 'created_at']); - $table->index(['tenant_id', 'created_at']); + $table->index(['managed_environment_id', 'type', 'created_at']); + $table->index(['managed_environment_id', 'created_at']); }); DB::table('operation_runs_old') ->orderBy('id') ->chunkById(500, function ($rows): void { foreach ($rows as $row) { - $workspaceId = DB::table('tenants') - ->where('id', (int) $row->tenant_id) + $workspaceId = DB::table('managed_environments') + ->where('id', (int) $row->managed_environment_id) ->value('workspace_id'); DB::table('operation_runs')->insert([ 'id' => (int) $row->id, 'workspace_id' => (int) $workspaceId, - 'tenant_id' => $row->tenant_id, + 'managed_environment_id' => $row->managed_environment_id, 'user_id' => $row->user_id, 'initiator_name' => $row->initiator_name, 'type' => $row->type, @@ -82,8 +84,8 @@ public function up(): void Schema::drop('operation_runs_old'); - DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique_tenant ON operation_runs (tenant_id, run_identity_hash) WHERE tenant_id IS NOT NULL AND status IN ('queued', 'running')"); - DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique_workspace ON operation_runs (workspace_id, run_identity_hash) WHERE tenant_id IS NULL AND status IN ('queued', 'running')"); + DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique_tenant ON operation_runs (managed_environment_id, run_identity_hash) WHERE managed_environment_id IS NOT NULL AND status IN ('queued', 'running')"); + DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique_workspace ON operation_runs (workspace_id, run_identity_hash) WHERE managed_environment_id IS NULL AND status IN ('queued', 'running')"); Schema::enableForeignKeyConstraints(); @@ -106,19 +108,19 @@ public function up(): void $this->backfillWorkspaceId($driver); if ($driver === 'pgsql') { - DB::statement('ALTER TABLE operation_runs ALTER COLUMN tenant_id DROP NOT NULL'); + DB::statement('ALTER TABLE operation_runs ALTER COLUMN managed_environment_id DROP NOT NULL'); DB::statement('ALTER TABLE operation_runs ALTER COLUMN workspace_id SET NOT NULL'); } if ($driver === 'mysql') { - DB::statement('ALTER TABLE operation_runs MODIFY tenant_id BIGINT UNSIGNED NULL'); + DB::statement('ALTER TABLE operation_runs MODIFY managed_environment_id BIGINT UNSIGNED NULL'); DB::statement('ALTER TABLE operation_runs MODIFY workspace_id BIGINT UNSIGNED NOT NULL'); } DB::statement('DROP INDEX IF EXISTS operation_runs_active_unique'); - DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique_tenant ON operation_runs (tenant_id, run_identity_hash) WHERE tenant_id IS NOT NULL AND status IN ('queued', 'running')"); - DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique_workspace ON operation_runs (workspace_id, run_identity_hash) WHERE tenant_id IS NULL AND status IN ('queued', 'running')"); + DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique_tenant ON operation_runs (managed_environment_id, run_identity_hash) WHERE managed_environment_id IS NOT NULL AND status IN ('queued', 'running')"); + DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique_workspace ON operation_runs (workspace_id, run_identity_hash) WHERE managed_environment_id IS NULL AND status IN ('queued', 'running')"); } public function down(): void @@ -139,6 +141,8 @@ public function down(): void 'operation_runs_active_unique_workspace', 'operation_runs_workspace_id_type_created_at_index', 'operation_runs_workspace_id_created_at_index', + 'operation_runs_managed_environment_id_type_created_at_index', + 'operation_runs_managed_environment_id_created_at_index', 'operation_runs_tenant_id_type_created_at_index', 'operation_runs_tenant_id_created_at_index', ] as $indexName) { @@ -147,7 +151,7 @@ public function down(): void Schema::create('operation_runs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete(); $table->string('initiator_name'); $table->string('type'); @@ -161,18 +165,18 @@ public function down(): void $table->timestamp('completed_at')->nullable(); $table->timestamps(); - $table->index(['tenant_id', 'type', 'created_at']); - $table->index(['tenant_id', 'created_at']); + $table->index(['managed_environment_id', 'type', 'created_at']); + $table->index(['managed_environment_id', 'created_at']); }); DB::table('operation_runs_with_workspace') - ->whereNotNull('tenant_id') + ->whereNotNull('managed_environment_id') ->orderBy('id') ->chunkById(500, function ($rows): void { foreach ($rows as $row) { DB::table('operation_runs')->insert([ 'id' => (int) $row->id, - 'tenant_id' => (int) $row->tenant_id, + 'managed_environment_id' => (int) $row->managed_environment_id, 'user_id' => $row->user_id, 'initiator_name' => $row->initiator_name, 'type' => $row->type, @@ -192,7 +196,7 @@ public function down(): void Schema::drop('operation_runs_with_workspace'); - DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique ON operation_runs (tenant_id, run_identity_hash) WHERE status IN ('queued', 'running')"); + DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique ON operation_runs (managed_environment_id, run_identity_hash) WHERE status IN ('queued', 'running')"); Schema::enableForeignKeyConstraints(); @@ -203,15 +207,15 @@ public function down(): void DB::statement('DROP INDEX IF EXISTS operation_runs_active_unique_workspace'); DB::statement('DROP INDEX IF EXISTS operation_runs_active_unique'); - DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique ON operation_runs (tenant_id, run_identity_hash) WHERE status IN ('queued', 'running')"); + DB::statement("CREATE UNIQUE INDEX operation_runs_active_unique ON operation_runs (managed_environment_id, run_identity_hash) WHERE status IN ('queued', 'running')"); if ($driver === 'pgsql') { - DB::statement('ALTER TABLE operation_runs ALTER COLUMN tenant_id SET NOT NULL'); + DB::statement('ALTER TABLE operation_runs ALTER COLUMN managed_environment_id SET NOT NULL'); DB::statement('ALTER TABLE operation_runs ALTER COLUMN workspace_id DROP NOT NULL'); } if ($driver === 'mysql') { - DB::statement('ALTER TABLE operation_runs MODIFY tenant_id BIGINT UNSIGNED NOT NULL'); + DB::statement('ALTER TABLE operation_runs MODIFY managed_environment_id BIGINT UNSIGNED NOT NULL'); DB::statement('ALTER TABLE operation_runs MODIFY workspace_id BIGINT UNSIGNED NULL'); } @@ -227,10 +231,10 @@ private function backfillWorkspaceId(string $driver): void if ($driver === 'pgsql') { DB::statement(<<<'SQL' UPDATE operation_runs - SET workspace_id = tenants.workspace_id - FROM tenants + SET workspace_id = managed_environments.workspace_id + FROM managed_environments WHERE operation_runs.workspace_id IS NULL - AND operation_runs.tenant_id = tenants.id + AND operation_runs.managed_environment_id = managed_environments.id SQL); return; @@ -239,8 +243,8 @@ private function backfillWorkspaceId(string $driver): void if ($driver === 'mysql') { DB::statement(<<<'SQL' UPDATE operation_runs - JOIN tenants ON tenants.id = operation_runs.tenant_id - SET operation_runs.workspace_id = tenants.workspace_id + JOIN managed_environments ON managed_environments.id = operation_runs.managed_environment_id + SET operation_runs.workspace_id = managed_environments.workspace_id WHERE operation_runs.workspace_id IS NULL SQL); @@ -252,8 +256,8 @@ private function backfillWorkspaceId(string $driver): void ->orderBy('id') ->chunkById(500, function ($rows): void { foreach ($rows as $row) { - $workspaceId = DB::table('tenants') - ->where('id', (int) $row->tenant_id) + $workspaceId = DB::table('managed_environments') + ->where('id', (int) $row->managed_environment_id) ->value('workspace_id'); if ($workspaceId !== null) { diff --git a/apps/platform/database/migrations/2026_02_05_000001_create_verification_check_acknowledgements_table.php b/apps/platform/database/migrations/2026_02_05_000001_create_verification_check_acknowledgements_table.php index a6488041..09bc7fc4 100644 --- a/apps/platform/database/migrations/2026_02_05_000001_create_verification_check_acknowledgements_table.php +++ b/apps/platform/database/migrations/2026_02_05_000001_create_verification_check_acknowledgements_table.php @@ -10,7 +10,7 @@ public function up(): void { Schema::create('verification_check_acknowledgements', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('workspace_id')->constrained()->cascadeOnDelete(); $table->foreignId('operation_run_id')->constrained('operation_runs')->cascadeOnDelete(); @@ -24,7 +24,7 @@ public function up(): void $table->unique(['operation_run_id', 'check_key']); - $table->index(['tenant_id', 'workspace_id', 'operation_run_id']); + $table->index(['managed_environment_id', 'workspace_id', 'operation_run_id']); $table->index(['operation_run_id']); }); } diff --git a/apps/platform/database/migrations/2026_02_10_004939_add_unique_index_for_backup_schedule_scheduled_operation_runs.php b/apps/platform/database/migrations/2026_02_10_004939_add_unique_index_for_backup_schedule_scheduled_operation_runs.php index 6d41cd82..b77bda88 100644 --- a/apps/platform/database/migrations/2026_02_10_004939_add_unique_index_for_backup_schedule_scheduled_operation_runs.php +++ b/apps/platform/database/migrations/2026_02_10_004939_add_unique_index_for_backup_schedule_scheduled_operation_runs.php @@ -23,7 +23,7 @@ public function up(): void DB::statement(<<<'SQL' CREATE UNIQUE INDEX IF NOT EXISTS operation_runs_backup_schedule_scheduled_unique - ON operation_runs (tenant_id, run_identity_hash) + ON operation_runs (managed_environment_id, run_identity_hash) WHERE type = 'backup_schedule_run' SQL); } diff --git a/apps/platform/database/migrations/2026_02_10_133238_create_entra_role_definitions_table.php b/apps/platform/database/migrations/2026_02_10_133238_create_entra_role_definitions_table.php index 7b87e2fd..b36da7b8 100644 --- a/apps/platform/database/migrations/2026_02_10_133238_create_entra_role_definitions_table.php +++ b/apps/platform/database/migrations/2026_02_10_133238_create_entra_role_definitions_table.php @@ -11,7 +11,7 @@ public function up(): void Schema::create('entra_role_definitions', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->uuid('entra_id'); $table->string('display_name'); @@ -21,9 +21,9 @@ public function up(): void $table->timestamps(); - $table->unique(['tenant_id', 'entra_id']); - $table->index(['tenant_id', 'display_name']); - $table->index(['tenant_id', 'last_seen_at']); + $table->unique(['managed_environment_id', 'entra_id']); + $table->index(['managed_environment_id', 'display_name']); + $table->index(['managed_environment_id', 'last_seen_at']); }); } diff --git a/apps/platform/database/migrations/2026_02_12_000002_add_operation_run_ids_to_findings_table.php b/apps/platform/database/migrations/2026_02_12_000002_add_operation_run_ids_to_findings_table.php index e285793a..d5df33eb 100644 --- a/apps/platform/database/migrations/2026_02_12_000002_add_operation_run_ids_to_findings_table.php +++ b/apps/platform/database/migrations/2026_02_12_000002_add_operation_run_ids_to_findings_table.php @@ -19,7 +19,7 @@ public function up(): void ->after('baseline_run_id') ->constrained('operation_runs') ->nullOnDelete(); - $table->index(['tenant_id', 'baseline_operation_run_id'], 'findings_tenant_baseline_operation_run_idx'); + $table->index(['managed_environment_id', 'baseline_operation_run_id'], 'findings_tenant_baseline_operation_run_idx'); } if (! Schema::hasColumn('findings', 'current_operation_run_id')) { @@ -28,7 +28,7 @@ public function up(): void ->after('current_run_id') ->constrained('operation_runs') ->nullOnDelete(); - $table->index(['tenant_id', 'current_operation_run_id'], 'findings_tenant_current_operation_run_idx'); + $table->index(['managed_environment_id', 'current_operation_run_id'], 'findings_tenant_current_operation_run_idx'); } }); } diff --git a/apps/platform/database/migrations/2026_02_12_000005_drop_legacy_run_id_columns_from_findings_and_inventory_items.php b/apps/platform/database/migrations/2026_02_12_000005_drop_legacy_run_id_columns_from_findings_and_inventory_items.php index 1381ce62..6ffa8bce 100644 --- a/apps/platform/database/migrations/2026_02_12_000005_drop_legacy_run_id_columns_from_findings_and_inventory_items.php +++ b/apps/platform/database/migrations/2026_02_12_000005_drop_legacy_run_id_columns_from_findings_and_inventory_items.php @@ -10,6 +10,8 @@ public function up(): void { if (Schema::hasTable('findings')) { + DB::statement('DROP INDEX IF EXISTS findings_managed_environment_id_baseline_run_id_index'); + DB::statement('DROP INDEX IF EXISTS findings_managed_environment_id_current_run_id_index'); DB::statement('DROP INDEX IF EXISTS findings_tenant_id_baseline_run_id_index'); DB::statement('DROP INDEX IF EXISTS findings_tenant_id_current_run_id_index'); @@ -46,7 +48,7 @@ public function down(): void ->nullable() ->after('scope_key') ->constrained('inventory_sync_runs'); - $table->index(['tenant_id', 'baseline_run_id']); + $table->index(['managed_environment_id', 'baseline_run_id']); } if (! Schema::hasColumn('findings', 'current_run_id')) { @@ -54,7 +56,7 @@ public function down(): void ->nullable() ->after('baseline_run_id') ->constrained('inventory_sync_runs'); - $table->index(['tenant_id', 'current_run_id']); + $table->index(['managed_environment_id', 'current_run_id']); } }); } diff --git a/apps/platform/database/migrations/2026_02_12_000006_drop_legacy_run_tables.php b/apps/platform/database/migrations/2026_02_12_000006_drop_legacy_run_tables.php index 6dad093e..37de67b2 100644 --- a/apps/platform/database/migrations/2026_02_12_000006_drop_legacy_run_tables.php +++ b/apps/platform/database/migrations/2026_02_12_000006_drop_legacy_run_tables.php @@ -18,7 +18,7 @@ public function down(): void if (! Schema::hasTable('inventory_sync_runs')) { Schema::create('inventory_sync_runs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained(); + $table->foreignId('managed_environment_id')->constrained(); $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete(); $table->string('selection_hash', 64); $table->jsonb('selection_payload')->nullable(); @@ -34,10 +34,10 @@ public function down(): void $table->foreignId('operation_run_id')->nullable()->constrained('operation_runs')->nullOnDelete(); $table->timestamps(); - $table->index(['tenant_id', 'selection_hash']); - $table->index(['tenant_id', 'status']); - $table->index(['tenant_id', 'finished_at']); - $table->index(['tenant_id', 'user_id']); + $table->index(['managed_environment_id', 'selection_hash']); + $table->index(['managed_environment_id', 'status']); + $table->index(['managed_environment_id', 'finished_at']); + $table->index(['managed_environment_id', 'user_id']); $table->index('operation_run_id'); }); } @@ -45,7 +45,7 @@ public function down(): void if (! Schema::hasTable('entra_group_sync_runs')) { Schema::create('entra_group_sync_runs', function (Blueprint $table) { $table->id(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->string('selection_key'); $table->string('slot_key')->nullable(); $table->string('status'); @@ -64,11 +64,11 @@ public function down(): void $table->foreignId('operation_run_id')->nullable()->constrained('operation_runs')->nullOnDelete(); $table->timestamps(); - $table->index(['tenant_id', 'selection_key']); - $table->index(['tenant_id', 'status']); - $table->index(['tenant_id', 'finished_at']); + $table->index(['managed_environment_id', 'selection_key']); + $table->index(['managed_environment_id', 'status']); + $table->index(['managed_environment_id', 'finished_at']); $table->index('operation_run_id'); - $table->unique(['tenant_id', 'selection_key', 'slot_key']); + $table->unique(['managed_environment_id', 'selection_key', 'slot_key']); }); } @@ -76,7 +76,7 @@ public function down(): void Schema::create('backup_schedule_runs', function (Blueprint $table) { $table->id(); $table->foreignId('backup_schedule_id')->constrained('backup_schedules')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete(); $table->dateTime('scheduled_for'); $table->dateTime('started_at')->nullable(); @@ -91,7 +91,7 @@ public function down(): void $table->unique(['backup_schedule_id', 'scheduled_for']); $table->index(['backup_schedule_id', 'scheduled_for']); - $table->index(['tenant_id', 'created_at']); + $table->index(['managed_environment_id', 'created_at']); $table->index(['user_id', 'created_at'], 'backup_schedule_runs_user_created'); $table->index('operation_run_id'); }); diff --git a/apps/platform/database/migrations/2026_02_13_120000_add_deleted_at_to_backup_schedules_table.php b/apps/platform/database/migrations/2026_02_13_120000_add_deleted_at_to_backup_schedules_table.php index 91ed58a7..c7feeade 100644 --- a/apps/platform/database/migrations/2026_02_13_120000_add_deleted_at_to_backup_schedules_table.php +++ b/apps/platform/database/migrations/2026_02_13_120000_add_deleted_at_to_backup_schedules_table.php @@ -13,7 +13,7 @@ public function up(): void { Schema::table('backup_schedules', function (Blueprint $table) { $table->softDeletes(); - $table->index(['tenant_id', 'deleted_at'], 'backup_schedules_tenant_deleted_at_idx'); + $table->index(['managed_environment_id', 'deleted_at'], 'backup_schedules_tenant_deleted_at_idx'); }); } diff --git a/apps/platform/database/migrations/2026_02_14_220101_add_workspace_id_to_policies_table.php b/apps/platform/database/migrations/2026_02_14_220101_add_workspace_id_to_policies_table.php index c11cc3d8..23403cf6 100644 --- a/apps/platform/database/migrations/2026_02_14_220101_add_workspace_id_to_policies_table.php +++ b/apps/platform/database/migrations/2026_02_14_220101_add_workspace_id_to_policies_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('policies', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('policies', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220102_add_workspace_id_to_policy_versions_table.php b/apps/platform/database/migrations/2026_02_14_220102_add_workspace_id_to_policy_versions_table.php index 805b325b..c1052e3e 100644 --- a/apps/platform/database/migrations/2026_02_14_220102_add_workspace_id_to_policy_versions_table.php +++ b/apps/platform/database/migrations/2026_02_14_220102_add_workspace_id_to_policy_versions_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('policy_versions', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('policy_versions', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220103_add_workspace_id_to_backup_sets_table.php b/apps/platform/database/migrations/2026_02_14_220103_add_workspace_id_to_backup_sets_table.php index 3b75110d..b0075ffe 100644 --- a/apps/platform/database/migrations/2026_02_14_220103_add_workspace_id_to_backup_sets_table.php +++ b/apps/platform/database/migrations/2026_02_14_220103_add_workspace_id_to_backup_sets_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('backup_sets', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('backup_sets', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220104_add_workspace_id_to_backup_items_table.php b/apps/platform/database/migrations/2026_02_14_220104_add_workspace_id_to_backup_items_table.php index d9b496f4..12afac0c 100644 --- a/apps/platform/database/migrations/2026_02_14_220104_add_workspace_id_to_backup_items_table.php +++ b/apps/platform/database/migrations/2026_02_14_220104_add_workspace_id_to_backup_items_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('backup_items', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('backup_items', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220105_add_workspace_id_to_restore_runs_table.php b/apps/platform/database/migrations/2026_02_14_220105_add_workspace_id_to_restore_runs_table.php index 611e9d5a..0a680bdd 100644 --- a/apps/platform/database/migrations/2026_02_14_220105_add_workspace_id_to_restore_runs_table.php +++ b/apps/platform/database/migrations/2026_02_14_220105_add_workspace_id_to_restore_runs_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('restore_runs', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('restore_runs', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220106_add_workspace_id_to_backup_schedules_table.php b/apps/platform/database/migrations/2026_02_14_220106_add_workspace_id_to_backup_schedules_table.php index d264f5fe..5de8f38e 100644 --- a/apps/platform/database/migrations/2026_02_14_220106_add_workspace_id_to_backup_schedules_table.php +++ b/apps/platform/database/migrations/2026_02_14_220106_add_workspace_id_to_backup_schedules_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('backup_schedules', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('backup_schedules', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220107_add_workspace_id_to_inventory_items_table.php b/apps/platform/database/migrations/2026_02_14_220107_add_workspace_id_to_inventory_items_table.php index 549652c0..9df383f1 100644 --- a/apps/platform/database/migrations/2026_02_14_220107_add_workspace_id_to_inventory_items_table.php +++ b/apps/platform/database/migrations/2026_02_14_220107_add_workspace_id_to_inventory_items_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('inventory_items', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('inventory_items', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220108_add_workspace_id_to_inventory_links_table.php b/apps/platform/database/migrations/2026_02_14_220108_add_workspace_id_to_inventory_links_table.php index c7ad9d38..cc837be0 100644 --- a/apps/platform/database/migrations/2026_02_14_220108_add_workspace_id_to_inventory_links_table.php +++ b/apps/platform/database/migrations/2026_02_14_220108_add_workspace_id_to_inventory_links_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('inventory_links', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('inventory_links', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220109_add_workspace_id_to_entra_groups_table.php b/apps/platform/database/migrations/2026_02_14_220109_add_workspace_id_to_entra_groups_table.php index 715b9b3d..e438e639 100644 --- a/apps/platform/database/migrations/2026_02_14_220109_add_workspace_id_to_entra_groups_table.php +++ b/apps/platform/database/migrations/2026_02_14_220109_add_workspace_id_to_entra_groups_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('entra_groups', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('entra_groups', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220110_add_workspace_id_to_findings_table.php b/apps/platform/database/migrations/2026_02_14_220110_add_workspace_id_to_findings_table.php index d0ae0266..13f65640 100644 --- a/apps/platform/database/migrations/2026_02_14_220110_add_workspace_id_to_findings_table.php +++ b/apps/platform/database/migrations/2026_02_14_220110_add_workspace_id_to_findings_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('findings', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('findings', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220111_add_workspace_id_to_entra_role_definitions_table.php b/apps/platform/database/migrations/2026_02_14_220111_add_workspace_id_to_entra_role_definitions_table.php index 91c57546..c631e84b 100644 --- a/apps/platform/database/migrations/2026_02_14_220111_add_workspace_id_to_entra_role_definitions_table.php +++ b/apps/platform/database/migrations/2026_02_14_220111_add_workspace_id_to_entra_role_definitions_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('entra_role_definitions', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('entra_role_definitions', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220112_add_workspace_id_to_tenant_permissions_table.php b/apps/platform/database/migrations/2026_02_14_220112_add_workspace_id_to_tenant_permissions_table.php index 6a577320..09ade547 100644 --- a/apps/platform/database/migrations/2026_02_14_220112_add_workspace_id_to_tenant_permissions_table.php +++ b/apps/platform/database/migrations/2026_02_14_220112_add_workspace_id_to_tenant_permissions_table.php @@ -15,7 +15,7 @@ public function up(): void Schema::table('tenant_permissions', function (Blueprint $table): void { $table->unsignedBigInteger('workspace_id')->nullable(); $table->index('workspace_id'); - $table->index(['workspace_id', 'tenant_id']); + $table->index(['workspace_id', 'managed_environment_id']); }); } @@ -26,7 +26,7 @@ public function down(): void } Schema::table('tenant_permissions', function (Blueprint $table): void { - $table->dropIndex(['workspace_id', 'tenant_id']); + $table->dropIndex(['workspace_id', 'managed_environment_id']); $table->dropIndex(['workspace_id']); $table->dropColumn('workspace_id'); }); diff --git a/apps/platform/database/migrations/2026_02_14_220113_add_tenants_id_workspace_id_unique.php b/apps/platform/database/migrations/2026_02_14_220113_add_tenants_id_workspace_id_unique.php index ceb49a3d..8e59fa4c 100644 --- a/apps/platform/database/migrations/2026_02_14_220113_add_tenants_id_workspace_id_unique.php +++ b/apps/platform/database/migrations/2026_02_14_220113_add_tenants_id_workspace_id_unique.php @@ -8,22 +8,22 @@ { public function up(): void { - if (! Schema::hasTable('tenants') || ! Schema::hasColumn('tenants', 'workspace_id')) { + if (! Schema::hasTable('managed_environments') || ! Schema::hasColumn('managed_environments', 'workspace_id')) { return; } - Schema::table('tenants', function (Blueprint $table): void { + Schema::table('managed_environments', function (Blueprint $table): void { $table->unique(['id', 'workspace_id'], 'tenants_id_workspace_id_unique'); }); } public function down(): void { - if (! Schema::hasTable('tenants')) { + if (! Schema::hasTable('managed_environments')) { return; } - Schema::table('tenants', function (Blueprint $table): void { + Schema::table('managed_environments', function (Blueprint $table): void { $table->dropUnique('tenants_id_workspace_id_unique'); }); } diff --git a/apps/platform/database/migrations/2026_02_14_220115_add_workspace_isolation_constraints_to_tenant_owned_tables.php b/apps/platform/database/migrations/2026_02_14_220115_add_workspace_isolation_constraints_to_tenant_owned_tables.php index 0617b219..448a194d 100644 --- a/apps/platform/database/migrations/2026_02_14_220115_add_workspace_isolation_constraints_to_tenant_owned_tables.php +++ b/apps/platform/database/migrations/2026_02_14_220115_add_workspace_isolation_constraints_to_tenant_owned_tables.php @@ -50,9 +50,9 @@ public function up(): void ->on('workspaces') ->cascadeOnDelete(); - $table->foreign(['tenant_id', 'workspace_id'], $tenantWorkspaceConstraint) + $table->foreign(['managed_environment_id', 'workspace_id'], $tenantWorkspaceConstraint) ->references(['id', 'workspace_id']) - ->on('tenants') + ->on('managed_environments') ->cascadeOnDelete(); }); } diff --git a/apps/platform/database/migrations/2026_02_14_220116_backfill_workspace_id_on_audit_logs.php b/apps/platform/database/migrations/2026_02_14_220116_backfill_workspace_id_on_audit_logs.php index b0a6ce26..600714a8 100644 --- a/apps/platform/database/migrations/2026_02_14_220116_backfill_workspace_id_on_audit_logs.php +++ b/apps/platform/database/migrations/2026_02_14_220116_backfill_workspace_id_on_audit_logs.php @@ -17,10 +17,10 @@ public function up(): void if ($driver === 'pgsql') { DB::statement(<<<'SQL' UPDATE audit_logs - SET workspace_id = tenants.workspace_id - FROM tenants - WHERE audit_logs.tenant_id = tenants.id - AND audit_logs.tenant_id IS NOT NULL + SET workspace_id = managed_environments.workspace_id + FROM managed_environments + WHERE audit_logs.managed_environment_id = managed_environments.id + AND audit_logs.managed_environment_id IS NOT NULL AND audit_logs.workspace_id IS NULL SQL); @@ -30,9 +30,9 @@ public function up(): void if ($driver === 'mysql') { DB::statement(<<<'SQL' UPDATE audit_logs - JOIN tenants ON tenants.id = audit_logs.tenant_id - SET audit_logs.workspace_id = tenants.workspace_id - WHERE audit_logs.tenant_id IS NOT NULL + JOIN managed_environments ON managed_environments.id = audit_logs.managed_environment_id + SET audit_logs.workspace_id = managed_environments.workspace_id + WHERE audit_logs.managed_environment_id IS NOT NULL AND audit_logs.workspace_id IS NULL SQL); @@ -40,13 +40,13 @@ public function up(): void } DB::table('audit_logs') - ->whereNotNull('tenant_id') + ->whereNotNull('managed_environment_id') ->whereNull('workspace_id') ->orderBy('id') ->chunkById(500, function ($rows): void { foreach ($rows as $row) { - $workspaceId = DB::table('tenants') - ->where('id', (int) $row->tenant_id) + $workspaceId = DB::table('managed_environments') + ->where('id', (int) $row->managed_environment_id) ->value('workspace_id'); if ($workspaceId === null) { diff --git a/apps/platform/database/migrations/2026_02_14_220117_add_audit_logs_scope_check_constraint.php b/apps/platform/database/migrations/2026_02_14_220117_add_audit_logs_scope_check_constraint.php index 807ee576..ca7ef301 100644 --- a/apps/platform/database/migrations/2026_02_14_220117_add_audit_logs_scope_check_constraint.php +++ b/apps/platform/database/migrations/2026_02_14_220117_add_audit_logs_scope_check_constraint.php @@ -15,13 +15,13 @@ public function up(): void $driver = DB::getDriverName(); if ($driver === 'pgsql') { - DB::statement('ALTER TABLE audit_logs ADD CONSTRAINT audit_logs_tenant_workspace_scope_check CHECK (tenant_id IS NULL OR workspace_id IS NOT NULL)'); + DB::statement('ALTER TABLE audit_logs ADD CONSTRAINT audit_logs_tenant_workspace_scope_check CHECK (managed_environment_id IS NULL OR workspace_id IS NOT NULL)'); return; } if ($driver === 'mysql') { - DB::statement('ALTER TABLE audit_logs ADD CONSTRAINT audit_logs_tenant_workspace_scope_check CHECK (tenant_id IS NULL OR workspace_id IS NOT NULL)'); + DB::statement('ALTER TABLE audit_logs ADD CONSTRAINT audit_logs_tenant_workspace_scope_check CHECK (managed_environment_id IS NULL OR workspace_id IS NOT NULL)'); } } diff --git a/apps/platform/database/migrations/2026_02_15_120001_create_tenant_settings_table.php b/apps/platform/database/migrations/2026_02_15_120001_create_tenant_settings_table.php index 4deab851..39ae9417 100644 --- a/apps/platform/database/migrations/2026_02_15_120001_create_tenant_settings_table.php +++ b/apps/platform/database/migrations/2026_02_15_120001_create_tenant_settings_table.php @@ -11,19 +11,19 @@ public function up(): void Schema::create('tenant_settings', function (Blueprint $table): void { $table->id(); $table->foreignId('workspace_id')->constrained()->cascadeOnDelete(); - $table->foreignId('tenant_id'); + $table->foreignId('managed_environment_id'); $table->string('domain'); $table->string('key'); $table->json('value'); $table->foreignId('updated_by_user_id')->nullable()->constrained('users')->nullOnDelete(); $table->timestamps(); - $table->unique(['tenant_id', 'domain', 'key']); - $table->index(['workspace_id', 'tenant_id']); + $table->unique(['managed_environment_id', 'domain', 'key']); + $table->index(['workspace_id', 'managed_environment_id']); - $table->foreign(['tenant_id', 'workspace_id'], 'tenant_settings_tenant_workspace_fk') + $table->foreign(['managed_environment_id', 'workspace_id'], 'tenant_settings_tenant_workspace_fk') ->references(['id', 'workspace_id']) - ->on('tenants') + ->on('managed_environments') ->cascadeOnDelete(); }); } diff --git a/apps/platform/database/migrations/2026_02_16_230300_create_alert_deliveries_table.php b/apps/platform/database/migrations/2026_02_16_230300_create_alert_deliveries_table.php index fbe7ed31..322b28c7 100644 --- a/apps/platform/database/migrations/2026_02_16_230300_create_alert_deliveries_table.php +++ b/apps/platform/database/migrations/2026_02_16_230300_create_alert_deliveries_table.php @@ -11,7 +11,7 @@ public function up(): void Schema::create('alert_deliveries', function (Blueprint $table): void { $table->id(); $table->foreignId('workspace_id')->constrained()->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('alert_rule_id')->constrained()->cascadeOnDelete(); $table->foreignId('alert_destination_id')->constrained()->cascadeOnDelete(); $table->string('event_type'); @@ -28,7 +28,7 @@ public function up(): void $table->index(['workspace_id', 'created_at']); $table->index(['workspace_id', 'status', 'send_after']); - $table->index(['workspace_id', 'tenant_id', 'created_at']); + $table->index(['workspace_id', 'managed_environment_id', 'created_at']); $table->index(['workspace_id', 'alert_rule_id', 'fingerprint_hash']); }); } diff --git a/apps/platform/database/migrations/2026_02_18_000001_make_alert_deliveries_tenant_and_rule_nullable_for_test_deliveries.php b/apps/platform/database/migrations/2026_02_18_000001_make_alert_deliveries_tenant_and_rule_nullable_for_test_deliveries.php index d9d2e773..58eace49 100644 --- a/apps/platform/database/migrations/2026_02_18_000001_make_alert_deliveries_tenant_and_rule_nullable_for_test_deliveries.php +++ b/apps/platform/database/migrations/2026_02_18_000001_make_alert_deliveries_tenant_and_rule_nullable_for_test_deliveries.php @@ -9,7 +9,7 @@ public function up(): void { Schema::table('alert_deliveries', function (Blueprint $table): void { - $table->unsignedBigInteger('tenant_id')->nullable()->change(); + $table->unsignedBigInteger('managed_environment_id')->nullable()->change(); $table->unsignedBigInteger('alert_rule_id')->nullable()->change(); $table->index( @@ -24,7 +24,7 @@ public function down(): void Schema::table('alert_deliveries', function (Blueprint $table): void { $table->dropIndex('alert_deliveries_last_test_lookup_index'); - $table->unsignedBigInteger('tenant_id')->nullable(false)->change(); + $table->unsignedBigInteger('managed_environment_id')->nullable(false)->change(); $table->unsignedBigInteger('alert_rule_id')->nullable(false)->change(); }); } diff --git a/apps/platform/database/migrations/2026_02_19_100004_create_baseline_tenant_assignments_table.php b/apps/platform/database/migrations/2026_02_19_100004_create_baseline_tenant_assignments_table.php index dcdd6bc9..96bd972b 100644 --- a/apps/platform/database/migrations/2026_02_19_100004_create_baseline_tenant_assignments_table.php +++ b/apps/platform/database/migrations/2026_02_19_100004_create_baseline_tenant_assignments_table.php @@ -11,13 +11,13 @@ public function up(): void Schema::create('baseline_tenant_assignments', function (Blueprint $table): void { $table->id(); $table->foreignId('workspace_id')->constrained('workspaces')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->foreignId('baseline_profile_id')->constrained('baseline_profiles')->cascadeOnDelete(); $table->jsonb('override_scope_jsonb')->nullable(); $table->foreignId('assigned_by_user_id')->nullable()->constrained('users')->nullOnDelete(); $table->timestamps(); - $table->unique(['workspace_id', 'tenant_id']); + $table->unique(['workspace_id', 'managed_environment_id']); $table->index(['workspace_id', 'baseline_profile_id']); }); } diff --git a/apps/platform/database/migrations/2026_02_19_100005_add_source_to_findings_table.php b/apps/platform/database/migrations/2026_02_19_100005_add_source_to_findings_table.php index 5071b39f..d87a29a6 100644 --- a/apps/platform/database/migrations/2026_02_19_100005_add_source_to_findings_table.php +++ b/apps/platform/database/migrations/2026_02_19_100005_add_source_to_findings_table.php @@ -10,14 +10,14 @@ public function up(): void { Schema::table('findings', function (Blueprint $table): void { $table->string('source')->nullable()->after('finding_type'); - $table->index(['tenant_id', 'source']); + $table->index(['managed_environment_id', 'source']); }); } public function down(): void { Schema::table('findings', function (Blueprint $table): void { - $table->dropIndex(['tenant_id', 'source']); + $table->dropIndex(['managed_environment_id', 'source']); $table->dropColumn('source'); }); } diff --git a/apps/platform/database/migrations/2026_02_21_114914_create_stored_reports_table.php b/apps/platform/database/migrations/2026_02_21_114914_create_stored_reports_table.php index 3ff058b6..893d84d2 100644 --- a/apps/platform/database/migrations/2026_02_21_114914_create_stored_reports_table.php +++ b/apps/platform/database/migrations/2026_02_21_114914_create_stored_reports_table.php @@ -15,13 +15,13 @@ public function up(): void Schema::create('stored_reports', function (Blueprint $table) { $table->id(); $table->foreignId('workspace_id')->constrained()->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->string('report_type'); $table->jsonb('payload'); $table->timestamps(); - $table->index(['workspace_id', 'tenant_id', 'report_type']); - $table->index(['tenant_id', 'created_at']); + $table->index(['workspace_id', 'managed_environment_id', 'report_type']); + $table->index(['managed_environment_id', 'created_at']); }); if (DB::getDriverName() === 'pgsql') { diff --git a/apps/platform/database/migrations/2026_02_22_000259_add_fingerprint_to_stored_reports_table.php b/apps/platform/database/migrations/2026_02_22_000259_add_fingerprint_to_stored_reports_table.php index 90960747..41d1925c 100644 --- a/apps/platform/database/migrations/2026_02_22_000259_add_fingerprint_to_stored_reports_table.php +++ b/apps/platform/database/migrations/2026_02_22_000259_add_fingerprint_to_stored_reports_table.php @@ -15,8 +15,8 @@ public function up(): void $table->string('fingerprint', 64)->nullable()->after('payload'); $table->string('previous_fingerprint', 64)->nullable()->after('fingerprint'); - $table->unique(['tenant_id', 'report_type', 'fingerprint']); - $table->index(['tenant_id', 'report_type', 'created_at']); + $table->unique(['managed_environment_id', 'report_type', 'fingerprint']); + $table->index(['managed_environment_id', 'report_type', 'created_at']); }); } @@ -26,8 +26,8 @@ public function up(): void public function down(): void { Schema::table('stored_reports', function (Blueprint $table) { - $table->dropIndex(['tenant_id', 'report_type', 'created_at']); - $table->dropUnique(['tenant_id', 'report_type', 'fingerprint']); + $table->dropIndex(['managed_environment_id', 'report_type', 'created_at']); + $table->dropUnique(['managed_environment_id', 'report_type', 'fingerprint']); $table->dropColumn(['fingerprint', 'previous_fingerprint']); }); } diff --git a/apps/platform/database/migrations/2026_02_23_100000_create_review_packs_table.php b/apps/platform/database/migrations/2026_02_23_100000_create_review_packs_table.php index 29b8b29d..4f232f7b 100644 --- a/apps/platform/database/migrations/2026_02_23_100000_create_review_packs_table.php +++ b/apps/platform/database/migrations/2026_02_23_100000_create_review_packs_table.php @@ -12,7 +12,7 @@ public function up(): void Schema::create('review_packs', function (Blueprint $table): void { $table->id(); $table->foreignId('workspace_id')->constrained('workspaces')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->foreignId('operation_run_id')->nullable()->constrained('operation_runs')->nullOnDelete(); $table->foreignId('initiated_by_user_id')->nullable()->constrained('users')->nullOnDelete(); $table->string('status')->default('queued'); @@ -28,13 +28,13 @@ public function up(): void $table->timestampTz('expires_at')->nullable(); $table->timestamps(); - $table->index(['workspace_id', 'tenant_id', 'generated_at']); + $table->index(['workspace_id', 'managed_environment_id', 'generated_at']); $table->index(['status', 'expires_at']); }); DB::statement(' CREATE UNIQUE INDEX review_packs_fingerprint_unique - ON review_packs (workspace_id, tenant_id, fingerprint) + ON review_packs (workspace_id, managed_environment_id, fingerprint) WHERE fingerprint IS NOT NULL AND status NOT IN (\'expired\', \'failed\') '); } diff --git a/apps/platform/database/migrations/2026_02_24_160001_add_finding_recurrence_key_and_sla_indexes_to_findings_table.php b/apps/platform/database/migrations/2026_02_24_160001_add_finding_recurrence_key_and_sla_indexes_to_findings_table.php index 23dc8038..7a45d0f3 100644 --- a/apps/platform/database/migrations/2026_02_24_160001_add_finding_recurrence_key_and_sla_indexes_to_findings_table.php +++ b/apps/platform/database/migrations/2026_02_24_160001_add_finding_recurrence_key_and_sla_indexes_to_findings_table.php @@ -14,9 +14,9 @@ public function up(): void Schema::table('findings', function (Blueprint $table): void { $table->string('recurrence_key', 64)->nullable(); - $table->index(['tenant_id', 'status', 'due_at'], 'findings_tenant_status_due_at_idx'); - $table->index(['tenant_id', 'assignee_user_id'], 'findings_tenant_assignee_idx'); - $table->index(['tenant_id', 'recurrence_key'], 'findings_tenant_recurrence_key_idx'); + $table->index(['managed_environment_id', 'status', 'due_at'], 'findings_tenant_status_due_at_idx'); + $table->index(['managed_environment_id', 'assignee_user_id'], 'findings_tenant_assignee_idx'); + $table->index(['managed_environment_id', 'recurrence_key'], 'findings_tenant_recurrence_key_idx'); $table->index(['workspace_id', 'status', 'due_at'], 'findings_workspace_status_due_at_idx'); }); } diff --git a/apps/platform/database/migrations/2026_03_02_000001_add_evidence_fidelity_to_findings_table.php b/apps/platform/database/migrations/2026_03_02_000001_add_evidence_fidelity_to_findings_table.php index f427d93f..b5510036 100644 --- a/apps/platform/database/migrations/2026_03_02_000001_add_evidence_fidelity_to_findings_table.php +++ b/apps/platform/database/migrations/2026_03_02_000001_add_evidence_fidelity_to_findings_table.php @@ -30,7 +30,7 @@ public function up(): void return; } - $table->index(['tenant_id', 'evidence_fidelity'], 'findings_tenant_evidence_fidelity_idx'); + $table->index(['managed_environment_id', 'evidence_fidelity'], 'findings_tenant_evidence_fidelity_idx'); }); } diff --git a/apps/platform/database/migrations/2026_03_03_100003_add_baseline_purpose_to_policy_versions_table.php b/apps/platform/database/migrations/2026_03_03_100003_add_baseline_purpose_to_policy_versions_table.php index 4f947ab1..0b7959a4 100644 --- a/apps/platform/database/migrations/2026_03_03_100003_add_baseline_purpose_to_policy_versions_table.php +++ b/apps/platform/database/migrations/2026_03_03_100003_add_baseline_purpose_to_policy_versions_table.php @@ -31,15 +31,15 @@ public function up(): void return; } - $table->index(['tenant_id', 'policy_id', 'capture_purpose', 'captured_at'], 'policy_versions_tenant_policy_purpose_captured_idx'); + $table->index(['managed_environment_id', 'policy_id', 'capture_purpose', 'captured_at'], 'policy_versions_tenant_policy_purpose_captured_idx'); if (Schema::hasColumn('policy_versions', 'operation_run_id')) { - $table->index(['tenant_id', 'capture_purpose', 'operation_run_id'], 'policy_versions_tenant_purpose_run_idx'); + $table->index(['managed_environment_id', 'capture_purpose', 'operation_run_id'], 'policy_versions_tenant_purpose_run_idx'); $table->foreign('operation_run_id')->references('id')->on('operation_runs')->nullOnDelete(); } if (Schema::hasColumn('policy_versions', 'baseline_profile_id')) { - $table->index(['tenant_id', 'capture_purpose', 'baseline_profile_id'], 'policy_versions_tenant_purpose_profile_idx'); + $table->index(['managed_environment_id', 'capture_purpose', 'baseline_profile_id'], 'policy_versions_tenant_purpose_profile_idx'); $table->foreign('baseline_profile_id')->references('id')->on('baseline_profiles')->nullOnDelete(); } }); diff --git a/apps/platform/database/migrations/2026_03_11_120000_expand_audit_logs_for_audit_foundation.php b/apps/platform/database/migrations/2026_03_11_120000_expand_audit_logs_for_audit_foundation.php index 845c8931..8a64d3a3 100644 --- a/apps/platform/database/migrations/2026_03_11_120000_expand_audit_logs_for_audit_foundation.php +++ b/apps/platform/database/migrations/2026_03_11_120000_expand_audit_logs_for_audit_foundation.php @@ -45,7 +45,7 @@ public function up(): void Schema::table('audit_logs', function (Blueprint $table): void { $table->index(['workspace_id', 'recorded_at'], 'audit_logs_workspace_recorded_at_index'); - $table->index(['tenant_id', 'recorded_at'], 'audit_logs_tenant_recorded_at_index'); + $table->index(['managed_environment_id', 'recorded_at'], 'audit_logs_tenant_recorded_at_index'); $table->index(['action', 'recorded_at'], 'audit_logs_action_recorded_at_index'); $table->index(['outcome', 'recorded_at'], 'audit_logs_outcome_recorded_at_index'); }); diff --git a/apps/platform/database/migrations/2026_03_13_120000_add_cancelled_at_to_managed_tenant_onboarding_sessions.php b/apps/platform/database/migrations/2026_03_13_120000_add_cancelled_at_to_managed_tenant_onboarding_sessions.php index 26201c4b..7484c548 100644 --- a/apps/platform/database/migrations/2026_03_13_120000_add_cancelled_at_to_managed_tenant_onboarding_sessions.php +++ b/apps/platform/database/migrations/2026_03_13_120000_add_cancelled_at_to_managed_tenant_onboarding_sessions.php @@ -25,7 +25,7 @@ public function up(): void DB::statement('DROP INDEX IF EXISTS managed_tenant_onboarding_sessions_active_tenant_unique'); DB::statement('CREATE UNIQUE INDEX managed_tenant_onboarding_sessions_active_workspace_entra_unique ON managed_tenant_onboarding_sessions (workspace_id, entra_tenant_id) WHERE completed_at IS NULL AND cancelled_at IS NULL'); - DB::statement('CREATE UNIQUE INDEX managed_tenant_onboarding_sessions_active_tenant_unique ON managed_tenant_onboarding_sessions (tenant_id) WHERE completed_at IS NULL AND cancelled_at IS NULL AND tenant_id IS NOT NULL'); + DB::statement('CREATE UNIQUE INDEX managed_tenant_onboarding_sessions_active_tenant_unique ON managed_tenant_onboarding_sessions (managed_environment_id) WHERE completed_at IS NULL AND cancelled_at IS NULL AND managed_environment_id IS NOT NULL'); } public function down(): void @@ -38,7 +38,7 @@ public function down(): void DB::statement('DROP INDEX IF EXISTS managed_tenant_onboarding_sessions_active_tenant_unique'); DB::statement('CREATE UNIQUE INDEX managed_tenant_onboarding_sessions_active_workspace_entra_unique ON managed_tenant_onboarding_sessions (workspace_id, entra_tenant_id) WHERE completed_at IS NULL'); - DB::statement('CREATE UNIQUE INDEX managed_tenant_onboarding_sessions_active_tenant_unique ON managed_tenant_onboarding_sessions (tenant_id) WHERE completed_at IS NULL AND tenant_id IS NOT NULL'); + DB::statement('CREATE UNIQUE INDEX managed_tenant_onboarding_sessions_active_tenant_unique ON managed_tenant_onboarding_sessions (managed_environment_id) WHERE completed_at IS NULL AND managed_environment_id IS NOT NULL'); if (Schema::hasColumn('managed_tenant_onboarding_sessions', 'cancelled_at')) { Schema::table('managed_tenant_onboarding_sessions', function (Blueprint $table): void { diff --git a/apps/platform/database/migrations/2026_03_19_000000_create_evidence_snapshots_table.php b/apps/platform/database/migrations/2026_03_19_000000_create_evidence_snapshots_table.php index 9b318391..5c6163bb 100644 --- a/apps/platform/database/migrations/2026_03_19_000000_create_evidence_snapshots_table.php +++ b/apps/platform/database/migrations/2026_03_19_000000_create_evidence_snapshots_table.php @@ -14,7 +14,7 @@ public function up(): void Schema::create('evidence_snapshots', function (Blueprint $table): void { $table->id(); $table->foreignId('workspace_id')->constrained('workspaces')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->foreignId('operation_run_id')->nullable()->constrained('operation_runs')->nullOnDelete(); $table->foreignId('initiated_by_user_id')->nullable()->constrained('users')->nullOnDelete(); $table->string('fingerprint', 64)->nullable(); @@ -26,13 +26,13 @@ public function up(): void $table->timestampTz('expires_at')->nullable(); $table->timestamps(); - $table->index(['workspace_id', 'tenant_id', 'created_at']); - $table->index(['tenant_id', 'status', 'generated_at']); + $table->index(['workspace_id', 'managed_environment_id', 'created_at']); + $table->index(['managed_environment_id', 'status', 'generated_at']); $table->index(['status', 'expires_at']); }); - DB::statement("CREATE UNIQUE INDEX evidence_snapshots_active_unique ON evidence_snapshots (workspace_id, tenant_id) WHERE status = 'active'"); - DB::statement("CREATE UNIQUE INDEX evidence_snapshots_fingerprint_unique ON evidence_snapshots (workspace_id, tenant_id, fingerprint) WHERE fingerprint IS NOT NULL AND status NOT IN ('expired', 'failed')"); + DB::statement("CREATE UNIQUE INDEX evidence_snapshots_active_unique ON evidence_snapshots (workspace_id, managed_environment_id) WHERE status = 'active'"); + DB::statement("CREATE UNIQUE INDEX evidence_snapshots_fingerprint_unique ON evidence_snapshots (workspace_id, managed_environment_id, fingerprint) WHERE fingerprint IS NOT NULL AND status NOT IN ('expired', 'failed')"); } public function down(): void diff --git a/apps/platform/database/migrations/2026_03_19_000001_create_evidence_snapshot_items_table.php b/apps/platform/database/migrations/2026_03_19_000001_create_evidence_snapshot_items_table.php index 08901fd1..c770ebce 100644 --- a/apps/platform/database/migrations/2026_03_19_000001_create_evidence_snapshot_items_table.php +++ b/apps/platform/database/migrations/2026_03_19_000001_create_evidence_snapshot_items_table.php @@ -15,7 +15,7 @@ public function up(): void $table->id(); $table->foreignId('evidence_snapshot_id')->constrained('evidence_snapshots')->cascadeOnDelete(); $table->foreignId('workspace_id')->constrained('workspaces')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->string('dimension_key'); $table->string('state')->default('missing'); $table->boolean('required')->default(true); @@ -30,8 +30,8 @@ public function up(): void $table->timestamps(); $table->unique(['evidence_snapshot_id', 'dimension_key']); - $table->index(['workspace_id', 'tenant_id', 'dimension_key']); - $table->index(['tenant_id', 'state']); + $table->index(['workspace_id', 'managed_environment_id', 'dimension_key']); + $table->index(['managed_environment_id', 'state']); }); if (DB::getDriverName() === 'pgsql') { diff --git a/apps/platform/database/migrations/2026_03_19_000001_create_finding_exceptions_table.php b/apps/platform/database/migrations/2026_03_19_000001_create_finding_exceptions_table.php index 2a2e6867..9445f011 100644 --- a/apps/platform/database/migrations/2026_03_19_000001_create_finding_exceptions_table.php +++ b/apps/platform/database/migrations/2026_03_19_000001_create_finding_exceptions_table.php @@ -14,7 +14,7 @@ public function up(): void Schema::create('finding_exceptions', function (Blueprint $table): void { $table->id(); $table->foreignId('workspace_id')->constrained('workspaces')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->foreignId('finding_id')->constrained('findings')->cascadeOnDelete(); $table->foreignId('requested_by_user_id')->constrained('users'); $table->foreignId('owner_user_id')->nullable()->constrained('users'); @@ -39,14 +39,14 @@ public function up(): void $table->unique('finding_id'); $table->index(['workspace_id', 'status', 'review_due_at'], 'finding_exceptions_workspace_status_review_idx'); $table->index(['workspace_id', 'status', 'expires_at'], 'finding_exceptions_workspace_status_expiry_idx'); - $table->index(['workspace_id', 'tenant_id', 'status'], 'finding_exceptions_tenant_status_idx'); - $table->index(['tenant_id', 'finding_id'], 'finding_exceptions_finding_lookup_idx'); - $table->index(['tenant_id', 'requested_at'], 'finding_exceptions_requested_at_idx'); + $table->index(['workspace_id', 'managed_environment_id', 'status'], 'finding_exceptions_tenant_status_idx'); + $table->index(['managed_environment_id', 'finding_id'], 'finding_exceptions_finding_lookup_idx'); + $table->index(['managed_environment_id', 'requested_at'], 'finding_exceptions_requested_at_idx'); $table - ->foreign(['tenant_id', 'workspace_id'], 'finding_exceptions_tenant_workspace_fk') + ->foreign(['managed_environment_id', 'workspace_id'], 'finding_exceptions_tenant_workspace_fk') ->references(['id', 'workspace_id']) - ->on('tenants') + ->on('managed_environments') ->cascadeOnDelete(); }); diff --git a/apps/platform/database/migrations/2026_03_19_000002_add_evidence_snapshot_id_to_review_packs_table.php b/apps/platform/database/migrations/2026_03_19_000002_add_evidence_snapshot_id_to_review_packs_table.php index 2043b733..d2040c2a 100644 --- a/apps/platform/database/migrations/2026_03_19_000002_add_evidence_snapshot_id_to_review_packs_table.php +++ b/apps/platform/database/migrations/2026_03_19_000002_add_evidence_snapshot_id_to_review_packs_table.php @@ -17,7 +17,7 @@ public function up(): void ->constrained('evidence_snapshots') ->nullOnDelete(); - $table->index(['tenant_id', 'evidence_snapshot_id']); + $table->index(['managed_environment_id', 'evidence_snapshot_id']); }); } diff --git a/apps/platform/database/migrations/2026_03_19_000002_create_finding_exception_decisions_table.php b/apps/platform/database/migrations/2026_03_19_000002_create_finding_exception_decisions_table.php index fd2f561b..ebfc4792 100644 --- a/apps/platform/database/migrations/2026_03_19_000002_create_finding_exception_decisions_table.php +++ b/apps/platform/database/migrations/2026_03_19_000002_create_finding_exception_decisions_table.php @@ -15,7 +15,7 @@ public function up(): void $table->id(); $table->foreignId('finding_exception_id')->constrained('finding_exceptions')->cascadeOnDelete(); $table->foreignId('workspace_id')->constrained('workspaces')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->foreignId('actor_user_id')->constrained('users'); $table->string('decision_type'); $table->text('reason')->nullable(); @@ -26,13 +26,13 @@ public function up(): void $table->timestamps(); $table->index(['finding_exception_id', 'decided_at'], 'finding_exception_decisions_history_idx'); - $table->index(['workspace_id', 'tenant_id', 'decision_type'], 'finding_exception_decisions_scope_type_idx'); - $table->index(['tenant_id', 'actor_user_id'], 'finding_exception_decisions_actor_idx'); + $table->index(['workspace_id', 'managed_environment_id', 'decision_type'], 'finding_exception_decisions_scope_type_idx'); + $table->index(['managed_environment_id', 'actor_user_id'], 'finding_exception_decisions_actor_idx'); $table - ->foreign(['tenant_id', 'workspace_id'], 'finding_exception_decisions_tenant_workspace_fk') + ->foreign(['managed_environment_id', 'workspace_id'], 'finding_exception_decisions_tenant_workspace_fk') ->references(['id', 'workspace_id']) - ->on('tenants') + ->on('managed_environments') ->cascadeOnDelete(); }); diff --git a/apps/platform/database/migrations/2026_03_19_000003_create_finding_exception_evidence_references_table.php b/apps/platform/database/migrations/2026_03_19_000003_create_finding_exception_evidence_references_table.php index a15243da..86863bb5 100644 --- a/apps/platform/database/migrations/2026_03_19_000003_create_finding_exception_evidence_references_table.php +++ b/apps/platform/database/migrations/2026_03_19_000003_create_finding_exception_evidence_references_table.php @@ -15,7 +15,7 @@ public function up(): void $table->id(); $table->foreignId('finding_exception_id')->constrained('finding_exceptions')->cascadeOnDelete(); $table->foreignId('workspace_id')->constrained('workspaces')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->string('source_type'); $table->string('source_id')->nullable(); $table->string('source_fingerprint')->nullable(); @@ -25,13 +25,13 @@ public function up(): void $table->timestamps(); $table->index(['finding_exception_id', 'source_type'], 'finding_exception_evidence_refs_parent_idx'); - $table->index(['workspace_id', 'tenant_id'], 'finding_exception_evidence_refs_scope_idx'); - $table->index(['tenant_id', 'source_type'], 'finding_exception_evidence_refs_source_idx'); + $table->index(['workspace_id', 'managed_environment_id'], 'finding_exception_evidence_refs_scope_idx'); + $table->index(['managed_environment_id', 'source_type'], 'finding_exception_evidence_refs_source_idx'); $table - ->foreign(['tenant_id', 'workspace_id'], 'finding_exception_evidence_refs_tenant_workspace_fk') + ->foreign(['managed_environment_id', 'workspace_id'], 'finding_exception_evidence_refs_tenant_workspace_fk') ->references(['id', 'workspace_id']) - ->on('tenants') + ->on('managed_environments') ->cascadeOnDelete(); }); diff --git a/apps/platform/database/migrations/2026_03_20_000000_create_tenant_reviews_table.php b/apps/platform/database/migrations/2026_03_20_000000_create_tenant_reviews_table.php index d3150870..2b18da47 100644 --- a/apps/platform/database/migrations/2026_03_20_000000_create_tenant_reviews_table.php +++ b/apps/platform/database/migrations/2026_03_20_000000_create_tenant_reviews_table.php @@ -14,7 +14,7 @@ public function up(): void Schema::create('tenant_reviews', function (Blueprint $table): void { $table->id(); $table->foreignId('workspace_id')->constrained('workspaces')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->foreignId('evidence_snapshot_id')->constrained('evidence_snapshots')->restrictOnDelete(); $table->foreignId('current_export_review_pack_id')->nullable()->constrained('review_packs')->nullOnDelete(); $table->foreignId('operation_run_id')->nullable()->constrained('operation_runs')->nullOnDelete(); @@ -30,13 +30,13 @@ public function up(): void $table->timestampTz('generated_at')->nullable(); $table->timestamps(); - $table->index(['workspace_id', 'tenant_id', 'created_at']); - $table->index(['tenant_id', 'status', 'published_at']); + $table->index(['workspace_id', 'managed_environment_id', 'created_at']); + $table->index(['managed_environment_id', 'status', 'published_at']); }); DB::statement(" CREATE UNIQUE INDEX tenant_reviews_fingerprint_mutable_unique - ON tenant_reviews (workspace_id, tenant_id, fingerprint) + ON tenant_reviews (workspace_id, managed_environment_id, fingerprint) WHERE fingerprint IS NOT NULL AND status IN ('draft', 'ready', 'failed') "); } diff --git a/apps/platform/database/migrations/2026_03_20_000100_create_tenant_review_sections_table.php b/apps/platform/database/migrations/2026_03_20_000100_create_tenant_review_sections_table.php index 5bebccd1..f0830d04 100644 --- a/apps/platform/database/migrations/2026_03_20_000100_create_tenant_review_sections_table.php +++ b/apps/platform/database/migrations/2026_03_20_000100_create_tenant_review_sections_table.php @@ -14,7 +14,7 @@ public function up(): void $table->id(); $table->foreignId('tenant_review_id')->constrained('tenant_reviews')->cascadeOnDelete(); $table->foreignId('workspace_id')->constrained('workspaces')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->string('section_key'); $table->string('title'); $table->unsignedInteger('sort_order')->default(0); @@ -27,8 +27,8 @@ public function up(): void $table->timestamps(); $table->unique(['tenant_review_id', 'section_key']); - $table->index(['workspace_id', 'tenant_id', 'section_key']); - $table->index(['tenant_id', 'completeness_state']); + $table->index(['workspace_id', 'managed_environment_id', 'section_key']); + $table->index(['managed_environment_id', 'completeness_state']); }); } diff --git a/apps/platform/database/migrations/2026_04_09_000002_drop_legacy_provider_state_columns_from_provider_connections.php b/apps/platform/database/migrations/2026_04_09_000002_drop_legacy_provider_state_columns_from_provider_connections.php index 34d5be87..45bd5045 100644 --- a/apps/platform/database/migrations/2026_04_09_000002_drop_legacy_provider_state_columns_from_provider_connections.php +++ b/apps/platform/database/migrations/2026_04_09_000002_drop_legacy_provider_state_columns_from_provider_connections.php @@ -9,8 +9,8 @@ public function up(): void { Schema::table('provider_connections', function (Blueprint $table): void { - $table->dropIndex(['tenant_id', 'provider', 'status']); - $table->dropIndex(['tenant_id', 'provider', 'health_status']); + $table->dropIndex(['managed_environment_id', 'provider', 'status']); + $table->dropIndex(['managed_environment_id', 'provider', 'health_status']); $table->dropIndex(['workspace_id', 'provider', 'status']); $table->dropIndex(['workspace_id', 'provider', 'health_status']); $table->dropColumn(['status', 'health_status']); @@ -22,8 +22,8 @@ public function down(): void Schema::table('provider_connections', function (Blueprint $table): void { $table->string('status')->default('needs_consent'); $table->string('health_status')->default('unknown'); - $table->index(['tenant_id', 'provider', 'status']); - $table->index(['tenant_id', 'provider', 'health_status']); + $table->index(['managed_environment_id', 'provider', 'status']); + $table->index(['managed_environment_id', 'provider', 'health_status']); $table->index(['workspace_id', 'provider', 'status']); $table->index(['workspace_id', 'provider', 'health_status']); }); diff --git a/apps/platform/database/migrations/2026_04_10_000003_create_tenant_triage_reviews_table.php b/apps/platform/database/migrations/2026_04_10_000003_create_tenant_triage_reviews_table.php index 3eec949a..2b388a4c 100644 --- a/apps/platform/database/migrations/2026_04_10_000003_create_tenant_triage_reviews_table.php +++ b/apps/platform/database/migrations/2026_04_10_000003_create_tenant_triage_reviews_table.php @@ -14,7 +14,7 @@ public function up(): void Schema::create('tenant_triage_reviews', function (Blueprint $table): void { $table->id(); $table->foreignId('workspace_id')->constrained('workspaces')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->string('concern_family', 64); $table->string('current_state', 64); $table->timestampTz('reviewed_at'); @@ -26,18 +26,18 @@ public function up(): void $table->timestamps(); $table->index( - ['workspace_id', 'concern_family', 'resolved_at', 'tenant_id'], + ['workspace_id', 'concern_family', 'resolved_at', 'managed_environment_id'], 'tenant_triage_reviews_lookup_index', ); $table->index( - ['tenant_id', 'concern_family', 'resolved_at'], + ['managed_environment_id', 'concern_family', 'resolved_at'], 'tenant_triage_reviews_tenant_family_index', ); }); DB::statement(" CREATE UNIQUE INDEX tenant_triage_reviews_active_unique - ON tenant_triage_reviews (workspace_id, tenant_id, concern_family) + ON tenant_triage_reviews (workspace_id, managed_environment_id, concern_family) WHERE resolved_at IS NULL "); diff --git a/apps/platform/database/migrations/2026_04_26_194038_create_product_usage_events_table.php b/apps/platform/database/migrations/2026_04_26_194038_create_product_usage_events_table.php index 298f95e4..8a033119 100644 --- a/apps/platform/database/migrations/2026_04_26_194038_create_product_usage_events_table.php +++ b/apps/platform/database/migrations/2026_04_26_194038_create_product_usage_events_table.php @@ -11,7 +11,7 @@ public function up(): void Schema::create('product_usage_events', function (Blueprint $table): void { $table->id(); $table->foreignId('workspace_id')->constrained()->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained()->cascadeOnDelete(); $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete(); $table->string('event_name', 120); $table->string('feature_area', 60); @@ -21,7 +21,7 @@ public function up(): void $table->timestampTz('occurred_at'); $table->timestamps(); - $table->index(['workspace_id', 'tenant_id', 'occurred_at']); + $table->index(['workspace_id', 'managed_environment_id', 'occurred_at']); $table->index(['event_name', 'occurred_at']); $table->index(['subject_type', 'subject_id', 'occurred_at']); }); diff --git a/apps/platform/database/migrations/2026_04_27_095518_create_support_requests_table.php b/apps/platform/database/migrations/2026_04_27_095518_create_support_requests_table.php index 49eec5c3..0c7a1f1a 100644 --- a/apps/platform/database/migrations/2026_04_27_095518_create_support_requests_table.php +++ b/apps/platform/database/migrations/2026_04_27_095518_create_support_requests_table.php @@ -16,7 +16,7 @@ public function up(): void Schema::create('support_requests', function (Blueprint $table): void { $table->id(); $table->foreignId('workspace_id')->constrained('workspaces')->cascadeOnDelete(); - $table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete(); + $table->foreignId('managed_environment_id')->constrained('managed_environments')->cascadeOnDelete(); $table->foreignId('operation_run_id')->nullable()->constrained('operation_runs')->nullOnDelete(); $table->foreignId('initiated_by_user_id')->nullable()->constrained('users')->nullOnDelete(); $table->string('internal_reference')->unique(); @@ -30,8 +30,8 @@ public function up(): void $table->jsonb('context_envelope')->default('{}'); $table->timestamps(); - $table->index(['workspace_id', 'tenant_id']); - $table->index(['tenant_id', 'created_at']); + $table->index(['workspace_id', 'managed_environment_id']); + $table->index(['managed_environment_id', 'created_at']); $table->index(['operation_run_id', 'created_at']); }); } diff --git a/apps/platform/database/seeders/PlatformUserSeeder.php b/apps/platform/database/seeders/PlatformUserSeeder.php index 659eb0c9..673baade 100644 --- a/apps/platform/database/seeders/PlatformUserSeeder.php +++ b/apps/platform/database/seeders/PlatformUserSeeder.php @@ -3,7 +3,7 @@ namespace Database\Seeders; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Auth\PlatformCapabilities; use Illuminate\Database\Seeder; @@ -21,9 +21,13 @@ public function run(): void ['name' => 'Default Workspace', 'slug' => 'default'], ); - Tenant::query()->updateOrCreate( - ['external_id' => 'platform'], - ['name' => 'Platform', 'workspace_id' => (int) $workspace->getKey()], + ManagedEnvironment::query()->updateOrCreate( + ['slug' => 'platform'], + [ + 'name' => 'Platform', + 'display_name' => 'Platform', + 'workspace_id' => (int) $workspace->getKey(), + ], ); PlatformUser::query()->updateOrCreate( diff --git a/apps/platform/database/seeders/PoliciesSeeder.php b/apps/platform/database/seeders/PoliciesSeeder.php index 604bcd09..03b9e974 100644 --- a/apps/platform/database/seeders/PoliciesSeeder.php +++ b/apps/platform/database/seeders/PoliciesSeeder.php @@ -3,7 +3,7 @@ namespace Database\Seeders; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use Illuminate\Database\Seeder; use Illuminate\Support\Str; @@ -12,20 +12,19 @@ class PoliciesSeeder extends Seeder { public function run(): void { - $seedTenantId = env('INTUNE_TENANT_ID', 'local-tenant'); + $seedManagedEnvironmentSlug = env('INTUNE_TENANT_ID', 'local-tenant'); $workspace = Workspace::query()->firstOrCreate( ['slug' => 'default'], ['name' => 'Default Workspace', 'slug' => 'default'], ); - $tenant = Tenant::firstOrCreate([ - 'tenant_id' => $seedTenantId, + $tenant = ManagedEnvironment::query()->firstOrCreate([ + 'slug' => $seedManagedEnvironmentSlug, ], [ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Default Tenant', - 'external_id' => (string) Str::uuid(), - 'domain' => null, + 'name' => 'Default Managed Environment', + 'display_name' => 'Default Managed Environment', 'metadata' => [], ]); @@ -35,15 +34,6 @@ public function run(): void ])->saveQuietly(); } - $externalId = (string) ($tenant->external_id ?? ''); - $isUuidV4 = Str::isUuid($externalId) && substr($externalId, 14, 1) === '4'; - - if (! $isUuidV4) { - $tenant->forceFill([ - 'external_id' => (string) Str::uuid(), - ])->saveQuietly(); - } - $supported = config('tenantpilot.supported_policy_types', []); $now = now(); @@ -55,7 +45,7 @@ public function run(): void Policy::updateOrCreate( [ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => $externalId, 'policy_type' => $policyType, ], diff --git a/apps/platform/lang/de/localization.php b/apps/platform/lang/de/localization.php index d50026e9..d96790ce 100644 --- a/apps/platform/lang/de/localization.php +++ b/apps/platform/lang/de/localization.php @@ -60,7 +60,7 @@ 'auth' => [ 'microsoft_not_configured' => 'Microsoft-Anmeldung ist nicht konfiguriert.', 'sign_in_microsoft' => 'Mit Microsoft anmelden', - 'tenant_admin_membership_required' => 'Tenant-Admin-Zugriff erfordert eine Tenant-Mitgliedschaft.', + 'tenant_admin_membership_required' => 'ManagedEnvironment-Admin-Zugriff erfordert eine ManagedEnvironment-Mitgliedschaft.', ], 'navigation' => [ 'findings' => 'Findings', @@ -277,7 +277,7 @@ 'customer_reviews' => 'Kundenreviews', 'customer_review_workspace' => 'Kundenreview-Workspace', 'customer_safe_review_workspace' => 'Kundensicherer Governance-Paket-Index', - 'customer_workspace_intro' => 'Prüfen Sie für jeden berechtigten Tenant den executive-fähigen Status des Governance-Pakets und öffnen Sie bei Bedarf die kundensichere Detailansicht.', + 'customer_workspace_intro' => 'Prüfen Sie für jeden berechtigten ManagedEnvironment den executive-fähigen Status des Governance-Pakets und öffnen Sie bei Bedarf die kundensichere Detailansicht.', 'customer_workspace_canonical_note' => 'Jede Zeile ist ein Einstieg in die Detailansicht: Dort sehen Sie Paketstatus, Executive-Einstieg, Nachweise, aktuelle Risiken und den nächsten kundensicheren Schritt.', 'customer_workspace_mapping_version' => 'Die Control-Readiness-Interpretation verwendet :version für diesen Workspace.', 'customer_workspace_non_certification_disclosure' => 'Dieser Workspace fasst die aktuelle Review- und Nachweislage für die Service-Auslieferung zusammen. Er ersetzt weder ein formales Auditurteil noch eine Zertifizierung oder rechtliche Attestierung.', diff --git a/apps/platform/resources/views/admin-consent-callback.blade.php b/apps/platform/resources/views/admin-consent-callback.blade.php index ea07dc95..9cc3cce1 100644 --- a/apps/platform/resources/views/admin-consent-callback.blade.php +++ b/apps/platform/resources/views/admin-consent-callback.blade.php @@ -17,7 +17,7 @@

Admin Consent Status

-

Tenant: {{ $tenant->name }} ({{ $tenant->graphTenantId() }})

+

ManagedEnvironment: {{ $tenant->name }} ({{ $tenant->graphTenantId() }})

@isset($connection)

Connection: {{ $connection->connection_type->value === 'platform' ? 'Platform connection' : 'Dedicated connection' }}

Verification state: {{ $verificationStateLabel ?? ucfirst($connection->verification_status->value) }}

@@ -37,11 +37,11 @@

@php - $isOnboarding = in_array($tenant->status, [\App\Models\Tenant::STATUS_DRAFT, \App\Models\Tenant::STATUS_ONBOARDING], true); + $isOnboarding = in_array($tenant->status, [\App\Models\ManagedEnvironment::STATUS_DRAFT, \App\Models\ManagedEnvironment::STATUS_ONBOARDING], true); $backUrl = $isOnboarding ? route('admin.onboarding') : route('filament.admin.resources.tenants.view', ['tenant' => $tenant->external_id, 'record' => $tenant]); - $backLabel = $isOnboarding ? 'Zurück zum Onboarding' : 'Zurück zur Tenant-Detailseite'; + $backLabel = $isOnboarding ? 'Zurück zum Onboarding' : 'Zurück zur ManagedEnvironment-Detailseite'; @endphp diff --git a/apps/platform/resources/views/filament/actions/verification-required-permissions-assist.blade.php b/apps/platform/resources/views/filament/actions/verification-required-permissions-assist.blade.php index 808c4721..752d9a90 100644 --- a/apps/platform/resources/views/filament/actions/verification-required-permissions-assist.blade.php +++ b/apps/platform/resources/views/filament/actions/verification-required-permissions-assist.blade.php @@ -69,10 +69,10 @@

- Tenant + ManagedEnvironment
- {{ (string) ($tenant['name'] ?? 'Tenant') }} + {{ (string) ($tenant['name'] ?? 'ManagedEnvironment') }}
{{ (string) ($tenant['external_id'] ?? 'Unknown tenant') }} diff --git a/apps/platform/resources/views/filament/infolists/entries/restore-results.blade.php b/apps/platform/resources/views/filament/infolists/entries/restore-results.blade.php index 07dfff9f..559f2fd7 100644 --- a/apps/platform/resources/views/filament/infolists/entries/restore-results.blade.php +++ b/apps/platform/resources/views/filament/infolists/entries/restore-results.blade.php @@ -18,7 +18,7 @@ $policyItems = collect($results)->reject($isFoundationEntry); } - $tenant = rescue(fn () => \App\Models\Tenant::current(), null); + $tenant = rescue(fn () => \App\Models\ManagedEnvironment::current(), null); $groupLabelResolver = $tenant ? app(\App\Services\Directory\EntraGroupLabelResolver::class) : null; $formatGroupId = function ($groupId, $fallbackName = null) use ($tenant, $groupLabelResolver) { diff --git a/apps/platform/resources/views/filament/modals/support-diagnostic-bundle.blade.php b/apps/platform/resources/views/filament/modals/support-diagnostic-bundle.blade.php index e8eec309..b8183dcd 100644 --- a/apps/platform/resources/views/filament/modals/support-diagnostic-bundle.blade.php +++ b/apps/platform/resources/views/filament/modals/support-diagnostic-bundle.blade.php @@ -60,8 +60,8 @@
{{ data_get($context, 'workspace_label', 'Workspace unavailable') }}
-
Tenant
-
{{ data_get($context, 'tenant_label', 'Tenant unavailable') }}
+
ManagedEnvironment
+
{{ data_get($context, 'tenant_label', 'ManagedEnvironment unavailable') }}
diff --git a/apps/platform/resources/views/filament/pages/baseline-compare-matrix.blade.php b/apps/platform/resources/views/filament/pages/baseline-compare-matrix.blade.php index 3096a506..01b278b0 100644 --- a/apps/platform/resources/views/filament/pages/baseline-compare-matrix.blade.php +++ b/apps/platform/resources/views/filament/pages/baseline-compare-matrix.blade.php @@ -250,7 +250,7 @@ - Tenant sort: {{ $tenantSortOptions[$currentFilters['tenant_sort'] ?? 'tenant_name'] ?? 'Tenant name' }} + ManagedEnvironment sort: {{ $tenantSortOptions[$currentFilters['tenant_sort'] ?? 'tenant_name'] ?? 'ManagedEnvironment name' }} diff --git a/apps/platform/resources/views/filament/pages/choose-tenant.blade.php b/apps/platform/resources/views/filament/pages/choose-tenant.blade.php index 360596c9..331f7729 100644 --- a/apps/platform/resources/views/filament/pages/choose-tenant.blade.php +++ b/apps/platform/resources/views/filament/pages/choose-tenant.blade.php @@ -46,7 +46,7 @@ class="inline-flex items-center gap-1.5 text-sm text-gray-500 transition-colors
@else - {{-- Tenant list --}} + {{-- ManagedEnvironment list --}}
{{-- Header row --}}
@@ -66,7 +66,7 @@ class="inline-flex items-center gap-1.5 text-sm text-gray-500 transition-colors

Select the tenant for your normal active operating context.

No tenant selected is still a valid workspace state on workspace-wide pages such as operations and managed tenants.

- {{-- Tenant cards --}} + {{-- ManagedEnvironment cards --}}
@foreach ($tenants as $tenant) @php diff --git a/apps/platform/resources/views/filament/pages/findings/findings-hygiene-report.blade.php b/apps/platform/resources/views/filament/pages/findings/findings-hygiene-report.blade.php index 4406ab2a..51857d66 100644 --- a/apps/platform/resources/views/filament/pages/findings/findings-hygiene-report.blade.php +++ b/apps/platform/resources/views/filament/pages/findings/findings-hygiene-report.blade.php @@ -69,10 +69,10 @@
@if (($scope['tenant_prefilter_source'] ?? 'none') === 'active_tenant_context') - Tenant prefilter from active context: + ManagedEnvironment prefilter from active context: {{ $scope['tenant_label'] }} @elseif (($scope['tenant_prefilter_source'] ?? 'none') === 'explicit_filter') - Tenant filter applied: + ManagedEnvironment filter applied: {{ $scope['tenant_label'] }} @else All visible tenants are currently included. diff --git a/apps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php b/apps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php index 456f50b7..f186c06b 100644 --- a/apps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php +++ b/apps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php @@ -18,7 +18,7 @@

- Review visible unassigned open findings across entitled tenants in one queue. Tenant context can narrow the view, but the intake scope stays fixed. + Review visible unassigned open findings across entitled tenants in one queue. ManagedEnvironment context can narrow the view, but the intake scope stays fixed.

@@ -69,10 +69,10 @@
@if (($scope['tenant_prefilter_source'] ?? 'none') === 'active_tenant_context') - Tenant prefilter from active context: + ManagedEnvironment prefilter from active context: {{ $scope['tenant_label'] }} @elseif (($scope['tenant_prefilter_source'] ?? 'none') === 'explicit_filter') - Tenant filter applied: + ManagedEnvironment filter applied: {{ $scope['tenant_label'] }} @else All visible tenants are currently included. diff --git a/apps/platform/resources/views/filament/pages/findings/my-findings-inbox.blade.php b/apps/platform/resources/views/filament/pages/findings/my-findings-inbox.blade.php index b8aea460..d4a4e4b3 100644 --- a/apps/platform/resources/views/filament/pages/findings/my-findings-inbox.blade.php +++ b/apps/platform/resources/views/filament/pages/findings/my-findings-inbox.blade.php @@ -18,7 +18,7 @@

- Review open assigned findings across visible tenants in one queue. Tenant context can narrow the view, but the personal assignment scope stays fixed. + Review open assigned findings across visible tenants in one queue. ManagedEnvironment context can narrow the view, but the personal assignment scope stays fixed.

@@ -57,10 +57,10 @@
@if (($scope['tenant_prefilter_source'] ?? 'none') === 'active_tenant_context') - Tenant prefilter from active context: + ManagedEnvironment prefilter from active context: {{ $scope['tenant_label'] }} @elseif (($scope['tenant_prefilter_source'] ?? 'none') === 'explicit_filter') - Tenant filter applied: + ManagedEnvironment filter applied: {{ $scope['tenant_label'] }} @else All visible tenants are currently included. diff --git a/apps/platform/resources/views/filament/pages/governance/decision-register.blade.php b/apps/platform/resources/views/filament/pages/governance/decision-register.blade.php index 63a83c6a..e736bee9 100644 --- a/apps/platform/resources/views/filament/pages/governance/decision-register.blade.php +++ b/apps/platform/resources/views/filament/pages/governance/decision-register.blade.php @@ -38,7 +38,7 @@ @if (filled($scope['tenant_label'] ?? null)) - Tenant: {{ $scope['tenant_label'] }} + ManagedEnvironment: {{ $scope['tenant_label'] }} @endif
diff --git a/apps/platform/resources/views/filament/pages/governance/governance-inbox.blade.php b/apps/platform/resources/views/filament/pages/governance/governance-inbox.blade.php index 2a6c5af9..b9d29f9d 100644 --- a/apps/platform/resources/views/filament/pages/governance/governance-inbox.blade.php +++ b/apps/platform/resources/views/filament/pages/governance/governance-inbox.blade.php @@ -39,7 +39,7 @@ @if (filled($scope['tenant_label'] ?? null)) - Tenant: {{ $scope['tenant_label'] }} + ManagedEnvironment: {{ $scope['tenant_label'] }} @endif diff --git a/apps/platform/resources/views/filament/pages/inventory-coverage.blade.php b/apps/platform/resources/views/filament/pages/inventory-coverage.blade.php index 573a9cd7..f6c00b10 100644 --- a/apps/platform/resources/views/filament/pages/inventory-coverage.blade.php +++ b/apps/platform/resources/views/filament/pages/inventory-coverage.blade.php @@ -9,7 +9,7 @@
- Tenant coverage truth + ManagedEnvironment coverage truth
diff --git a/apps/platform/resources/views/filament/pages/monitoring/evidence-overview.blade.php b/apps/platform/resources/views/filament/pages/monitoring/evidence-overview.blade.php index 8aa9b567..d43a61d6 100644 --- a/apps/platform/resources/views/filament/pages/monitoring/evidence-overview.blade.php +++ b/apps/platform/resources/views/filament/pages/monitoring/evidence-overview.blade.php @@ -2,7 +2,7 @@
-

Tenant and search query seeds can reopen this overview in a specific monitoring slice.

+

ManagedEnvironment and search query seeds can reopen this overview in a specific monitoring slice.

Compatible filters and sorting still restore from the last session, but row inspection always leaves the page for the canonical evidence detail.

diff --git a/apps/platform/resources/views/filament/pages/monitoring/operations.blade.php b/apps/platform/resources/views/filament/pages/monitoring/operations.blade.php index c3f3fa6d..f3d96af9 100644 --- a/apps/platform/resources/views/filament/pages/monitoring/operations.blade.php +++ b/apps/platform/resources/views/filament/pages/monitoring/operations.blade.php @@ -100,7 +100,7 @@

- Tenant prefilters and the selected operations tab remain shareable through the URL. Additional table filters still restore from the last compatible session state. + ManagedEnvironment prefilters and the selected operations tab remain shareable through the URL. Additional table filters still restore from the last compatible session state.

@if (($lifecycleSummary['likely_stale'] ?? 0) > 0 || ($lifecycleSummary['reconciled'] ?? 0) > 0) diff --git a/apps/platform/resources/views/filament/pages/tenant-diagnostics.blade.php b/apps/platform/resources/views/filament/pages/tenant-diagnostics.blade.php index fbeebc5e..fecf2b5d 100644 --- a/apps/platform/resources/views/filament/pages/tenant-diagnostics.blade.php +++ b/apps/platform/resources/views/filament/pages/tenant-diagnostics.blade.php @@ -1,7 +1,7 @@
-

Tenant diagnostics

+

ManagedEnvironment diagnostics

Identify common tenant configuration issues and apply safe repairs.

diff --git a/apps/platform/resources/views/filament/pages/workspaces/managed-tenants-landing.blade.php b/apps/platform/resources/views/filament/pages/workspaces/managed-tenants-landing.blade.php index 923056e1..1790f9a3 100644 --- a/apps/platform/resources/views/filament/pages/workspaces/managed-tenants-landing.blade.php +++ b/apps/platform/resources/views/filament/pages/workspaces/managed-tenants-landing.blade.php @@ -45,7 +45,7 @@ class="inline-flex items-center gap-1.5 text-sm text-gray-500 transition-colors
@else - {{-- Tenant list --}} + {{-- ManagedEnvironment list --}}
{{-- Header row --}}
@@ -70,7 +70,7 @@ class="inline-flex items-center gap-1.5 text-sm text-gray-500 transition-colors
- {{-- Tenant cards --}} + {{-- ManagedEnvironment cards --}}
@foreach ($tenants as $tenant) @php diff --git a/apps/platform/resources/views/filament/partials/context-bar.blade.php b/apps/platform/resources/views/filament/partials/context-bar.blade.php index 2216dafb..7e997c85 100644 --- a/apps/platform/resources/views/filament/partials/context-bar.blade.php +++ b/apps/platform/resources/views/filament/partials/context-bar.blade.php @@ -1,7 +1,7 @@ @php use App\Filament\Pages\ChooseTenant; use App\Filament\Pages\ChooseWorkspace; - use App\Models\Tenant; + use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\OperateHub\OperateHubShell; use App\Support\Workspaces\WorkspaceContext; @@ -18,16 +18,16 @@ $tenants = collect(); if ($user instanceof User && $workspace) { $tenants = collect($user->getTenants(Filament::getCurrentOrDefaultPanel())) - ->filter(fn ($tenant): bool => $tenant instanceof Tenant && (int) $tenant->workspace_id === (int) $workspace->getKey()) + ->filter(fn ($tenant): bool => $tenant instanceof ManagedEnvironment && (int) $tenant->workspace_id === (int) $workspace->getKey()) ->values(); } $currentTenant = $resolvedContext->tenant; - $currentTenantId = $currentTenant instanceof Tenant ? (int) $currentTenant->getKey() : null; - $currentTenantName = $currentTenant instanceof Tenant ? $currentTenant->getFilamentName() : null; + $currentTenantId = $currentTenant instanceof ManagedEnvironment ? (int) $currentTenant->getKey() : null; + $currentTenantName = $currentTenant instanceof ManagedEnvironment ? $currentTenant->getFilamentName() : null; $lastTenantId = $workspaceContext->lastTenantId(request()); - $canClearTenantContext = $currentTenant instanceof Tenant || $lastTenantId !== null; + $canClearTenantContext = $currentTenant instanceof ManagedEnvironment || $lastTenantId !== null; @endphp @php @@ -121,7 +121,7 @@ class="flex items-center gap-2 rounded-lg px-3 py-2 text-sm text-gray-700 transi @if ($workspace)
- {{-- Tenant section --}} + {{-- ManagedEnvironment section --}}
@@ -183,7 +183,7 @@ class="fi-input fi-text-input w-full"
@csrf - +
-
Tenant
+
ManagedEnvironment
{{ $run->tenant?->name ?? 'Tenantless' }}
diff --git a/apps/platform/resources/views/filament/system/widgets/control-tower-top-offenders.blade.php b/apps/platform/resources/views/filament/system/widgets/control-tower-top-offenders.blade.php index 25fbbc5c..1bec056e 100644 --- a/apps/platform/resources/views/filament/system/widgets/control-tower-top-offenders.blade.php +++ b/apps/platform/resources/views/filament/system/widgets/control-tower-top-offenders.blade.php @@ -18,7 +18,7 @@ Workspace - Tenant + ManagedEnvironment Operation Failed diff --git a/apps/platform/resources/views/filament/widgets/tenant/admin-roles-summary.blade.php b/apps/platform/resources/views/filament/widgets/tenant/admin-roles-summary.blade.php index 3fbe6cba..560fcaf8 100644 --- a/apps/platform/resources/views/filament/widgets/tenant/admin-roles-summary.blade.php +++ b/apps/platform/resources/views/filament/widgets/tenant/admin-roles-summary.blade.php @@ -1,5 +1,5 @@ @php - /** @var ?\App\Models\Tenant $tenant */ + /** @var ?\App\Models\ManagedEnvironment $tenant */ /** @var ?array $reportSummary */ /** @var ?string $lastScanAt */ /** @var int $highPrivilegeCount */ diff --git a/apps/platform/resources/views/filament/widgets/tenant/recent-operations-summary.blade.php b/apps/platform/resources/views/filament/widgets/tenant/recent-operations-summary.blade.php index 5112bd88..c4e90036 100644 --- a/apps/platform/resources/views/filament/widgets/tenant/recent-operations-summary.blade.php +++ b/apps/platform/resources/views/filament/widgets/tenant/recent-operations-summary.blade.php @@ -1,5 +1,5 @@ @php - /** @var ?\App\Models\Tenant $tenant */ + /** @var ?\App\Models\ManagedEnvironment $tenant */ /** @var \Illuminate\Support\Collection $runs */ /** @var string $operationsIndexUrl */ /** @var string $operationsIndexLabel */ diff --git a/apps/platform/resources/views/filament/widgets/tenant/tenant-archived-banner.blade.php b/apps/platform/resources/views/filament/widgets/tenant/tenant-archived-banner.blade.php index 1916f474..39ac714a 100644 --- a/apps/platform/resources/views/filament/widgets/tenant/tenant-archived-banner.blade.php +++ b/apps/platform/resources/views/filament/widgets/tenant/tenant-archived-banner.blade.php @@ -1,5 +1,5 @@ @php - /** @var ?\App\Models\Tenant $tenant */ + /** @var ?\App\Models\ManagedEnvironment $tenant */ /** @var ?\App\Support\Tenants\TenantLifecyclePresentation $presentation */ @endphp @@ -7,7 +7,7 @@ @if ($tenant?->trashed())
-
Tenant {{ strtolower($presentation?->label ?? 'Archived') }}
+
ManagedEnvironment {{ strtolower($presentation?->label ?? 'Archived') }}
{{ \App\Support\Rbac\UiTooltips::TENANT_ARCHIVED }}
{{ $presentation?->longDescription }} diff --git a/apps/platform/resources/views/filament/widgets/tenant/tenant-review-pack-card.blade.php b/apps/platform/resources/views/filament/widgets/tenant/tenant-review-pack-card.blade.php index 8aa2d392..c17d17a5 100644 --- a/apps/platform/resources/views/filament/widgets/tenant/tenant-review-pack-card.blade.php +++ b/apps/platform/resources/views/filament/widgets/tenant/tenant-review-pack-card.blade.php @@ -3,7 +3,7 @@ use App\Support\Badges\BadgeDomain; use App\Support\ReviewPackStatus; - /** @var ?\App\Models\Tenant $tenant */ + /** @var ?\App\Models\ManagedEnvironment $tenant */ /** @var ?\App\Models\ReviewPack $pack */ /** @var ?ReviewPackStatus $statusEnum */ /** @var ?string $pollingInterval */ diff --git a/apps/platform/routes/console.php b/apps/platform/routes/console.php index 8434e4a5..b88d6e9e 100644 --- a/apps/platform/routes/console.php +++ b/apps/platform/routes/console.php @@ -3,7 +3,7 @@ use App\Jobs\PruneOldOperationRunsJob; use App\Jobs\ReconcileAdapterRunsJob; use App\Jobs\ScanEntraAdminRolesJob; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Inspiring; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Schedule; @@ -55,7 +55,7 @@ ->withoutOverlapping(); Schedule::call(function (): void { - $tenants = Tenant::query() + $tenants = ManagedEnvironment::query() ->whereHas('providerConnections', function ($q): void { $q->where('status', 'connected'); }) diff --git a/apps/platform/routes/web.php b/apps/platform/routes/web.php index 0435c31a..2cdb990f 100644 --- a/apps/platform/routes/web.php +++ b/apps/platform/routes/web.php @@ -13,7 +13,7 @@ use App\Http\Controllers\TenantOnboardingController; use App\Http\Middleware\SuppressDebugbarForSmokeRequests; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -89,18 +89,17 @@ 120, ); -$resolveSmokeTenant = static function (?string $identifier): ?Tenant { +$resolveSmokeTenant = static function (?string $identifier): ?ManagedEnvironment { $identifier = trim((string) $identifier); if ($identifier === '') { return null; } - return Tenant::query() + return ManagedEnvironment::query() ->withTrashed() ->where(function ($query) use ($identifier): void { - $query->where('external_id', $identifier) - ->orWhere('tenant_id', $identifier); + $query->where('slug', $identifier); if (ctype_digit($identifier)) { $query->orWhereKey((int) $identifier); @@ -109,8 +108,8 @@ ->first(); }; -$resolveSmokeWorkspace = static function (?string $identifier, ?Tenant $tenant = null): ?Workspace { - if ($tenant instanceof Tenant) { +$resolveSmokeWorkspace = static function (?string $identifier, ?ManagedEnvironment $tenant = null): ?Workspace { + if ($tenant instanceof ManagedEnvironment) { return Workspace::query()->whereKey($tenant->workspace_id)->first(); } @@ -131,9 +130,9 @@ ->first(); }; -$resolveSmokeRedirect = static function (?string $redirect, ?Tenant $tenant = null): string { - $fallback = $tenant instanceof Tenant && ! $tenant->trashed() - ? '/admin/t/'.$tenant->external_id +$resolveSmokeRedirect = static function (?string $redirect, ?ManagedEnvironment $tenant = null): string { + $fallback = $tenant instanceof ManagedEnvironment && ! $tenant->trashed() + ? '/admin/t/'.$tenant->slug : '/admin'; $redirect = trim((string) $redirect); @@ -160,7 +159,7 @@ return $path.$query.$fragment; }; -$resolveSmokeUser = static function (?string $email, ?Workspace $workspace = null, ?Tenant $tenant = null): ?User { +$resolveSmokeUser = static function (?string $email, ?Workspace $workspace = null, ?ManagedEnvironment $tenant = null): ?User { $email = trim((string) $email); if ($email !== '') { @@ -171,7 +170,7 @@ $scopedWorkspace = $workspace; - if (! $scopedWorkspace instanceof Workspace && $tenant instanceof Tenant) { + if (! $scopedWorkspace instanceof Workspace && $tenant instanceof ManagedEnvironment) { $scopedWorkspace = Workspace::query()->whereKey($tenant->workspace_id)->first(); } @@ -190,9 +189,9 @@ ->whereHas('workspaceMemberships', function ($query) use ($scopedWorkspace): void { $query->where('workspace_id', (int) $scopedWorkspace->getKey()); }) - ->when($tenant instanceof Tenant, function ($query) use ($tenant): void { + ->when($tenant instanceof ManagedEnvironment, function ($query) use ($tenant): void { $query->whereHas('tenantMemberships', function ($membershipQuery) use ($tenant): void { - $membershipQuery->where('tenant_id', (int) $tenant->getKey()); + $membershipQuery->where('managed_environment_id', (int) $tenant->getKey()); }); }) ->with(['workspaceMemberships' => function ($query) use ($scopedWorkspace): void { @@ -200,7 +199,7 @@ }]) ->get() ->filter(function (User $user) use ($tenant): bool { - return ! $tenant instanceof Tenant || $user->canAccessTenant($tenant); + return ! $tenant instanceof ManagedEnvironment || $user->canAccessTenant($tenant); }) ->sortBy(function (User $user) use ($rolePriority): array { $role = $user->workspaceMemberships->first()?->role; @@ -245,7 +244,7 @@ abort_unless($workspace instanceof Workspace, 404); abort_unless($workspaceContext->isMember($user, $workspace), 404); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { abort_unless((int) $tenant->workspace_id === (int) $workspace->getKey(), 404); abort_unless($user->canAccessTenant($tenant), 404); } @@ -259,7 +258,7 @@ $workspaceContext->setCurrentWorkspace($workspace, $user, $request); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $workspaceContext->rememberTenantContext($tenant, $request); } else { $workspaceContext->clearRememberedTenantContext($request); @@ -276,7 +275,7 @@ $fixture = config('tenantpilot.backup_health.browser_smoke_fixture'); $defaultEmail = is_array($fixture) ? data_get($fixture, 'user.email') : null; $defaultTenant = is_array($fixture) - ? (data_get($fixture, 'blocked_drillthrough.tenant_external_id') ?? data_get($fixture, 'blocked_drillthrough.tenant_id')) + ? (data_get($fixture, 'blocked_drillthrough.tenant_external_id') ?? data_get($fixture, 'blocked_drillthrough.managed_environment_id')) : null; $defaultWorkspace = is_array($fixture) ? data_get($fixture, 'workspace.slug') : null; @@ -295,7 +294,7 @@ $fixture = config('tenantpilot.backup_health.browser_smoke_fixture'); $userEmail = is_array($fixture) ? data_get($fixture, 'user.email') : null; $tenantRouteKey = is_array($fixture) - ? (data_get($fixture, 'blocked_drillthrough.tenant_id') ?? data_get($fixture, 'blocked_drillthrough.tenant_external_id')) + ? (data_get($fixture, 'blocked_drillthrough.managed_environment_id') ?? data_get($fixture, 'blocked_drillthrough.tenant_external_id')) : null; abort_unless(is_string($userEmail) && $userEmail !== '', 404); @@ -351,7 +350,7 @@ return app(OnboardingDraftResolver::class)->resolve((int) $value, $user, $workspace); }); -$authorizeManagedTenantRoute = function (Tenant $tenant, Request $request): void { +$authorizeManagedTenantRoute = function (ManagedEnvironment $tenant, Request $request): void { $user = $request->user(); abort_unless($user instanceof User, 403); @@ -442,32 +441,32 @@ FilamentAuthenticate::class, 'ensure-workspace-selected', ]) - ->prefix('/admin/tenants/{tenant:external_id}/provider-connections') + ->prefix('/admin/tenants/{tenant:slug}/provider-connections') ->group(function () use ($authorizeManagedTenantRoute): void { - Route::get('/', function (Tenant $tenant, Request $request) use ($authorizeManagedTenantRoute) { + Route::get('/', function (ManagedEnvironment $tenant, Request $request) use ($authorizeManagedTenantRoute) { $authorizeManagedTenantRoute($tenant, $request); - return redirect()->to('/admin/provider-connections?tenant_id='.$tenant->external_id); + return redirect()->to('/admin/provider-connections?managed_environment_id='.$tenant->external_id); })->name('admin.provider-connections.legacy-index'); - Route::get('/create', function (Tenant $tenant, Request $request) use ($authorizeManagedTenantRoute) { + Route::get('/create', function (ManagedEnvironment $tenant, Request $request) use ($authorizeManagedTenantRoute) { $authorizeManagedTenantRoute($tenant, $request); - return redirect()->to('/admin/provider-connections/create?tenant_id='.$tenant->external_id); + return redirect()->to('/admin/provider-connections/create?managed_environment_id='.$tenant->external_id); })->name('admin.provider-connections.legacy-create'); - Route::get('/{record}/edit', function (Tenant $tenant, mixed $record, Request $request) use ($authorizeManagedTenantRoute) { + Route::get('/{record}/edit', function (ManagedEnvironment $tenant, mixed $record, Request $request) use ($authorizeManagedTenantRoute) { $authorizeManagedTenantRoute($tenant, $request); $connection = ProviderConnection::query() ->whereKey((int) $record) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('workspace_id', (int) $tenant->workspace_id) ->first(); abort_unless($connection instanceof ProviderConnection, 404); - return redirect()->to('/admin/provider-connections/'.$connection->getKey().'/edit?tenant_id='.$tenant->external_id); + return redirect()->to('/admin/provider-connections/'.$connection->getKey().'/edit?managed_environment_id='.$tenant->external_id); })->name('admin.provider-connections.legacy-edit'); }); diff --git a/apps/platform/tests/Browser/Dashboard/TenantDashboardProductizationSmokeTest.php b/apps/platform/tests/Browser/Dashboard/TenantDashboardProductizationSmokeTest.php index fc29a7e6..2eca432f 100644 --- a/apps/platform/tests/Browser/Dashboard/TenantDashboardProductizationSmokeTest.php +++ b/apps/platform/tests/Browser/Dashboard/TenantDashboardProductizationSmokeTest.php @@ -18,7 +18,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'severity' => Finding::SEVERITY_HIGH, @@ -26,7 +26,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, @@ -35,14 +35,14 @@ ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Browser smoke backup', 'item_count' => 1, 'completed_at' => now()->subMinutes(30), ]); BackupItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'payload' => ['id' => 'browser-smoke-policy'], 'metadata' => [], @@ -50,7 +50,7 @@ ]); ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'is_default' => true, ]); diff --git a/apps/platform/tests/Browser/OnboardingDraftRefreshTest.php b/apps/platform/tests/Browser/OnboardingDraftRefreshTest.php index 6bfea3eb..9b55f0a4 100644 --- a/apps/platform/tests/Browser/OnboardingDraftRefreshTest.php +++ b/apps/platform/tests/Browser/OnboardingDraftRefreshTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\OperationRunOutcome; @@ -16,11 +16,11 @@ it('restores the canonical draft route, derived stage, and transient secret inputs after a refresh', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '20202020-2020-2020-2020-202020202020', - 'name' => 'Browser Refresh Tenant', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '20202020-2020-2020-2020-202020202020', + 'name' => 'Browser Refresh ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(['name' => 'Browser Owner']); @@ -34,9 +34,9 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Browser platform connection', 'is_default' => true, 'consent_status' => 'granted', @@ -49,7 +49,7 @@ 'updated_by' => $user, 'current_step' => 'connection', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'environment' => 'prod', 'provider_connection_id' => (int) $connection->getKey(), @@ -94,11 +94,11 @@ it('auto-refreshes verification status and blocked assist visibility without a manual refresh', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '50505050-5050-5050-5050-505050505050', - 'name' => 'Browser Poll Verification Tenant', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '50505050-5050-5050-5050-505050505050', + 'name' => 'Browser Poll Verification ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(['name' => 'Polling Owner']); @@ -112,9 +112,9 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Polling verification connection', 'is_default' => true, 'consent_status' => 'granted', @@ -122,14 +122,14 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Running->value, 'outcome' => OperationRunOutcome::Pending->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], ], @@ -142,7 +142,7 @@ 'updated_by' => $user, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -170,7 +170,7 @@ 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ @@ -198,11 +198,11 @@ it('auto-refreshes bootstrap checkpoint summaries without a manual refresh', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '60606060-6060-6060-6060-606060606060', - 'name' => 'Browser Poll Bootstrap Tenant', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '60606060-6060-6060-6060-606060606060', + 'name' => 'Browser Poll Bootstrap ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(['name' => 'Bootstrap Poll Owner']); @@ -216,9 +216,9 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Polling bootstrap connection', 'is_default' => true, 'consent_status' => 'granted', @@ -226,7 +226,7 @@ $verificationRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -234,7 +234,7 @@ 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], ], @@ -252,7 +252,7 @@ 'updated_by' => $user, 'current_step' => 'bootstrap', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $verificationRun->getKey(), diff --git a/apps/platform/tests/Browser/OnboardingDraftVerificationResumeTest.php b/apps/platform/tests/Browser/OnboardingDraftVerificationResumeTest.php index b361e5a9..665a89b0 100644 --- a/apps/platform/tests/Browser/OnboardingDraftVerificationResumeTest.php +++ b/apps/platform/tests/Browser/OnboardingDraftVerificationResumeTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantPermission; use App\Models\User; use App\Models\Workspace; @@ -17,11 +17,11 @@ it('keeps stale verification warnings and the selected provider connection stable after refresh', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '30303030-3030-3030-3030-303030303030', - 'name' => 'Stale Verification Tenant', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '30303030-3030-3030-3030-303030303030', + 'name' => 'Stale Verification ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(['name' => 'Verification Owner']); @@ -35,9 +35,9 @@ $verifiedConnection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Previously verified connection', 'is_default' => true, 'consent_status' => 'granted', @@ -45,9 +45,9 @@ $selectedConnection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'dummy', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Current selected connection', 'is_default' => false, 'consent_status' => 'granted', @@ -55,14 +55,14 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'context' => [ 'provider_connection_id' => (int) $verifiedConnection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ], ], ]); @@ -74,7 +74,7 @@ 'updated_by' => $user, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $selectedConnection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -107,11 +107,11 @@ it('preserves bootstrap revisit state and blocked activation guards after refresh', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '40404040-4040-4040-4040-404040404040', - 'name' => 'Blocked Review Tenant', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '40404040-4040-4040-4040-404040404040', + 'name' => 'Blocked Review ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(['name' => 'Review Owner']); @@ -125,9 +125,9 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Blocked review connection', 'is_default' => true, 'consent_status' => 'granted', @@ -135,14 +135,14 @@ $verificationRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ @@ -173,7 +173,7 @@ 'updated_by' => $user, 'current_step' => 'complete', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $verificationRun->getKey(), @@ -212,7 +212,7 @@ ); $tenant->forceFill([ - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ])->save(); $workspace = $tenant->workspace()->firstOrFail(); @@ -240,7 +240,7 @@ foreach (array_slice($permissionKeys, 1) as $key) { TenantPermission::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'permission_key' => $key, 'status' => 'granted', @@ -251,9 +251,9 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Browser assist connection', 'is_default' => true, 'consent_status' => 'granted', @@ -261,14 +261,14 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ @@ -294,7 +294,7 @@ 'updated_by' => $user, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -333,7 +333,7 @@ ); $tenant->forceFill([ - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ])->save(); $workspace = $tenant->workspace()->firstOrFail(); @@ -359,7 +359,7 @@ foreach (array_slice($permissionKeys, 1) as $key) { TenantPermission::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'permission_key' => $key, 'status' => 'granted', @@ -370,9 +370,9 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Browser next-step connection', 'is_default' => true, 'consent_status' => 'granted', @@ -380,14 +380,14 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ @@ -422,7 +422,7 @@ 'updated_by' => $user, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), diff --git a/apps/platform/tests/Browser/OpsUx/OperationActivityFeedbackSmokeTest.php b/apps/platform/tests/Browser/OpsUx/OperationActivityFeedbackSmokeTest.php index 08814fc5..0c616eb3 100644 --- a/apps/platform/tests/Browser/OpsUx/OperationActivityFeedbackSmokeTest.php +++ b/apps/platform/tests/Browser/OpsUx/OperationActivityFeedbackSmokeTest.php @@ -7,7 +7,7 @@ use App\Models\Finding; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -15,7 +15,7 @@ uses(RefreshDatabase::class); -function operationActivityFeedbackSmokeLoginUrl(User $user, Tenant $tenant, string $redirect = ''): string +function operationActivityFeedbackSmokeLoginUrl(User $user, ManagedEnvironment $tenant, string $redirect = ''): string { return route('admin.local.smoke-login', array_filter([ 'email' => $user->email, @@ -29,7 +29,7 @@ function operationActivityFeedbackSmokeLoginUrl(User $user, Tenant $tenant, stri [$user, $tenant] = createUserWithTenant(role: 'owner'); InventoryItem::factory()->count(3)->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Browser Inventory Item', 'policy_type' => 'deviceConfiguration', @@ -43,7 +43,7 @@ function operationActivityFeedbackSmokeLoginUrl(User $user, Tenant $tenant, stri ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -219,7 +219,7 @@ function operationActivityFeedbackSmokeLoginUrl(User $user, Tenant $tenant, stri [$user, $tenant] = createUserWithTenant(role: 'owner'); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Browser Progress Inventory Item', 'policy_type' => 'deviceConfiguration', @@ -228,7 +228,7 @@ function operationActivityFeedbackSmokeLoginUrl(User $user, Tenant $tenant, stri ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'baseline_capture', @@ -274,7 +274,7 @@ function operationActivityFeedbackSmokeLoginUrl(User $user, Tenant $tenant, stri [$user, $tenant] = createUserWithTenant(role: 'owner'); $failedRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -323,7 +323,7 @@ function operationActivityFeedbackSmokeLoginUrl(User $user, Tenant $tenant, stri ->and($failedRun->outcome)->toBe('failed'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', diff --git a/apps/platform/tests/Browser/PortfolioCompare/CrossTenantPromotionExecutionSmokeTest.php b/apps/platform/tests/Browser/PortfolioCompare/CrossTenantPromotionExecutionSmokeTest.php index 84df205c..527f2004 100644 --- a/apps/platform/tests/Browser/PortfolioCompare/CrossTenantPromotionExecutionSmokeTest.php +++ b/apps/platform/tests/Browser/PortfolioCompare/CrossTenantPromotionExecutionSmokeTest.php @@ -12,7 +12,7 @@ pest()->browser()->timeout(15_000); -it('smokes queued promotion execution handoff from compare page into the operation viewer', function (): void { +it('smokes queued promotion execution and the canonical operation viewer', function (): void { $fixture = $this->makeCrossTenantCompareFixture(); $this->createPortfolioCompareSubject( @@ -42,13 +42,11 @@ ->click('Execute promotion') ->waitForText('Queue promotion') ->click('Queue promotion') - ->waitForText('Promotion execution queued') - ->assertSee('Open operation'); + ->waitForText('Promotion execution queued'); $run = OperationRun::query()->latest('id')->firstOrFail(); - $page - ->click('Open operation') + visit(OperationRunLinks::tenantlessView($run)) ->waitForText(OperationRunLinks::identifier((int) $run->getKey())) ->assertRoute('admin.operations.view', ['run' => (int) $run->getKey()]) ->assertNoJavaScriptErrors() diff --git a/apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php b/apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php index 352d4a7e..af65be06 100644 --- a/apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php +++ b/apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\TenantReviewResource; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\TenantReviewStatus; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -19,7 +19,7 @@ }); it('smokes the customer review workspace handoff from tenant review detail', function (): void { - $tenantPublished = Tenant::factory()->create(['name' => 'Published Tenant']); + $tenantPublished = ManagedEnvironment::factory()->create(['name' => 'Published ManagedEnvironment']); [$user, $tenantPublished] = createUserWithTenant( tenant: $tenantPublished, role: 'owner', @@ -27,9 +27,9 @@ ); $user->forceFill(['preferred_locale' => 'de'])->save(); - $tenantWithoutPublished = Tenant::factory()->create([ + $tenantWithoutPublished = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantPublished->workspace_id, - 'name' => 'No Published Tenant', + 'name' => 'No Published ManagedEnvironment', ]); createUserWithTenant( @@ -59,7 +59,7 @@ Storage::disk('exports')->put('review-packs/customer-review-workspace-smoke.zip', 'PK-test'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenantPublished->getKey(), + 'managed_environment_id' => (int) $tenantPublished->getKey(), 'workspace_id' => (int) $tenantPublished->workspace_id, 'tenant_review_id' => (int) $publishedReview->getKey(), 'evidence_snapshot_id' => (int) $publishedSnapshot->getKey(), @@ -89,7 +89,7 @@ ->assertSee('Governance-Paket') ->assertSee('Status') ->assertSee('Nachweise') - ->assertSee('Prüfen Sie für jeden berechtigten Tenant den executive-fähigen Status des Governance-Pakets') + ->assertSee('Prüfen Sie für jeden berechtigten ManagedEnvironment den executive-fähigen Status des Governance-Pakets') ->assertSee('Dieser Workspace fasst die aktuelle Review- und Nachweislage für die Service-Auslieferung zusammen. Er ersetzt weder ein formales Auditurteil noch eine Zertifizierung oder rechtliche Attestierung.') ->assertSee('Teilweise') ->assertSee('Prüfung erforderlich') @@ -103,8 +103,8 @@ ->assertDontSee('Publish review') ->assertDontSee('Refresh review') ->click('Filter löschen') - ->waitForText('Published Tenant') - ->assertDontSee('No Published Tenant') + ->waitForText('Published ManagedEnvironment') + ->assertDontSee('No Published ManagedEnvironment') ->assertDontSee('No published review available yet') ->click('Review öffnen') ->waitForText('Ergebniszusammenfassung') diff --git a/apps/platform/tests/Browser/Spec172DeferredOperatorSurfacesSmokeTest.php b/apps/platform/tests/Browser/Spec172DeferredOperatorSurfacesSmokeTest.php index 4276249b..bde09d77 100644 --- a/apps/platform/tests/Browser/Spec172DeferredOperatorSurfacesSmokeTest.php +++ b/apps/platform/tests/Browser/Spec172DeferredOperatorSurfacesSmokeTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\TenantResource\Pages\ViewTenant; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -37,13 +37,13 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Blocked->value, 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ], 'verification_report' => $report, ], @@ -98,9 +98,9 @@ it('smokes onboarding verify step without a verification run', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(['name' => 'Spec172 Browser Owner']); @@ -114,17 +114,17 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -149,9 +149,9 @@ it('smokes onboarding active verification state with refresh and current-run inspection', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(['name' => 'Spec172 Active Browser Owner']); @@ -165,23 +165,23 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Running->value, 'outcome' => OperationRunOutcome::Pending->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], ], @@ -189,8 +189,8 @@ TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -215,11 +215,11 @@ it('smokes onboarding completed verification details with secondary links revealed only in technical details', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '17217217-2172-4172-9172-172172172172', + 'managed_environment_id' => '17217217-2172-4172-9172-172172172172', 'external_id' => 'browser-spec172-complete', - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(['name' => 'Spec172 Completed Browser Owner']); @@ -233,9 +233,9 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Spec172 completed connection', 'is_default' => true, 'consent_status' => 'granted', @@ -243,14 +243,14 @@ $previousRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', []), ], @@ -273,14 +273,14 @@ $currentRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => $report, @@ -289,8 +289,8 @@ TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), diff --git a/apps/platform/tests/Browser/Spec174EvidenceFreshnessPublicationTrustSmokeTest.php b/apps/platform/tests/Browser/Spec174EvidenceFreshnessPublicationTrustSmokeTest.php index 7298480a..b0146e0a 100644 --- a/apps/platform/tests/Browser/Spec174EvidenceFreshnessPublicationTrustSmokeTest.php +++ b/apps/platform/tests/Browser/Spec174EvidenceFreshnessPublicationTrustSmokeTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\EvidenceSnapshotResource; use App\Filament\Resources\ReviewPackResource; use App\Filament\Resources\TenantReviewResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\TenantReviewCompletenessState; use App\Support\TenantReviewStatus; use App\Support\Workspaces\WorkspaceContext; @@ -16,12 +16,12 @@ pest()->browser()->timeout(15_000); it('smokes tenant-scoped evidence freshness and publication trust surfaces', function (): void { - $staleTenant = Tenant::factory()->create(['name' => 'Browser Smoke Stale Tenant']); + $staleTenant = ManagedEnvironment::factory()->create(['name' => 'Browser Smoke Stale ManagedEnvironment']); [$user, $staleTenant] = createUserWithTenant(tenant: $staleTenant, role: 'owner'); - $partialTenant = Tenant::factory()->create([ + $partialTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $staleTenant->workspace_id, - 'name' => 'Browser Smoke Partial Tenant', + 'name' => 'Browser Smoke Partial ManagedEnvironment', ]); createUserWithTenant(tenant: $partialTenant, user: $user, role: 'owner'); @@ -112,18 +112,18 @@ }); it('smokes canonical evidence and review trust surfaces', function (): void { - $staleTenant = Tenant::factory()->create(['name' => 'Browser Canonical Stale Tenant']); + $staleTenant = ManagedEnvironment::factory()->create(['name' => 'Browser Canonical Stale ManagedEnvironment']); [$user, $staleTenant] = createUserWithTenant(tenant: $staleTenant, role: 'owner'); - $partialTenant = Tenant::factory()->create([ + $partialTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $staleTenant->workspace_id, - 'name' => 'Browser Canonical Partial Tenant', + 'name' => 'Browser Canonical Partial ManagedEnvironment', ]); createUserWithTenant(tenant: $partialTenant, user: $user, role: 'owner'); - $freshTenant = Tenant::factory()->create([ + $freshTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $staleTenant->workspace_id, - 'name' => 'Browser Canonical Fresh Tenant', + 'name' => 'Browser Canonical Fresh ManagedEnvironment', ]); createUserWithTenant(tenant: $freshTenant, user: $user, role: 'owner'); @@ -177,16 +177,16 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $staleTenant->workspace_id); visit(route('admin.evidence.overview')) - ->waitForText('Browser Canonical Stale Tenant') + ->waitForText('Browser Canonical Stale ManagedEnvironment') ->assertNoJavaScriptErrors() - ->assertSee('Browser Canonical Fresh Tenant') + ->assertSee('Browser Canonical Fresh ManagedEnvironment') ->assertSee('Refresh the stale evidence before relying on this snapshot') ->assertSee('Create a current review from this evidence snapshot'); visit('/admin/reviews') - ->waitForText('Browser Canonical Stale Tenant') + ->waitForText('Browser Canonical Stale ManagedEnvironment') ->assertNoJavaScriptErrors() - ->assertSee('Browser Canonical Partial Tenant') + ->assertSee('Browser Canonical Partial ManagedEnvironment') ->assertSee('Internal only') ->assertSee('Refresh the evidence basis before publishing this review') ->assertSee('Complete the evidence basis before publishing this review') diff --git a/apps/platform/tests/Browser/Spec177InventoryCoverageTruthSmokeTest.php b/apps/platform/tests/Browser/Spec177InventoryCoverageTruthSmokeTest.php index 1a815a6c..88fe62ef 100644 --- a/apps/platform/tests/Browser/Spec177InventoryCoverageTruthSmokeTest.php +++ b/apps/platform/tests/Browser/Spec177InventoryCoverageTruthSmokeTest.php @@ -6,18 +6,18 @@ use App\Filament\Resources\InventoryItemResource; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunLinks; use App\Support\OperationRunOutcome; use App\Support\Workspaces\WorkspaceContext; pest()->browser()->timeout(15_000); -function seedSpec177InventoryCoverageTruthFixtures(Tenant $tenant): OperationRun +function seedSpec177InventoryCoverageTruthFixtures(ManagedEnvironment $tenant): OperationRun { foreach (range(1, 130) as $index) { InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => sprintf('Browser Inventory %02d', $index), 'policy_type' => 'deviceConfiguration', 'external_id' => sprintf('browser-inventory-%02d', $index), @@ -27,7 +27,7 @@ function seedSpec177InventoryCoverageTruthFixtures(Tenant $tenant): OperationRun } InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Browser Conditional Access', 'policy_type' => 'conditionalAccessPolicy', 'external_id' => 'browser-conditional-access', @@ -50,11 +50,11 @@ function seedSpec177InventoryCoverageTruthFixtures(Tenant $tenant): OperationRun ); } -function seedSpec177InventoryItemFilterPaginationFixtures(Tenant $tenant): void +function seedSpec177InventoryItemFilterPaginationFixtures(ManagedEnvironment $tenant): void { foreach (range(1, 45) as $index) { InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => sprintf('Windows Fresh Device %02d', $index), 'policy_type' => 'deviceConfiguration', 'external_id' => sprintf('windows-fresh-device-%02d', $index), @@ -65,7 +65,7 @@ function seedSpec177InventoryItemFilterPaginationFixtures(Tenant $tenant): void foreach (range(1, 3) as $index) { InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => sprintf('Mac Fresh Device %02d', $index), 'policy_type' => 'deviceConfiguration', 'external_id' => sprintf('mac-fresh-device-%02d', $index), @@ -76,7 +76,7 @@ function seedSpec177InventoryItemFilterPaginationFixtures(Tenant $tenant): void foreach (range(1, 3) as $index) { InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => sprintf('Conditional Access Fresh %02d', $index), 'policy_type' => 'conditionalAccessPolicy', 'external_id' => sprintf('conditional-access-fresh-%02d', $index), @@ -87,7 +87,7 @@ function seedSpec177InventoryItemFilterPaginationFixtures(Tenant $tenant): void foreach (range(46, 55) as $index) { InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => sprintf('Windows Fresh Device %02d', $index), 'policy_type' => 'deviceConfiguration', 'external_id' => sprintf('windows-fresh-device-%02d', $index), @@ -98,7 +98,7 @@ function seedSpec177InventoryItemFilterPaginationFixtures(Tenant $tenant): void foreach (range(1, 3) as $index) { InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => sprintf('Windows Stale Device %02d', $index), 'policy_type' => 'deviceConfiguration', 'external_id' => sprintf('windows-stale-device-%02d', $index), @@ -109,8 +109,8 @@ function seedSpec177InventoryItemFilterPaginationFixtures(Tenant $tenant): void } it('smokes inventory coverage truth surfaces with filters, pagination, and run drill-through', function (): void { - $tenant = Tenant::factory()->create([ - 'name' => 'Spec177 Browser Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'Spec177 Browser ManagedEnvironment', 'external_id' => 'spec177-browser-tenant', ]); @@ -147,7 +147,7 @@ function seedSpec177InventoryItemFilterPaginationFixtures(Tenant $tenant): void $page = visit($coverageUrl); $page - ->waitForText('Tenant coverage truth') + ->waitForText('ManagedEnvironment coverage truth') ->assertNoJavaScriptErrors() ->assertSee('Latest coverage-bearing sync completed') ->assertSee('Open basis run') @@ -167,7 +167,7 @@ function seedSpec177InventoryItemFilterPaginationFixtures(Tenant $tenant): void ->assertSee('Need follow-up'); visit($coverageUrl) - ->waitForText('Tenant coverage truth') + ->waitForText('ManagedEnvironment coverage truth') ->assertNoJavaScriptErrors() ->assertScript("Array.from(document.querySelectorAll('a[href=\"{$inventoryItemsUrl}\"]')).some((element) => element.textContent?.includes('Open inventory items'))", true); @@ -178,8 +178,8 @@ function seedSpec177InventoryItemFilterPaginationFixtures(Tenant $tenant): void }); it('smokes inventory item pagination with stable browser slices', function (): void { - $tenant = Tenant::factory()->create([ - 'name' => 'Spec177 Browser Filter Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'Spec177 Browser Filter ManagedEnvironment', 'external_id' => 'spec177-browser-filter-tenant', ]); diff --git a/apps/platform/tests/Browser/Spec192RecordPageHeaderDisciplineSmokeTest.php b/apps/platform/tests/Browser/Spec192RecordPageHeaderDisciplineSmokeTest.php index 745684a5..2143051a 100644 --- a/apps/platform/tests/Browser/Spec192RecordPageHeaderDisciplineSmokeTest.php +++ b/apps/platform/tests/Browser/Spec192RecordPageHeaderDisciplineSmokeTest.php @@ -24,7 +24,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Findings\FindingExceptionService; use App\Support\Evidence\EvidenceCompletenessState; @@ -33,7 +33,7 @@ pest()->browser()->timeout(20_000); -function spec192ApprovedFindingException(Tenant $tenant, User $requester) +function spec192ApprovedFindingException(ManagedEnvironment $tenant, User $requester) { $approver = User::factory()->create(); createUserWithTenant(tenant: $tenant, user: $approver, role: 'owner', workspaceRole: 'manager'); @@ -61,14 +61,14 @@ function spec192ApprovedFindingException(Tenant $tenant, User $requester) } it('smokes remediated standard record pages with contextual navigation and one clear next step', function (): void { - $tenant = Tenant::factory()->active()->create([ - 'name' => 'Spec192 Browser Tenant', + $tenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Spec192 Browser ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'name' => 'Spec192 Browser Onboarding Tenant', + 'name' => 'Spec192 Browser Onboarding ManagedEnvironment', ]); createUserWithTenant( tenant: $onboardingTenant, @@ -84,7 +84,7 @@ function spec192ApprovedFindingException(Tenant $tenant, User $requester) 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $onboardingTenant->tenant_id, + 'entra_tenant_id' => (string) $onboardingTenant->managed_environment_id, 'tenant_name' => (string) $onboardingTenant->name, ], ]); @@ -103,7 +103,7 @@ function spec192ApprovedFindingException(Tenant $tenant, User $requester) \App\Models\BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -112,7 +112,7 @@ function spec192ApprovedFindingException(Tenant $tenant, User $requester) ]); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'operation_run_id' => (int) $run->getKey(), 'status' => EvidenceSnapshotStatus::Active->value, @@ -122,7 +122,7 @@ function spec192ApprovedFindingException(Tenant $tenant, User $requester) ]); ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), @@ -173,8 +173,8 @@ function spec192ApprovedFindingException(Tenant $tenant, User $requester) }); it('smokes the explicit workflow-heavy tenant detail exception without javascript errors', function (): void { - $tenant = Tenant::factory()->active()->create([ - 'name' => 'Spec192 Workflow Tenant', + $tenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Spec192 Workflow ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); @@ -192,8 +192,8 @@ function spec192ApprovedFindingException(Tenant $tenant, User $requester) }); it('smokes the compliant reference baseline without header regressions or javascript errors', function (): void { - $tenant = Tenant::factory()->active()->create([ - 'name' => 'Spec192 Reference Tenant', + $tenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Spec192 Reference ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); $workspace = $tenant->workspace; @@ -211,12 +211,12 @@ function spec192ApprovedFindingException(Tenant $tenant, User $requester) $profile->update(['active_snapshot_id' => (int) $baselineSnapshot->getKey()]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Spec192 Browser Policy', ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), 'version_number' => 4, @@ -233,7 +233,7 @@ function spec192ApprovedFindingException(Tenant $tenant, User $requester) ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Spec192 Browser Backup', ]); @@ -249,7 +249,7 @@ function spec192ApprovedFindingException(Tenant $tenant, User $requester) $review = composeTenantReviewForTest($tenant, $user, $reviewSnapshot); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $reviewSnapshot->getKey(), diff --git a/apps/platform/tests/Browser/Spec193MonitoringSurfaceHierarchySmokeTest.php b/apps/platform/tests/Browser/Spec193MonitoringSurfaceHierarchySmokeTest.php index a1957313..e4d0d4f2 100644 --- a/apps/platform/tests/Browser/Spec193MonitoringSurfaceHierarchySmokeTest.php +++ b/apps/platform/tests/Browser/Spec193MonitoringSurfaceHierarchySmokeTest.php @@ -6,8 +6,8 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\Workspaces\WorkspaceContext; @@ -25,7 +25,7 @@ FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -39,13 +39,13 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, ]); - $diagnosticsTenant = Tenant::factory()->create([ + $diagnosticsTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); @@ -57,8 +57,8 @@ ensureDefaultMicrosoftProviderConnection: false, ); - TenantMembership::query() - ->where('tenant_id', (int) $diagnosticsTenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $diagnosticsTenant->getKey()) ->update(['role' => 'readonly']); $this->actingAs($user)->withSession([ diff --git a/apps/platform/tests/Browser/Spec194GovernanceFrictionSmokeTest.php b/apps/platform/tests/Browser/Spec194GovernanceFrictionSmokeTest.php index fb1a1ba8..ca860f68 100644 --- a/apps/platform/tests/Browser/Spec194GovernanceFrictionSmokeTest.php +++ b/apps/platform/tests/Browser/Spec194GovernanceFrictionSmokeTest.php @@ -13,7 +13,7 @@ use App\Models\OperationRun; use App\Models\PlatformUser; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Findings\FindingExceptionService; use App\Support\Evidence\EvidenceCompletenessState; @@ -30,7 +30,7 @@ uses(RefreshDatabase::class); -function spec194ApprovedFindingException(Tenant $tenant, User $requester): FindingException +function spec194ApprovedFindingException(ManagedEnvironment $tenant, User $requester): FindingException { $approver = User::factory()->create(); createUserWithTenant( @@ -63,7 +63,7 @@ function spec194ApprovedFindingException(Tenant $tenant, User $requester): Findi ]); } -function spec194SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = ''): string +function spec194SmokeLoginUrl(User $user, ManagedEnvironment $tenant, string $redirect = ''): string { return route('admin.local.smoke-login', array_filter([ 'email' => $user->email, @@ -84,7 +84,7 @@ function spec194SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = '') $pendingException = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -103,7 +103,7 @@ function spec194SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = '') ]); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'operation_run_id' => (int) $snapshotRun->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), @@ -114,7 +114,7 @@ function spec194SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = '') ]); ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), @@ -138,9 +138,9 @@ function spec194SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = '') $review = $review->refresh(); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'name' => 'Spec194 Archived Tenant', + 'name' => 'Spec194 Archived ManagedEnvironment', ]); createUserWithTenant( diff --git a/apps/platform/tests/Browser/Spec198MonitoringPageStateSmokeTest.php b/apps/platform/tests/Browser/Spec198MonitoringPageStateSmokeTest.php index 88fe7c04..a4c2394a 100644 --- a/apps/platform/tests/Browser/Spec198MonitoringPageStateSmokeTest.php +++ b/apps/platform/tests/Browser/Spec198MonitoringPageStateSmokeTest.php @@ -13,7 +13,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Evidence\EvidenceCompletenessState; use App\Support\Evidence\EvidenceSnapshotStatus; use App\Support\OperationRunOutcome; @@ -28,14 +28,14 @@ it('smokes monitoring deeplinks for operations, audit log, finding exceptions queue, and evidence overview', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); - $secondTenant = Tenant::factory()->create([ + $secondTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'name' => 'Second Evidence Tenant', + 'name' => 'Second Evidence ManagedEnvironment', ]); createUserWithTenant(tenant: $secondTenant, user: $user, role: 'owner', workspaceRole: 'manager'); $activeRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Running->value, @@ -46,7 +46,7 @@ $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -63,7 +63,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -77,7 +77,7 @@ foreach ([$tenant, $secondTenant] as $snapshotTenant) { EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $snapshotTenant->getKey(), + 'managed_environment_id' => (int) $snapshotTenant->getKey(), 'workspace_id' => (int) $snapshotTenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -95,11 +95,11 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); visit(route('admin.operations.index', [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'activeTab' => 'active', ])) ->waitForText('Monitoring landing') - ->assertSee('Tenant prefilters and the selected operations tab remain shareable through the URL.') + ->assertSee('ManagedEnvironment prefilters and the selected operations tab remain shareable through the URL.') ->assertSee('Open run detail') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); @@ -119,10 +119,10 @@ ->assertNoConsoleLogs(); visit(route('admin.evidence.overview', [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'search' => $tenant->name, ])) - ->waitForText('Tenant and search query seeds can reopen this overview in a specific monitoring slice.') + ->waitForText('ManagedEnvironment and search query seeds can reopen this overview in a specific monitoring slice.') ->assertSee($tenant->name) ->assertSee('Clear filters') ->assertNoJavaScriptErrors() @@ -147,7 +147,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); diff --git a/apps/platform/tests/Browser/Spec202GovernanceSubjectTaxonomySmokeTest.php b/apps/platform/tests/Browser/Spec202GovernanceSubjectTaxonomySmokeTest.php index 88d48738..70dab616 100644 --- a/apps/platform/tests/Browser/Spec202GovernanceSubjectTaxonomySmokeTest.php +++ b/apps/platform/tests/Browser/Spec202GovernanceSubjectTaxonomySmokeTest.php @@ -6,7 +6,7 @@ use App\Models\BaselineProfile; use App\Models\BaselineSnapshot; use App\Models\BaselineTenantAssignment; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\DB; @@ -15,7 +15,7 @@ uses(RefreshDatabase::class); -function spec202SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = ''): string +function spec202SmokeLoginUrl(User $user, ManagedEnvironment $tenant, string $redirect = ''): string { return route('admin.local.smoke-login', array_filter([ 'email' => $user->email, @@ -68,7 +68,7 @@ function spec202SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = '') BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $compareProfile->getKey(), ]); @@ -100,7 +100,7 @@ function spec202SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = '') ->assertSee('Support readiness') ->assertSee('Capture baseline') ->click('Capture baseline') - ->waitForText('Source Tenant') + ->waitForText('Source ManagedEnvironment') ->click('Cancel') ->assertSee('Capture baseline'); @@ -113,7 +113,7 @@ function spec202SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = '') ->assertSee('Canonical governed-subject scope V2 is already stored for this baseline profile.') ->assertSee('Compare now') ->click('Compare now') - ->waitForText('Target Tenant') + ->waitForText('Target ManagedEnvironment') ->click('Cancel') ->assertSee('Compare now'); }); diff --git a/apps/platform/tests/Browser/Spec265DecisionRegisterSmokeTest.php b/apps/platform/tests/Browser/Spec265DecisionRegisterSmokeTest.php index 9702c08d..e9a109b6 100644 --- a/apps/platform/tests/Browser/Spec265DecisionRegisterSmokeTest.php +++ b/apps/platform/tests/Browser/Spec265DecisionRegisterSmokeTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Governance\DecisionRegister; use App\Models\Finding; use App\Models\FindingException; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Findings\FindingExceptionService; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -14,7 +14,7 @@ uses(RefreshDatabase::class); -function spec265ApprovedFindingException(Tenant $tenant, User $requester): FindingException +function spec265ApprovedFindingException(ManagedEnvironment $tenant, User $requester): FindingException { $approver = User::factory()->create(); createUserWithTenant( @@ -47,7 +47,7 @@ function spec265ApprovedFindingException(Tenant $tenant, User $requester): Findi ]); } -function spec265SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = ''): string +function spec265SmokeLoginUrl(User $user, ManagedEnvironment $tenant, string $redirect = ''): string { return route('admin.local.smoke-login', array_filter([ 'email' => $user->email, @@ -67,7 +67,7 @@ function spec265SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = '') spec265ApprovedFindingException($tenant, $user); $decisionRegisterUrl = DecisionRegister::getUrl(panel: 'admin', parameters: [ - 'tenant_id' => (string) $tenant->getKey(), + 'managed_environment_id' => (string) $tenant->getKey(), ]); visit(spec265SmokeLoginUrl($user, $tenant)) @@ -81,8 +81,8 @@ function spec265SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = '') ->assertNoConsoleLogs() ->assertSee('The register is currently filtered to one tenant.') ->assertSee($tenant->name) - ->assertSee('Open decision') - ->click('Open decision') + ->assertSee('Showing 1 result') + ->click('tbody tr.fi-ta-row') ->waitForText('Opened from the workspace decision register') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() @@ -95,5 +95,5 @@ function spec265SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = '') ->assertNoConsoleLogs() ->assertSee('The register is currently filtered to one tenant.') ->assertSee($tenant->name) - ->assertSee('Open decision'); + ->assertSee('Showing 1 result'); }); diff --git a/apps/platform/tests/Browser/Spec274BillingSubscriptionTruthSmokeTest.php b/apps/platform/tests/Browser/Spec274BillingSubscriptionTruthSmokeTest.php index c4fce6cd..efa4b263 100644 --- a/apps/platform/tests/Browser/Spec274BillingSubscriptionTruthSmokeTest.php +++ b/apps/platform/tests/Browser/Spec274BillingSubscriptionTruthSmokeTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Settings\WorkspaceSettings; use App\Filament\System\Pages\Directory\ViewWorkspace; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\WorkspaceSubscription; use App\Support\Auth\PlatformCapabilities; use App\Support\Workspaces\WorkspaceContext; @@ -13,8 +13,8 @@ pest()->browser()->timeout(20_000); it('smokes subscription truth mutation on the system page', function (): void { - $tenant = Tenant::factory()->create([ - 'name' => 'Browser Billing Truth Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'Browser Billing Truth ManagedEnvironment', ]); [$workspaceUser, $tenant] = createUserWithTenant( @@ -107,8 +107,8 @@ }); it('smokes the admin read-only commercial summary for subscription-backed truth', function (): void { - $tenant = Tenant::factory()->create([ - 'name' => 'Browser Billing Summary Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'Browser Billing Summary ManagedEnvironment', ]); [$workspaceUser, $tenant] = createUserWithTenant( diff --git a/apps/platform/tests/Browser/Spec277StoredReportsSurfaceSmokeTest.php b/apps/platform/tests/Browser/Spec277StoredReportsSurfaceSmokeTest.php index 8c61e266..6f200903 100644 --- a/apps/platform/tests/Browser/Spec277StoredReportsSurfaceSmokeTest.php +++ b/apps/platform/tests/Browser/Spec277StoredReportsSurfaceSmokeTest.php @@ -29,7 +29,7 @@ ], ]) ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'fingerprint' => 'spec-277-browser-fingerprint', ]); diff --git a/apps/platform/tests/Browser/Spec279ManagedEnvironmentCoreCutoverSmokeTest.php b/apps/platform/tests/Browser/Spec279ManagedEnvironmentCoreCutoverSmokeTest.php new file mode 100644 index 00000000..faf789f3 --- /dev/null +++ b/apps/platform/tests/Browser/Spec279ManagedEnvironmentCoreCutoverSmokeTest.php @@ -0,0 +1,41 @@ +browser()->timeout(20_000); + +it('smokes managed-environment selection and temporary tenant-shell dashboard boot', function (): void { + [$user, $environment] = createUserWithTenant( + role: 'owner', + workspaceRole: 'manager', + ensureDefaultMicrosoftProviderConnection: false, + ); + + $environment->forceFill([ + 'name' => 'Spec 279 Production', + 'slug' => 'spec-279-production', + 'kind' => 'production', + 'lifecycle_status' => ManagedEnvironment::STATUS_ACTIVE, + ])->save(); + + $this->actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]); + + visit(ChooseTenant::getUrl(panel: 'admin')) + ->waitForText('Spec 279 Production') + ->assertSee($environment->workspace->name) + ->assertSee('Active') + ->click('Spec 279 Production') + ->waitForText('Spec 279 Production') + ->assertPathContains('/admin/t/spec-279-production') + ->assertNoJavaScriptErrors() + ->assertNoConsoleLogs(); +}); diff --git a/apps/platform/tests/Browser/TenantMembershipsPageTest.php b/apps/platform/tests/Browser/TenantMembershipsPageTest.php index b47893d1..f42877e1 100644 --- a/apps/platform/tests/Browser/TenantMembershipsPageTest.php +++ b/apps/platform/tests/Browser/TenantMembershipsPageTest.php @@ -38,7 +38,7 @@ ->assertNoJavaScriptErrors() ->assertSee('Manage tenant memberships') ->assertSee('Back to tenant overview') - ->assertSee('Tenant access is managed here. Use the tenant overview for provider state, verification, and operational context.'); + ->assertSee('ManagedEnvironment access is managed here. Use the tenant overview for provider state, verification, and operational context.'); $membershipsPage->script(<<<'JS' window.scrollTo(0, document.body.scrollHeight); diff --git a/apps/platform/tests/Feature/078/CanonicalDetailRenderTest.php b/apps/platform/tests/Feature/078/CanonicalDetailRenderTest.php index d3fe0a4f..e5dc837b 100644 --- a/apps/platform/tests/Feature/078/CanonicalDetailRenderTest.php +++ b/apps/platform/tests/Feature/078/CanonicalDetailRenderTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -23,7 +23,7 @@ public function test_renders_canonical_detail_for_a_workspace_member_when_tenant $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'policy.sync', 'status' => 'completed', 'outcome' => 'succeeded', @@ -61,7 +61,7 @@ public function test_renders_canonical_detail_gracefully_when_tenant_id_is_null( $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'failed', @@ -77,12 +77,12 @@ public function test_renders_canonical_detail_gracefully_when_tenant_id_is_null( public function test_returns_404_on_canonical_detail_for_non_members(): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$otherUser] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'policy.sync', 'status' => 'completed', 'outcome' => 'succeeded', @@ -102,7 +102,7 @@ public function test_renders_canonical_detail_db_only_with_no_job_dispatch(): vo $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'failed', diff --git a/apps/platform/tests/Feature/078/KpiHeaderTenantlessTest.php b/apps/platform/tests/Feature/078/KpiHeaderTenantlessTest.php index bf4d54e1..92b17750 100644 --- a/apps/platform/tests/Feature/078/KpiHeaderTenantlessTest.php +++ b/apps/platform/tests/Feature/078/KpiHeaderTenantlessTest.php @@ -18,7 +18,7 @@ public function test_hides_operations_kpi_stats_when_tenant_context_is_absent(): OperationRun::factory()->count(3)->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); Filament::setTenant(null, true); diff --git a/apps/platform/tests/Feature/078/LegacyRoutesReturnNotFoundTest.php b/apps/platform/tests/Feature/078/LegacyRoutesReturnNotFoundTest.php index 8e203b53..06829ece 100644 --- a/apps/platform/tests/Feature/078/LegacyRoutesReturnNotFoundTest.php +++ b/apps/platform/tests/Feature/078/LegacyRoutesReturnNotFoundTest.php @@ -17,7 +17,7 @@ public function test_returns_404_for_legacy_tenant_scoped_operation_detail_urls( $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $this->actingAs($user) diff --git a/apps/platform/tests/Feature/078/OperationsListTenantlessSafetyTest.php b/apps/platform/tests/Feature/078/OperationsListTenantlessSafetyTest.php index 6b56a41f..7da4fffe 100644 --- a/apps/platform/tests/Feature/078/OperationsListTenantlessSafetyTest.php +++ b/apps/platform/tests/Feature/078/OperationsListTenantlessSafetyTest.php @@ -18,7 +18,7 @@ public function test_renders_workspace_operations_list_with_tenantless_runs_when OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'initiator_name' => 'Tenantless run', 'status' => 'queued', @@ -27,9 +27,9 @@ public function test_renders_workspace_operations_list_with_tenantless_runs_when OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'policy.sync', - 'initiator_name' => 'Tenant run', + 'initiator_name' => 'ManagedEnvironment run', 'status' => 'queued', 'outcome' => 'pending', ]); @@ -41,7 +41,7 @@ public function test_renders_workspace_operations_list_with_tenantless_runs_when ->get(route('admin.operations.index')) ->assertOk() ->assertSee('Tenantless run') - ->assertSee('Tenant run'); + ->assertSee('ManagedEnvironment run'); } public function test_renders_workspace_operations_list_workspace_wide_even_with_tenant_context_and_tenantless_records_present(): void @@ -50,7 +50,7 @@ public function test_renders_workspace_operations_list_workspace_wide_even_with_ OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'initiator_name' => 'Tenantless run', 'status' => 'queued', @@ -59,9 +59,9 @@ public function test_renders_workspace_operations_list_workspace_wide_even_with_ OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'policy.sync', - 'initiator_name' => 'Tenant run', + 'initiator_name' => 'ManagedEnvironment run', 'status' => 'queued', 'outcome' => 'pending', ]); @@ -72,7 +72,7 @@ public function test_renders_workspace_operations_list_workspace_wide_even_with_ ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(route('admin.operations.index')) ->assertOk() - ->assertSee('Tenant run') + ->assertSee('ManagedEnvironment run') ->assertSee('Tenantless run'); } } diff --git a/apps/platform/tests/Feature/078/RelatedLinksOnDetailTest.php b/apps/platform/tests/Feature/078/RelatedLinksOnDetailTest.php index 8c14bab2..ba2cb2c1 100644 --- a/apps/platform/tests/Feature/078/RelatedLinksOnDetailTest.php +++ b/apps/platform/tests/Feature/078/RelatedLinksOnDetailTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\RestoreRunResource; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunLinks; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -22,12 +22,12 @@ public function test_shows_restore_related_links_on_canonical_detail_for_restore [$user, $tenant] = createUserWithTenant(role: 'owner'); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'restore.execute', 'context' => [ 'restore_run_id' => (int) $restoreRun->getKey(), @@ -52,7 +52,7 @@ public function test_shows_only_generic_links_for_tenantless_runs_on_canonical_d $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'restore.execute', 'context' => [ 'restore_run_id' => 999, @@ -74,7 +74,7 @@ public function test_does_not_show_legacy_admin_details_cta_and_keeps_canonical_ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'policy.sync', ]); @@ -91,19 +91,19 @@ public function test_does_not_show_legacy_admin_details_cta_and_keeps_canonical_ ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(route('admin.operations.index')) ->assertOk() - ->assertSee('Open operation'); + ->assertSee('Open run detail'); } public function test_hides_tenant_scoped_follow_up_links_when_the_run_tenant_is_not_selector_eligible(): void { - $activeTenant = Tenant::factory()->active()->create([ - 'name' => 'Viewer Active Tenant', + $activeTenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Viewer Active ManagedEnvironment', ]); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Viewer Onboarding Tenant', + 'name' => 'Viewer Onboarding ManagedEnvironment', ]); createUserWithTenant( @@ -116,7 +116,7 @@ public function test_hides_tenant_scoped_follow_up_links_when_the_run_tenant_is_ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'tenant_id' => (int) $onboardingTenant->getKey(), + 'managed_environment_id' => (int) $onboardingTenant->getKey(), 'type' => 'inventory_sync', ]); diff --git a/apps/platform/tests/Feature/078/VerificationReportTenantlessTest.php b/apps/platform/tests/Feature/078/VerificationReportTenantlessTest.php index 3e098b12..34f75c0b 100644 --- a/apps/platform/tests/Feature/078/VerificationReportTenantlessTest.php +++ b/apps/platform/tests/Feature/078/VerificationReportTenantlessTest.php @@ -25,7 +25,7 @@ public function test_renders_verification_report_on_canonical_detail_without_fil $previousRun = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', @@ -39,7 +39,7 @@ public function test_renders_verification_report_on_canonical_detail_without_fil $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/090/AuditLoggingTest.php b/apps/platform/tests/Feature/090/AuditLoggingTest.php index 39c8dbea..ef5712c0 100644 --- a/apps/platform/tests/Feature/090/AuditLoggingTest.php +++ b/apps/platform/tests/Feature/090/AuditLoggingTest.php @@ -27,7 +27,7 @@ public function test_spec090_writes_an_audit_log_when_capture_snapshot_dispatch_ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); Livewire::test(ViewPolicy::class, ['record' => $policy->getRouteKey()]) @@ -40,7 +40,7 @@ public function test_spec090_writes_an_audit_log_when_capture_snapshot_dispatch_ Queue::assertPushed(CapturePolicySnapshotJob::class); $audit = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'policy.capture_snapshot_dispatched') ->latest('id') ->first(); @@ -62,7 +62,7 @@ public function test_spec090_does_not_require_audit_logs_for_denied_capture_snap Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); Livewire::test(ViewPolicy::class, ['record' => $policy->getRouteKey()]) @@ -77,7 +77,7 @@ public function test_spec090_does_not_require_audit_logs_for_denied_capture_snap $this->assertSame( 0, AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'policy.capture_snapshot_dispatched') ->count(), ); @@ -94,7 +94,7 @@ public function test_spec090_does_not_require_audit_logs_for_cancelled_capture_s Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); Livewire::test(ViewPolicy::class, ['record' => $policy->getRouteKey()]) @@ -106,7 +106,7 @@ public function test_spec090_does_not_require_audit_logs_for_cancelled_capture_s $this->assertSame( 0, AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'policy.capture_snapshot_dispatched') ->count(), ); diff --git a/apps/platform/tests/Feature/144/CanonicalOperationViewerContextMismatchTest.php b/apps/platform/tests/Feature/144/CanonicalOperationViewerContextMismatchTest.php index d37dd92c..4839fffa 100644 --- a/apps/platform/tests/Feature/144/CanonicalOperationViewerContextMismatchTest.php +++ b/apps/platform/tests/Feature/144/CanonicalOperationViewerContextMismatchTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\Workspaces\WorkspaceContext; @@ -17,14 +17,14 @@ final class CanonicalOperationViewerContextMismatchTest extends TestCase public function test_shows_non_blocking_mismatch_context_when_the_selected_tenant_differs_from_the_run_tenant(): void { - $runTenant = Tenant::factory()->create([ - 'name' => 'Run Tenant', + $runTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Run ManagedEnvironment', 'workspace_id' => null, ]); [$user, $runTenant] = createUserWithTenant(tenant: $runTenant, role: 'owner'); - $currentTenant = Tenant::factory()->create([ - 'name' => 'Current Tenant', + $currentTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Current ManagedEnvironment', 'workspace_id' => (int) $runTenant->workspace_id, ]); @@ -32,7 +32,7 @@ public function test_shows_non_blocking_mismatch_context_when_the_selected_tenan $run = OperationRun::factory()->create([ 'workspace_id' => (int) $runTenant->workspace_id, - 'tenant_id' => (int) $runTenant->getKey(), + 'managed_environment_id' => (int) $runTenant->getKey(), 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -45,21 +45,21 @@ public function test_shows_non_blocking_mismatch_context_when_the_selected_tenan ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertOk() ->assertSee('Current tenant context differs from this operation') - ->assertSee('Current tenant context: Current Tenant.') - ->assertSee('Operation tenant: Run Tenant.') + ->assertSee('Current tenant context: Current ManagedEnvironment.') + ->assertSee('Operation tenant: Run ManagedEnvironment.') ->assertSee('canonical workspace view'); } public function test_frames_tenantless_runs_as_workspace_level_even_when_tenant_context_is_selected(): void { - $selectedTenant = Tenant::factory()->create([ - 'name' => 'Selected Tenant', + $selectedTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Selected ManagedEnvironment', ]); [$user, $selectedTenant] = createUserWithTenant(tenant: $selectedTenant, role: 'owner'); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $selectedTenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -72,20 +72,20 @@ public function test_frames_tenantless_runs_as_workspace_level_even_when_tenant_ ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertOk() ->assertSee('Workspace-level operation') - ->assertSee('This canonical workspace view is not tied to the current tenant context (Selected Tenant).'); + ->assertSee('This canonical workspace view is not tied to the current tenant context (Selected ManagedEnvironment).'); } public function test_keeps_onboarding_tenant_runs_viewable_with_lifecycle_aware_context(): void { - $tenant = Tenant::factory()->create([ - 'name' => 'Onboarding Tenant', - 'status' => Tenant::STATUS_ONBOARDING, + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'Onboarding ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -98,24 +98,24 @@ public function test_keeps_onboarding_tenant_runs_viewable_with_lifecycle_aware_ ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertOk() ->assertSee('Operation tenant is not available in the current tenant selector') - ->assertSee('Operation tenant: Onboarding Tenant.') + ->assertSee('Operation tenant: Onboarding ManagedEnvironment.') ->assertSee('This tenant is currently onboarding') ->assertSee('Back to Operations') ->assertDontSee('This tenant is currently active') - ->assertDontSee('← Back to Onboarding Tenant'); + ->assertDontSee('← Back to Onboarding ManagedEnvironment'); } public function test_keeps_archived_tenant_runs_viewable_with_lifecycle_aware_context(): void { - $activeTenant = Tenant::factory()->create([ - 'name' => 'Active Tenant', + $activeTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Active ManagedEnvironment', ]); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); - $archivedTenant = Tenant::factory()->create([ - 'name' => 'Archived Tenant', + $archivedTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Archived ManagedEnvironment', 'workspace_id' => (int) $activeTenant->workspace_id, - 'status' => Tenant::STATUS_ACTIVE, + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); createUserWithTenant(tenant: $archivedTenant, user: $user, role: 'owner'); @@ -123,7 +123,7 @@ public function test_keeps_archived_tenant_runs_viewable_with_lifecycle_aware_co $run = OperationRun::factory()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'tenant_id' => (int) $archivedTenant->getKey(), + 'managed_environment_id' => (int) $archivedTenant->getKey(), 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -136,24 +136,24 @@ public function test_keeps_archived_tenant_runs_viewable_with_lifecycle_aware_co ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertOk() ->assertSee('Operation tenant is not available in the current tenant selector') - ->assertSee('Operation tenant: Archived Tenant.') + ->assertSee('Operation tenant: Archived ManagedEnvironment.') ->assertSee('This tenant is currently archived') ->assertSee('Back to Operations') ->assertDontSee('deactivated') - ->assertDontSee('← Back to Archived Tenant'); + ->assertDontSee('← Back to Archived ManagedEnvironment'); } public function test_keeps_selector_excluded_draft_tenant_runs_viewable_with_lifecycle_aware_context(): void { - $tenant = Tenant::factory()->create([ - 'name' => 'Draft Tenant', - 'status' => Tenant::STATUS_DRAFT, + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'Draft ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_DRAFT, ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -166,7 +166,7 @@ public function test_keeps_selector_excluded_draft_tenant_runs_viewable_with_lif ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertOk() ->assertSee('Operation tenant is not available in the current tenant selector') - ->assertSee('Operation tenant: Draft Tenant.') + ->assertSee('Operation tenant: Draft ManagedEnvironment.') ->assertSee('This tenant is currently draft') ->assertDontSee('Resume onboarding'); } diff --git a/apps/platform/tests/Feature/144/CanonicalOperationViewerDeepLinkTrustTest.php b/apps/platform/tests/Feature/144/CanonicalOperationViewerDeepLinkTrustTest.php index 1c08fec4..5a16224c 100644 --- a/apps/platform/tests/Feature/144/CanonicalOperationViewerDeepLinkTrustTest.php +++ b/apps/platform/tests/Feature/144/CanonicalOperationViewerDeepLinkTrustTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Navigation\CanonicalNavigationContext; use App\Support\OperationRunLinks; use App\Support\Workspaces\WorkspaceContext; @@ -17,13 +17,13 @@ final class CanonicalOperationViewerDeepLinkTrustTest extends TestCase public function test_trusts_canonical_run_links_opened_from_a_tenant_surface_after_the_header_tenant_changes(): void { - $runTenant = Tenant::factory()->create([ - 'name' => 'Tenant Surface', + $runTenant = ManagedEnvironment::factory()->create([ + 'name' => 'ManagedEnvironment Surface', ]); [$user, $runTenant] = createUserWithTenant(tenant: $runTenant, role: 'owner'); - $otherTenant = Tenant::factory()->create([ - 'name' => 'Other Tenant', + $otherTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Other ManagedEnvironment', 'workspace_id' => (int) $runTenant->workspace_id, ]); @@ -31,7 +31,7 @@ public function test_trusts_canonical_run_links_opened_from_a_tenant_surface_aft $run = OperationRun::factory()->create([ 'workspace_id' => (int) $runTenant->workspace_id, - 'tenant_id' => (int) $runTenant->getKey(), + 'managed_environment_id' => (int) $runTenant->getKey(), 'type' => 'policy.sync', ]); @@ -56,12 +56,12 @@ public function test_trusts_canonical_run_links_opened_from_a_tenant_surface_aft public function test_trusts_notification_style_run_links_with_no_selected_tenant_context(): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'inventory_sync', ]); @@ -77,10 +77,10 @@ public function test_trusts_notification_style_run_links_with_no_selected_tenant public function test_uses_canonical_collection_link_for_default_back_and_show_all_fallbacks(): void { - $runTenant = Tenant::factory()->create(); + $runTenant = ManagedEnvironment::factory()->create(); [$user, $runTenant] = createUserWithTenant(tenant: $runTenant, role: 'owner'); - $otherTenant = Tenant::factory()->create([ + $otherTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $runTenant->workspace_id, ]); @@ -88,7 +88,7 @@ public function test_uses_canonical_collection_link_for_default_back_and_show_al $run = OperationRun::factory()->create([ 'workspace_id' => (int) $runTenant->workspace_id, - 'tenant_id' => (int) $runTenant->getKey(), + 'managed_environment_id' => (int) $runTenant->getKey(), 'type' => 'inventory_sync', ]); @@ -105,12 +105,12 @@ public function test_uses_canonical_collection_link_for_default_back_and_show_al public function test_trusts_verification_surface_run_links_with_no_selected_tenant_context(): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'context' => [ 'verification_report' => json_decode( diff --git a/apps/platform/tests/Feature/AdminConsentCallbackTest.php b/apps/platform/tests/Feature/AdminConsentCallbackTest.php index 676892a0..84be06a5 100644 --- a/apps/platform/tests/Feature/AdminConsentCallbackTest.php +++ b/apps/platform/tests/Feature/AdminConsentCallbackTest.php @@ -1,7 +1,7 @@ create([ - 'tenant_id' => 'tenant-1', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-1', 'name' => 'Contoso', ]); $response = $this->get(route('admin.consent.callback', [ - 'tenant' => $tenant->tenant_id, + 'tenant' => $tenant->managed_environment_id, 'admin_consent' => 'true', ])); @@ -30,7 +30,7 @@ ); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('entra_tenant_id', $tenant->graphTenantId()) ->first(); @@ -42,21 +42,21 @@ ->and($connection?->last_error_reason_code)->toBeNull(); $this->assertDatabaseHas('audit_logs', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'action' => 'tenant.consent.callback', 'status' => 'success', ]); }); it('links back to onboarding when tenant is onboarding', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-3', - 'name' => 'Onboarding Tenant', - 'status' => Tenant::STATUS_ONBOARDING, + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-3', + 'name' => 'Onboarding ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $response = $this->get(route('admin.consent.callback', [ - 'tenant' => $tenant->tenant_id, + 'tenant' => $tenant->managed_environment_id, 'admin_consent' => 'true', ])); @@ -65,30 +65,30 @@ }); it('invalidates resumable onboarding verification state for the same platform connection after a successful callback', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-verify-reset', - 'name' => 'Reset Tenant', - 'status' => Tenant::STATUS_ONBOARDING, + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-verify-reset', + 'name' => 'Reset ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => $tenant->graphTenantId(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', ]); $draft = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -101,7 +101,7 @@ ]); $this->get(route('admin.consent.callback', [ - 'tenant' => $tenant->tenant_id, + 'tenant' => $tenant->managed_environment_id, 'admin_consent' => 'true', ]))->assertOk(); @@ -128,11 +128,11 @@ $response->assertOk(); - $tenant = Tenant::where('tenant_id', 'new-tenant')->first(); + $tenant = ManagedEnvironment::query()->forTenant('new-tenant')->first(); expect($tenant)->not->toBeNull(); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->id) + ->where('managed_environment_id', (int) $tenant->id) ->where('provider', 'microsoft') ->where('entra_tenant_id', $tenant->graphTenantId()) ->first(); @@ -145,13 +145,13 @@ }); it('records consent callback errors on provider connection canonical state', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-2', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-2', 'name' => 'Fabrikam', ]); $response = $this->get(route('admin.consent.callback', [ - 'tenant' => $tenant->tenant_id, + 'tenant' => $tenant->managed_environment_id, 'error' => 'access_denied', ])); @@ -160,7 +160,7 @@ $response->assertSeeText('Not verified'); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('entra_tenant_id', $tenant->graphTenantId()) ->first(); @@ -173,7 +173,7 @@ ->and($connection?->last_error_message)->toBe('access_denied'); $this->assertDatabaseHas('audit_logs', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'action' => 'tenant.consent.callback', 'status' => 'failed', ]); diff --git a/apps/platform/tests/Feature/Alerts/AlertDeliveryDeepLinkFiltersTest.php b/apps/platform/tests/Feature/Alerts/AlertDeliveryDeepLinkFiltersTest.php index 89be7d4d..f0d00ef5 100644 --- a/apps/platform/tests/Feature/Alerts/AlertDeliveryDeepLinkFiltersTest.php +++ b/apps/platform/tests/Feature/Alerts/AlertDeliveryDeepLinkFiltersTest.php @@ -6,7 +6,7 @@ use App\Models\AlertDelivery; use App\Models\AlertDestination; use App\Models\AlertRule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -48,7 +48,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $normalDelivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'alert_rule_id' => $rule->getKey(), 'alert_destination_id' => $destination->getKey(), 'event_type' => 'high_drift', @@ -84,7 +84,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $deliveryA = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'alert_rule_id' => $rule->getKey(), 'alert_destination_id' => $destinationA->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -92,7 +92,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $deliveryB = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'alert_rule_id' => $rule->getKey(), 'alert_destination_id' => $destinationB->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -105,10 +105,10 @@ function alertDeliveryFilterIndicatorLabels($component): array ->assertCanNotSeeTableRecords([$deliveryB]); }); -it('filters deliveries by tenant_id for multi-tenant members', function (): void { +it('filters deliveries by managed_environment_id for multi-tenant members', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -129,7 +129,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $deliveryA = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -137,7 +137,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $deliveryB = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -145,7 +145,7 @@ function alertDeliveryFilterIndicatorLabels($component): array Livewire::test(ListAlertDeliveries::class) ->assertCanSeeTableRecords([$deliveryA, $deliveryB]) - ->filterTable('tenant_id', (string) $tenantA->getKey()) + ->filterTable('managed_environment_id', (string) $tenantA->getKey()) ->assertCanSeeTableRecords([$deliveryA]) ->assertCanNotSeeTableRecords([$deliveryB]); }); @@ -169,7 +169,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $sentDelivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -177,7 +177,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $failedDelivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_FAILED, @@ -200,10 +200,10 @@ function alertDeliveryFilterIndicatorLabels($component): array }); it('replaces the persisted tenant filter when canonical tenant context changes', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -222,7 +222,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $deliveryA = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -230,7 +230,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $deliveryB = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -247,7 +247,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $component = Livewire::test(ListAlertDeliveries::class) ->filterTable('status', AlertDelivery::STATUS_SENT); - expect(data_get(session()->get($component->instance()->getTableFiltersSessionKey()), 'tenant_id.value')) + expect(data_get(session()->get($component->instance()->getTableFiltersSessionKey()), 'managed_environment_id.value')) ->toBe((string) $tenantA->getKey()); expect(data_get(session()->get($component->instance()->getTableFiltersSessionKey()), 'status.value')) ->toBe(AlertDelivery::STATUS_SENT); @@ -257,7 +257,7 @@ function alertDeliveryFilterIndicatorLabels($component): array ]); Livewire::test(ListAlertDeliveries::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantB->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantB->getKey()) ->assertSet('tableFilters.status.value', AlertDelivery::STATUS_SENT) ->assertCanSeeTableRecords([$deliveryB]) ->assertCanNotSeeTableRecords([$deliveryA]); @@ -301,7 +301,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $matching = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -310,7 +310,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $wrongStatus = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_FAILED, @@ -319,7 +319,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $outsideWindow = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -355,7 +355,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $queued = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_QUEUED, @@ -364,7 +364,7 @@ function alertDeliveryFilterIndicatorLabels($component): array $sent = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, diff --git a/apps/platform/tests/Feature/Alerts/AlertDestinationLastTestStatusTest.php b/apps/platform/tests/Feature/Alerts/AlertDestinationLastTestStatusTest.php index 72e6b5d8..fc318c3d 100644 --- a/apps/platform/tests/Feature/Alerts/AlertDestinationLastTestStatusTest.php +++ b/apps/platform/tests/Feature/Alerts/AlertDestinationLastTestStatusTest.php @@ -166,7 +166,7 @@ AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'event_type' => 'high_drift', diff --git a/apps/platform/tests/Feature/Alerts/AlertDestinationSendTestMessageTest.php b/apps/platform/tests/Feature/Alerts/AlertDestinationSendTestMessageTest.php index c857e52c..122e8cef 100644 --- a/apps/platform/tests/Feature/Alerts/AlertDestinationSendTestMessageTest.php +++ b/apps/platform/tests/Feature/Alerts/AlertDestinationSendTestMessageTest.php @@ -42,7 +42,7 @@ expect($delivery)->not->toBeNull(); expect($delivery->workspace_id)->toBe($workspaceId); - expect($delivery->tenant_id)->toBeNull(); + expect($delivery->managed_environment_id)->toBeNull(); expect($delivery->alert_rule_id)->toBeNull(); expect($delivery->status)->toBe(AlertDelivery::STATUS_QUEUED); diff --git a/apps/platform/tests/Feature/Alerts/BaselineCompareFailedAlertTest.php b/apps/platform/tests/Feature/Alerts/BaselineCompareFailedAlertTest.php index c7b73d39..2df9cfb9 100644 --- a/apps/platform/tests/Feature/Alerts/BaselineCompareFailedAlertTest.php +++ b/apps/platform/tests/Feature/Alerts/BaselineCompareFailedAlertTest.php @@ -70,7 +70,7 @@ function invokeBaselineCompareFailedEvents(int $workspaceId, CarbonImmutable $wi $failedRun = OperationRun::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -82,7 +82,7 @@ function invokeBaselineCompareFailedEvents(int $workspaceId, CarbonImmutable $wi $partialRun = OperationRun::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::PartiallySucceeded->value, @@ -94,7 +94,7 @@ function invokeBaselineCompareFailedEvents(int $workspaceId, CarbonImmutable $wi OperationRun::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -103,7 +103,7 @@ function invokeBaselineCompareFailedEvents(int $workspaceId, CarbonImmutable $wi OperationRun::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::InventorySync->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -119,7 +119,7 @@ function invokeBaselineCompareFailedEvents(int $workspaceId, CarbonImmutable $wi expect($eventsByRunId[$failedRun->getKey()]) ->toMatchArray([ 'event_type' => 'baseline_compare_failed', - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => 'high', 'fingerprint_key' => 'operation_run:'.$failedRun->getKey(), 'metadata' => [ @@ -130,7 +130,7 @@ function invokeBaselineCompareFailedEvents(int $workspaceId, CarbonImmutable $wi expect($eventsByRunId[$partialRun->getKey()]) ->toMatchArray([ 'event_type' => 'baseline_compare_failed', - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => 'high', 'fingerprint_key' => 'operation_run:'.$partialRun->getKey(), 'metadata' => [ @@ -146,7 +146,7 @@ function invokeBaselineCompareFailedEvents(int $workspaceId, CarbonImmutable $wi $run = OperationRun::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -155,7 +155,7 @@ function invokeBaselineCompareFailedEvents(int $workspaceId, CarbonImmutable $wi $event = [ 'event_type' => 'baseline_compare_failed', - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => 'high', 'fingerprint_key' => 'operation_run:'.$run->getKey(), 'title' => 'Baseline compare failed', diff --git a/apps/platform/tests/Feature/Alerts/BaselineHighDriftAlertTest.php b/apps/platform/tests/Feature/Alerts/BaselineHighDriftAlertTest.php index f6b02f33..187bb5b9 100644 --- a/apps/platform/tests/Feature/Alerts/BaselineHighDriftAlertTest.php +++ b/apps/platform/tests/Feature/Alerts/BaselineHighDriftAlertTest.php @@ -76,7 +76,7 @@ function invokeBaselineHighDriftEvents(int $workspaceId, CarbonImmutable $window $newFinding = Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'source' => 'baseline.compare', 'fingerprint' => 'baseline-fingerprint-new', 'severity' => Finding::SEVERITY_CRITICAL, @@ -87,7 +87,7 @@ function invokeBaselineHighDriftEvents(int $workspaceId, CarbonImmutable $window $reopenedFinding = Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'source' => 'baseline.compare', 'fingerprint' => 'baseline-fingerprint-reopened', 'severity' => Finding::SEVERITY_HIGH, @@ -98,7 +98,7 @@ function invokeBaselineHighDriftEvents(int $workspaceId, CarbonImmutable $window Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'source' => 'baseline.compare', 'fingerprint' => 'baseline-too-old', 'severity' => Finding::SEVERITY_HIGH, @@ -109,7 +109,7 @@ function invokeBaselineHighDriftEvents(int $workspaceId, CarbonImmutable $window Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'source' => 'baseline.compare', 'fingerprint' => 'baseline-below-threshold', 'severity' => Finding::SEVERITY_MEDIUM, @@ -120,7 +120,7 @@ function invokeBaselineHighDriftEvents(int $workspaceId, CarbonImmutable $window Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'source' => 'permission_check', 'fingerprint' => 'not-baseline', 'severity' => Finding::SEVERITY_CRITICAL, @@ -138,7 +138,7 @@ function invokeBaselineHighDriftEvents(int $workspaceId, CarbonImmutable $window expect($eventsByFindingId[$newFinding->getKey()]) ->toMatchArray([ 'event_type' => 'baseline_high_drift', - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => Finding::SEVERITY_CRITICAL, 'fingerprint_key' => 'finding_fingerprint:baseline-fingerprint-new', 'metadata' => [ @@ -151,7 +151,7 @@ function invokeBaselineHighDriftEvents(int $workspaceId, CarbonImmutable $window expect($eventsByFindingId[$reopenedFinding->getKey()]) ->toMatchArray([ 'event_type' => 'baseline_high_drift', - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => Finding::SEVERITY_HIGH, 'fingerprint_key' => 'finding_fingerprint:baseline-fingerprint-reopened', 'metadata' => [ @@ -169,7 +169,7 @@ function invokeBaselineHighDriftEvents(int $workspaceId, CarbonImmutable $window $finding = Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'source' => 'baseline.compare', 'fingerprint' => 'stable-fingerprint-key', 'severity' => Finding::SEVERITY_HIGH, @@ -179,7 +179,7 @@ function invokeBaselineHighDriftEvents(int $workspaceId, CarbonImmutable $window $event = [ 'event_type' => 'baseline_high_drift', - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => Finding::SEVERITY_HIGH, 'fingerprint_key' => 'finding_fingerprint:stable-fingerprint-key', 'title' => 'Baseline drift detected', diff --git a/apps/platform/tests/Feature/Alerts/FindingsAlertRuleIntegrationTest.php b/apps/platform/tests/Feature/Alerts/FindingsAlertRuleIntegrationTest.php index 2e62a489..375fca0c 100644 --- a/apps/platform/tests/Feature/Alerts/FindingsAlertRuleIntegrationTest.php +++ b/apps/platform/tests/Feature/Alerts/FindingsAlertRuleIntegrationTest.php @@ -9,7 +9,7 @@ use App\Models\AlertDestination; use App\Models\AlertRule; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -94,7 +94,7 @@ [$ownerA, $tenantA] = createUserWithTenant(role: 'owner'); $workspaceId = (int) $tenantA->workspace_id; - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspaceId, ]); [$ownerB] = createUserWithTenant(tenant: $tenantB, role: 'owner'); @@ -201,7 +201,7 @@ }); it('renders finding event labels and filters in the existing alert deliveries viewer', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $workspaceId = (int) $tenant->workspace_id; @@ -217,7 +217,7 @@ $delivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'event_type' => AlertRule::EVENT_FINDINGS_OVERDUE, diff --git a/apps/platform/tests/Feature/Alerts/PermissionMissingAlertTest.php b/apps/platform/tests/Feature/Alerts/PermissionMissingAlertTest.php index 1d45c7dc..22678199 100644 --- a/apps/platform/tests/Feature/Alerts/PermissionMissingAlertTest.php +++ b/apps/platform/tests/Feature/Alerts/PermissionMissingAlertTest.php @@ -49,14 +49,14 @@ function createAlertRuleWithDestination(int $workspaceId, string $eventType, str // Create a high-severity permission posture finding $finding = Finding::factory()->permissionPosture()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'severity' => Finding::SEVERITY_HIGH, 'status' => Finding::STATUS_NEW, ]); $event = [ 'event_type' => AlertRule::EVENT_PERMISSION_MISSING, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => Finding::SEVERITY_HIGH, 'fingerprint_key' => 'finding:'.(int) $finding->getKey(), 'title' => 'Missing permission detected', @@ -94,7 +94,7 @@ function createAlertRuleWithDestination(int $workspaceId, string $eventType, str $event = [ 'event_type' => AlertRule::EVENT_PERMISSION_MISSING, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => Finding::SEVERITY_HIGH, // high < critical — should not match 'fingerprint_key' => 'finding:999', 'title' => 'Missing permission detected', @@ -124,14 +124,14 @@ function createAlertRuleWithDestination(int $workspaceId, string $eventType, str $finding = Finding::factory()->permissionPosture()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'severity' => Finding::SEVERITY_HIGH, 'status' => Finding::STATUS_NEW, ]); $event = [ 'event_type' => AlertRule::EVENT_PERMISSION_MISSING, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => Finding::SEVERITY_HIGH, 'fingerprint_key' => 'finding:'.(int) $finding->getKey(), 'title' => 'Missing permission detected', @@ -169,7 +169,7 @@ function createAlertRuleWithDestination(int $workspaceId, string $eventType, str // Create a resolved finding — should not appear in events Finding::factory()->permissionPosture()->resolved()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'severity' => Finding::SEVERITY_HIGH, ]); @@ -192,7 +192,7 @@ function createAlertRuleWithDestination(int $workspaceId, string $eventType, str $finding = Finding::factory()->permissionPosture()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'severity' => Finding::SEVERITY_HIGH, 'status' => Finding::STATUS_REOPENED, 'reopened_at' => now(), @@ -209,6 +209,6 @@ function createAlertRuleWithDestination(int $workspaceId, string $eventType, str expect($events)->toHaveCount(1) ->and($events[0]['event_type'])->toBe(AlertRule::EVENT_PERMISSION_MISSING) - ->and($events[0]['tenant_id'])->toBe((int) $tenant->getKey()) + ->and($events[0]['managed_environment_id'])->toBe((int) $tenant->getKey()) ->and($events[0]['metadata']['finding_id'])->toBe((int) $finding->getKey()); }); diff --git a/apps/platform/tests/Feature/Alerts/SlaDueAlertTest.php b/apps/platform/tests/Feature/Alerts/SlaDueAlertTest.php index 3b42a07d..b91a66db 100644 --- a/apps/platform/tests/Feature/Alerts/SlaDueAlertTest.php +++ b/apps/platform/tests/Feature/Alerts/SlaDueAlertTest.php @@ -4,7 +4,7 @@ use App\Models\AlertRule; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -35,14 +35,14 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr [$user, $tenantA] = createUserWithTenant(role: 'owner'); $workspaceId = (int) session()->get(WorkspaceContext::SESSION_KEY); - $tenantB = Tenant::factory()->create(['workspace_id' => $workspaceId]); - $tenantC = Tenant::factory()->create(['workspace_id' => $workspaceId]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => $workspaceId]); + $tenantC = ManagedEnvironment::factory()->create(['workspace_id' => $workspaceId]); $windowStart = $now->subHour(); Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'status' => Finding::STATUS_IN_PROGRESS, 'severity' => Finding::SEVERITY_CRITICAL, 'due_at' => $now->subMinutes(10), @@ -50,7 +50,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'status' => Finding::STATUS_TRIAGED, 'severity' => Finding::SEVERITY_HIGH, 'due_at' => $now->subDays(1), @@ -58,7 +58,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'status' => Finding::STATUS_NEW, 'severity' => Finding::SEVERITY_MEDIUM, 'due_at' => $windowStart, @@ -66,7 +66,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'status' => Finding::STATUS_RESOLVED, 'severity' => Finding::SEVERITY_LOW, 'due_at' => $now->subMinutes(5), @@ -74,7 +74,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'status' => Finding::STATUS_REOPENED, 'severity' => Finding::SEVERITY_HIGH, 'due_at' => $now->subDays(2), @@ -82,7 +82,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenantC->getKey(), + 'managed_environment_id' => $tenantC->getKey(), 'status' => Finding::STATUS_NEW, 'severity' => Finding::SEVERITY_LOW, 'due_at' => $now->subMinutes(20), @@ -92,7 +92,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr expect($events)->toHaveCount(2); - $eventsByTenant = collect($events)->keyBy(static fn (array $event): int => (int) $event['tenant_id']); + $eventsByTenant = collect($events)->keyBy(static fn (array $event): int => (int) $event['managed_environment_id']); expect($eventsByTenant->keys()->all()) ->toEqualCanonicalizing([(int) $tenantA->getKey(), (int) $tenantC->getKey()]); @@ -141,7 +141,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => Finding::STATUS_NEW, 'severity' => Finding::SEVERITY_HIGH, 'due_at' => $now->subDays(1), @@ -149,7 +149,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => Finding::STATUS_NEW, 'severity' => Finding::SEVERITY_MEDIUM, 'due_at' => $windowStart, @@ -157,7 +157,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => Finding::STATUS_CLOSED, 'severity' => Finding::SEVERITY_CRITICAL, 'due_at' => $now->subMinutes(5), @@ -175,7 +175,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => Finding::STATUS_NEW, 'severity' => Finding::SEVERITY_HIGH, 'due_at' => $now->subMinute(), @@ -204,7 +204,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => Finding::STATUS_TRIAGED, 'severity' => Finding::SEVERITY_HIGH, 'due_at' => $now->subHour(), @@ -212,7 +212,7 @@ function invokeSlaDueEvents(int $workspaceId, CarbonImmutable $windowStart): arr Finding::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => Finding::STATUS_IN_PROGRESS, 'severity' => Finding::SEVERITY_CRITICAL, 'due_at' => $now->addHours(6), diff --git a/apps/platform/tests/Feature/Audit/AssignmentRestoreAuditSummaryTest.php b/apps/platform/tests/Feature/Audit/AssignmentRestoreAuditSummaryTest.php index 3d2962e8..feb0357b 100644 --- a/apps/platform/tests/Feature/Audit/AssignmentRestoreAuditSummaryTest.php +++ b/apps/platform/tests/Feature/Audit/AssignmentRestoreAuditSummaryTest.php @@ -4,7 +4,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -47,23 +47,23 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon } }); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-assignment-audit-summary', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-assignment-audit-summary', ]); ensureDefaultProviderConnection($tenant); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-assignment-audit-summary', 'policy_type' => 'settingsCatalogPolicy', ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $backupItem = BackupItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_identifier' => (string) $policy->external_id, @@ -108,7 +108,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ); $summaryEntries = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'restore.assignments.summary') ->where('resource_type', 'restore_run') ->where('resource_id', (string) $restoreRun->getKey()) @@ -119,7 +119,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon expect($summaryEntries->first()?->metadata['failed'] ?? null)->toBe(0); $perAssignmentEntryCount = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereIn('action', [ 'restore.assignment.created', 'restore.assignment.failed', diff --git a/apps/platform/tests/Feature/Audit/FindingAuditVisibilityTest.php b/apps/platform/tests/Feature/Audit/FindingAuditVisibilityTest.php index c4c3ea82..c5d831b7 100644 --- a/apps/platform/tests/Feature/Audit/FindingAuditVisibilityTest.php +++ b/apps/platform/tests/Feature/Audit/FindingAuditVisibilityTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Monitoring\AuditLog as AuditLogPage; use App\Models\AuditLog; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Livewire\Livewire; @@ -17,7 +17,7 @@ $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -57,7 +57,7 @@ $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -96,7 +96,7 @@ $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -134,7 +134,7 @@ it('hides finding audit rows for tenants outside the viewer entitlement scope', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -143,7 +143,7 @@ $visible = AuditLog::query()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -163,7 +163,7 @@ $hidden = AuditLog::query()->create([ 'workspace_id' => (int) $tenantB->workspace_id, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', diff --git a/apps/platform/tests/Feature/Audit/OnboardingDraftAuditTest.php b/apps/platform/tests/Feature/Audit/OnboardingDraftAuditTest.php index f94acb6b..2a1de263 100644 --- a/apps/platform/tests/Feature/Audit/OnboardingDraftAuditTest.php +++ b/apps/platform/tests/Feature/Audit/OnboardingDraftAuditTest.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -37,7 +37,7 @@ ->call('identifyManagedTenant', [ 'entra_tenant_id' => '11111111-1111-1111-1111-111111111111', 'environment' => 'prod', - 'name' => 'Audit Tenant', + 'name' => 'Audit ManagedEnvironment', ]); $firstDraft = TenantOnboardingSession::query() @@ -61,7 +61,7 @@ ->call('identifyManagedTenant', [ 'entra_tenant_id' => '11111111-1111-1111-1111-111111111111', 'environment' => 'prod', - 'name' => 'Audit Tenant', + 'name' => 'Audit ManagedEnvironment', ]) ->assertRedirect(route('admin.onboarding.draft', ['onboardingDraft' => $firstDraft->getKey()])); @@ -142,9 +142,9 @@ Bus::fake(); $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(); @@ -158,9 +158,9 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Audit Connection', 'is_default' => true, 'consent_status' => 'granted', @@ -173,7 +173,7 @@ 'updated_by' => $user, 'current_step' => 'connection', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), ], @@ -246,7 +246,7 @@ $component->call('identifyManagedTenant', [ 'entra_tenant_id' => '55555555-5555-5555-5555-555555555555', 'environment' => 'prod', - 'name' => 'Override Tenant', + 'name' => 'Override ManagedEnvironment', ]); $component->call('createProviderConnection', [ @@ -258,10 +258,10 @@ $component->call('startVerification'); - $tenant = Tenant::query()->where('tenant_id', '55555555-5555-5555-5555-555555555555')->firstOrFail(); + $tenant = ManagedEnvironment::query()->forTenant('55555555-5555-5555-5555-555555555555')->firstOrFail(); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->firstOrFail(); diff --git a/apps/platform/tests/Feature/Audit/ProviderConnectionConsentAuditTest.php b/apps/platform/tests/Feature/Audit/ProviderConnectionConsentAuditTest.php index ec3599d0..4ca6cdee 100644 --- a/apps/platform/tests/Feature/Audit/ProviderConnectionConsentAuditTest.php +++ b/apps/platform/tests/Feature/Audit/ProviderConnectionConsentAuditTest.php @@ -4,7 +4,7 @@ use App\Models\AuditLog; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\Workspaces\WorkspaceContext; @@ -17,10 +17,10 @@ config()->set('graph.client_secret', 'platform-app-secret'); $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => 'tenant-consent-start', - 'name' => 'Tenant Consent Start', + 'managed_environment_id' => 'tenant-consent-start', + 'name' => 'ManagedEnvironment Consent Start', ]); $user = User::factory()->create(); @@ -28,16 +28,16 @@ ->withSession([ WorkspaceContext::SESSION_KEY => (int) $workspace->getKey(), ]) - ->get(route('admin.consent.start', ['tenant' => $tenant->tenant_id])) + ->get(route('admin.consent.start', ['tenant' => $tenant->managed_environment_id])) ->assertRedirect(); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->firstOrFail(); $log = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.consent_started') ->latest('id') ->first(); @@ -53,23 +53,23 @@ }); it('audits admin consent callback results with connection type and outcome metadata', function (): void { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-consent-result', - 'name' => 'Tenant Consent Result', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-consent-result', + 'name' => 'ManagedEnvironment Consent Result', ]); $this->get(route('admin.consent.callback', [ - 'tenant' => $tenant->tenant_id, + 'tenant' => $tenant->managed_environment_id, 'admin_consent' => 'true', ]))->assertOk(); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->firstOrFail(); $log = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.consent_result') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Audit/ProviderConnectionConsentRevocationAuditTest.php b/apps/platform/tests/Feature/Audit/ProviderConnectionConsentRevocationAuditTest.php index a1400541..e3eb1e2c 100644 --- a/apps/platform/tests/Feature/Audit/ProviderConnectionConsentRevocationAuditTest.php +++ b/apps/platform/tests/Feature/Audit/ProviderConnectionConsentRevocationAuditTest.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -56,13 +56,13 @@ public function request(string $method, string $path, array $options = []): Grap }); $user = User::factory()->create(); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'revoked-audit-tenant-id', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'revoked-audit-tenant-id', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, user: $user, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); $connection = ProviderConnection::factory()->platform()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'revoked-audit-tenant-id', @@ -73,7 +73,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, @@ -108,7 +108,7 @@ public function request(string $method, string $path, array $options = []): Grap ->and($run->context['reason_code'] ?? null)->toBe(ProviderReasonCodes::ProviderConsentRevoked); $log = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.consent_revoked') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Audit/ProviderConnectionIdentityAuditTest.php b/apps/platform/tests/Feature/Audit/ProviderConnectionIdentityAuditTest.php index d683b92a..0bbf8380 100644 --- a/apps/platform/tests/Feature/Audit/ProviderConnectionIdentityAuditTest.php +++ b/apps/platform/tests/Feature/Audit/ProviderConnectionIdentityAuditTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\ProviderConnectionResource\Pages\CreateProviderConnection; use App\Models\AuditLog; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -18,8 +18,8 @@ config()->set('graph.client_secret', 'platform-client-secret'); $user = User::factory()->create(); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'identity-audit-tenant-id', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'identity-audit-tenant-id', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, user: $user, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); @@ -33,7 +33,7 @@ $state = session('tenant_onboard_state'); $this->get(route('admin.consent.callback', [ - 'tenant' => $tenant->tenant_id, + 'tenant' => $tenant->managed_environment_id, 'state' => $state, 'admin_consent' => 'True', ]))->assertSuccessful(); @@ -42,7 +42,7 @@ ->assertSuccessful(); $logs = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereIn('action', [ 'provider_connection.consent_started', 'provider_connection.consent_result', @@ -86,12 +86,12 @@ ->assertHasNoFormErrors(); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('display_name', 'Audit target scope connection') ->firstOrFail(); $log = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.created') ->where('resource_id', (string) $connection->getKey()) ->firstOrFail(); diff --git a/apps/platform/tests/Feature/Audit/ProviderConnectionMigrationAuditTest.php b/apps/platform/tests/Feature/Audit/ProviderConnectionMigrationAuditTest.php index c23d1056..6468cf46 100644 --- a/apps/platform/tests/Feature/Audit/ProviderConnectionMigrationAuditTest.php +++ b/apps/platform/tests/Feature/Audit/ProviderConnectionMigrationAuditTest.php @@ -5,7 +5,7 @@ use App\Models\AuditLog; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); @@ -14,14 +14,14 @@ config()->set('graph.client_id', 'platform-client-id'); config()->set('graph.client_secret', 'platform-client-secret'); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'audit-classification-tenant-id', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'audit-classification-tenant-id', 'app_client_id' => 'legacy-tenant-client-id', 'app_client_secret' => 'legacy-tenant-client-secret', ]); $connection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'audit-classification-tenant-id', @@ -41,13 +41,13 @@ ->assertSuccessful(); $started = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.migration_classification_started') ->latest('id') ->first(); $applied = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.migration_classification_applied') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Audit/ProviderConnectionVerificationAuditTest.php b/apps/platform/tests/Feature/Audit/ProviderConnectionVerificationAuditTest.php index 162be523..811867a4 100644 --- a/apps/platform/tests/Feature/Audit/ProviderConnectionVerificationAuditTest.php +++ b/apps/platform/tests/Feature/Audit/ProviderConnectionVerificationAuditTest.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -53,13 +53,13 @@ public function request(string $method, string $path, array $options = []): Grap }); $user = User::factory()->create(); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'verification-audit-tenant-id', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'verification-audit-tenant-id', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, user: $user, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); $connection = ProviderConnection::factory()->platform()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'verification-audit-tenant-id', @@ -69,7 +69,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, @@ -96,7 +96,7 @@ public function request(string $method, string $path, array $options = []): Grap $job->handle(app(\App\Services\Providers\MicrosoftProviderHealthCheck::class), app(OperationRunService::class)); $log = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.verification_result') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Audit/ProviderCredentialAuditSpec081Test.php b/apps/platform/tests/Feature/Audit/ProviderCredentialAuditSpec081Test.php index 4817bb20..ef41f931 100644 --- a/apps/platform/tests/Feature/Audit/ProviderCredentialAuditSpec081Test.php +++ b/apps/platform/tests/Feature/Audit/ProviderCredentialAuditSpec081Test.php @@ -14,7 +14,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $connection = ProviderConnection::factory()->dedicated()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', ]); @@ -30,7 +30,7 @@ ); $log = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.credentials_created') ->latest('id') ->first(); @@ -50,7 +50,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $connection = ProviderConnection::factory()->dedicated()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', ]); @@ -71,7 +71,7 @@ ); $log = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.credentials_updated') ->latest('id') ->first(); @@ -88,7 +88,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $connection = ProviderConnection::factory()->dedicated()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', ]); @@ -112,7 +112,7 @@ ); $log = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.credentials_rotated') ->latest('id') ->first(); @@ -129,7 +129,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $connection = ProviderConnection::factory()->dedicated()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', ]); @@ -147,7 +147,7 @@ $credential->delete(); $log = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.credentials_deleted') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Audit/TenantLifecycleAuditLogTest.php b/apps/platform/tests/Feature/Audit/TenantLifecycleAuditLogTest.php index 8b2d4be7..a13574d7 100644 --- a/apps/platform/tests/Feature/Audit/TenantLifecycleAuditLogTest.php +++ b/apps/platform/tests/Feature/Audit/TenantLifecycleAuditLogTest.php @@ -4,14 +4,14 @@ use App\Filament\Resources\TenantResource\Pages\ViewTenant; use App\Models\AuditLog; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Audit\AuditActionId; use Filament\Actions\Action; use Filament\Facades\Filament; use Livewire\Livewire; it('records archive and restore audit entries for tenant lifecycle mutations from the tenant view', function (): void { - $tenant = Tenant::factory()->active()->create(['name' => 'Lifecycle Audit Tenant']); + $tenant = ManagedEnvironment::factory()->active()->create(['name' => 'Lifecycle Audit ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user); @@ -34,13 +34,13 @@ expect($tenant->trashed())->toBeTrue(); expect(AuditLog::query() ->where('workspace_id', (int) $tenant->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', AuditActionId::TenantArchived->value) ->exists())->toBeTrue(); $archiveAudit = AuditLog::query() ->where('workspace_id', (int) $tenant->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', AuditActionId::TenantArchived->value) ->latest('id') ->first(); @@ -63,7 +63,7 @@ expect($tenant->trashed())->toBeFalse(); expect(AuditLog::query() ->where('workspace_id', (int) $tenant->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', AuditActionId::TenantRestored->value) ->exists())->toBeTrue(); }); diff --git a/apps/platform/tests/Feature/Audit/TenantMembershipAuditLogTest.php b/apps/platform/tests/Feature/Audit/TenantMembershipAuditLogTest.php index e9fa7dbb..0a81f2e2 100644 --- a/apps/platform/tests/Feature/Audit/TenantMembershipAuditLogTest.php +++ b/apps/platform/tests/Feature/Audit/TenantMembershipAuditLogTest.php @@ -1,7 +1,7 @@ where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->whereIn('action', [ AuditActionId::TenantMembershipAdd->value, AuditActionId::TenantMembershipRoleChange->value, @@ -83,8 +83,8 @@ it('writes a last-owner-blocked audit log when demoting or removing the last owner', function () { [$owner, $tenant] = createUserWithTenant(role: 'owner'); - $membership = TenantMembership::query() - ->where('tenant_id', $tenant->id) + $membership = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', $tenant->id) ->where('user_id', $owner->id) ->firstOrFail(); @@ -105,7 +105,7 @@ ))->toThrow(DomainException::class); $blockedLogs = AuditLog::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('action', AuditActionId::TenantMembershipLastOwnerBlocked->value) ->where('status', 'blocked') ->get(); diff --git a/apps/platform/tests/Feature/Auth/BackupHealthBrowserFixtureLoginTest.php b/apps/platform/tests/Feature/Auth/BackupHealthBrowserFixtureLoginTest.php index be5f3a7a..cd79a2f0 100644 --- a/apps/platform/tests/Feature/Auth/BackupHealthBrowserFixtureLoginTest.php +++ b/apps/platform/tests/Feature/Auth/BackupHealthBrowserFixtureLoginTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\TenantDashboard; use App\Filament\Resources\BackupSetResource; use App\Http\Middleware\SuppressDebugbarForSmokeRequests; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\Workspaces\WorkspaceContext; @@ -17,11 +17,11 @@ $workspaceConfig = config('tenantpilot.backup_health.browser_smoke_fixture.workspace'); $userConfig = config('tenantpilot.backup_health.browser_smoke_fixture.user'); $scenarioConfig = config('tenantpilot.backup_health.browser_smoke_fixture.blocked_drillthrough'); - $tenantRouteKey = $scenarioConfig['tenant_id'] ?? $scenarioConfig['tenant_external_id']; + $tenantRouteKey = $scenarioConfig['managed_environment_id'] ?? $scenarioConfig['tenant_external_id']; $workspace = Workspace::query()->where('slug', $workspaceConfig['slug'])->first(); $user = User::query()->where('email', $userConfig['email'])->first(); - $tenant = Tenant::query()->where('external_id', $tenantRouteKey)->first(); + $tenant = ManagedEnvironment::query()->where('slug', $tenantRouteKey)->first(); expect($workspace)->not->toBeNull(); expect($user)->not->toBeNull(); diff --git a/apps/platform/tests/Feature/Auth/BreakGlassModeTest.php b/apps/platform/tests/Feature/Auth/BreakGlassModeTest.php index 3a57f353..32cf9144 100644 --- a/apps/platform/tests/Feature/Auth/BreakGlassModeTest.php +++ b/apps/platform/tests/Feature/Auth/BreakGlassModeTest.php @@ -3,7 +3,7 @@ use App\Filament\System\Pages\Dashboard; use App\Models\AuditLog; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\PlatformCapabilities; use Carbon\CarbonImmutable; use Filament\Facades\Filament; @@ -16,8 +16,8 @@ Filament::setCurrentPanel('system'); Filament::bootCurrentPanel(); - Tenant::factory()->create([ - 'tenant_id' => null, + ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); @@ -70,10 +70,10 @@ $this->get('/system')->assertSuccessful()->assertDontSee('Recovery mode active'); - $tenant = Tenant::query()->where('external_id', 'platform')->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('slug', 'platform')->firstOrFail(); - expect(AuditLog::query()->where('tenant_id', $tenant->getKey())->where('action', 'platform.break_glass.enter')->exists())->toBeTrue(); - expect(AuditLog::query()->where('tenant_id', $tenant->getKey())->where('action', 'platform.break_glass.exit')->exists())->toBeTrue(); + expect(AuditLog::query()->where('managed_environment_id', $tenant->getKey())->where('action', 'platform.break_glass.enter')->exists())->toBeTrue(); + expect(AuditLog::query()->where('managed_environment_id', $tenant->getKey())->where('action', 'platform.break_glass.exit')->exists())->toBeTrue(); }); it('expires break-glass mode after TTL and audits expiry', function () { @@ -102,7 +102,7 @@ $this->get('/system')->assertSuccessful()->assertDontSee('Recovery mode active'); - $tenant = Tenant::query()->where('external_id', 'platform')->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('slug', 'platform')->firstOrFail(); - expect(AuditLog::query()->where('tenant_id', $tenant->getKey())->where('action', 'platform.break_glass.expired')->exists())->toBeTrue(); + expect(AuditLog::query()->where('managed_environment_id', $tenant->getKey())->where('action', 'platform.break_glass.expired')->exists())->toBeTrue(); }); diff --git a/apps/platform/tests/Feature/Auth/BreakGlassWorkspaceOwnerRecoveryTest.php b/apps/platform/tests/Feature/Auth/BreakGlassWorkspaceOwnerRecoveryTest.php index f478afe4..be8434fc 100644 --- a/apps/platform/tests/Feature/Auth/BreakGlassWorkspaceOwnerRecoveryTest.php +++ b/apps/platform/tests/Feature/Auth/BreakGlassWorkspaceOwnerRecoveryTest.php @@ -7,7 +7,7 @@ use App\Models\AuditLog; use App\Models\PlatformUser; use App\Models\SupportAccessGrant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -23,8 +23,8 @@ Filament::setCurrentPanel('system'); Filament::bootCurrentPanel(); - Tenant::factory()->create([ - 'tenant_id' => null, + ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); diff --git a/apps/platform/tests/Feature/Auth/PostLoginRoutingByMembershipTest.php b/apps/platform/tests/Feature/Auth/PostLoginRoutingByMembershipTest.php index 40324327..20d569f6 100644 --- a/apps/platform/tests/Feature/Auth/PostLoginRoutingByMembershipTest.php +++ b/apps/platform/tests/Feature/Auth/PostLoginRoutingByMembershipTest.php @@ -2,8 +2,8 @@ declare(strict_types=1); -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -80,13 +80,13 @@ function entra_fake_token_exchange(string $tid, string $oid): void 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => $workspace->getKey(), ]); - TenantMembership::query()->create([ - 'tenant_id' => $tenant->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', @@ -119,14 +119,14 @@ function entra_fake_token_exchange(string $tid, string $oid): void 'role' => 'owner', ]); - $tenants = Tenant::factory()->count(2)->create([ + $tenants = ManagedEnvironment::factory()->count(2)->create([ 'status' => 'active', 'workspace_id' => $workspace->getKey(), ]); foreach ($tenants as $tenant) { - TenantMembership::query()->create([ - 'tenant_id' => $tenant->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', diff --git a/apps/platform/tests/Feature/Auth/SessionSeparationSmokeTest.php b/apps/platform/tests/Feature/Auth/SessionSeparationSmokeTest.php index 60287e3f..8c286545 100644 --- a/apps/platform/tests/Feature/Auth/SessionSeparationSmokeTest.php +++ b/apps/platform/tests/Feature/Auth/SessionSeparationSmokeTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -14,7 +14,7 @@ it('does not allow a non-member user to access tenant-scoped admin routes', function () { [$member, $tenant] = createUserWithTenant( - tenant: Tenant::factory()->create(['status' => 'active']), + tenant: ManagedEnvironment::factory()->create(['status' => 'active']), user: User::factory()->create(), role: 'owner', ); diff --git a/apps/platform/tests/Feature/Auth/SystemPanelAuthTest.php b/apps/platform/tests/Feature/Auth/SystemPanelAuthTest.php index e93c2acb..02e43ee6 100644 --- a/apps/platform/tests/Feature/Auth/SystemPanelAuthTest.php +++ b/apps/platform/tests/Feature/Auth/SystemPanelAuthTest.php @@ -3,7 +3,7 @@ use App\Filament\System\Pages\Auth\Login; use App\Models\AuditLog; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\PlatformCapabilities; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -21,8 +21,8 @@ }); it('authenticates a platform user and audits success', function () { - $platformTenant = Tenant::factory()->create([ - 'tenant_id' => null, + $platformTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); @@ -43,7 +43,7 @@ expect($user->fresh()->last_login_at)->not->toBeNull(); $audit = AuditLog::query() - ->where('tenant_id', $platformTenant->getKey()) + ->where('managed_environment_id', $platformTenant->getKey()) ->where('action', 'platform.auth.login') ->latest('id') ->first(); @@ -55,8 +55,8 @@ }); it('rejects invalid credentials and audits failure', function () { - $platformTenant = Tenant::factory()->create([ - 'tenant_id' => null, + $platformTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); @@ -75,7 +75,7 @@ expect(auth('platform')->check())->toBeFalse(); $audit = AuditLog::query() - ->where('tenant_id', $platformTenant->getKey()) + ->where('managed_environment_id', $platformTenant->getKey()) ->where('action', 'platform.auth.login') ->latest('id') ->first(); @@ -87,8 +87,8 @@ }); it('rejects inactive platform users and audits failure', function () { - $platformTenant = Tenant::factory()->create([ - 'tenant_id' => null, + $platformTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); @@ -109,7 +109,7 @@ expect($user->fresh()->last_login_at)->toBeNull(); $audit = AuditLog::query() - ->where('tenant_id', $platformTenant->getKey()) + ->where('managed_environment_id', $platformTenant->getKey()) ->where('action', 'platform.auth.login') ->latest('id') ->first(); @@ -121,8 +121,8 @@ }); it('denies system panel access (403) for platform users without the required capability', function () { - Tenant::factory()->create([ - 'tenant_id' => null, + ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); @@ -143,8 +143,8 @@ }); it('allows system panel access for platform users with the required capability', function () { - Tenant::factory()->create([ - 'tenant_id' => null, + ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); diff --git a/apps/platform/tests/Feature/Auth/TenantChooserSelectionTest.php b/apps/platform/tests/Feature/Auth/TenantChooserSelectionTest.php index 4a47d081..afe84837 100644 --- a/apps/platform/tests/Feature/Auth/TenantChooserSelectionTest.php +++ b/apps/platform/tests/Feature/Auth/TenantChooserSelectionTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\ChooseTenant; use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Schema; @@ -13,26 +13,26 @@ uses(RefreshDatabase::class); it('shows only active tenants in the standard chooser and persists the last-used tenant', function (): void { - $activeTenant = Tenant::factory()->active()->create(['name' => 'Active Tenant']); + $activeTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Active ManagedEnvironment']); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); $this->actingAs($user); - $otherActiveTenant = Tenant::factory()->active()->create([ + $otherActiveTenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Other Active Tenant', + 'name' => 'Other Active ManagedEnvironment', ]); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Onboarding Tenant', + 'name' => 'Onboarding ManagedEnvironment', ]); - $draftTenant = Tenant::factory()->draft()->create([ + $draftTenant = ManagedEnvironment::factory()->draft()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Draft Tenant', + 'name' => 'Draft ManagedEnvironment', ]); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Archived Tenant', + 'name' => 'Archived ManagedEnvironment', ]); createUserWithTenant(tenant: $otherActiveTenant, user: $user, role: 'owner'); @@ -44,11 +44,11 @@ $this->get('/admin/choose-tenant') ->assertSuccessful() - ->assertSee('Active Tenant') - ->assertSee('Other Active Tenant') - ->assertDontSee('Onboarding Tenant') - ->assertDontSee('Draft Tenant') - ->assertDontSee('Archived Tenant'); + ->assertSee('Active ManagedEnvironment') + ->assertSee('Other Active ManagedEnvironment') + ->assertDontSee('Onboarding ManagedEnvironment') + ->assertDontSee('Draft ManagedEnvironment') + ->assertDontSee('Archived ManagedEnvironment'); Livewire::test(ChooseTenant::class) ->call('selectTenant', (int) $activeTenant->getKey()) @@ -62,9 +62,9 @@ return; } - if (Schema::hasTable('user_tenant_preferences')) { + if (Schema::hasTable('user_managed_environment_preferences')) { $preference = $user->tenantPreferences() - ->where('tenant_id', $activeTenant->getKey()) + ->where('managed_environment_id', $activeTenant->getKey()) ->first(); expect($preference)->not->toBeNull(); @@ -73,11 +73,11 @@ }); it('returns 404 when a non-operable tenant is selected through the chooser endpoint', function (): void { - $tenant = Tenant::factory()->onboarding()->create(); + $tenant = ManagedEnvironment::factory()->onboarding()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) - ->post(route('admin.select-tenant'), ['tenant_id' => (int) $tenant->getKey()]) + ->post(route('admin.select-tenant'), ['managed_environment_id' => (int) $tenant->getKey()]) ->assertNotFound(); }); diff --git a/apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php b/apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php index dff8301b..e238aa1b 100644 --- a/apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php +++ b/apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Findings\FindingsIntakeQueue; use App\Filament\Resources\FindingResource; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -61,7 +61,7 @@ 'role' => 'owner', ]); - Tenant::factory()->create([ + ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'status' => 'active', ]); @@ -73,10 +73,10 @@ }); it('suppresses hidden-tenant findings and keeps their detail route not found', function (): void { - $visibleTenant = Tenant::factory()->create(['status' => 'active']); + $visibleTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $visibleTenant] = createUserWithTenant($visibleTenant, role: 'readonly', workspaceRole: 'readonly'); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, ]); @@ -109,7 +109,7 @@ }); it('keeps inspect access while disabling claim for members without assign capability', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly', workspaceRole: 'readonly'); $finding = Finding::factory()->for($tenant)->create([ diff --git a/apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php b/apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php index c75a5d7e..210691c5 100644 --- a/apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php +++ b/apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Findings\MyFindingsInbox; use App\Filament\Resources\FindingResource; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -57,7 +57,7 @@ }); it('keeps the inbox accessible while suppressing blocked-tenant rows and summary counts', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly', workspaceRole: 'readonly'); $finding = Finding::factory()->for($tenant)->create([ @@ -71,7 +71,7 @@ $mock->shouldReceive('primeMemberships')->once(); $mock->shouldReceive('isMember')->andReturnTrue(); $mock->shouldReceive('can') - ->andReturnUsing(static function (User $user, Tenant $resolvedTenant, string $capability) use ($tenant): bool { + ->andReturnUsing(static function (User $user, ManagedEnvironment $resolvedTenant, string $capability) use ($tenant): bool { expect((int) $resolvedTenant->getKey())->toBe((int) $tenant->getKey()); return $capability === Capabilities::TENANT_FINDINGS_VIEW ? false : false; @@ -93,10 +93,10 @@ }); it('suppresses hidden-tenant findings and keeps their detail route not found', function (): void { - $visibleTenant = Tenant::factory()->create(['status' => 'active']); + $visibleTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $visibleTenant] = createUserWithTenant($visibleTenant, role: 'readonly', workspaceRole: 'readonly'); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, ]); @@ -131,7 +131,7 @@ }); it('preserves forbidden detail destinations for workspace members who still lack findings capability', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly', workspaceRole: 'readonly'); $finding = Finding::factory()->for($tenant)->create([ @@ -145,7 +145,7 @@ $mock->shouldReceive('primeMemberships')->once(); $mock->shouldReceive('isMember')->andReturnTrue(); $mock->shouldReceive('can') - ->andReturnUsing(static function (User $user, Tenant $resolvedTenant, string $capability) use ($tenant): bool { + ->andReturnUsing(static function (User $user, ManagedEnvironment $resolvedTenant, string $capability) use ($tenant): bool { expect((int) $resolvedTenant->getKey())->toBe((int) $tenant->getKey()); return $capability === Capabilities::TENANT_FINDINGS_VIEW ? false : false; @@ -160,7 +160,7 @@ ->test(MyFindingsInbox::class) ->assertCanNotSeeTableRecords([$finding]); - Gate::define(Capabilities::TENANT_FINDINGS_VIEW, static function (User $user, ?Tenant $resolvedTenant = null): bool { + Gate::define(Capabilities::TENANT_FINDINGS_VIEW, static function (User $user, ?ManagedEnvironment $resolvedTenant = null): bool { return false; }); diff --git a/apps/platform/tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php b/apps/platform/tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php index 0d119173..4b462f1b 100644 --- a/apps/platform/tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php +++ b/apps/platform/tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php @@ -10,7 +10,7 @@ use App\Models\BaselineProfile; use App\Models\BaselineSnapshot; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -30,12 +30,12 @@ }); it('returns 403 for members missing the required capability on the canonical run detail surface', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$owner, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); [$readonly] = createUserWithTenant(tenant: $tenant, user: User::factory()->create(), role: 'readonly'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', ]); @@ -77,7 +77,7 @@ }); it('returns 404 for non-members on the tenant review explanation detail surface', function (): void { - $targetTenant = Tenant::factory()->create(); + $targetTenant = ManagedEnvironment::factory()->create(); [$member] = createUserWithTenant(role: 'owner'); $reviewOwner = User::factory()->create(); createUserWithTenant(tenant: $targetTenant, user: $reviewOwner, role: 'owner'); @@ -105,11 +105,11 @@ }); it('renders governance summary facts for entitled viewers on the canonical run detail surface', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', @@ -137,11 +137,11 @@ }); it('allows entitled viewers to open blocked baseline-capture run detail surfaces', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_capture', 'status' => 'completed', @@ -167,7 +167,7 @@ it('keeps governance summary surfaces deny-as-not-found for workspace members without tenant entitlement', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'status' => 'active', ]); @@ -181,7 +181,7 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'type' => 'tenant.review_pack.generate', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Authorization/ReasonTranslationScopeSafetyTest.php b/apps/platform/tests/Feature/Authorization/ReasonTranslationScopeSafetyTest.php index b9b1394e..854f5316 100644 --- a/apps/platform/tests/Feature/Authorization/ReasonTranslationScopeSafetyTest.php +++ b/apps/platform/tests/Feature/Authorization/ReasonTranslationScopeSafetyTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\Workspaces\WorkspaceContext; @@ -13,7 +13,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -48,9 +48,9 @@ }); it('returns not found before any translated guidance can leak to non-members', function (): void { - $workspaceTenant = Tenant::factory()->create(); + $workspaceTenant = ManagedEnvironment::factory()->create(); [$owner, $visibleTenant] = createUserWithTenant(tenant: $workspaceTenant, role: 'owner'); - $hiddenTenant = Tenant::factory()->for($visibleTenant->workspace)->create(); + $hiddenTenant = ManagedEnvironment::factory()->for($visibleTenant->workspace)->create(); createUserWithTenant(tenant: $hiddenTenant, user: $owner, role: 'owner'); $outsider = \App\Models\User::factory()->create(); @@ -58,7 +58,7 @@ createUserWithTenant(tenant: $visibleTenant, user: $outsider, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $hiddenTenant->getKey(), + 'managed_environment_id' => (int) $hiddenTenant->getKey(), 'workspace_id' => (int) $hiddenTenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/BackupItemReaddTest.php b/apps/platform/tests/Feature/BackupItemReaddTest.php index 3e636411..687792b4 100644 --- a/apps/platform/tests/Feature/BackupItemReaddTest.php +++ b/apps/platform/tests/Feature/BackupItemReaddTest.php @@ -3,7 +3,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Intune\BackupService; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -11,9 +11,9 @@ uses(RefreshDatabase::class); beforeEach(function () { - $this->tenant = Tenant::create([ - 'tenant_id' => 'tenant-123', - 'name' => 'Test Tenant', + $this->tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-123', + 'name' => 'Test ManagedEnvironment', ]); $this->tenant->makeCurrent(); @@ -21,7 +21,7 @@ $this->actingAs($this->user); $this->policy = Policy::create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'external_id' => 'policy-456', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Test Policy', @@ -29,7 +29,7 @@ ]); $this->backupSet = BackupSet::create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'name' => 'Test Backup Set', 'status' => 'completed', 'created_by' => $this->user->email, @@ -39,7 +39,7 @@ it('excludes soft-deleted items when listing available policies to add', function () { // Create a backup item $backupItem = BackupItem::create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'backup_set_id' => $this->backupSet->id, 'policy_id' => $this->policy->id, 'policy_identifier' => $this->policy->external_id, @@ -71,7 +71,7 @@ it('prevents re-adding soft-deleted policies via BackupService', function () { // Create initial backup item $backupItem = BackupItem::create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'backup_set_id' => $this->backupSet->id, 'policy_id' => $this->policy->id, 'policy_identifier' => $this->policy->external_id, @@ -105,7 +105,7 @@ it('allows adding different policy after one was soft-deleted', function () { // Create initial backup item $backupItem = BackupItem::create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'backup_set_id' => $this->backupSet->id, 'policy_id' => $this->policy->id, 'policy_identifier' => $this->policy->external_id, @@ -120,7 +120,7 @@ // Create a different policy $otherPolicy = Policy::create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'external_id' => 'policy-789', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Other Policy', diff --git a/apps/platform/tests/Feature/BackupScheduling/ApplyRetentionJobTest.php b/apps/platform/tests/Feature/BackupScheduling/ApplyRetentionJobTest.php index 88151b24..abbb8038 100644 --- a/apps/platform/tests/Feature/BackupScheduling/ApplyRetentionJobTest.php +++ b/apps/platform/tests/Feature/BackupScheduling/ApplyRetentionJobTest.php @@ -10,7 +10,7 @@ [$user, $tenant] = createUserWithTenant(role: 'manager'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly', 'is_enabled' => true, 'timezone' => 'UTC', @@ -27,7 +27,7 @@ $sets = collect(range(1, 5))->map(function (int $i) use ($tenant): BackupSet { return BackupSet::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Set '.$i, 'status' => 'completed', 'item_count' => 0, @@ -40,7 +40,7 @@ foreach ($sets as $set) { OperationRun::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->id, + 'managed_environment_id' => (int) $tenant->id, 'user_id' => null, 'initiator_name' => 'System', 'type' => 'backup_schedule_run', @@ -81,7 +81,7 @@ } $retentionRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->id) + ->where('managed_environment_id', (int) $tenant->id) ->where('type', 'backup.schedule.retention') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleAdminTenantParityTest.php b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleAdminTenantParityTest.php index a2b43de8..d3c80897 100644 --- a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleAdminTenantParityTest.php +++ b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleAdminTenantParityTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\BackupScheduleResource; use App\Models\BackupSchedule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -12,13 +12,13 @@ uses(RefreshDatabase::class); it('returns not found for admin backup-schedule edit outside the canonical tenant scope', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $allowed = BackupSchedule::create([ - 'tenant_id' => $tenantA->id, + 'managed_environment_id' => $tenantA->id, 'name' => 'Allowed schedule', 'is_enabled' => true, 'timezone' => 'UTC', @@ -32,7 +32,7 @@ ]); $blocked = BackupSchedule::create([ - 'tenant_id' => $tenantB->id, + 'managed_environment_id' => $tenantB->id, 'name' => 'Blocked schedule', 'is_enabled' => true, 'timezone' => 'UTC', diff --git a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleBulkDeleteTest.php b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleBulkDeleteTest.php index c0030561..788d8436 100644 --- a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleBulkDeleteTest.php +++ b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleBulkDeleteTest.php @@ -9,7 +9,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'No bulk delete', 'is_enabled' => true, 'timezone' => 'UTC', @@ -36,7 +36,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $scheduleA = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Keep A', 'is_enabled' => true, 'timezone' => 'UTC', @@ -49,7 +49,7 @@ ]); $scheduleB = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Keep B', 'is_enabled' => true, 'timezone' => 'UTC', @@ -67,6 +67,6 @@ Livewire::test(ListBackupSchedules::class) ->assertTableBulkActionDoesNotExist('bulk_delete'); - expect(BackupSchedule::query()->where('tenant_id', $tenant->id)->pluck('id')->all()) + expect(BackupSchedule::query()->where('managed_environment_id', $tenant->id)->pluck('id')->all()) ->toContain((int) $scheduleA->id, (int) $scheduleB->id); }); diff --git a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleCrudTest.php b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleCrudTest.php index af334f5b..12a4ef21 100644 --- a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleCrudTest.php +++ b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleCrudTest.php @@ -3,22 +3,22 @@ use App\Filament\Resources\BackupScheduleResource\Pages\CreateBackupSchedule; use App\Filament\Resources\BackupScheduleResource\Pages\EditBackupSchedule; use App\Models\BackupSchedule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Filament\Facades\Filament; use Livewire\Livewire; test('backup schedules listing is tenant scoped', function () { [$user, $tenantA] = createUserWithTenant(role: 'manager'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'manager'); BackupSchedule::query()->create([ - 'tenant_id' => $tenantA->id, - 'name' => 'Tenant A schedule', + 'managed_environment_id' => $tenantA->id, + 'name' => 'ManagedEnvironment A schedule', 'is_enabled' => true, 'timezone' => 'UTC', 'frequency' => 'daily', @@ -34,8 +34,8 @@ ]); BackupSchedule::query()->create([ - 'tenant_id' => $tenantB->id, - 'name' => 'Tenant B schedule', + 'managed_environment_id' => $tenantB->id, + 'name' => 'ManagedEnvironment B schedule', 'is_enabled' => true, 'timezone' => 'UTC', 'frequency' => 'daily', @@ -54,17 +54,17 @@ $this->get(route('filament.admin.resources.backup-schedules.index', filamentTenantRouteParams($tenantA))) ->assertOk() - ->assertSee('Tenant A schedule') + ->assertSee('ManagedEnvironment A schedule') ->assertSee('Device Configuration') ->assertSee('more') - ->assertDontSee('Tenant B schedule'); + ->assertDontSee('ManagedEnvironment B schedule'); }); test('backup schedules listing shows next run in schedule timezone', function () { [$user, $tenant] = createUserWithTenant(role: 'manager'); BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Berlin schedule', 'is_enabled' => true, 'timezone' => 'Europe/Berlin', @@ -86,7 +86,7 @@ test('backup schedules pages return 404 for unauthorized tenant', function () { [$user] = createUserWithTenant(role: 'manager'); - $unauthorizedTenant = Tenant::factory()->create(); + $unauthorizedTenant = ManagedEnvironment::factory()->create(); $this->actingAs($user) ->get(route('filament.admin.resources.backup-schedules.index', filamentTenantRouteParams($unauthorizedTenant))) @@ -113,7 +113,7 @@ ->call('create') ->assertHasNoFormErrors(); - $schedule = BackupSchedule::query()->where('tenant_id', $tenant->id)->first(); + $schedule = BackupSchedule::query()->where('managed_environment_id', $tenant->id)->first(); expect($schedule)->not->toBeNull(); expect($schedule->next_run_at)->not->toBeNull(); @@ -132,7 +132,7 @@ [$user, $tenant] = createUserWithTenant(role: 'manager'); $active = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Active schedule', 'is_enabled' => true, 'timezone' => 'UTC', @@ -145,7 +145,7 @@ ]); $archived = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Archived schedule', 'is_enabled' => true, 'timezone' => 'UTC', diff --git a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleLifecycleAuthorizationTest.php b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleLifecycleAuthorizationTest.php index 602ba414..2e56c3ba 100644 --- a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleLifecycleAuthorizationTest.php +++ b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleLifecycleAuthorizationTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\BackupScheduleResource; use App\Filament\Resources\BackupScheduleResource\Pages\ListBackupSchedules; use App\Models\BackupSchedule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\UiTooltips; use Filament\Actions\Action; use Filament\Facades\Filament; @@ -26,7 +26,7 @@ function getBackupScheduleEmptyStateAction(Testable $component, string $name): ? } it('returns 404 for non-members trying to access schedule lifecycle pages', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant(role: 'owner'); $this->actingAs($user) @@ -38,7 +38,7 @@ function getBackupScheduleEmptyStateAction(Testable $component, string $name): ? [$user, $tenant] = createUserWithTenant(role: 'readonly'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Lifecycle auth readonly', 'is_enabled' => true, 'timezone' => 'UTC', @@ -78,7 +78,7 @@ function getBackupScheduleEmptyStateAction(Testable $component, string $name): ? [$user, $tenant] = createUserWithTenant(role: 'owner'); $activeSchedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Lifecycle confirmation active', 'is_enabled' => true, 'timezone' => 'UTC', @@ -91,7 +91,7 @@ function getBackupScheduleEmptyStateAction(Testable $component, string $name): ? ]); $archivedSchedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Lifecycle confirmation archived', 'is_enabled' => true, 'timezone' => 'UTC', @@ -135,7 +135,7 @@ function getBackupScheduleEmptyStateAction(Testable $component, string $name): ? [$user, $tenant] = createUserWithTenant(role: 'manager'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Force delete forbidden', 'is_enabled' => true, 'timezone' => 'UTC', @@ -164,10 +164,10 @@ function getBackupScheduleEmptyStateAction(Testable $component, string $name): ? it('returns 404 and mutates nothing when forged foreign-tenant schedule keys are mounted', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); - $foreignTenant = Tenant::factory()->create(); + $foreignTenant = ManagedEnvironment::factory()->create(); $activeForeignSchedule = BackupSchedule::query()->create([ - 'tenant_id' => $foreignTenant->id, + 'managed_environment_id' => $foreignTenant->id, 'name' => 'Foreign active schedule', 'is_enabled' => true, 'timezone' => 'UTC', @@ -180,7 +180,7 @@ function getBackupScheduleEmptyStateAction(Testable $component, string $name): ? ]); $trashedForeignSchedule = BackupSchedule::query()->create([ - 'tenant_id' => $foreignTenant->id, + 'managed_environment_id' => $foreignTenant->id, 'name' => 'Foreign trashed schedule', 'is_enabled' => true, 'timezone' => 'UTC', diff --git a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php index 9b9745e8..5a64067b 100644 --- a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php +++ b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php @@ -15,10 +15,10 @@ use Illuminate\Support\Facades\Gate; use Livewire\Livewire; -function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attributes = []): BackupSchedule +function makeBackupScheduleForLifecycle(\App\Models\ManagedEnvironment $tenant, array $attributes = []): BackupSchedule { return BackupSchedule::query()->create(array_merge([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly lifecycle', 'is_enabled' => true, 'timezone' => 'UTC', @@ -47,7 +47,7 @@ function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attri expect($schedule->trashed())->toBeTrue(); $this->assertDatabaseHas('audit_logs', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'action' => 'backup_schedule.archived', 'resource_type' => 'backup_schedule', 'resource_id' => (string) $schedule->id, @@ -86,7 +86,7 @@ function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attri expect((bool) $schedule->is_enabled)->toBeFalse(); $this->assertDatabaseHas('audit_logs', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'action' => 'backup_schedule.restored', 'resource_type' => 'backup_schedule', 'resource_id' => (string) $schedule->id, @@ -119,7 +119,7 @@ function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attri $schedule->delete(); OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => $tenant->workspace_id, 'type' => 'backup_schedule_run', 'status' => 'completed', @@ -140,7 +140,7 @@ function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attri expect(BackupSchedule::withTrashed()->whereKey($schedule->id)->exists())->toBeTrue(); $this->assertDatabaseMissing('audit_logs', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'action' => 'backup_schedule.force_deleted', 'resource_id' => (string) $schedule->id, ]); @@ -163,7 +163,7 @@ function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attri expect(BackupSchedule::withTrashed()->whereKey($schedule->id)->exists())->toBeFalse(); $this->assertDatabaseHas('audit_logs', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'action' => 'backup_schedule.force_deleted', 'resource_type' => 'backup_schedule', 'resource_id' => (string) $schedule->id, @@ -236,7 +236,7 @@ function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attri $sets = collect(range(1, 6))->map(function (int $index) use ($tenant): BackupSet { return BackupSet::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Clamp Default '.$index, 'status' => 'completed', 'item_count' => 0, @@ -249,7 +249,7 @@ function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attri foreach ($sets as $set) { OperationRun::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => null, 'initiator_name' => 'System', 'type' => 'backup_schedule_run', @@ -272,7 +272,7 @@ function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attri ApplyBackupScheduleRetentionJob::dispatchSync((int) $schedule->id); $keptIds = BackupSet::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereNull('deleted_at') ->orderBy('id') ->pluck('id') @@ -299,7 +299,7 @@ function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attri $sets = collect(range(1, 5))->map(function (int $index) use ($tenant): BackupSet { return BackupSet::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Clamp Override '.$index, 'status' => 'completed', 'item_count' => 0, @@ -312,7 +312,7 @@ function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attri foreach ($sets as $set) { OperationRun::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => null, 'initiator_name' => 'System', 'type' => 'backup_schedule_run', @@ -335,7 +335,7 @@ function makeBackupScheduleForLifecycle(\App\Models\Tenant $tenant, array $attri ApplyBackupScheduleRetentionJob::dispatchSync((int) $schedule->id); $keptIds = BackupSet::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereNull('deleted_at') ->orderBy('id') ->pluck('id') diff --git a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleOperationRunsRelationManagerTest.php b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleOperationRunsRelationManagerTest.php index 0ca79620..def5124a 100644 --- a/apps/platform/tests/Feature/BackupScheduling/BackupScheduleOperationRunsRelationManagerTest.php +++ b/apps/platform/tests/Feature/BackupScheduling/BackupScheduleOperationRunsRelationManagerTest.php @@ -13,10 +13,10 @@ uses(RefreshDatabase::class); -function makeBackupScheduleForTenant(\App\Models\Tenant $tenant, string $name): BackupSchedule +function makeBackupScheduleForTenant(\App\Models\ManagedEnvironment $tenant, string $name): BackupSchedule { return BackupSchedule::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => $name, 'is_enabled' => true, 'timezone' => 'UTC', diff --git a/apps/platform/tests/Feature/BackupScheduling/DispatchIdempotencyTest.php b/apps/platform/tests/Feature/BackupScheduling/DispatchIdempotencyTest.php index f16c6c97..c46d1450 100644 --- a/apps/platform/tests/Feature/BackupScheduling/DispatchIdempotencyTest.php +++ b/apps/platform/tests/Feature/BackupScheduling/DispatchIdempotencyTest.php @@ -15,7 +15,7 @@ $this->actingAs($user); BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Daily 10:00', 'is_enabled' => true, 'timezone' => 'UTC', @@ -36,7 +36,7 @@ $dispatcher->dispatchDue([$tenant->external_id]); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'backup.schedule.execute') ->count())->toBe(1); @@ -44,7 +44,7 @@ Bus::assertDispatched(RunBackupScheduleJob::class, function (RunBackupScheduleJob $job) use ($tenant): bool { return $job->backupScheduleId !== null - && $job->operationRun?->tenant_id === $tenant->getKey() + && $job->operationRun?->managed_environment_id === $tenant->getKey() && $job->operationRun?->type === 'backup.schedule.execute'; }); }); @@ -56,7 +56,7 @@ $this->actingAs($user); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Daily 10:00', 'is_enabled' => true, 'timezone' => 'UTC', @@ -93,7 +93,7 @@ Bus::assertNotDispatched(RunBackupScheduleJob::class); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'backup.schedule.execute') ->count())->toBe(1); @@ -109,7 +109,7 @@ $this->actingAs($user); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Archived daily 10:00', 'is_enabled' => true, 'timezone' => 'UTC', @@ -132,7 +132,7 @@ expect($result['created_runs'])->toBe(0) ->and($result['scanned_schedules'])->toBe(0) ->and(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'backup.schedule.execute') ->count())->toBe(0); diff --git a/apps/platform/tests/Feature/BackupScheduling/RunBackupScheduleJobTest.php b/apps/platform/tests/Feature/BackupScheduling/RunBackupScheduleJobTest.php index 5cb18e7f..5789a24f 100644 --- a/apps/platform/tests/Feature/BackupScheduling/RunBackupScheduleJobTest.php +++ b/apps/platform/tests/Feature/BackupScheduling/RunBackupScheduleJobTest.php @@ -25,7 +25,7 @@ $this->actingAs($user); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Daily 10:00', 'is_enabled' => true, 'timezone' => 'UTC', @@ -58,7 +58,7 @@ public function syncPoliciesWithReport($tenant, ?array $supportedTypes = null): }); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'status' => 'completed', 'item_count' => 0, ]); @@ -110,7 +110,7 @@ public function createBackupSet($tenant, $policyIds, ?string $actorEmail = null, $this->actingAs($user); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Daily 10:00', 'is_enabled' => true, 'timezone' => 'UTC', @@ -169,7 +169,7 @@ public function createBackupSet($tenant, $policyIds, ?string $actorEmail = null, $this->actingAs($user); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Archived schedule', 'is_enabled' => true, 'timezone' => 'UTC', @@ -225,7 +225,7 @@ public function createBackupSet($tenant, $policyIds, ?string $actorEmail = null, ]); $this->assertDatabaseHas('audit_logs', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'action' => 'backup_schedule.run_skipped', ]); @@ -239,7 +239,7 @@ public function createBackupSet($tenant, $policyIds, ?string $actorEmail = null, $this->actingAs($user); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Daily 10:00', 'is_enabled' => true, 'timezone' => 'UTC', diff --git a/apps/platform/tests/Feature/BackupScheduling/RunNowRetryActionsTest.php b/apps/platform/tests/Feature/BackupScheduling/RunNowRetryActionsTest.php index 63f5341a..64319923 100644 --- a/apps/platform/tests/Feature/BackupScheduling/RunNowRetryActionsTest.php +++ b/apps/platform/tests/Feature/BackupScheduling/RunNowRetryActionsTest.php @@ -28,7 +28,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly', 'is_enabled' => true, 'timezone' => 'UTC', @@ -47,7 +47,7 @@ ->callTableAction('runNow', $schedule); $operationRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup.schedule.execute') ->first(); @@ -73,7 +73,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly', 'is_enabled' => true, 'timezone' => 'UTC', @@ -95,7 +95,7 @@ ->callTableAction('runNow', $schedule); $runs = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup.schedule.execute') ->pluck('id') ->all(); @@ -113,7 +113,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly', 'is_enabled' => true, 'timezone' => 'UTC', @@ -132,7 +132,7 @@ ->callTableAction('retry', $schedule); $operationRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup.schedule.execute') ->first(); @@ -157,7 +157,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly', 'is_enabled' => true, 'timezone' => 'UTC', @@ -179,7 +179,7 @@ ->callTableAction('retry', $schedule); $runs = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup.schedule.execute') ->pluck('id') ->all(); @@ -195,7 +195,7 @@ [$user, $tenant] = createUserWithTenant(role: 'readonly'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly', 'is_enabled' => true, 'timezone' => 'UTC', @@ -225,7 +225,7 @@ } expect(OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->whereIn('type', ['backup.schedule.execute']) ->count()) ->toBe(0); @@ -237,7 +237,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $scheduleA = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly A', 'is_enabled' => true, 'timezone' => 'UTC', @@ -250,7 +250,7 @@ ]); $scheduleB = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly B', 'is_enabled' => true, 'timezone' => 'UTC', @@ -269,13 +269,13 @@ ->callTableBulkAction('bulk_run_now', collect([$scheduleA, $scheduleB])); expect(OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup.schedule.execute') ->count()) ->toBe(2); expect(OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup.schedule.execute') ->pluck('user_id') ->unique() @@ -293,7 +293,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $scheduleA = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly A', 'is_enabled' => true, 'timezone' => 'UTC', @@ -306,7 +306,7 @@ ]); $scheduleB = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly B', 'is_enabled' => true, 'timezone' => 'UTC', @@ -325,13 +325,13 @@ ->callTableBulkAction('bulk_retry', collect([$scheduleA, $scheduleB])); expect(OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup.schedule.execute') ->count()) ->toBe(2); expect(OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup.schedule.execute') ->pluck('user_id') ->unique() @@ -353,7 +353,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $scheduleA = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly A', 'is_enabled' => true, 'timezone' => 'UTC', @@ -366,7 +366,7 @@ ]); $scheduleB = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly B', 'is_enabled' => true, 'timezone' => 'UTC', @@ -402,7 +402,7 @@ ->callTableBulkAction('bulk_retry', collect([$scheduleA, $scheduleB])); expect(OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup.schedule.execute') ->count()) ->toBe(3); diff --git a/apps/platform/tests/Feature/BackupServiceVersionReuseTest.php b/apps/platform/tests/Feature/BackupServiceVersionReuseTest.php index 7a68c11e..6887a894 100644 --- a/apps/platform/tests/Feature/BackupServiceVersionReuseTest.php +++ b/apps/platform/tests/Feature/BackupServiceVersionReuseTest.php @@ -3,7 +3,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Intune\BackupService; use App\Services\Intune\FoundationSnapshotService; @@ -14,25 +14,25 @@ uses(RefreshDatabase::class); it('reuses latest policy version for backup when it is up-to-date and satisfies capture options', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $tenant->makeCurrent(); $user = User::factory()->create(); $this->actingAs($user); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'status' => 'completed', ]); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'last_synced_at' => now(), 'ignored_at' => null, ]); $existingVersion = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'captured_at' => now(), 'snapshot' => ['id' => $policy->external_id, 'name' => $policy->display_name], @@ -75,25 +75,25 @@ }); it('captures a new policy version for backup when no suitable existing version is available', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $tenant->makeCurrent(); $user = User::factory()->create(); $this->actingAs($user); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'status' => 'completed', ]); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'last_synced_at' => now(), 'ignored_at' => null, ]); $staleVersion = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(2), @@ -107,7 +107,7 @@ ->once() ->andReturnUsing(function () use ($policy, $tenant) { $newVersion = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 2, 'captured_at' => now(), @@ -145,7 +145,7 @@ }); it('reuses an existing RBAC foundation version across backup sets when the snapshot is unchanged', function () { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); ensureDefaultProviderConnection($tenant); config()->set('tenantpilot.foundation_types', [ @@ -182,7 +182,7 @@ $this->mock(FoundationSnapshotService::class, function (MockInterface $mock) use ($payload) { $mock->shouldReceive('fetchAll') ->twice() - ->withArgs(fn (Tenant $tenant, string $foundationType): bool => $foundationType === 'intuneRoleDefinition') + ->withArgs(fn (ManagedEnvironment $tenant, string $foundationType): bool => $foundationType === 'intuneRoleDefinition') ->andReturn([ 'items' => [[ 'source_id' => 'role-def-1', @@ -224,5 +224,5 @@ expect($secondItem)->not->toBeNull(); expect($firstItem->policy_id)->toBe($secondItem->policy_id); expect($firstItem->policy_version_id)->toBe($secondItem->policy_version_id); - expect(PolicyVersion::query()->where('tenant_id', $tenant->id)->where('policy_type', 'intuneRoleDefinition')->count())->toBe(1); + expect(PolicyVersion::query()->where('managed_environment_id', $tenant->id)->where('policy_type', 'intuneRoleDefinition')->count())->toBe(1); }); diff --git a/apps/platform/tests/Feature/BackupSets/AddPoliciesStartSurfaceTest.php b/apps/platform/tests/Feature/BackupSets/AddPoliciesStartSurfaceTest.php index 5bb674ab..1cf37d88 100644 --- a/apps/platform/tests/Feature/BackupSets/AddPoliciesStartSurfaceTest.php +++ b/apps/platform/tests/Feature/BackupSets/AddPoliciesStartSurfaceTest.php @@ -30,12 +30,12 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', ]); $policies = Policy::factory()->count(2)->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => null, 'last_synced_at' => now(), ]); @@ -48,7 +48,7 @@ ->assertHasNoTableBulkActionErrors(); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'backup_set.update') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/BackupSets/AddPoliciesToBackupSetJobTest.php b/apps/platform/tests/Feature/BackupSets/AddPoliciesToBackupSetJobTest.php index 3788e08e..43fbd5f8 100644 --- a/apps/platform/tests/Feature/BackupSets/AddPoliciesToBackupSetJobTest.php +++ b/apps/platform/tests/Feature/BackupSets/AddPoliciesToBackupSetJobTest.php @@ -21,24 +21,24 @@ $this->actingAs($user); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', 'status' => 'completed', 'metadata' => ['failures' => []], ]); $policyA = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => null, ]); $policyB = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => null, ]); $versionA = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policyA->id, 'policy_type' => $policyA->policy_type, 'platform' => $policyA->platform, @@ -46,7 +46,7 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'initiator_name' => $user->name, 'type' => 'backup_set.update', @@ -65,7 +65,7 @@ ->twice() ->andReturnUsing(function ( Policy $policy, - \App\Models\Tenant $tenantArg, + \App\Models\ManagedEnvironment $tenantArg, bool $includeAssignments = false, bool $includeScopeTags = false, ?string $createdBy = null, @@ -154,24 +154,24 @@ $this->actingAs($user); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Progress test backup', 'status' => 'completed', 'metadata' => ['failures' => []], ]); $policyA = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => null, ]); $policyB = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => null, ]); $versionA = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policyA->id, 'policy_type' => $policyA->policy_type, 'platform' => $policyA->platform, @@ -179,7 +179,7 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'initiator_name' => $user->name, 'type' => 'backup_set.update', @@ -328,21 +328,21 @@ public function incrementSummaryCounts(OperationRun $run, array $delta): Operati ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'RBAC foundations', 'status' => 'completed', 'metadata' => ['failures' => []], ]); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_type' => 'deviceConfiguration', 'platform' => 'windows', 'ignored_at' => null, ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'policy_type' => $policy->policy_type, 'platform' => $policy->platform, @@ -350,7 +350,7 @@ public function incrementSummaryCounts(OperationRun $run, array $delta): Operati ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'initiator_name' => $user->name, 'type' => 'backup_set.update', @@ -369,7 +369,7 @@ public function incrementSummaryCounts(OperationRun $run, array $delta): Operati ->once() ->andReturnUsing(function ( Policy $capturedPolicy, - \App\Models\Tenant $tenantArg, + \App\Models\ManagedEnvironment $tenantArg, bool $includeAssignments = false, bool $includeScopeTags = false, ?string $createdBy = null, @@ -397,7 +397,7 @@ public function incrementSummaryCounts(OperationRun $run, array $delta): Operati $this->mock(FoundationSnapshotService::class, function (MockInterface $mock) { $mock->shouldReceive('fetchAll') ->twice() - ->andReturnUsing(function (\App\Models\Tenant $tenant, string $foundationType): array { + ->andReturnUsing(function (\App\Models\ManagedEnvironment $tenant, string $foundationType): array { return match ($foundationType) { 'intuneRoleDefinition' => [ 'items' => [[ diff --git a/apps/platform/tests/Feature/BackupSets/RemovePoliciesJobNotificationTest.php b/apps/platform/tests/Feature/BackupSets/RemovePoliciesJobNotificationTest.php index 7d8d81c0..7873d1b9 100644 --- a/apps/platform/tests/Feature/BackupSets/RemovePoliciesJobNotificationTest.php +++ b/apps/platform/tests/Feature/BackupSets/RemovePoliciesJobNotificationTest.php @@ -12,20 +12,20 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'name' => 'Test backup', 'item_count' => 0, ]); $item = BackupItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->getKey(), ]); $backupSet->update(['item_count' => $backupSet->items()->count()]); $opRun = OperationRun::create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'backup_set.update', diff --git a/apps/platform/tests/Feature/BackupSets/RemovePoliciesStartSurfaceTest.php b/apps/platform/tests/Feature/BackupSets/RemovePoliciesStartSurfaceTest.php index 8a3d03b3..ec47fa4e 100644 --- a/apps/platform/tests/Feature/BackupSets/RemovePoliciesStartSurfaceTest.php +++ b/apps/platform/tests/Feature/BackupSets/RemovePoliciesStartSurfaceTest.php @@ -30,7 +30,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', ]); @@ -49,7 +49,7 @@ }); $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'backup_set.update') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/BackupWithAssignmentsConsistencyTest.php b/apps/platform/tests/Feature/BackupWithAssignmentsConsistencyTest.php index b497ccf2..af6ee425 100644 --- a/apps/platform/tests/Feature/BackupWithAssignmentsConsistencyTest.php +++ b/apps/platform/tests/Feature/BackupWithAssignmentsConsistencyTest.php @@ -3,7 +3,7 @@ use App\Models\BackupItem; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\AssignmentFetcher; use App\Services\Graph\GroupResolver; use App\Services\Intune\BackupService; @@ -15,12 +15,12 @@ uses(RefreshDatabase::class); beforeEach(function () { - $this->tenant = Tenant::factory()->create(['status' => 'active']); + $this->tenant = ManagedEnvironment::factory()->create(['status' => 'active']); ensureDefaultProviderConnection($this->tenant, 'microsoft'); $this->policy = Policy::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'external_id' => 'test-policy-123', 'policy_type' => 'settingsCatalogPolicy', 'platform' => 'windows10', @@ -162,7 +162,7 @@ // Create an existing PolicyVersion without assignments (simulate old backup) $existingVersion = PolicyVersion::create([ 'policy_id' => $this->policy->id, - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'version_number' => 1, 'capture_purpose' => PolicyVersionCapturePurpose::Backup, 'policy_type' => 'settingsCatalogPolicy', @@ -223,7 +223,7 @@ $existingVersion = PolicyVersion::create([ 'policy_id' => $this->policy->id, - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'version_number' => 1, 'capture_purpose' => PolicyVersionCapturePurpose::Backup, 'policy_type' => 'settingsCatalogPolicy', diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/BaselineCaptureAuditEventsTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/BaselineCaptureAuditEventsTest.php index 4f6024ef..f19345f5 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/BaselineCaptureAuditEventsTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/BaselineCaptureAuditEventsTest.php @@ -24,7 +24,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'audit-policy-a', 'policy_type' => 'deviceConfiguration', @@ -54,13 +54,13 @@ ); $started = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'baseline.capture.started') ->latest('id') ->first(); $completed = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'baseline.capture.completed') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/BaselineSnapshotNoTenantIdentifiersTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/BaselineSnapshotNoTenantIdentifiersTest.php index e1d2a474..ab6dd284 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/BaselineSnapshotNoTenantIdentifiersTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/BaselineSnapshotNoTenantIdentifiersTest.php @@ -27,7 +27,7 @@ ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'tenant-policy-external-id', 'platform' => 'windows', @@ -41,7 +41,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => (string) $policy->policy_type, 'external_id' => (string) $policy->external_id, 'display_name' => (string) $policy->display_name, diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineContentTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineContentTest.php index 3dce3a01..fc87700d 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineContentTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineContentTest.php @@ -26,7 +26,7 @@ ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'policy-capture-content', 'platform' => 'windows', @@ -34,7 +34,7 @@ ]); $inventory = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => (string) $policy->policy_type, 'external_id' => (string) $policy->external_id, 'display_name' => (string) $policy->display_name, @@ -57,7 +57,7 @@ $capturedAt = now(); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineFullContentOnDemandTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineFullContentOnDemandTest.php index 1e504b70..d89ad671 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineFullContentOnDemandTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineFullContentOnDemandTest.php @@ -7,7 +7,7 @@ use App\Models\InventoryItem; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\BaselineContentCapturePhase; use App\Services\Baselines\BaselineSnapshotIdentity; use App\Services\Baselines\CurrentStateHashResolver; @@ -35,7 +35,7 @@ ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'policy-on-demand', 'platform' => 'windows', @@ -43,7 +43,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => (string) $policy->policy_type, 'external_id' => (string) $policy->external_id, 'display_name' => (string) $policy->display_name, @@ -70,7 +70,7 @@ public function __construct() {} public function capture( Policy $policy, - Tenant $tenant, + ManagedEnvironment $tenant, bool $includeAssignments = false, bool $includeScopeTags = false, ?string $createdBy = null, @@ -87,7 +87,7 @@ public function capture( ]; $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -142,7 +142,7 @@ public function capture( expect($fakeOrchestrator->calls)->toHaveCount(1); $version = PolicyVersion::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('policy_id', (int) $policy->getKey()) ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineMetaFallbackTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineMetaFallbackTest.php index b7006446..09351960 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineMetaFallbackTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/CaptureBaselineMetaFallbackTest.php @@ -27,7 +27,7 @@ ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'policy-capture-meta', 'platform' => 'windows', @@ -41,7 +41,7 @@ ]); $inventory = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => (string) $policy->policy_type, 'external_id' => (string) $policy->external_id, 'display_name' => (string) $policy->display_name, diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/CompareContentEvidenceTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/CompareContentEvidenceTest.php index 70264860..7e4011ca 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/CompareContentEvidenceTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/CompareContentEvidenceTest.php @@ -39,7 +39,7 @@ ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'policy-a', 'platform' => 'windows', @@ -83,7 +83,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, 'display_name' => (string) $policy->display_name, @@ -98,7 +98,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -130,7 +130,7 @@ ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('subject_external_id', (string) $policy->external_id) ->first(); @@ -163,7 +163,7 @@ ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'policy-b', 'platform' => 'windows', @@ -207,7 +207,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, 'display_name' => (string) $policy->display_name, @@ -222,7 +222,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -249,5 +249,5 @@ $opService, ); - expect(Finding::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(0); + expect(Finding::query()->where('managed_environment_id', (int) $tenant->getKey())->count())->toBe(0); }); diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/CompareFidelityMismatchTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/CompareFidelityMismatchTest.php index 770a2b02..d7dee28a 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/CompareFidelityMismatchTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/CompareFidelityMismatchTest.php @@ -39,7 +39,7 @@ ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'policy-meta', 'platform' => 'windows', @@ -47,7 +47,7 @@ ]); $inventory = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, 'display_name' => (string) $policy->display_name, @@ -92,7 +92,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -123,7 +123,7 @@ $opService, ); - expect(Finding::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(0); + expect(Finding::query()->where('managed_environment_id', (int) $tenant->getKey())->count())->toBe(0); $run->refresh(); $context = is_array($run->context) ? $run->context : []; @@ -157,7 +157,7 @@ ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'policy-content', 'platform' => 'windows', @@ -201,7 +201,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, 'display_name' => (string) $policy->display_name, @@ -216,7 +216,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -243,7 +243,7 @@ $opService, ); - expect(Finding::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(0); + expect(Finding::query()->where('managed_environment_id', (int) $tenant->getKey())->count())->toBe(0); $run->refresh(); $context = is_array($run->context) ? $run->context : []; diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/ComplianceNoncomplianceActionsDriftTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/ComplianceNoncomplianceActionsDriftTest.php index 8bc0a9cc..82e5bea8 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/ComplianceNoncomplianceActionsDriftTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/ComplianceNoncomplianceActionsDriftTest.php @@ -79,7 +79,7 @@ expect($run->status)->toBe('completed'); expect(data_get($run->context, 'baseline_compare.reason_code'))->toBe('no_drift_detected'); - expect(Finding::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(0); + expect(Finding::query()->where('managed_environment_id', (int) $tenant->getKey())->count())->toBe(0); }); it('creates drift when compliance noncompliance action timing changes', function (): void { @@ -139,7 +139,7 @@ ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->first(); @@ -175,7 +175,7 @@ function createComplianceActionCompareFixture(array $baselineSnapshotPayload, ar ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceCompliancePolicy', 'external_id' => 'bitlocker-require-policy', 'platform' => 'windows', @@ -186,7 +186,7 @@ function createComplianceActionCompareFixture(array $baselineSnapshotPayload, ar expect($subjectKey)->not->toBeNull(); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, 'policy_type' => (string) $policy->policy_type, @@ -219,7 +219,7 @@ function createComplianceActionCompareFixture(array $baselineSnapshotPayload, ar ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, 'display_name' => (string) $policy->display_name, @@ -234,7 +234,7 @@ function createComplianceActionCompareFixture(array $baselineSnapshotPayload, ar ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, 'policy_type' => (string) $policy->policy_type, diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/FindingFidelityTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/FindingFidelityTest.php index c5db433b..9de23c9d 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/FindingFidelityTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/FindingFidelityTest.php @@ -37,7 +37,7 @@ ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'policy-fidelity-content', 'platform' => 'windows', @@ -81,7 +81,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, 'display_name' => (string) $policy->display_name, @@ -96,7 +96,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, 'policy_type' => (string) $policy->policy_type, @@ -106,7 +106,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, 'policy_type' => (string) $policy->policy_type, @@ -146,7 +146,7 @@ ->and(data_get($compareRun->context, 'baseline_compare.strategy.execution_diagnostics.rbac_role_definitions.total_compared'))->toBe(0); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('subject_external_id', (string) $policy->external_id) ->sole(); @@ -175,7 +175,7 @@ ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'policy-fidelity-meta', 'platform' => 'windows', @@ -220,7 +220,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, 'display_name' => (string) $policy->display_name, @@ -235,7 +235,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -267,7 +267,7 @@ ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('subject_external_id', (string) $policy->external_id) ->sole(); diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/FindingProvenanceTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/FindingProvenanceTest.php index bea7a3da..ae751cb3 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/FindingProvenanceTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/FindingProvenanceTest.php @@ -37,7 +37,7 @@ ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'policy-provenance', 'platform' => 'windows', @@ -81,7 +81,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, 'display_name' => (string) $policy->display_name, @@ -96,7 +96,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -128,7 +128,7 @@ ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('subject_external_id', (string) $policy->external_id) ->sole(); diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/PerformanceGuardTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/PerformanceGuardTest.php index f75f9d74..e0e853f6 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/PerformanceGuardTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/PerformanceGuardTest.php @@ -10,7 +10,7 @@ $inventoryItems = InventoryItem::factory() ->count(500) ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'meta_jsonb' => [ 'odata_type' => '#microsoft.graph.deviceConfiguration', diff --git a/apps/platform/tests/Feature/BaselineDriftEngine/ResolverTest.php b/apps/platform/tests/Feature/BaselineDriftEngine/ResolverTest.php index e0ed0b21..36dbb4d7 100644 --- a/apps/platform/tests/Feature/BaselineDriftEngine/ResolverTest.php +++ b/apps/platform/tests/Feature/BaselineDriftEngine/ResolverTest.php @@ -11,14 +11,14 @@ [, $tenant] = createUserWithTenant(); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'settingsCatalogPolicy', 'external_id' => 'policy-a', 'platform' => 'windows10', ]); $policyVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -31,7 +31,7 @@ ]); $inventory = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => (string) $policy->policy_type, 'external_id' => (string) $policy->external_id, 'meta_jsonb' => [ @@ -80,14 +80,14 @@ [, $tenant] = createUserWithTenant(); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'settingsCatalogPolicy', 'external_id' => 'policy-b', 'platform' => 'windows10', ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -100,7 +100,7 @@ ]); $inventory = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => (string) $policy->policy_type, 'external_id' => (string) $policy->external_id, 'meta_jsonb' => [ diff --git a/apps/platform/tests/Feature/Baselines/BaselineAssignmentTest.php b/apps/platform/tests/Feature/Baselines/BaselineAssignmentTest.php index 4aadd43d..89df1842 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineAssignmentTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineAssignmentTest.php @@ -2,7 +2,7 @@ use App\Models\BaselineProfile; use App\Models\BaselineTenantAssignment; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; // --- T039: Assignment CRUD tests (RBAC + uniqueness) --- @@ -16,14 +16,14 @@ $assignment = BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), 'assigned_by_user_id' => (int) $user->getKey(), ]); expect($assignment)->toBeInstanceOf(BaselineTenantAssignment::class); expect($assignment->workspace_id)->toBe((int) $tenant->workspace_id); - expect($assignment->tenant_id)->toBe((int) $tenant->getKey()); + expect($assignment->managed_environment_id)->toBe((int) $tenant->getKey()); expect($assignment->baseline_profile_id)->toBe((int) $profile->getKey()); expect($assignment->assigned_by_user_id)->toBe((int) $user->getKey()); }); @@ -40,16 +40,16 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile1->getKey(), 'assigned_by_user_id' => (int) $user->getKey(), ]); // Attempting to assign the same tenant in the same workspace should fail - // due to the unique constraint on (workspace_id, tenant_id) + // due to the unique constraint on (workspace_id, managed_environment_id) expect(fn () => BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile2->getKey(), 'assigned_by_user_id' => (int) $user->getKey(), ]))->toThrow(\Illuminate\Database\QueryException::class); @@ -68,12 +68,12 @@ $a1 = BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant1->workspace_id, - 'tenant_id' => (int) $tenant1->getKey(), + 'managed_environment_id' => (int) $tenant1->getKey(), 'baseline_profile_id' => (int) $profile1->getKey(), ]); $a2 = BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant2->workspace_id, - 'tenant_id' => (int) $tenant2->getKey(), + 'managed_environment_id' => (int) $tenant2->getKey(), 'baseline_profile_id' => (int) $profile2->getKey(), ]); @@ -90,7 +90,7 @@ $assignment = BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), 'assigned_by_user_id' => (int) $user->getKey(), ]); @@ -100,7 +100,7 @@ expect(BaselineTenantAssignment::query()->find($assignmentId))->toBeNull(); expect(BaselineProfile::query()->find($profile->getKey()))->not->toBeNull(); - expect(Tenant::query()->find($tenant->getKey()))->not->toBeNull(); + expect(ManagedEnvironment::query()->find($tenant->getKey()))->not->toBeNull(); }); it('loads the baseline profile relationship from assignment', function () { @@ -113,7 +113,7 @@ $assignment = BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCaptureAmbiguousMatchGapTest.php b/apps/platform/tests/Feature/Baselines/BaselineCaptureAmbiguousMatchGapTest.php index 847eea4c..45808b4a 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCaptureAmbiguousMatchGapTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCaptureAmbiguousMatchGapTest.php @@ -28,7 +28,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'dup-1', 'policy_type' => 'deviceConfiguration', @@ -38,7 +38,7 @@ 'last_seen_at' => now(), ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'dup-2', 'policy_type' => 'deviceConfiguration', @@ -48,7 +48,7 @@ 'last_seen_at' => now(), ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'unique-1', 'policy_type' => 'deviceConfiguration', @@ -140,7 +140,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'stale-standard', 'policy_type' => 'deviceConfiguration', @@ -150,7 +150,7 @@ 'last_seen_at' => now()->subMinutes(10), ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'current-standard', 'policy_type' => 'deviceConfiguration', @@ -160,7 +160,7 @@ 'last_seen_at' => now(), ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'current-unique', 'policy_type' => 'deviceConfiguration', diff --git a/apps/platform/tests/Feature/Baselines/BaselineCaptureGapClassificationTest.php b/apps/platform/tests/Feature/Baselines/BaselineCaptureGapClassificationTest.php index 0d4403d2..dd67da4a 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCaptureGapClassificationTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCaptureGapClassificationTest.php @@ -40,7 +40,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'policy-missing-1', 'policy_type' => 'deviceConfiguration', @@ -51,7 +51,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'scope-tag-1', 'policy_type' => 'roleScopeTag', diff --git a/apps/platform/tests/Feature/Baselines/BaselineCaptureRbacRoleDefinitionsTest.php b/apps/platform/tests/Feature/Baselines/BaselineCaptureRbacRoleDefinitionsTest.php index 4551b9e7..5bcd99b8 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCaptureRbacRoleDefinitionsTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCaptureRbacRoleDefinitionsTest.php @@ -37,7 +37,7 @@ ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'role-def-1', 'display_name' => 'Security Reader', 'policy_type' => 'intuneRoleDefinition', @@ -45,7 +45,7 @@ ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -67,7 +67,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'role-def-1', 'policy_type' => 'intuneRoleDefinition', @@ -86,7 +86,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'role-assignment-1', 'policy_type' => 'intuneRoleAssignment', diff --git a/apps/platform/tests/Feature/Baselines/BaselineCaptureTest.php b/apps/platform/tests/Feature/Baselines/BaselineCaptureTest.php index ef417484..726c8720 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCaptureTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCaptureTest.php @@ -6,7 +6,7 @@ use App\Models\BaselineSnapshotItem; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\BaselineCaptureService; use App\Services\Baselines\BaselineSnapshotIdentity; use App\Services\Baselines\InventoryMetaContract; @@ -21,7 +21,7 @@ use Illuminate\Support\Facades\Queue; function createBaselineCaptureInventoryBasis( - Tenant $tenant, + ManagedEnvironment $tenant, array $statusByType, array $attributes = [], ): OperationRun { @@ -68,7 +68,7 @@ function runBaselineCaptureJob( $run = $result['run']; expect($run->type)->toBe(OperationRunType::BaselineCapture->value); expect($run->status)->toBe('queued'); - expect($run->tenant_id)->toBe((int) $tenant->getKey()); + expect($run->managed_environment_id)->toBe((int) $tenant->getKey()); $context = is_array($run->context) ? $run->context : []; expect($context['baseline_profile_id'])->toBe((int) $profile->getKey()); @@ -294,7 +294,7 @@ function runBaselineCaptureJob( ]); $inventoryA = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'policy-a', 'policy_type' => 'deviceConfiguration', @@ -303,7 +303,7 @@ function runBaselineCaptureJob( 'last_seen_operation_run_id' => (int) $inventorySyncRun->getKey(), ]); $inventoryB = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'policy-b', 'policy_type' => 'deviceConfiguration', @@ -312,7 +312,7 @@ function runBaselineCaptureJob( 'last_seen_operation_run_id' => (int) $inventorySyncRun->getKey(), ]); $inventoryC = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'policy-c', 'policy_type' => 'deviceConfiguration', @@ -467,7 +467,7 @@ function runBaselineCaptureJob( ]); InventoryItem::factory()->count(2)->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'policy_type' => 'deviceConfiguration', 'meta_jsonb' => ['odata_type' => '#microsoft.graph.deviceConfiguration', 'stable_field' => 'value'], @@ -501,7 +501,7 @@ function runBaselineCaptureJob( $run2 = OperationRun::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => OperationRunType::BaselineCapture->value, @@ -643,14 +643,14 @@ function runBaselineCaptureJob( ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'policy_type' => 'deviceConfiguration', 'last_seen_operation_run_id' => (int) $inventorySyncRun->getKey(), ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'policy_type' => 'deviceCompliancePolicy', 'last_seen_operation_run_id' => (int) $inventorySyncRun->getKey(), @@ -658,7 +658,7 @@ function runBaselineCaptureJob( // Foundation types are excluded by default (unless foundation_types is selected). InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'policy_type' => 'assignmentFilter', 'last_seen_operation_run_id' => (int) $inventorySyncRun->getKey(), diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareAmbiguousMatchGapTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareAmbiguousMatchGapTest.php index f33baffd..d2f6d12c 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareAmbiguousMatchGapTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareAmbiguousMatchGapTest.php @@ -63,7 +63,7 @@ // Two current policies with the same display name (→ same subject_key). InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'dup-1', 'policy_type' => 'deviceConfiguration', @@ -73,7 +73,7 @@ 'last_seen_at' => now(), ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'dup-2', 'policy_type' => 'deviceConfiguration', @@ -108,7 +108,7 @@ expect( Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->count(), )->toBe(0); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareAuditEventsTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareAuditEventsTest.php index 090e36dd..ac2a4abd 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareAuditEventsTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareAuditEventsTest.php @@ -58,7 +58,7 @@ ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'audit-compare-policy', 'platform' => 'windows', @@ -71,7 +71,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, @@ -87,7 +87,7 @@ public function __construct() {} public function capture( Policy $policy, - \App\Models\Tenant $tenant, + \App\Models\ManagedEnvironment $tenant, bool $includeAssignments = false, bool $includeScopeTags = false, ?string $createdBy = null, @@ -97,7 +97,7 @@ public function capture( ?int $baselineProfileId = null, ): array { $version = \App\Models\PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -148,13 +148,13 @@ public function capture( ); $started = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'baseline.compare.started') ->latest('id') ->first(); $completed = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'baseline.compare.completed') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareCoverageGuardTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareCoverageGuardTest.php index 6a275976..549ab0e6 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareCoverageGuardTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareCoverageGuardTest.php @@ -81,7 +81,7 @@ ]); $inventorySyncRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::InventorySync->value, 'status' => OperationRunStatus::Completed->value, @@ -101,7 +101,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'covered-uuid', 'policy_type' => 'deviceConfiguration', @@ -141,7 +141,7 @@ expect((int) ($counts['errors_recorded'] ?? 0))->toBe(1); $findings = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->get(); @@ -183,7 +183,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'policy-uuid', 'policy_type' => 'deviceConfiguration', @@ -223,7 +223,7 @@ expect( Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->count() )->toBe(0); @@ -246,7 +246,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::InventorySync->value, 'status' => OperationRunStatus::Completed->value, @@ -266,7 +266,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'policy-uuid', 'policy_type' => 'deviceConfiguration', @@ -306,7 +306,7 @@ expect( Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->count() )->toBe(0); @@ -364,7 +364,7 @@ expect( Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->count() )->toBe(0); @@ -431,7 +431,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'device-config-covered', 'policy_type' => 'deviceConfiguration', @@ -477,7 +477,7 @@ ]); expect( Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->count() )->toBe(0); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareCoverageProofGuardTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareCoverageProofGuardTest.php index 5bd46ca9..a043578e 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareCoverageProofGuardTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareCoverageProofGuardTest.php @@ -89,7 +89,7 @@ ]); $inventorySyncRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::InventorySync->value, 'status' => OperationRunStatus::Completed->value, @@ -109,7 +109,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => $coveredExternalId, 'policy_type' => 'deviceConfiguration', @@ -146,7 +146,7 @@ expect($compareRun->outcome)->toBe(OperationRunOutcome::PartiallySucceeded->value); $findings = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->get(); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareCrossTenantMatchTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareCrossTenantMatchTest.php index 49972d68..f013bde2 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareCrossTenantMatchTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareCrossTenantMatchTest.php @@ -8,7 +8,7 @@ use App\Models\InventoryItem; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\BaselineSnapshotIdentity; use App\Services\Intune\AuditLogger; use App\Services\OperationRunService; @@ -18,7 +18,7 @@ it('matches baseline to tenant inventory by policy_type + subject_key (cross-tenant)', function () { [$user, $sourceTenant] = createUserWithTenant(role: 'owner'); - $targetTenant = Tenant::factory()->create([ + $targetTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $sourceTenant->workspace_id, ]); $user->tenants()->syncWithoutDetaching([ @@ -80,7 +80,7 @@ ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $targetTenant->getKey(), + 'managed_environment_id' => (int) $targetTenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'tenant-policy-uuid', 'platform' => 'windows', @@ -88,7 +88,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $targetTenant->getKey(), + 'managed_environment_id' => (int) $targetTenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -99,7 +99,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $targetTenant->getKey(), + 'managed_environment_id' => (int) $targetTenant->getKey(), 'workspace_id' => (int) $targetTenant->workspace_id, 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, @@ -134,7 +134,7 @@ expect( Finding::query() - ->where('tenant_id', (int) $targetTenant->getKey()) + ->where('managed_environment_id', (int) $targetTenant->getKey()) ->where('source', 'baseline.compare') ->count(), )->toBe(0); @@ -143,7 +143,7 @@ it('does not match role definitions across tenants when the role definition id differs', function (): void { [$user, $sourceTenant] = createUserWithTenant(role: 'owner'); - $targetTenant = Tenant::factory()->create([ + $targetTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $sourceTenant->workspace_id, ]); $user->tenants()->syncWithoutDetaching([ @@ -175,7 +175,7 @@ expect($baselineSubjectExternalId)->not->toBeNull(); $sourcePolicy = Policy::factory()->create([ - 'tenant_id' => (int) $sourceTenant->getKey(), + 'managed_environment_id' => (int) $sourceTenant->getKey(), 'external_id' => $sourceExternalId, 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -183,7 +183,7 @@ ]); $sourceVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $sourceTenant->getKey(), + 'managed_environment_id' => (int) $sourceTenant->getKey(), 'policy_id' => (int) $sourcePolicy->getKey(), 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -240,7 +240,7 @@ ); $targetPolicy = Policy::factory()->create([ - 'tenant_id' => (int) $targetTenant->getKey(), + 'managed_environment_id' => (int) $targetTenant->getKey(), 'policy_type' => 'intuneRoleDefinition', 'external_id' => $targetExternalId, 'platform' => 'all', @@ -248,7 +248,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $targetTenant->getKey(), + 'managed_environment_id' => (int) $targetTenant->getKey(), 'policy_id' => (int) $targetPolicy->getKey(), 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -273,7 +273,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $targetTenant->getKey(), + 'managed_environment_id' => (int) $targetTenant->getKey(), 'workspace_id' => (int) $targetTenant->workspace_id, 'external_id' => $targetExternalId, 'policy_type' => 'intuneRoleDefinition', @@ -314,7 +314,7 @@ expect(['succeeded', 'partially_succeeded'])->toContain((string) $run->outcome); $findings = Finding::query() - ->where('tenant_id', (int) $targetTenant->getKey()) + ->where('managed_environment_id', (int) $targetTenant->getKey()) ->where('source', 'baseline.compare') ->get(); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareDriftEvidenceContractRbacTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareDriftEvidenceContractRbacTest.php index b3b8890d..74861cea 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareDriftEvidenceContractRbacTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareDriftEvidenceContractRbacTest.php @@ -45,12 +45,12 @@ function rbacContractSnapshot( } function rbacContractPolicy( - \App\Models\Tenant $tenant, + \App\Models\ManagedEnvironment $tenant, string $externalId, string $displayName, ): Policy { return Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => $externalId, 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -65,7 +65,7 @@ function rbacContractVersion( array $snapshot, ): PolicyVersion { return PolicyVersion::factory()->create([ - 'tenant_id' => (int) $policy->tenant_id, + 'managed_environment_id' => (int) $policy->managed_environment_id, 'policy_id' => (int) $policy->getKey(), 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -128,7 +128,7 @@ function rbacContractBaselineItem( } function rbacContractInventoryItem( - \App\Models\Tenant $tenant, + \App\Models\ManagedEnvironment $tenant, int $inventorySyncRunId, string $externalId, string $displayName, @@ -136,7 +136,7 @@ function rbacContractInventoryItem( int $rolePermissionCount = 1, ): InventoryItem { return InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => $externalId, 'policy_type' => 'intuneRoleDefinition', @@ -154,7 +154,7 @@ function rbacContractInventoryItem( } function rbacContractRun( - \App\Models\Tenant $tenant, + \App\Models\ManagedEnvironment $tenant, \App\Models\User $user, BaselineProfile $profile, BaselineSnapshot $snapshot, @@ -250,7 +250,7 @@ function rbacContractRun( ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->sole(); @@ -323,7 +323,7 @@ function rbacContractRun( ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->sole(); @@ -371,7 +371,7 @@ function rbacContractRun( versionNumber: 1, snapshot: rbacContractSnapshot( displayName: 'Unexpected Role', - description: 'Tenant-only role', + description: 'ManagedEnvironment-only role', isBuiltIn: false, allowedActions: ['microsoft.intune/devices/read'], deniedActions: ['microsoft.intune/devices/delete'], @@ -395,7 +395,7 @@ function rbacContractRun( ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->sole(); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareDriftEvidenceContractTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareDriftEvidenceContractTest.php index 61d65f64..4b8dc581 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareDriftEvidenceContractTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareDriftEvidenceContractTest.php @@ -45,7 +45,7 @@ $externalId = 'policy-alpha-uuid'; $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => $externalId, 'policy_type' => $policyType, 'platform' => 'windows10', @@ -53,7 +53,7 @@ ]); $baselineVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => $policyType, 'platform' => 'windows10', @@ -65,7 +65,7 @@ ]); $currentVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => $policyType, 'platform' => 'windows10', @@ -106,7 +106,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => $externalId, 'policy_type' => $policyType, @@ -137,7 +137,7 @@ ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->sole(); @@ -184,7 +184,7 @@ ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-alpha-uuid', 'policy_type' => $policyType, 'platform' => 'windows10', @@ -192,7 +192,7 @@ ]); $baselineVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => $policyType, 'platform' => 'windows10', @@ -253,7 +253,7 @@ ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->sole(); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php index 71589ee1..67147147 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareExecutionGuardTest.php @@ -42,7 +42,7 @@ createInventorySyncOperationRunWithCoverage($tenant, ['deviceConfiguration' => 'succeeded']); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => OperationRunType::BaselineCompare->value, @@ -97,7 +97,7 @@ createInventorySyncOperationRunWithCoverage($tenant, ['deviceConfiguration' => 'succeeded']); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => OperationRunType::BaselineCompare->value, @@ -159,7 +159,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -176,7 +176,7 @@ $inventorySyncRun = createInventorySyncOperationRunWithCoverage($tenant, ['conditionalAccessPolicy' => 'succeeded']); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'conditional-access-policy-1', 'policy_type' => 'conditionalAccessPolicy', diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareExplanationFallbackTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareExplanationFallbackTest.php index 845be520..173ce656 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareExplanationFallbackTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareExplanationFallbackTest.php @@ -31,7 +31,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareFindingRecurrenceKeyTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareFindingRecurrenceKeyTest.php index 7604ba5a..4b8a8cca 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareFindingRecurrenceKeyTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareFindingRecurrenceKeyTest.php @@ -60,7 +60,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'policy-x-uuid', 'policy_type' => 'deviceConfiguration', @@ -92,7 +92,7 @@ ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->sole(); @@ -202,7 +202,7 @@ function rbacRecurrenceSnapshot(string $displayName, string $description, array expect($workspaceSafeExternalId)->not->toBeNull(); $policy = \App\Models\Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => $externalId, 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -210,7 +210,7 @@ function rbacRecurrenceSnapshot(string $displayName, string $description, array ]); $baselineVersionOne = \App\Models\PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -222,7 +222,7 @@ function rbacRecurrenceSnapshot(string $displayName, string $description, array ]); $baselineVersionTwo = \App\Models\PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -268,7 +268,7 @@ function rbacRecurrenceSnapshot(string $displayName, string $description, array ]); $currentVersion = \App\Models\PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -289,7 +289,7 @@ function rbacRecurrenceSnapshot(string $displayName, string $description, array ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => $externalId, 'policy_type' => 'intuneRoleDefinition', @@ -327,7 +327,7 @@ function rbacRecurrenceSnapshot(string $displayName, string $description, array ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->sole(); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareFindingsTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareFindingsTest.php index f187ae45..6f03d080 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareFindingsTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareFindingsTest.php @@ -85,9 +85,9 @@ 'meta_jsonb' => ['display_name' => $displayNameB], ]); - // Tenant has policyA (different content) and policyC (unexpected) + // ManagedEnvironment has policyA (different content) and policyC (unexpected) InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'policy-a-uuid', 'policy_type' => $policyType, @@ -97,7 +97,7 @@ 'last_seen_at' => now(), ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'policy-c-uuid', 'policy_type' => $policyType, @@ -145,7 +145,7 @@ $scopeKey = 'baseline_profile:'.$profile->getKey(); $findings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) ->get(); @@ -227,7 +227,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'policy-a-uuid', 'policy_type' => $policyType, @@ -280,7 +280,7 @@ $scopeKey = 'baseline_profile:'.$profile->getKey(); $findings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) ->get(); @@ -343,7 +343,7 @@ // Inventory item exists, but it was NOT observed in the latest sync run. InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'settings-catalog-policy-uuid', 'policy_type' => 'settingsCatalogPolicy', @@ -379,7 +379,7 @@ $scopeKey = 'baseline_profile:'.$profile->getKey(); $findings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) ->get(); @@ -433,7 +433,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'policy-x-uuid', 'policy_type' => 'deviceConfiguration', @@ -467,7 +467,7 @@ $scopeKey = 'baseline_profile:'.$profile->getKey(); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) ->sole(); @@ -496,7 +496,7 @@ // Change inventory evidence (hash changes) and run compare again with a new OperationRun. InventoryItem::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('policy_type', 'deviceConfiguration') ->where('external_id', 'policy-x-uuid') ->update([ @@ -575,7 +575,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'policy-x-uuid', 'policy_type' => 'deviceConfiguration', @@ -608,7 +608,7 @@ $scopeKey = 'baseline_profile:'.$profile->getKey(); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) ->sole(); @@ -699,7 +699,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'policy-x-uuid', 'policy_type' => 'deviceConfiguration', @@ -731,7 +731,7 @@ $scopeKey = 'baseline_profile:'.$profile->getKey(); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) ->sole(); @@ -773,7 +773,7 @@ ); $findings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) ->orderBy('id') @@ -835,9 +835,9 @@ 'meta_jsonb' => ['display_name' => $displayName], ]); - // Tenant inventory with same content → same hash + // ManagedEnvironment inventory with same content → same hash InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'matching-uuid', 'policy_type' => 'deviceConfiguration', @@ -875,7 +875,7 @@ expect((int) ($counts['total'] ?? -1))->toBe(0); $findings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('source', 'baseline.compare') ->count(); @@ -951,7 +951,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'matching-uuid', 'policy_type' => 'deviceConfiguration', @@ -962,7 +962,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'foundation-uuid', 'policy_type' => 'notificationMessageTemplate', @@ -999,7 +999,7 @@ expect( Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) ->count() @@ -1059,9 +1059,9 @@ 'meta_jsonb' => ['display_name' => $changedDisplayName], ]); - // Tenant only has changed-uuid with different content + extra-uuid (unexpected) + // ManagedEnvironment only has changed-uuid with different content + extra-uuid (unexpected) InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'changed-uuid', 'policy_type' => 'deviceConfiguration', @@ -1071,7 +1071,7 @@ 'last_seen_at' => now(), ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'extra-uuid', 'policy_type' => 'deviceConfiguration', @@ -1220,7 +1220,7 @@ ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->sole(); @@ -1307,7 +1307,7 @@ ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->sole(); @@ -1404,7 +1404,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'different-policy', 'policy_type' => 'deviceConfiguration', @@ -1414,7 +1414,7 @@ 'last_seen_at' => now(), ]); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'external_id' => 'unexpected-policy', 'policy_type' => 'deviceConfiguration', @@ -1444,7 +1444,7 @@ ); $findings = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->get() ->keyBy(fn (Finding $finding): string => (string) data_get($finding->evidence_jsonb, 'change_type')); @@ -1468,7 +1468,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'policy-a', 'policy_type' => 'deviceConfiguration', diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareGapClassificationTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareGapClassificationTest.php index fc31a20b..e8f216a5 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareGapClassificationTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareGapClassificationTest.php @@ -76,7 +76,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'compare-missing-policy', 'policy_type' => 'deviceConfiguration', @@ -87,7 +87,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'compare-scope-tag', 'policy_type' => 'roleScopeTag', diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php index 3499e76c..e28c3353 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceMembership; use App\Support\Baselines\BaselineCompareMatrixBuilder; @@ -78,19 +78,19 @@ $matchTenant = $fixture['visibleTenant']; $differTenant = $fixture['visibleTenantTwo']; - $missingTenant = Tenant::factory()->create([ + $missingTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $fixture['workspace']->getKey(), 'name' => 'Contoso Missing', ]); - $ambiguousTenant = Tenant::factory()->create([ + $ambiguousTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $fixture['workspace']->getKey(), 'name' => 'Contoso Ambiguous', ]); - $notComparedTenant = Tenant::factory()->create([ + $notComparedTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $fixture['workspace']->getKey(), 'name' => 'Contoso Uncovered', ]); - $staleTenant = Tenant::factory()->create([ + $staleTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $fixture['workspace']->getKey(), 'name' => 'Contoso Stale', ]); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php index 561aaaf2..df378896 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php @@ -7,7 +7,7 @@ use App\Filament\Pages\BaselineCompareMatrix; use App\Jobs\CompareBaselineToTenantJob; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\BaselineCompareService; use App\Support\Baselines\BaselineReasonCodes; use App\Support\Baselines\Compare\CompareStrategyRegistry; @@ -30,7 +30,7 @@ $fixture = $this->makeBaselineCompareMatrixFixture(); - $readonlyTenant = Tenant::factory()->create([ + $readonlyTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $fixture['workspace']->getKey(), 'name' => 'Readonly Contoso', ]); @@ -74,10 +74,10 @@ ->get(); expect($activeRuns)->toHaveCount(2) - ->and($activeRuns->every(static fn (OperationRun $run): bool => $run->tenant_id !== null))->toBeTrue() + ->and($activeRuns->every(static fn (OperationRun $run): bool => $run->managed_environment_id !== null))->toBeTrue() ->and($activeRuns->every(static fn (OperationRun $run): bool => (string) $run->status === OperationRunStatus::Queued->value))->toBeTrue() ->and($activeRuns->every(static fn (OperationRun $run): bool => (string) $run->outcome === OperationRunOutcome::Pending->value))->toBeTrue() - ->and(OperationRun::query()->whereNull('tenant_id')->where('type', OperationRunType::BaselineCompare->value)->count())->toBe(0); + ->and(OperationRun::query()->whereNull('managed_environment_id')->where('type', OperationRunType::BaselineCompare->value)->count())->toBe(0); }); it('runs compare assigned tenants from the matrix page and keeps feedback on tenant-owned runs', function (): void { @@ -99,7 +99,7 @@ expect(OperationRun::query() ->where('workspace_id', (int) $fixture['workspace']->getKey()) ->where('type', OperationRunType::BaselineCompare->value) - ->whereNull('tenant_id') + ->whereNull('managed_environment_id') ->count())->toBe(0); }); diff --git a/apps/platform/tests/Feature/Baselines/BaselineComparePerformanceGuardTest.php b/apps/platform/tests/Feature/Baselines/BaselineComparePerformanceGuardTest.php index 0f00f945..f818882c 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineComparePerformanceGuardTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineComparePerformanceGuardTest.php @@ -64,7 +64,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'policy-uuid', 'policy_type' => 'deviceConfiguration', @@ -110,9 +110,9 @@ $fixture = $this->makeBaselineCompareMatrixFixture(); foreach (range(1, 6) as $index) { - $tenant = \App\Models\Tenant::factory()->create([ + $tenant = \App\Models\ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $fixture['workspace']->getKey(), - 'name' => 'Matrix Tenant '.$index, + 'name' => 'Matrix ManagedEnvironment '.$index, ]); $fixture['user']->tenants()->syncWithoutDetaching([ diff --git a/apps/platform/tests/Feature/Baselines/BaselineComparePreconditionsTest.php b/apps/platform/tests/Feature/Baselines/BaselineComparePreconditionsTest.php index 8b911970..929dd9de 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineComparePreconditionsTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineComparePreconditionsTest.php @@ -47,7 +47,7 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -72,7 +72,7 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -98,7 +98,7 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -129,7 +129,7 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -170,7 +170,7 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -202,7 +202,7 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -267,7 +267,7 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -316,7 +316,7 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -364,7 +364,7 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -402,7 +402,7 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -440,7 +440,7 @@ BaselineTenantAssignment::create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareProtectedChangeTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareProtectedChangeTest.php index 9676f3c6..e8fed527 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareProtectedChangeTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareProtectedChangeTest.php @@ -50,7 +50,7 @@ ); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'policy-secret', 'platform' => 'windows', @@ -111,7 +111,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, 'display_name' => (string) $policy->display_name, @@ -126,7 +126,7 @@ ]); $baselineVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, 'policy_type' => (string) $policy->policy_type, @@ -148,7 +148,7 @@ ); $currentVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, 'policy_type' => (string) $policy->policy_type, @@ -179,7 +179,7 @@ ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('subject_external_id', (string) $policy->external_id) ->first(); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareRbacRoleDefinitionsTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareRbacRoleDefinitionsTest.php index e0f4b737..090435f4 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareRbacRoleDefinitionsTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareRbacRoleDefinitionsTest.php @@ -8,7 +8,7 @@ use App\Models\InventoryItem; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\BaselineSnapshotIdentity; use App\Services\Baselines\Evidence\ContentEvidenceProvider; use App\Services\Intune\AuditLogger; @@ -46,10 +46,10 @@ function rbacRoleDefinitionSnapshot( ]; } -function createRoleDefinitionPolicy(Tenant $tenant, string $externalId, string $displayName): Policy +function createRoleDefinitionPolicy(ManagedEnvironment $tenant, string $externalId, string $displayName): Policy { return Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => $externalId, 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -60,7 +60,7 @@ function createRoleDefinitionPolicy(Tenant $tenant, string $externalId, string $ function createRoleDefinitionVersion(Policy $policy, CarbonImmutable $capturedAt, int $versionNumber, array $snapshot): PolicyVersion { return PolicyVersion::factory()->create([ - 'tenant_id' => (int) $policy->tenant_id, + 'managed_environment_id' => (int) $policy->managed_environment_id, 'policy_id' => (int) $policy->getKey(), 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -125,7 +125,7 @@ function createBaselineRoleDefinitionSnapshotItem( } function createRoleDefinitionInventoryItem( - Tenant $tenant, + ManagedEnvironment $tenant, int $inventorySyncRunId, string $externalId, string $displayName, @@ -133,7 +133,7 @@ function createRoleDefinitionInventoryItem( int $rolePermissionCount = 1, ): InventoryItem { return InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => $externalId, 'policy_type' => 'intuneRoleDefinition', @@ -264,7 +264,7 @@ function createRoleDefinitionInventoryItem( createRoleDefinitionInventoryItem($tenant, (int) $inventorySyncRun->getKey(), 'role-unexpected', 'Unexpected Role', true); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'assignment-noise', 'policy_type' => 'intuneRoleAssignment', @@ -318,7 +318,7 @@ function createRoleDefinitionInventoryItem( ]); $findings = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->get() ->keyBy(fn (Finding $finding): string => (string) data_get($finding->evidence_jsonb, 'display_name')); @@ -428,7 +428,7 @@ function createRoleDefinitionInventoryItem( ]); $findings = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->get(); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareResumeIdempotencyTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareResumeIdempotencyTest.php index b8f7ba92..88459c5f 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareResumeIdempotencyTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareResumeIdempotencyTest.php @@ -66,7 +66,7 @@ foreach ($displayNames as $i => $displayName) { $policies[] = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => $i === 0 ? 'resume-idem-a' : 'resume-idem-b', 'platform' => 'windows', @@ -81,7 +81,7 @@ foreach ($policies as $policy) { InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, @@ -100,7 +100,7 @@ public function __construct() {} public function capture( Policy $policy, - \App\Models\Tenant $tenant, + \App\Models\ManagedEnvironment $tenant, bool $includeAssignments = false, bool $includeScopeTags = false, ?string $createdBy = null, @@ -112,7 +112,7 @@ public function capture( $this->capturedExternalIds[] = (string) $policy->external_id; $version = \App\Models\PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareResumeTokenTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareResumeTokenTest.php index 85a3660c..111069d8 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareResumeTokenTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareResumeTokenTest.php @@ -69,7 +69,7 @@ foreach ($displayNames as $i => $displayName) { $policies[] = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => $i === 0 ? 'resume-token-a' : 'resume-token-b', 'platform' => 'windows', @@ -84,7 +84,7 @@ foreach ($policies as $policy) { InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, @@ -101,7 +101,7 @@ public function __construct() {} public function capture( Policy $policy, - \App\Models\Tenant $tenant, + \App\Models\ManagedEnvironment $tenant, bool $includeAssignments = false, bool $includeScopeTags = false, ?string $createdBy = null, @@ -111,7 +111,7 @@ public function capture( ?int $baselineProfileId = null, ): array { $version = \App\Models\PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -223,7 +223,7 @@ public function capture( ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'missing-capture-policy', 'policy_type' => 'deviceConfiguration', @@ -239,7 +239,7 @@ public function __construct() {} public function capture( Policy $policy, - \App\Models\Tenant $tenant, + \App\Models\ManagedEnvironment $tenant, bool $includeAssignments = false, bool $includeScopeTags = false, ?string $createdBy = null, diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareStatsTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareStatsTest.php index 52fdb9c4..06f08e53 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareStatsTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareStatsTest.php @@ -36,7 +36,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -72,7 +72,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -98,7 +98,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -125,12 +125,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'queued', @@ -159,12 +159,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', @@ -198,7 +198,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -206,7 +206,7 @@ Finding::factory()->count(2)->create([ 'workspace_id' => $tenant->workspace_id, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => $scopeKey, @@ -216,7 +216,7 @@ Finding::factory()->create([ 'workspace_id' => $tenant->workspace_id, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => $scopeKey, @@ -226,7 +226,7 @@ Finding::factory()->create([ 'workspace_id' => $tenant->workspace_id, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => $scopeKey, @@ -237,7 +237,7 @@ // Terminal finding should not be counted in "open" drift totals. Finding::factory()->create([ 'workspace_id' => $tenant->workspace_id, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => $scopeKey, @@ -246,7 +246,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', @@ -283,7 +283,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -303,7 +303,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -312,7 +312,7 @@ // New finding (should be counted) Finding::factory()->create([ 'workspace_id' => $tenant->workspace_id, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => $scopeKey, @@ -323,7 +323,7 @@ // Resolved finding (should NOT be counted) Finding::factory()->create([ 'workspace_id' => $tenant->workspace_id, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => $scopeKey, @@ -353,12 +353,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', @@ -380,18 +380,18 @@ Finding::factory()->triaged()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'due_at' => now()->subDay(), ]); $expiringFinding = Finding::factory()->riskAccepted()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $expiringFinding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -410,12 +410,12 @@ $lapsedFinding = Finding::factory()->riskAccepted()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $lapsedFinding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -434,12 +434,12 @@ Finding::factory()->inProgress()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); Finding::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => Finding::SEVERITY_HIGH, 'status' => Finding::STATUS_NEW, ]); diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareStrategySelectionTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareStrategySelectionTest.php index 9e768d0c..c15cbedf 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareStrategySelectionTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareStrategySelectionTest.php @@ -60,7 +60,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -98,7 +98,7 @@ ]); $inventorySyncRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::InventorySync->value, 'status' => OperationRunStatus::Completed->value, @@ -117,7 +117,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => $externalId, 'policy_type' => 'conditionalAccessPolicy', @@ -151,7 +151,7 @@ ->and(data_get($run->context, 'findings.counts_by_change_type.different_version'))->toBe(1) ->and(data_get($run->context, 'result.findings_total'))->toBe(1); - $finding = Finding::query()->where('tenant_id', (int) $tenant->getKey())->first(); + $finding = Finding::query()->where('managed_environment_id', (int) $tenant->getKey())->first(); expect($finding)->not->toBeNull() ->and($finding?->subject_type)->toBe('control') diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareSummaryAssessmentTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareSummaryAssessmentTest.php index 404d9825..e66c3846 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareSummaryAssessmentTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareSummaryAssessmentTest.php @@ -32,7 +32,7 @@ function createAssignedBaselineTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -43,7 +43,7 @@ function createAssignedBaselineTenant(): array [$tenant, $profile, $snapshot] = createAssignedBaselineTenant(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -76,7 +76,7 @@ function createAssignedBaselineTenant(): array [$tenant, $profile, $snapshot] = createAssignedBaselineTenant(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -109,7 +109,7 @@ function createAssignedBaselineTenant(): array [$tenant, $profile, $snapshot] = createAssignedBaselineTenant(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -132,7 +132,7 @@ function createAssignedBaselineTenant(): array [$tenant, $profile, $snapshot] = createAssignedBaselineTenant(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -164,7 +164,7 @@ function createAssignedBaselineTenant(): array [$tenant, $profile, $snapshot] = createAssignedBaselineTenant(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -186,7 +186,7 @@ function createAssignedBaselineTenant(): array Finding::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => 'baseline_profile:'.$profile->getKey(), @@ -205,7 +205,7 @@ function createAssignedBaselineTenant(): array [$tenant, $profile, $snapshot] = createAssignedBaselineTenant(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -228,14 +228,14 @@ function createAssignedBaselineTenant(): array Finding::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'status' => Finding::STATUS_TRIAGED, 'due_at' => now()->subDay(), ]); Finding::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'status' => Finding::STATUS_RISK_ACCEPTED, ]); @@ -258,7 +258,7 @@ function createAssignedBaselineTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -275,7 +275,7 @@ function createAssignedBaselineTenant(): array [$user] = createUserWithTenant(tenant: $tenant, role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -298,13 +298,13 @@ function createAssignedBaselineTenant(): array $finding = Finding::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'status' => Finding::STATUS_RISK_ACCEPTED, ]); FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), diff --git a/apps/platform/tests/Feature/Baselines/BaselineCompareWhyNoFindingsReasonCodeTest.php b/apps/platform/tests/Feature/Baselines/BaselineCompareWhyNoFindingsReasonCodeTest.php index e650d580..408a77b1 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineCompareWhyNoFindingsReasonCodeTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineCompareWhyNoFindingsReasonCodeTest.php @@ -44,7 +44,7 @@ $profile->update(['active_snapshot_id' => (int) $snapshot->getKey()]); $inventorySyncRun = \App\Models\OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::InventorySync->value, 'status' => OperationRunStatus::Completed->value, @@ -149,7 +149,7 @@ ]); $inventorySyncRun = \App\Models\OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::InventorySync->value, 'status' => OperationRunStatus::Completed->value, @@ -168,7 +168,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => $externalId, 'policy_type' => 'deviceConfiguration', @@ -231,7 +231,7 @@ $profile->update(['active_snapshot_id' => (int) $snapshot->getKey()]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'rbac-role-stable', 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -239,7 +239,7 @@ ]); $baselineVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -265,7 +265,7 @@ ]); $currentVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -321,7 +321,7 @@ ]); $inventorySyncRun = \App\Models\OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::InventorySync->value, 'status' => OperationRunStatus::Completed->value, @@ -342,7 +342,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'rbac-role-stable', 'policy_type' => 'intuneRoleDefinition', @@ -421,7 +421,7 @@ $profile->update(['active_snapshot_id' => (int) $snapshot->getKey()]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'stable-policy', 'platform' => 'windows', @@ -473,7 +473,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => (string) $policy->external_id, 'policy_type' => (string) $policy->policy_type, @@ -489,7 +489,7 @@ ]); $existingVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'platform' => (string) $policy->platform, @@ -509,7 +509,7 @@ public function __construct( public function capture( Policy $policy, - \App\Models\Tenant $tenant, + \App\Models\ManagedEnvironment $tenant, bool $includeAssignments = false, bool $includeScopeTags = false, ?string $createdBy = null, @@ -562,7 +562,7 @@ public function capture( expect(data_get($compareRun->context, 'baseline_compare.evidence_gaps.count'))->toBe(0); expect( Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->count(), )->toBe(0); diff --git a/apps/platform/tests/Feature/Baselines/BaselineGapContractCleanupTest.php b/apps/platform/tests/Feature/Baselines/BaselineGapContractCleanupTest.php index 5003ead0..4250cfa1 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineGapContractCleanupTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineGapContractCleanupTest.php @@ -15,7 +15,7 @@ [, $tenant] = createUserWithTenant(role: 'owner'); $legacyCompare = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -36,7 +36,7 @@ ]); $legacyCapture = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCapture->value, 'status' => OperationRunStatus::Completed->value, @@ -57,7 +57,7 @@ ]); $structuredCompare = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -85,7 +85,7 @@ [, $tenant] = createUserWithTenant(role: 'owner'); $legacyCompare = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -106,7 +106,7 @@ ]); $structuredCompare = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -117,7 +117,7 @@ ]); $structuredCapture = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCapture->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/Baselines/BaselineOperabilityAutoCloseTest.php b/apps/platform/tests/Feature/Baselines/BaselineOperabilityAutoCloseTest.php index 216c4e32..bd69f81c 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineOperabilityAutoCloseTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineOperabilityAutoCloseTest.php @@ -6,7 +6,7 @@ use App\Models\BaselineSnapshotItem; use App\Models\Finding; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceSetting; use App\Services\Baselines\BaselineAutoCloseService; @@ -18,7 +18,7 @@ use App\Support\OperationRunType; /** - * @return array{0: User, 1: Tenant, 2: BaselineProfile, 3: BaselineSnapshot} + * @return array{0: User, 1: ManagedEnvironment, 2: BaselineProfile, 3: BaselineSnapshot} */ function createBaselineOperabilityFixture(): array { @@ -41,7 +41,7 @@ function createBaselineOperabilityFixture(): array function runBaselineCompareForSnapshot( User $user, - Tenant $tenant, + ManagedEnvironment $tenant, BaselineProfile $profile, BaselineSnapshot $snapshot, ): OperationRun { @@ -89,7 +89,7 @@ function runBaselineCompareForSnapshot( $firstRun = runBaselineCompareForSnapshot($user, $tenant, $profile, $firstSnapshot); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->first(); @@ -178,7 +178,7 @@ function runBaselineCompareForSnapshot( $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/Baselines/BaselineResolutionDeterminismTest.php b/apps/platform/tests/Feature/Baselines/BaselineResolutionDeterminismTest.php index e6db3bae..11b03828 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineResolutionDeterminismTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineResolutionDeterminismTest.php @@ -77,7 +77,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'deterministic-policy', 'policy_type' => 'deviceConfiguration', @@ -88,7 +88,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'deterministic-foundation', 'policy_type' => 'roleScopeTag', @@ -100,7 +100,7 @@ $captureRunA = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCapture->value, 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -119,7 +119,7 @@ $captureRunB = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCapture->value, 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -143,7 +143,7 @@ $compareRunA = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -162,7 +162,7 @@ $compareRunB = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, diff --git a/apps/platform/tests/Feature/Baselines/BaselineResumeCaptureAuditEventsTest.php b/apps/platform/tests/Feature/Baselines/BaselineResumeCaptureAuditEventsTest.php index efb2f2ac..0e12e128 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineResumeCaptureAuditEventsTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineResumeCaptureAuditEventsTest.php @@ -51,7 +51,7 @@ expect($result['ok'] ?? false)->toBeTrue(); $audit = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'baseline.evidence.resume.started') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Baselines/BaselineSupportCapabilityGuardTest.php b/apps/platform/tests/Feature/Baselines/BaselineSupportCapabilityGuardTest.php index d0dcc797..0acc4b8e 100644 --- a/apps/platform/tests/Feature/Baselines/BaselineSupportCapabilityGuardTest.php +++ b/apps/platform/tests/Feature/Baselines/BaselineSupportCapabilityGuardTest.php @@ -63,7 +63,7 @@ function appendBrokenFoundationSupportConfig(): void BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); diff --git a/apps/platform/tests/Feature/Baselines/Support/FakeCompareStrategy.php b/apps/platform/tests/Feature/Baselines/Support/FakeCompareStrategy.php index c130f2af..c43319de 100644 --- a/apps/platform/tests/Feature/Baselines/Support/FakeCompareStrategy.php +++ b/apps/platform/tests/Feature/Baselines/Support/FakeCompareStrategy.php @@ -4,7 +4,7 @@ namespace Tests\Feature\Baselines\Support; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\Evidence\EvidenceProvenance; use App\Services\Baselines\Evidence\ResolvedEvidence; use App\Support\Baselines\Compare\CompareFindingCandidate; @@ -46,7 +46,7 @@ public function capabilities(): array public function compare( CompareOrchestrationContext $context, - Tenant $tenant, + ManagedEnvironment $tenant, array $baselineItems, array $currentItems, array $resolvedCurrentEvidence, @@ -352,7 +352,7 @@ public function capabilities(): array public function compare( CompareOrchestrationContext $context, - Tenant $tenant, + ManagedEnvironment $tenant, array $baselineItems, array $currentItems, array $resolvedCurrentEvidence, diff --git a/apps/platform/tests/Feature/Baselines/TenantGovernanceAggregateResolverTest.php b/apps/platform/tests/Feature/Baselines/TenantGovernanceAggregateResolverTest.php index 2a610cc4..6227f2b3 100644 --- a/apps/platform/tests/Feature/Baselines/TenantGovernanceAggregateResolverTest.php +++ b/apps/platform/tests/Feature/Baselines/TenantGovernanceAggregateResolverTest.php @@ -8,7 +8,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Baselines\BaselineCompareReasonCode; use App\Support\Baselines\BaselineCompareSummaryAssessment; @@ -35,7 +35,7 @@ function createTenantGovernanceAggregateTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -46,10 +46,10 @@ function createTenantGovernanceAggregateTenant(): array * @param array $attributes * @param array $compareContext */ -function seedTenantGovernanceAggregateRun(Tenant $tenant, BaselineProfile $profile, BaselineSnapshot $snapshot, array $attributes = [], array $compareContext = []): OperationRun +function seedTenantGovernanceAggregateRun(ManagedEnvironment $tenant, BaselineProfile $profile, BaselineSnapshot $snapshot, array $attributes = [], array $compareContext = []): OperationRun { return OperationRun::factory()->create(array_replace_recursive([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -71,11 +71,11 @@ function seedTenantGovernanceAggregateRun(Tenant $tenant, BaselineProfile $profi ], $attributes)); } -function createTenantGovernanceException(Tenant $tenant, Finding $finding, User $user, string $status, string $validityState, ?\Carbon\CarbonInterface $expiresAt = null): void +function createTenantGovernanceException(ManagedEnvironment $tenant, Finding $finding, User $user, string $status, string $validityState, ?\Carbon\CarbonInterface $expiresAt = null): void { FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -103,7 +103,7 @@ function createTenantGovernanceException(Tenant $tenant, Finding $finding, User BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -168,7 +168,7 @@ function createTenantGovernanceException(Tenant $tenant, Finding $finding, User Finding::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => 'baseline_profile:'.$profile->getKey(), @@ -192,7 +192,7 @@ function createTenantGovernanceException(Tenant $tenant, Finding $finding, User Finding::factory()->triaged()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'due_at' => now()->subDay(), ]); @@ -213,7 +213,7 @@ function createTenantGovernanceException(Tenant $tenant, Finding $finding, User $finding = Finding::factory()->riskAccepted()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); createTenantGovernanceException( @@ -242,7 +242,7 @@ function createTenantGovernanceException(Tenant $tenant, Finding $finding, User $finding = Finding::factory()->riskAccepted()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); createTenantGovernanceException( diff --git a/apps/platform/tests/Feature/BulkDeleteBackupSetsTest.php b/apps/platform/tests/Feature/BulkDeleteBackupSetsTest.php index 9b0e7cbc..56e6aac4 100644 --- a/apps/platform/tests/Feature/BulkDeleteBackupSetsTest.php +++ b/apps/platform/tests/Feature/BulkDeleteBackupSetsTest.php @@ -5,7 +5,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -14,7 +14,7 @@ uses(RefreshDatabase::class); test('backup sets table bulk archive creates a run and archives selected sets', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -24,7 +24,7 @@ $sets = collect(range(1, 3))->map(function (int $i) use ($tenant) { return BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup '.$i, 'status' => 'completed', 'item_count' => 1, @@ -33,7 +33,7 @@ $sets->each(function (BackupSet $set) use ($tenant) { BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $set->id, 'policy_id' => null, 'policy_identifier' => 'policy-'.$set->id, @@ -52,7 +52,7 @@ $sets->each(fn (BackupSet $set) => expect(BackupSet::withTrashed()->find($set->id)?->trashed())->toBeTrue()); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('user_id', $user->id) ->where('type', 'backup_set.delete') ->latest('id') @@ -63,7 +63,7 @@ }); test('backup sets can be archived even when referenced by restore runs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -72,14 +72,14 @@ Filament::setTenant($tenant, true); $set = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $set->id, 'status' => 'completed', 'is_dry_run' => true, @@ -96,7 +96,7 @@ }); test('backup sets table bulk archive requires type-to-confirm for 10+ sets', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -106,7 +106,7 @@ $sets = collect(range(1, 10))->map(function (int $i) use ($tenant) { return BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup '.$i, 'status' => 'completed', 'item_count' => 0, diff --git a/apps/platform/tests/Feature/BulkDeleteMixedStatusTest.php b/apps/platform/tests/Feature/BulkDeleteMixedStatusTest.php index 5969c390..e2391d2a 100644 --- a/apps/platform/tests/Feature/BulkDeleteMixedStatusTest.php +++ b/apps/platform/tests/Feature/BulkDeleteMixedStatusTest.php @@ -4,7 +4,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); test('bulk delete restore runs skips running items', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -22,7 +22,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, @@ -30,7 +30,7 @@ $completedRuns = collect(range(1, 3))->map(function () use ($tenant, $backupSet) { return RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, @@ -39,7 +39,7 @@ }); $running = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'running', 'is_dry_run' => true, @@ -57,7 +57,7 @@ expect(RestoreRun::withTrashed()->find($running->id)?->trashed())->toBeFalse(); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('user_id', $user->id) ->where('type', 'restore_run.delete') ->latest('id') diff --git a/apps/platform/tests/Feature/BulkDeletePoliciesAsyncTest.php b/apps/platform/tests/Feature/BulkDeletePoliciesAsyncTest.php index 62f7827e..2f4b0d10 100644 --- a/apps/platform/tests/Feature/BulkDeletePoliciesAsyncTest.php +++ b/apps/platform/tests/Feature/BulkDeletePoliciesAsyncTest.php @@ -2,7 +2,7 @@ use App\Jobs\BulkPolicyDeleteJob; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,9 +13,9 @@ test('bulk delete large batch dispatches async job', function () { Queue::fake(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); - $policies = Policy::factory()->count(25)->create(['tenant_id' => $tenant->id]); + $policies = Policy::factory()->count(25)->create(['managed_environment_id' => $tenant->id]); $policyIds = $policies->pluck('id')->toArray(); /** @var OperationRunService $service */ diff --git a/apps/platform/tests/Feature/BulkDeletePoliciesTest.php b/apps/platform/tests/Feature/BulkDeletePoliciesTest.php index 07297aec..e472bdf1 100644 --- a/apps/platform/tests/Feature/BulkDeletePoliciesTest.php +++ b/apps/platform/tests/Feature/BulkDeletePoliciesTest.php @@ -3,7 +3,7 @@ use App\Jobs\BulkPolicyDeleteJob; use App\Models\OperationRun; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Services\Operations\BulkSelectionIdentity; @@ -12,10 +12,10 @@ uses(RefreshDatabase::class); test('bulk delete sync execution updates policies immediately', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); createUserWithTenant(tenant: $tenant, user: $user, role: 'owner'); - $policies = Policy::factory()->count(10)->create(['tenant_id' => $tenant->id]); + $policies = Policy::factory()->count(10)->create(['managed_environment_id' => $tenant->id]); $policyIds = $policies->pluck('id')->toArray(); /** @var OperationRunService $service */ @@ -30,7 +30,7 @@ tenant: $tenant, type: 'policy.delete', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id ?? $tenant->getKey()), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id ?? $tenant->getKey()), ], selectionIdentity: $selectionIdentity, dispatcher: function ($operationRun) use ($tenant, $user, $policyIds): void { diff --git a/apps/platform/tests/Feature/BulkDeleteRestoreRunsTest.php b/apps/platform/tests/Feature/BulkDeleteRestoreRunsTest.php index 2bb1e108..6fab6141 100644 --- a/apps/platform/tests/Feature/BulkDeleteRestoreRunsTest.php +++ b/apps/platform/tests/Feature/BulkDeleteRestoreRunsTest.php @@ -4,7 +4,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); test('bulk delete restore runs soft deletes selected runs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -22,7 +22,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, @@ -30,7 +30,7 @@ $runs = collect(range(1, 5))->map(function () use ($tenant, $backupSet) { return RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, @@ -46,7 +46,7 @@ $runs->each(fn (RestoreRun $run) => expect(RestoreRun::withTrashed()->find($run->id)?->trashed())->toBeTrue()); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('user_id', $user->id) ->where('type', 'restore_run.delete') ->latest('id') diff --git a/apps/platform/tests/Feature/BulkExportFailuresTest.php b/apps/platform/tests/Feature/BulkExportFailuresTest.php index d6e76b15..5cc3c81a 100644 --- a/apps/platform/tests/Feature/BulkExportFailuresTest.php +++ b/apps/platform/tests/Feature/BulkExportFailuresTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -12,12 +12,12 @@ uses(RefreshDatabase::class); test('bulk export completes with errors when some policies cannot be exported', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); - $okPolicy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $okPolicy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $okPolicy->id, 'policy_type' => $okPolicy->policy_type, 'version_number' => 1, @@ -25,7 +25,7 @@ 'captured_at' => now(), ]); - $missingVersionPolicy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $missingVersionPolicy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); /** @var OperationRunService $service */ $service = app(OperationRunService::class); @@ -61,7 +61,7 @@ ]); $this->assertDatabaseHas('backup_sets', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Failures Backup', ]); }); diff --git a/apps/platform/tests/Feature/BulkExportToBackupTest.php b/apps/platform/tests/Feature/BulkExportToBackupTest.php index 6433942f..45c3396a 100644 --- a/apps/platform/tests/Feature/BulkExportToBackupTest.php +++ b/apps/platform/tests/Feature/BulkExportToBackupTest.php @@ -5,7 +5,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,12 +13,12 @@ uses(RefreshDatabase::class); test('bulk export creates backup set with items', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'policy_type' => $policy->policy_type, 'version_number' => 1, @@ -27,7 +27,7 @@ ]); $opRun = OperationRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'initiator_name' => $user->name, 'type' => 'policy.export', @@ -56,21 +56,21 @@ $this->assertDatabaseHas('backup_sets', [ 'name' => 'Feature Backup', - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); }); test('bulk export blocks provider-missing policies before creating items', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'missing_from_provider_at' => now(), ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'policy_type' => $policy->policy_type, 'version_number' => 1, @@ -79,7 +79,7 @@ ]); $opRun = OperationRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'initiator_name' => $user->name, 'type' => 'policy.export', diff --git a/apps/platform/tests/Feature/BulkForceDeleteBackupSetsTest.php b/apps/platform/tests/Feature/BulkForceDeleteBackupSetsTest.php index 085b90fa..5f97344a 100644 --- a/apps/platform/tests/Feature/BulkForceDeleteBackupSetsTest.php +++ b/apps/platform/tests/Feature/BulkForceDeleteBackupSetsTest.php @@ -4,7 +4,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); test('backup sets table bulk force delete permanently deletes archived sets and their items', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -22,14 +22,14 @@ Filament::setTenant($tenant, true); $set = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $item = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $set->id, 'policy_id' => null, 'policy_identifier' => 'policy-1', @@ -51,7 +51,7 @@ expect(BackupItem::withTrashed()->find($item->id))->toBeNull(); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('user_id', $user->id) ->where('type', 'backup_set.force_delete') ->latest('id') diff --git a/apps/platform/tests/Feature/BulkForceDeletePolicyVersionsTest.php b/apps/platform/tests/Feature/BulkForceDeletePolicyVersionsTest.php index d4dae8fa..5303db97 100644 --- a/apps/platform/tests/Feature/BulkForceDeletePolicyVersionsTest.php +++ b/apps/platform/tests/Feature/BulkForceDeletePolicyVersionsTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); test('policy versions table bulk force delete creates a run and skips non-archived records', function () { - $tenant = Tenant::factory()->create(['is_current' => true]); + $tenant = ManagedEnvironment::factory()->create(['is_current' => true]); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -21,9 +21,9 @@ Filament::setTenant($tenant, true); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), @@ -39,7 +39,7 @@ ->assertHasNoTableBulkActionErrors(); $run = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('user_id', $user->id) ->where('type', 'policy_version.force_delete') ->latest('id') diff --git a/apps/platform/tests/Feature/BulkForceDeleteRestoreRunsTest.php b/apps/platform/tests/Feature/BulkForceDeleteRestoreRunsTest.php index 0cb04426..dd7d342b 100644 --- a/apps/platform/tests/Feature/BulkForceDeleteRestoreRunsTest.php +++ b/apps/platform/tests/Feature/BulkForceDeleteRestoreRunsTest.php @@ -4,7 +4,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); test('bulk force delete restore runs permanently deletes archived runs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -22,7 +22,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, @@ -30,7 +30,7 @@ $runs = collect(range(1, 3))->map(function () use ($tenant, $backupSet) { $run = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, @@ -53,7 +53,7 @@ $runs->each(fn (RestoreRun $run) => expect(RestoreRun::withTrashed()->find($run->id))->toBeNull()); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'restore_run.force_delete') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/BulkProgressNotificationTest.php b/apps/platform/tests/Feature/BulkProgressNotificationTest.php index f1f8b4a9..bdc6ab2b 100644 --- a/apps/platform/tests/Feature/BulkProgressNotificationTest.php +++ b/apps/platform/tests/Feature/BulkProgressNotificationTest.php @@ -15,7 +15,7 @@ // Active op OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'initiator_name' => $user->name, 'type' => 'policy.delete', @@ -26,7 +26,7 @@ // Completed op (should not show) OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'initiator_name' => $user->name, 'type' => 'policy.delete', @@ -47,7 +47,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'initiator_name' => $user->name, 'type' => 'backup_schedule_run', diff --git a/apps/platform/tests/Feature/BulkPruneSkipReasonsTest.php b/apps/platform/tests/Feature/BulkPruneSkipReasonsTest.php index 97fc3fa3..0174f264 100644 --- a/apps/platform/tests/Feature/BulkPruneSkipReasonsTest.php +++ b/apps/platform/tests/Feature/BulkPruneSkipReasonsTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); test('bulk prune records skip reasons', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -21,23 +21,23 @@ Filament::setTenant($tenant, true); - $policyA = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policyA = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $current = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policyA->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), ]); - $policyB = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policyB = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $tooRecent = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policyB->id, 'version_number' => 1, 'captured_at' => now()->subDays(10), ]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policyB->id, 'version_number' => 2, 'captured_at' => now()->subDays(10), @@ -51,7 +51,7 @@ ->assertHasNoTableBulkActionErrors(); $run = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('user_id', $user->id) ->where('type', 'policy_version.prune') ->latest('id') diff --git a/apps/platform/tests/Feature/BulkPruneVersionsTest.php b/apps/platform/tests/Feature/BulkPruneVersionsTest.php index d9cbe48f..62aa3bb4 100644 --- a/apps/platform/tests/Feature/BulkPruneVersionsTest.php +++ b/apps/platform/tests/Feature/BulkPruneVersionsTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\PolicyVersionResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -12,7 +12,7 @@ uses(RefreshDatabase::class); test('bulk prune archives eligible policy versions', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -20,17 +20,17 @@ Filament::setTenant($tenant, true); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $eligible = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), ]); $current = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 2, 'captured_at' => now()->subDays(120), diff --git a/apps/platform/tests/Feature/BulkRestoreBackupSetsTest.php b/apps/platform/tests/Feature/BulkRestoreBackupSetsTest.php index 2d4a62dc..b27c90ea 100644 --- a/apps/platform/tests/Feature/BulkRestoreBackupSetsTest.php +++ b/apps/platform/tests/Feature/BulkRestoreBackupSetsTest.php @@ -4,7 +4,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); test('backup sets table bulk restore restores archived sets and their items', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -22,14 +22,14 @@ Filament::setTenant($tenant, true); $set = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $item = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $set->id, 'policy_id' => null, 'policy_identifier' => 'policy-1', @@ -54,7 +54,7 @@ expect($item->trashed())->toBeFalse(); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('user_id', $user->id) ->where('type', 'backup_set.restore') ->latest('id') diff --git a/apps/platform/tests/Feature/BulkRestorePolicyVersionsTest.php b/apps/platform/tests/Feature/BulkRestorePolicyVersionsTest.php index fdab5fe0..e35cfda8 100644 --- a/apps/platform/tests/Feature/BulkRestorePolicyVersionsTest.php +++ b/apps/platform/tests/Feature/BulkRestorePolicyVersionsTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); test('policy versions table bulk restore creates a run and restores archived records', function () { - $tenant = Tenant::factory()->create(['is_current' => true]); + $tenant = ManagedEnvironment::factory()->create(['is_current' => true]); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -21,9 +21,9 @@ Filament::setTenant($tenant, true); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), @@ -37,7 +37,7 @@ ->assertHasNoTableBulkActionErrors(); $run = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('user_id', $user->id) ->where('type', 'policy_version.restore') ->latest('id') diff --git a/apps/platform/tests/Feature/BulkRestoreRestoreRunsTest.php b/apps/platform/tests/Feature/BulkRestoreRestoreRunsTest.php index ab2cf8f0..30a27939 100644 --- a/apps/platform/tests/Feature/BulkRestoreRestoreRunsTest.php +++ b/apps/platform/tests/Feature/BulkRestoreRestoreRunsTest.php @@ -4,7 +4,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); test('restore runs table bulk restore creates a run and restores archived records', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], @@ -22,14 +22,14 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $run = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, @@ -46,7 +46,7 @@ ->assertHasNoTableBulkActionErrors(); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('user_id', $user->id) ->where('type', 'restore_run.restore') ->latest('id') diff --git a/apps/platform/tests/Feature/BulkSyncPoliciesTest.php b/apps/platform/tests/Feature/BulkSyncPoliciesTest.php index 3b7c5476..e61820ed 100644 --- a/apps/platform/tests/Feature/BulkSyncPoliciesTest.php +++ b/apps/platform/tests/Feature/BulkSyncPoliciesTest.php @@ -2,7 +2,7 @@ use App\Jobs\SyncPoliciesJob; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -12,7 +12,7 @@ uses(RefreshDatabase::class); test('policy sync updates selected policies from graph and updates the operation run', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', ]); $tenant->makeCurrent(); @@ -25,7 +25,7 @@ $policies = Policy::factory() ->count(3) ->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_type' => 'deviceConfiguration', 'platform' => 'windows10AndLater', 'last_synced_at' => null, diff --git a/apps/platform/tests/Feature/BulkTypeToConfirmTest.php b/apps/platform/tests/Feature/BulkTypeToConfirmTest.php index 43a78a91..493a8e2e 100644 --- a/apps/platform/tests/Feature/BulkTypeToConfirmTest.php +++ b/apps/platform/tests/Feature/BulkTypeToConfirmTest.php @@ -2,7 +2,7 @@ use App\Filament\Resources\PolicyResource; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -11,14 +11,14 @@ uses(RefreshDatabase::class); test('bulk delete requires confirmation string for large batches', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], ]); Filament::setTenant($tenant, true); - $policies = Policy::factory()->count(20)->create(['tenant_id' => $tenant->id]); + $policies = Policy::factory()->count(20)->create(['managed_environment_id' => $tenant->id]); Livewire::actingAs($user) ->test(PolicyResource\Pages\ListPolicies::class) @@ -31,14 +31,14 @@ }); test('bulk delete fails with incorrect confirmation string', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], ]); Filament::setTenant($tenant, true); - $policies = Policy::factory()->count(20)->create(['tenant_id' => $tenant->id]); + $policies = Policy::factory()->count(20)->create(['managed_environment_id' => $tenant->id]); Livewire::actingAs($user) ->test(PolicyResource\Pages\ListPolicies::class) @@ -51,14 +51,14 @@ }); test('bulk delete does not require confirmation string for small batches', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], ]); Filament::setTenant($tenant, true); - $policies = Policy::factory()->count(10)->create(['tenant_id' => $tenant->id]); + $policies = Policy::factory()->count(10)->create(['managed_environment_id' => $tenant->id]); Livewire::actingAs($user) ->test(PolicyResource\Pages\ListPolicies::class) diff --git a/apps/platform/tests/Feature/BulkUnignorePoliciesTest.php b/apps/platform/tests/Feature/BulkUnignorePoliciesTest.php index 62426b09..99448616 100644 --- a/apps/platform/tests/Feature/BulkUnignorePoliciesTest.php +++ b/apps/platform/tests/Feature/BulkUnignorePoliciesTest.php @@ -3,27 +3,27 @@ use App\Jobs\BulkPolicyUnignoreJob; use App\Models\OperationRun; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('bulk restore (unignore) clears ignored_at for selected policies', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $policies = Policy::factory() ->count(5) ->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => now(), ]); $policyIds = $policies->pluck('id')->toArray(); $opRun = OperationRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'initiator_name' => $user->name, 'type' => 'policy.unignore', diff --git a/apps/platform/tests/Feature/Concerns/BuildsBaselineCompareMatrixFixtures.php b/apps/platform/tests/Feature/Concerns/BuildsBaselineCompareMatrixFixtures.php index d9f04127..38fc9aa7 100644 --- a/apps/platform/tests/Feature/Concerns/BuildsBaselineCompareMatrixFixtures.php +++ b/apps/platform/tests/Feature/Concerns/BuildsBaselineCompareMatrixFixtures.php @@ -10,7 +10,7 @@ use App\Models\BaselineTenantAssignment; use App\Models\Finding; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -31,9 +31,9 @@ trait BuildsBaselineCompareMatrixFixtures * workspace: Workspace, * profile: BaselineProfile, * snapshot: BaselineSnapshot, - * visibleTenant: Tenant, - * visibleTenantTwo: Tenant, - * hiddenTenant: Tenant, + * visibleTenant: ManagedEnvironment, + * visibleTenantTwo: ManagedEnvironment, + * hiddenTenant: ManagedEnvironment, * subjects: array * } */ @@ -67,12 +67,12 @@ protected function makeBaselineCompareMatrixFixture( 'active_snapshot_id' => (int) $snapshot->getKey(), ])->save(); - $visibleTenantTwo = Tenant::factory()->create([ + $visibleTenantTwo = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'name' => 'Northwind', ]); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'name' => 'Hidden Fabrikam', ]); @@ -137,12 +137,12 @@ protected function makeBaselineCompareMatrixSubject( ]); } - protected function assignTenantToBaselineProfile(BaselineProfile $profile, Tenant $tenant): BaselineTenantAssignment + protected function assignTenantToBaselineProfile(BaselineProfile $profile, ManagedEnvironment $tenant): BaselineTenantAssignment { return BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $profile->workspace_id, 'baseline_profile_id' => (int) $profile->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); } @@ -151,14 +151,14 @@ protected function assignTenantToBaselineProfile(BaselineProfile $profile, Tenan * @param array $attributes */ protected function makeBaselineCompareMatrixRun( - Tenant $tenant, + ManagedEnvironment $tenant, BaselineProfile $profile, BaselineSnapshot $snapshot, array $contextOverrides = [], array $attributes = [], ): OperationRun { $defaults = [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -201,14 +201,14 @@ protected function makeBaselineCompareMatrixRun( * @param array $overrides */ protected function makeBaselineCompareMatrixFinding( - Tenant $tenant, + ManagedEnvironment $tenant, BaselineProfile $profile, OperationRun $run, string $subjectKey, array $overrides = [], ): Finding { $defaults = [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', @@ -240,7 +240,7 @@ protected function baselineCompareMatrixGap(string $policyType, string $subjectK ], $overrides)); } - protected function setAdminWorkspaceContext(User $user, Workspace|int $workspace, ?Tenant $rememberedTenant = null): array + protected function setAdminWorkspaceContext(User $user, Workspace|int $workspace, ?ManagedEnvironment $rememberedTenant = null): array { $workspaceId = $workspace instanceof Workspace ? (int) $workspace->getKey() : (int) $workspace; @@ -248,7 +248,7 @@ protected function setAdminWorkspaceContext(User $user, Workspace|int $workspace WorkspaceContext::SESSION_KEY => $workspaceId, ]; - if ($rememberedTenant instanceof Tenant) { + if ($rememberedTenant instanceof ManagedEnvironment) { $session[WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY] = [ (string) $workspaceId => (int) $rememberedTenant->getKey(), ]; @@ -257,7 +257,7 @@ protected function setAdminWorkspaceContext(User $user, Workspace|int $workspace $this->actingAs($user)->withSession($session); session()->put(WorkspaceContext::SESSION_KEY, $workspaceId); - if ($rememberedTenant instanceof Tenant) { + if ($rememberedTenant instanceof ManagedEnvironment) { session()->put(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY, [ (string) $workspaceId => (int) $rememberedTenant->getKey(), ]); diff --git a/apps/platform/tests/Feature/Concerns/BuildsGovernanceArtifactTruthFixtures.php b/apps/platform/tests/Feature/Concerns/BuildsGovernanceArtifactTruthFixtures.php index 49ba4954..1e47cdc7 100644 --- a/apps/platform/tests/Feature/Concerns/BuildsGovernanceArtifactTruthFixtures.php +++ b/apps/platform/tests/Feature/Concerns/BuildsGovernanceArtifactTruthFixtures.php @@ -7,7 +7,7 @@ use App\Models\EvidenceSnapshot; use App\Models\OperationRun; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Support\Evidence\EvidenceCompletenessState; @@ -21,12 +21,12 @@ trait BuildsGovernanceArtifactTruthFixtures { protected function makeArtifactTruthEvidenceSnapshot( - Tenant $tenant, + ManagedEnvironment $tenant, array $snapshotOverrides = [], array $summaryOverrides = [], ): EvidenceSnapshot { $defaults = [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -46,7 +46,7 @@ protected function makeArtifactTruthEvidenceSnapshot( } protected function makeStaleArtifactTruthEvidenceSnapshot( - Tenant $tenant, + ManagedEnvironment $tenant, array $snapshotOverrides = [], array $summaryOverrides = [], ): EvidenceSnapshot { @@ -63,7 +63,7 @@ protected function makeStaleArtifactTruthEvidenceSnapshot( } protected function makePartialArtifactTruthEvidenceSnapshot( - Tenant $tenant, + ManagedEnvironment $tenant, array $snapshotOverrides = [], array $summaryOverrides = [], ): EvidenceSnapshot { @@ -80,7 +80,7 @@ protected function makePartialArtifactTruthEvidenceSnapshot( } protected function makeMissingArtifactTruthEvidenceSnapshot( - Tenant $tenant, + ManagedEnvironment $tenant, array $snapshotOverrides = [], array $summaryOverrides = [], ): EvidenceSnapshot { @@ -98,7 +98,7 @@ protected function makeMissingArtifactTruthEvidenceSnapshot( } protected function makeArtifactTruthReview( - Tenant $tenant, + ManagedEnvironment $tenant, User $user, ?EvidenceSnapshot $snapshot = null, array $reviewOverrides = [], @@ -107,7 +107,7 @@ protected function makeArtifactTruthReview( $snapshot ??= $this->makeArtifactTruthEvidenceSnapshot($tenant); $defaults = [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), @@ -134,7 +134,7 @@ protected function makeArtifactTruthReview( } protected function makePartialArtifactTruthReview( - Tenant $tenant, + ManagedEnvironment $tenant, User $user, ?EvidenceSnapshot $snapshot = null, array $reviewOverrides = [], @@ -160,7 +160,7 @@ protected function makePartialArtifactTruthReview( } protected function makeBlockedArtifactTruthReview( - Tenant $tenant, + ManagedEnvironment $tenant, User $user, ?EvidenceSnapshot $snapshot = null, array $reviewOverrides = [], @@ -181,7 +181,7 @@ protected function makeBlockedArtifactTruthReview( } protected function makeInternalOnlyArtifactTruthReview( - Tenant $tenant, + ManagedEnvironment $tenant, User $user, ?EvidenceSnapshot $snapshot = null, array $reviewOverrides = [], @@ -209,7 +209,7 @@ protected function makeInternalOnlyArtifactTruthReview( } protected function makeArtifactTruthReviewPack( - Tenant $tenant, + ManagedEnvironment $tenant, User $user, ?EvidenceSnapshot $snapshot = null, ?TenantReview $review = null, @@ -220,7 +220,7 @@ protected function makeArtifactTruthReviewPack( $review ??= $this->makeArtifactTruthReview($tenant, $user, $snapshot); $defaults = [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -252,7 +252,7 @@ protected function makeArtifactTruthReviewPack( } protected function makeBlockedArtifactTruthReviewPack( - Tenant $tenant, + ManagedEnvironment $tenant, User $user, ?EvidenceSnapshot $snapshot = null, ?TenantReview $review = null, @@ -279,7 +279,7 @@ protected function makeBlockedArtifactTruthReviewPack( } protected function makeInternalOnlyArtifactTruthReviewPack( - Tenant $tenant, + ManagedEnvironment $tenant, User $user, ?EvidenceSnapshot $snapshot = null, ?TenantReview $review = null, @@ -305,13 +305,13 @@ protected function makeInternalOnlyArtifactTruthReviewPack( } protected function makeArtifactTruthRun( - Tenant $tenant, + ManagedEnvironment $tenant, string $type, array $context = [], array $attributes = [], ): OperationRun { $defaults = [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => $type, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/Concerns/BuildsPortfolioCompareFixtures.php b/apps/platform/tests/Feature/Concerns/BuildsPortfolioCompareFixtures.php index 1945c41f..5a356595 100644 --- a/apps/platform/tests/Feature/Concerns/BuildsPortfolioCompareFixtures.php +++ b/apps/platform/tests/Feature/Concerns/BuildsPortfolioCompareFixtures.php @@ -7,7 +7,7 @@ use App\Models\InventoryItem; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -18,14 +18,14 @@ trait BuildsPortfolioCompareFixtures { /** - * @return array{user: User, workspace: Workspace, sourceTenant: Tenant, targetTenant: Tenant} + * @return array{user: User, workspace: Workspace, sourceTenant: ManagedEnvironment, targetTenant: ManagedEnvironment} */ protected function makeCrossTenantCompareFixture( string $workspaceRole = 'owner', string $tenantRole = 'owner', ): array { - $sourceTenant = Tenant::factory()->create([ - 'name' => 'Source Tenant', + $sourceTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Source ManagedEnvironment', ]); [$user, $sourceTenant] = createUserWithTenant( @@ -36,9 +36,9 @@ protected function makeCrossTenantCompareFixture( $workspace = Workspace::query()->findOrFail((int) $sourceTenant->workspace_id); - $targetTenant = Tenant::factory()->create([ + $targetTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Target Tenant', + 'name' => 'Target ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -77,14 +77,14 @@ protected function setAdminWorkspaceContext(User $user, Workspace $workspace): a * @return array{policy: Policy, version: PolicyVersion, inventory: InventoryItem} */ protected function createPortfolioCompareSubject( - Tenant $tenant, + ManagedEnvironment $tenant, string $displayName, array $snapshot, string $policyType = 'deviceConfiguration', ?string $externalId = null, ): array { $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => $policyType, 'external_id' => $externalId ?? str($displayName)->slug()->append('-')->append((string) str()->uuid())->toString(), 'display_name' => $displayName, @@ -92,7 +92,7 @@ protected function createPortfolioCompareSubject( ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => $policyType, 'platform' => 'windows', @@ -103,7 +103,7 @@ protected function createPortfolioCompareSubject( ]); $inventory = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => $policyType, 'external_id' => (string) $policy->external_id, 'display_name' => $displayName, diff --git a/apps/platform/tests/Feature/Concerns/BuildsPortfolioTriageFixtures.php b/apps/platform/tests/Feature/Concerns/BuildsPortfolioTriageFixtures.php index 527d4969..ab53ee00 100644 --- a/apps/platform/tests/Feature/Concerns/BuildsPortfolioTriageFixtures.php +++ b/apps/platform/tests/Feature/Concerns/BuildsPortfolioTriageFixtures.php @@ -7,7 +7,7 @@ use App\Filament\Resources\TenantResource\Pages\ListTenants; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Models\User; use App\Services\PortfolioTriage\TenantTriageReviewService; @@ -24,14 +24,14 @@ trait BuildsPortfolioTriageFixtures { /** - * @return array{0: User, 1: Tenant} + * @return array{0: User, 1: ManagedEnvironment} */ protected function makePortfolioTriageActor( - string $tenantName = 'Anchor Tenant', + string $tenantName = 'Anchor ManagedEnvironment', string $role = 'owner', string $workspaceRole = 'readonly', ): array { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'name' => $tenantName, ]); @@ -47,9 +47,9 @@ protected function makePortfolioTriageActor( return [$user, $tenant]; } - protected function makePortfolioTriagePeer(User $user, Tenant $workspaceTenant, string $name): Tenant + protected function makePortfolioTriagePeer(User $user, ManagedEnvironment $workspaceTenant, string $name): ManagedEnvironment { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $workspaceTenant->workspace_id, 'name' => $name, @@ -67,7 +67,7 @@ protected function makePortfolioTriagePeer(User $user, Tenant $workspaceTenant, return $tenant; } - protected function seedPortfolioBackupConcern(Tenant $tenant, string $state): ?BackupSet + protected function seedPortfolioBackupConcern(ManagedEnvironment $tenant, string $state): ?BackupSet { return match ($state) { TenantBackupHealthAssessment::POSTURE_ABSENT => null, @@ -90,7 +90,7 @@ protected function seedPortfolioBackupConcern(Tenant $tenant, string $state): ?B } protected function seedPortfolioRecoveryConcern( - Tenant $tenant, + ManagedEnvironment $tenant, string $reason = 'no_history', ?BackupSet $backupSet = null, ): ?RestoreRun { @@ -131,7 +131,7 @@ protected function seedPortfolioRecoveryConcern( }; } - protected function usePortfolioTriageWorkspace(User $user, Tenant $tenant): void + protected function usePortfolioTriageWorkspace(User $user, ManagedEnvironment $tenant): void { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -142,7 +142,7 @@ protected function usePortfolioTriageWorkspace(User $user, Tenant $tenant): void session()->forget('tables.'.md5(ListTenants::class).'_sort'); } - protected function portfolioTriageRegistryList(User $user, Tenant $workspaceTenant, array $query = []): mixed + protected function portfolioTriageRegistryList(User $user, ManagedEnvironment $workspaceTenant, array $query = []): mixed { $this->usePortfolioTriageWorkspace($user, $workspaceTenant); @@ -171,7 +171,7 @@ protected function portfolioReturnFilters( } protected function seedPortfolioTriageReview( - Tenant $tenant, + ManagedEnvironment $tenant, string $concernFamily, string $manualState = TenantTriageReview::STATE_REVIEWED, ?User $actor = null, diff --git a/apps/platform/tests/Feature/Console/ReconcileBackupScheduleOperationRunsCommandTest.php b/apps/platform/tests/Feature/Console/ReconcileBackupScheduleOperationRunsCommandTest.php index f2504fde..73624e20 100644 --- a/apps/platform/tests/Feature/Console/ReconcileBackupScheduleOperationRunsCommandTest.php +++ b/apps/platform/tests/Feature/Console/ReconcileBackupScheduleOperationRunsCommandTest.php @@ -2,17 +2,17 @@ use App\Models\BackupSchedule; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); it('reconciles stale running backup schedule operation runs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $schedule = BackupSchedule::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Daily', 'is_enabled' => true, 'timezone' => 'UTC', diff --git a/apps/platform/tests/Feature/Console/TenantpilotPurgeNonPersistentDataTest.php b/apps/platform/tests/Feature/Console/TenantpilotPurgeNonPersistentDataTest.php index 3b9d4bbf..24fc5973 100644 --- a/apps/platform/tests/Feature/Console/TenantpilotPurgeNonPersistentDataTest.php +++ b/apps/platform/tests/Feature/Console/TenantpilotPurgeNonPersistentDataTest.php @@ -12,15 +12,15 @@ use App\Models\RestoreRun; use App\Models\SettingsCatalogCategory; use App\Models\SettingsCatalogDefinition; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); it('purges non-persistent tenant data while preserving durable audit history', function (): void { - $tenantA = Tenant::factory()->create(['name' => 'Tenant A']); - $tenantB = Tenant::factory()->create(['name' => 'Tenant B']); + $tenantA = ManagedEnvironment::factory()->create(['name' => 'ManagedEnvironment A']); + $tenantB = ManagedEnvironment::factory()->create(['name' => 'ManagedEnvironment B']); SettingsCatalogCategory::create([ 'category_id' => 'cat-1', @@ -40,35 +40,35 @@ $user = User::factory()->create(); - $policyA = Policy::factory()->create(['tenant_id' => $tenantA->id]); - $policyB = Policy::factory()->create(['tenant_id' => $tenantB->id]); + $policyA = Policy::factory()->create(['managed_environment_id' => $tenantA->id]); + $policyB = Policy::factory()->create(['managed_environment_id' => $tenantB->id]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenantA->id, + 'managed_environment_id' => $tenantA->id, 'policy_id' => $policyA->id, 'version_number' => 1, ]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenantB->id, + 'managed_environment_id' => $tenantB->id, 'policy_id' => $policyB->id, 'version_number' => 1, ]); - $backupSetA = BackupSet::factory()->create(['tenant_id' => $tenantA->id]); + $backupSetA = BackupSet::factory()->create(['managed_environment_id' => $tenantA->id]); BackupItem::factory()->create([ - 'tenant_id' => $tenantA->id, + 'managed_environment_id' => $tenantA->id, 'backup_set_id' => $backupSetA->id, 'policy_id' => $policyA->id, ]); RestoreRun::factory()->create([ - 'tenant_id' => $tenantA->id, + 'managed_environment_id' => $tenantA->id, 'backup_set_id' => $backupSetA->id, ]); AuditLog::create([ - 'tenant_id' => $tenantA->id, + 'managed_environment_id' => $tenantA->id, 'actor_id' => null, 'actor_email' => null, 'actor_name' => null, @@ -81,13 +81,13 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => $tenantA->id, + 'managed_environment_id' => $tenantA->id, 'user_id' => $user->id, 'status' => 'completed', ]); $scheduleA = BackupSchedule::create([ - 'tenant_id' => $tenantA->id, + 'managed_environment_id' => $tenantA->id, 'name' => 'Schedule A', 'is_enabled' => true, 'timezone' => 'UTC', @@ -102,9 +102,9 @@ 'next_run_at' => now()->addHour(), ]); - expect(Policy::query()->where('tenant_id', $tenantA->id)->count())->toBeGreaterThan(0); - expect(BackupSet::withTrashed()->where('tenant_id', $tenantA->id)->count())->toBeGreaterThan(0); - expect(OperationRun::query()->where('tenant_id', $tenantA->id)->count())->toBeGreaterThan(0); + expect(Policy::query()->where('managed_environment_id', $tenantA->id)->count())->toBeGreaterThan(0); + expect(BackupSet::withTrashed()->where('managed_environment_id', $tenantA->id)->count())->toBeGreaterThan(0); + expect(OperationRun::query()->where('managed_environment_id', $tenantA->id)->count())->toBeGreaterThan(0); $this->artisan('tenantpilot:purge-nonpersistent', [ 'tenant' => $tenantA->id, @@ -112,28 +112,28 @@ '--no-interaction' => true, ])->assertSuccessful(); - expect(Policy::query()->where('tenant_id', $tenantA->id)->count())->toBe(0); - expect(PolicyVersion::withTrashed()->where('tenant_id', $tenantA->id)->count())->toBe(0); - expect(BackupItem::withTrashed()->where('tenant_id', $tenantA->id)->count())->toBe(0); - expect(BackupSet::withTrashed()->where('tenant_id', $tenantA->id)->count())->toBe(0); - expect(RestoreRun::withTrashed()->where('tenant_id', $tenantA->id)->count())->toBe(0); - expect(AuditLog::query()->where('tenant_id', $tenantA->id)->count())->toBe(2); + expect(Policy::query()->where('managed_environment_id', $tenantA->id)->count())->toBe(0); + expect(PolicyVersion::withTrashed()->where('managed_environment_id', $tenantA->id)->count())->toBe(0); + expect(BackupItem::withTrashed()->where('managed_environment_id', $tenantA->id)->count())->toBe(0); + expect(BackupSet::withTrashed()->where('managed_environment_id', $tenantA->id)->count())->toBe(0); + expect(RestoreRun::withTrashed()->where('managed_environment_id', $tenantA->id)->count())->toBe(0); + expect(AuditLog::query()->where('managed_environment_id', $tenantA->id)->count())->toBe(2); expect(AuditLog::query() - ->where('tenant_id', $tenantA->id) + ->where('managed_environment_id', $tenantA->id) ->orderBy('action') ->pluck('action') ->all())->toBe([ 'operation.completed', 'test.action', ]); - expect(OperationRun::query()->where('tenant_id', $tenantA->id)->count())->toBe(1); + expect(OperationRun::query()->where('managed_environment_id', $tenantA->id)->count())->toBe(1); expect(OperationRun::query() - ->where('tenant_id', $tenantA->id) + ->where('managed_environment_id', $tenantA->id) ->where('type', 'backup.schedule.purge') ->exists())->toBeTrue(); $purgeRun = OperationRun::query() - ->where('tenant_id', $tenantA->id) + ->where('managed_environment_id', $tenantA->id) ->where('type', 'backup.schedule.purge') ->latest('id') ->first(); @@ -142,10 +142,10 @@ expect(data_get($purgeRun?->context, 'audit_logs_retained'))->toBe(2) ->and(data_get($purgeRun?->context, 'deleted_rows.audit_logs_retained'))->toBeNull(); - expect(BackupSchedule::query()->where('tenant_id', $tenantA->id)->count())->toBe(0); + expect(BackupSchedule::query()->where('managed_environment_id', $tenantA->id)->count())->toBe(0); - expect(Policy::query()->where('tenant_id', $tenantB->id)->count())->toBe(1); - expect(PolicyVersion::withTrashed()->where('tenant_id', $tenantB->id)->count())->toBe(1); + expect(Policy::query()->where('managed_environment_id', $tenantB->id)->count())->toBe(1); + expect(PolicyVersion::withTrashed()->where('managed_environment_id', $tenantB->id)->count())->toBe(1); expect(SettingsCatalogCategory::query()->count())->toBe(1); expect(SettingsCatalogDefinition::query()->count())->toBe(1); diff --git a/apps/platform/tests/Feature/Console/TenantpilotSeedBackupHealthBrowserFixtureCommandTest.php b/apps/platform/tests/Feature/Console/TenantpilotSeedBackupHealthBrowserFixtureCommandTest.php index 1a4d2cbd..b7a3b876 100644 --- a/apps/platform/tests/Feature/Console/TenantpilotSeedBackupHealthBrowserFixtureCommandTest.php +++ b/apps/platform/tests/Feature/Console/TenantpilotSeedBackupHealthBrowserFixtureCommandTest.php @@ -8,7 +8,7 @@ use App\Filament\Widgets\Dashboard\RecoveryReadiness; use App\Models\BackupItem; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Services\Auth\CapabilityResolver; @@ -27,17 +27,17 @@ $workspaceConfig = config('tenantpilot.backup_health.browser_smoke_fixture.workspace'); $userConfig = config('tenantpilot.backup_health.browser_smoke_fixture.user'); $scenarioConfig = config('tenantpilot.backup_health.browser_smoke_fixture.blocked_drillthrough'); - $tenantRouteKey = $scenarioConfig['tenant_id'] ?? $scenarioConfig['tenant_external_id']; + $tenantRouteKey = $scenarioConfig['managed_environment_id'] ?? $scenarioConfig['tenant_external_id']; $workspace = Workspace::query()->where('slug', $workspaceConfig['slug'])->first(); $user = User::query()->where('email', $userConfig['email'])->first(); - $tenant = Tenant::query()->where('external_id', $tenantRouteKey)->first(); + $tenant = ManagedEnvironment::query()->where('slug', $tenantRouteKey)->first(); expect($workspace)->not->toBeNull(); expect($user)->not->toBeNull(); expect($tenant)->not->toBeNull(); - expect(BackupSet::query()->where('tenant_id', $tenant->getKey())->where('name', $scenarioConfig['backup_set_name'])->exists())->toBeTrue(); - expect(BackupItem::query()->where('tenant_id', $tenant->getKey())->where('policy_identifier', $scenarioConfig['policy_external_id'])->exists())->toBeTrue(); + expect(BackupSet::query()->where('managed_environment_id', $tenant->getKey())->where('name', $scenarioConfig['backup_set_name'])->exists())->toBeTrue(); + expect(BackupItem::query()->where('managed_environment_id', $tenant->getKey())->where('policy_identifier', $scenarioConfig['policy_external_id'])->exists())->toBeTrue(); $resolver = app(CapabilityResolver::class); $resolver->clearCache(); diff --git a/apps/platform/tests/Feature/Dashboard/MyFindingsSignalTest.php b/apps/platform/tests/Feature/Dashboard/MyFindingsSignalTest.php index 466d25e4..19d2e526 100644 --- a/apps/platform/tests/Feature/Dashboard/MyFindingsSignalTest.php +++ b/apps/platform/tests/Feature/Dashboard/MyFindingsSignalTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Findings\MyFindingsInbox; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -20,20 +20,20 @@ it('builds an assigned-to-me signal from visible assigned findings only', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 21, 9, 0, 0, 'UTC')); - $tenantA = Tenant::factory()->create(['status' => 'active']); + $tenantA = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'readonly', workspaceRole: 'readonly'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Bravo Tenant', + 'name' => 'Bravo ManagedEnvironment', ]); createUserWithTenant($tenantB, $user, role: 'readonly', workspaceRole: 'readonly'); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Hidden Tenant', + 'name' => 'Hidden ManagedEnvironment', ]); Finding::factory()->for($tenantA)->create([ @@ -77,7 +77,7 @@ }); it('keeps the signal calm when no visible assigned findings remain', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly', workspaceRole: 'readonly'); Finding::factory()->for($tenant)->create([ @@ -98,13 +98,13 @@ }); it('suppresses blocked-tenant findings from the assigned-to-me signal', function (): void { - $visibleTenant = Tenant::factory()->create(['status' => 'active']); + $visibleTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $visibleTenant] = createUserWithTenant($visibleTenant, role: 'readonly', workspaceRole: 'readonly'); - $blockedTenant = Tenant::factory()->create([ + $blockedTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, - 'name' => 'Blocked Tenant', + 'name' => 'Blocked ManagedEnvironment', ]); createUserWithTenant($blockedTenant, $user, role: 'readonly', workspaceRole: 'readonly'); @@ -126,7 +126,7 @@ $mock->shouldReceive('primeMemberships')->once(); $mock->shouldReceive('isMember')->andReturnTrue(); $mock->shouldReceive('can') - ->andReturnUsing(static function (User $user, Tenant $tenant, string $capability) use ($visibleTenant, $blockedTenant): bool { + ->andReturnUsing(static function (User $user, ManagedEnvironment $tenant, string $capability) use ($visibleTenant, $blockedTenant): bool { expect([(int) $visibleTenant->getKey(), (int) $blockedTenant->getKey()]) ->toContain((int) $tenant->getKey()); diff --git a/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationActionsTest.php b/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationActionsTest.php index cc40b14f..1b825128 100644 --- a/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationActionsTest.php +++ b/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationActionsTest.php @@ -8,7 +8,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\TenantRequiredPermissionsViewModelBuilder; use App\Support\Links\RequiredPermissionsLinks; use App\Support\OperationRunLinks; @@ -61,11 +61,11 @@ function tenantDashboardButtonClassesForXPath(string $content, string $xpathExpr } it('builds the canonical operations follow-up baseline with tenant continuity', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); expect(OperationRunLinks::index($tenant, activeTab: 'active')) ->toBe(route('admin.operations.index', [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'activeTab' => 'active', ])) ->and(OperationRunLinks::index( @@ -74,14 +74,14 @@ function tenantDashboardButtonClassesForXPath(string $content, string $xpathExpr problemClass: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, )) ->toBe(route('admin.operations.index', [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'activeTab' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, 'problemClass' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, ])); }); it('builds the required-permissions follow-up baseline with tenant continuity', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'external_id' => 'tenant-dashboard-productization', ]); @@ -109,7 +109,7 @@ function tenantDashboardButtonClassesForXPath(string $content, string $xpathExpr workspaceOverviewSeedRestoreHistory($tenant, $backupSet); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'severity' => Finding::SEVERITY_HIGH, @@ -117,7 +117,7 @@ function tenantDashboardButtonClassesForXPath(string $content, string $xpathExpr ]); $riskFinding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'severity' => Finding::SEVERITY_LOW, @@ -126,7 +126,7 @@ function tenantDashboardButtonClassesForXPath(string $content, string $xpathExpr FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $riskFinding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), diff --git a/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationAuthorizationTest.php b/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationAuthorizationTest.php index 60710bf6..83d89568 100644 --- a/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationAuthorizationTest.php +++ b/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationAuthorizationTest.php @@ -6,7 +6,7 @@ use App\Filament\Pages\Governance\GovernanceInbox; use App\Filament\Pages\TenantDashboard; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Services\Intune\TenantRequiredPermissionsViewModelBuilder; @@ -134,7 +134,7 @@ function tenantDashboardProductizationHeaderMoreActionNames(Testable $component) [$user, $tenant] = createUserWithTenant(role: 'owner'); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'severity' => Finding::SEVERITY_HIGH, @@ -193,7 +193,7 @@ function tenantDashboardProductizationHeaderMoreActionNames(Testable $component) ->toBeInstanceOf(Action::class) ->and($primaryAction->getLabel())->toBe('Open governance inbox') ->and($primaryAction->getUrl())->toBe(GovernanceInbox::getUrl(panel: 'admin').'?'.http_build_query([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ])); }); @@ -247,7 +247,7 @@ function tenantDashboardProductizationHeaderMoreActionNames(Testable $component) ->and($rows['provider_permissions']['tag'])->toBe('a') ->and($rows['provider_permissions']['interactive'])->toBeTrue() ->and($rows['provider_permissions']['href'])->toBe(collect($summary['governanceStatus'])->firstWhere('key', 'provider_permissions')['actionUrl']) - ->and($rows['provider_permissions']['class'])->toContain('hover:shadow-sm') + ->and($rows['provider_permissions']['class'])->toContain('hover:shadow-md') ->and($rows['backup_posture']['tag'])->toBe('div') ->and($rows['backup_posture']['interactive'])->toBeFalse(); }); @@ -307,10 +307,10 @@ function tenantDashboardProductizationHeaderMoreActionNames(Testable $component) $this->mock(CapabilityResolver::class, function ($mock) use ($tenant): void { $mock->shouldReceive('primeMemberships')->andReturnNull(); $mock->shouldReceive('isMember') - ->andReturnUsing(static fn ($actor, Tenant $resolvedTenant): bool => (int) $resolvedTenant->getKey() === (int) $tenant->getKey()); + ->andReturnUsing(static fn ($actor, ManagedEnvironment $resolvedTenant): bool => (int) $resolvedTenant->getKey() === (int) $tenant->getKey()); $mock->shouldReceive('can') - ->andReturnUsing(static function ($actor, Tenant $resolvedTenant, string $capability) use ($tenant): bool { + ->andReturnUsing(static function ($actor, ManagedEnvironment $resolvedTenant, string $capability) use ($tenant): bool { expect((int) $resolvedTenant->getKey())->toBe((int) $tenant->getKey()); return match ($capability) { @@ -329,7 +329,7 @@ function tenantDashboardProductizationHeaderMoreActionNames(Testable $component) workspaceOverviewSeedRestoreHistory($tenant, $backupSet); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'severity' => Finding::SEVERITY_HIGH, diff --git a/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationReadinessTest.php b/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationReadinessTest.php index 93fbb530..804575ad 100644 --- a/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationReadinessTest.php +++ b/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationReadinessTest.php @@ -44,14 +44,14 @@ function mockTenantDashboardReadinessPermissions(array $overview = []): void [$user, $tenant] = createUserWithTenant(role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Productization baseline backup', 'item_count' => 1, 'completed_at' => now()->subMinutes(15), ]); BackupItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'payload' => ['id' => 'baseline-policy'], 'metadata' => [], @@ -94,7 +94,7 @@ function mockTenantDashboardReadinessPermissions(array $overview = []): void $snapshot = seedTenantReviewEvidence($tenant); $review = composeTenantReviewForTest($tenant, $user, $snapshot); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -128,7 +128,7 @@ function mockTenantDashboardReadinessPermissions(array $overview = []): void ]); ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'is_default' => true, 'verification_status' => 'blocked', @@ -198,7 +198,7 @@ function mockTenantDashboardReadinessPermissions(array $overview = []): void mockTenantDashboardReadinessPermissions(); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => Finding::STATUS_RESOLVED, 'resolved_reason' => Finding::RESOLVE_REASON_REMEDIATED, @@ -206,7 +206,7 @@ function mockTenantDashboardReadinessPermissions(array $overview = []): void ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => Finding::STATUS_RISK_ACCEPTED, ]); @@ -245,7 +245,7 @@ function mockTenantDashboardReadinessPermissions(array $overview = []): void mockTenantDashboardReadinessPermissions(); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => Finding::STATUS_RESOLVED, 'resolved_reason' => Finding::RESOLVE_REASON_REMEDIATED, @@ -253,7 +253,7 @@ function mockTenantDashboardReadinessPermissions(array $overview = []): void ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => Finding::STATUS_RISK_ACCEPTED, ]); diff --git a/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationSummaryTest.php b/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationSummaryTest.php index c853e805..fc8fb464 100644 --- a/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationSummaryTest.php +++ b/apps/platform/tests/Feature/Dashboard/TenantDashboardProductizationSummaryTest.php @@ -48,7 +48,7 @@ function mockTenantDashboardSummaryPermissions(array $overview = []): void workspaceOverviewSeedRestoreHistory($tenant, $backupSet); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'severity' => Finding::SEVERITY_HIGH, @@ -56,7 +56,7 @@ function mockTenantDashboardSummaryPermissions(array $overview = []): void ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, @@ -65,7 +65,7 @@ function mockTenantDashboardSummaryPermissions(array $overview = []): void ]); ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'is_default' => true, ]); @@ -147,7 +147,7 @@ function mockTenantDashboardSummaryPermissions(array $overview = []): void foreach ([6, 6, 4, 1] as $daysAgo) { Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'severity' => $daysAgo === 4 ? Finding::SEVERITY_CRITICAL : Finding::SEVERITY_HIGH, @@ -158,7 +158,7 @@ function mockTenantDashboardSummaryPermissions(array $overview = []): void } Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'severity' => Finding::SEVERITY_MEDIUM, @@ -168,7 +168,7 @@ function mockTenantDashboardSummaryPermissions(array $overview = []): void ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'severity' => Finding::SEVERITY_MEDIUM, @@ -180,7 +180,7 @@ function mockTenantDashboardSummaryPermissions(array $overview = []): void foreach ([5, 2, 2] as $daysAgo) { OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, @@ -225,7 +225,7 @@ function mockTenantDashboardSummaryPermissions(array $overview = []): void mockTenantDashboardSummaryPermissions(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, @@ -235,7 +235,7 @@ function mockTenantDashboardSummaryPermissions(array $overview = []): void ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'tenant.review_pack.generate', 'status' => OperationRunStatus::Completed->value, @@ -245,7 +245,7 @@ function mockTenantDashboardSummaryPermissions(array $overview = []): void ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationCatalog::TYPE_PERMISSION_POSTURE_CHECK, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/Database/PoliciesSeederTest.php b/apps/platform/tests/Feature/Database/PoliciesSeederTest.php index 9cb30713..d5567822 100644 --- a/apps/platform/tests/Feature/Database/PoliciesSeederTest.php +++ b/apps/platform/tests/Feature/Database/PoliciesSeederTest.php @@ -1,12 +1,10 @@ set('tenantpilot.supported_policy_types', []); $_ENV['INTUNE_TENANT_ID'] = 'test-tenant-id'; @@ -16,9 +14,9 @@ $this->artisan('db:seed', ['--class' => Database\Seeders\PoliciesSeeder::class]) ->assertExitCode(0); - $tenant = Tenant::query()->first(); + $tenant = ManagedEnvironment::query()->first(); expect($tenant)->not->toBeNull(); - expect($tenant->tenant_id)->toBe('test-tenant-id'); - expect(Str::isUuid((string) $tenant->external_id))->toBeTrue(); + expect($tenant->managed_environment_id)->toBe('test-tenant-id'); + expect($tenant->external_id)->toBe('test-tenant-id'); }); diff --git a/apps/platform/tests/Feature/DependencyExtractionFeatureTest.php b/apps/platform/tests/Feature/DependencyExtractionFeatureTest.php index 1c1f059b..144ee9ad 100644 --- a/apps/platform/tests/Feature/DependencyExtractionFeatureTest.php +++ b/apps/platform/tests/Feature/DependencyExtractionFeatureTest.php @@ -2,7 +2,7 @@ use App\Models\InventoryItem; use App\Models\InventoryLink; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Inventory\DependencyQueryService; @@ -54,7 +54,7 @@ public function request(string $method, string $path, array $options = []): Grap } it('extracts edges during inventory sync and marks missing appropriately', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); $this->app->bind(GraphClientInterface::class, fn () => new FakeGraphClientForDeps); @@ -70,13 +70,13 @@ public function request(string $method, string $path, array $options = []): Grap expect($run->status)->toBe(OperationRunStatus::Completed->value); expect($run->outcome)->toBe(OperationRunOutcome::Succeeded->value); - $edges = InventoryLink::query()->where('tenant_id', $tenant->getKey())->get(); + $edges = InventoryLink::query()->where('managed_environment_id', $tenant->getKey())->get(); // 2 assigned_to + 2 scoped_by = 4 expect($edges->count())->toBe(4); }); it('respects 50-edge limit for outbound extraction', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); // Fake client returning 60 group assignments $this->app->bind(GraphClientInterface::class, function () { @@ -131,12 +131,12 @@ public function request(string $method, string $path, array $options = []): Grap 'include_dependencies' => true, ]); - $count = InventoryLink::query()->where('tenant_id', $tenant->getKey())->count(); + $count = InventoryLink::query()->where('managed_environment_id', $tenant->getKey())->count(); expect($count)->toBe(50); }); it('persists unsupported reference warnings on the sync run record', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); $this->app->bind(GraphClientInterface::class, function () { @@ -192,21 +192,21 @@ public function request(string $method, string $path, array $options = []): Grap expect($warnings)->toBeArray()->toHaveCount(1); expect($warnings[0]['type'] ?? null)->toBe('unsupported_reference'); - expect(InventoryLink::query()->where('tenant_id', $tenant->getKey())->count())->toBe(0); + expect(InventoryLink::query()->where('managed_environment_id', $tenant->getKey())->count())->toBe(0); }); it('orders inbound/outbound edges by created_at desc and applies limit-only behavior', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); $svc = app(DependencyQueryService::class); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'foundation_object', @@ -216,7 +216,7 @@ public function request(string $method, string $path, array $options = []): Grap 'updated_at' => now()->subMinutes(10), ]); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'foundation_object', @@ -226,7 +226,7 @@ public function request(string $method, string $path, array $options = []): Grap 'updated_at' => now()->subMinutes(5), ]); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'foundation_object', @@ -243,7 +243,7 @@ public function request(string $method, string $path, array $options = []): Grap expect($outbound[0]->created_at->greaterThan($outbound[1]->created_at))->toBeTrue(); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'target_type' => 'inventory_item', @@ -253,7 +253,7 @@ public function request(string $method, string $path, array $options = []): Grap 'updated_at' => now()->subMinutes(9), ]); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'target_type' => 'inventory_item', @@ -263,7 +263,7 @@ public function request(string $method, string $path, array $options = []): Grap 'updated_at' => now()->subMinutes(2), ]); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => 'cccccccc-cccc-cccc-cccc-cccccccccccc', 'target_type' => 'inventory_item', @@ -281,7 +281,7 @@ public function request(string $method, string $path, array $options = []): Grap }); it('hydrates settings catalog assignments and extracts include/exclude/filter edges', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); $this->app->bind(GraphClientInterface::class, function () { @@ -364,7 +364,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon expect($run->status)->toBe(OperationRunStatus::Completed->value); expect($run->outcome)->toBe(OperationRunOutcome::Succeeded->value); - $edges = InventoryLink::query()->where('tenant_id', $tenant->getKey())->get(); + $edges = InventoryLink::query()->where('managed_environment_id', $tenant->getKey())->get(); expect($edges->where('relationship_type', 'scoped_by'))->toHaveCount(1); expect($edges->where('relationship_type', 'assigned_to_include'))->toHaveCount(2); expect($edges->where('relationship_type', 'assigned_to_exclude'))->toHaveCount(1); diff --git a/apps/platform/tests/Feature/DependencyQueryServiceTest.php b/apps/platform/tests/Feature/DependencyQueryServiceTest.php index 8869b5b8..854b1890 100644 --- a/apps/platform/tests/Feature/DependencyQueryServiceTest.php +++ b/apps/platform/tests/Feature/DependencyQueryServiceTest.php @@ -2,22 +2,22 @@ use App\Models\InventoryItem; use App\Models\InventoryLink; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Inventory\DependencyQueryService; use Illuminate\Support\Str; it('returns outbound and inbound edges filtered by tenant and direction', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); // Outbound edge for this item InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'foundation_object', @@ -27,7 +27,7 @@ // Inbound edge pointing to this item as target InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => (string) Str::uuid(), 'target_type' => 'inventory_item', diff --git a/apps/platform/tests/Feature/DependencyTenantIsolationTest.php b/apps/platform/tests/Feature/DependencyTenantIsolationTest.php index 2515503f..1c79a0eb 100644 --- a/apps/platform/tests/Feature/DependencyTenantIsolationTest.php +++ b/apps/platform/tests/Feature/DependencyTenantIsolationTest.php @@ -2,23 +2,23 @@ use App\Models\InventoryItem; use App\Models\InventoryLink; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Inventory\DependencyQueryService; use Illuminate\Support\Str; it('does not leak edges across tenants in service queries', function () { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); /** @var InventoryItem $itemA */ $itemA = InventoryItem::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'external_id' => (string) Str::uuid(), ]); // Edge for tenant A InventoryLink::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'source_type' => 'inventory_item', 'source_id' => $itemA->external_id, 'target_type' => 'foundation_object', @@ -28,7 +28,7 @@ // Edge for tenant B with same source/target ids but different tenant InventoryLink::factory()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'source_type' => 'inventory_item', 'source_id' => $itemA->external_id, 'target_type' => 'foundation_object', diff --git a/apps/platform/tests/Feature/DeviceComplianceScriptPolicyTypeTest.php b/apps/platform/tests/Feature/DeviceComplianceScriptPolicyTypeTest.php index b364493d..b1fb59ad 100644 --- a/apps/platform/tests/Feature/DeviceComplianceScriptPolicyTypeTest.php +++ b/apps/platform/tests/Feature/DeviceComplianceScriptPolicyTypeTest.php @@ -3,7 +3,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -93,27 +93,27 @@ public function request(string $method, string $path, array $options = []): Grap ); app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-1', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-1', ]); ensureDefaultProviderConnection($tenant); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'dcs-1', 'policy_type' => 'deviceComplianceScript', 'platform' => 'windows', ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/Directory/ProviderBackedDirectoryStartTest.php b/apps/platform/tests/Feature/Directory/ProviderBackedDirectoryStartTest.php index e0bfa5ca..1e21d5a3 100644 --- a/apps/platform/tests/Feature/Directory/ProviderBackedDirectoryStartTest.php +++ b/apps/platform/tests/Feature/Directory/ProviderBackedDirectoryStartTest.php @@ -4,7 +4,7 @@ use App\Jobs\EntraGroupSyncJob; use App\Jobs\SyncRoleDefinitionsJob; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Directory\RoleDefinitionsSyncService; use App\Services\Graph\GraphClientInterface; use App\Support\Providers\ProviderReasonCodes; @@ -38,7 +38,7 @@ ->callAction('sync_groups'); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'directory.groups.sync') ->latest('id') ->first(); @@ -56,7 +56,7 @@ it('blocks role definitions sync before queue when no provider connection is available', function (): void { Bus::fake(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'app_client_id' => 'client-123', 'app_client_secret' => 'secret', 'status' => 'active', diff --git a/apps/platform/tests/Feature/DirectoryGroups/BrowseGroupsTest.php b/apps/platform/tests/Feature/DirectoryGroups/BrowseGroupsTest.php index be22341e..de23034a 100644 --- a/apps/platform/tests/Feature/DirectoryGroups/BrowseGroupsTest.php +++ b/apps/platform/tests/Feature/DirectoryGroups/BrowseGroupsTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\EntraGroupResource; use App\Filament\Resources\EntraGroupResource\Pages\ListEntraGroups; use App\Models\EntraGroup; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -16,12 +16,12 @@ [$user, $tenant] = createUserWithTenant(role: 'owner', fixtureProfile: 'credential-enabled'); $this->actingAs($user); - $otherTenant = Tenant::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); $stalenessDays = (int) config('directory_groups.staleness_days', 30); EntraGroup::query()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'entra_id' => '00000000-0000-0000-0000-000000000001', 'display_name' => 'Alpha Team', 'group_types' => null, @@ -31,7 +31,7 @@ ]); EntraGroup::query()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'entra_id' => '00000000-0000-0000-0000-000000000002', 'display_name' => 'Beta Unified', 'group_types' => ['Unified'], @@ -41,9 +41,9 @@ ]); EntraGroup::query()->create([ - 'tenant_id' => $otherTenant->getKey(), + 'managed_environment_id' => $otherTenant->getKey(), 'entra_id' => '00000000-0000-0000-0000-000000000003', - 'display_name' => 'Other Tenant Group', + 'display_name' => 'Other ManagedEnvironment Group', 'group_types' => null, 'security_enabled' => true, 'mail_enabled' => false, @@ -72,7 +72,7 @@ $names = $extractNames(Livewire::test(ListEntraGroups::class)); expect($names)->toContain('Alpha Team'); expect($names)->toContain('Beta Unified'); - expect($names)->not->toContain('Other Tenant Group'); + expect($names)->not->toContain('Other ManagedEnvironment Group'); $names = $extractNames( Livewire::test(ListEntraGroups::class) @@ -101,15 +101,15 @@ }); test('group detail is tenant-scoped and cross-tenant access is not found (404)', function () { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => $tenantA->workspace_id, ]); $groupB = EntraGroup::query()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'entra_id' => '00000000-0000-0000-0000-000000000099', - 'display_name' => 'Tenant B Group', + 'display_name' => 'ManagedEnvironment B Group', 'group_types' => null, 'security_enabled' => true, 'mail_enabled' => false, diff --git a/apps/platform/tests/Feature/DirectoryGroups/NoLiveGraphOnRenderTest.php b/apps/platform/tests/Feature/DirectoryGroups/NoLiveGraphOnRenderTest.php index acbd74ad..c9164756 100644 --- a/apps/platform/tests/Feature/DirectoryGroups/NoLiveGraphOnRenderTest.php +++ b/apps/platform/tests/Feature/DirectoryGroups/NoLiveGraphOnRenderTest.php @@ -2,7 +2,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; @@ -12,9 +12,9 @@ putenv('INTUNE_TENANT_ID'); unset($_ENV['INTUNE_TENANT_ID'], $_SERVER['INTUNE_TENANT_ID']); - $this->tenant = Tenant::factory()->create(); + $this->tenant = ManagedEnvironment::factory()->create(); $this->policy = Policy::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, ]); $this->user = User::factory()->create(); @@ -31,7 +31,7 @@ ->shouldNotReceive('request'); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_id' => $this->policy->id, 'version_number' => 1, 'assignments' => [ diff --git a/apps/platform/tests/Feature/DirectoryGroups/ScheduledSyncDispatchTest.php b/apps/platform/tests/Feature/DirectoryGroups/ScheduledSyncDispatchTest.php index 8e6f9198..eecc2e30 100644 --- a/apps/platform/tests/Feature/DirectoryGroups/ScheduledSyncDispatchTest.php +++ b/apps/platform/tests/Feature/DirectoryGroups/ScheduledSyncDispatchTest.php @@ -10,7 +10,7 @@ it('scheduled dispatcher creates a run without a user initiator', function () { Queue::fake(); - $tenant = \App\Models\Tenant::factory()->create(); + $tenant = \App\Models\ManagedEnvironment::factory()->create(); Config::set('directory_groups.schedule.enabled', true); Config::set('directory_groups.schedule.time_utc', '02:00'); @@ -18,13 +18,13 @@ CarbonImmutable::setTestNow(CarbonImmutable::parse('2026-01-11 02:00:00', 'UTC')); Artisan::call('tenantpilot:directory-groups:dispatch', [ - '--tenant' => [$tenant->tenant_id], + '--tenant' => [$tenant->managed_environment_id], ]); $slotKey = CarbonImmutable::now('UTC')->format('YmdHi').'Z'; $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'directory.groups.sync') ->where('context->slot_key', $slotKey) ->first(); diff --git a/apps/platform/tests/Feature/DirectoryGroups/StartSyncFromGroupsPageTest.php b/apps/platform/tests/Feature/DirectoryGroups/StartSyncFromGroupsPageTest.php index 867307db..ccac5b1a 100644 --- a/apps/platform/tests/Feature/DirectoryGroups/StartSyncFromGroupsPageTest.php +++ b/apps/platform/tests/Feature/DirectoryGroups/StartSyncFromGroupsPageTest.php @@ -30,7 +30,7 @@ ->callAction('sync_groups'); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'directory.groups.sync') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/DirectoryGroups/StartSyncTest.php b/apps/platform/tests/Feature/DirectoryGroups/StartSyncTest.php index bedea333..19539259 100644 --- a/apps/platform/tests/Feature/DirectoryGroups/StartSyncTest.php +++ b/apps/platform/tests/Feature/DirectoryGroups/StartSyncTest.php @@ -20,7 +20,7 @@ ->and($result->status)->toBe('started'); expect($run) - ->and($run->tenant_id)->toBe($tenant->getKey()) + ->and($run->managed_environment_id)->toBe($tenant->getKey()) ->and($run->user_id)->toBe($user->getKey()) ->and($run->type)->toBe(OperationRunType::DirectoryGroupsSync->value) ->and($run->status)->toBe('queued') diff --git a/apps/platform/tests/Feature/DirectoryGroups/SyncJobUpsertsGroupsTest.php b/apps/platform/tests/Feature/DirectoryGroups/SyncJobUpsertsGroupsTest.php index 717ca5b3..91710092 100644 --- a/apps/platform/tests/Feature/DirectoryGroups/SyncJobUpsertsGroupsTest.php +++ b/apps/platform/tests/Feature/DirectoryGroups/SyncJobUpsertsGroupsTest.php @@ -14,7 +14,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner', fixtureProfile: 'credential-enabled'); EntraGroup::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'entra_id' => '11111111-1111-1111-1111-111111111111', 'display_name' => 'Old Name', 'last_seen_at' => now('UTC')->subDays(10), @@ -78,10 +78,10 @@ ->and($opRun->summary_counts['updated'] ?? null)->toBe(2) ->and($opRun->summary_counts['failed'] ?? null)->toBe(0); - expect(EntraGroup::query()->where('tenant_id', $tenant->getKey())->count())->toBe(2); + expect(EntraGroup::query()->where('managed_environment_id', $tenant->getKey())->count())->toBe(2); $updated = EntraGroup::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('entra_id', '11111111-1111-1111-1111-111111111111') ->first(); diff --git a/apps/platform/tests/Feature/DirectoryGroups/SyncRetentionPurgeTest.php b/apps/platform/tests/Feature/DirectoryGroups/SyncRetentionPurgeTest.php index 1f7929b6..2bffc49f 100644 --- a/apps/platform/tests/Feature/DirectoryGroups/SyncRetentionPurgeTest.php +++ b/apps/platform/tests/Feature/DirectoryGroups/SyncRetentionPurgeTest.php @@ -16,12 +16,12 @@ Config::set('directory_groups.retention_days', 90); $oldGroup = EntraGroup::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'last_seen_at' => now('UTC')->subDays(91), ]); $newGroup = EntraGroup::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'last_seen_at' => now('UTC')->subDays(10), ]); diff --git a/apps/platform/tests/Feature/DirectoryGroups/TenantGroupSelectorsDbOnlyTest.php b/apps/platform/tests/Feature/DirectoryGroups/TenantGroupSelectorsDbOnlyTest.php index 3369d3ba..286db6e9 100644 --- a/apps/platform/tests/Feature/DirectoryGroups/TenantGroupSelectorsDbOnlyTest.php +++ b/apps/platform/tests/Feature/DirectoryGroups/TenantGroupSelectorsDbOnlyTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\TenantResource; use App\Models\EntraGroup; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); @@ -12,8 +12,8 @@ it('searches cached directory groups without Graph calls', function (): void { bindFailHardGraphClient(); - /** @var Tenant $tenant */ - $tenant = Tenant::factory()->create(); + /** @var ManagedEnvironment $tenant */ + $tenant = ManagedEnvironment::factory()->create(); EntraGroup::factory() ->for($tenant) @@ -32,8 +32,8 @@ it('resolves a directory group label from cached data without Graph calls', function (): void { bindFailHardGraphClient(); - /** @var Tenant $tenant */ - $tenant = Tenant::factory()->create(); + /** @var ManagedEnvironment $tenant */ + $tenant = ManagedEnvironment::factory()->create(); EntraGroup::factory() ->for($tenant) diff --git a/apps/platform/tests/Feature/Drift/DriftFindingDetailTest.php b/apps/platform/tests/Feature/Drift/DriftFindingDetailTest.php index 3d99d00a..e570458e 100644 --- a/apps/platform/tests/Feature/Drift/DriftFindingDetailTest.php +++ b/apps/platform/tests/Feature/Drift/DriftFindingDetailTest.php @@ -54,7 +54,7 @@ [$user, $tenant] = createUserWithTenant(role: 'manager'); $policy = Policy::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-redaction-note', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Policy redaction note', @@ -62,7 +62,7 @@ ]); $baseline = PolicyVersion::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, @@ -85,7 +85,7 @@ ]); $protectedCurrent = PolicyVersion::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, diff --git a/apps/platform/tests/Feature/Drift/DriftFindingDiffUnavailableTest.php b/apps/platform/tests/Feature/Drift/DriftFindingDiffUnavailableTest.php index cf7b8755..8377ba5a 100644 --- a/apps/platform/tests/Feature/Drift/DriftFindingDiffUnavailableTest.php +++ b/apps/platform/tests/Feature/Drift/DriftFindingDiffUnavailableTest.php @@ -8,7 +8,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $finding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'subject_type' => 'policy', @@ -56,7 +56,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-unexpected-uuid', 'policy_type' => 'deviceCompliancePolicy', 'platform' => 'windows', @@ -64,7 +64,7 @@ ]); $currentVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => 'deviceCompliancePolicy', 'platform' => 'windows', @@ -77,7 +77,7 @@ ]); $finding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'subject_type' => 'policy', @@ -126,7 +126,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-missing-uuid', 'policy_type' => 'deviceCompliancePolicy', 'platform' => 'windows', @@ -134,7 +134,7 @@ ]); $baselineVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => 'deviceCompliancePolicy', 'platform' => 'windows', @@ -147,7 +147,7 @@ ]); $finding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'subject_type' => 'policy', diff --git a/apps/platform/tests/Feature/EndpointSecurityIntentRestoreSanitizationTest.php b/apps/platform/tests/Feature/EndpointSecurityIntentRestoreSanitizationTest.php index b5e32bde..17f68941 100644 --- a/apps/platform/tests/Feature/EndpointSecurityIntentRestoreSanitizationTest.php +++ b/apps/platform/tests/Feature/EndpointSecurityIntentRestoreSanitizationTest.php @@ -2,7 +2,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\RestoreService; @@ -57,7 +57,7 @@ public function request(string $method, string $path, array $options = []): Grap $client = new EndpointSecurityIntentRestoreGraphClient; app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); $backupSet = BackupSet::factory()->for($tenant)->create([ diff --git a/apps/platform/tests/Feature/EndpointSecurityPolicyRestore023Test.php b/apps/platform/tests/Feature/EndpointSecurityPolicyRestore023Test.php index ea2382eb..72dd783d 100644 --- a/apps/platform/tests/Feature/EndpointSecurityPolicyRestore023Test.php +++ b/apps/platform/tests/Feature/EndpointSecurityPolicyRestore023Test.php @@ -2,7 +2,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\RestoreRiskChecker; @@ -81,7 +81,7 @@ public function request(string $method, string $path, array $options = []): Grap $client = new EndpointSecurityRestoreGraphClient(new GraphResponse(true, [])); app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); $backupSet = BackupSet::factory()->for($tenant)->create([ @@ -164,7 +164,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); $backupSet = BackupSet::factory()->for($tenant)->create([ @@ -230,7 +230,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); $backupSet = BackupSet::factory()->for($tenant)->create([ diff --git a/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesAlertIntegrationTest.php b/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesAlertIntegrationTest.php index 0c39c633..f1568ff2 100644 --- a/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesAlertIntegrationTest.php +++ b/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesAlertIntegrationTest.php @@ -52,14 +52,14 @@ function createEntraAlertRuleWithDestination(int $workspaceId, string $minSeveri $finding = Finding::factory()->entraAdminRoles()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'severity' => Finding::SEVERITY_CRITICAL, 'status' => Finding::STATUS_NEW, ]); $event = [ 'event_type' => AlertRule::EVENT_ENTRA_ADMIN_ROLES_HIGH, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => Finding::SEVERITY_CRITICAL, 'fingerprint_key' => 'finding:'.(int) $finding->getKey(), 'title' => 'High-privilege Entra admin role detected', @@ -92,7 +92,7 @@ function createEntraAlertRuleWithDestination(int $workspaceId, string $minSeveri $event = [ 'event_type' => AlertRule::EVENT_ENTRA_ADMIN_ROLES_HIGH, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => Finding::SEVERITY_HIGH, 'fingerprint_key' => 'finding:999', 'title' => 'High-privilege Entra admin role detected', @@ -116,14 +116,14 @@ function createEntraAlertRuleWithDestination(int $workspaceId, string $minSeveri $finding = Finding::factory()->entraAdminRoles()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'severity' => Finding::SEVERITY_CRITICAL, 'status' => Finding::STATUS_NEW, ]); $event = [ 'event_type' => AlertRule::EVENT_ENTRA_ADMIN_ROLES_HIGH, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => Finding::SEVERITY_CRITICAL, 'fingerprint_key' => 'finding:'.(int) $finding->getKey(), 'title' => 'High-privilege Entra admin role detected', @@ -160,7 +160,7 @@ function createEntraAlertRuleWithDestination(int $workspaceId, string $minSeveri // Create a resolved finding — should not appear in events Finding::factory()->entraAdminRoles()->resolved()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'severity' => Finding::SEVERITY_CRITICAL, ]); @@ -182,7 +182,7 @@ function createEntraAlertRuleWithDestination(int $workspaceId, string $minSeveri $finding = Finding::factory()->entraAdminRoles()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'severity' => Finding::SEVERITY_CRITICAL, 'status' => Finding::STATUS_REOPENED, 'reopened_at' => now(), @@ -199,7 +199,7 @@ function createEntraAlertRuleWithDestination(int $workspaceId, string $minSeveri expect($events)->toHaveCount(1) ->and($events[0]['event_type'])->toBe(AlertRule::EVENT_ENTRA_ADMIN_ROLES_HIGH) - ->and($events[0]['tenant_id'])->toBe((int) $tenant->getKey()) + ->and($events[0]['managed_environment_id'])->toBe((int) $tenant->getKey()) ->and($events[0]['metadata']['finding_id'])->toBe((int) $finding->getKey()); }); diff --git a/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesReportViewerTest.php b/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesReportViewerTest.php index 2e3367df..2bd1c878 100644 --- a/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesReportViewerTest.php +++ b/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesReportViewerTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); @@ -12,7 +12,7 @@ // Helpers // --------------------------------------------------------------------------- -function createEntraReport(Tenant $tenant, array $summaryOverrides = [], ?string $fingerprint = null): StoredReport +function createEntraReport(ManagedEnvironment $tenant, array $summaryOverrides = [], ?string $fingerprint = null): StoredReport { $totals = array_merge([ 'roles_total' => 8, @@ -22,7 +22,7 @@ function createEntraReport(Tenant $tenant, array $summaryOverrides = [], ?string return StoredReport::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'fingerprint' => $fingerprint ?? hash('sha256', (string) now()->timestamp.random_int(0, 99999)), 'payload' => [ @@ -58,14 +58,14 @@ function createEntraReport(Tenant $tenant, array $summaryOverrides = [], ?string // Also create a report of a different type to ensure filtering works StoredReport::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => 'permission_posture', 'fingerprint' => hash('sha256', 'other-report'), 'payload' => ['summary' => ['score' => 85]], ]); $results = StoredReport::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES) ->get(); @@ -128,7 +128,7 @@ function createEntraReport(Tenant $tenant, array $summaryOverrides = [], ?string $latest = createEntraReport($tenant, ['high_privilege_assignments' => 1], 'fp-latest'); $results = StoredReport::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES) ->orderByDesc('created_at') ->get(); diff --git a/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesSummaryWidgetTest.php b/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesSummaryWidgetTest.php index efe52277..d4a0acd8 100644 --- a/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesSummaryWidgetTest.php +++ b/apps/platform/tests/Feature/EntraAdminRoles/AdminRolesSummaryWidgetTest.php @@ -6,7 +6,7 @@ use App\Filament\Widgets\Tenant\AdminRolesSummaryWidget; use App\Jobs\ScanEntraAdminRolesJob; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\Capabilities; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -20,7 +20,7 @@ // Helpers // --------------------------------------------------------------------------- -function createAdminRolesReport(Tenant $tenant, ?array $summaryOverrides = null): StoredReport +function createAdminRolesReport(ManagedEnvironment $tenant, ?array $summaryOverrides = null): StoredReport { $totals = array_merge([ 'roles_total' => 8, @@ -30,7 +30,7 @@ function createAdminRolesReport(Tenant $tenant, ?array $summaryOverrides = null) return StoredReport::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'fingerprint' => hash('sha256', (string) now()->timestamp), 'payload' => [ @@ -173,7 +173,7 @@ function createAdminRolesReport(Tenant $tenant, ?array $summaryOverrides = null) it('renders empty state for non-member user', function (): void { $user = \App\Models\User::factory()->create(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); Filament::setTenant($tenant, true); diff --git a/apps/platform/tests/Feature/EntraAdminRoles/EntraAdminRolesFindingGeneratorTest.php b/apps/platform/tests/Feature/EntraAdminRoles/EntraAdminRolesFindingGeneratorTest.php index 8d392607..9b5098b6 100644 --- a/apps/platform/tests/Feature/EntraAdminRoles/EntraAdminRolesFindingGeneratorTest.php +++ b/apps/platform/tests/Feature/EntraAdminRoles/EntraAdminRolesFindingGeneratorTest.php @@ -106,7 +106,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator ->and($result->unchanged)->toBe(0); $findings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->get(); @@ -145,7 +145,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator makeGenerator()->generate($tenant, $payload); $findings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->orderBy('severity') ->get(); @@ -180,14 +180,14 @@ function makeGenerator(): EntraAdminRolesFindingGenerator ->and($second->unchanged)->toBe(1); $count = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->count(); expect($count)->toBe(1); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->first(); @@ -208,7 +208,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator )); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->firstOrFail(); @@ -262,7 +262,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator expect($result2->resolved)->toBeGreaterThanOrEqual(1); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->where('subject_external_id', 'user-1:def-ga') ->first(); @@ -299,7 +299,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator expect($result3->reopened)->toBe(1); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->where('subject_external_id', 'user-1:def-ga') ->first(); @@ -326,7 +326,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator // 6 individual + 1 aggregate = 7 findings $findings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->get(); @@ -361,7 +361,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator expect($result2->resolved)->toBeGreaterThanOrEqual(1); $aggregate = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('subject_external_id', 'ga_aggregate') ->first(); @@ -386,7 +386,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator $event = $events[0]; expect($event['event_type'])->toBe(AlertRule::EVENT_ENTRA_ADMIN_ROLES_HIGH) - ->and($event['tenant_id'])->toBe((int) $tenant->getKey()); + ->and($event['managed_environment_id'])->toBe((int) $tenant->getKey()); }); it('produces no alert events for unchanged or resolved findings', function (): void { @@ -421,7 +421,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator makeGenerator()->generate($tenant, $payload); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->where('subject_external_id', 'user-1:def-ga') ->first(); @@ -462,7 +462,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator makeGenerator()->generate($tenant, $payload); $findings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->get(); @@ -484,7 +484,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator makeGenerator()->generate($tenant, $payload); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->first(); @@ -506,7 +506,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator // Triage the finding $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('subject_external_id', 'user-1:def-ga') ->first(); $finding->forceFill([ @@ -538,7 +538,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator makeGenerator()->generate($tenant, $payload); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->first(); @@ -559,7 +559,7 @@ function makeGenerator(): EntraAdminRolesFindingGenerator expect($result->created)->toBe(0); $count = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->count(); diff --git a/apps/platform/tests/Feature/EntraAdminRoles/EntraAdminRolesReportServiceTest.php b/apps/platform/tests/Feature/EntraAdminRoles/EntraAdminRolesReportServiceTest.php index 038d09fb..2f3da0ba 100644 --- a/apps/platform/tests/Feature/EntraAdminRoles/EntraAdminRolesReportServiceTest.php +++ b/apps/platform/tests/Feature/EntraAdminRoles/EntraAdminRolesReportServiceTest.php @@ -171,7 +171,7 @@ function buildReportService(GraphClientInterface $graphMock): EntraAdminRolesRep expect($report)->not->toBeNull() ->and($report->report_type)->toBe(StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES) - ->and($report->tenant_id)->toBe((int) $tenant->getKey()) + ->and($report->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($report->fingerprint)->toBe($result->fingerprint) ->and($report->previous_fingerprint)->toBeNull(); }); @@ -191,7 +191,7 @@ function buildReportService(GraphClientInterface $graphMock): EntraAdminRolesRep ->and($second->fingerprint)->toBe($first->fingerprint); $count = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES) ->count(); diff --git a/apps/platform/tests/Feature/EntraAdminRoles/ScanEntraAdminRolesJobTest.php b/apps/platform/tests/Feature/EntraAdminRoles/ScanEntraAdminRolesJobTest.php index b02f268b..b2e2f6fa 100644 --- a/apps/platform/tests/Feature/EntraAdminRoles/ScanEntraAdminRolesJobTest.php +++ b/apps/platform/tests/Feature/EntraAdminRoles/ScanEntraAdminRolesJobTest.php @@ -139,7 +139,7 @@ public function request(string $method, string $path, array $options = []): Grap ); $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'entra.admin_roles.scan') ->first(); @@ -152,14 +152,14 @@ public function request(string $method, string $path, array $options = []): Grap // Verify report and findings also exist $report = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES) ->first(); expect($report)->not->toBeNull(); $findingsCount = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->count(); @@ -182,14 +182,14 @@ public function request(string $method, string $path, array $options = []): Grap ); $runCount = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'entra.admin_roles.scan') ->count(); expect($runCount)->toBe(0); $reportCount = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES) ->count(); @@ -216,7 +216,7 @@ public function request(string $method, string $path, array $options = []): Grap ); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'entra.admin_roles.scan') ->count())->toBe(0); }); @@ -241,7 +241,7 @@ public function request(string $method, string $path, array $options = []): Grap ); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'entra.admin_roles.scan') ->count())->toBe(0); }); @@ -272,7 +272,7 @@ public function request(string $method, string $path, array $options = []): Grap expect($thrown)->toBeTrue(); $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'entra.admin_roles.scan') ->first(); @@ -301,14 +301,14 @@ public function request(string $method, string $path, array $options = []): Grap $job1->handle($reportService, $findingGenerator, $runService); $reportCount = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES) ->count(); expect($reportCount)->toBe(1); // Mark existing OperationRun as completed so a new one can be created OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'entra.admin_roles.scan') ->update(['status' => OperationRunStatus::Completed->value]); @@ -321,14 +321,14 @@ public function request(string $method, string $path, array $options = []): Grap // Still only 1 report (deduped) $reportCount2 = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES) ->count(); expect($reportCount2)->toBe(1); // But the run completed successfully with deduped count $latestRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'entra.admin_roles.scan') ->where('outcome', OperationRunOutcome::Succeeded->value) ->latest() diff --git a/apps/platform/tests/Feature/EntraAdminRoles/StoredReportFingerprintTest.php b/apps/platform/tests/Feature/EntraAdminRoles/StoredReportFingerprintTest.php index a46b8c26..ddc43556 100644 --- a/apps/platform/tests/Feature/EntraAdminRoles/StoredReportFingerprintTest.php +++ b/apps/platform/tests/Feature/EntraAdminRoles/StoredReportFingerprintTest.php @@ -11,7 +11,7 @@ [$user, $tenant] = createUserWithTenant(); $report = StoredReport::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'fingerprint' => str_repeat('a', 64), 'previous_fingerprint' => str_repeat('b', 64), @@ -23,18 +23,18 @@ ->and($fresh->previous_fingerprint)->toBe(str_repeat('b', 64)); }); -it('prevents duplicate (tenant_id, report_type, fingerprint) via unique index', function (): void { +it('prevents duplicate (managed_environment_id, report_type, fingerprint) via unique index', function (): void { [$user, $tenant] = createUserWithTenant(); $fingerprint = hash('sha256', 'test-content'); StoredReport::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'fingerprint' => $fingerprint, ]); expect(fn () => StoredReport::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'fingerprint' => $fingerprint, ]))->toThrow(\Illuminate\Database\QueryException::class); @@ -44,7 +44,7 @@ [$user, $tenant] = createUserWithTenant(); $report = StoredReport::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'fingerprint' => null, 'previous_fingerprint' => null, diff --git a/apps/platform/tests/Feature/Evidence/EvidenceOverviewPageTest.php b/apps/platform/tests/Feature/Evidence/EvidenceOverviewPageTest.php index 2970c404..188fb7c8 100644 --- a/apps/platform/tests/Feature/Evidence/EvidenceOverviewPageTest.php +++ b/apps/platform/tests/Feature/Evidence/EvidenceOverviewPageTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Monitoring\EvidenceOverview; use App\Filament\Resources\EvidenceSnapshotResource; use App\Models\EvidenceSnapshot; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Evidence\EvidenceCompletenessState; use App\Support\Evidence\EvidenceSnapshotStatus; use App\Support\Workspaces\WorkspaceContext; @@ -17,12 +17,12 @@ uses(RefreshDatabase::class, BuildsGovernanceArtifactTruthFixtures::class); it('shows only authorized tenant rows on the workspace evidence overview', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); - $foreignWorkspaceTenant = Tenant::factory()->create(); + $foreignWorkspaceTenant = ManagedEnvironment::factory()->create(); foreach ([ [$tenantA, EvidenceCompletenessState::Complete->value], @@ -30,7 +30,7 @@ [$foreignWorkspaceTenant, EvidenceCompletenessState::Missing->value], ] as [$tenant, $state]) { EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => $state, @@ -58,7 +58,7 @@ }); it('returns 404 for users without workspace membership on the evidence overview', function (): void { - $workspaceTenant = Tenant::factory()->create(); + $workspaceTenant = ManagedEnvironment::factory()->create(); $user = App\Models\User::factory()->create(); Filament::setTenant(null, true); @@ -70,16 +70,16 @@ }); it('applies the entitled tenant prefilter on the workspace evidence overview', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $snapshots = []; foreach ([[$tenantA, EvidenceCompletenessState::Complete->value], [$tenantB, EvidenceCompletenessState::Partial->value]] as [$tenant, $state]) { $snapshots[(int) $tenant->getKey()] = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => $state, @@ -92,19 +92,19 @@ $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenantA->workspace_id]) - ->get(route('admin.evidence.overview', ['tenant_id' => (int) $tenantB->getKey()])) + ->get(route('admin.evidence.overview', ['managed_environment_id' => (int) $tenantB->getKey()])) ->assertOk() ->assertSee(EvidenceSnapshotResource::getUrl('view', ['record' => $snapshots[(int) $tenantB->getKey()]], tenant: $tenantB, panel: 'tenant'), false) ->assertDontSee(EvidenceSnapshotResource::getUrl('view', ['record' => $snapshots[(int) $tenantA->getKey()]], tenant: $tenantA, panel: 'tenant'), false); }); it('shows stale evidence burden and a create-review next step on the overview', function (): void { - $staleTenant = Tenant::factory()->create(['name' => 'Stale Tenant']); + $staleTenant = ManagedEnvironment::factory()->create(['name' => 'Stale ManagedEnvironment']); [$user, $staleTenant] = createUserWithTenant(tenant: $staleTenant, role: 'owner'); - $freshTenant = Tenant::factory()->create([ + $freshTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $staleTenant->workspace_id, - 'name' => 'Fresh Tenant', + 'name' => 'Fresh ManagedEnvironment', ]); createUserWithTenant(tenant: $freshTenant, user: $user, role: 'owner'); @@ -126,16 +126,16 @@ }); it('seeds the native entitled-tenant prefilter once and clears it through the page action', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $snapshotA = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -144,7 +144,7 @@ ]); $snapshotB = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Partial->value, @@ -158,12 +158,12 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); $component = Livewire::withQueryParams([ - 'tenant_id' => (string) $tenantB->getKey(), + 'managed_environment_id' => (string) $tenantB->getKey(), 'search' => $tenantB->name, ])->test(EvidenceOverview::class); $component - ->assertSet('tableFilters.tenant_id.value', (string) $tenantB->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantB->getKey()) ->assertSet('tableSearch', $tenantB->name) ->assertCanSeeTableRecords([(string) $snapshotB->getKey()]) ->assertCanNotSeeTableRecords([(string) $snapshotA->getKey()]); diff --git a/apps/platform/tests/Feature/Evidence/EvidenceSnapshotAuditLogTest.php b/apps/platform/tests/Feature/Evidence/EvidenceSnapshotAuditLogTest.php index a33b7c3f..41cfe6a1 100644 --- a/apps/platform/tests/Feature/Evidence/EvidenceSnapshotAuditLogTest.php +++ b/apps/platform/tests/Feature/Evidence/EvidenceSnapshotAuditLogTest.php @@ -39,7 +39,7 @@ [$user, $tenant] = createUserWithTenant(role: 'readonly'); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, diff --git a/apps/platform/tests/Feature/Evidence/EvidenceSnapshotCanonicalControlReferenceTest.php b/apps/platform/tests/Feature/Evidence/EvidenceSnapshotCanonicalControlReferenceTest.php index 7c5af726..8888df0b 100644 --- a/apps/platform/tests/Feature/Evidence/EvidenceSnapshotCanonicalControlReferenceTest.php +++ b/apps/platform/tests/Feature/Evidence/EvidenceSnapshotCanonicalControlReferenceTest.php @@ -10,15 +10,15 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); Finding::factory()->permissionPosture()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); Finding::factory()->entraAdminRoles()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'evidence_jsonb' => [ @@ -51,7 +51,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => 'unknown_provider_signal', ]); diff --git a/apps/platform/tests/Feature/Evidence/EvidenceSnapshotResourceTest.php b/apps/platform/tests/Feature/Evidence/EvidenceSnapshotResourceTest.php index c4b68c56..3389f3e2 100644 --- a/apps/platform/tests/Feature/Evidence/EvidenceSnapshotResourceTest.php +++ b/apps/platform/tests/Feature/Evidence/EvidenceSnapshotResourceTest.php @@ -14,7 +14,7 @@ use App\Models\PlatformUser; use App\Models\ReviewPack; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Entitlements\WorkspaceCommercialLifecycleResolver; use App\Services\Settings\SettingsWriter; use App\Support\Auth\Capabilities; @@ -34,27 +34,27 @@ uses(RefreshDatabase::class, BuildsGovernanceArtifactTruthFixtures::class); -function seedEvidenceDomain(Tenant $tenant): void +function seedEvidenceDomain(ManagedEnvironment $tenant): void { StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'fingerprint' => hash('sha256', 'permission-'.$tenant->getKey()), ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'fingerprint' => hash('sha256', 'entra-'.$tenant->getKey()), ]); Finding::factory()->count(2)->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]); @@ -73,7 +73,7 @@ function evidenceSnapshotHeaderActions(Testable $component): array return $instance->getCachedHeaderActions(); } -function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void +function suspendEvidenceSnapshotWorkspace(ManagedEnvironment $tenant): void { app(SettingsWriter::class)->updateWorkspaceCommercialLifecycle( actor: PlatformUser::factory()->create([ @@ -91,7 +91,7 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void } it('renders the evidence list page for an authorized user', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user) @@ -107,7 +107,7 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void }); it('returns 404 for non members on the evidence list route', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant(role: 'owner'); $this->actingAs($user) @@ -116,7 +116,7 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void }); it('returns 403 for tenant members without evidence view capability on the evidence list route', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); Gate::define(Capabilities::EVIDENCE_VIEW, fn (): bool => false); @@ -127,7 +127,7 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void }); it('disables create snapshot for readonly members', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $tenant->makeCurrent(); @@ -142,7 +142,7 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void it('queues snapshot generation from the list header action', function (): void { Queue::fake(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); seedEvidenceDomain($tenant); @@ -160,12 +160,12 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void }); it('renders the view page for an active snapshot', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->forTenant($tenant)->create(); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'operation_run_id' => (int) $run->getKey(), 'status' => EvidenceSnapshotStatus::Active->value, @@ -175,7 +175,7 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void ]); ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), @@ -230,11 +230,11 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void }); it('keeps evidence snapshot detail accessible for readonly members while suspended read-only', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -260,11 +260,11 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void }); it('shows artifact truth and next-step guidance for degraded evidence snapshots', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Partial->value, @@ -292,9 +292,9 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void }); it('shows stale evidence snapshots as cautionary while fresh snapshots remain current', function (): void { - $freshTenant = Tenant::factory()->create(); + $freshTenant = ManagedEnvironment::factory()->create(); [$user, $freshTenant] = createUserWithTenant(tenant: $freshTenant, role: 'owner'); - $staleTenant = Tenant::factory()->create([ + $staleTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $freshTenant->workspace_id, ]); createUserWithTenant(tenant: $staleTenant, user: $user, role: 'owner'); @@ -316,11 +316,11 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void }); it('renders readable evidence dimension summaries and keeps raw json available', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -335,7 +335,7 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void EvidenceSnapshotItem::query()->create([ 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'dimension_key' => 'findings_summary', 'state' => EvidenceCompletenessState::Complete->value, 'required' => true, @@ -363,7 +363,7 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void EvidenceSnapshotItem::query()->create([ 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'dimension_key' => 'entra_admin_roles', 'state' => EvidenceCompletenessState::Complete->value, 'required' => true, @@ -381,7 +381,7 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void EvidenceSnapshotItem::query()->create([ 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'dimension_key' => 'operations_summary', 'state' => EvidenceCompletenessState::Complete->value, 'required' => true, @@ -422,17 +422,17 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void ->assertSeeText('Evidence snapshot generation · In progress') ->assertSeeText('Review pack generation · Completed successfully') ->assertSeeText('Backup schedule purge · Queued for execution') - ->assertDontSeeText('Tenant.evidence.snapshot.generate · Pending · Running') + ->assertDontSeeText('ManagedEnvironment.evidence.snapshot.generate · Pending · Running') ->assertSeeText('Copy JSON'); }); it('hides evidence refresh, expiry, operation, fingerprint, and raw json in the customer review proof flow', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $run = OperationRun::factory()->forTenant($tenant)->create(); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'operation_run_id' => (int) $run->getKey(), 'status' => EvidenceSnapshotStatus::Active->value, @@ -445,7 +445,7 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void EvidenceSnapshotItem::query()->create([ 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'dimension_key' => 'findings_summary', 'state' => EvidenceCompletenessState::Complete->value, 'required' => true, @@ -484,11 +484,11 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void }); it('hides expire actions for expired snapshots on list and detail surfaces', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Expired->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -511,11 +511,11 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void }); it('disables refresh and expire actions for readonly members on snapshot detail', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -535,11 +535,11 @@ function suspendEvidenceSnapshotWorkspace(Tenant $tenant): void }); it('keeps evidence list actions within the declared action surface contract', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, diff --git a/apps/platform/tests/Feature/Evidence/ExceptionValidityEvidenceIntegrationTest.php b/apps/platform/tests/Feature/Evidence/ExceptionValidityEvidenceIntegrationTest.php index 23b4e6b1..67a7b825 100644 --- a/apps/platform/tests/Feature/Evidence/ExceptionValidityEvidenceIntegrationTest.php +++ b/apps/platform/tests/Feature/Evidence/ExceptionValidityEvidenceIntegrationTest.php @@ -19,12 +19,12 @@ createUserWithTenant(tenant: $tenant, user: $approver, role: 'owner', workspaceRole: 'manager'); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, ]); diff --git a/apps/platform/tests/Feature/Evidence/GenerateEvidenceSnapshotJobTest.php b/apps/platform/tests/Feature/Evidence/GenerateEvidenceSnapshotJobTest.php index 6fc64269..57b68540 100644 --- a/apps/platform/tests/Feature/Evidence/GenerateEvidenceSnapshotJobTest.php +++ b/apps/platform/tests/Feature/Evidence/GenerateEvidenceSnapshotJobTest.php @@ -7,7 +7,7 @@ use App\Models\Finding; use App\Models\OperationRun; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Evidence\EvidenceSnapshotService; use App\Services\OperationRunService; use App\Support\Evidence\EvidenceSnapshotStatus; @@ -18,24 +18,24 @@ uses(RefreshDatabase::class); -function seedSnapshotInputs(Tenant $tenant): void +function seedSnapshotInputs(ManagedEnvironment $tenant): void { StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'fingerprint' => hash('sha256', 'perm-'.$tenant->getKey()), ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'fingerprint' => hash('sha256', 'entra-'.$tenant->getKey()), ]); Finding::factory()->count(2)->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]); @@ -163,7 +163,7 @@ public function incrementSummaryCounts(OperationRun $run, array $delta): Operati $first->refresh(); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'fingerprint' => Str::random(64), ]); diff --git a/apps/platform/tests/Feature/ExecuteRestoreRunJobTest.php b/apps/platform/tests/Feature/ExecuteRestoreRunJobTest.php index b6b23920..2f83ec6b 100644 --- a/apps/platform/tests/Feature/ExecuteRestoreRunJobTest.php +++ b/apps/platform/tests/Feature/ExecuteRestoreRunJobTest.php @@ -5,7 +5,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\AuditLogger; use App\Services\Intune\RestoreService; use App\Services\OperationRunService; @@ -16,21 +16,23 @@ uses(RefreshDatabase::class); test('execute restore run job moves queued to running and calls the executor', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], + 'rbac_status' => 'ok', + 'rbac_last_checked_at' => now(), ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'requested_by' => 'actor@example.com', 'is_dry_run' => false, @@ -44,7 +46,7 @@ $restoreService = $this->mock(RestoreService::class, function (MockInterface $mock) use ($tenant, $backupSet) { $mock->shouldReceive('executeForRun') ->once() - ->withArgs(function (RestoreRun $run, Tenant $runTenant, BackupSet $runBackupSet, ?string $email, ?string $name) use ($tenant, $backupSet): bool { + ->withArgs(function (RestoreRun $run, ManagedEnvironment $runTenant, BackupSet $runBackupSet, ?string $email, ?string $name) use ($tenant, $backupSet): bool { return $run->status === RestoreRunStatus::Running->value && $runTenant->is($tenant) && $runBackupSet->is($backupSet) @@ -82,21 +84,23 @@ }); test('execute restore run job persists per-item outcomes keyed by backup_item_id', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-results', - 'name' => 'Tenant Results', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-results', + 'name' => 'ManagedEnvironment Results', 'metadata' => [], + 'rbac_status' => 'ok', + 'rbac_last_checked_at' => now(), ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-results', 'policy_type' => 'unknownPreviewOnlyType', 'display_name' => 'Preview-only policy', @@ -104,7 +108,7 @@ ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -117,7 +121,7 @@ ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'requested_by' => 'actor@example.com', 'is_dry_run' => false, diff --git a/apps/platform/tests/Feature/Filament/AdminHomeRedirectsToChooseTenantWhenWorkspaceSelectedTest.php b/apps/platform/tests/Feature/Filament/AdminHomeRedirectsToChooseTenantWhenWorkspaceSelectedTest.php index f203eed3..d5d80b45 100644 --- a/apps/platform/tests/Feature/Filament/AdminHomeRedirectsToChooseTenantWhenWorkspaceSelectedTest.php +++ b/apps/platform/tests/Feature/Filament/AdminHomeRedirectsToChooseTenantWhenWorkspaceSelectedTest.php @@ -2,8 +2,8 @@ declare(strict_types=1); -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -43,14 +43,14 @@ 'role' => 'owner', ]); - $tenants = Tenant::factory()->count(2)->create([ + $tenants = ManagedEnvironment::factory()->count(2)->create([ 'status' => 'active', 'workspace_id' => $workspace->getKey(), ]); foreach ($tenants as $tenant) { - TenantMembership::query()->create([ - 'tenant_id' => $tenant->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', @@ -79,13 +79,13 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => $workspace->getKey(), ]); - TenantMembership::query()->create([ - 'tenant_id' => $tenant->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', diff --git a/apps/platform/tests/Feature/Filament/AdminSharedSurfacePanelParityTest.php b/apps/platform/tests/Feature/Filament/AdminSharedSurfacePanelParityTest.php index dbb5dd98..6b1f7cfd 100644 --- a/apps/platform/tests/Feature/Filament/AdminSharedSurfacePanelParityTest.php +++ b/apps/platform/tests/Feature/Filament/AdminSharedSurfacePanelParityTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\BackupSetResource\Pages\ListBackupSets; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,13 +13,13 @@ uses(RefreshDatabase::class); it('keeps backup-set scoping split between admin remembered context and tenant-panel context', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $backupSetA = BackupSet::factory()->for($tenantA)->create(['name' => 'Remembered admin backup']); - $backupSetB = BackupSet::factory()->for($tenantB)->create(['name' => 'Tenant panel backup']); + $backupSetB = BackupSet::factory()->for($tenantB)->create(['name' => 'ManagedEnvironment panel backup']); $this->actingAs($user); diff --git a/apps/platform/tests/Feature/Filament/AdminTenantScopedSurfacesRedirectToChooseTenantTest.php b/apps/platform/tests/Feature/Filament/AdminTenantScopedSurfacesRedirectToChooseTenantTest.php index 871eaed4..445cfc67 100644 --- a/apps/platform/tests/Feature/Filament/AdminTenantScopedSurfacesRedirectToChooseTenantTest.php +++ b/apps/platform/tests/Feature/Filament/AdminTenantScopedSurfacesRedirectToChooseTenantTest.php @@ -2,8 +2,8 @@ declare(strict_types=1); -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -31,14 +31,14 @@ 'role' => 'owner', ]); - $tenants = Tenant::factory()->count(2)->create([ + $tenants = ManagedEnvironment::factory()->count(2)->create([ 'status' => 'active', 'workspace_id' => $workspace->getKey(), ]); foreach ($tenants as $tenant) { - TenantMembership::query()->create([ - 'tenant_id' => $tenant->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', @@ -73,10 +73,10 @@ }); it('allows tenant-scoped admin surfaces to load from the remembered canonical tenant', function (string $path): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); diff --git a/apps/platform/tests/Feature/Filament/AdminTenantSurfaceParityTest.php b/apps/platform/tests/Feature/Filament/AdminTenantSurfaceParityTest.php index 24d990c6..07801fc1 100644 --- a/apps/platform/tests/Feature/Filament/AdminTenantSurfaceParityTest.php +++ b/apps/platform/tests/Feature/Filament/AdminTenantSurfaceParityTest.php @@ -8,7 +8,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -16,9 +16,9 @@ uses(RefreshDatabase::class); it('returns not found for admin direct record access outside the remembered canonical tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $allowedPolicy = Policy::factory()->for($tenantA)->create(); @@ -44,9 +44,9 @@ }); it('keeps admin direct policy-version resolution inside the remembered canonical tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $policyA = Policy::factory()->for($tenantA)->create(); diff --git a/apps/platform/tests/Feature/Filament/Alerts/AlertDeliveryViewerTest.php b/apps/platform/tests/Feature/Filament/Alerts/AlertDeliveryViewerTest.php index 2c575c47..f603d805 100644 --- a/apps/platform/tests/Feature/Filament/Alerts/AlertDeliveryViewerTest.php +++ b/apps/platform/tests/Feature/Filament/Alerts/AlertDeliveryViewerTest.php @@ -8,7 +8,7 @@ use App\Models\AlertDelivery; use App\Models\AlertDestination; use App\Models\AlertRule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -47,7 +47,7 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio it('lists only deliveries for entitled tenants', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'readonly'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -63,7 +63,7 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio $tenantADelivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'event_type' => 'high_drift', @@ -71,7 +71,7 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio $tenantBDelivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'event_type' => 'compare_failed', @@ -123,7 +123,7 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio $delivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), ]); @@ -160,7 +160,7 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio [$user] = createUserWithTenant(role: 'owner'); $otherWorkspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $otherWorkspace->getKey(), ]); $rule = AlertRule::factory()->create([ @@ -171,7 +171,7 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio ]); $delivery = AlertDelivery::factory()->create([ 'workspace_id' => (int) $otherWorkspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), ]); @@ -204,10 +204,10 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio }); it('keeps persisted alert delivery filters inside the active tenant scope', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -225,7 +225,7 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio $tenantADelivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -233,7 +233,7 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio $tenantBDelivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -254,21 +254,21 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio }); it('preselects the tenant filter when a tenant context exists', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user); Filament::setTenant($tenant, true); Livewire::test(ListAlertDeliveries::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenant->getKey()); + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenant->getKey()); }); it('scopes alert deliveries to the remembered tenant context when filament tenant is absent', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -286,7 +286,7 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio $tenantADelivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -294,7 +294,7 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio $tenantBDelivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -307,7 +307,7 @@ function getAlertDeliveryHeaderAction(Testable $component, string $name): ?Actio ->withSession([WorkspaceContext::SESSION_KEY => $workspaceId]); Livewire::test(ListAlertDeliveries::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()) ->assertCanSeeTableRecords([$tenantADelivery]) ->assertCanNotSeeTableRecords([$tenantBDelivery]); }); diff --git a/apps/platform/tests/Feature/Filament/Alerts/AlertRuleCrudTest.php b/apps/platform/tests/Feature/Filament/Alerts/AlertRuleCrudTest.php index 75a1fc03..d0bdb627 100644 --- a/apps/platform/tests/Feature/Filament/Alerts/AlertRuleCrudTest.php +++ b/apps/platform/tests/Feature/Filament/Alerts/AlertRuleCrudTest.php @@ -91,8 +91,8 @@ ->assertSee('This rule is workspace-wide. Use this to limit where it applies.') ->assertSee('Selected tenants') ->assertSee('Only these tenants will trigger this rule.') - ->assertDontSee('Tenant scope mode') - ->assertDontSee('Tenant allowlist'); + ->assertDontSee('ManagedEnvironment scope mode') + ->assertDontSee('ManagedEnvironment allowlist'); }); it('shows form section headings on alert rule edit form', function (): void { diff --git a/apps/platform/tests/Feature/Filament/Alerts/AlertsKpiHeaderTest.php b/apps/platform/tests/Feature/Filament/Alerts/AlertsKpiHeaderTest.php index 216a490e..1f0c3aca 100644 --- a/apps/platform/tests/Feature/Filament/Alerts/AlertsKpiHeaderTest.php +++ b/apps/platform/tests/Feature/Filament/Alerts/AlertsKpiHeaderTest.php @@ -6,7 +6,7 @@ use App\Models\AlertDelivery; use App\Models\AlertDestination; use App\Models\AlertRule; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Filament\Widgets\StatsOverviewWidget\Stat; @@ -34,21 +34,21 @@ function alertsKpiValues($component): array AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, 'created_at' => now()->subHour(), ]); - $otherTenant = Tenant::factory()->create(['workspace_id' => $workspaceId]); + $otherTenant = ManagedEnvironment::factory()->create(['workspace_id' => $workspaceId]); $user->tenants()->syncWithoutDetaching([ $otherTenant->getKey() => ['role' => 'owner'], ]); AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $otherTenant->getKey(), + 'managed_environment_id' => (int) $otherTenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -81,21 +81,21 @@ function alertsKpiValues($component): array AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, 'created_at' => now()->subHour(), ]); - $otherTenant = Tenant::factory()->create(['workspace_id' => $workspaceId]); + $otherTenant = ManagedEnvironment::factory()->create(['workspace_id' => $workspaceId]); $user->tenants()->syncWithoutDetaching([ $otherTenant->getKey() => ['role' => 'owner'], ]); AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $otherTenant->getKey(), + 'managed_environment_id' => (int) $otherTenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -125,21 +125,21 @@ function alertsKpiValues($component): array AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, 'created_at' => now()->subHour(), ]); - $otherTenant = Tenant::factory()->create(['workspace_id' => $workspaceId]); + $otherTenant = ManagedEnvironment::factory()->create(['workspace_id' => $workspaceId]); $user->tenants()->syncWithoutDetaching([ $otherTenant->getKey() => ['role' => 'owner'], ]); AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $otherTenant->getKey(), + 'managed_environment_id' => (int) $otherTenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -164,7 +164,7 @@ function alertsKpiValues($component): array $workspaceId = (int) $tenantA->workspace_id; - $tenantB = Tenant::factory()->create(['workspace_id' => $workspaceId]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => $workspaceId]); $user->tenants()->syncWithoutDetaching([ $tenantB->getKey() => ['role' => 'owner'], ]); @@ -174,7 +174,7 @@ function alertsKpiValues($component): array AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, @@ -183,7 +183,7 @@ function alertsKpiValues($component): array AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_FAILED, diff --git a/apps/platform/tests/Feature/Filament/AppProtectionPolicySettingsDisplayTest.php b/apps/platform/tests/Feature/Filament/AppProtectionPolicySettingsDisplayTest.php index 1bcd99d0..e04442ef 100644 --- a/apps/platform/tests/Feature/Filament/AppProtectionPolicySettingsDisplayTest.php +++ b/apps/platform/tests/Feature/Filament/AppProtectionPolicySettingsDisplayTest.php @@ -3,22 +3,22 @@ use App\Filament\Resources\PolicyResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('policy detail shows app protection settings in readable sections', function () { - $tenant = Tenant::factory()->create([ - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'ManagedEnvironment One', 'status' => 'active', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => 'policy-1', 'policy_type' => 'appProtectionPolicy', 'display_name' => 'Teams', @@ -26,7 +26,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_id' => $policy->getKey(), 'version_number' => 1, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/ArchivedTenantViewTest.php b/apps/platform/tests/Feature/Filament/ArchivedTenantViewTest.php index 36fed5a7..150d123a 100644 --- a/apps/platform/tests/Feature/Filament/ArchivedTenantViewTest.php +++ b/apps/platform/tests/Feature/Filament/ArchivedTenantViewTest.php @@ -20,7 +20,7 @@ Filament::setTenant($tenant, true); Livewire::test(ViewTenant::class, ['record' => $tenant->getRouteKey()]) - ->assertSee('Tenant archived') + ->assertSee('ManagedEnvironment archived') ->assertSee(UiTooltips::TENANT_ARCHIVED) ->assertSee('This tenant remains available for inspection and audit history, but it is not selectable as active context until you restore it.') ->assertDontSee('deactivated'); diff --git a/apps/platform/tests/Feature/Filament/AuditLogAuthorizationTest.php b/apps/platform/tests/Feature/Filament/AuditLogAuthorizationTest.php index 6959559c..dc603151 100644 --- a/apps/platform/tests/Feature/Filament/AuditLogAuthorizationTest.php +++ b/apps/platform/tests/Feature/Filament/AuditLogAuthorizationTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Monitoring\AuditLog as AuditLogPage; use App\Models\AuditLog as AuditLogModel; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -13,11 +13,11 @@ use Filament\Facades\Filament; use Livewire\Livewire; -function auditLogAuthorizationTestRecord(Tenant $tenant, array $attributes = []): AuditLogModel +function auditLogAuthorizationTestRecord(ManagedEnvironment $tenant, array $attributes = []): AuditLogModel { return AuditLogModel::query()->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'auditor@example.com', 'action' => 'verification.completed', 'status' => 'success', @@ -63,16 +63,16 @@ function auditLogAuthorizationTestRecord(Tenant $tenant, array $attributes = []) it('limits audit rows and event inspection to the user tenant scope', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); $visible = auditLogAuthorizationTestRecord($tenantA, [ - 'summary' => 'Tenant A audit event', + 'summary' => 'ManagedEnvironment A audit event', ]); $hidden = auditLogAuthorizationTestRecord($tenantB, [ - 'summary' => 'Tenant B audit event', + 'summary' => 'ManagedEnvironment B audit event', ]); test()->actingAs($user); @@ -86,7 +86,7 @@ function auditLogAuthorizationTestRecord(Tenant $tenant, array $attributes = []) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenantA->workspace_id]) ->get(route('admin.monitoring.audit-log').'?event='.(int) $hidden->getKey()) ->assertSuccessful() - ->assertDontSee('Tenant B audit event'); + ->assertDontSee('ManagedEnvironment B audit event'); Livewire::withQueryParams(['event' => (int) $hidden->getKey()]) ->actingAs($user) diff --git a/apps/platform/tests/Feature/Filament/AuditLogDetailInspectionTest.php b/apps/platform/tests/Feature/Filament/AuditLogDetailInspectionTest.php index fd380047..1641f19d 100644 --- a/apps/platform/tests/Feature/Filament/AuditLogDetailInspectionTest.php +++ b/apps/platform/tests/Feature/Filament/AuditLogDetailInspectionTest.php @@ -5,13 +5,13 @@ use App\Filament\Pages\Monitoring\AuditLog as AuditLogPage; use App\Models\AuditLog as AuditLogModel; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Livewire\Features\SupportTesting\Testable; use Livewire\Livewire; -function auditLogDetailTestComponent(User $user, ?Tenant $tenant = null, ?int $selectedAuditLogId = null): Testable +function auditLogDetailTestComponent(User $user, ?ManagedEnvironment $tenant = null, ?int $selectedAuditLogId = null): Testable { test()->actingAs($user); Filament::setTenant($tenant, true); @@ -25,11 +25,11 @@ function auditLogDetailTestComponent(User $user, ?Tenant $tenant = null, ?int $s return Livewire::actingAs($user)->test(AuditLogPage::class); } -function auditLogDetailTestRecord(Tenant $tenant, array $attributes = []): AuditLogModel +function auditLogDetailTestRecord(ManagedEnvironment $tenant, array $attributes = []): AuditLogModel { return AuditLogModel::query()->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'auditor@example.com', 'actor_name' => 'Audit Operator', 'action' => 'backup.created', @@ -48,7 +48,7 @@ function auditLogDetailTestRecord(Tenant $tenant, array $attributes = []): Audit [$user, $tenant] = createUserWithTenant(role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Nightly iOS backup', ]); @@ -71,7 +71,7 @@ function auditLogDetailTestRecord(Tenant $tenant, array $attributes = []): Audit [$user, $tenant] = createUserWithTenant(role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Archived backup', ]); diff --git a/apps/platform/tests/Feature/Filament/AuditLogPageTest.php b/apps/platform/tests/Feature/Filament/AuditLogPageTest.php index 9327cdd3..d53273ea 100644 --- a/apps/platform/tests/Feature/Filament/AuditLogPageTest.php +++ b/apps/platform/tests/Feature/Filament/AuditLogPageTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Monitoring\AuditLog as AuditLogPage; use App\Models\AuditLog as AuditLogModel; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\Workspaces\WorkspaceContext; @@ -13,7 +13,7 @@ use Livewire\Features\SupportTesting\Testable; use Livewire\Livewire; -function auditLogPageTestComponent(User $user, ?Tenant $tenant = null): Testable +function auditLogPageTestComponent(User $user, ?ManagedEnvironment $tenant = null): Testable { test()->actingAs($user); Filament::setTenant($tenant, true); @@ -21,7 +21,7 @@ function auditLogPageTestComponent(User $user, ?Tenant $tenant = null): Testable return Livewire::actingAs($user)->test(AuditLogPage::class); } -function auditLogPageTestRecord(?Tenant $tenant, array $attributes = []): AuditLogModel +function auditLogPageTestRecord(?ManagedEnvironment $tenant, array $attributes = []): AuditLogModel { $workspaceId = array_key_exists('workspace_id', $attributes) ? (int) $attributes['workspace_id'] @@ -29,7 +29,7 @@ function auditLogPageTestRecord(?Tenant $tenant, array $attributes = []): AuditL return AuditLogModel::query()->create(array_merge([ 'workspace_id' => $workspaceId, - 'tenant_id' => $tenant?->getKey(), + 'managed_environment_id' => $tenant?->getKey(), 'actor_email' => 'auditor@example.com', 'actor_name' => 'Audit Operator', 'action' => 'operation.completed', @@ -94,7 +94,7 @@ function auditLogPageTestRecord(?Tenant $tenant, array $attributes = []): AuditL DB::table('audit_logs')->insert([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_id' => null, 'actor_email' => 'spo_admin@yptw2.onmicrosoft.com', 'actor_name' => 'Ahmed Darrazi', @@ -143,7 +143,7 @@ function auditLogPageTestRecord(?Tenant $tenant, array $attributes = []): AuditL it('shows reverse-chronological audit rows and supports summary search', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -182,7 +182,7 @@ function auditLogPageTestRecord(?Tenant $tenant, array $attributes = []): AuditL it('preselects the active tenant as the default audit filter', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -190,30 +190,30 @@ function auditLogPageTestRecord(?Tenant $tenant, array $attributes = []): AuditL $visible = auditLogPageTestRecord($tenantA, [ 'resource_id' => '201', - 'summary' => 'Tenant A verification completed', + 'summary' => 'ManagedEnvironment A verification completed', 'action' => 'verification.completed', ]); $hidden = auditLogPageTestRecord($tenantB, [ 'resource_id' => '202', - 'summary' => 'Tenant B verification completed', + 'summary' => 'ManagedEnvironment B verification completed', 'action' => 'verification.completed', ]); auditLogPageTestComponent($user, $tenantA) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()) ->assertCanSeeTableRecords([$visible]) ->assertCanNotSeeTableRecords([$hidden]); }); it('preselects the remembered tenant as the default audit filter when the filament tenant is absent', function (): void { - $tenantA = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create([ 'name' => 'Phoenicon', 'environment' => 'dev', ]); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, 'name' => 'YPTW2', 'environment' => 'dev', @@ -242,19 +242,19 @@ function auditLogPageTestRecord(?Tenant $tenant, array $attributes = []): AuditL ]); Livewire::actingAs($user)->test(AuditLogPage::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()) ->assertCanSeeTableRecords([$visible]) ->assertCanNotSeeTableRecords([$hidden]); }); it('replaces a stale persisted audit tenant filter when the remembered tenant context changes', function (): void { - $tenantA = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create([ 'name' => 'YPTW2', 'environment' => 'dev', ]); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, 'name' => 'Phoenicon', 'environment' => 'dev', @@ -283,11 +283,11 @@ function auditLogPageTestRecord(?Tenant $tenant, array $attributes = []): AuditL ]); $component = Livewire::actingAs($user)->test(AuditLogPage::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()) ->assertCanSeeTableRecords([$tenantARecord]) ->assertCanNotSeeTableRecords([$tenantBRecord]); - expect(data_get(session()->get($component->instance()->getTableFiltersSessionKey()), 'tenant_id.value')) + expect(data_get(session()->get($component->instance()->getTableFiltersSessionKey()), 'managed_environment_id.value')) ->toBe((string) $tenantA->getKey()); session()->put(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY, [ @@ -295,7 +295,7 @@ function auditLogPageTestRecord(?Tenant $tenant, array $attributes = []): AuditL ]); Livewire::actingAs($user)->test(AuditLogPage::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantB->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantB->getKey()) ->assertCanSeeTableRecords([$tenantBRecord]) ->assertCanNotSeeTableRecords([$tenantARecord]); }); diff --git a/apps/platform/tests/Feature/Filament/BackupCreationTest.php b/apps/platform/tests/Feature/Filament/BackupCreationTest.php index d4ac7f1c..64468b7f 100644 --- a/apps/platform/tests/Feature/Filament/BackupCreationTest.php +++ b/apps/platform/tests/Feature/Filament/BackupCreationTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\BackupSetResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -72,9 +72,9 @@ public function request(string $method, string $path, array $options = []): Grap } }); - $tenant = Tenant::create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ]); @@ -83,7 +83,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant->makeCurrent(); $policyA = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -92,7 +92,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $policyB = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-2', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Policy B', @@ -163,10 +163,10 @@ public function request(string $method, string $path, array $options = []): Grap }); }); - $tenant = Tenant::create([ + $tenant = ManagedEnvironment::create([ 'name' => 'Test tenant', 'external_id' => 'tenant-1', - 'tenant_id' => 'tenant-1', + 'managed_environment_id' => 'tenant-1', 'status' => 'active', 'metadata' => [], ]); @@ -176,7 +176,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant->makeCurrent(); $policyA = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -185,7 +185,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $policyB = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-2', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Policy B', @@ -195,7 +195,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $policyC = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-3', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Policy C', @@ -205,7 +205,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $policyD = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-4', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Policy D', diff --git a/apps/platform/tests/Feature/Filament/BackupItemsBulkRemoveTest.php b/apps/platform/tests/Feature/Filament/BackupItemsBulkRemoveTest.php index b8658769..4603a2e2 100644 --- a/apps/platform/tests/Feature/Filament/BackupItemsBulkRemoveTest.php +++ b/apps/platform/tests/Feature/Filament/BackupItemsBulkRemoveTest.php @@ -6,7 +6,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Queue; @@ -17,32 +17,32 @@ test('backup items table can bulk remove selected items', function () { Queue::fake(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $tenant->makeCurrent(); Filament::setTenant($tenant, true); [$user] = createUserWithTenant(tenant: $tenant, role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', 'item_count' => 0, ]); $policyA = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => null, 'last_synced_at' => now(), ]); $policyB = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => null, 'last_synced_at' => now(), ]); $itemA = BackupItem::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policyA->id, 'policy_identifier' => $policyA->external_id, @@ -51,7 +51,7 @@ ]); $itemB = BackupItem::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policyB->id, 'policy_identifier' => $policyB->external_id, @@ -73,7 +73,7 @@ Queue::assertPushed(RemovePoliciesFromBackupSetJob::class); $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'backup_set.update') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Filament/BackupItemsNoPollingTest.php b/apps/platform/tests/Feature/Filament/BackupItemsNoPollingTest.php index ae9d22ff..f8cee745 100644 --- a/apps/platform/tests/Feature/Filament/BackupItemsNoPollingTest.php +++ b/apps/platform/tests/Feature/Filament/BackupItemsNoPollingTest.php @@ -16,7 +16,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', ]); diff --git a/apps/platform/tests/Feature/Filament/BackupItemsRelationManagerFiltersTest.php b/apps/platform/tests/Feature/Filament/BackupItemsRelationManagerFiltersTest.php index 86b022e9..771a1bc4 100644 --- a/apps/platform/tests/Feature/Filament/BackupItemsRelationManagerFiltersTest.php +++ b/apps/platform/tests/Feature/Filament/BackupItemsRelationManagerFiltersTest.php @@ -29,15 +29,15 @@ function backupItemsRelationManagerComponent(BackupSet $backupSet) Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $otherBackupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $roleDefinition = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'role-definition', 'policy_type' => 'intuneRoleDefinition', 'display_name' => 'Application Manager', @@ -45,7 +45,7 @@ function backupItemsRelationManagerComponent(BackupSet $backupSet) ]); $roleAssignment = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'role-assignment', 'policy_type' => 'intuneRoleAssignment', 'display_name' => 'TenantPilot Assignment', @@ -53,7 +53,7 @@ function backupItemsRelationManagerComponent(BackupSet $backupSet) ]); $settingsCatalog = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'settings-policy', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Windows Hardening', @@ -108,11 +108,11 @@ function backupItemsRelationManagerComponent(BackupSet $backupSet) Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $roleDefinition = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'role-definition-clear', 'policy_type' => 'intuneRoleDefinition', 'display_name' => 'Help Desk Operator', @@ -120,7 +120,7 @@ function backupItemsRelationManagerComponent(BackupSet $backupSet) ]); $roleAssignment = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'role-assignment-clear', 'policy_type' => 'intuneRoleAssignment', 'display_name' => 'TenantPilot Assignment', @@ -163,11 +163,11 @@ function backupItemsRelationManagerComponent(BackupSet $backupSet) Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'role-definition-persist', 'policy_type' => 'intuneRoleDefinition', 'display_name' => 'Role Persistence', @@ -199,11 +199,11 @@ function backupItemsRelationManagerComponent(BackupSet $backupSet) Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'quality-policy', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Quality Policy', diff --git a/apps/platform/tests/Feature/Filament/BackupSetAdminTenantParityTest.php b/apps/platform/tests/Feature/Filament/BackupSetAdminTenantParityTest.php index 9e3fc42d..0b25c98e 100644 --- a/apps/platform/tests/Feature/Filament/BackupSetAdminTenantParityTest.php +++ b/apps/platform/tests/Feature/Filament/BackupSetAdminTenantParityTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\BackupSetResource\Pages\ListBackupSets; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,9 +13,9 @@ uses(RefreshDatabase::class); it('scopes the admin backup-set list to the remembered canonical tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $backupSetA = BackupSet::factory()->for($tenantA)->create(['name' => 'Remembered tenant backup']); diff --git a/apps/platform/tests/Feature/Filament/BackupSetEnterpriseDetailPageTest.php b/apps/platform/tests/Feature/Filament/BackupSetEnterpriseDetailPageTest.php index 31b1c1ba..ebdd8fe3 100644 --- a/apps/platform/tests/Feature/Filament/BackupSetEnterpriseDetailPageTest.php +++ b/apps/platform/tests/Feature/Filament/BackupSetEnterpriseDetailPageTest.php @@ -21,7 +21,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Nightly backup', 'item_count' => 12, 'created_by' => 'owner@example.test', @@ -72,7 +72,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Sparse backup', 'item_count' => 0, 'metadata' => [], @@ -93,7 +93,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Archived backup', 'item_count' => 1, ]); @@ -125,7 +125,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Stale dashboard backup', 'item_count' => 1, 'completed_at' => now()->subDays(2), @@ -156,7 +156,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Degraded dashboard backup', 'item_count' => 1, 'completed_at' => now()->subMinutes(45), diff --git a/apps/platform/tests/Feature/Filament/BackupSetGraphSafetyTest.php b/apps/platform/tests/Feature/Filament/BackupSetGraphSafetyTest.php index 8c03a783..3aae470f 100644 --- a/apps/platform/tests/Feature/Filament/BackupSetGraphSafetyTest.php +++ b/apps/platform/tests/Feature/Filament/BackupSetGraphSafetyTest.php @@ -2,11 +2,11 @@ use App\Filament\Resources\BackupSetResource; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; test('backup sets index renders without touching graph', function () { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant); $user->tenants()->syncWithoutDetaching([ @@ -14,12 +14,12 @@ ]); $visibleSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'name' => 'visible-backup-set', ]); $hiddenSet = BackupSet::factory()->create([ - 'tenant_id' => $otherTenant->getKey(), + 'managed_environment_id' => $otherTenant->getKey(), 'name' => 'hidden-backup-set', ]); diff --git a/apps/platform/tests/Feature/Filament/BackupSetPolicyPickerTableTest.php b/apps/platform/tests/Feature/Filament/BackupSetPolicyPickerTableTest.php index 389b7738..7643e19d 100644 --- a/apps/platform/tests/Feature/Filament/BackupSetPolicyPickerTableTest.php +++ b/apps/platform/tests/Feature/Filament/BackupSetPolicyPickerTableTest.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Intune\BackupService; use App\Support\OpsUx\OperationUxPresenter; @@ -28,12 +28,12 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', ]); $policies = Policy::factory()->count(2)->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => null, 'last_synced_at' => now(), ]); @@ -61,7 +61,7 @@ ->all(); $run = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup_set.update') ->latest('id') ->first(); @@ -91,12 +91,12 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', ]); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'display_name' => 'Provider missing policy', 'ignored_at' => null, 'missing_from_provider_at' => now()->subHour(), @@ -116,7 +116,7 @@ Queue::assertNothingPushed(); expect(OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup_set.update') ->exists())->toBeFalse(); }); @@ -131,12 +131,12 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', ]); $policies = Policy::factory()->count(2)->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => null, 'last_synced_at' => now(), ]); @@ -161,7 +161,7 @@ ->callTableBulkAction('add_selected_to_backup_set', $policies); expect(OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup_set.update') ->count())->toBe(1); @@ -185,12 +185,12 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', ]); $policies = Policy::factory()->count(1)->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => null, 'last_synced_at' => now(), ]); @@ -212,7 +212,7 @@ Queue::assertNothingPushed(); expect(OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'backup_set.update') ->exists())->toBeFalse(); }); @@ -220,8 +220,8 @@ test('policy picker table rejects cross-tenant starts (403) with no run records created', function () { Queue::fake(); - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ @@ -235,12 +235,12 @@ Filament::setTenant($tenantA, true); $backupSetB = BackupSet::factory()->create([ - 'tenant_id' => $tenantB->id, - 'name' => 'Tenant B backup', + 'managed_environment_id' => $tenantB->id, + 'name' => 'ManagedEnvironment B backup', ]); $policiesB = Policy::factory()->count(1)->create([ - 'tenant_id' => $tenantB->id, + 'managed_environment_id' => $tenantB->id, 'ignored_at' => null, 'last_synced_at' => now(), ]); @@ -262,43 +262,43 @@ Queue::assertNothingPushed(); expect(OperationRun::query() - ->where('tenant_id', $tenantA->id) + ->where('managed_environment_id', $tenantA->id) ->where('type', 'backup_set.update') ->exists())->toBeFalse(); expect(OperationRun::query() - ->where('tenant_id', $tenantB->id) + ->where('managed_environment_id', $tenantB->id) ->where('type', 'backup_set.update') ->exists())->toBeFalse(); }); test('policy picker table can filter by has versions', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $tenant->makeCurrent(); $user = User::factory()->create(); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', ]); $withVersions = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'display_name' => 'With Versions', 'ignored_at' => null, 'last_synced_at' => now(), ]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $withVersions->id, 'policy_type' => $withVersions->policy_type, 'platform' => $withVersions->platform, ]); $withoutVersions = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'display_name' => 'Without Versions', 'ignored_at' => null, 'last_synced_at' => now(), diff --git a/apps/platform/tests/Feature/Filament/BackupSetRelatedNavigationTest.php b/apps/platform/tests/Feature/Filament/BackupSetRelatedNavigationTest.php index df00f0fd..e011cbd2 100644 --- a/apps/platform/tests/Feature/Filament/BackupSetRelatedNavigationTest.php +++ b/apps/platform/tests/Feature/Filament/BackupSetRelatedNavigationTest.php @@ -13,7 +13,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Nightly backup', ]); diff --git a/apps/platform/tests/Feature/Filament/BackupSetUiEnforcementTest.php b/apps/platform/tests/Feature/Filament/BackupSetUiEnforcementTest.php index 95618f81..b7e2d764 100644 --- a/apps/platform/tests/Feature/Filament/BackupSetUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Filament/BackupSetUiEnforcementTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\BackupSetResource; use App\Filament\Resources\BackupSetResource\Pages\ListBackupSets; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\UiTooltips; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -28,8 +28,8 @@ function getTableEmptyStateAction($component, string $name): ?\Filament\Actions\ }); test('non-members are denied access to BackupSet tenant routes (404)', function () { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'owner'); @@ -39,11 +39,11 @@ function getTableEmptyStateAction($component, string $name): ?\Filament\Actions\ }); test('members without capability see BackupSet actions disabled with standard tooltip and cannot execute', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'readonly'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => 'completed', 'deleted_at' => null, ]); @@ -60,11 +60,11 @@ function getTableEmptyStateAction($component, string $name): ?\Filament\Actions\ }); test('members with capability can execute BackupSet actions', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => 'completed', 'deleted_at' => null, ]); @@ -80,7 +80,7 @@ function getTableEmptyStateAction($component, string $name): ?\Filament\Actions\ }); test('backup sets list shows empty state create action enabled for members with sync capability', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'owner'); Filament::setTenant($tenant, true); @@ -97,7 +97,7 @@ function getTableEmptyStateAction($component, string $name): ?\Filament\Actions\ }); test('backup sets list shows empty state create action disabled for members without sync capability', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'readonly'); Filament::setTenant($tenant, true); @@ -114,17 +114,17 @@ function getTableEmptyStateAction($component, string $name): ?\Filament\Actions\ }); test('readonly members still see backup quality truth on the backup-set list', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'readonly'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => 'completed', 'item_count' => 1, ]); \App\Models\BackupItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->getKey(), 'payload' => [], 'metadata' => [ diff --git a/apps/platform/tests/Feature/Filament/BaselineCompareCoverageBannerTest.php b/apps/platform/tests/Feature/Filament/BaselineCompareCoverageBannerTest.php index 5184689c..652ecdec 100644 --- a/apps/platform/tests/Feature/Filament/BaselineCompareCoverageBannerTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineCompareCoverageBannerTest.php @@ -32,7 +32,7 @@ function createCoverageBannerTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -44,7 +44,7 @@ function createCoverageBannerTenant(): array $this->actingAs($user); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -84,7 +84,7 @@ function createCoverageBannerTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -101,7 +101,7 @@ function createCoverageBannerTenant(): array $this->actingAs($user); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -135,7 +135,7 @@ function createCoverageBannerTenant(): array $this->actingAs($user); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -158,7 +158,7 @@ function createCoverageBannerTenant(): array Finding::factory()->triaged()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'due_at' => now()->subDay(), ]); diff --git a/apps/platform/tests/Feature/Filament/BaselineCompareExplanationSurfaceTest.php b/apps/platform/tests/Feature/Filament/BaselineCompareExplanationSurfaceTest.php index 3ed0489f..17b720bf 100644 --- a/apps/platform/tests/Feature/Filament/BaselineCompareExplanationSurfaceTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineCompareExplanationSurfaceTest.php @@ -34,12 +34,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Filament/BaselineCompareLandingAdminTenantParityTest.php b/apps/platform/tests/Feature/Filament/BaselineCompareLandingAdminTenantParityTest.php index b44bec07..9de30d55 100644 --- a/apps/platform/tests/Feature/Filament/BaselineCompareLandingAdminTenantParityTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineCompareLandingAdminTenantParityTest.php @@ -67,7 +67,7 @@ function baselineCompareLandingGapContext(): array ]); } -function seedBaselineCompareLandingGapRun(\App\Models\Tenant $tenant): OperationRun +function seedBaselineCompareLandingGapRun(\App\Models\ManagedEnvironment $tenant): OperationRun { $profile = BaselineProfile::factory()->active()->create([ 'workspace_id' => (int) $tenant->workspace_id, @@ -82,12 +82,12 @@ function seedBaselineCompareLandingGapRun(\App\Models\Tenant $tenant): Operation BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); return OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/Filament/BaselineCompareLandingDuplicateNamesBannerTest.php b/apps/platform/tests/Feature/Filament/BaselineCompareLandingDuplicateNamesBannerTest.php index a51f7240..aaca7835 100644 --- a/apps/platform/tests/Feature/Filament/BaselineCompareLandingDuplicateNamesBannerTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineCompareLandingDuplicateNamesBannerTest.php @@ -29,7 +29,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -40,7 +40,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'dup-1', 'policy_type' => 'deviceConfiguration', @@ -50,7 +50,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'dup-2', 'policy_type' => 'deviceConfiguration', @@ -87,7 +87,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -110,7 +110,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'stale-duplicate', 'policy_type' => 'deviceConfiguration', @@ -120,7 +120,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'current-standard', 'policy_type' => 'deviceConfiguration', @@ -130,7 +130,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'current-unique', 'policy_type' => 'deviceConfiguration', diff --git a/apps/platform/tests/Feature/Filament/BaselineCompareLandingRbacLabelsTest.php b/apps/platform/tests/Feature/Filament/BaselineCompareLandingRbacLabelsTest.php index 8e8e7b75..cf81e7de 100644 --- a/apps/platform/tests/Feature/Filament/BaselineCompareLandingRbacLabelsTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineCompareLandingRbacLabelsTest.php @@ -37,12 +37,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -72,7 +72,7 @@ ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => 'baseline_profile:'.$profile->getKey(), diff --git a/apps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php b/apps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php index 9894f08f..384ffaa2 100644 --- a/apps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php @@ -63,7 +63,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -102,7 +102,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -114,7 +114,7 @@ Queue::assertPushed(CompareBaselineToTenantJob::class); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::BaselineCompare->value) ->latest('id') ->first(); @@ -144,7 +144,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -180,7 +180,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -240,7 +240,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -285,7 +285,7 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -320,12 +320,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); $compareRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -374,12 +374,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); $compareRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -423,12 +423,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCapture->value, 'status' => OperationRunStatus::Completed->value, @@ -470,12 +470,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCapture->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/Filament/BaselineCompareLandingWhyNoFindingsTest.php b/apps/platform/tests/Feature/Filament/BaselineCompareLandingWhyNoFindingsTest.php index fe9fdc59..aa567a3a 100644 --- a/apps/platform/tests/Feature/Filament/BaselineCompareLandingWhyNoFindingsTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineCompareLandingWhyNoFindingsTest.php @@ -33,12 +33,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -87,12 +87,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -146,12 +146,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -203,12 +203,12 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/Filament/BaselineCompareNowWidgetTest.php b/apps/platform/tests/Feature/Filament/BaselineCompareNowWidgetTest.php index fb09b8bd..1d637f47 100644 --- a/apps/platform/tests/Feature/Filament/BaselineCompareNowWidgetTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineCompareNowWidgetTest.php @@ -32,7 +32,7 @@ function createBaselineCompareWidgetTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -43,7 +43,7 @@ function createBaselineCompareWidgetTenant(): array [$user, $tenant, $profile, $snapshot] = createBaselineCompareWidgetTenant(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -82,7 +82,7 @@ function createBaselineCompareWidgetTenant(): array [$user, $tenant, $profile, $snapshot] = createBaselineCompareWidgetTenant(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -126,7 +126,7 @@ function createBaselineCompareWidgetTenant(): array [$user, $tenant, $profile, $snapshot] = createBaselineCompareWidgetTenant(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -155,7 +155,7 @@ function createBaselineCompareWidgetTenant(): array [$user, $tenant, $profile, $snapshot] = createBaselineCompareWidgetTenant(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Queued->value, @@ -189,7 +189,7 @@ function createBaselineCompareWidgetTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); diff --git a/apps/platform/tests/Feature/Filament/BaselineCompareSummaryConsistencyTest.php b/apps/platform/tests/Feature/Filament/BaselineCompareSummaryConsistencyTest.php index 2cc486dd..9de988b1 100644 --- a/apps/platform/tests/Feature/Filament/BaselineCompareSummaryConsistencyTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineCompareSummaryConsistencyTest.php @@ -34,7 +34,7 @@ function createBaselineCompareSummaryConsistencyTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -58,12 +58,12 @@ function createBaselineCompareSummaryConsistencyTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -108,7 +108,7 @@ function createBaselineCompareSummaryConsistencyTenant(): array $this->actingAs($user); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -131,7 +131,7 @@ function createBaselineCompareSummaryConsistencyTenant(): array Finding::factory()->triaged()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'due_at' => now()->subDay(), ]); @@ -158,7 +158,7 @@ function createBaselineCompareSummaryConsistencyTenant(): array $this->actingAs($user); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Running->value, diff --git a/apps/platform/tests/Feature/Filament/BaselineGapSurfacesDbOnlyRenderTest.php b/apps/platform/tests/Feature/Filament/BaselineGapSurfacesDbOnlyRenderTest.php index 41506e0a..73936420 100644 --- a/apps/platform/tests/Feature/Filament/BaselineGapSurfacesDbOnlyRenderTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineGapSurfacesDbOnlyRenderTest.php @@ -64,7 +64,7 @@ function structuredGapSurfaceContext(): array Filament::setTenant(null, true); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -109,12 +109,12 @@ function structuredGapSurfaceContext(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/Filament/BaselineProfileCaptureStartSurfaceTest.php b/apps/platform/tests/Feature/Filament/BaselineProfileCaptureStartSurfaceTest.php index d5b01831..a81386ed 100644 --- a/apps/platform/tests/Feature/Filament/BaselineProfileCaptureStartSurfaceTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineProfileCaptureStartSurfaceTest.php @@ -7,7 +7,7 @@ use App\Jobs\CaptureBaselineSnapshotJob; use App\Models\BaselineProfile; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Baselines\BaselineCaptureMode; use App\Support\OperationRunType; use App\Support\Workspaces\WorkspaceContext; @@ -33,7 +33,7 @@ function baselineProfileCaptureHeaderActions(Testable $component): array } function seedCaptureProfileForTenant( - Tenant $tenant, + ManagedEnvironment $tenant, BaselineCaptureMode $captureMode = BaselineCaptureMode::FullContent, array $attributes = [], ): BaselineProfile { @@ -121,7 +121,7 @@ function seedCaptureProfileForTenant( Queue::assertPushed(CaptureBaselineSnapshotJob::class); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::BaselineCapture->value) ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php b/apps/platform/tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php index 3dfbda3a..4bb2e89a 100644 --- a/apps/platform/tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php @@ -8,7 +8,7 @@ use App\Models\BaselineProfile; use App\Models\BaselineSnapshot; use App\Models\BaselineTenantAssignment; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\OperationRun; use App\Support\Baselines\BaselineCaptureMode; use App\Support\Baselines\Compare\CompareStrategyRegistry; @@ -39,7 +39,7 @@ function baselineProfileHeaderActions(Testable $component): array /** * @return array{0: BaselineProfile, 1: BaselineSnapshot} */ -function seedComparableBaselineProfileForTenant(Tenant $tenant, BaselineCaptureMode $captureMode = BaselineCaptureMode::FullContent): array +function seedComparableBaselineProfileForTenant(ManagedEnvironment $tenant, BaselineCaptureMode $captureMode = BaselineCaptureMode::FullContent): array { [$profile, $snapshot] = seedActiveBaselineForTenant($tenant); @@ -92,7 +92,7 @@ function seedComparableBaselineProfileForTenant(Tenant $tenant, BaselineCaptureM Queue::assertPushed(CompareBaselineToTenantJob::class); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::BaselineCompare->value) ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Filament/BaselineProfileListFiltersTest.php b/apps/platform/tests/Feature/Filament/BaselineProfileListFiltersTest.php index efb439dd..2f363020 100644 --- a/apps/platform/tests/Feature/Filament/BaselineProfileListFiltersTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineProfileListFiltersTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\BaselineProfileResource\Pages\ListBaselineProfiles; use App\Models\BaselineProfile; use App\Models\BaselineTenantAssignment; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Baselines\BaselineProfileStatus; use Filament\Tables\Columns\TextColumn; @@ -71,23 +71,23 @@ 'workspace_id' => (int) $tenant->workspace_id, ]); - $firstAssignedTenant = Tenant::factory()->create([ + $firstAssignedTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); - $secondAssignedTenant = Tenant::factory()->create([ + $secondAssignedTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $firstAssignedTenant->getKey(), + 'managed_environment_id' => (int) $firstAssignedTenant->getKey(), 'baseline_profile_id' => (int) $assignedProfile->getKey(), ]); BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $secondAssignedTenant->getKey(), + 'managed_environment_id' => (int) $secondAssignedTenant->getKey(), 'baseline_profile_id' => (int) $assignedProfile->getKey(), ]); diff --git a/apps/platform/tests/Feature/Filament/BaselineSnapshotTruthSurfaceTest.php b/apps/platform/tests/Feature/Filament/BaselineSnapshotTruthSurfaceTest.php index 1c5d6b33..fb9254d3 100644 --- a/apps/platform/tests/Feature/Filament/BaselineSnapshotTruthSurfaceTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineSnapshotTruthSurfaceTest.php @@ -64,7 +64,7 @@ \App\Models\BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); diff --git a/apps/platform/tests/Feature/Filament/BaselineTenantAssignmentsRelationManagerTest.php b/apps/platform/tests/Feature/Filament/BaselineTenantAssignmentsRelationManagerTest.php index a8635aae..1df616c4 100644 --- a/apps/platform/tests/Feature/Filament/BaselineTenantAssignmentsRelationManagerTest.php +++ b/apps/platform/tests/Feature/Filament/BaselineTenantAssignmentsRelationManagerTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\BaselineProfileResource\RelationManagers\BaselineTenantAssignmentsRelationManager; use App\Models\BaselineProfile; use App\Models\BaselineTenantAssignment; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Filament\Forms\Components\Select; use Livewire\Livewire; @@ -25,23 +25,23 @@ BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $currentProfile->getKey(), ]); - $assignedTenant = Tenant::factory()->create([ + $assignedTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'name' => 'Already Assigned Tenant', + 'name' => 'Already Assigned ManagedEnvironment', ]); - $availableTenant = Tenant::factory()->create([ + $availableTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'name' => 'Available Tenant', + 'name' => 'Available ManagedEnvironment', ]); BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $assignedTenant->getKey(), + 'managed_environment_id' => (int) $assignedTenant->getKey(), 'baseline_profile_id' => (int) $otherProfile->getKey(), ]); @@ -51,7 +51,7 @@ 'pageClass' => EditBaselineProfile::class, ]) ->mountTableAction('assign') - ->assertFormFieldExists('tenant_id', function (Select $field) use ($assignedTenant, $availableTenant, $otherProfile): bool { + ->assertFormFieldExists('managed_environment_id', function (Select $field) use ($assignedTenant, $availableTenant, $otherProfile): bool { $options = $field->getOptions(); $assignedTenantKey = (int) $assignedTenant->getKey(); @@ -61,9 +61,9 @@ $availableLabel = $options[$availableTenantKey] ?? $options[(string) $availableTenantKey] ?? null; return $field->isSearchable() - && $assignedLabel === 'Already Assigned Tenant (assigned to baseline: '.$otherProfile->name.')' + && $assignedLabel === 'Already Assigned ManagedEnvironment (assigned to baseline: '.$otherProfile->name.')' && $field->isOptionDisabled($assignedTenantKey, $assignedLabel) - && $availableLabel === 'Available Tenant' + && $availableLabel === 'Available ManagedEnvironment' && ! $field->isOptionDisabled($availableTenantKey, $availableLabel); }); }); diff --git a/apps/platform/tests/Feature/Filament/CanonicalAdminTenantFilterStateTest.php b/apps/platform/tests/Feature/Filament/CanonicalAdminTenantFilterStateTest.php index fc6b5167..ec08eafd 100644 --- a/apps/platform/tests/Feature/Filament/CanonicalAdminTenantFilterStateTest.php +++ b/apps/platform/tests/Feature/Filament/CanonicalAdminTenantFilterStateTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Filament\CanonicalAdminTenantFilterState; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -20,10 +20,10 @@ function canonicalAdminTenantRequest(): Request } it('clears tenant-sensitive persisted filters when the canonical admin tenant changes', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); diff --git a/apps/platform/tests/Feature/Filament/ChooseTenantEmptyStateRegisterTenantCtaVisibilityTest.php b/apps/platform/tests/Feature/Filament/ChooseTenantEmptyStateRegisterTenantCtaVisibilityTest.php index a20923d1..88d4d387 100644 --- a/apps/platform/tests/Feature/Filament/ChooseTenantEmptyStateRegisterTenantCtaVisibilityTest.php +++ b/apps/platform/tests/Feature/Filament/ChooseTenantEmptyStateRegisterTenantCtaVisibilityTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -21,7 +21,7 @@ 'role' => 'owner', ]); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); diff --git a/apps/platform/tests/Feature/Filament/ChooseTenantIsWorkspaceScopedTest.php b/apps/platform/tests/Feature/Filament/ChooseTenantIsWorkspaceScopedTest.php index 514f10c5..6e7ffd00 100644 --- a/apps/platform/tests/Feature/Filament/ChooseTenantIsWorkspaceScopedTest.php +++ b/apps/platform/tests/Feature/Filament/ChooseTenantIsWorkspaceScopedTest.php @@ -2,8 +2,8 @@ declare(strict_types=1); -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -18,15 +18,15 @@ $workspaceA = Workspace::factory()->create(['name' => 'Workspace A']); $workspaceB = Workspace::factory()->create(['name' => 'Workspace B']); - $tenantA = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspaceA->getKey(), - 'name' => 'Tenant A', + 'name' => 'ManagedEnvironment A', 'status' => 'active', ]); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspaceB->getKey(), - 'name' => 'Tenant B', + 'name' => 'ManagedEnvironment B', 'status' => 'active', ]); @@ -42,8 +42,8 @@ 'role' => 'owner', ]); - TenantMembership::query()->create([ - 'tenant_id' => $tenantA->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenantA->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', @@ -51,8 +51,8 @@ 'created_by_user_id' => null, ]); - TenantMembership::query()->create([ - 'tenant_id' => $tenantB->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenantB->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', @@ -64,6 +64,6 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspaceA->getKey()]) ->get('/admin/choose-tenant') ->assertSuccessful() - ->assertSee('Tenant A') - ->assertDontSee('Tenant B'); + ->assertSee('ManagedEnvironment A') + ->assertDontSee('ManagedEnvironment B'); }); diff --git a/apps/platform/tests/Feature/Filament/ConditionalAccessPreviewOnlyTest.php b/apps/platform/tests/Feature/Filament/ConditionalAccessPreviewOnlyTest.php index 836b8f7b..9d37e906 100644 --- a/apps/platform/tests/Feature/Filament/ConditionalAccessPreviewOnlyTest.php +++ b/apps/platform/tests/Feature/Filament/ConditionalAccessPreviewOnlyTest.php @@ -3,7 +3,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\RestoreService; @@ -51,16 +51,16 @@ public function request(string $method, string $path, array $options = []): Grap app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-ca', - 'name' => 'Tenant CA', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-ca', + 'name' => 'ManagedEnvironment CA', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'ca-policy-1', 'policy_type' => 'conditionalAccessPolicy', 'display_name' => 'CA Policy', @@ -68,14 +68,14 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'CA Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/Filament/CreateCtaPlacementTest.php b/apps/platform/tests/Feature/Filament/CreateCtaPlacementTest.php index 5426b2a0..e8715154 100644 --- a/apps/platform/tests/Feature/Filament/CreateCtaPlacementTest.php +++ b/apps/platform/tests/Feature/Filament/CreateCtaPlacementTest.php @@ -142,7 +142,7 @@ function getPlacementEmptyStateAction(Testable $component, string $name): ?Actio Filament::setTenant($tenant, true); BackupSchedule::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Daily schedule', 'is_enabled' => true, 'timezone' => 'UTC', @@ -191,7 +191,7 @@ function getPlacementEmptyStateAction(Testable $component, string $name): ?Actio Filament::setTenant($tenant, true); RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $component = Livewire::test(ListRestoreRuns::class) @@ -231,7 +231,7 @@ function getPlacementEmptyStateAction(Testable $component, string $name): ?Actio Filament::setTenant($tenant, true); BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $component = Livewire::test(ListBackupSets::class) @@ -269,7 +269,7 @@ function getPlacementEmptyStateAction(Testable $component, string $name): ?Actio Filament::setTenant($tenant, true); ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -348,7 +348,7 @@ function getPlacementEmptyStateAction(Testable $component, string $name): ?Actio 'updated_by' => $user, 'state' => [ 'entra_tenant_id' => 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', - 'tenant_name' => 'Onboarding Tenant', + 'tenant_name' => 'Onboarding ManagedEnvironment', ], ]); @@ -449,7 +449,7 @@ function getPlacementEmptyStateAction(Testable $component, string $name): ?Actio Filament::setTenant($tenant, true); ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); diff --git a/apps/platform/tests/Feature/Filament/DashboardKpisWidgetTest.php b/apps/platform/tests/Feature/Filament/DashboardKpisWidgetTest.php index 99ed3628..11794fe2 100644 --- a/apps/platform/tests/Feature/Filament/DashboardKpisWidgetTest.php +++ b/apps/platform/tests/Feature/Filament/DashboardKpisWidgetTest.php @@ -50,7 +50,7 @@ function dashboardKpiStatPayloads($component): array /** * @return array */ -function recoveryReadinessViewData(\App\Models\Tenant $tenant): array +function recoveryReadinessViewData(\App\Models\ManagedEnvironment $tenant): array { Filament::setCurrentPanel(Filament::getPanel('tenant')); Filament::setTenant($tenant, true); @@ -65,7 +65,7 @@ function recoveryReadinessViewData(\App\Models\Tenant $tenant): array /** * @return array{value:string,description:string|null,url:string|null} */ -function backupPostureStatPayload(\App\Models\Tenant $tenant): array +function backupPostureStatPayload(\App\Models\ManagedEnvironment $tenant): array { return recoveryReadinessViewData($tenant)['backupPosture']; } @@ -73,15 +73,15 @@ function backupPostureStatPayload(\App\Models\Tenant $tenant): array /** * @return array{value:string,description:string|null,url:string|null} */ -function recoveryEvidenceStatPayload(\App\Models\Tenant $tenant): array +function recoveryEvidenceStatPayload(\App\Models\ManagedEnvironment $tenant): array { return recoveryReadinessViewData($tenant)['recoveryEvidence']; } -function makeBackupHealthScheduleForKpi(\App\Models\Tenant $tenant, array $attributes = []): BackupSchedule +function makeBackupHealthScheduleForKpi(\App\Models\ManagedEnvironment $tenant, array $attributes = []): BackupSchedule { return BackupSchedule::query()->create(array_merge([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'KPI schedule', 'is_enabled' => true, 'timezone' => 'UTC', @@ -99,7 +99,7 @@ function makeBackupHealthScheduleForKpi(\App\Models\Tenant $tenant, array $attri CarbonImmutable::setTestNow(); }); -function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attributes = []): BackupSet +function makeHealthyBackupForRecoveryKpi(\App\Models\ManagedEnvironment $tenant, array $attributes = []): BackupSet { $backupSet = BackupSet::factory()->for($tenant)->recentCompleted()->create(array_merge([ 'name' => 'Healthy recovery KPI backup', @@ -117,7 +117,7 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr dataset('dashboard-recovery-evidence-cases', [ 'failed history' => [ - fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() + fn (\App\Models\ManagedEnvironment $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->failedOutcome() @@ -126,11 +126,11 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr ]), 'Weakened', 'The restore did not complete successfully. Follow-up is still required.', - 'Tenant recovery is not proven.', + 'ManagedEnvironment recovery is not proven.', RestoreResultAttention::STATE_FAILED, ], 'partial history' => [ - fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() + fn (\App\Models\ManagedEnvironment $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->partialOutcome() @@ -139,11 +139,11 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr ]), 'Weakened', 'The restore reached a terminal state, but some items or assignments still need follow-up.', - 'Tenant-wide recovery is not proven.', + 'ManagedEnvironment-wide recovery is not proven.', RestoreResultAttention::STATE_PARTIAL, ], 'follow-up history' => [ - fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() + fn (\App\Models\ManagedEnvironment $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->completedWithFollowUp() @@ -152,11 +152,11 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr ]), 'Weakened', 'The restore completed, but follow-up remains for skipped or non-applied work.', - 'Tenant-wide recovery is not proven.', + 'ManagedEnvironment-wide recovery is not proven.', RestoreResultAttention::STATE_COMPLETED_WITH_FOLLOW_UP, ], 'calm completed history' => [ - fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() + fn (\App\Models\ManagedEnvironment $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->completedOutcome() @@ -165,7 +165,7 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr ]), 'No recent issues visible', 'Recent executed restore history exists without a current follow-up signal.', - 'Tenant-wide recovery is not proven.', + 'ManagedEnvironment-wide recovery is not proven.', 'no_recent_issues_visible', ], ]); @@ -205,7 +205,7 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -214,7 +214,7 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -223,7 +223,7 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -231,7 +231,7 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -243,47 +243,34 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr $stats = dashboardKpiStatPayloads(Livewire::test(DashboardKpis::class)); - expect($stats)->toMatchArray([ - 'Open drift findings' => [ - 'value' => '3', - 'description' => 'active drift workflow items', - 'url' => FindingResource::getUrl('index', [ - 'tab' => 'needs_action', - 'finding_type' => Finding::FINDING_TYPE_DRIFT, - ], panel: 'tenant', tenant: $tenant), - ], - 'High severity active findings' => [ + expect($stats)->toHaveKeys([ + 'High severity findings', + 'Overdue findings', + 'Missing permissions', + 'Active operations', + ]); + + expect($stats['High severity findings'])->toMatchArray([ 'value' => '2', - 'description' => 'high or critical findings needing review', 'url' => FindingResource::getUrl('index', [ 'tab' => 'needs_action', 'high_severity' => 1, ], panel: 'tenant', tenant: $tenant), - ], - 'Active operations' => [ - 'value' => '1', - 'description' => 'healthy queued or running tenant work', - 'url' => OperationRunLinks::index($tenant, activeTab: 'active'), - ], - 'Likely stale operations' => [ - 'value' => '1', - 'description' => 'queued or running past the lifecycle window', - 'url' => OperationRunLinks::index( - $tenant, - activeTab: OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION, - problemClass: OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION, - ), - ], - 'Terminal follow-up operations' => [ - 'value' => '2', - 'description' => 'blocked, partial, failed, or auto-reconciled runs', + ]) + ->and($stats['Overdue findings']['value'])->toBe('0') + ->and($stats['Overdue findings']['url'])->toBe(FindingResource::getUrl('index', [ + 'tab' => 'overdue', + ], panel: 'tenant', tenant: $tenant)) + ->and((int) $stats['Missing permissions']['value'])->toBeGreaterThan(0) + ->and($stats['Missing permissions']['url'])->not->toBeNull() + ->and($stats['Active operations'])->toMatchArray([ + 'value' => '3', 'url' => OperationRunLinks::index( $tenant, activeTab: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, problemClass: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, ), - ], - ]); + ]); }); it('keeps findings KPI truth visible while disabling dead-end drill-throughs for members without findings access', function (): void { @@ -303,17 +290,12 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr $stats = dashboardKpiStatPayloads(Livewire::test(DashboardKpis::class)); - expect($stats['Open drift findings'])->toMatchArray([ - 'value' => '1', - 'description' => UiTooltips::INSUFFICIENT_PERMISSION, - 'url' => null, - ]); + expect($stats['High severity findings']['value'])->toBe('1') + ->and($stats['High severity findings']['description'])->toContain('1 active') + ->and($stats['High severity findings']['description'])->not->toBe(UiTooltips::INSUFFICIENT_PERMISSION) + ->and($stats['High severity findings']['url'])->toBeNull(); - expect($stats['High severity active findings'])->toMatchArray([ - 'value' => '1', - 'description' => UiTooltips::INSUFFICIENT_PERMISSION, - 'url' => null, - ]); + expect($stats)->not->toHaveKey('Open drift findings'); }); it('shows absent backup posture and routes the KPI to the backup-set list', function (): void { @@ -456,7 +438,7 @@ function makeHealthyBackupForRecoveryKpi(\App\Models\Tenant $tenant, array $attr expect($recoveryStat['description']) ->toContain('No executed restore history is visible in the latest tenant restore records.') - ->toContain('Tenant-wide recovery is not proven.'); + ->toContain('ManagedEnvironment-wide recovery is not proven.'); }); it('surfaces weak and calm restore history on the recovery evidence KPI', function ( diff --git a/apps/platform/tests/Feature/Filament/DashboardRecoveryPosturePerformanceTest.php b/apps/platform/tests/Feature/Filament/DashboardRecoveryPosturePerformanceTest.php index 9d76f2e4..e613f5a8 100644 --- a/apps/platform/tests/Feature/Filament/DashboardRecoveryPosturePerformanceTest.php +++ b/apps/platform/tests/Feature/Filament/DashboardRecoveryPosturePerformanceTest.php @@ -12,7 +12,7 @@ use Illuminate\Support\Facades\DB; use Livewire\Livewire; -function makeHealthyBackupForRecoveryPerformance(\App\Models\Tenant $tenant): BackupSet +function makeHealthyBackupForRecoveryPerformance(\App\Models\ManagedEnvironment $tenant): BackupSet { $backupSet = BackupSet::factory()->for($tenant)->recentCompleted()->create([ 'name' => 'Performance healthy backup', @@ -72,7 +72,7 @@ function makeHealthyBackupForRecoveryPerformance(\App\Models\Tenant $tenant): Ba it('keeps the latest-10 restore-history cap when recovery evidence is derived for multiple tenants in batch', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'owner', ensureDefaultMicrosoftProviderConnection: false); - $tenantB = \App\Models\Tenant::factory()->create([ + $tenantB = \App\Models\ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, 'name' => 'Second batch tenant', @@ -83,7 +83,7 @@ function makeHealthyBackupForRecoveryPerformance(\App\Models\Tenant $tenant): Ba makeHealthyBackupForRecoveryPerformance($tenantB); $tenantABackup = BackupSet::factory()->for($tenantA)->create([ - 'name' => 'Tenant A candidate cap backup', + 'name' => 'ManagedEnvironment A candidate cap backup', ]); foreach (range(1, 10) as $minutesAgo) { @@ -109,7 +109,7 @@ function makeHealthyBackupForRecoveryPerformance(\App\Models\Tenant $tenant): Ba ]); $tenantBBackup = BackupSet::factory()->for($tenantB)->create([ - 'name' => 'Tenant B weakened backup', + 'name' => 'ManagedEnvironment B weakened backup', ]); RestoreRun::factory() diff --git a/apps/platform/tests/Feature/Filament/DerivedStateMutationFreshnessTest.php b/apps/platform/tests/Feature/Filament/DerivedStateMutationFreshnessTest.php index ed8abd81..0c3de12c 100644 --- a/apps/platform/tests/Feature/Filament/DerivedStateMutationFreshnessTest.php +++ b/apps/platform/tests/Feature/Filament/DerivedStateMutationFreshnessTest.php @@ -28,11 +28,11 @@ uses(RefreshDatabase::class); it('refreshes evidence artifact truth after expiring a snapshot in the same request', function (): void { - $tenant = \App\Models\Tenant::factory()->create(); + $tenant = \App\Models\ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -67,11 +67,11 @@ }); it('refreshes review-pack artifact truth after expiring a pack in the same request', function (): void { - $tenant = \App\Models\Tenant::factory()->create(); + $tenant = \App\Models\ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'file_disk' => 'exports', @@ -101,11 +101,11 @@ }); it('returns fresh operation guidance after run state changes within the same request', function (): void { - $tenant = \App\Models\Tenant::factory()->create(); + $tenant = \App\Models\ManagedEnvironment::factory()->create(); createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -149,17 +149,17 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $versionA = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, ]); $versionB = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, ]); diff --git a/apps/platform/tests/Feature/Filament/EditTenantHeaderDisciplineTest.php b/apps/platform/tests/Feature/Filament/EditTenantHeaderDisciplineTest.php index 84597ae9..09f6db79 100644 --- a/apps/platform/tests/Feature/Filament/EditTenantHeaderDisciplineTest.php +++ b/apps/platform/tests/Feature/Filament/EditTenantHeaderDisciplineTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Resources\TenantResource\Pages\EditTenant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Filament\Actions\Action; use Filament\Actions\ActionGroup; use Filament\Facades\Filament; @@ -45,7 +45,7 @@ function editTenantHeaderPrimaryNames(Testable $component): array } it('keeps related links in contextual placement and reserves the header for lifecycle actions', function (): void { - $tenant = Tenant::factory()->onboarding()->create(); + $tenant = ManagedEnvironment::factory()->onboarding()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); createOnboardingDraft([ @@ -54,7 +54,7 @@ function editTenantHeaderPrimaryNames(Testable $component): array 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -72,7 +72,7 @@ function editTenantHeaderPrimaryNames(Testable $component): array }); it('keeps tenant lifecycle mutations available under the lifecycle header group with confirmation intact', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user); diff --git a/apps/platform/tests/Feature/Filament/EnrollmentAutopilotSettingsDisplayTest.php b/apps/platform/tests/Feature/Filament/EnrollmentAutopilotSettingsDisplayTest.php index 06724b3c..229cc548 100644 --- a/apps/platform/tests/Feature/Filament/EnrollmentAutopilotSettingsDisplayTest.php +++ b/apps/platform/tests/Feature/Filament/EnrollmentAutopilotSettingsDisplayTest.php @@ -17,7 +17,7 @@ test('policy detail renders normalized settings for Autopilot profiles', function () { $policy = Policy::factory()->create([ - 'tenant_id' => $this->tenant->getKey(), + 'managed_environment_id' => $this->tenant->getKey(), 'external_id' => 'autopilot-1', 'policy_type' => 'windowsAutopilotDeploymentProfile', 'display_name' => 'Autopilot Profile A', @@ -25,7 +25,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->getKey(), + 'managed_environment_id' => $this->tenant->getKey(), 'policy_id' => $policy->getKey(), 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -60,7 +60,7 @@ test('policy detail renders normalized settings for Enrollment Status Page (ESP)', function () { $policy = Policy::factory()->create([ - 'tenant_id' => $this->tenant->getKey(), + 'managed_environment_id' => $this->tenant->getKey(), 'external_id' => 'esp-1', 'policy_type' => 'windowsEnrollmentStatusPage', 'display_name' => 'ESP A', @@ -68,7 +68,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->getKey(), + 'managed_environment_id' => $this->tenant->getKey(), 'policy_id' => $policy->getKey(), 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -102,7 +102,7 @@ test('policy detail renders normalized settings for platform restrictions (enrollment)', function () { $policy = Policy::factory()->create([ - 'tenant_id' => $this->tenant->getKey(), + 'managed_environment_id' => $this->tenant->getKey(), 'external_id' => 'enroll-restrict-1', 'policy_type' => 'deviceEnrollmentPlatformRestrictionsConfiguration', 'display_name' => 'Restriction A', @@ -110,7 +110,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->getKey(), + 'managed_environment_id' => $this->tenant->getKey(), 'policy_id' => $policy->getKey(), 'version_number' => 1, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/EnrollmentRestrictionsPreviewOnlyTest.php b/apps/platform/tests/Feature/Filament/EnrollmentRestrictionsPreviewOnlyTest.php index 4099ec34..798940de 100644 --- a/apps/platform/tests/Feature/Filament/EnrollmentRestrictionsPreviewOnlyTest.php +++ b/apps/platform/tests/Feature/Filament/EnrollmentRestrictionsPreviewOnlyTest.php @@ -3,7 +3,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\RestoreService; @@ -51,16 +51,16 @@ public function request(string $method, string $path, array $options = []): Grap app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-enrollment-restriction', - 'name' => 'Tenant Enrollment Restriction', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-enrollment-restriction', + 'name' => 'ManagedEnvironment Enrollment Restriction', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'enrollment-restriction-1', 'policy_type' => 'enrollmentRestriction', 'display_name' => 'Enrollment Restriction', @@ -68,14 +68,14 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Enrollment Restriction Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -155,16 +155,16 @@ public function request(string $method, string $path, array $options = []): Grap app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-enrollment-limit', - 'name' => 'Tenant Enrollment Limit', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-enrollment-limit', + 'name' => 'ManagedEnvironment Enrollment Limit', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'enrollment-limit-1', 'policy_type' => 'deviceEnrollmentLimitConfiguration', 'display_name' => 'Enrollment Limit', @@ -172,14 +172,14 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Enrollment Limit Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/Filament/EnterpriseDetailTemplateRegressionTest.php b/apps/platform/tests/Feature/Filament/EnterpriseDetailTemplateRegressionTest.php index 646578b0..7fe54f55 100644 --- a/apps/platform/tests/Feature/Filament/EnterpriseDetailTemplateRegressionTest.php +++ b/apps/platform/tests/Feature/Filament/EnterpriseDetailTemplateRegressionTest.php @@ -50,7 +50,7 @@ ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Nightly backup', ]); @@ -61,7 +61,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, diff --git a/apps/platform/tests/Feature/Filament/EntraGroupAdminScopeTest.php b/apps/platform/tests/Feature/Filament/EntraGroupAdminScopeTest.php index 9f434e2c..c326773b 100644 --- a/apps/platform/tests/Feature/Filament/EntraGroupAdminScopeTest.php +++ b/apps/platform/tests/Feature/Filament/EntraGroupAdminScopeTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\EntraGroupResource; use App\Filament\Resources\EntraGroupResource\Pages\ListEntraGroups; use App\Models\EntraGroup; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -26,10 +26,10 @@ }); it('scopes the admin group list to the remembered tenant context', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -58,10 +58,10 @@ }); it('returns not found for admin direct group detail outside the canonical tenant scope', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -90,10 +90,10 @@ }); it('keeps persisted admin group search inside the remembered canonical tenant after tenant changes', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); diff --git a/apps/platform/tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php b/apps/platform/tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php index 1fef73d7..df3a0b9c 100644 --- a/apps/platform/tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php +++ b/apps/platform/tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\EntraGroupResource; use App\Models\EntraGroup; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -35,10 +35,10 @@ function entraGroupSearchTitles($results): array }); it('scopes admin global-search results to the remembered tenant context', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -73,21 +73,21 @@ function entraGroupSearchTitles($results): array }); it('keeps tenant-panel global-search results panel-native', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $groupA = EntraGroup::factory()->for($tenantA)->create([ - 'display_name' => 'Tenant panel group', + 'display_name' => 'ManagedEnvironment panel group', ]); EntraGroup::factory()->for($tenantB)->create([ - 'display_name' => 'Tenant panel outsider', + 'display_name' => 'ManagedEnvironment panel outsider', ]); $this->actingAs($user); @@ -97,10 +97,10 @@ function entraGroupSearchTitles($results): array session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); - $results = EntraGroupResource::getGlobalSearchResults('Tenant panel'); + $results = EntraGroupResource::getGlobalSearchResults('ManagedEnvironment panel'); expect(entraGroupSearchTitles($results))->toBe([ - 'Tenant panel group', + 'ManagedEnvironment panel group', ]); expect($results->first()?->url) diff --git a/apps/platform/tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php b/apps/platform/tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php index 3a6393a6..45b46ada 100644 --- a/apps/platform/tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php +++ b/apps/platform/tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php @@ -18,11 +18,11 @@ uses(RefreshDatabase::class); it('reuses one artifact-truth resolution per active snapshot row on the evidence overview', function (): void { - $tenant = \App\Models\Tenant::factory()->create(); + $tenant = \App\Models\ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Partial->value, @@ -82,7 +82,7 @@ }); it('keeps the evidence overview deny-as-not-found for users outside the workspace boundary', function (): void { - $workspaceTenant = \App\Models\Tenant::factory()->create(); + $workspaceTenant = \App\Models\ManagedEnvironment::factory()->create(); $user = \App\Models\User::factory()->create(); Filament::setTenant(null, true); diff --git a/apps/platform/tests/Feature/Filament/FindingViewRbacEvidenceTest.php b/apps/platform/tests/Feature/Filament/FindingViewRbacEvidenceTest.php index 631f3ec5..14248db3 100644 --- a/apps/platform/tests/Feature/Filament/FindingViewRbacEvidenceTest.php +++ b/apps/platform/tests/Feature/Filament/FindingViewRbacEvidenceTest.php @@ -134,7 +134,7 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => $rawSubjectExternalId, 'policy_type' => 'intuneRoleDefinition', @@ -144,7 +144,7 @@ ]); $finding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'subject_type' => 'policy', @@ -183,7 +183,7 @@ /** * @param array $rbacOverrides */ -function findingViewRbacFinding(\App\Models\Tenant $tenant, array $rbacOverrides = []): Finding +function findingViewRbacFinding(\App\Models\ManagedEnvironment $tenant, array $rbacOverrides = []): Finding { $subjectExternalId = BaselineSubjectKey::workspaceSafeSubjectExternalIdForPolicy( 'intuneRoleDefinition', @@ -192,7 +192,7 @@ function findingViewRbacFinding(\App\Models\Tenant $tenant, array $rbacOverrides ); return Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'subject_type' => 'policy', diff --git a/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationHydrationTest.php b/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationHydrationTest.php index 869b9f9f..46996281 100644 --- a/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationHydrationTest.php +++ b/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationHydrationTest.php @@ -1,7 +1,7 @@ instance(GraphClientInterface::class, $client); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-gpo-hydration', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-gpo-hydration', + 'name' => 'ManagedEnvironment One', 'status' => 'active', ]); ensureDefaultProviderConnection($tenant); - putenv('INTUNE_TENANT_ID='.$tenant->tenant_id); - $_ENV['INTUNE_TENANT_ID'] = $tenant->tenant_id; - $_SERVER['INTUNE_TENANT_ID'] = $tenant->tenant_id; + putenv('INTUNE_TENANT_ID='.$tenant->managed_environment_id); + $_ENV['INTUNE_TENANT_ID'] = $tenant->managed_environment_id; + $_SERVER['INTUNE_TENANT_ID'] = $tenant->managed_environment_id; $tenant->makeCurrent(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => 'gpo-hydrate', 'policy_type' => 'groupPolicyConfiguration', 'display_name' => 'Admin Templates Alpha', diff --git a/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationNormalizedDiffTest.php b/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationNormalizedDiffTest.php index bf57922a..3a16ece5 100644 --- a/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationNormalizedDiffTest.php +++ b/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationNormalizedDiffTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\PolicyVersionResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\PolicyNormalizer; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -37,14 +37,14 @@ }); test('group policy configuration policy-version detail renders the shared normalized diff family', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'gpo-policy-1', 'policy_type' => 'groupPolicyConfiguration', 'display_name' => 'Admin Templates Alpha', @@ -52,7 +52,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -76,7 +76,7 @@ ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationRestoreTest.php b/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationRestoreTest.php index d19a3e27..ba6e72fc 100644 --- a/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationRestoreTest.php +++ b/apps/platform/tests/Feature/Filament/GroupPolicyConfigurationRestoreTest.php @@ -3,7 +3,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -97,16 +97,16 @@ public function request(string $method, string $path, array $options = []): Grap app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-gpo-restore', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-gpo-restore', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'gpo-1', 'policy_type' => 'groupPolicyConfiguration', 'display_name' => 'Admin Templates Alpha', @@ -114,7 +114,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, @@ -143,7 +143,7 @@ public function request(string $method, string $path, array $options = []): Grap ]; $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/Filament/HousekeepingTest.php b/apps/platform/tests/Feature/Filament/HousekeepingTest.php index b2b2a877..6f424508 100644 --- a/apps/platform/tests/Feature/Filament/HousekeepingTest.php +++ b/apps/platform/tests/Feature/Filament/HousekeepingTest.php @@ -10,7 +10,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -19,21 +19,21 @@ uses(RefreshDatabase::class); test('backup set can be archived when unused', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment', ]); $tenant->makeCurrent(); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Set 1', 'status' => 'completed', ]); BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'policy-1', @@ -62,21 +62,21 @@ }); test('backup set can be archived when restore runs exist', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-2', - 'name' => 'Tenant 2', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-2', + 'name' => 'ManagedEnvironment 2', ]); $tenant->makeCurrent(); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Set with restore', 'status' => 'completed', ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', ]); @@ -101,21 +101,21 @@ }); test('backup set can be force deleted when trashed and unused', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-force', - 'name' => 'Tenant Force', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-force', + 'name' => 'ManagedEnvironment Force', ]); $tenant->makeCurrent(); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Set force', 'status' => 'completed', ]); BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'policy-force', @@ -146,21 +146,21 @@ }); test('backup set can be restored when archived', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-restore-backup-set', - 'name' => 'Tenant Restore Backup Set', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-restore-backup-set', + 'name' => 'ManagedEnvironment Restore Backup Set', ]); $tenant->makeCurrent(); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Set restore', 'status' => 'completed', ]); BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'policy-restore', @@ -191,22 +191,22 @@ }); test('restore run can be archived and force deleted', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-restore-run', - 'name' => 'Tenant Restore Run', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-restore-run', + 'name' => 'ManagedEnvironment Restore Run', ]); $tenant->makeCurrent(); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Set RR', 'status' => 'completed', 'item_count' => 1, ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, @@ -233,22 +233,22 @@ }); test('restore run can be restored when archived', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-restore-restore-run', - 'name' => 'Tenant Restore Restore Run', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-restore-restore-run', + 'name' => 'ManagedEnvironment Restore Restore Run', ]); $tenant->makeCurrent(); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Set for restore run restore', 'status' => 'completed', 'item_count' => 1, ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, @@ -275,16 +275,16 @@ }); test('policy can be ignored and restored via row actions', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-policy-row-actions', - 'name' => 'Tenant Policy Row Actions', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-policy-row-actions', + 'name' => 'ManagedEnvironment Policy Row Actions', 'metadata' => [], ]); $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-row-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Row Action Policy', @@ -314,22 +314,22 @@ }); test('policy version can be archived with audit log', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-3', - 'name' => 'Tenant 3', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-3', + 'name' => 'ManagedEnvironment 3', ]); $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'pol-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy', ]); $version = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => 'deviceConfiguration', @@ -355,22 +355,22 @@ }); test('policy version can be force deleted when trashed', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-3b', - 'name' => 'Tenant 3b', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-3b', + 'name' => 'ManagedEnvironment 3b', ]); $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'pol-1b', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy B', ]); $version = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => 'deviceConfiguration', @@ -398,9 +398,9 @@ }); test('tenant can be archived and hidden from default lists', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-4', - 'name' => 'Tenant 4', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-4', + 'name' => 'ManagedEnvironment 4', 'status' => 'active', ]); @@ -413,9 +413,9 @@ 'archive_reason' => 'Removing this tenant from the active housekeeping list.', ]); - expect(Tenant::count())->toBe(0); + expect(ManagedEnvironment::count())->toBe(0); - $this->assertSoftDeleted('tenants', ['id' => $tenant->id]); + $this->assertSoftDeleted('managed_environments', ['id' => $tenant->id]); $this->assertDatabaseHas('audit_logs', [ 'resource_type' => 'tenant', 'resource_id' => (string) $tenant->id, @@ -424,30 +424,30 @@ }); test('tenant must be trashed before force delete and removes permanently', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-5', - 'name' => 'Tenant 5', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-5', + 'name' => 'ManagedEnvironment 5', ]); $tenant->delete(); $tenant->forceDelete(); - $this->assertDatabaseMissing('tenants', ['id' => $tenant->id]); + $this->assertDatabaseMissing('managed_environments', ['id' => $tenant->id]); }); test('tenant table archive filter toggles active and archived tenants', function () { - $active = Tenant::factory()->create([ - 'tenant_id' => 'tenant-active', - 'name' => 'Active Tenant', + $active = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-active', + 'name' => 'Active ManagedEnvironment', 'status' => 'active', ]); [$user, $active] = createUserWithTenant(tenant: $active, role: 'owner'); $this->actingAs($user); - $archived = Tenant::factory()->create([ - 'tenant_id' => 'tenant-archived', - 'name' => 'Archived Tenant', + $archived = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-archived', + 'name' => 'Archived ManagedEnvironment', 'status' => 'active', 'workspace_id' => $active->workspace_id, ]); @@ -484,18 +484,18 @@ }); test('archived tenant can be restored from the table', function () { - $contextTenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-restore-context', - 'name' => 'Restore Context Tenant', + $contextTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-restore-context', + 'name' => 'Restore Context ManagedEnvironment', 'status' => 'active', ]); [$user, $contextTenant] = createUserWithTenant(tenant: $contextTenant, role: 'owner'); $this->actingAs($user); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-restore', - 'name' => 'Restore Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-restore', + 'name' => 'Restore ManagedEnvironment', 'status' => 'active', 'workspace_id' => $contextTenant->workspace_id, ]); @@ -518,10 +518,10 @@ ->filterTable('trashed', false) ->callTableAction('restore', $tenant); - $this->assertDatabaseHas('tenants', [ + $this->assertDatabaseHas('managed_environments', [ 'id' => $tenant->id, 'deleted_at' => null, - 'status' => 'active', + 'lifecycle_status' => 'active', ]); $this->assertDatabaseHas('audit_logs', [ diff --git a/apps/platform/tests/Feature/Filament/InventoryCoverageAdminTenantParityTest.php b/apps/platform/tests/Feature/Filament/InventoryCoverageAdminTenantParityTest.php index e437fdb0..b4e187ea 100644 --- a/apps/platform/tests/Feature/Filament/InventoryCoverageAdminTenantParityTest.php +++ b/apps/platform/tests/Feature/Filament/InventoryCoverageAdminTenantParityTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\InventoryCoverage; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Badges\BadgeCatalog; use App\Support\Badges\BadgeDomain; use App\Support\Inventory\InventoryCoverage as InventoryCoveragePayload; @@ -16,13 +16,13 @@ uses(RefreshDatabase::class); it('loads inventory coverage from the remembered canonical tenant in the admin panel', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', @@ -42,7 +42,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', @@ -72,7 +72,7 @@ Livewire::actingAs($user)->test(InventoryCoverage::class) ->assertOk() - ->assertSee('Tenant coverage truth') + ->assertSee('ManagedEnvironment coverage truth') ->assertTableColumnFormattedStateSet( 'coverage_state', BadgeCatalog::spec(BadgeDomain::InventoryCoverageState, 'failed')->label, diff --git a/apps/platform/tests/Feature/Filament/InventoryCoverageRunContinuityTest.php b/apps/platform/tests/Feature/Filament/InventoryCoverageRunContinuityTest.php index 84b8bbf2..22511dd3 100644 --- a/apps/platform/tests/Feature/Filament/InventoryCoverageRunContinuityTest.php +++ b/apps/platform/tests/Feature/Filament/InventoryCoverageRunContinuityTest.php @@ -6,17 +6,17 @@ use App\Filament\Resources\InventoryItemResource; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Inventory\InventoryCoverage as InventoryCoveragePayload; use App\Support\OperationRunLinks; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); -function seedCoverageBasisRun(Tenant $tenant): OperationRun +function seedCoverageBasisRun(ManagedEnvironment $tenant): OperationRun { return OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', @@ -37,7 +37,7 @@ function seedCoverageBasisRun(Tenant $tenant): OperationRun } it('shows the basis run and tenant-scoped history path on the coverage report for authorized viewers', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = seedCoverageBasisRun($tenant); @@ -55,7 +55,7 @@ function seedCoverageBasisRun(Tenant $tenant): OperationRun }); it('degrades basis-run links safely for viewers who cannot open inventory-sync runs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); seedCoverageBasisRun($tenant); @@ -74,7 +74,7 @@ function seedCoverageBasisRun(Tenant $tenant): OperationRun }); it('shows the last inventory sync as a canonical admin operation detail link', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->forTenant($tenant)->create([ @@ -82,7 +82,7 @@ function seedCoverageBasisRun(Tenant $tenant): OperationRun ]); $item = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'last_seen_operation_run_id' => (int) $run->getKey(), ]); @@ -94,7 +94,7 @@ function seedCoverageBasisRun(Tenant $tenant): OperationRun }); it('keeps the no-basis fallback explicit on the inventory items list', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user) diff --git a/apps/platform/tests/Feature/Filament/InventoryCoverageTableTest.php b/apps/platform/tests/Feature/Filament/InventoryCoverageTableTest.php index d9bd1d9a..bc92e7d4 100644 --- a/apps/platform/tests/Feature/Filament/InventoryCoverageTableTest.php +++ b/apps/platform/tests/Feature/Filament/InventoryCoverageTableTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\InventoryCoverage; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceMembership; use App\Support\Badges\BadgeCatalog; @@ -23,7 +23,7 @@ function inventoryCoverageRecordKey(string $segment, string $type): string return "{$segment}:{$type}"; } -function inventoryCoverageComponent(User $user, Tenant $tenant): Testable +function inventoryCoverageComponent(User $user, ManagedEnvironment $tenant): Testable { $tenant->makeCurrent(); Filament::setTenant($tenant, true); @@ -33,10 +33,10 @@ function inventoryCoverageComponent(User $user, Tenant $tenant): Testable return Livewire::actingAs($user)->test(InventoryCoverage::class); } -function seedTruthfulCoverageRun(Tenant $tenant): OperationRun +function seedTruthfulCoverageRun(ManagedEnvironment $tenant): OperationRun { InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Conditional Access Prod', 'policy_type' => 'conditionalAccessPolicy', 'external_id' => 'ca-1', @@ -44,7 +44,7 @@ function seedTruthfulCoverageRun(Tenant $tenant): OperationRun ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Compliance Legacy', 'policy_type' => 'deviceCompliancePolicy', 'external_id' => 'dc-1', @@ -52,7 +52,7 @@ function seedTruthfulCoverageRun(Tenant $tenant): OperationRun ]); return OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Filament/InventoryHubDbOnlyTest.php b/apps/platform/tests/Feature/Filament/InventoryHubDbOnlyTest.php index 0a867f8e..8a9d0eb6 100644 --- a/apps/platform/tests/Feature/Filament/InventoryHubDbOnlyTest.php +++ b/apps/platform/tests/Feature/Filament/InventoryHubDbOnlyTest.php @@ -12,7 +12,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'display_name' => 'Item A', 'policy_type' => 'deviceConfiguration', 'external_id' => 'item-a', @@ -20,7 +20,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', @@ -41,7 +41,7 @@ $this->get(InventoryCoverage::getUrl(tenant: $tenant)) ->assertOk() - ->assertSee('Tenant coverage truth'); + ->assertSee('ManagedEnvironment coverage truth'); }); Bus::assertNothingDispatched(); diff --git a/apps/platform/tests/Feature/Filament/InventoryItemDependencyEdgesTableTest.php b/apps/platform/tests/Feature/Filament/InventoryItemDependencyEdgesTableTest.php index c27abadc..1d883f22 100644 --- a/apps/platform/tests/Feature/Filament/InventoryItemDependencyEdgesTableTest.php +++ b/apps/platform/tests/Feature/Filament/InventoryItemDependencyEdgesTableTest.php @@ -5,7 +5,7 @@ use App\Livewire\InventoryItemDependencyEdgesTable; use App\Models\InventoryItem; use App\Models\InventoryLink; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -14,7 +14,7 @@ uses(RefreshDatabase::class); -function dependencyEdgesTableComponent(User $user, Tenant $tenant, InventoryItem $item) +function dependencyEdgesTableComponent(User $user, ManagedEnvironment $tenant, InventoryItem $item) { $tenant->makeCurrent(); Filament::setTenant($tenant, true); @@ -30,12 +30,12 @@ function dependencyEdgesTableComponent(User $user, Tenant $tenant, InventoryItem [$user, $tenant] = createUserWithTenant(role: 'owner'); $item = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); $assigned = InventoryLink::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'missing', @@ -48,7 +48,7 @@ function dependencyEdgesTableComponent(User $user, Tenant $tenant, InventoryItem ]); $scoped = InventoryLink::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'missing', @@ -61,7 +61,7 @@ function dependencyEdgesTableComponent(User $user, Tenant $tenant, InventoryItem ]); $inbound = InventoryLink::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => (string) Str::uuid(), 'target_type' => 'inventory_item', @@ -113,7 +113,7 @@ function dependencyEdgesTableComponent(User $user, Tenant $tenant, InventoryItem [$user, $tenant] = createUserWithTenant(role: 'owner'); $foreignItem = InventoryItem::factory()->create([ - 'tenant_id' => (int) Tenant::factory()->create()->getKey(), + 'managed_environment_id' => (int) ManagedEnvironment::factory()->create()->getKey(), 'external_id' => (string) Str::uuid(), ]); diff --git a/apps/platform/tests/Feature/Filament/InventoryItemListFiltersTest.php b/apps/platform/tests/Feature/Filament/InventoryItemListFiltersTest.php index 2cc40f05..8509da40 100644 --- a/apps/platform/tests/Feature/Filament/InventoryItemListFiltersTest.php +++ b/apps/platform/tests/Feature/Filament/InventoryItemListFiltersTest.php @@ -4,36 +4,36 @@ use App\Filament\Resources\InventoryItemResource\Pages\ListInventoryItems; use App\Models\InventoryItem; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Filament\Facades\Filament; use Livewire\Livewire; it('filters inventory items by policy type, platform, and freshness inside the active tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $matching = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'policy_type' => 'deviceConfiguration', 'platform' => 'windows', 'last_seen_at' => now(), ]); $stale = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'policy_type' => 'deviceConfiguration', 'platform' => 'windows', 'last_seen_at' => now()->subDays(3), ]); $otherTenant = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'policy_type' => 'deviceConfiguration', 'platform' => 'windows', 'last_seen_at' => now(), @@ -55,13 +55,13 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $fresh = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'platform' => 'windows', 'last_seen_at' => now(), ]); $stale = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'platform' => 'windows', 'last_seen_at' => now()->subDays(3), ]); diff --git a/apps/platform/tests/Feature/Filament/InventoryItemResourceTest.php b/apps/platform/tests/Feature/Filament/InventoryItemResourceTest.php index bfd13c85..578dd783 100644 --- a/apps/platform/tests/Feature/Filament/InventoryItemResourceTest.php +++ b/apps/platform/tests/Feature/Filament/InventoryItemResourceTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\InventoryItemResource\Pages\ListInventoryItems; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\UiTooltips; use App\Support\Inventory\InventoryCoverage as InventoryCoveragePayload; use App\Support\Workspaces\WorkspaceContext; @@ -19,13 +19,13 @@ }); test('inventory items are listed for the active tenant', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); - $otherTenant = Tenant::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'display_name' => 'Item A', 'policy_type' => 'deviceConfiguration', 'external_id' => 'item-a', @@ -33,7 +33,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => $otherTenant->getKey(), + 'managed_environment_id' => $otherTenant->getKey(), 'display_name' => 'Item B', 'policy_type' => 'deviceConfiguration', 'external_id' => 'item-b', @@ -48,7 +48,7 @@ }); test('inventory items page remembers the active tenant for follow-up interactions', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user) @@ -65,8 +65,8 @@ }); test('non-members are denied access to inventory item tenant routes (404)', function () { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'owner'); @@ -76,7 +76,7 @@ }); test('members without capability see inventory sync action disabled with standard tooltip', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'readonly'); $tenant->makeCurrent(); @@ -90,11 +90,11 @@ }); test('inventory items page shows truthful coverage stats instead of support-matrix wording', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Conditional Access Prod', 'policy_type' => 'conditionalAccessPolicy', 'external_id' => 'ca-1', @@ -102,7 +102,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Filament/InventoryKpiActivityAgreementTest.php b/apps/platform/tests/Feature/Filament/InventoryKpiActivityAgreementTest.php index 50eeacc0..d3ead8d8 100644 --- a/apps/platform/tests/Feature/Filament/InventoryKpiActivityAgreementTest.php +++ b/apps/platform/tests/Feature/Filament/InventoryKpiActivityAgreementTest.php @@ -26,7 +26,7 @@ function inventoryKpiValues($component): array [$user, $tenant] = createUserWithTenant(role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -65,7 +65,7 @@ function inventoryKpiValues($component): array ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', diff --git a/apps/platform/tests/Feature/Filament/InventoryPagesTest.php b/apps/platform/tests/Feature/Filament/InventoryPagesTest.php index 9e6e716a..43422342 100644 --- a/apps/platform/tests/Feature/Filament/InventoryPagesTest.php +++ b/apps/platform/tests/Feature/Filament/InventoryPagesTest.php @@ -6,17 +6,17 @@ use App\Filament\Resources\InventoryItemResource; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Inventory\InventoryCoverage as InventoryCoveragePayload; use App\Support\Inventory\InventoryPolicyTypeMeta; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); -function seedInventoryCoverageBasis(Tenant $tenant): OperationRun +function seedInventoryCoverageBasis(ManagedEnvironment $tenant): OperationRun { InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Conditional Access Prod', 'policy_type' => 'conditionalAccessPolicy', 'external_id' => 'ca-1', @@ -24,7 +24,7 @@ function seedInventoryCoverageBasis(Tenant $tenant): OperationRun ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Device Compliance Legacy', 'policy_type' => 'deviceCompliancePolicy', 'external_id' => 'dc-1', @@ -32,7 +32,7 @@ function seedInventoryCoverageBasis(Tenant $tenant): OperationRun ]); return OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', @@ -61,7 +61,7 @@ function seedInventoryCoverageBasis(Tenant $tenant): OperationRun } test('inventory hub pages render truthful coverage-first summaries and basis continuity', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $basisRun = seedInventoryCoverageBasis($tenant); @@ -85,7 +85,7 @@ function seedInventoryCoverageBasis(Tenant $tenant): OperationRun $this->actingAs($user) ->get($coverageUrl) ->assertOk() - ->assertSee('Tenant coverage truth') + ->assertSee('ManagedEnvironment coverage truth') ->assertSee('Covered types') ->assertSee('Need follow-up') ->assertSee('Observed items') @@ -98,7 +98,7 @@ function seedInventoryCoverageBasis(Tenant $tenant): OperationRun }); test('inventory coverage page makes the no-basis fallback explicit', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user) diff --git a/apps/platform/tests/Feature/Filament/Localization/PolicyInventoryLocalizationTest.php b/apps/platform/tests/Feature/Filament/Localization/PolicyInventoryLocalizationTest.php index f91b51ef..f8409f5f 100644 --- a/apps/platform/tests/Feature/Filament/Localization/PolicyInventoryLocalizationTest.php +++ b/apps/platform/tests/Feature/Filament/Localization/PolicyInventoryLocalizationTest.php @@ -60,7 +60,7 @@ function getPolicyInventoryEmptyStateAction(Testable $component, string $name): Filament::setTenant($tenant, true); Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'display_name' => 'German Source Unavailable Policy', 'ignored_at' => null, 'missing_from_provider_at' => now()->subMinute(), @@ -100,11 +100,11 @@ function getPolicyInventoryEmptyStateAction(Testable $component, string $name): Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_id' => $policy->getKey(), 'metadata' => [], ]); @@ -125,13 +125,13 @@ function getPolicyInventoryEmptyStateAction(Testable $component, string $name): Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'display_name' => 'Windows Policy', 'platform' => 'all', ]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_id' => $policy->getKey(), 'version_number' => 1, 'platform' => 'all', @@ -158,13 +158,13 @@ function getPolicyInventoryEmptyStateAction(Testable $component, string $name): Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'display_name' => 'Enrollment Notifications', 'platform' => 'all', ]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_id' => $policy->getKey(), 'snapshot' => [ 'displayName' => 'Enrollment Notifications', diff --git a/apps/platform/tests/Feature/Filament/MalformedSnapshotWarningTest.php b/apps/platform/tests/Feature/Filament/MalformedSnapshotWarningTest.php index 314c7a8c..b3aa4d71 100644 --- a/apps/platform/tests/Feature/Filament/MalformedSnapshotWarningTest.php +++ b/apps/platform/tests/Feature/Filament/MalformedSnapshotWarningTest.php @@ -4,16 +4,16 @@ use App\Filament\Resources\PolicyVersionResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('malformed snapshot renders warning on policy and version detail', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'ManagedEnvironment One', 'status' => 'active', ]); @@ -21,7 +21,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -29,7 +29,7 @@ ]); $version = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php b/apps/platform/tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php index e07cf93c..316a354a 100644 --- a/apps/platform/tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php +++ b/apps/platform/tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -21,19 +21,19 @@ 'role' => 'owner', ]); - $active = Tenant::factory()->active()->create([ + $active = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Active Tenant', + 'name' => 'Active ManagedEnvironment', ]); - $onboarding = Tenant::factory()->onboarding()->create([ + $onboarding = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Onboarding Tenant', + 'name' => 'Onboarding ManagedEnvironment', ]); - $archived = Tenant::factory()->archived()->create([ + $archived = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Archived Tenant', + 'name' => 'Archived ManagedEnvironment', ]); - $outsider = Tenant::factory()->active()->create(['name' => 'Other Workspace Tenant']); + $outsider = ManagedEnvironment::factory()->active()->create(['name' => 'Other Workspace ManagedEnvironment']); $user->tenants()->syncWithoutDetaching([ $active->getKey() => ['role' => 'owner'], @@ -46,13 +46,13 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]) ->get(route('admin.workspace.managed-tenants.index', ['workspace' => $workspace])) ->assertSuccessful() - ->assertSee('Active Tenant') - ->assertSee('Onboarding Tenant') - ->assertSee('Archived Tenant') + ->assertSee('Active ManagedEnvironment') + ->assertSee('Onboarding ManagedEnvironment') + ->assertSee('Archived ManagedEnvironment') ->assertSee('Active') ->assertSee('Onboarding') ->assertSee('Archived') - ->assertDontSee('Other Workspace Tenant'); + ->assertDontSee('Other Workspace ManagedEnvironment'); }); it('keeps managed tenants discoverable with no selected tenant context', function (): void { @@ -65,17 +65,17 @@ 'role' => 'owner', ]); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Discoverable Onboarding Tenant', + 'name' => 'Discoverable Onboarding ManagedEnvironment', ]); - $draftTenant = Tenant::factory()->draft()->create([ + $draftTenant = ManagedEnvironment::factory()->draft()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Discoverable Draft Tenant', + 'name' => 'Discoverable Draft ManagedEnvironment', ]); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Discoverable Archived Tenant', + 'name' => 'Discoverable Archived ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -88,9 +88,9 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]) ->get(route('admin.workspace.managed-tenants.index', ['workspace' => $workspace])) ->assertSuccessful() - ->assertSee('Discoverable Draft Tenant') - ->assertSee('Discoverable Onboarding Tenant') - ->assertSee('Discoverable Archived Tenant'); + ->assertSee('Discoverable Draft ManagedEnvironment') + ->assertSee('Discoverable Onboarding ManagedEnvironment') + ->assertSee('Discoverable Archived ManagedEnvironment'); }); it('keeps administrative landing discoverability broader than choose-tenant selection', function (): void { @@ -103,21 +103,21 @@ 'role' => 'owner', ]); - $activeTenant = Tenant::factory()->active()->create([ + $activeTenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Landing Active Tenant', + 'name' => 'Landing Active ManagedEnvironment', ]); - $draftTenant = Tenant::factory()->draft()->create([ + $draftTenant = ManagedEnvironment::factory()->draft()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Landing Draft Tenant', + 'name' => 'Landing Draft ManagedEnvironment', ]); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Landing Onboarding Tenant', + 'name' => 'Landing Onboarding ManagedEnvironment', ]); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Landing Archived Tenant', + 'name' => 'Landing Archived ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -131,17 +131,17 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]) ->get(route('admin.workspace.managed-tenants.index', ['workspace' => $workspace])) ->assertSuccessful() - ->assertSee('Landing Active Tenant') - ->assertSee('Landing Draft Tenant') - ->assertSee('Landing Onboarding Tenant') - ->assertSee('Landing Archived Tenant'); + ->assertSee('Landing Active ManagedEnvironment') + ->assertSee('Landing Draft ManagedEnvironment') + ->assertSee('Landing Onboarding ManagedEnvironment') + ->assertSee('Landing Archived ManagedEnvironment'); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]) ->get('/admin/choose-tenant') ->assertSuccessful() - ->assertSee('Landing Active Tenant') - ->assertDontSee('Landing Draft Tenant') - ->assertDontSee('Landing Onboarding Tenant') - ->assertDontSee('Landing Archived Tenant'); + ->assertSee('Landing Active ManagedEnvironment') + ->assertDontSee('Landing Draft ManagedEnvironment') + ->assertDontSee('Landing Onboarding ManagedEnvironment') + ->assertDontSee('Landing Archived ManagedEnvironment'); }); diff --git a/apps/platform/tests/Feature/Filament/NeedsAttentionWidgetTest.php b/apps/platform/tests/Feature/Filament/NeedsAttentionWidgetTest.php index df8691dc..6f1e8f86 100644 --- a/apps/platform/tests/Feature/Filament/NeedsAttentionWidgetTest.php +++ b/apps/platform/tests/Feature/Filament/NeedsAttentionWidgetTest.php @@ -47,17 +47,17 @@ function createNeedsAttentionTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); return [$user, $tenant, $profile, $snapshot]; } -function makeBackupHealthScheduleForNeedsAttention(\App\Models\Tenant $tenant, array $attributes = []): BackupSchedule +function makeBackupHealthScheduleForNeedsAttention(\App\Models\ManagedEnvironment $tenant, array $attributes = []): BackupSchedule { return BackupSchedule::query()->create(array_merge([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Needs Attention backup schedule', 'is_enabled' => true, 'timezone' => 'UTC', @@ -71,7 +71,7 @@ function makeBackupHealthScheduleForNeedsAttention(\App\Models\Tenant $tenant, a ], $attributes)); } -function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, array $attributes = []): BackupSet +function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\ManagedEnvironment $tenant, array $attributes = []): BackupSet { $backupSet = BackupSet::factory()->for($tenant)->recentCompleted()->create(array_merge([ 'name' => 'Healthy recovery needs-attention backup', @@ -89,7 +89,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, dataset('needs-attention-recovery-cases', [ 'failed history' => [ - fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() + fn (\App\Models\ManagedEnvironment $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->failedOutcome() @@ -101,7 +101,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, 'failed', ], 'partial history' => [ - fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() + fn (\App\Models\ManagedEnvironment $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->partialOutcome() @@ -113,7 +113,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, 'partial', ], 'follow-up history' => [ - fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() + fn (\App\Models\ManagedEnvironment $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->completedWithFollowUp() @@ -135,7 +135,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, $this->actingAs($user); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -200,7 +200,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -239,7 +239,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, $this->actingAs($user); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -312,7 +312,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, $this->actingAs($user); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -335,12 +335,12 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, $finding = Finding::factory()->riskAccepted()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -397,7 +397,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, $this->actingAs($user); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -406,7 +406,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -575,7 +575,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -682,7 +682,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, makeHealthyBackupForRecoveryNeedsAttention($tenant); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -723,7 +723,7 @@ function makeHealthyBackupForRecoveryNeedsAttention(\App\Models\Tenant $tenant, ->assertSee('Backups are recent and healthy') ->assertSee('No recent restore issues visible') ->assertSee('Recent executed restore history exists without a current follow-up signal.') - ->assertSee('Tenant-wide recovery is not proven.') + ->assertSee('ManagedEnvironment-wide recovery is not proven.') ->assertDontSee('Recovery evidence is unvalidated') ->assertDontSee('Recent restore failed'); }); diff --git a/apps/platform/tests/Feature/Filament/NormalizedDetailFamilyContractTest.php b/apps/platform/tests/Feature/Filament/NormalizedDetailFamilyContractTest.php index 55211f0f..2d241f90 100644 --- a/apps/platform/tests/Feature/Filament/NormalizedDetailFamilyContractTest.php +++ b/apps/platform/tests/Feature/Filament/NormalizedDetailFamilyContractTest.php @@ -15,15 +15,15 @@ uses(RefreshDatabase::class); it('renders shared normalized settings and diff families on policy and policy-version detail hosts', function (): void { - $tenant = \App\Models\Tenant::factory()->create([ - 'name' => 'Tenant One', + $tenant = \App\Models\ManagedEnvironment::factory()->create([ + 'name' => 'ManagedEnvironment One', 'status' => 'active', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -31,7 +31,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_id' => $policy->getKey(), 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -47,7 +47,7 @@ ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_id' => $policy->getKey(), 'version_number' => 2, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/ODataTypeMismatchTest.php b/apps/platform/tests/Feature/Filament/ODataTypeMismatchTest.php index 6a3ed26d..276d705c 100644 --- a/apps/platform/tests/Feature/Filament/ODataTypeMismatchTest.php +++ b/apps/platform/tests/Feature/Filament/ODataTypeMismatchTest.php @@ -5,7 +5,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\RestoreService; @@ -48,9 +48,9 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon } }); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'ManagedEnvironment One', 'status' => 'active', ]); @@ -60,7 +60,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -73,7 +73,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]; PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -84,14 +84,14 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php b/apps/platform/tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php index 7b7affce..20fa57de 100644 --- a/apps/platform/tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php +++ b/apps/platform/tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php @@ -44,7 +44,7 @@ function visibleLivewireText(Testable $component): string ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_capture', 'status' => 'completed', @@ -97,7 +97,7 @@ function visibleLivewireText(Testable $component): string [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_capture', 'status' => 'completed', @@ -135,7 +135,7 @@ function visibleLivewireText(Testable $component): string [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', @@ -192,7 +192,7 @@ function visibleLivewireText(Testable $component): string [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', @@ -259,7 +259,7 @@ function visibleLivewireText(Testable $component): string [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', @@ -305,12 +305,12 @@ function visibleLivewireText(Testable $component): string BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', @@ -410,7 +410,7 @@ function visibleLivewireText(Testable $component): string $assignment = BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), 'override_scope_jsonb' => null, ]); diff --git a/apps/platform/tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.php b/apps/platform/tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.php index 3db1aea7..29fed6ae 100644 --- a/apps/platform/tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.php +++ b/apps/platform/tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.php @@ -17,11 +17,11 @@ uses(RefreshDatabase::class); it('reuses operation guidance and explanation state on the canonical run detail surface', function (): void { - $tenant = \App\Models\Tenant::factory()->create(); + $tenant = \App\Models\ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'baseline_compare', diff --git a/apps/platform/tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php b/apps/platform/tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php index 8d9b7185..4664ccf0 100644 --- a/apps/platform/tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php +++ b/apps/platform/tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php @@ -4,7 +4,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -100,7 +100,7 @@ function baselineCompareGapContext(array $overrides = []): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -166,13 +166,13 @@ function baselineCompareGapContext(array $overrides = []): array Filament::setTenant(null, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Nightly backup', ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'backup_set.update', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -195,13 +195,13 @@ function baselineCompareGapContext(array $overrides = []): array }); it('renders mismatch context above the enterprise detail content without blocking the page', function (): void { - $runTenant = Tenant::factory()->create([ - 'name' => 'Run Tenant', + $runTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Run ManagedEnvironment', ]); [$user, $runTenant] = createUserWithTenant(tenant: $runTenant, role: 'owner'); - $currentTenant = Tenant::factory()->create([ - 'name' => 'Current Tenant', + $currentTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Current ManagedEnvironment', 'workspace_id' => (int) $runTenant->workspace_id, ]); @@ -211,7 +211,7 @@ function baselineCompareGapContext(array $overrides = []): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $runTenant->workspace_id, - 'tenant_id' => (int) $runTenant->getKey(), + 'managed_environment_id' => (int) $runTenant->getKey(), 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -249,7 +249,7 @@ function baselineCompareGapContext(array $overrides = []): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -275,7 +275,7 @@ function baselineCompareGapContext(array $overrides = []): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'restore.execute', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -312,7 +312,7 @@ function baselineCompareGapContext(array $overrides = []): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Blocked->value, @@ -353,7 +353,7 @@ function baselineCompareGapContext(array $overrides = []): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'baseline_compare', 'status' => 'completed', 'outcome' => 'partially_succeeded', @@ -416,7 +416,7 @@ function baselineCompareGapContext(array $overrides = []): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'baseline_compare', 'status' => 'completed', 'outcome' => 'partially_succeeded', @@ -439,7 +439,7 @@ function baselineCompareGapContext(array $overrides = []): array $legacyRun = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'baseline_compare', 'status' => 'completed', 'outcome' => 'partially_succeeded', @@ -455,7 +455,7 @@ function baselineCompareGapContext(array $overrides = []): array $cleanRun = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'baseline_compare', 'status' => 'completed', 'outcome' => 'succeeded', @@ -490,13 +490,13 @@ function baselineCompareGapContext(array $overrides = []): array it('returns 404 for workspace members without tenant entitlement when evidence-gap details exist on the canonical surface', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'baseline_compare', 'status' => 'completed', 'outcome' => 'partially_succeeded', @@ -527,7 +527,7 @@ function baselineCompareGapContext(array $overrides = []): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::PartiallySucceeded->value, diff --git a/apps/platform/tests/Feature/Filament/OperationRunListFiltersTest.php b/apps/platform/tests/Feature/Filament/OperationRunListFiltersTest.php index 2b8cf360..2c615379 100644 --- a/apps/platform/tests/Feature/Filament/OperationRunListFiltersTest.php +++ b/apps/platform/tests/Feature/Filament/OperationRunListFiltersTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Monitoring\Operations; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\Workspaces\WorkspaceContext; @@ -23,7 +23,7 @@ function operationRunFilterIndicatorLabels($component): array [$user, $tenant] = createUserWithTenant(role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', ]); @@ -42,17 +42,17 @@ function operationRunFilterIndicatorLabels($component): array }); it('filters operations by type and outcome without leaking runs from other tenants', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $matching = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -60,7 +60,7 @@ function operationRunFilterIndicatorLabels($component): array ]); $wrongType = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, @@ -68,7 +68,7 @@ function operationRunFilterIndicatorLabels($component): array ]); $otherTenant = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -91,13 +91,13 @@ function operationRunFilterIndicatorLabels($component): array [$user, $tenant] = createUserWithTenant(role: 'owner'); $recent = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'created_at' => now()->subDay(), ]); $old = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'created_at' => now()->subDays(45), ]); @@ -124,23 +124,23 @@ function operationRunFilterIndicatorLabels($component): array }); it('keeps operation type filter options workspace-scoped even when a remembered tenant is active', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', ]); @@ -169,7 +169,7 @@ function operationRunFilterIndicatorLabels($component): array [$user, $tenant] = createUserWithTenant(role: 'owner'); $legacyRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, @@ -177,7 +177,7 @@ function operationRunFilterIndicatorLabels($component): array ]); $providerPrefixedRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.inventory.sync', 'status' => OperationRunStatus::Completed->value, @@ -185,7 +185,7 @@ function operationRunFilterIndicatorLabels($component): array ]); $otherRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -208,7 +208,7 @@ function operationRunFilterIndicatorLabels($component): array foreach (['inventory.sync', 'inventory_sync', 'provider.inventory.sync'] as $type) { OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => $type, ]); @@ -231,24 +231,24 @@ function operationRunFilterIndicatorLabels($component): array }); it('clears tenant-sensitive persisted filters when the canonical tenant context changes', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'initiator_name' => 'Alpha', ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', 'initiator_name' => 'Bravo', @@ -276,7 +276,7 @@ function operationRunFilterIndicatorLabels($component): array ]); Livewire::test(Operations::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantB->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantB->getKey()) ->assertSet('tableFilters.type.value', null) ->assertSet('tableFilters.initiator_name.value', null); }); diff --git a/apps/platform/tests/Feature/Filament/OperationRunResumeCaptureActionTest.php b/apps/platform/tests/Feature/Filament/OperationRunResumeCaptureActionTest.php index a92e529e..51e97e12 100644 --- a/apps/platform/tests/Feature/Filament/OperationRunResumeCaptureActionTest.php +++ b/apps/platform/tests/Feature/Filament/OperationRunResumeCaptureActionTest.php @@ -57,7 +57,7 @@ Queue::assertPushed(CompareBaselineToTenantJob::class); $resumed = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::BaselineCompare->value) ->where('status', OperationRunStatus::Queued->value) ->latest('id') diff --git a/apps/platform/tests/Feature/Filament/PolicyCaptureSnapshotOptionsTest.php b/apps/platform/tests/Feature/Filament/PolicyCaptureSnapshotOptionsTest.php index 8af287e7..88e9e528 100644 --- a/apps/platform/tests/Feature/Filament/PolicyCaptureSnapshotOptionsTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyCaptureSnapshotOptionsTest.php @@ -4,7 +4,7 @@ use App\Jobs\CapturePolicySnapshotJob; use App\Jobs\Operations\CapturePolicySnapshotWorkerJob; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\AssignmentFetcher; use App\Services\Graph\ScopeTagResolver; @@ -22,7 +22,7 @@ it('captures a policy snapshot with scope tags when requested', function () { Queue::fake(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $tenant->makeCurrent(); ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::factory()->for($tenant)->create([ diff --git a/apps/platform/tests/Feature/Filament/PolicyListingTest.php b/apps/platform/tests/Feature/Filament/PolicyListingTest.php index 0f8228f0..4e46831f 100644 --- a/apps/platform/tests/Feature/Filament/PolicyListingTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyListingTest.php @@ -2,7 +2,7 @@ use App\Filament\Resources\PolicyResource\Pages\ListPolicies; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Support\Facades\App; @@ -11,10 +11,10 @@ uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); test('policies are listed for the active tenant', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -22,10 +22,10 @@ 'last_synced_at' => now(), ]); - $otherTenant = Tenant::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); Policy::create([ - 'tenant_id' => $otherTenant->id, + 'managed_environment_id' => $otherTenant->id, 'external_id' => 'policy-2', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy B', diff --git a/apps/platform/tests/Feature/Filament/PolicyProviderMissingUiTest.php b/apps/platform/tests/Feature/Filament/PolicyProviderMissingUiTest.php index d3460259..6fb6a0c9 100644 --- a/apps/platform/tests/Feature/Filament/PolicyProviderMissingUiTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyProviderMissingUiTest.php @@ -17,21 +17,21 @@ Filament::setTenant($tenant, true); $active = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'display_name' => 'Active policy', 'ignored_at' => null, 'missing_from_provider_at' => null, ]); $missing = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'display_name' => 'Provider missing policy', 'ignored_at' => null, 'missing_from_provider_at' => now()->subHour(), ]); $combined = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'display_name' => 'Ignored missing policy', 'ignored_at' => now()->subDay(), 'missing_from_provider_at' => now()->subHour(), @@ -59,7 +59,7 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'display_name' => 'Provider missing policy', 'ignored_at' => null, 'missing_from_provider_at' => now()->subHour(), diff --git a/apps/platform/tests/Feature/Filament/PolicyResourceAdminSearchParityTest.php b/apps/platform/tests/Feature/Filament/PolicyResourceAdminSearchParityTest.php index 39969a10..4da8efdf 100644 --- a/apps/platform/tests/Feature/Filament/PolicyResourceAdminSearchParityTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyResourceAdminSearchParityTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\PolicyResource; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -16,7 +16,7 @@ }); it('returns no policy global-search results even with a remembered canonical admin tenant', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); Policy::factory()->for($tenant)->create([ diff --git a/apps/platform/tests/Feature/Filament/PolicyResourceAdminTenantParityTest.php b/apps/platform/tests/Feature/Filament/PolicyResourceAdminTenantParityTest.php index 3421c225..8202fe62 100644 --- a/apps/platform/tests/Feature/Filament/PolicyResourceAdminTenantParityTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyResourceAdminTenantParityTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\PolicyResource\Pages\ListPolicies; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Carbon\CarbonImmutable; use Filament\Facades\Filament; @@ -15,9 +15,9 @@ uses(RefreshDatabase::class); it('scopes the admin policy list to the remembered canonical tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $policyA = Policy::factory()->for($tenantA)->create(['display_name' => 'Remembered tenant policy']); @@ -39,9 +39,9 @@ }); it('renders remembered canonical tenant policy detail with shared normalized settings markers', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $policyA = Policy::factory()->for($tenantA)->create(['display_name' => 'Remembered tenant policy']); diff --git a/apps/platform/tests/Feature/Filament/PolicySettingsDisplayTest.php b/apps/platform/tests/Feature/Filament/PolicySettingsDisplayTest.php index 4c6d17f6..4a8ae93e 100644 --- a/apps/platform/tests/Feature/Filament/PolicySettingsDisplayTest.php +++ b/apps/platform/tests/Feature/Filament/PolicySettingsDisplayTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\PolicyResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -11,10 +11,10 @@ uses(RefreshDatabase::class); test('policy detail shows normalized settings section', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -22,7 +22,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/PolicySettingsStandardRendersArraysTest.php b/apps/platform/tests/Feature/Filament/PolicySettingsStandardRendersArraysTest.php index b0743078..f686187f 100644 --- a/apps/platform/tests/Feature/Filament/PolicySettingsStandardRendersArraysTest.php +++ b/apps/platform/tests/Feature/Filament/PolicySettingsStandardRendersArraysTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\PolicyResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -11,10 +11,10 @@ uses(RefreshDatabase::class); test('policy settings standard view renders array values without crashing', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-arrays-1', 'policy_type' => 'windowsAutopilotDeploymentProfile', 'display_name' => 'Autopilot Policy With Arrays', @@ -22,7 +22,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/PolicySyncCtaPlacementTest.php b/apps/platform/tests/Feature/Filament/PolicySyncCtaPlacementTest.php index ac2b519c..a4f58ed5 100644 --- a/apps/platform/tests/Feature/Filament/PolicySyncCtaPlacementTest.php +++ b/apps/platform/tests/Feature/Filament/PolicySyncCtaPlacementTest.php @@ -49,7 +49,7 @@ function getPolicySyncHeaderAction(Testable $component, string $name): ?Action Filament::setTenant($tenant, true); Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'ignored_at' => null, ]); diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionAdminSearchParityTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionAdminSearchParityTest.php index f973a7fd..e94eeb82 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionAdminSearchParityTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionAdminSearchParityTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\PolicyVersionResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -17,7 +17,7 @@ }); it('returns no policy-version global-search results even with a remembered canonical admin tenant', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $policy = Policy::factory()->for($tenant)->create(); diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionAdminTenantParityTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionAdminTenantParityTest.php index accb9335..169af33b 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionAdminTenantParityTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionAdminTenantParityTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\PolicyVersionResource\Pages\ListPolicyVersions; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Carbon\CarbonImmutable; use Filament\Facades\Filament; @@ -16,9 +16,9 @@ uses(RefreshDatabase::class); it('scopes the admin policy-version list to the remembered canonical tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $policyA = Policy::factory()->for($tenantA)->create(['display_name' => 'Remembered policy']); @@ -43,9 +43,9 @@ }); it('returns not found for admin policy-version detail outside the remembered canonical tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $policyA = Policy::factory()->for($tenantA)->create(); @@ -76,9 +76,9 @@ }); it('renders remembered canonical tenant policy-version detail with shared normalized detail markers', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $policyA = Policy::factory()->for($tenantA)->create(['display_name' => 'Remembered policy']); diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionBaselineEvidenceVisibilityTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionBaselineEvidenceVisibilityTest.php index 55c46624..c2daf6f9 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionBaselineEvidenceVisibilityTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionBaselineEvidenceVisibilityTest.php @@ -30,7 +30,7 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $baselineProfile = BaselineProfile::factory()->active()->create([ @@ -38,14 +38,14 @@ ]); $backupVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, 'capture_purpose' => PolicyVersionCapturePurpose::Backup->value, ]); $baselinePurposeVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, 'capture_purpose' => PolicyVersionCapturePurpose::BaselineCompare->value, @@ -70,7 +70,7 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $baselineProfile = BaselineProfile::factory()->active()->create([ @@ -78,14 +78,14 @@ ]); $backupVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, 'capture_purpose' => PolicyVersionCapturePurpose::Backup->value, ]); $baselinePurposeVersion = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, 'capture_purpose' => PolicyVersionCapturePurpose::BaselineCapture->value, diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionListFiltersTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionListFiltersTest.php index b74bd80d..6ed7a94c 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionListFiltersTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionListFiltersTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\PolicyVersionResource\Pages\ListPolicyVersions; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Filament\Facades\Filament; use Livewire\Livewire; @@ -17,17 +17,17 @@ function policyVersionFilterIndicatorLabels($component): array } it('filters policy versions by type and platform without leaking other tenants', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $policyA = Policy::query()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'external_id' => 'policy-a', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -35,7 +35,7 @@ function policyVersionFilterIndicatorLabels($component): array ]); $policyB = Policy::query()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'external_id' => 'policy-b', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy B', @@ -43,7 +43,7 @@ function policyVersionFilterIndicatorLabels($component): array ]); $matching = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'policy_id' => (int) $policyA->getKey(), 'version_number' => 1, 'policy_type' => 'deviceConfiguration', @@ -51,7 +51,7 @@ function policyVersionFilterIndicatorLabels($component): array ]); $wrongPlatform = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'policy_id' => (int) $policyA->getKey(), 'version_number' => 2, 'policy_type' => 'deviceConfiguration', @@ -59,7 +59,7 @@ function policyVersionFilterIndicatorLabels($component): array ]); $otherTenant = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'policy_id' => (int) $policyB->getKey(), 'policy_type' => 'deviceConfiguration', 'platform' => 'windows', @@ -80,7 +80,7 @@ function policyVersionFilterIndicatorLabels($component): array [$user, $tenant] = createUserWithTenant(role: 'owner'); $policy = Policy::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-date', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy Date', @@ -88,14 +88,14 @@ function policyVersionFilterIndicatorLabels($component): array ]); $recentActive = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, 'captured_at' => now()->subDay(), ]); $recentArchived = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, 'captured_at' => now()->subDay(), @@ -103,7 +103,7 @@ function policyVersionFilterIndicatorLabels($component): array ]); $oldActive = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 3, 'captured_at' => now()->subDays(10), @@ -134,7 +134,7 @@ function policyVersionFilterIndicatorLabels($component): array [$user, $tenant] = createUserWithTenant(role: 'owner'); $policy = Policy::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-clear', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy Clear', @@ -142,7 +142,7 @@ function policyVersionFilterIndicatorLabels($component): array ]); $active = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, 'platform' => 'windows', @@ -150,7 +150,7 @@ function policyVersionFilterIndicatorLabels($component): array ]); $archived = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, 'platform' => 'windows', diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionQualityTruthSurfaceTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionQualityTruthSurfaceTest.php index 367e23d2..3577901c 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionQualityTruthSurfaceTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionQualityTruthSurfaceTest.php @@ -17,14 +17,14 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Windows Policy', 'policy_type' => 'settingsCatalogPolicy', 'platform' => 'windows', ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, 'snapshot' => ['id' => 'policy-1'], @@ -32,7 +32,7 @@ ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, 'snapshot' => [], @@ -58,14 +58,14 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Versioned policy', 'policy_type' => 'settingsCatalogPolicy', 'platform' => 'windows', ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'snapshot' => ['id' => 'policy-1'], 'metadata' => [ diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionReadableLayoutTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionReadableLayoutTest.php index c6506e34..e741a593 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionReadableLayoutTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionReadableLayoutTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\PolicyVersionResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -11,10 +11,10 @@ uses(RefreshDatabase::class); test('policy version detail renders tabs and scroll-safe blocks', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-policy-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Policy', @@ -24,7 +24,7 @@ $longDefinitionId = 'device_vendor_msft_policy_config_system_'.str_repeat('minimumpinlength_', 12); $version = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -57,8 +57,8 @@ ->get(PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $tenant)); $response->assertOk(); - $response->assertSee('Normalized settings'); - $response->assertSee('Raw JSON'); + $response->assertSee('Settings'); + $response->assertSee('JSON'); $response->assertSee('Diff'); $response->assertSee('fi-width-full'); diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionRelatedNavigationTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionRelatedNavigationTest.php index 4c8b99f5..fb66a3f0 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionRelatedNavigationTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionRelatedNavigationTest.php @@ -31,12 +31,12 @@ ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Windows Lockdown', ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 4, 'baseline_profile_id' => (int) $profile->getKey(), diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionRestoreToIntuneTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionRestoreToIntuneTest.php index f00d0465..f716fc16 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionRestoreToIntuneTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionRestoreToIntuneTest.php @@ -3,7 +3,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -66,16 +66,16 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon $client = new PolicyVersionRestoreGraphClient; app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-version-restore', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-version-restore', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'gpo-versioned-1', 'policy_type' => 'groupPolicyConfiguration', 'display_name' => 'Admin Templates', @@ -109,7 +109,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]; PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -121,7 +121,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]); $versionToRestore = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 2, 'policy_type' => $policy->policy_type, @@ -161,28 +161,28 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon }); test('restore rejects policy versions from a different tenant before creating backup artifacts', function () { - $tenantA = Tenant::create([ - 'tenant_id' => 'tenant-version-restore-a', - 'name' => 'Tenant A', + $tenantA = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-version-restore-a', + 'name' => 'ManagedEnvironment A', 'metadata' => [], ]); - $tenantB = Tenant::create([ - 'tenant_id' => 'tenant-version-restore-b', - 'name' => 'Tenant B', + $tenantB = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-version-restore-b', + 'name' => 'ManagedEnvironment B', 'metadata' => [], ]); $policy = Policy::create([ - 'tenant_id' => $tenantB->id, + 'managed_environment_id' => $tenantB->id, 'external_id' => 'gpo-versioned-wrong-tenant', 'policy_type' => 'groupPolicyConfiguration', - 'display_name' => 'Wrong Tenant Policy', + 'display_name' => 'Wrong ManagedEnvironment Policy', 'platform' => 'windows', ]); $version = PolicyVersion::create([ - 'tenant_id' => $tenantB->id, + 'managed_environment_id' => $tenantB->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionRestoreViaWizardTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionRestoreViaWizardTest.php index 98ec5c79..1b4f02e3 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionRestoreViaWizardTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionRestoreViaWizardTest.php @@ -6,7 +6,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GroupResolver; use Filament\Facades\Filament; @@ -17,16 +17,16 @@ uses(RefreshDatabase::class); test('policy version can open restore wizard via row action', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-policy-version-wizard', - 'name' => 'Tenant', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-policy-version-wizard', + 'name' => 'ManagedEnvironment', 'metadata' => [], ]); $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog', @@ -34,7 +34,7 @@ ]); $version = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 3, 'policy_type' => $policy->policy_type, @@ -72,7 +72,7 @@ $backupSet = BackupSet::query()->where('metadata->source', 'policy_version')->first(); expect($backupSet)->not->toBeNull(); - expect($backupSet->tenant_id)->toBe($tenant->id); + expect($backupSet->managed_environment_id)->toBe($tenant->id); expect($backupSet->metadata['policy_version_id'] ?? null)->toBe($version->id); expect($backupSet->metadata['integrity_warning'] ?? null)->toContain('Protected values are intentionally hidden'); @@ -88,16 +88,16 @@ }); test('readonly users cannot open restore wizard via policy version row action', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-policy-version-wizard-readonly', - 'name' => 'Tenant', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-policy-version-wizard-readonly', + 'name' => 'ManagedEnvironment', 'metadata' => [], ]); $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-ro-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog', @@ -105,7 +105,7 @@ ]); $version = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -132,16 +132,16 @@ }); test('metadata-only versions keep quality visible while restore-via-wizard stays disabled', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-policy-version-wizard-quality', - 'name' => 'Tenant', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-policy-version-wizard-quality', + 'name' => 'ManagedEnvironment', 'metadata' => [], ]); $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-quality', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog', @@ -149,7 +149,7 @@ ]); $version = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -174,16 +174,16 @@ }); test('restore run wizard can be prefilled from query params for policy version backup set', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-policy-version-prefill', - 'name' => 'Tenant', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-policy-version-prefill', + 'name' => 'ManagedEnvironment', 'metadata' => [], ]); $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-2', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog', @@ -191,7 +191,7 @@ ]); $version = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -209,7 +209,7 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Policy Version Restore', 'status' => 'completed', 'item_count' => 1, @@ -221,7 +221,7 @@ ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_version_id' => $version->id, diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionScopeTagsDisplayTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionScopeTagsDisplayTest.php index 94ec7ed5..7820d479 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionScopeTagsDisplayTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionScopeTagsDisplayTest.php @@ -3,22 +3,22 @@ use App\Filament\Resources\PolicyVersionResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('policy version view shows scope tags even when assignments are missing', function () { - $tenant = Tenant::factory()->create([ - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'ManagedEnvironment One', 'status' => 'active', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -26,7 +26,7 @@ ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_id' => $policy->getKey(), 'version_number' => 1, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionSettingsTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionSettingsTest.php index 1c3c69c9..61538de6 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionSettingsTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionSettingsTest.php @@ -3,22 +3,22 @@ use App\Filament\Resources\PolicyVersionResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('policy version detail shows raw and normalized settings', function () { - $tenant = Tenant::factory()->create([ - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'ManagedEnvironment One', 'status' => 'active', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -26,7 +26,7 @@ ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_id' => $policy->getKey(), 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -45,9 +45,9 @@ ->get(PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $tenant)); $response->assertOk(); - $response->assertSee('Raw JSON'); + $response->assertSee('JSON'); $response->assertSee('displayName'); - $response->assertSee('Normalized settings'); + $response->assertSee('Settings'); $response->assertSee('Enable feature'); $response->assertSee('Normalized diff'); @@ -59,16 +59,16 @@ }); test('policy version detail shows enrollment notification template settings', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-enrollment-notify', - 'name' => 'Tenant Enrollment Notify', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-enrollment-notify', + 'name' => 'ManagedEnvironment Enrollment Notify', 'status' => 'active', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => 'enroll-notify-1', 'policy_type' => 'deviceEnrollmentNotificationConfiguration', 'display_name' => 'Enrollment Notifications', @@ -76,7 +76,7 @@ ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_id' => $policy->getKey(), 'version_number' => 1, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/PolicyVersionTest.php b/apps/platform/tests/Feature/Filament/PolicyVersionTest.php index e697a219..d3c9cb9b 100644 --- a/apps/platform/tests/Feature/Filament/PolicyVersionTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyVersionTest.php @@ -2,7 +2,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceMembership; use App\Services\Intune\VersionService; @@ -11,10 +11,10 @@ uses(RefreshDatabase::class); test('policy versions render with timeline data', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -38,12 +38,12 @@ }); test('policy version detail renders readable normalized RBAC assignment content', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'rbac-assign-1', 'policy_type' => 'intuneRoleAssignment', 'display_name' => 'Current assignment name', @@ -52,7 +52,7 @@ ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'policy_type' => 'intuneRoleAssignment', 'platform' => 'all', @@ -91,12 +91,12 @@ }); test('policy version detail returns 404 for non-members on RBAC versions', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$owner, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'rbac-assign-404', 'policy_type' => 'intuneRoleAssignment', 'display_name' => 'Hidden assignment', @@ -105,7 +105,7 @@ ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'policy_type' => 'intuneRoleAssignment', 'platform' => 'all', diff --git a/apps/platform/tests/Feature/Filament/PolicyViewSettingsCatalogReadableTest.php b/apps/platform/tests/Feature/Filament/PolicyViewSettingsCatalogReadableTest.php index 74bbe57c..c617c556 100644 --- a/apps/platform/tests/Feature/Filament/PolicyViewSettingsCatalogReadableTest.php +++ b/apps/platform/tests/Feature/Filament/PolicyViewSettingsCatalogReadableTest.php @@ -4,16 +4,16 @@ use App\Models\Policy; use App\Models\PolicyVersion; use App\Models\SettingsCatalogDefinition; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); it('shows Settings tab for Settings Catalog policy', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'Test ManagedEnvironment', 'status' => 'active', ]); @@ -21,7 +21,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-sc-1', 'policy_type' => 'settingsCatalog', 'display_name' => 'Settings Catalog Policy', @@ -40,7 +40,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -81,9 +81,9 @@ }); it('shows display names instead of definition IDs', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'Test ManagedEnvironment', 'status' => 'active', ]); @@ -91,7 +91,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-sc-2', 'policy_type' => 'settingsCatalog', 'display_name' => 'Defender Policy', @@ -106,7 +106,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -135,9 +135,9 @@ })->skip('Manual UI verification required'); it('shows fallback prettified labels when definitions not cached', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'Test ManagedEnvironment', 'status' => 'active', ]); @@ -145,7 +145,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-sc-3', 'policy_type' => 'settingsCatalog', 'display_name' => 'Uncached Policy', @@ -155,7 +155,7 @@ $uncachedDefinitionId = 'device_vendor_msft_policy_config_uncached_test_setting'; PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -184,9 +184,9 @@ })->skip('Manual UI verification required'); it('shows tabbed layout for non-Settings Catalog policies', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'Test ManagedEnvironment', 'status' => 'active', ]); @@ -194,7 +194,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-dc-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Device Configuration Policy', @@ -202,7 +202,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -228,9 +228,9 @@ // T034: Test display names shown (not definition IDs) it('displays setting display names instead of raw definition IDs', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'Test ManagedEnvironment', 'status' => 'active', ]); @@ -245,7 +245,7 @@ ]); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'test-policy', 'policy_type' => 'settingsCatalog', 'display_name' => 'Test Policy', @@ -253,7 +253,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => 'settingsCatalog', @@ -283,9 +283,9 @@ // T035: Test values formatted correctly it('formats setting values correctly based on type', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'Test ManagedEnvironment', 'status' => 'active', ]); @@ -309,7 +309,7 @@ ]); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'format-test', 'policy_type' => 'settingsCatalog', 'display_name' => 'Format Test', @@ -317,7 +317,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => 'settingsCatalog', @@ -358,9 +358,9 @@ // T036: Test search/filter functionality it('search filters settings in real-time', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'Test ManagedEnvironment', 'status' => 'active', ]); @@ -379,7 +379,7 @@ ]); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'search-test', 'policy_type' => 'settingsCatalog', 'display_name' => 'Search Test', @@ -387,7 +387,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => 'settingsCatalog', @@ -422,9 +422,9 @@ // T037: Test graceful degradation for missing definitions it('shows prettified fallback labels when definitions are not cached', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'Test ManagedEnvironment', 'status' => 'active', ]); @@ -432,7 +432,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'fallback-test', 'policy_type' => 'settingsCatalog', 'display_name' => 'Fallback Test', @@ -440,7 +440,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => 'settingsCatalog', diff --git a/apps/platform/tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php b/apps/platform/tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php index 9760c7bb..ff056dde 100644 --- a/apps/platform/tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php +++ b/apps/platform/tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php @@ -13,7 +13,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'display_name' => 'Contoso', 'entra_tenant_id' => fake()->uuid(), 'provider' => 'microsoft', diff --git a/apps/platform/tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php b/apps/platform/tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php index d2ddf07e..057d0e08 100644 --- a/apps/platform/tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\ProviderConnectionResource\Pages\ListProviderConnections; use App\Filament\Resources\ProviderConnectionResource\Pages\ViewProviderConnection; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\UiTooltips; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -18,31 +18,31 @@ }); test('unauthorized tenant filter yields an empty list without leaking metadata', function () { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'owner'); ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, - 'display_name' => 'Unauthorized Tenant Connection', + 'display_name' => 'Unauthorized ManagedEnvironment Connection', ]); $this->actingAs($user) ->get(ProviderConnectionResource::getUrl('index', tenant: $tenant)) ->assertOk() - ->assertDontSee('Unauthorized Tenant Connection'); + ->assertDontSee('Unauthorized ManagedEnvironment Connection'); }); test('non-members cannot reach provider connection detail target-scope metadata', function (): void { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'owner'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Hidden Scope Connection', 'entra_tenant_id' => '77777777-7777-7777-7777-777777777777', @@ -54,11 +54,11 @@ }); test('members without capability see provider connection actions disabled with standard tooltip', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'readonly'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'consent_status' => 'required', 'is_enabled' => true, 'provider' => 'microsoft', @@ -88,11 +88,11 @@ }); test('members with capability can see provider connection actions enabled', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'owner'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'consent_status' => 'required', 'is_enabled' => true, 'provider' => 'microsoft', diff --git a/apps/platform/tests/Feature/Filament/RecentOperationsSummaryWidgetTest.php b/apps/platform/tests/Feature/Filament/RecentOperationsSummaryWidgetTest.php index fc95c688..12884dfd 100644 --- a/apps/platform/tests/Feature/Filament/RecentOperationsSummaryWidgetTest.php +++ b/apps/platform/tests/Feature/Filament/RecentOperationsSummaryWidgetTest.php @@ -18,7 +18,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'succeeded', @@ -45,7 +45,7 @@ OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -54,7 +54,7 @@ OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'restore.execute', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, diff --git a/apps/platform/tests/Feature/Filament/ReferencedTenantLifecyclePresentationTest.php b/apps/platform/tests/Feature/Filament/ReferencedTenantLifecyclePresentationTest.php index bf2886fc..2e68d060 100644 --- a/apps/platform/tests/Feature/Filament/ReferencedTenantLifecyclePresentationTest.php +++ b/apps/platform/tests/Feature/Filament/ReferencedTenantLifecyclePresentationTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\Workspaces\WorkspaceContext; @@ -13,14 +13,14 @@ uses(RefreshDatabase::class); it('renders onboarding referenced tenant lifecycle consistently in the viewer banner and summary card', function (): void { - $tenant = Tenant::factory()->onboarding()->create([ - 'name' => 'Onboarding Tenant', + $tenant = ManagedEnvironment::factory()->onboarding()->create([ + 'name' => 'Onboarding ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -34,21 +34,21 @@ ->assertOk() ->assertSee('Operation tenant is not available in the current tenant selector') ->assertSee('This tenant is currently onboarding and may not appear in the tenant selector.') - ->assertSee('Tenant lifecycle') + ->assertSee('ManagedEnvironment lifecycle') ->assertSee('Onboarding') - ->assertSee('Tenant selector context') + ->assertSee('ManagedEnvironment selector context') ->assertSee('Some tenant follow-up actions may be unavailable from this canonical workspace view.'); }); it('renders archived referenced tenant lifecycle consistently in the viewer banner and summary card', function (): void { - $activeTenant = Tenant::factory()->create([ - 'name' => 'Active Tenant', + $activeTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Active ManagedEnvironment', ]); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); - $archivedTenant = Tenant::factory()->active()->create([ + $archivedTenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Archived Tenant', + 'name' => 'Archived ManagedEnvironment', ]); createUserWithTenant(tenant: $archivedTenant, user: $user, role: 'owner'); @@ -56,7 +56,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'tenant_id' => (int) $archivedTenant->getKey(), + 'managed_environment_id' => (int) $archivedTenant->getKey(), 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -70,7 +70,7 @@ ->assertOk() ->assertSee('Operation tenant is not available in the current tenant selector') ->assertSee('This tenant is currently archived and may not appear in the tenant selector.') - ->assertSee('Tenant lifecycle') + ->assertSee('ManagedEnvironment lifecycle') ->assertSee('Archived') ->assertSee('Viewer context') ->assertDontSee('deactivated'); diff --git a/apps/platform/tests/Feature/Filament/ResolvedReferenceRenderingSmokeTest.php b/apps/platform/tests/Feature/Filament/ResolvedReferenceRenderingSmokeTest.php index d97eafd7..9f623ca0 100644 --- a/apps/platform/tests/Feature/Filament/ResolvedReferenceRenderingSmokeTest.php +++ b/apps/platform/tests/Feature/Filament/ResolvedReferenceRenderingSmokeTest.php @@ -20,7 +20,7 @@ 'linkTarget' => [ 'url' => '/admin/t/1/policy-versions/42', 'actionLabel' => 'View policy version', - 'contextBadge' => 'Tenant', + 'contextBadge' => 'ManagedEnvironment', ], 'technicalDetail' => [ 'displayId' => '42', @@ -56,7 +56,7 @@ 'linkTarget' => [ 'url' => '/admin/operations/189', 'actionLabel' => 'Open operation', - 'contextBadge' => 'Tenant context', + 'contextBadge' => 'ManagedEnvironment context', ], 'technicalDetail' => [ 'displayId' => '189', @@ -81,7 +81,7 @@ ], ); - $referenceBadgePosition = strpos($html, 'Tenant context'); + $referenceBadgePosition = strpos($html, 'ManagedEnvironment context'); $referenceActionPosition = strpos($html, 'Open operation'); $fallbackBadgePosition = strpos($html, 'Workspace context'); $fallbackActionPosition = strpos($html, 'Inspect operations'); diff --git a/apps/platform/tests/Feature/Filament/Resources/FindingResourceOwnershipSemanticsTest.php b/apps/platform/tests/Feature/Filament/Resources/FindingResourceOwnershipSemanticsTest.php index 26946aa0..65275491 100644 --- a/apps/platform/tests/Feature/Filament/Resources/FindingResourceOwnershipSemanticsTest.php +++ b/apps/platform/tests/Feature/Filament/Resources/FindingResourceOwnershipSemanticsTest.php @@ -7,7 +7,7 @@ use App\Filament\Resources\FindingResource\Pages\ViewFinding; use App\Models\Finding; use App\Models\FindingException; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Filament\Forms\Components\Field; @@ -151,7 +151,7 @@ FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $findingWithException->getKey(), 'requested_by_user_id' => (int) $owner->getKey(), 'owner_user_id' => (int) $exceptionOwner->getKey(), @@ -203,7 +203,7 @@ }); it('allows in-scope members and returns 404 for non-members on tenant findings routes', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$member, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $finding = Finding::factory()->for($tenant)->create(); @@ -216,7 +216,7 @@ ->get(FindingResource::getUrl('view', ['record' => $finding], panel: 'tenant', tenant: $tenant)) ->assertSuccessful(); - $tenantInSameWorkspace = Tenant::factory()->create([ + $tenantInSameWorkspace = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); [$outsider] = createUserWithTenant(tenant: $tenantInSameWorkspace, role: 'owner'); @@ -230,7 +230,7 @@ ->assertNotFound(); }); -function tenantFindingUser(Tenant $tenant, string $name): User +function tenantFindingUser(ManagedEnvironment $tenant, string $name): User { $user = User::factory()->create([ 'name' => $name, diff --git a/apps/platform/tests/Feature/Filament/RestoreExecutionTest.php b/apps/platform/tests/Feature/Filament/RestoreExecutionTest.php index 6078f8fe..f6975604 100644 --- a/apps/platform/tests/Feature/Filament/RestoreExecutionTest.php +++ b/apps/platform/tests/Feature/Filament/RestoreExecutionTest.php @@ -4,7 +4,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -51,15 +51,15 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon config()->set('graph_contracts.types.deviceConfiguration.assignments_payload_key', 'assignments'); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -67,14 +67,14 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -148,7 +148,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ], ]); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); $backupSet = BackupSet::factory()->for($tenant)->create(); $backupItem = BackupItem::factory() @@ -252,7 +252,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon } }); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); $backupSet = BackupSet::factory()->for($tenant)->create([ @@ -333,15 +333,15 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon } }); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-3', - 'name' => 'Tenant Three', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-3', + 'name' => 'ManagedEnvironment Three', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-3', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Compliance Policy', @@ -349,14 +349,14 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -447,16 +447,16 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-scope-tags', - 'name' => 'Tenant Scope Tags', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-scope-tags', + 'name' => 'ManagedEnvironment Scope Tags', 'status' => 'active', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'app-1', 'policy_type' => 'mobileApp', 'display_name' => 'Mozilla Firefox', @@ -464,14 +464,14 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -565,9 +565,9 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon app()->instance(GraphClientInterface::class, $graphClient); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); @@ -671,9 +671,9 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon app()->instance(GraphClientInterface::class, $graphClient); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-4', - 'name' => 'Tenant Four', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-4', + 'name' => 'ManagedEnvironment Four', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); diff --git a/apps/platform/tests/Feature/Filament/RestoreItemSelectionTest.php b/apps/platform/tests/Feature/Filament/RestoreItemSelectionTest.php index 6ad170d4..b631d6ba 100644 --- a/apps/platform/tests/Feature/Filament/RestoreItemSelectionTest.php +++ b/apps/platform/tests/Feature/Filament/RestoreItemSelectionTest.php @@ -5,7 +5,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -14,25 +14,25 @@ uses(RefreshDatabase::class); test('restore selection options are grouped and preserve provider-missing continuity', function () { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); $tenant->makeCurrent(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Policy Display', 'platform' => 'windows', ]); $previewOnlyPolicy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-preview-only', 'policy_type' => 'conditionalAccessPolicy', 'display_name' => 'Conditional Access Policy', 'platform' => 'all', ]); $ignoredPolicy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-ignored', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Ignored Policy', @@ -40,7 +40,7 @@ 'ignored_at' => now(), ]); $providerMissingPolicy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-provider-missing', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Provider Missing Policy', @@ -48,7 +48,7 @@ 'missing_from_provider_at' => now(), ]); $combinedPolicy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-ignored-provider-missing', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Ignored Provider Missing Policy', diff --git a/apps/platform/tests/Feature/Filament/RestorePreviewTest.php b/apps/platform/tests/Feature/Filament/RestorePreviewTest.php index bd5d6800..369046fd 100644 --- a/apps/platform/tests/Feature/Filament/RestorePreviewTest.php +++ b/apps/platform/tests/Feature/Filament/RestorePreviewTest.php @@ -3,7 +3,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\RestoreService; @@ -45,15 +45,15 @@ public function request(string $method, string $path, array $options = []): Grap } }); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy A', @@ -61,14 +61,14 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -78,7 +78,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'filter-1', @@ -139,22 +139,22 @@ public function request(string $method, string $path, array $options = []): Grap } }); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-driver-preview', - 'name' => 'Tenant Preview', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-driver-preview', + 'name' => 'ManagedEnvironment Preview', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant, 'microsoft'); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'wdp-1', @@ -211,15 +211,15 @@ public function request(string $method, string $path, array $options = []): Grap } }); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-2', - 'name' => 'Tenant Two', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-2', + 'name' => 'ManagedEnvironment Two', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-2', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Compliance Policy', @@ -227,14 +227,14 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/Filament/RestoreResultAttentionSurfaceTest.php b/apps/platform/tests/Feature/Filament/RestoreResultAttentionSurfaceTest.php index 29a2ddbb..1d97836c 100644 --- a/apps/platform/tests/Feature/Filament/RestoreResultAttentionSurfaceTest.php +++ b/apps/platform/tests/Feature/Filament/RestoreResultAttentionSurfaceTest.php @@ -15,7 +15,7 @@ dataset('dashboard-linked-restore-result-reasons', [ 'failed' => [ - fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() + fn (\App\Models\ManagedEnvironment $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->failedOutcome() @@ -27,7 +27,7 @@ 'The restore did not complete successfully. Follow-up is still required.', ], 'partial' => [ - fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() + fn (\App\Models\ManagedEnvironment $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->partialOutcome() @@ -39,7 +39,7 @@ 'The restore reached a terminal state, but some items or assignments still need follow-up.', ], 'completed with follow-up' => [ - fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() + fn (\App\Models\ManagedEnvironment $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->completedWithFollowUp() @@ -57,11 +57,11 @@ $this->actingAs($user); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'results' => [ @@ -106,7 +106,7 @@ ->assertSee('Follow-up required') ->assertSee('Review skipped or non-applied items before closing the run.') ->assertSee('No dominant cause recorded') - ->assertSee('Tenant-wide recovery is not proven.') + ->assertSee('ManagedEnvironment-wide recovery is not proven.') ->assertDontSee('review_skipped_items') ->assertDontSee('run_completed_not_recovery_proven'); }); @@ -116,7 +116,7 @@ $this->actingAs($user); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); /** @var RestoreSafetyResolver $resolver */ @@ -139,7 +139,7 @@ $previewBasis = $resolver->previewBasisFromData($previewData); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'previewed', 'is_dry_run' => true, @@ -181,11 +181,11 @@ $this->actingAs($user); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'previewed', 'is_dry_run' => true, @@ -225,11 +225,11 @@ $this->actingAs($user); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => false, diff --git a/apps/platform/tests/Feature/Filament/RestoreRunAdminTenantParityTest.php b/apps/platform/tests/Feature/Filament/RestoreRunAdminTenantParityTest.php index 3dcd50ad..cf6a32b0 100644 --- a/apps/platform/tests/Feature/Filament/RestoreRunAdminTenantParityTest.php +++ b/apps/platform/tests/Feature/Filament/RestoreRunAdminTenantParityTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\RestoreRunResource; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,9 +13,9 @@ uses(RefreshDatabase::class); it('scopes the admin restore-run list to the remembered canonical tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $backupSetA = BackupSet::factory()->for($tenantA)->create(); diff --git a/apps/platform/tests/Feature/Filament/RestoreRunListFiltersTest.php b/apps/platform/tests/Feature/Filament/RestoreRunListFiltersTest.php index 389315b3..8aa733c5 100644 --- a/apps/platform/tests/Feature/Filament/RestoreRunListFiltersTest.php +++ b/apps/platform/tests/Feature/Filament/RestoreRunListFiltersTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\RestoreRunResource\Pages\ListRestoreRuns; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\RestoreRunStatus; use Filament\Facades\Filament; use Livewire\Livewire; @@ -18,37 +18,37 @@ function restoreRunFilterIndicatorLabels($component): array } it('filters restore runs by status and derived outcome without leaking other tenants', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); $backupSetA = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), ]); $backupSetB = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), ]); $matching = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'backup_set_id' => (int) $backupSetA->getKey(), 'status' => RestoreRunStatus::Completed->value, 'started_at' => now()->subDay(), ]); $partial = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'backup_set_id' => (int) $backupSetA->getKey(), 'status' => RestoreRunStatus::Partial->value, 'started_at' => now()->subDay(), ]); $otherTenant = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'backup_set_id' => (int) $backupSetB->getKey(), 'status' => RestoreRunStatus::Completed->value, 'started_at' => now()->subDay(), @@ -69,18 +69,18 @@ function restoreRunFilterIndicatorLabels($component): array [$user, $tenant] = createUserWithTenant(role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $recentActive = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'status' => RestoreRunStatus::Completed->value, 'started_at' => now()->subDay(), ]); $recentArchived = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'status' => RestoreRunStatus::Failed->value, 'started_at' => now()->subDay(), @@ -88,7 +88,7 @@ function restoreRunFilterIndicatorLabels($component): array ]); $oldActive = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'status' => RestoreRunStatus::Completed->value, 'started_at' => now()->subDays(10), @@ -119,17 +119,17 @@ function restoreRunFilterIndicatorLabels($component): array [$user, $tenant] = createUserWithTenant(role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $active = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'status' => RestoreRunStatus::Completed->value, ]); $archived = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'status' => RestoreRunStatus::Failed->value, 'deleted_at' => now(), diff --git a/apps/platform/tests/Feature/Filament/RestoreRunUiEnforcementTest.php b/apps/platform/tests/Feature/Filament/RestoreRunUiEnforcementTest.php index 0317ed88..9de41b60 100644 --- a/apps/platform/tests/Feature/Filament/RestoreRunUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Filament/RestoreRunUiEnforcementTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\RestoreRunResource\Pages\ListRestoreRuns; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; use App\Support\Auth\UiTooltips; @@ -35,8 +35,8 @@ function getRestoreRunEmptyStateAction(Testable $component, string $name): ?Acti } test('non-members are denied access to RestoreRun tenant routes (404)', function () { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'owner'); @@ -46,16 +46,16 @@ function getRestoreRunEmptyStateAction(Testable $component, string $name): ?Acti }); test('members without capability see RestoreRun actions disabled with standard tooltip and cannot execute', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'readonly'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => 'completed', ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->getKey(), 'status' => 'completed', 'deleted_at' => null, @@ -73,16 +73,16 @@ function getRestoreRunEmptyStateAction(Testable $component, string $name): ?Acti }); test('members with capability can execute RestoreRun actions', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => 'completed', ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->getKey(), 'status' => 'completed', 'deleted_at' => null, @@ -99,7 +99,7 @@ function getRestoreRunEmptyStateAction(Testable $component, string $name): ?Acti }); test('restore runs list shows empty state create action enabled for members with manage capability', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'owner'); Filament::setTenant($tenant, true); @@ -116,7 +116,7 @@ function getRestoreRunEmptyStateAction(Testable $component, string $name): ?Acti }); test('restore runs list shows empty state create action disabled for members without manage capability', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'readonly'); Filament::setTenant($tenant, true); @@ -133,11 +133,11 @@ function getRestoreRunEmptyStateAction(Testable $component, string $name): ?Acti }); test('readonly members can inspect restore-run history while mutations remain disabled', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'readonly'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => 'completed', ]); @@ -158,11 +158,11 @@ function getRestoreRunEmptyStateAction(Testable $component, string $name): ?Acti }); test('in-scope members without restore-history view capability receive 403 on restore-run list and detail drillthroughs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'status' => 'completed', ]); @@ -171,10 +171,10 @@ function getRestoreRunEmptyStateAction(Testable $component, string $name): ?Acti mock(CapabilityResolver::class, function ($mock) use ($tenant): void { $mock->shouldReceive('primeMemberships')->andReturnNull(); $mock->shouldReceive('isMember') - ->andReturnUsing(static fn ($user, Tenant $resolvedTenant): bool => (int) $resolvedTenant->getKey() === (int) $tenant->getKey()); + ->andReturnUsing(static fn ($user, ManagedEnvironment $resolvedTenant): bool => (int) $resolvedTenant->getKey() === (int) $tenant->getKey()); $mock->shouldReceive('can') - ->andReturnUsing(static function ($user, Tenant $resolvedTenant, string $capability) use ($tenant): bool { + ->andReturnUsing(static function ($user, ManagedEnvironment $resolvedTenant, string $capability) use ($tenant): bool { expect((int) $resolvedTenant->getKey())->toBe((int) $tenant->getKey()); return match ($capability) { diff --git a/apps/platform/tests/Feature/Filament/RestoreSafetyIntegrityWizardTest.php b/apps/platform/tests/Feature/Filament/RestoreSafetyIntegrityWizardTest.php index 1bc40116..25770317 100644 --- a/apps/platform/tests/Feature/Filament/RestoreSafetyIntegrityWizardTest.php +++ b/apps/platform/tests/Feature/Filament/RestoreSafetyIntegrityWizardTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Resources\RestoreRunResource\Pages\CreateRestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\RestoreSafety\RestoreSafetyResolver; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -12,7 +12,7 @@ uses(RefreshDatabase::class); it('renders warning-suppressed execution guidance when current evidence still has warnings', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), ]); diff --git a/apps/platform/tests/Feature/Filament/RestoreWizardGraphSafetyTest.php b/apps/platform/tests/Feature/Filament/RestoreWizardGraphSafetyTest.php index 70acfa0d..5fb4cc52 100644 --- a/apps/platform/tests/Feature/Filament/RestoreWizardGraphSafetyTest.php +++ b/apps/platform/tests/Feature/Filament/RestoreWizardGraphSafetyTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\RestoreRunResource; use App\Models\BackupItem; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; function makeAssignment(string $odataType, string $groupId, ?string $displayName = null): array { @@ -20,7 +20,7 @@ function makeAssignment(string $odataType, string $groupId, ?string $displayName } test('restore wizard create page renders without touching graph', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant); bindFailHardGraphClient(); @@ -33,11 +33,11 @@ function makeAssignment(string $odataType, string $groupId, ?string $displayName }); test('restore wizard group mapping renders DB-only with manual GUID UX', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'name' => 'group-mapping-backup-set', ]); @@ -45,7 +45,7 @@ function makeAssignment(string $odataType, string $groupId, ?string $displayName $expectedMasked = '…'.substr($groupId, -8); BackupItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->getKey(), 'assignments' => [ makeAssignment('#microsoft.graph.groupAssignmentTarget', $groupId, 'Example Group'), diff --git a/apps/platform/tests/Feature/Filament/ScriptPoliciesNormalizedDisplayTest.php b/apps/platform/tests/Feature/Filament/ScriptPoliciesNormalizedDisplayTest.php index 5485b52b..8c4e53a6 100644 --- a/apps/platform/tests/Feature/Filament/ScriptPoliciesNormalizedDisplayTest.php +++ b/apps/platform/tests/Feature/Filament/ScriptPoliciesNormalizedDisplayTest.php @@ -2,7 +2,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); @@ -11,14 +11,14 @@ $originalEnv = getenv('INTUNE_TENANT_ID'); putenv('INTUNE_TENANT_ID='); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $this->actingAs($user); - putenv('INTUNE_TENANT_ID='.$tenant->tenant_id); + putenv('INTUNE_TENANT_ID='.$tenant->managed_environment_id); $tenant->makeCurrent(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_type' => $policyType, 'platform' => 'all', 'display_name' => 'Script policy', @@ -40,7 +40,7 @@ $version = PolicyVersion::factory()->create([ 'policy_id' => $policy->id, - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_type' => $policyType, 'snapshot' => [ '@odata.type' => $odataType, @@ -75,14 +75,14 @@ 'tenantpilot.display.max_script_content_chars' => 5000, ]); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $this->actingAs($user); - putenv('INTUNE_TENANT_ID='.$tenant->tenant_id); + putenv('INTUNE_TENANT_ID='.$tenant->managed_environment_id); $tenant->makeCurrent(); $policy = \App\Models\Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_type' => 'deviceManagementScript', 'platform' => 'windows', ]); @@ -92,7 +92,7 @@ $v1 = \App\Models\PolicyVersion::factory()->create([ 'policy_id' => $policy->getKey(), - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'version_number' => 1, 'policy_type' => 'deviceManagementScript', 'platform' => 'windows', @@ -105,7 +105,7 @@ $v2 = \App\Models\PolicyVersion::factory()->create([ 'policy_id' => $policy->getKey(), - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'version_number' => 2, 'policy_type' => 'deviceManagementScript', 'platform' => 'windows', @@ -140,14 +140,14 @@ 'tenantpilot.display.max_script_content_chars' => 5000, ]); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user); - putenv('INTUNE_TENANT_ID='.$tenant->tenant_id); + putenv('INTUNE_TENANT_ID='.$tenant->managed_environment_id); $tenant->makeCurrent(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_type' => 'deviceComplianceScript', 'platform' => 'windows', ]); @@ -157,7 +157,7 @@ $v1 = PolicyVersion::factory()->create([ 'policy_id' => $policy->getKey(), - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'version_number' => 1, 'policy_type' => 'deviceComplianceScript', 'platform' => 'windows', @@ -170,7 +170,7 @@ $v2 = PolicyVersion::factory()->create([ 'policy_id' => $policy->getKey(), - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'version_number' => 2, 'policy_type' => 'deviceComplianceScript', 'platform' => 'windows', diff --git a/apps/platform/tests/Feature/Filament/SelectTenantPostPersistsLastUsedTest.php b/apps/platform/tests/Feature/Filament/SelectTenantPostPersistsLastUsedTest.php index 95d942e4..481fe08f 100644 --- a/apps/platform/tests/Feature/Filament/SelectTenantPostPersistsLastUsedTest.php +++ b/apps/platform/tests/Feature/Filament/SelectTenantPostPersistsLastUsedTest.php @@ -3,8 +3,8 @@ declare(strict_types=1); use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -25,13 +25,13 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => $workspace->getKey(), ]); - TenantMembership::query()->create([ - 'tenant_id' => $tenant->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', @@ -42,7 +42,7 @@ $response = $this ->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]) - ->post(route('admin.select-tenant'), ['tenant_id' => (int) $tenant->getKey()]); + ->post(route('admin.select-tenant'), ['managed_environment_id' => (int) $tenant->getKey()]); $response->assertRedirect(TenantDashboard::getUrl(tenant: $tenant)); @@ -54,9 +54,9 @@ return; } - if (Schema::hasTable('user_tenant_preferences')) { + if (Schema::hasTable('user_managed_environment_preferences')) { $preference = $user->tenantPreferences() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->first(); expect($preference)->not->toBeNull(); diff --git a/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyHydrationTest.php b/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyHydrationTest.php index f32ce885..6fa8d3b4 100644 --- a/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyHydrationTest.php +++ b/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyHydrationTest.php @@ -1,7 +1,7 @@ instance(GraphClientInterface::class, $client); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-hydration', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-hydration', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'is_current' => true, ]); ensureDefaultProviderConnection($tenant); - putenv('INTUNE_TENANT_ID='.$tenant->tenant_id); - $_ENV['INTUNE_TENANT_ID'] = $tenant->tenant_id; - $_SERVER['INTUNE_TENANT_ID'] = $tenant->tenant_id; + putenv('INTUNE_TENANT_ID='.$tenant->managed_environment_id); + $_ENV['INTUNE_TENANT_ID'] = $tenant->managed_environment_id; + $_SERVER['INTUNE_TENANT_ID'] = $tenant->managed_environment_id; $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-hydrate', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Alpha', @@ -121,22 +121,22 @@ public function request(string $method, string $path, array $options = []): Grap $client = new SettingsCatalogHydrationGraphClient; app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-hydration-version', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-hydration-version', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'is_current' => true, ]); ensureDefaultProviderConnection($tenant); - putenv('INTUNE_TENANT_ID='.$tenant->tenant_id); - $_ENV['INTUNE_TENANT_ID'] = $tenant->tenant_id; - $_SERVER['INTUNE_TENANT_ID'] = $tenant->tenant_id; + putenv('INTUNE_TENANT_ID='.$tenant->managed_environment_id); + $_ENV['INTUNE_TENANT_ID'] = $tenant->managed_environment_id; + $_SERVER['INTUNE_TENANT_ID'] = $tenant->managed_environment_id; $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-version', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Beta', diff --git a/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyNormalizedDiffTest.php b/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyNormalizedDiffTest.php index 83f1ec1b..00fe6ee5 100644 --- a/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyNormalizedDiffTest.php +++ b/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyNormalizedDiffTest.php @@ -5,7 +5,7 @@ use App\Models\PolicyVersion; use App\Models\SettingsCatalogCategory; use App\Models\SettingsCatalogDefinition; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\PolicyNormalizer; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -76,14 +76,14 @@ 'raw' => [], ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'settings-catalog-policy-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Policy', @@ -91,7 +91,7 @@ ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyNormalizedDisplayTest.php b/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyNormalizedDisplayTest.php index 71b41b72..e5bbb47f 100644 --- a/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyNormalizedDisplayTest.php +++ b/apps/platform/tests/Feature/Filament/SettingsCatalogPolicyNormalizedDisplayTest.php @@ -4,16 +4,16 @@ use App\Filament\Resources\PolicyVersionResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('configuration policy types render a normalized settings table', function (string $policyType) { - $tenant = Tenant::create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'is_current' => true, ]); @@ -21,7 +21,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-policy-1', 'policy_type' => $policyType, 'display_name' => 'Settings Catalog Policy', @@ -29,7 +29,7 @@ ]); $version = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policyType, @@ -106,7 +106,7 @@ ->get(PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $tenant)); $versionResponse->assertOk(); - $versionResponse->assertSee('Normalized settings'); + $versionResponse->assertSee('Settings'); $versionResponse->assertSee('device_vendor_msft_policy_config_system_usebiometrics'); $versionResponse->assertSee('Enabled'); $versionResponse->assertSee('device_vendor_msft_policy_config_system_child'); diff --git a/apps/platform/tests/Feature/Filament/SettingsCatalogPolicySyncTest.php b/apps/platform/tests/Feature/Filament/SettingsCatalogPolicySyncTest.php index 402cb64a..0284b8ac 100644 --- a/apps/platform/tests/Feature/Filament/SettingsCatalogPolicySyncTest.php +++ b/apps/platform/tests/Feature/Filament/SettingsCatalogPolicySyncTest.php @@ -4,7 +4,7 @@ use App\Models\PolicyVersion; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -76,23 +76,23 @@ public function request(string $method, string $path, array $options = []): Grap app()->instance(GraphClientInterface::class, new SettingsCatalogFakeGraphClient($responses)); - $tenant = Tenant::create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'is_current' => true, ]); $tenant->makeCurrent(); - expect(Tenant::current()->id)->toBe($tenant->id); + expect(ManagedEnvironment::current()->id)->toBe($tenant->id); $workspace = Workspace::factory()->create(); $tenant->forceFill(['workspace_id' => (int) $workspace->getKey()])->save(); $connection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => $tenant->tenant_id, + 'entra_tenant_id' => $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); @@ -118,7 +118,7 @@ public function request(string $method, string $path, array $options = []): Grap expect(Policy::where('policy_type', 'deviceConfiguration')->where('external_id', 'scp-1')->exists())->toBeFalse(); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $settingsPolicy->id, 'version_number' => 1, 'policy_type' => $settingsPolicy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/SettingsCatalogRestoreApplySettingsPatchTest.php b/apps/platform/tests/Feature/Filament/SettingsCatalogRestoreApplySettingsPatchTest.php index e1156f8a..3324a7f4 100644 --- a/apps/platform/tests/Feature/Filament/SettingsCatalogRestoreApplySettingsPatchTest.php +++ b/apps/platform/tests/Feature/Filament/SettingsCatalogRestoreApplySettingsPatchTest.php @@ -3,7 +3,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\RestoreService; @@ -97,16 +97,16 @@ public function request(string $method, string $path, array $options = []): Grap app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-3', - 'name' => 'Tenant Three', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-3', + 'name' => 'ManagedEnvironment Three', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-3', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Gamma', @@ -114,7 +114,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, @@ -138,7 +138,7 @@ public function request(string $method, string $path, array $options = []): Grap ]; $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/Filament/SettingsCatalogRestoreTest.php b/apps/platform/tests/Feature/Filament/SettingsCatalogRestoreTest.php index 054911c9..54c58330 100644 --- a/apps/platform/tests/Feature/Filament/SettingsCatalogRestoreTest.php +++ b/apps/platform/tests/Feature/Filament/SettingsCatalogRestoreTest.php @@ -5,7 +5,7 @@ use App\Models\Policy; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -15,16 +15,16 @@ uses(RefreshDatabase::class); if (! function_exists('makeTenantWithDefaultProviderConnection')) { - function makeTenantWithDefaultProviderConnection(array $attributes = []): Tenant + function makeTenantWithDefaultProviderConnection(array $attributes = []): ManagedEnvironment { - $tenant = Tenant::create(array_merge([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create(array_merge([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ], $attributes)); $connection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', @@ -134,7 +134,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant = makeTenantWithDefaultProviderConnection(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Alpha', @@ -142,7 +142,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, @@ -174,7 +174,7 @@ public function request(string $method, string $path, array $options = []): Grap ]; $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -248,12 +248,12 @@ public function request(string $method, string $path, array $options = []): Grap app()->instance(GraphClientInterface::class, $client); $tenant = makeTenantWithDefaultProviderConnection([ - 'tenant_id' => 'tenant-2', - 'name' => 'Tenant Two', + 'managed_environment_id' => 'tenant-2', + 'name' => 'ManagedEnvironment Two', ]); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-2', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Beta', @@ -261,7 +261,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, @@ -286,7 +286,7 @@ public function request(string $method, string $path, array $options = []): Grap ]; $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -368,12 +368,12 @@ public function request(string $method, string $path, array $options = []): Grap app()->instance(GraphClientInterface::class, $client); $tenant = makeTenantWithDefaultProviderConnection([ - 'tenant_id' => 'tenant-4', - 'name' => 'Tenant Four', + 'managed_environment_id' => 'tenant-4', + 'name' => 'ManagedEnvironment Four', ]); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-4', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Delta', @@ -381,7 +381,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, @@ -405,7 +405,7 @@ public function request(string $method, string $path, array $options = []): Grap ]; $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -485,12 +485,12 @@ public function request(string $method, string $path, array $options = []): Grap app()->instance(GraphClientInterface::class, $client); $tenant = makeTenantWithDefaultProviderConnection([ - 'tenant_id' => 'tenant-5', - 'name' => 'Tenant Five', + 'managed_environment_id' => 'tenant-5', + 'name' => 'ManagedEnvironment Five', ]); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-5', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Epsilon', @@ -498,7 +498,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, @@ -524,7 +524,7 @@ public function request(string $method, string $path, array $options = []): Grap ]; $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/Filament/SettingsCatalogSettingsTableRenderTest.php b/apps/platform/tests/Feature/Filament/SettingsCatalogSettingsTableRenderTest.php index 6a02b5c6..b894b236 100644 --- a/apps/platform/tests/Feature/Filament/SettingsCatalogSettingsTableRenderTest.php +++ b/apps/platform/tests/Feature/Filament/SettingsCatalogSettingsTableRenderTest.php @@ -4,16 +4,16 @@ use App\Filament\Resources\PolicyVersionResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('settings catalog settings render as a filament table with details action', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'is_current' => true, ]); @@ -21,7 +21,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-policy-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Policy', @@ -29,7 +29,7 @@ ]); $version = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -74,7 +74,7 @@ $versionResponse->assertOk(); $versionResponse->assertSee('fi-width-full'); - $versionResponse->assertSee('Normalized settings'); + $versionResponse->assertSee('Settings'); $versionResponse->assertSee('Details'); $versionResponse->assertSee('fi-ta-table'); }); diff --git a/apps/platform/tests/Feature/Filament/SharedVerificationReportFamilyContractTest.php b/apps/platform/tests/Feature/Filament/SharedVerificationReportFamilyContractTest.php index 81a4978e..727defb9 100644 --- a/apps/platform/tests/Feature/Filament/SharedVerificationReportFamilyContractTest.php +++ b/apps/platform/tests/Feature/Filament/SharedVerificationReportFamilyContractTest.php @@ -5,7 +5,7 @@ use App\Filament\Widgets\Tenant\TenantVerificationReport; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -36,7 +36,7 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', @@ -73,9 +73,9 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -84,7 +84,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'is_default' => true, ]); @@ -104,7 +104,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'blocked', @@ -116,8 +116,8 @@ TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -150,7 +150,7 @@ $report = VerificationReportWriter::build('provider.connection.check', [ [ 'key' => 'tenant_widget_report', - 'title' => 'Tenant widget verification', + 'title' => 'ManagedEnvironment widget verification', 'status' => 'fail', 'severity' => 'high', 'blocking' => false, @@ -163,13 +163,13 @@ OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'blocked', 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ], 'verification_report' => $report, ], @@ -177,7 +177,7 @@ $component = Livewire::actingAs($user) ->test(TenantVerificationReport::class, ['record' => $tenant]) - ->assertSee('Tenant widget verification'); + ->assertSee('ManagedEnvironment widget verification'); expect($component->html()) ->toContain('data-shared-detail-family="verification-report"') diff --git a/apps/platform/tests/Feature/Filament/TableDetailVisibilityTest.php b/apps/platform/tests/Feature/Filament/TableDetailVisibilityTest.php index 54d92394..57715c6a 100644 --- a/apps/platform/tests/Feature/Filament/TableDetailVisibilityTest.php +++ b/apps/platform/tests/Feature/Filament/TableDetailVisibilityTest.php @@ -35,7 +35,7 @@ function spec125DetailTable(Testable $component): Table } /** - * @return array{0: \App\Models\User, 1: \App\Models\Tenant} + * @return array{0: \App\Models\User, 1: \App\Models\ManagedEnvironment} */ function spec125DetailTenantContext(): array { @@ -67,7 +67,7 @@ function spec125DetailPlatformContext(): PlatformUser [$user, $tenant] = spec125DetailTenantContext(); $group = EntraGroup::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_id' => '00000000-0000-0000-0000-1234567890ab', 'display_name' => 'Alpha Security Group', 'group_types' => null, @@ -137,7 +137,7 @@ function spec125DetailPlatformContext(): PlatformUser [$user, $tenant] = spec125DetailTenantContext(); $operation = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::InventorySync->value, 'status' => OperationRunStatus::Queued->value, @@ -171,7 +171,7 @@ function spec125DetailPlatformContext(): PlatformUser [$user, $tenant] = spec125DetailTenantContext(); $finding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]); @@ -188,7 +188,7 @@ function spec125DetailPlatformContext(): PlatformUser [$user, $tenant] = spec125DetailTenantContext(); $group = EntraGroup::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_id' => '00000000-0000-0000-0000-1234567890ab', 'display_name' => 'Bravo Group', 'group_types' => null, diff --git a/apps/platform/tests/Feature/Filament/TableStandardsBaselineTest.php b/apps/platform/tests/Feature/Filament/TableStandardsBaselineTest.php index 11e4122a..98e317fd 100644 --- a/apps/platform/tests/Feature/Filament/TableStandardsBaselineTest.php +++ b/apps/platform/tests/Feature/Filament/TableStandardsBaselineTest.php @@ -27,7 +27,7 @@ function spec125BaselineTable(Testable $component): Table } /** - * @return array{0: \App\Models\User, 1: \App\Models\Tenant} + * @return array{0: \App\Models\User, 1: \App\Models\ManagedEnvironment} */ function spec125BaselineTenantContext(): array { @@ -78,7 +78,7 @@ function spec125BaselineTenantContext(): array [$user, $tenant] = spec125BaselineTenantContext(); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $component = Livewire::actingAs($user)->test(VersionsRelationManager::class, [ @@ -103,7 +103,7 @@ function spec125BaselineTenantContext(): array [$user, $tenant] = spec125BaselineTenantContext(); $finding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]); diff --git a/apps/platform/tests/Feature/Filament/TableStandardsCriticalListsTest.php b/apps/platform/tests/Feature/Filament/TableStandardsCriticalListsTest.php index 30c2aca7..27d1fe60 100644 --- a/apps/platform/tests/Feature/Filament/TableStandardsCriticalListsTest.php +++ b/apps/platform/tests/Feature/Filament/TableStandardsCriticalListsTest.php @@ -27,7 +27,7 @@ function spec125CriticalTable(Testable $component): Table } /** - * @return array{0: \App\Models\User, 1: \App\Models\Tenant} + * @return array{0: \App\Models\User, 1: \App\Models\ManagedEnvironment} */ function spec125CriticalTenantContext(bool $ensureDefaultMicrosoftProviderConnection = true): array { @@ -59,8 +59,8 @@ function spec125CriticalTenantContext(bool $ensureDefaultMicrosoftProviderConnec expect($table->getEmptyStateDescription())->toBe('Add a tenant to start syncing inventory, policies, and provider health into this workspace.'); expect($table->getColumn('name')?->isSearchable())->toBeTrue(); expect($table->getColumn('name')?->isSortable())->toBeTrue(); - expect($table->getColumn('tenant_id')?->isToggleable())->toBeTrue(); - expect($table->getColumn('tenant_id')?->isToggledHiddenByDefault())->toBeTrue(); + expect($table->getColumn('managed_environment_id')?->isToggleable())->toBeTrue(); + expect($table->getColumn('managed_environment_id')?->isToggledHiddenByDefault())->toBeTrue(); expect($table->getColumn('domain')?->isToggleable())->toBeTrue(); expect($table->getColumn('domain')?->isToggledHiddenByDefault())->toBeTrue(); expect($table->getColumn('created_at')?->isToggleable())->toBeTrue(); @@ -242,7 +242,7 @@ function spec125CriticalTenantContext(bool $ensureDefaultMicrosoftProviderConnec Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $component = Livewire::actingAs($user)->test(BackupItemsRelationManager::class, [ diff --git a/apps/platform/tests/Feature/Filament/TableStatePersistenceTest.php b/apps/platform/tests/Feature/Filament/TableStatePersistenceTest.php index 074096c8..046f5e6f 100644 --- a/apps/platform/tests/Feature/Filament/TableStatePersistenceTest.php +++ b/apps/platform/tests/Feature/Filament/TableStatePersistenceTest.php @@ -20,7 +20,7 @@ use App\Models\AuditLog; use App\Models\Finding; use App\Models\FindingException; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -71,7 +71,7 @@ function spec125AssertPersistedTableState( spec125AssertPersistedTableState( ListTenants::class, [], - 'Tenant', + 'ManagedEnvironment', 'name', 'desc', 'tableFilters.environment.value', @@ -320,7 +320,7 @@ function spec125AssertPersistedTableState( $selectedAudit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -335,7 +335,7 @@ function spec125AssertPersistedTableState( AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -373,7 +373,7 @@ function spec125AssertPersistedTableState( $selectedException = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $approver->getKey(), 'owner_user_id' => (int) $approver->getKey(), @@ -389,7 +389,7 @@ function spec125AssertPersistedTableState( FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $rejectedFinding->getKey(), 'requested_by_user_id' => (int) $approver->getKey(), 'owner_user_id' => (int) $approver->getKey(), @@ -419,9 +419,9 @@ function spec125AssertPersistedTableState( }); it('reseeds the provider-connections tenant filter when the remembered admin tenant changes', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); diff --git a/apps/platform/tests/Feature/Filament/TenantActionsAuthorizationTest.php b/apps/platform/tests/Feature/Filament/TenantActionsAuthorizationTest.php index c6279d5a..8089a032 100644 --- a/apps/platform/tests/Feature/Filament/TenantActionsAuthorizationTest.php +++ b/apps/platform/tests/Feature/Filament/TenantActionsAuthorizationTest.php @@ -3,7 +3,7 @@ use App\Filament\Pages\ChooseTenant; use App\Filament\Pages\TenantDashboard; use App\Filament\Resources\TenantResource\Pages\ListTenants; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\UiTooltips; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -20,7 +20,7 @@ test('readonly users may switch current tenant via ChooseTenant', function () { [$user, $tenantA] = createUserWithTenant(role: 'readonly', fixtureProfile: 'credential-enabled'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'is_current' => false, ]); @@ -43,7 +43,7 @@ test('users cannot switch to a tenant they are not a member of', function () { [$user] = createUserWithTenant(role: 'readonly', fixtureProfile: 'credential-enabled'); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', ]); @@ -86,7 +86,7 @@ ->assertTableActionExists('forceDelete', fn ($action): bool => $action->getTooltip() === UiTooltips::insufficientPermission(), $tenant) ->callTableAction('forceDelete', $tenant); - expect(Tenant::withTrashed()->find($tenant->getKey()))->not->toBeNull(); + expect(ManagedEnvironment::withTrashed()->find($tenant->getKey()))->not->toBeNull(); }); test('readonly users cannot verify tenant configuration', function () { diff --git a/apps/platform/tests/Feature/Filament/TenantContextResolvedReferenceCarryoverTest.php b/apps/platform/tests/Feature/Filament/TenantContextResolvedReferenceCarryoverTest.php index 6b2cb1c5..ee65f650 100644 --- a/apps/platform/tests/Feature/Filament/TenantContextResolvedReferenceCarryoverTest.php +++ b/apps/platform/tests/Feature/Filament/TenantContextResolvedReferenceCarryoverTest.php @@ -42,5 +42,5 @@ $response->assertOk() ->assertSee('nav%5Bsource_surface%5D=finding.detail_section', false) - ->assertSee('nav%5Btenant_id%5D='.(int) $tenant->getKey(), false); + ->assertSee('nav%5Bmanaged_environment_id%5D='.(int) $tenant->getKey(), false); }); diff --git a/apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextPerformanceTest.php b/apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextPerformanceTest.php index 3429c138..59f81382 100644 --- a/apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextPerformanceTest.php +++ b/apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextPerformanceTest.php @@ -26,7 +26,7 @@ function performanceArrivalRequest(array $query, int $workspaceId): Request } it('memoizes arrival-context resolution within a single request', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Performance Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Performance ManagedEnvironment'); $this->seedPortfolioRecoveryConcern($tenant, RestoreResultAttention::STATE_COMPLETED_WITH_FOLLOW_UP); $this->actingAs($user); @@ -61,7 +61,7 @@ function performanceArrivalRequest(array $query, int $workspaceId): Request }); it('renders the arrival continuity shell and productized overview DB-only with bounded query volume', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('DB Only Arrival Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('DB Only Arrival ManagedEnvironment'); $this->seedPortfolioRecoveryConcern($tenant, RestoreResultAttention::STATE_PARTIAL); $this->actingAs($user); diff --git a/apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php b/apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php index dc1a915e..17a84820 100644 --- a/apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php +++ b/apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php @@ -26,14 +26,14 @@ uses(BuildsPortfolioTriageFixtures::class); -function tenantDashboardArrivalUrl(\App\Models\Tenant $tenant, array $state): string +function tenantDashboardArrivalUrl(\App\Models\ManagedEnvironment $tenant, array $state): string { return TenantDashboard::getUrl([ PortfolioArrivalContextToken::QUERY_PARAMETER => PortfolioArrivalContextToken::encode($state), ], panel: 'tenant', tenant: $tenant); } -function tenantDashboardArrivalWidget(\App\Models\User $user, \App\Models\Tenant $tenant, array $state): mixed +function tenantDashboardArrivalWidget(\App\Models\User $user, \App\Models\ManagedEnvironment $tenant, array $state): mixed { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -46,7 +46,7 @@ function tenantDashboardArrivalWidget(\App\Models\User $user, \App\Models\Tenant } it('renders source surface, concern, next step, and return flow for workspace backup arrivals', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Workspace Backup Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Workspace Backup ManagedEnvironment'); $this->actingAs($user); $arrivalUrl = tenantDashboardArrivalUrl($tenant, [ @@ -74,7 +74,7 @@ function tenantDashboardArrivalWidget(\App\Models\User $user, \App\Models\Tenant }); it('renders registry arrival continuity with restore follow-up and preserved return filters', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Registry Recovery Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Registry Recovery ManagedEnvironment'); $restoreRun = $this->seedPortfolioRecoveryConcern($tenant, RestoreResultAttention::STATE_COMPLETED_WITH_FOLLOW_UP); $this->actingAs($user); @@ -98,7 +98,7 @@ function tenantDashboardArrivalWidget(\App\Models\User $user, \App\Models\Tenant $this->get($arrivalUrl) ->assertOk() - ->assertSee('Tenant registry triage') + ->assertSee('ManagedEnvironment registry triage') ->assertSee('Recovery evidence') ->assertSee('Weakened') ->assertSee('Open restore run') @@ -111,7 +111,7 @@ function tenantDashboardArrivalWidget(\App\Models\User $user, \App\Models\Tenant }); it('suppresses the continuity block for generic or malformed sessions', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Generic Tenant Session'); + [$user, $tenant] = $this->makePortfolioTriageActor('Generic ManagedEnvironment Session'); $this->actingAs($user); $this->get(TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant)) @@ -126,7 +126,7 @@ function tenantDashboardArrivalWidget(\App\Models\User $user, \App\Models\Tenant }); it('keeps the continuity block truthful when current truth has changed and multiple concerns remain visible', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Truth Shift Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Truth Shift ManagedEnvironment'); $backupSet = $this->seedPortfolioBackupConcern($tenant, TenantBackupHealthAssessment::POSTURE_STALE); $this->seedPortfolioRecoveryConcern($tenant, RestoreResultAttention::STATE_PARTIAL, $backupSet); $this->actingAs($user); @@ -151,7 +151,7 @@ function tenantDashboardArrivalWidget(\App\Models\User $user, \App\Models\Tenant }); it('degrades the next-step CTA when the operator cannot open deeper follow-up surfaces', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Restricted Arrival Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Restricted Arrival ManagedEnvironment'); $this->actingAs($user); mock(CapabilityResolver::class, function ($mock) use ($tenant): void { @@ -185,7 +185,7 @@ function tenantDashboardArrivalWidget(\App\Models\User $user, \App\Models\Tenant }); it('shows review-state context and requires preview confirmation before marking the current concern reviewed', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Dashboard Review Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Dashboard Review ManagedEnvironment'); $this->seedPortfolioBackupConcern($tenant, TenantBackupHealthAssessment::POSTURE_STALE); $component = tenantDashboardArrivalWidget($user, $tenant, [ @@ -214,20 +214,20 @@ function tenantDashboardArrivalWidget(\App\Models\User $user, \App\Models\Tenant ->assertSee('Reviewed'); expect(TenantTriageReview::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('concern_family', PortfolioArrivalContextToken::FAMILY_BACKUP_HEALTH) ->where('current_state', TenantTriageReview::STATE_REVIEWED) ->whereNull('resolved_at') ->exists())->toBeTrue() ->and(AuditLog::query() ->where('workspace_id', (int) $tenant->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', AuditActionId::TenantTriageReviewMarkedReviewed->value) ->exists())->toBeTrue(); }); it('renders changed-since-review when the current concern fingerprint no longer matches the stored review', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Dashboard Changed Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Dashboard Changed ManagedEnvironment'); $this->seedPortfolioBackupConcern($tenant, TenantBackupHealthAssessment::POSTURE_STALE); $this->seedPortfolioTriageReview( $tenant, diff --git a/apps/platform/tests/Feature/Filament/TenantDashboardDbOnlyTest.php b/apps/platform/tests/Feature/Filament/TenantDashboardDbOnlyTest.php index 759a8969..f2dfeabf 100644 --- a/apps/platform/tests/Feature/Filament/TenantDashboardDbOnlyTest.php +++ b/apps/platform/tests/Feature/Filament/TenantDashboardDbOnlyTest.php @@ -19,14 +19,14 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); Finding::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'severity' => Finding::SEVERITY_HIGH, 'status' => Finding::STATUS_NEW, ]); $operation = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'inventory_sync', 'status' => 'queued', 'outcome' => 'pending', @@ -34,14 +34,14 @@ ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'DB-only healthy backup', 'item_count' => 1, 'completed_at' => now()->subMinutes(30), ]); BackupItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'payload' => ['id' => 'healthy-policy'], 'metadata' => [], @@ -67,7 +67,7 @@ Livewire::test(DashboardKpis::class) ->assertSee('Active operations') - ->assertSee('healthy queued or running tenant work'); + ->assertSee('No follow-up queued'); Livewire::test(DashboardRecentOperations::class) ->assertSee('Operation ID') diff --git a/apps/platform/tests/Feature/Filament/TenantDashboardTenantScopeTest.php b/apps/platform/tests/Feature/Filament/TenantDashboardTenantScopeTest.php index 8305955c..4c53f456 100644 --- a/apps/platform/tests/Feature/Filament/TenantDashboardTenantScopeTest.php +++ b/apps/platform/tests/Feature/Filament/TenantDashboardTenantScopeTest.php @@ -11,7 +11,7 @@ use App\Models\Finding; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; use App\Support\Rbac\UiTooltips; @@ -23,22 +23,22 @@ it('does not leak data across tenants on the dashboard', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); - $otherTenant = Tenant::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); InventoryItem::factory()->create([ - 'tenant_id' => $otherTenant->getKey(), + 'managed_environment_id' => $otherTenant->getKey(), 'external_id' => 'other-tenant-finding', - 'display_name' => 'Other Tenant Policy', + 'display_name' => 'Other ManagedEnvironment Policy', ]); Finding::factory()->create([ - 'tenant_id' => $otherTenant->getKey(), + 'managed_environment_id' => $otherTenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'subject_external_id' => 'other-tenant-finding', ]); OperationRun::factory()->create([ - 'tenant_id' => $otherTenant->getKey(), + 'managed_environment_id' => $otherTenant->getKey(), 'type' => 'inventory_sync', 'status' => 'running', 'outcome' => 'pending', @@ -49,7 +49,7 @@ $this->get(TenantDashboard::getUrl(tenant: $tenant)) ->assertOk() - ->assertDontSee('Other Tenant Policy'); + ->assertDontSee('Other ManagedEnvironment Policy'); }); it('keeps backup summary truth visible on the dashboard while blocked backup drill-through routes still fail with 403', function (): void { @@ -72,10 +72,10 @@ mock(CapabilityResolver::class, function ($mock) use ($tenant): void { $mock->shouldReceive('isMember') - ->andReturnUsing(static fn ($user, Tenant $resolvedTenant): bool => (int) $resolvedTenant->getKey() === (int) $tenant->getKey()); + ->andReturnUsing(static fn ($user, ManagedEnvironment $resolvedTenant): bool => (int) $resolvedTenant->getKey() === (int) $tenant->getKey()); $mock->shouldReceive('can') - ->andReturnUsing(static function ($user, Tenant $resolvedTenant, string $capability) use ($tenant): bool { + ->andReturnUsing(static function ($user, ManagedEnvironment $resolvedTenant, string $capability) use ($tenant): bool { expect((int) $resolvedTenant->getKey())->toBe((int) $tenant->getKey()); return match ($capability) { diff --git a/apps/platform/tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php b/apps/platform/tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php index 41e29af5..69156611 100644 --- a/apps/platform/tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php +++ b/apps/platform/tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php @@ -40,7 +40,7 @@ function createTruthAlignedDashboardTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -52,7 +52,7 @@ function seedTrustworthyCompare(array $tenantContext): void [$user, $tenant, $profile, $snapshot] = $tenantContext; OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -86,7 +86,7 @@ function seedTrustworthyCompare(array $tenantContext): void seedTrustworthyCompare($tenantContext); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -95,7 +95,7 @@ function seedTrustworthyCompare(array $tenantContext): void ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -175,7 +175,7 @@ function seedTrustworthyCompare(array $tenantContext): void ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Running->value, @@ -217,7 +217,7 @@ function seedTrustworthyCompare(array $tenantContext): void FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $lapsedFinding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -328,7 +328,7 @@ function seedTrustworthyCompare(array $tenantContext): void ->assertDontSee('Backup schedules need follow-up'); BackupSchedule::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Overdue dashboard schedule', 'is_enabled' => true, 'timezone' => 'UTC', diff --git a/apps/platform/tests/Feature/Filament/TenantDiagnosticsRepairsTest.php b/apps/platform/tests/Feature/Filament/TenantDiagnosticsRepairsTest.php index f05c9e58..d5e28e11 100644 --- a/apps/platform/tests/Feature/Filament/TenantDiagnosticsRepairsTest.php +++ b/apps/platform/tests/Feature/Filament/TenantDiagnosticsRepairsTest.php @@ -4,18 +4,20 @@ use App\Filament\Pages\TenantDiagnostics; use App\Models\AuditLog; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironmentMembership; use App\Support\Audit\AuditActionId; use App\Support\Rbac\UiTooltips; use Filament\Actions\Action; use Filament\Facades\Filament; +use Illuminate\Database\Schema\Blueprint; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Schema; use Livewire\Livewire; uses(RefreshDatabase::class); -describe('Tenant diagnostics repairs', function () { +describe('ManagedEnvironment diagnostics repairs', function () { it('hides repair actions when no defect is present', function () { [$owner, $tenant] = createUserWithTenant(role: 'owner'); @@ -36,8 +38,8 @@ Filament::setTenant($tenant, true); - expect(TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + expect(ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('role', 'owner') ->count())->toBe(0); @@ -49,13 +51,13 @@ ->callMountedAction() ->assertSuccessful(); - expect(TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + expect(ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('role', 'owner') ->count())->toBe(1); expect(AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', AuditActionId::TenantMembershipBootstrapRecover->value) ->exists())->toBeTrue(); }); @@ -68,8 +70,8 @@ Filament::setTenant($tenant, true); // Force missing-owner state. - TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->update(['role' => 'readonly']); Livewire::test(TenantDiagnostics::class) @@ -87,25 +89,21 @@ Filament::setTenant($tenant, true); - // Intentionally create a broken state by temporarily dropping the unique uniqueness enforcement. - // Tests typically run on SQLite, which uses a unique index rather than a named table constraint. - $driver = DB::getDriverName(); - if ($driver === 'sqlite') { - DB::statement('DROP INDEX tenant_memberships_tenant_id_user_id_unique'); - } else { - DB::statement('ALTER TABLE tenant_memberships DROP CONSTRAINT tenant_memberships_tenant_id_user_id_unique'); - } + // Intentionally create a broken state by temporarily dropping the current uniqueness enforcement. + Schema::table('managed_environment_memberships', function (Blueprint $table): void { + $table->dropUnique(['managed_environment_id', 'user_id']); + }); - TenantMembership::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $owner->getKey(), 'role' => 'readonly', 'source' => 'manual', 'created_by_user_id' => (int) $owner->getKey(), ]); - expect(TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + expect(ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $owner->getKey()) ->count())->toBeGreaterThan(1); @@ -116,13 +114,13 @@ ->callMountedAction() ->assertSuccessful(); - expect(TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + expect(ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $owner->getKey()) ->count())->toBe(1); expect(AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', AuditActionId::TenantMembershipDuplicatesMerged->value) ->exists())->toBeTrue(); }); diff --git a/apps/platform/tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php b/apps/platform/tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php index 167cd2e7..a7b37d9a 100644 --- a/apps/platform/tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php +++ b/apps/platform/tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php @@ -7,7 +7,7 @@ use App\Filament\Resources\OperationRunResource; use App\Filament\Resources\TenantResource; use App\Filament\Resources\TenantReviewResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -20,18 +20,18 @@ function tenantSearchTitles($results): array } it('keeps tenant global-search aligned with administrative discoverability in the current workspace', function (): void { - $active = Tenant::factory()->active()->create(['name' => 'Lifecycle Active']); + $active = ManagedEnvironment::factory()->active()->create(['name' => 'Lifecycle Active']); [$user, $active] = createUserWithTenant(tenant: $active, role: 'owner'); - $onboarding = Tenant::factory()->onboarding()->create([ + $onboarding = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $active->workspace_id, 'name' => 'Lifecycle Onboarding', ]); - $draft = Tenant::factory()->draft()->create([ + $draft = ManagedEnvironment::factory()->draft()->create([ 'workspace_id' => (int) $active->workspace_id, 'name' => 'Lifecycle Draft', ]); - $archived = Tenant::factory()->archived()->create([ + $archived = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $active->workspace_id, 'name' => 'Lifecycle Archived', ]); diff --git a/apps/platform/tests/Feature/Filament/TenantGovernanceAggregateMemoizationTest.php b/apps/platform/tests/Feature/Filament/TenantGovernanceAggregateMemoizationTest.php index 61bf6bd8..774ddcce 100644 --- a/apps/platform/tests/Feature/Filament/TenantGovernanceAggregateMemoizationTest.php +++ b/apps/platform/tests/Feature/Filament/TenantGovernanceAggregateMemoizationTest.php @@ -7,7 +7,7 @@ use App\Models\BaselineProfile; use App\Models\BaselineSnapshot; use App\Models\BaselineTenantAssignment; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Baselines\BaselineCompareReasonCode; use App\Support\Baselines\TenantGovernanceAggregateResolver; use App\Support\OperationRunOutcome; @@ -35,12 +35,12 @@ function createTenantGovernanceMemoizationTenant(): array BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); \App\Models\OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -76,7 +76,7 @@ function createTenantGovernanceMemoizationTenant(): array expect(app(RequestScopedDerivedStateStore::class)->countStored( DerivedStateFamily::TenantGovernanceAggregate, - Tenant::class, + ManagedEnvironment::class, (string) $tenant->getKey(), TenantGovernanceAggregateResolver::VARIANT_TENANT_GOVERNANCE_SUMMARY, ))->toBe(1); @@ -100,13 +100,13 @@ function createTenantGovernanceMemoizationTenant(): array ->and($aggregateA?->tenantId)->not->toBe($aggregateB?->tenantId) ->and($store->countStored( DerivedStateFamily::TenantGovernanceAggregate, - Tenant::class, + ManagedEnvironment::class, (string) $tenantA->getKey(), TenantGovernanceAggregateResolver::VARIANT_TENANT_GOVERNANCE_SUMMARY, ))->toBe(1) ->and($store->countStored( DerivedStateFamily::TenantGovernanceAggregate, - Tenant::class, + ManagedEnvironment::class, (string) $tenantB->getKey(), TenantGovernanceAggregateResolver::VARIANT_TENANT_GOVERNANCE_SUMMARY, ))->toBe(1); diff --git a/apps/platform/tests/Feature/Filament/TenantLifecyclePresentationAcrossTenantSurfacesTest.php b/apps/platform/tests/Feature/Filament/TenantLifecyclePresentationAcrossTenantSurfacesTest.php index 91d36ccf..a524f612 100644 --- a/apps/platform/tests/Feature/Filament/TenantLifecyclePresentationAcrossTenantSurfacesTest.php +++ b/apps/platform/tests/Feature/Filament/TenantLifecyclePresentationAcrossTenantSurfacesTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Resources\TenantResource\Pages\ViewTenant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -24,17 +24,17 @@ 'role' => 'owner', ]); - $active = Tenant::factory()->active()->create([ + $active = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Active Tenant', + 'name' => 'Active ManagedEnvironment', ]); - $onboarding = Tenant::factory()->onboarding()->create([ + $onboarding = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Onboarding Tenant', + 'name' => 'Onboarding ManagedEnvironment', ]); - $archived = Tenant::factory()->archived()->create([ + $archived = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Archived Tenant', + 'name' => 'Archived ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -47,9 +47,9 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]) ->get(route('admin.workspace.managed-tenants.index', ['workspace' => $workspace])) ->assertSuccessful() - ->assertSee('Active Tenant') - ->assertSee('Onboarding Tenant') - ->assertSee('Archived Tenant') + ->assertSee('Active ManagedEnvironment') + ->assertSee('Onboarding ManagedEnvironment') + ->assertSee('Archived ManagedEnvironment') ->assertSee('Active') ->assertSee('Onboarding') ->assertSee('Archived'); @@ -80,6 +80,6 @@ Filament::setTenant($tenant, true); Livewire::test(ViewTenant::class, ['record' => $tenant->getRouteKey()]) - ->assertSee('Tenant archived') + ->assertSee('ManagedEnvironment archived') ->assertSee('This tenant remains available for inspection and audit history, but it is not selectable as active context until you restore it.'); }); diff --git a/apps/platform/tests/Feature/Filament/TenantLifecycleStatusDomainSeparationTest.php b/apps/platform/tests/Feature/Filament/TenantLifecycleStatusDomainSeparationTest.php index fe17798f..4c06bf54 100644 --- a/apps/platform/tests/Feature/Filament/TenantLifecycleStatusDomainSeparationTest.php +++ b/apps/platform/tests/Feature/Filament/TenantLifecycleStatusDomainSeparationTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\TenantResource\Pages\ViewTenant; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\Workspaces\WorkspaceContext; @@ -16,11 +16,11 @@ it('keeps lifecycle and rbac status separated while removing app status from the tenant view page', function (): void { [$user, $tenant] = createUserWithTenant( - tenant: Tenant::factory()->create([ - 'status' => Tenant::STATUS_ONBOARDING, + tenant: ManagedEnvironment::factory()->create([ + 'status' => ManagedEnvironment::STATUS_ONBOARDING, 'app_status' => 'consent_required', 'rbac_status' => 'failed', - 'name' => 'Separated Status Tenant', + 'name' => 'Separated Status ManagedEnvironment', ]), role: 'owner', ); @@ -41,16 +41,16 @@ }); it('keeps referenced tenant lifecycle context separate from run status in the tenantless operations viewer', function (): void { - expect(array_key_exists('app_status', Tenant::factory()->onboarding()->raw()))->toBeFalse(); + expect(array_key_exists('app_status', ManagedEnvironment::factory()->onboarding()->raw()))->toBeFalse(); - $tenant = Tenant::factory()->onboarding()->create([ - 'name' => 'Viewer Separation Tenant', + $tenant = ManagedEnvironment::factory()->onboarding()->create([ + 'name' => 'Viewer Separation ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -65,8 +65,8 @@ ->assertSee('Execution state') ->assertSee('Operation finished') ->assertSee('Outcome') - ->assertSee('Tenant lifecycle') + ->assertSee('ManagedEnvironment lifecycle') ->assertSee('Onboarding') - ->assertSee('Tenant selector context') + ->assertSee('ManagedEnvironment selector context') ->assertSee('This tenant is currently onboarding and may not appear in the tenant selector.'); }); diff --git a/apps/platform/tests/Feature/Filament/TenantMakeCurrentTest.php b/apps/platform/tests/Feature/Filament/TenantMakeCurrentTest.php index d072eaa3..db74b041 100644 --- a/apps/platform/tests/Feature/Filament/TenantMakeCurrentTest.php +++ b/apps/platform/tests/Feature/Filament/TenantMakeCurrentTest.php @@ -2,7 +2,7 @@ use App\Filament\Pages\ChooseTenant; use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\UserTenantPreference; use App\Support\Workspaces\WorkspaceContext; @@ -13,11 +13,11 @@ uses(RefreshDatabase::class); test('choosing a tenant persists last used tenant preference', function () { - $first = Tenant::factory()->create([ + $first = ManagedEnvironment::factory()->create([ 'status' => 'active', ]); - $second = Tenant::factory()->create([ + $second = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $first->workspace_id, 'status' => 'active', ]); @@ -39,7 +39,7 @@ $preference = UserTenantPreference::query() ->where('user_id', $user->getKey()) - ->where('tenant_id', $second->getKey()) + ->where('managed_environment_id', $second->getKey()) ->first(); expect($preference)->not->toBeNull(); diff --git a/apps/platform/tests/Feature/Filament/TenantMembersTest.php b/apps/platform/tests/Feature/Filament/TenantMembersTest.php index 5f7da440..01df9849 100644 --- a/apps/platform/tests/Feature/Filament/TenantMembersTest.php +++ b/apps/platform/tests/Feature/Filament/TenantMembersTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\TenantResource\Pages\ViewTenant; use App\Filament\Resources\TenantResource\RelationManagers\TenantMembershipsRelationManager; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use Livewire\Livewire; @@ -25,8 +25,8 @@ 'role' => 'readonly', ]); - $membership = TenantMembership::query() - ->where('tenant_id', $tenant->getKey()) + $membership = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', $tenant->getKey()) ->where('user_id', $member->getKey()) ->first(); @@ -51,7 +51,7 @@ ]) ->callTableAction('remove', $membership); - expect(TenantMembership::query()->whereKey($membership?->getKey())->exists())->toBeFalse(); + expect(ManagedEnvironmentMembership::query()->whereKey($membership?->getKey())->exists())->toBeFalse(); }); it('hides membership management actions from non-owners', function (): void { @@ -64,8 +64,8 @@ $tenant->getKey() => ['role' => 'readonly'], ]); - $membership = TenantMembership::query() - ->where('tenant_id', $tenant->getKey()) + $membership = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', $tenant->getKey()) ->where('user_id', $member->getKey()) ->firstOrFail(); @@ -87,8 +87,8 @@ $tenant->makeCurrent(); - $ownerMembership = TenantMembership::query() - ->where('tenant_id', $tenant->getKey()) + $ownerMembership = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', $tenant->getKey()) ->where('user_id', $owner->getKey()) ->firstOrFail(); @@ -110,5 +110,5 @@ ]) ->callTableAction('remove', $ownerMembership); - expect(TenantMembership::query()->whereKey($ownerMembership->getKey())->exists())->toBeTrue(); + expect(ManagedEnvironmentMembership::query()->whereKey($ownerMembership->getKey())->exists())->toBeTrue(); }); diff --git a/apps/platform/tests/Feature/Filament/TenantOwnedResourceScopeParityTest.php b/apps/platform/tests/Feature/Filament/TenantOwnedResourceScopeParityTest.php index fc1293f1..ce594a03 100644 --- a/apps/platform/tests/Feature/Filament/TenantOwnedResourceScopeParityTest.php +++ b/apps/platform/tests/Feature/Filament/TenantOwnedResourceScopeParityTest.php @@ -26,7 +26,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -34,7 +34,7 @@ uses(RefreshDatabase::class); -function tenantOwnedAdminSession(Tenant $tenant): array +function tenantOwnedAdminSession(ManagedEnvironment $tenant): array { return [ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, @@ -47,13 +47,13 @@ function tenantOwnedAdminSession(Tenant $tenant): array dataset('tenant-owned-list-pages', [ 'policy list' => [ ListPolicies::class, - static fn (Tenant $tenant, string $label): Policy => Policy::factory()->for($tenant)->create([ + static fn (ManagedEnvironment $tenant, string $label): Policy => Policy::factory()->for($tenant)->create([ 'display_name' => $label, ]), ], 'policy-version list' => [ ListPolicyVersions::class, - static function (Tenant $tenant, string $label): PolicyVersion { + static function (ManagedEnvironment $tenant, string $label): PolicyVersion { $policy = Policy::factory()->for($tenant)->create([ 'display_name' => $label.' policy', ]); @@ -65,9 +65,9 @@ static function (Tenant $tenant, string $label): PolicyVersion { ], 'backup-schedule list' => [ ListBackupSchedules::class, - static function (Tenant $tenant, string $label): BackupSchedule { + static function (ManagedEnvironment $tenant, string $label): BackupSchedule { return BackupSchedule::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => $label, 'is_enabled' => true, 'timezone' => 'UTC', @@ -83,13 +83,13 @@ static function (Tenant $tenant, string $label): BackupSchedule { ], 'backup-set list' => [ ListBackupSets::class, - static fn (Tenant $tenant, string $label): BackupSet => BackupSet::factory()->for($tenant)->create([ + static fn (ManagedEnvironment $tenant, string $label): BackupSet => BackupSet::factory()->for($tenant)->create([ 'name' => $label, ]), ], 'restore-run list' => [ ListRestoreRuns::class, - static function (Tenant $tenant, string $label): RestoreRun { + static function (ManagedEnvironment $tenant, string $label): RestoreRun { $backupSet = BackupSet::factory()->for($tenant)->create([ 'name' => $label.' backup set', ]); @@ -99,18 +99,18 @@ static function (Tenant $tenant, string $label): RestoreRun { ], 'inventory-item list' => [ ListInventoryItems::class, - static fn (Tenant $tenant, string $label): InventoryItem => InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + static fn (ManagedEnvironment $tenant, string $label): InventoryItem => InventoryItem::factory()->create([ + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => $label, ]), ], 'finding list' => [ ListFindings::class, - static fn (Tenant $tenant, string $label): Finding => Finding::factory()->for($tenant)->create(), + static fn (ManagedEnvironment $tenant, string $label): Finding => Finding::factory()->for($tenant)->create(), ], 'entra-group list' => [ ListEntraGroups::class, - static fn (Tenant $tenant, string $label): EntraGroup => EntraGroup::factory()->for($tenant)->create([ + static fn (ManagedEnvironment $tenant, string $label): EntraGroup => EntraGroup::factory()->for($tenant)->create([ 'display_name' => $label, ]), ], @@ -120,14 +120,14 @@ static function (Tenant $tenant, string $label): RestoreRun { 'policy view' => [ PolicyResource::class, 'view', - static fn (Tenant $tenant, string $label): Policy => Policy::factory()->for($tenant)->create([ + static fn (ManagedEnvironment $tenant, string $label): Policy => Policy::factory()->for($tenant)->create([ 'display_name' => $label, ]), ], 'policy-version view' => [ PolicyVersionResource::class, 'view', - static function (Tenant $tenant, string $label): PolicyVersion { + static function (ManagedEnvironment $tenant, string $label): PolicyVersion { $policy = Policy::factory()->for($tenant)->create([ 'display_name' => $label.' policy', ]); @@ -140,14 +140,14 @@ static function (Tenant $tenant, string $label): PolicyVersion { 'backup-set view' => [ BackupSetResource::class, 'view', - static fn (Tenant $tenant, string $label): BackupSet => BackupSet::factory()->for($tenant)->create([ + static fn (ManagedEnvironment $tenant, string $label): BackupSet => BackupSet::factory()->for($tenant)->create([ 'name' => $label, ]), ], 'restore-run view' => [ RestoreRunResource::class, 'view', - static function (Tenant $tenant, string $label): RestoreRun { + static function (ManagedEnvironment $tenant, string $label): RestoreRun { $backupSet = BackupSet::factory()->for($tenant)->create([ 'name' => $label.' backup set', ]); @@ -158,21 +158,21 @@ static function (Tenant $tenant, string $label): RestoreRun { 'finding view' => [ FindingResource::class, 'view', - static fn (Tenant $tenant, string $label): Finding => Finding::factory()->for($tenant)->create(), + static fn (ManagedEnvironment $tenant, string $label): Finding => Finding::factory()->for($tenant)->create(), ], 'entra-group view' => [ EntraGroupResource::class, 'view', - static fn (Tenant $tenant, string $label): EntraGroup => EntraGroup::factory()->for($tenant)->create([ + static fn (ManagedEnvironment $tenant, string $label): EntraGroup => EntraGroup::factory()->for($tenant)->create([ 'display_name' => $label, ]), ], 'backup-schedule edit' => [ BackupScheduleResource::class, 'edit', - static function (Tenant $tenant, string $label): BackupSchedule { + static function (ManagedEnvironment $tenant, string $label): BackupSchedule { return BackupSchedule::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => $label, 'is_enabled' => true, 'timezone' => 'UTC', @@ -189,9 +189,9 @@ static function (Tenant $tenant, string $label): BackupSchedule { ]); it('scopes covered tenant-owned admin lists to the remembered canonical tenant', function (string $pageClass, Closure $makeRecord): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $allowed = $makeRecord($tenantA, 'Allowed record'); @@ -213,9 +213,9 @@ static function (Tenant $tenant, string $label): BackupSchedule { })->with('tenant-owned-list-pages'); it('returns not found for covered tenant-owned admin detail pages outside the remembered canonical tenant', function (string $resourceClass, string $page, Closure $makeRecord): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $allowed = $makeRecord($tenantA, 'Allowed record'); @@ -238,18 +238,18 @@ static function (Tenant $tenant, string $label): BackupSchedule { })->with('tenant-owned-detail-pages'); it('returns not found for admin inventory item detail pages outside the explicit tenant query scope', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $allowed = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'display_name' => 'Allowed inventory item', ]); $blocked = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'display_name' => 'Blocked inventory item', ]); diff --git a/apps/platform/tests/Feature/Filament/TenantPortfolioContextSwitchTest.php b/apps/platform/tests/Feature/Filament/TenantPortfolioContextSwitchTest.php index f5b5029e..22dea740 100644 --- a/apps/platform/tests/Feature/Filament/TenantPortfolioContextSwitchTest.php +++ b/apps/platform/tests/Feature/Filament/TenantPortfolioContextSwitchTest.php @@ -2,7 +2,7 @@ use App\Filament\Resources\TenantResource\Pages\ListTenants; use App\Jobs\BulkTenantSyncJob; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\UiTooltips; use Filament\Events\TenantSet; use Filament\Facades\Filament; @@ -19,7 +19,7 @@ test('tenant-scoped pages return 404 for unauthorized tenant', function () { [$user, $authorizedTenant] = createUserWithTenant(); - $unauthorizedTenant = Tenant::factory()->create(); + $unauthorizedTenant = ManagedEnvironment::factory()->create(); $this->actingAs($user) ->get(route('filament.tenant.resources.policies.index', filamentTenantRouteParams($unauthorizedTenant))) @@ -27,8 +27,8 @@ }); test('tenant portfolio tenant view returns 404 for non-member tenant record', function () { - $authorizedTenant = Tenant::factory()->create(['tenant_id' => 'tenant-portfolio-authorized-view']); - $unauthorizedTenant = Tenant::factory()->create(['tenant_id' => 'tenant-portfolio-unauthorized-view']); + $authorizedTenant = ManagedEnvironment::factory()->create(['managed_environment_id' => 'tenant-portfolio-authorized-view']); + $unauthorizedTenant = ManagedEnvironment::factory()->create(['managed_environment_id' => 'tenant-portfolio-unauthorized-view']); [$user, $authorizedTenant] = createUserWithTenant($authorizedTenant, role: 'owner'); $this->actingAs($user); @@ -40,8 +40,8 @@ }); test('tenant portfolio tenant edit returns 404 for non-member tenant record', function () { - $authorizedTenant = Tenant::factory()->create(['tenant_id' => 'tenant-portfolio-authorized-edit']); - $unauthorizedTenant = Tenant::factory()->create(['tenant_id' => 'tenant-portfolio-unauthorized-edit']); + $authorizedTenant = ManagedEnvironment::factory()->create(['managed_environment_id' => 'tenant-portfolio-authorized-edit']); + $unauthorizedTenant = ManagedEnvironment::factory()->create(['managed_environment_id' => 'tenant-portfolio-unauthorized-edit']); [$user, $authorizedTenant] = createUserWithTenant($authorizedTenant, role: 'owner'); $this->actingAs($user); @@ -53,14 +53,14 @@ }); test('tenant portfolio lists only tenants the user can access', function () { - $authorizedTenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-portfolio-authorized', - 'name' => 'Authorized Tenant', + $authorizedTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-portfolio-authorized', + 'name' => 'Authorized ManagedEnvironment', ]); - $unauthorizedTenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-portfolio-unauthorized', - 'name' => 'Unauthorized Tenant', + $unauthorizedTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-portfolio-unauthorized', + 'name' => 'Unauthorized ManagedEnvironment', ]); [$user, $authorizedTenant] = createUserWithTenant($authorizedTenant, role: 'owner'); @@ -75,12 +75,12 @@ test('tenant portfolio bulk sync dispatches one job per eligible tenant', function () { Bus::fake(); - $tenantA = Tenant::factory()->create(['tenant_id' => 'tenant-bulk-a']); + $tenantA = ManagedEnvironment::factory()->create(['managed_environment_id' => 'tenant-bulk-a']); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); $this->actingAs($user); - $tenantB = Tenant::factory()->create([ - 'tenant_id' => 'tenant-bulk-b', + $tenantB = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-bulk-b', 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -97,7 +97,7 @@ Bus::assertDispatchedTimes(BulkTenantSyncJob::class, 1); $this->assertDatabaseHas('operation_runs', [ - 'tenant_id' => $tenantA->id, + 'managed_environment_id' => $tenantA->id, 'user_id' => $user->id, 'type' => 'tenant.sync', 'status' => 'queued', @@ -107,7 +107,7 @@ test('tenant portfolio bulk sync is disabled for readonly users', function () { Bus::fake(); - $tenant = Tenant::factory()->create(['tenant_id' => 'tenant-bulk-readonly']); + $tenant = ManagedEnvironment::factory()->create(['managed_environment_id' => 'tenant-bulk-readonly']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly'); $this->actingAs($user); @@ -130,12 +130,12 @@ test('tenant portfolio bulk sync is disabled when selection includes unauthorized tenants', function () { Bus::fake(); - $tenantA = Tenant::factory()->create(['tenant_id' => 'tenant-bulk-mixed-a']); + $tenantA = ManagedEnvironment::factory()->create(['managed_environment_id' => 'tenant-bulk-mixed-a']); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); $this->actingAs($user); - $tenantB = Tenant::factory()->create([ - 'tenant_id' => 'tenant-bulk-mixed-b', + $tenantB = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-bulk-mixed-b', 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -164,8 +164,8 @@ TenantSet::dispatch($tenant, $user); - $this->assertDatabaseHas('user_tenant_preferences', [ + $this->assertDatabaseHas('user_managed_environment_preferences', [ 'user_id' => $user->id, - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); }); diff --git a/apps/platform/tests/Feature/Filament/TenantRbacWizardTest.php b/apps/platform/tests/Feature/Filament/TenantRbacWizardTest.php index a3893284..08aeac54 100644 --- a/apps/platform/tests/Feature/Filament/TenantRbacWizardTest.php +++ b/apps/platform/tests/Feature/Filament/TenantRbacWizardTest.php @@ -4,7 +4,7 @@ use App\Http\Controllers\RbacDelegatedAuthController; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Support\Providers\ProviderConnectionType; @@ -22,18 +22,18 @@ config()->set('tenantpilot.features.conditional_access', false); }); -function tenantWithApp(): Tenant +function tenantWithApp(): ManagedEnvironment { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-guid', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-guid', + 'name' => 'ManagedEnvironment One', 'app_client_id' => 'client-123', 'app_client_secret' => 'secret', 'status' => 'active', ]); $connection = ProviderConnection::factory()->dedicated()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'is_enabled' => true, diff --git a/apps/platform/tests/Feature/Filament/TenantRegistryArrivalContextTest.php b/apps/platform/tests/Feature/Filament/TenantRegistryArrivalContextTest.php index b7980602..e0599cd6 100644 --- a/apps/platform/tests/Feature/Filament/TenantRegistryArrivalContextTest.php +++ b/apps/platform/tests/Feature/Filament/TenantRegistryArrivalContextTest.php @@ -20,8 +20,8 @@ function tenantRegistryArrivalStateFromUrl(string $url): ?array } it('adds arrival context and bounded return state to triage-driven tenant opens', function (): void { - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Tenant'); - $weakenedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Weakened Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor ManagedEnvironment'); + $weakenedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Weakened ManagedEnvironment'); $backupSet = $this->seedPortfolioBackupConcern($weakenedTenant, TenantBackupHealthAssessment::POSTURE_STALE); $this->seedPortfolioRecoveryConcern($weakenedTenant, RestoreResultAttention::STATE_COMPLETED_WITH_FOLLOW_UP, $backupSet); @@ -54,7 +54,7 @@ function tenantRegistryArrivalStateFromUrl(string $url): ?array }); it('keeps generic registry opens free of arrival context when triage intent is not active', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Generic Registry Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Generic Registry ManagedEnvironment'); $expectedUrl = TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant); @@ -69,7 +69,7 @@ function tenantRegistryArrivalStateFromUrl(string $url): ?array it('chooses the leading visible concern when worst-first triage is active without explicit family filters', function (): void { [$user, $anchorTenant] = $this->makePortfolioTriageActor('Worst First Anchor'); - $priorityTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Priority Tenant'); + $priorityTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Priority ManagedEnvironment'); $this->seedPortfolioBackupConcern($priorityTenant, TenantBackupHealthAssessment::POSTURE_STALE); $this->seedPortfolioRecoveryConcern($priorityTenant, RestoreResultAttention::STATE_PARTIAL); diff --git a/apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php b/apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php index d24f7fdb..11585f04 100644 --- a/apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php +++ b/apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\TenantResource; use App\Filament\Resources\TenantResource\Pages\ListTenants; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\BackupHealth\BackupFreshnessEvaluation; use App\Support\BackupHealth\BackupScheduleFollowUpEvaluation; @@ -27,9 +27,9 @@ CarbonImmutable::setTestNow(); }); -function tenantRegistryBaseContext(string $anchorName = 'Anchor Tenant'): array +function tenantRegistryBaseContext(string $anchorName = 'Anchor ManagedEnvironment'): array { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'name' => $anchorName, ]); @@ -43,9 +43,9 @@ function tenantRegistryBaseContext(string $anchorName = 'Anchor Tenant'): array return [$user, $tenant]; } -function tenantRegistryPeer(User $user, Tenant $workspaceTenant, string $name): Tenant +function tenantRegistryPeer(User $user, ManagedEnvironment $workspaceTenant, string $name): ManagedEnvironment { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $workspaceTenant->workspace_id, 'name' => $name, @@ -61,7 +61,7 @@ function tenantRegistryPeer(User $user, Tenant $workspaceTenant, string $name): return $tenant; } -function tenantRegistryList(Tenant $workspaceTenant, User $user, array $query = []) +function tenantRegistryList(ManagedEnvironment $workspaceTenant, User $user, array $query = []) { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspaceTenant->workspace_id); @@ -122,7 +122,7 @@ function tenantRegistryRecoveryEvidence( return [ 'overview_state' => $overviewState, 'summary' => $summary, - 'claim_boundary' => 'Tenant-wide recovery is not proven.', + 'claim_boundary' => 'ManagedEnvironment-wide recovery is not proven.', 'reason' => $reason, 'latest_relevant_restore_run' => null, 'latest_relevant_attention' => null, @@ -133,17 +133,17 @@ function tenantRegistryRecoveryEvidence( it('shows separate backup posture and recovery evidence signals without turning metadata into recovery truth', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - [$user, $absentTenant] = tenantRegistryBaseContext('Absent Backup Tenant'); + [$user, $absentTenant] = tenantRegistryBaseContext('Absent Backup ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($absentTenant); - $weakenedTenant = tenantRegistryPeer($user, $absentTenant, 'Weakened Recovery Tenant'); + $weakenedTenant = tenantRegistryPeer($user, $absentTenant, 'Weakened Recovery ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($weakenedTenant); $weakenedBackup = workspaceOverviewSeedHealthyBackup($weakenedTenant, [ 'completed_at' => now()->subMinutes(20), ]); workspaceOverviewSeedRestoreHistory($weakenedTenant, $weakenedBackup, 'follow_up'); - $metadataTenant = tenantRegistryPeer($user, $absentTenant, 'Metadata Drift Tenant'); + $metadataTenant = tenantRegistryPeer($user, $absentTenant, 'Metadata Drift ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($metadataTenant); $metadataBackup = workspaceOverviewSeedHealthyBackup($metadataTenant, [ 'completed_at' => now()->subMinutes(15), @@ -176,14 +176,14 @@ function tenantRegistryRecoveryEvidence( it('filters the registry to exact backup and recovery posture slices', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - [$user, $calmTenant] = tenantRegistryBaseContext('Calm Tenant'); + [$user, $calmTenant] = tenantRegistryBaseContext('Calm ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($calmTenant); $calmBackup = workspaceOverviewSeedHealthyBackup($calmTenant, [ 'completed_at' => now()->subMinutes(10), ]); workspaceOverviewSeedRestoreHistory($calmTenant, $calmBackup, 'completed'); - $degradedTenant = tenantRegistryPeer($user, $calmTenant, 'Degraded Backup Tenant'); + $degradedTenant = tenantRegistryPeer($user, $calmTenant, 'Degraded Backup ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($degradedTenant); $degradedBackup = workspaceOverviewSeedHealthyBackup($degradedTenant, [ 'completed_at' => now()->subMinutes(12), @@ -198,7 +198,7 @@ function tenantRegistryRecoveryEvidence( ]); workspaceOverviewSeedRestoreHistory($degradedTenant, $degradedBackup, 'completed'); - $unvalidatedTenant = tenantRegistryPeer($user, $calmTenant, 'Unvalidated Recovery Tenant'); + $unvalidatedTenant = tenantRegistryPeer($user, $calmTenant, 'Unvalidated Recovery ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($unvalidatedTenant); workspaceOverviewSeedHealthyBackup($unvalidatedTenant, [ 'completed_at' => now()->subMinutes(11), @@ -217,15 +217,15 @@ function tenantRegistryRecoveryEvidence( $backupFiltered = tenantRegistryList($calmTenant, $user) ->filterTable('backup_posture', [TenantBackupHealthAssessment::POSTURE_DEGRADED]); - expect($backupFiltered->instance()->getFilteredTableQuery()?->pluck('tenants.name')->all()) - ->toBe(['Degraded Backup Tenant']); + expect($backupFiltered->instance()->getFilteredTableQuery()?->pluck('managed_environments.name')->all()) + ->toBe(['Degraded Backup ManagedEnvironment']); $recoveryFiltered = tenantRegistryList($calmTenant, $user) ->filterTable('recovery_evidence', ['unvalidated']) ->assertSet('tableFilters.recovery_evidence.values', ['unvalidated']); - expect($recoveryFiltered->instance()->getFilteredTableQuery()?->pluck('tenants.name')->all()) - ->toBe(['Unvalidated Recovery Tenant']) + expect($recoveryFiltered->instance()->getFilteredTableQuery()?->pluck('managed_environments.name')->all()) + ->toBe(['Unvalidated Recovery ManagedEnvironment']) ->and($recoveryFiltered->instance()->getTable()->getRecordUrl($unvalidatedTenant)) ->toBe(TenantResource::getUrl('view', ['record' => $unvalidatedTenant], panel: 'admin')); }); @@ -233,37 +233,37 @@ function tenantRegistryRecoveryEvidence( it('orders the visible tenant registry worst-first with stable tenant-name tie breaks when triage sorting is requested', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - [$user, $absentTenant] = tenantRegistryBaseContext('Absent Backup Tenant'); + [$user, $absentTenant] = tenantRegistryBaseContext('Absent Backup ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($absentTenant); - $alphaWeakenedTenant = tenantRegistryPeer($user, $absentTenant, 'Alpha Weakened Tenant'); + $alphaWeakenedTenant = tenantRegistryPeer($user, $absentTenant, 'Alpha Weakened ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($alphaWeakenedTenant); $alphaWeakenedBackup = workspaceOverviewSeedHealthyBackup($alphaWeakenedTenant, [ 'completed_at' => now()->subMinutes(20), ]); workspaceOverviewSeedRestoreHistory($alphaWeakenedTenant, $alphaWeakenedBackup, 'follow_up'); - $zetaWeakenedTenant = tenantRegistryPeer($user, $absentTenant, 'Zeta Weakened Tenant'); + $zetaWeakenedTenant = tenantRegistryPeer($user, $absentTenant, 'Zeta Weakened ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($zetaWeakenedTenant); $zetaWeakenedBackup = workspaceOverviewSeedHealthyBackup($zetaWeakenedTenant, [ 'completed_at' => now()->subMinutes(21), ]); workspaceOverviewSeedRestoreHistory($zetaWeakenedTenant, $zetaWeakenedBackup, 'failed'); - $staleTenant = tenantRegistryPeer($user, $absentTenant, 'Stale Backup Tenant'); + $staleTenant = tenantRegistryPeer($user, $absentTenant, 'Stale Backup ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($staleTenant); $staleBackup = workspaceOverviewSeedHealthyBackup($staleTenant, [ 'completed_at' => now()->subDays(2), ]); workspaceOverviewSeedRestoreHistory($staleTenant, $staleBackup, 'completed'); - $unvalidatedTenant = tenantRegistryPeer($user, $absentTenant, 'Unvalidated Recovery Tenant'); + $unvalidatedTenant = tenantRegistryPeer($user, $absentTenant, 'Unvalidated Recovery ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($unvalidatedTenant); workspaceOverviewSeedHealthyBackup($unvalidatedTenant, [ 'completed_at' => now()->subMinutes(18), ]); - $degradedTenant = tenantRegistryPeer($user, $absentTenant, 'Degraded Backup Tenant'); + $degradedTenant = tenantRegistryPeer($user, $absentTenant, 'Degraded Backup ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($degradedTenant); $degradedBackup = workspaceOverviewSeedHealthyBackup($degradedTenant, [ 'completed_at' => now()->subMinutes(17), @@ -278,7 +278,7 @@ function tenantRegistryRecoveryEvidence( ]); workspaceOverviewSeedRestoreHistory($degradedTenant, $degradedBackup, 'completed'); - $calmTenant = tenantRegistryPeer($user, $absentTenant, 'Calm Tenant'); + $calmTenant = tenantRegistryPeer($user, $absentTenant, 'Calm ManagedEnvironment'); workspaceOverviewSeedQuietTenantTruth($calmTenant); $calmBackup = workspaceOverviewSeedHealthyBackup($calmTenant, [ 'completed_at' => now()->subMinutes(14), @@ -301,8 +301,8 @@ function tenantRegistryRecoveryEvidence( }); it('loads backup posture and recovery evidence with one batch per registry render instead of per-row fanout', function (): void { - [$user, $firstTenant] = tenantRegistryBaseContext('Batch Tenant Alpha'); - $secondTenant = tenantRegistryPeer($user, $firstTenant, 'Batch Tenant Beta'); + [$user, $firstTenant] = tenantRegistryBaseContext('Batch ManagedEnvironment Alpha'); + $secondTenant = tenantRegistryPeer($user, $firstTenant, 'Batch ManagedEnvironment Beta'); $backupAssessments = [ (int) $firstTenant->getKey() => tenantRegistryBackupAssessment( diff --git a/apps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.php b/apps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.php index 62b52994..11e39c60 100644 --- a/apps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.php +++ b/apps/platform/tests/Feature/Filament/TenantRegistryTriageReviewStateTest.php @@ -7,7 +7,7 @@ use App\Models\AuditLog; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Support\Audit\AuditActionId; use App\Support\BackupHealth\TenantBackupHealthAssessment; @@ -29,13 +29,13 @@ it('renders review-state badges and all four review-state filters for the current backup slice', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 10, 8, 0, 0, 'UTC')); - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Backup Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Backup ManagedEnvironment'); - $reviewedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Reviewed Backup Tenant'); - $followUpTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Follow-up Backup Tenant'); - $changedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Changed Backup Tenant'); - $notReviewedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Not Reviewed Backup Tenant'); - $calmTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Calm Backup Tenant'); + $reviewedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Reviewed Backup ManagedEnvironment'); + $followUpTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Follow-up Backup ManagedEnvironment'); + $changedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Changed Backup ManagedEnvironment'); + $notReviewedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Not Reviewed Backup ManagedEnvironment'); + $calmTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Calm Backup ManagedEnvironment'); foreach ([$reviewedTenant, $followUpTenant, $changedTenant, $notReviewedTenant] as $tenant) { $this->seedPortfolioBackupConcern($tenant, TenantBackupHealthAssessment::POSTURE_STALE); @@ -55,7 +55,7 @@ ->assertTableColumnFormattedStateSet('review_state', 'Follow-up needed', $followUpTenant) ->assertTableColumnFormattedStateSet('review_state', 'Changed since review', $changedTenant) ->assertTableColumnFormattedStateSet('review_state', 'Not reviewed', $notReviewedTenant) - ->assertDontSee('Calm Backup Tenant'); + ->assertDontSee('Calm Backup ManagedEnvironment'); $reviewedNames = $this->portfolioTriageRegistryList($user, $anchorTenant, [ 'backup_posture' => [TenantBackupHealthAssessment::POSTURE_STALE], @@ -63,7 +63,7 @@ ->filterTable('review_state', [TenantTriageReview::STATE_REVIEWED]) ->instance() ->getFilteredTableQuery() - ?->pluck('tenants.name') + ?->pluck('managed_environments.name') ->all(); $followUpNames = $this->portfolioTriageRegistryList($user, $anchorTenant, [ @@ -72,7 +72,7 @@ ->filterTable('review_state', [TenantTriageReview::STATE_FOLLOW_UP_NEEDED]) ->instance() ->getFilteredTableQuery() - ?->pluck('tenants.name') + ?->pluck('managed_environments.name') ->all(); $changedNames = $this->portfolioTriageRegistryList($user, $anchorTenant, [ @@ -81,7 +81,7 @@ ->filterTable('review_state', [TenantTriageReview::DERIVED_STATE_CHANGED_SINCE_REVIEW]) ->instance() ->getFilteredTableQuery() - ?->pluck('tenants.name') + ?->pluck('managed_environments.name') ->all(); $notReviewedNames = $this->portfolioTriageRegistryList($user, $anchorTenant, [ @@ -90,18 +90,18 @@ ->filterTable('review_state', [TenantTriageReview::DERIVED_STATE_NOT_REVIEWED]) ->instance() ->getFilteredTableQuery() - ?->pluck('tenants.name') + ?->pluck('managed_environments.name') ->all(); - expect($reviewedNames)->toBe(['Reviewed Backup Tenant']) - ->and($followUpNames)->toBe(['Follow-up Backup Tenant']) - ->and($changedNames)->toBe(['Changed Backup Tenant']) - ->and($notReviewedNames)->toBe(['Not Reviewed Backup Tenant']); + expect($reviewedNames)->toBe(['Reviewed Backup ManagedEnvironment']) + ->and($followUpNames)->toBe(['Follow-up Backup ManagedEnvironment']) + ->and($changedNames)->toBe(['Changed Backup ManagedEnvironment']) + ->and($notReviewedNames)->toBe(['Not Reviewed Backup ManagedEnvironment']); }); it('uses the highest-priority current concern family when the registry slice is mixed', function (): void { - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Mixed Tenant'); - $mixedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Mixed Concern Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Mixed ManagedEnvironment'); + $mixedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Mixed Concern ManagedEnvironment'); $backupSet = $this->seedPortfolioBackupConcern($mixedTenant, TenantBackupHealthAssessment::POSTURE_STALE); $this->seedPortfolioRecoveryConcern($mixedTenant, 'failed', $backupSet); @@ -120,8 +120,8 @@ }); it('keeps review-state mutations in overflow with a preview-confirmed write path', function (): void { - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Action Tenant'); - $actionTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Action Backup Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Action ManagedEnvironment'); + $actionTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Action Backup ManagedEnvironment'); $this->seedPortfolioBackupConcern($actionTenant, TenantBackupHealthAssessment::POSTURE_STALE); $component = $this->portfolioTriageRegistryList($user, $anchorTenant, [ @@ -148,7 +148,7 @@ expect(app(CapabilityResolver::class)->can($user, $actionTenant, Capabilities::TENANT_TRIAGE_REVIEW_MANAGE))->toBeTrue(); expect($action)->not->toBeNull() - ->and($action?->getRecord())->toBeInstanceOf(Tenant::class) + ->and($action?->getRecord())->toBeInstanceOf(ManagedEnvironment::class) ->and((int) $action?->getRecord()?->getKey())->toBe((int) $actionTenant->getKey()) ->and($action?->isDisabled())->toBeFalse() ->and($component->instance()->mountedActionShouldOpenModal($action))->toBeTrue(); @@ -166,29 +166,29 @@ $mountedAction = $component->instance()->getMountedAction(); expect($mountedAction)->not->toBeNull() - ->and($mountedAction?->getRecord())->toBeInstanceOf(Tenant::class) + ->and($mountedAction?->getRecord())->toBeInstanceOf(ManagedEnvironment::class) ->and((int) $mountedAction?->getRecord()?->getKey())->toBe((int) $actionTenant->getKey()); $component ->callMountedAction(); expect(TenantTriageReview::query() - ->where('tenant_id', (int) $actionTenant->getKey()) + ->where('managed_environment_id', (int) $actionTenant->getKey()) ->where('concern_family', PortfolioArrivalContextToken::FAMILY_BACKUP_HEALTH) ->where('current_state', TenantTriageReview::STATE_REVIEWED) ->whereNull('resolved_at') ->exists())->toBeTrue() ->and(AuditLog::query() ->where('workspace_id', (int) $actionTenant->workspace_id) - ->where('tenant_id', (int) $actionTenant->getKey()) + ->where('managed_environment_id', (int) $actionTenant->getKey()) ->where('action', AuditActionId::TenantTriageReviewMarkedReviewed->value) ->exists())->toBeTrue() ->and($component->instance())->toBeInstanceOf(ListTenants::class); }); it('keeps review-state mutations available on the tenant detail header for the current concern', function (): void { - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Detail Action Tenant'); - $actionTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Detail Action Backup Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Detail Action ManagedEnvironment'); + $actionTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Detail Action Backup ManagedEnvironment'); $this->seedPortfolioBackupConcern($actionTenant, TenantBackupHealthAssessment::POSTURE_STALE); $this->actingAs($user); @@ -215,14 +215,14 @@ ->assertHasNoActionErrors(); expect(TenantTriageReview::query() - ->where('tenant_id', (int) $actionTenant->getKey()) + ->where('managed_environment_id', (int) $actionTenant->getKey()) ->where('concern_family', PortfolioArrivalContextToken::FAMILY_BACKUP_HEALTH) ->where('current_state', TenantTriageReview::STATE_REVIEWED) ->whereNull('resolved_at') ->exists())->toBeTrue() ->and(AuditLog::query() ->where('workspace_id', (int) $actionTenant->workspace_id) - ->where('tenant_id', (int) $actionTenant->getKey()) + ->where('managed_environment_id', (int) $actionTenant->getKey()) ->where('action', AuditActionId::TenantTriageReviewMarkedReviewed->value) ->exists())->toBeTrue() ->and($component->instance())->toBeInstanceOf(ViewTenant::class); diff --git a/apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php b/apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php index 1a3e85c1..bb14f0f2 100644 --- a/apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php +++ b/apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\TenantRequiredPermissions; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantPermission; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; @@ -12,7 +12,7 @@ uses(RefreshDatabase::class); -function seedTenantRequiredPermissionsFixture(Tenant $tenant): void +function seedTenantRequiredPermissionsFixture(ManagedEnvironment $tenant): void { config()->set('intune_permissions.permissions', [ [ @@ -37,7 +37,7 @@ function seedTenantRequiredPermissionsFixture(Tenant $tenant): void config()->set('entra_permissions.permissions', []); TenantPermission::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'permission_key' => 'Group.Read.All', 'status' => 'missing', 'details' => ['source' => 'fixture'], @@ -45,7 +45,7 @@ function seedTenantRequiredPermissionsFixture(Tenant $tenant): void ]); TenantPermission::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'permission_key' => 'Reports.Read.All', 'status' => 'granted', 'details' => ['source' => 'fixture'], @@ -53,7 +53,7 @@ function seedTenantRequiredPermissionsFixture(Tenant $tenant): void ]); } -function tenantRequiredPermissionsComponent(User $user, Tenant $tenant, array $query = []) +function tenantRequiredPermissionsComponent(User $user, ManagedEnvironment $tenant, array $query = []) { test()->actingAs($user); setAdminPanelContext(); diff --git a/apps/platform/tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php b/apps/platform/tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php index 163fcaa6..bb448f54 100644 --- a/apps/platform/tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php +++ b/apps/platform/tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php @@ -3,8 +3,8 @@ declare(strict_types=1); use App\Filament\Resources\TenantResource\Pages\ListTenants; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -34,24 +34,24 @@ 'role' => 'owner', ]); - $tenantA = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspaceA->getKey(), 'external_id' => '11111111-1111-1111-1111-111111111111', - 'tenant_id' => '11111111-1111-1111-1111-111111111111', - 'name' => 'Tenant A', + 'managed_environment_id' => '11111111-1111-1111-1111-111111111111', + 'name' => 'ManagedEnvironment A', 'status' => 'active', ]); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspaceB->getKey(), 'external_id' => '22222222-2222-2222-2222-222222222222', - 'tenant_id' => '22222222-2222-2222-2222-222222222222', - 'name' => 'Tenant B', + 'managed_environment_id' => '22222222-2222-2222-2222-222222222222', + 'name' => 'ManagedEnvironment B', 'status' => 'active', ]); - TenantMembership::query()->create([ - 'tenant_id' => $tenantA->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenantA->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', @@ -59,8 +59,8 @@ 'created_by_user_id' => null, ]); - TenantMembership::query()->create([ - 'tenant_id' => $tenantB->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenantB->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', @@ -72,8 +72,8 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspaceA->getKey()]) ->get(route('filament.admin.resources.tenants.index', filamentTenantRouteParams($tenantA))) ->assertOk() - ->assertSee('Tenant A') - ->assertDontSee('Tenant B'); + ->assertSee('ManagedEnvironment A') + ->assertDontSee('ManagedEnvironment B'); }); it('keeps tenant list defaults calm and persists list state in-session', function (): void { @@ -85,7 +85,7 @@ $component = Livewire::actingAs($user) ->test(\App\Filament\Resources\TenantResource\Pages\ListTenants::class) ->assertTableEmptyStateActionsExistInOrder(['add_tenant']) - ->searchTable('Tenant') + ->searchTable('ManagedEnvironment') ->call('sortTable', 'name', 'desc') ->set('tableFilters.environment.value', 'prod'); @@ -95,41 +95,41 @@ expect($table->getEmptyStateHeading())->toBe('No tenants connected'); expect($table->getColumn('name')?->isSearchable())->toBeTrue(); expect($table->getColumn('name')?->isSortable())->toBeTrue(); - expect($table->getColumn('tenant_id')?->isToggledHiddenByDefault())->toBeTrue(); + expect($table->getColumn('managed_environment_id')?->isToggledHiddenByDefault())->toBeTrue(); expect($table->getColumn('domain')?->isToggledHiddenByDefault())->toBeTrue(); expect(count($table->getVisibleColumns()))->toBeLessThanOrEqual(7); - expect(session()->get($component->instance()->getTableSearchSessionKey()))->toBe('Tenant'); + expect(session()->get($component->instance()->getTableSearchSessionKey()))->toBe('ManagedEnvironment'); expect(session()->get($component->instance()->getTableSortSessionKey()))->toBe('name:desc'); Livewire::actingAs($user) ->test(\App\Filament\Resources\TenantResource\Pages\ListTenants::class) - ->assertSet('tableSearch', 'Tenant') + ->assertSet('tableSearch', 'ManagedEnvironment') ->assertSet('tableSort', 'name:desc') ->assertSet('tableFilters.environment.value', 'prod'); }); it('keeps posture filters scoped to visible workspace tenants only', function (): void { - $visibleTenant = Tenant::factory()->create(['status' => 'active']); + $visibleTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $visibleTenant] = createUserWithTenant($visibleTenant, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($visibleTenant); workspaceOverviewSeedHealthyBackup($visibleTenant, [ 'completed_at' => now()->subMinutes(10), ]); - $hiddenRecoveryTenant = Tenant::factory()->create([ + $hiddenRecoveryTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, - 'name' => 'Hidden Recovery Tenant', + 'name' => 'Hidden Recovery ManagedEnvironment', ]); workspaceOverviewSeedQuietTenantTruth($hiddenRecoveryTenant); workspaceOverviewSeedHealthyBackup($hiddenRecoveryTenant, [ 'completed_at' => now()->subMinutes(9), ]); - $hiddenBackupTenant = Tenant::factory()->create([ + $hiddenBackupTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, - 'name' => 'Hidden Degraded Tenant', + 'name' => 'Hidden Degraded ManagedEnvironment', ]); workspaceOverviewSeedQuietTenantTruth($hiddenBackupTenant); workspaceOverviewSeedHealthyBackup($hiddenBackupTenant, [ @@ -151,13 +151,13 @@ ->test(ListTenants::class) ->filterTable('recovery_evidence', ['unvalidated']); - expect($recoveryFiltered->instance()->getFilteredTableQuery()?->pluck('tenants.name')->all()) + expect($recoveryFiltered->instance()->getFilteredTableQuery()?->pluck('managed_environments.name')->all()) ->toBe([(string) $visibleTenant->name]); $backupFiltered = Livewire::actingAs($user) ->test(ListTenants::class) ->filterTable('backup_posture', [TenantBackupHealthAssessment::POSTURE_DEGRADED]); - expect($backupFiltered->instance()->getFilteredTableQuery()?->pluck('tenants.name')->all()) + expect($backupFiltered->instance()->getFilteredTableQuery()?->pluck('managed_environments.name')->all()) ->toBe([]); }); diff --git a/apps/platform/tests/Feature/Filament/TenantRoleDefinitionsSelectorDbOnlyTest.php b/apps/platform/tests/Feature/Filament/TenantRoleDefinitionsSelectorDbOnlyTest.php index 0bec2e2f..45d5f062 100644 --- a/apps/platform/tests/Feature/Filament/TenantRoleDefinitionsSelectorDbOnlyTest.php +++ b/apps/platform/tests/Feature/Filament/TenantRoleDefinitionsSelectorDbOnlyTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\TenantResource; use App\Models\EntraRoleDefinition; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); @@ -12,8 +12,8 @@ it('searches cached role definitions without Graph calls', function (): void { bindFailHardGraphClient(); - /** @var Tenant $tenant */ - $tenant = Tenant::factory()->create(); + /** @var ManagedEnvironment $tenant */ + $tenant = ManagedEnvironment::factory()->create(); EntraRoleDefinition::factory() ->for($tenant) @@ -32,8 +32,8 @@ it('resolves a role definition label from cached data without Graph calls', function (): void { bindFailHardGraphClient(); - /** @var Tenant $tenant */ - $tenant = Tenant::factory()->create(); + /** @var ManagedEnvironment $tenant */ + $tenant = ManagedEnvironment::factory()->create(); EntraRoleDefinition::factory() ->for($tenant) diff --git a/apps/platform/tests/Feature/Filament/TenantScopingTest.php b/apps/platform/tests/Feature/Filament/TenantScopingTest.php index 8583003e..412b9e37 100644 --- a/apps/platform/tests/Feature/Filament/TenantScopingTest.php +++ b/apps/platform/tests/Feature/Filament/TenantScopingTest.php @@ -4,44 +4,44 @@ use App\Filament\Resources\ProviderConnectionResource; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; it('returns an empty canonical list for unauthorized tenant filters', function (): void { - $tenantA = Tenant::factory()->create(['name' => 'Tenant A']); - $tenantB = Tenant::factory()->create(['name' => 'Tenant B']); + $tenantA = ManagedEnvironment::factory()->create(['name' => 'ManagedEnvironment A']); + $tenantB = ManagedEnvironment::factory()->create(['name' => 'ManagedEnvironment B']); [$user] = createUserWithTenant($tenantA, role: 'owner'); ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, - 'display_name' => 'Tenant A Connection', + 'display_name' => 'ManagedEnvironment A Connection', ]); ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, - 'display_name' => 'Tenant B Connection', + 'display_name' => 'ManagedEnvironment B Connection', ]); $this->actingAs($user) ->get(ProviderConnectionResource::getUrl('index', tenant: $tenantB)) ->assertOk() - ->assertDontSee('Tenant A Connection') - ->assertDontSee('Tenant B Connection'); + ->assertDontSee('ManagedEnvironment A Connection') + ->assertDontSee('ManagedEnvironment B Connection'); }); it('does not show non-member tenants in the choose-tenant list', function (): void { - $tenantA = Tenant::factory()->create(['name' => 'Tenant A']); - $tenantB = Tenant::factory()->create(['name' => 'Tenant B']); + $tenantA = ManagedEnvironment::factory()->create(['name' => 'ManagedEnvironment A']); + $tenantB = ManagedEnvironment::factory()->create(['name' => 'ManagedEnvironment B']); [$user] = createUserWithTenant($tenantA, role: 'owner'); $this->actingAs($user) ->get('/admin/choose-tenant') ->assertOk() - ->assertSee('Tenant A') - ->assertDontSee('Tenant B'); + ->assertSee('ManagedEnvironment A') + ->assertDontSee('ManagedEnvironment B'); }); it('keeps provider connections excluded from global search', function (): void { diff --git a/apps/platform/tests/Feature/Filament/TenantSetupTest.php b/apps/platform/tests/Feature/Filament/TenantSetupTest.php index a8464ee7..0332aff2 100644 --- a/apps/platform/tests/Feature/Filament/TenantSetupTest.php +++ b/apps/platform/tests/Feature/Filament/TenantSetupTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantPermission; use App\Models\User; use App\Support\OperationRunLinks; @@ -24,8 +24,8 @@ $user = User::factory()->create(); $this->actingAs($user); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-guid', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-guid', 'name' => 'Contoso', 'environment' => 'other', 'domain' => 'contoso.com', @@ -35,10 +35,10 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); @@ -56,7 +56,7 @@ ->callAction('verify'); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); @@ -80,7 +80,7 @@ Queue::assertPushed(\App\Jobs\ProviderConnectionHealthCheckJob::class, 1); $this->assertDatabaseMissing('audit_logs', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'action' => 'tenant.config.verified', ]); }); @@ -90,9 +90,9 @@ $user = User::factory()->create(); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-error', - 'name' => 'Error Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-error', + 'name' => 'Error ManagedEnvironment', 'status' => 'active', ]); @@ -101,10 +101,10 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); @@ -113,7 +113,7 @@ ->callAction('verify'); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); @@ -132,9 +132,9 @@ $user = User::factory()->create(); $this->actingAs($user); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-ui', - 'name' => 'UI Tenant', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-ui', + 'name' => 'UI ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant($tenant, $user, role: 'owner'); $this->actingAs($user); @@ -145,7 +145,7 @@ $firstKey = $permissions[0]['key'] ?? 'DeviceManagementConfiguration.ReadWrite.All'; TenantPermission::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'permission_key' => $firstKey, 'status' => 'ok', ]); @@ -163,9 +163,9 @@ $user = User::factory()->create(); $this->actingAs($user); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-ui-list', - 'name' => 'UI Tenant List', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-ui-list', + 'name' => 'UI ManagedEnvironment List', 'app_client_id' => 'client-123', ]); @@ -182,9 +182,9 @@ $user = User::factory()->create(); $this->actingAs($user); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-ui-archive', - 'name' => 'UI Tenant Archive', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-ui-archive', + 'name' => 'UI ManagedEnvironment Archive', ]); [$user, $tenant] = createUserWithTenant($tenant, $user, role: 'owner'); @@ -200,5 +200,5 @@ ->callMountedAction() ->assertHasNoActionErrors(); - $this->assertSoftDeleted('tenants', ['id' => $tenant->id]); + $this->assertSoftDeleted('managed_environments', ['id' => $tenant->id]); }); diff --git a/apps/platform/tests/Feature/Filament/TenantSwitcherUrlResolvesTenantTest.php b/apps/platform/tests/Feature/Filament/TenantSwitcherUrlResolvesTenantTest.php index 08ab387a..6da56501 100644 --- a/apps/platform/tests/Feature/Filament/TenantSwitcherUrlResolvesTenantTest.php +++ b/apps/platform/tests/Feature/Filament/TenantSwitcherUrlResolvesTenantTest.php @@ -2,22 +2,22 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use Filament\Facades\Filament; it('switches tenant when visiting the tenant menu URL', function (): void { $workspace = Workspace::factory()->create(); - $tenantA = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), - 'name' => 'Tenant A', + 'name' => 'ManagedEnvironment A', 'status' => 'active', ]); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), - 'name' => 'Tenant B', + 'name' => 'ManagedEnvironment B', 'status' => 'active', ]); @@ -32,6 +32,6 @@ ->get('/admin/t/'.$tenantB->external_id); expect(in_array($response->getStatusCode(), [200, 302], true))->toBeTrue(); - expect(Filament::getTenant())->toBeInstanceOf(Tenant::class); + expect(Filament::getTenant())->toBeInstanceOf(ManagedEnvironment::class); expect(Filament::getTenant()?->is($tenantB))->toBeTrue(); }); diff --git a/apps/platform/tests/Feature/Filament/TenantTruthCleanupSpec179Test.php b/apps/platform/tests/Feature/Filament/TenantTruthCleanupSpec179Test.php index 346f606c..1b8b6d51 100644 --- a/apps/platform/tests/Feature/Filament/TenantTruthCleanupSpec179Test.php +++ b/apps/platform/tests/Feature/Filament/TenantTruthCleanupSpec179Test.php @@ -5,7 +5,7 @@ use App\Filament\Resources\TenantResource\Pages\ListTenants; use App\Filament\Resources\TenantResource\Pages\ViewTenant; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Providers\ProviderConsentStatus; use App\Support\Providers\ProviderVerificationStatus; use App\Support\Workspaces\WorkspaceContext; @@ -16,8 +16,8 @@ uses(RefreshDatabase::class); it('removes tenant app status from tenant list primary truth and filters', function (): void { - $tenant = Tenant::factory()->active()->create([ - 'name' => 'Primary Truth Tenant', + $tenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Primary Truth ManagedEnvironment', 'app_status' => 'ok', ]); @@ -29,7 +29,7 @@ ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'display_name' => 'Primary Truth Connection', 'is_default' => true, @@ -64,10 +64,10 @@ }); it('keeps legacy app status as opt-in test setup instead of a factory default', function (): void { - expect(array_key_exists('app_status', Tenant::factory()->raw()))->toBeFalse(); + expect(array_key_exists('app_status', ManagedEnvironment::factory()->raw()))->toBeFalse(); - $tenant = Tenant::factory()->create([ - 'name' => 'Explicit Historical App Status Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'Explicit Historical App Status ManagedEnvironment', 'app_status' => 'error', ]); @@ -75,11 +75,11 @@ }); it('keeps lifecycle and rbac separate while leading the provider summary with consent and verification', function (): void { - $tenant = Tenant::factory()->create([ - 'status' => Tenant::STATUS_ONBOARDING, + $tenant = ManagedEnvironment::factory()->create([ + 'status' => ManagedEnvironment::STATUS_ONBOARDING, 'app_status' => 'consent_required', 'rbac_status' => 'failed', - 'name' => 'Truth Cleanup Tenant', + 'name' => 'Truth Cleanup ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant( @@ -90,7 +90,7 @@ ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'display_name' => 'Truth Cleanup Connection', 'is_default' => true, @@ -125,8 +125,8 @@ }); it('flags tenants that have microsoft connections but no default connection configured', function (): void { - $tenant = Tenant::factory()->active()->create([ - 'name' => 'Missing Default Tenant', + $tenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Missing Default ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant( @@ -137,7 +137,7 @@ ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'display_name' => 'Fallback Microsoft Connection', 'is_default' => false, @@ -158,8 +158,8 @@ }); it('does not collapse active lifecycle and blocked provider verification into readiness language', function (): void { - $tenant = Tenant::factory()->active()->create([ - 'name' => 'No False Readiness Tenant', + $tenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'No False Readiness ManagedEnvironment', 'app_status' => 'ok', 'rbac_status' => 'configured', ]); @@ -172,7 +172,7 @@ ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'display_name' => 'Blocked Connection', 'is_default' => true, diff --git a/apps/platform/tests/Feature/Filament/TenantVerificationReportWidgetTest.php b/apps/platform/tests/Feature/Filament/TenantVerificationReportWidgetTest.php index e72cf210..273c7cf9 100644 --- a/apps/platform/tests/Feature/Filament/TenantVerificationReportWidgetTest.php +++ b/apps/platform/tests/Feature/Filament/TenantVerificationReportWidgetTest.php @@ -28,10 +28,10 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); @@ -49,7 +49,7 @@ ->callAction('verify'); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); @@ -93,13 +93,13 @@ OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'blocked', 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ], 'verification_report' => $report, ], @@ -133,7 +133,7 @@ OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => $status, 'outcome' => $outcome, @@ -190,10 +190,10 @@ $this->actingAs($user); $connection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); @@ -212,7 +212,7 @@ ->call('startVerification'); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); @@ -255,10 +255,10 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); @@ -276,7 +276,7 @@ ->callTableAction('verify', $tenant); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Filament/TenantViewHeaderUiEnforcementTest.php b/apps/platform/tests/Feature/Filament/TenantViewHeaderUiEnforcementTest.php index d2f17cf0..bb7b7ee6 100644 --- a/apps/platform/tests/Feature/Filament/TenantViewHeaderUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Filament/TenantViewHeaderUiEnforcementTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\TenantResource; use App\Filament\Resources\TenantResource\Pages\ViewTenant; use App\Models\AuditLog; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Rbac\UiTooltips; use Filament\Actions\Action; use Filament\Facades\Filament; @@ -14,7 +14,7 @@ uses(RefreshDatabase::class); -describe('Tenant View header action UI enforcement', function () { +describe('ManagedEnvironment View header action UI enforcement', function () { it('keeps archive visible in the workflow header and moves edit/provider navigation into contextual unavailable entries for readonly members', function () { [$user, $tenant] = createUserWithTenant(role: 'readonly'); @@ -71,11 +71,11 @@ ->callMountedAction() ->assertSuccessful(); - expect(Tenant::withTrashed()->find($tenant->getKey())?->trashed())->toBeFalse(); + expect(ManagedEnvironment::withTrashed()->find($tenant->getKey())?->trashed())->toBeFalse(); }); it('shows resume onboarding when the tenant has a resumable linked onboarding draft', function () { - $tenant = Tenant::factory()->onboarding()->create(); + $tenant = ManagedEnvironment::factory()->onboarding()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); createOnboardingDraft([ @@ -84,7 +84,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -98,8 +98,8 @@ }); it('shows a cancelled-onboarding label and repairs stale onboarding tenant status when the linked draft was cancelled', function () { - $tenant = Tenant::factory()->onboarding()->create([ - 'name' => 'Cancelled Flow Tenant', + $tenant = ManagedEnvironment::factory()->onboarding()->create([ + 'name' => 'Cancelled Flow ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); @@ -110,7 +110,7 @@ 'updated_by' => $user, 'status' => 'cancelled', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -124,10 +124,10 @@ $tenant->refresh(); - expect($tenant->status)->toBe(Tenant::STATUS_DRAFT); + expect($tenant->status)->toBe(ManagedEnvironment::STATUS_DRAFT); expect(AuditLog::query() ->where('workspace_id', (int) $tenant->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', \App\Support\Audit\AuditActionId::TenantReturnedToDraft->value) ->exists())->toBeTrue(); diff --git a/apps/platform/tests/Feature/Filament/WindowsUpdateProfilesRestoreTest.php b/apps/platform/tests/Feature/Filament/WindowsUpdateProfilesRestoreTest.php index b911c73e..c91ed906 100644 --- a/apps/platform/tests/Feature/Filament/WindowsUpdateProfilesRestoreTest.php +++ b/apps/platform/tests/Feature/Filament/WindowsUpdateProfilesRestoreTest.php @@ -6,7 +6,7 @@ use App\Models\PolicyVersion; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -16,16 +16,16 @@ uses(RefreshDatabase::class); if (! function_exists('makeTenantWithDefaultProviderConnection')) { - function makeTenantWithDefaultProviderConnection(array $attributes = []): Tenant + function makeTenantWithDefaultProviderConnection(array $attributes = []): ManagedEnvironment { - $tenant = Tenant::create(array_merge([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create(array_merge([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ], $attributes)); $connection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', @@ -91,7 +91,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon $tenant = makeTenantWithDefaultProviderConnection(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-feature', 'policy_type' => 'windowsFeatureUpdateProfile', 'display_name' => 'Feature Updates A', @@ -99,7 +99,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, @@ -116,7 +116,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]; $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -166,7 +166,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon $tenant = makeTenantWithDefaultProviderConnection(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-quality', 'policy_type' => 'windowsQualityUpdateProfile', 'display_name' => 'Quality Updates A', @@ -174,7 +174,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, @@ -191,7 +191,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]; $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -241,7 +241,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon $tenant = makeTenantWithDefaultProviderConnection(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-driver', 'policy_type' => 'windowsDriverUpdateProfile', 'display_name' => 'Driver Updates A', @@ -249,7 +249,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, @@ -272,7 +272,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]; $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/Filament/WindowsUpdateRingPolicyTest.php b/apps/platform/tests/Feature/Filament/WindowsUpdateRingPolicyTest.php index ee368b71..6463c373 100644 --- a/apps/platform/tests/Feature/Filament/WindowsUpdateRingPolicyTest.php +++ b/apps/platform/tests/Feature/Filament/WindowsUpdateRingPolicyTest.php @@ -3,16 +3,16 @@ use App\Filament\Resources\PolicyResource; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Carbon\CarbonImmutable; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('policy detail shows normalized settings for windows update ring', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'local-tenant', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'local-tenant', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'is_current' => true, ]); @@ -20,7 +20,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-wuring', 'policy_type' => 'windowsUpdateRing', 'display_name' => 'Windows Update Ring A', @@ -28,7 +28,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, diff --git a/apps/platform/tests/Feature/Filament/WindowsUpdateRingRestoreTest.php b/apps/platform/tests/Feature/Filament/WindowsUpdateRingRestoreTest.php index d0b32695..cd13d01a 100644 --- a/apps/platform/tests/Feature/Filament/WindowsUpdateRingRestoreTest.php +++ b/apps/platform/tests/Feature/Filament/WindowsUpdateRingRestoreTest.php @@ -6,7 +6,7 @@ use App\Models\PolicyVersion; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -16,16 +16,16 @@ uses(RefreshDatabase::class); if (! function_exists('makeTenantWithDefaultProviderConnection')) { - function makeTenantWithDefaultProviderConnection(array $attributes = []): Tenant + function makeTenantWithDefaultProviderConnection(array $attributes = []): ManagedEnvironment { - $tenant = Tenant::create(array_merge([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create(array_merge([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ], $attributes)); $connection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', @@ -95,7 +95,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon $tenant = makeTenantWithDefaultProviderConnection(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-wuring', 'policy_type' => 'windowsUpdateRing', 'display_name' => 'Windows Update Ring A', @@ -103,7 +103,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, @@ -123,7 +123,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ]; $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/Filament/WorkspaceContextRecoveryDisplayTest.php b/apps/platform/tests/Feature/Filament/WorkspaceContextRecoveryDisplayTest.php index d816f3e1..0b1438af 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceContextRecoveryDisplayTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceContextRecoveryDisplayTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -10,7 +10,7 @@ uses(RefreshDatabase::class); it('shows a recovery label when workspace-scoped surfaces render without an active workspace', function (): void { - $tenant = Tenant::factory()->active()->create(['name' => 'Recovery Tenant']); + $tenant = ManagedEnvironment::factory()->active()->create(['name' => 'Recovery ManagedEnvironment']); [$user] = createUserWithTenant(tenant: $tenant, role: 'owner'); session()->forget(WorkspaceContext::SESSION_KEY); @@ -23,10 +23,10 @@ }); it('shows explicit recovery wording when an invalid tenant hint is discarded on a workspace route', function (): void { - $validTenant = Tenant::factory()->active()->create(['name' => 'Valid Workspace Tenant']); + $validTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Valid Workspace ManagedEnvironment']); [$user, $validTenant] = createUserWithTenant(tenant: $validTenant, role: 'owner'); - $foreignTenant = Tenant::factory()->active()->create(['name' => 'Foreign Workspace Tenant']); + $foreignTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Foreign Workspace ManagedEnvironment']); createUserWithTenant(tenant: $foreignTenant, user: User::factory()->create(), role: 'owner'); $this->actingAs($user) @@ -37,5 +37,5 @@ ->assertOk() ->assertSee('Context unavailable') ->assertSee('No tenant selected') - ->assertDontSee('Tenant scope: '.$foreignTenant->name); + ->assertDontSee('ManagedEnvironment scope: '.$foreignTenant->name); }); diff --git a/apps/platform/tests/Feature/Filament/WorkspaceContextTopbarAndTenantSelectionTest.php b/apps/platform/tests/Feature/Filament/WorkspaceContextTopbarAndTenantSelectionTest.php index 13d98a69..634b9d28 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceContextTopbarAndTenantSelectionTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceContextTopbarAndTenantSelectionTest.php @@ -1,6 +1,6 @@ 'owner', ]); - $tenantA = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspaceA->getKey(), 'status' => 'active', ]); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspaceB->getKey(), 'status' => 'active', ]); @@ -66,17 +66,17 @@ }); test('workspace-scoped operations honor a valid tenant query hint over remembered tenant context', function () { - $rememberedTenant = Tenant::factory()->create([ + $rememberedTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => null, 'status' => 'active', - 'name' => 'Remembered Topbar Tenant', + 'name' => 'Remembered Topbar ManagedEnvironment', ]); [$user, $rememberedTenant] = createUserWithTenant(tenant: $rememberedTenant, role: 'owner'); - $hintedTenant = Tenant::factory()->create([ + $hintedTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $rememberedTenant->workspace_id, 'status' => 'active', - 'name' => 'Hinted Topbar Tenant', + 'name' => 'Hinted Topbar ManagedEnvironment', ]); createUserWithTenant(tenant: $hintedTenant, user: $user, role: 'owner'); @@ -94,6 +94,6 @@ ]) ->get(route('admin.operations.index', ['tenant' => $hintedTenant->external_id])) ->assertOk() - ->assertSee('Tenant scope: Hinted Topbar Tenant') - ->assertDontSee('Tenant scope: Remembered Topbar Tenant'); + ->assertSee('ManagedEnvironment scope: Hinted Topbar ManagedEnvironment') + ->assertDontSee('ManagedEnvironment scope: Remembered Topbar ManagedEnvironment'); }); diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOnlySurfaceTenantIndependenceTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOnlySurfaceTenantIndependenceTest.php index a1b8e46e..3e18b2d9 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOnlySurfaceTenantIndependenceTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOnlySurfaceTenantIndependenceTest.php @@ -7,7 +7,7 @@ use App\Filament\Resources\TenantResource; use App\Models\AlertRule; use App\Models\BaselineProfile; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -51,13 +51,13 @@ }); it('keeps workspace-only admin surfaces independent from remembered tenant changes', function (): void { - $tenantA = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create([ 'name' => 'Phoenicon', 'environment' => 'dev', ]); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, 'name' => 'YPTW2', 'environment' => 'dev', diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewArrivalContextTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewArrivalContextTest.php index e1209bd2..b019af76 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewArrivalContextTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewArrivalContextTest.php @@ -18,8 +18,8 @@ function workspaceOverviewArrivalStateFromUrl(string $url): ?array } it('emits bounded arrival tokens for workspace backup and recovery attention drilldowns', function (): void { - [$user, $backupTenant] = $this->makePortfolioTriageActor('Backup Weak Tenant'); - $recoveryTenant = $this->makePortfolioTriagePeer($user, $backupTenant, 'Recovery Weak Tenant'); + [$user, $backupTenant] = $this->makePortfolioTriageActor('Backup Weak ManagedEnvironment'); + $recoveryTenant = $this->makePortfolioTriagePeer($user, $backupTenant, 'Recovery Weak ManagedEnvironment'); $this->seedPortfolioRecoveryConcern($recoveryTenant, RestoreResultAttention::STATE_COMPLETED_WITH_FOLLOW_UP); $workspace = $backupTenant->workspace()->firstOrFail(); @@ -46,12 +46,12 @@ function workspaceOverviewArrivalStateFromUrl(string $url): ?array }); it('emits summary-metric arrival tokens only when the workspace drilldown lands on a single tenant dashboard', function (): void { - [$user, $backupTenant] = $this->makePortfolioTriageActor('Single Backup Tenant'); + [$user, $backupTenant] = $this->makePortfolioTriageActor('Single Backup ManagedEnvironment'); - $recoveryTenantA = $this->makePortfolioTriagePeer($user, $backupTenant, 'Recovery Tenant A'); + $recoveryTenantA = $this->makePortfolioTriagePeer($user, $backupTenant, 'Recovery ManagedEnvironment A'); $this->seedPortfolioRecoveryConcern($recoveryTenantA, RestoreResultAttention::STATE_FAILED); - $recoveryTenantB = $this->makePortfolioTriagePeer($user, $backupTenant, 'Recovery Tenant B'); + $recoveryTenantB = $this->makePortfolioTriagePeer($user, $backupTenant, 'Recovery ManagedEnvironment B'); $this->seedPortfolioRecoveryConcern($recoveryTenantB, RestoreResultAttention::STATE_PARTIAL); $workspace = $backupTenant->workspace()->firstOrFail(); diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php index 4b0cf686..3ab39e57 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\User; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Models\WorkspaceMembership; use App\Services\Auth\CapabilityResolver; @@ -34,7 +34,7 @@ }); it('falls back to workspace-safe operations recovery when only workspace-level activity is actionable', function (): void { - $tenant = \App\Models\Tenant::factory()->create(['status' => 'active']); + $tenant = \App\Models\ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly', workspaceRole: 'readonly'); [$profile, $snapshot] = seedActiveBaselineForTenant($tenant); seedBaselineCompareRun($tenant, $profile, $snapshot, workspaceOverviewCompareCoverage()); @@ -78,7 +78,7 @@ it('keeps single-tenant backup and recovery metric drill-through available when the tenant dashboard stays membership-accessible', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - $backupTenant = Tenant::factory()->create(['status' => 'active']); + $backupTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $backupTenant] = createUserWithTenant($backupTenant, role: 'readonly', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($backupTenant); $backupTenantSet = workspaceOverviewSeedHealthyBackup($backupTenant, [ @@ -86,10 +86,10 @@ ]); workspaceOverviewSeedRestoreHistory($backupTenant, $backupTenantSet, 'completed'); - $recoveryTenant = Tenant::factory()->create([ + $recoveryTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $backupTenant->workspace_id, - 'name' => 'Recovery Tenant', + 'name' => 'Recovery ManagedEnvironment', ]); createUserWithTenant($recoveryTenant, $user, role: 'readonly', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($recoveryTenant); @@ -102,7 +102,7 @@ $mock->shouldReceive('primeMemberships')->once(); $mock->shouldReceive('isMember')->andReturnTrue(); $mock->shouldReceive('can') - ->andReturnUsing(static function ($user, Tenant $tenant, string $capability): bool { + ->andReturnUsing(static function ($user, ManagedEnvironment $tenant, string $capability): bool { return match ($capability) { Capabilities::TENANT_VIEW => false, default => false, @@ -127,7 +127,7 @@ it('falls back to the visible tenant dashboard when hidden peers are excluded from backup and recovery metric drill-through', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - $visibleBackupTenant = Tenant::factory()->create(['status' => 'active']); + $visibleBackupTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $visibleBackupTenant] = createUserWithTenant($visibleBackupTenant, role: 'readonly', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($visibleBackupTenant); $visibleBackupSet = workspaceOverviewSeedHealthyBackup($visibleBackupTenant, [ @@ -135,10 +135,10 @@ ]); workspaceOverviewSeedRestoreHistory($visibleBackupTenant, $visibleBackupSet, 'completed'); - $visibleRecoveryTenant = Tenant::factory()->create([ + $visibleRecoveryTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleBackupTenant->workspace_id, - 'name' => 'Visible Recovery Tenant', + 'name' => 'Visible Recovery ManagedEnvironment', ]); createUserWithTenant($visibleRecoveryTenant, $user, role: 'readonly', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($visibleRecoveryTenant); @@ -147,17 +147,17 @@ ]); workspaceOverviewSeedRestoreHistory($visibleRecoveryTenant, $visibleRecoveryBackup, 'follow_up'); - $hiddenBackupTenant = Tenant::factory()->create([ + $hiddenBackupTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleBackupTenant->workspace_id, - 'name' => 'Hidden Backup Tenant', + 'name' => 'Hidden Backup ManagedEnvironment', ]); workspaceOverviewSeedQuietTenantTruth($hiddenBackupTenant); - $hiddenRecoveryTenant = Tenant::factory()->create([ + $hiddenRecoveryTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleBackupTenant->workspace_id, - 'name' => 'Hidden Recovery Tenant', + 'name' => 'Hidden Recovery ManagedEnvironment', ]); workspaceOverviewSeedQuietTenantTruth($hiddenRecoveryTenant); $hiddenRecoveryBackup = workspaceOverviewSeedHealthyBackup($hiddenRecoveryTenant, [ diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewContentTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewContentTest.php index a4c67233..28db3138 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewContentTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewContentTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Resources\TenantResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\OperationRun; use App\Support\OperationRunStatus; use App\Support\RestoreSafety\RestoreResultAttention; @@ -19,7 +19,7 @@ workspaceOverviewSeedRestoreHistory($tenant, $backupSet, 'completed'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Running->value, @@ -55,10 +55,10 @@ [$user, $anchorTenant] = createUserWithTenant(role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($anchorTenant); - $backupTenant = Tenant::factory()->create([ + $backupTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $anchorTenant->workspace_id, - 'name' => 'Backup Attention Tenant', + 'name' => 'Backup Attention ManagedEnvironment', ]); createUserWithTenant($backupTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($backupTenant); @@ -66,10 +66,10 @@ 'completed_at' => now()->subDays(2), ]); - $backupTenantB = Tenant::factory()->create([ + $backupTenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $anchorTenant->workspace_id, - 'name' => 'Backup Attention Tenant B', + 'name' => 'Backup Attention ManagedEnvironment B', ]); createUserWithTenant($backupTenantB, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($backupTenantB); @@ -84,10 +84,10 @@ 'assignments' => [], ]); - $recoveryTenantA = Tenant::factory()->create([ + $recoveryTenantA = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $anchorTenant->workspace_id, - 'name' => 'Recovery Attention Tenant A', + 'name' => 'Recovery Attention ManagedEnvironment A', ]); createUserWithTenant($recoveryTenantA, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($recoveryTenantA); @@ -96,10 +96,10 @@ ]); workspaceOverviewSeedRestoreHistory($recoveryTenantA, $recoveryBackupA, 'failed'); - $recoveryTenantB = Tenant::factory()->create([ + $recoveryTenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $anchorTenant->workspace_id, - 'name' => 'Recovery Attention Tenant B', + 'name' => 'Recovery Attention ManagedEnvironment B', ]); createUserWithTenant($recoveryTenantB, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($recoveryTenantB); diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewDbOnlyTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewDbOnlyTest.php index 90880b60..09c257b9 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewDbOnlyTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewDbOnlyTest.php @@ -4,7 +4,7 @@ use App\Models\Finding; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Carbon\CarbonImmutable; use Illuminate\Support\Facades\DB; @@ -16,7 +16,7 @@ it('renders the workspace overview DB-only with bounded query volume for representative visible-tenant scenarios', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - $tenantA = Tenant::factory()->create(['status' => 'active']); + $tenantA = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($tenantA); @@ -26,10 +26,10 @@ 'due_at' => now()->subDay(), ]); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Second Tenant', + 'name' => 'Second ManagedEnvironment', ]); createUserWithTenant($tenantB, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($tenantB); @@ -37,10 +37,10 @@ 'completed_at' => now()->subDays(2), ]); - $tenantC = Tenant::factory()->create([ + $tenantC = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Third Tenant', + 'name' => 'Third ManagedEnvironment', ]); createUserWithTenant($tenantC, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($tenantC); @@ -50,7 +50,7 @@ workspaceOverviewSeedRestoreHistory($tenantC, $tenantCBackup, 'follow_up'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantC->getKey(), + 'managed_environment_id' => (int) $tenantC->getKey(), 'workspace_id' => (int) $tenantC->workspace_id, 'status' => \App\Support\OperationRunStatus::Running->value, 'outcome' => \App\Support\OperationRunOutcome::Pending->value, @@ -71,5 +71,5 @@ ->assertSee('Recent operations'); }); - expect(count(DB::getQueryLog()))->toBeLessThanOrEqual(86); + expect(count(DB::getQueryLog()))->toBeLessThanOrEqual(92); }); diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php index 03fdb178..146f435a 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php @@ -10,7 +10,7 @@ use App\Models\AlertDelivery; use App\Models\Finding; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\OperationRunType; @@ -26,7 +26,7 @@ }); it('preserves canonical findings, compare, alerts, and operations drill-through continuity from the workspace overview', function (): void { - $tenantDashboard = Tenant::factory()->create(['status' => 'active']); + $tenantDashboard = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantDashboard] = createUserWithTenant($tenantDashboard, role: 'owner', workspaceRole: 'readonly'); [$dashboardProfile, $dashboardSnapshot] = seedActiveBaselineForTenant($tenantDashboard); seedBaselineCompareRun($tenantDashboard, $dashboardProfile, $dashboardSnapshot, workspaceOverviewCompareCoverage()); @@ -37,10 +37,10 @@ Finding::factory()->riskAccepted()->create([ 'workspace_id' => (int) $tenantDashboard->workspace_id, - 'tenant_id' => (int) $tenantDashboard->getKey(), + 'managed_environment_id' => (int) $tenantDashboard->getKey(), ]); - $tenantFindings = Tenant::factory()->create([ + $tenantFindings = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantDashboard->workspace_id, ]); @@ -58,10 +58,10 @@ 'due_at' => now()->subDay(), ]); - $tenantCompare = Tenant::factory()->create([ + $tenantCompare = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantDashboard->workspace_id, - 'name' => 'Compare Tenant', + 'name' => 'Compare ManagedEnvironment', ]); createUserWithTenant($tenantCompare, $user, role: 'owner', workspaceRole: 'readonly'); [$compareProfile, $compareSnapshot] = seedActiveBaselineForTenant($tenantCompare); @@ -77,10 +77,10 @@ ]); workspaceOverviewSeedRestoreHistory($tenantCompare, $tenantCompareBackup, 'completed'); - $tenantOperations = Tenant::factory()->create([ + $tenantOperations = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantDashboard->workspace_id, - 'name' => 'Operations Tenant', + 'name' => 'Operations ManagedEnvironment', ]); createUserWithTenant($tenantOperations, $user, role: 'owner', workspaceRole: 'readonly'); [$operationsProfile, $operationsSnapshot] = seedActiveBaselineForTenant($tenantOperations); @@ -91,17 +91,17 @@ workspaceOverviewSeedRestoreHistory($tenantOperations, $tenantOperationsBackup, 'completed'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantOperations->getKey(), + 'managed_environment_id' => (int) $tenantOperations->getKey(), 'workspace_id' => (int) $tenantOperations->workspace_id, 'type' => OperationRunType::PolicySync->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, ]); - $tenantAlerts = Tenant::factory()->create([ + $tenantAlerts = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantDashboard->workspace_id, - 'name' => 'Alerts Tenant', + 'name' => 'Alerts ManagedEnvironment', ]); createUserWithTenant($tenantAlerts, $user, role: 'owner', workspaceRole: 'readonly'); [$alertsProfile, $alertsSnapshot] = seedActiveBaselineForTenant($tenantAlerts); @@ -112,7 +112,7 @@ workspaceOverviewSeedRestoreHistory($tenantAlerts, $tenantAlertsBackup, 'completed'); AlertDelivery::factory()->create([ - 'tenant_id' => (int) $tenantAlerts->getKey(), + 'managed_environment_id' => (int) $tenantAlerts->getKey(), 'workspace_id' => (int) $tenantAlerts->workspace_id, 'status' => AlertDelivery::STATUS_FAILED, 'created_at' => now(), @@ -129,7 +129,7 @@ ->and($items->get('tenant_operations_terminal_follow_up')['destination']['kind'])->toBe('operations_index') ->and($items->get('tenant_operations_terminal_follow_up')['destination']['url'])->toContain('activeTab=terminal_follow_up') ->and($items->get('tenant_operations_terminal_follow_up')['destination']['url'])->toContain('problemClass=terminal_follow_up') - ->and($items->get('tenant_operations_terminal_follow_up')['destination']['url'])->toContain('tenant_id='.(string) $tenantOperations->getKey()) + ->and($items->get('tenant_operations_terminal_follow_up')['destination']['url'])->toContain('managed_environment_id='.(string) $tenantOperations->getKey()) ->and($items->get('tenant_alert_delivery_failures')['destination']['kind'])->toBe('alerts_overview') ->and($items->get('tenant_alert_delivery_failures')['destination']['url'])->toContain('nav%5Bback_url%5D='); }); @@ -144,7 +144,7 @@ $items = [ [ 'key' => 'tenant_evidence_attention', - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'tenant_label' => (string) $tenant->name, 'tenant_route_key' => (string) $tenant->external_id, 'family' => 'evidence', @@ -169,7 +169,7 @@ ], [ 'key' => 'tenant_review_attention', - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'tenant_label' => (string) $tenant->name, 'tenant_route_key' => (string) $tenant->external_id, 'family' => 'review', @@ -211,17 +211,17 @@ it('hydrates filtered tenant-registry triage state from multi-tenant workspace backup and recovery metrics', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - $absentTenant = Tenant::factory()->create([ + $absentTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Absent Backup Tenant', + 'name' => 'Absent Backup ManagedEnvironment', ]); [$user, $absentTenant] = createUserWithTenant($absentTenant, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($absentTenant); - $staleTenant = Tenant::factory()->create([ + $staleTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $absentTenant->workspace_id, - 'name' => 'Stale Backup Tenant', + 'name' => 'Stale Backup ManagedEnvironment', ]); createUserWithTenant($staleTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($staleTenant); @@ -230,10 +230,10 @@ ]); workspaceOverviewSeedRestoreHistory($staleTenant, $staleBackup, 'completed'); - $degradedTenant = Tenant::factory()->create([ + $degradedTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $absentTenant->workspace_id, - 'name' => 'Degraded Backup Tenant', + 'name' => 'Degraded Backup ManagedEnvironment', ]); createUserWithTenant($degradedTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($degradedTenant); @@ -249,10 +249,10 @@ ]); workspaceOverviewSeedRestoreHistory($degradedTenant, $degradedBackup, 'completed'); - $weakenedTenant = Tenant::factory()->create([ + $weakenedTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $absentTenant->workspace_id, - 'name' => 'Weakened Recovery Tenant', + 'name' => 'Weakened Recovery ManagedEnvironment', ]); createUserWithTenant($weakenedTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($weakenedTenant); @@ -261,10 +261,10 @@ ]); workspaceOverviewSeedRestoreHistory($weakenedTenant, $weakenedBackup, 'follow_up'); - $unvalidatedTenant = Tenant::factory()->create([ + $unvalidatedTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $absentTenant->workspace_id, - 'name' => 'Unvalidated Recovery Tenant', + 'name' => 'Unvalidated Recovery ManagedEnvironment', ]); createUserWithTenant($unvalidatedTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($unvalidatedTenant); @@ -272,10 +272,10 @@ 'completed_at' => now()->subMinutes(16), ]); - $calmTenant = Tenant::factory()->create([ + $calmTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $absentTenant->workspace_id, - 'name' => 'Calm Tenant', + 'name' => 'Calm ManagedEnvironment', ]); createUserWithTenant($calmTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($calmTenant); @@ -303,11 +303,11 @@ ]) ->assertSet('tableFilters.triage_sort.value', TenantRecoveryTriagePresentation::TRIAGE_SORT_WORST_FIRST); - expect($backupRegistry->instance()->getFilteredSortedTableQuery()?->pluck('tenants.name')->all()) + expect($backupRegistry->instance()->getFilteredSortedTableQuery()?->pluck('managed_environments.name')->all()) ->toBe([ - 'Absent Backup Tenant', - 'Stale Backup Tenant', - 'Degraded Backup Tenant', + 'Absent Backup ManagedEnvironment', + 'Stale Backup ManagedEnvironment', + 'Degraded Backup ManagedEnvironment', ]); parse_str((string) parse_url((string) $metrics->get('recovery_attention_tenants')['destination_url'], PHP_URL_QUERY), $recoveryQuery); @@ -321,26 +321,26 @@ ]) ->assertSet('tableFilters.triage_sort.value', TenantRecoveryTriagePresentation::TRIAGE_SORT_WORST_FIRST); - expect($recoveryRegistry->instance()->getFilteredSortedTableQuery()?->pluck('tenants.name')->all()) + expect($recoveryRegistry->instance()->getFilteredSortedTableQuery()?->pluck('managed_environments.name')->all()) ->toBe([ - 'Absent Backup Tenant', - 'Weakened Recovery Tenant', - 'Unvalidated Recovery Tenant', + 'Absent Backup ManagedEnvironment', + 'Weakened Recovery ManagedEnvironment', + 'Unvalidated Recovery ManagedEnvironment', ]); }); it('routes backup and recovery workspace attention into tenant dashboards that still show the same weakness', function (): void { - $backupTenant = Tenant::factory()->create([ + $backupTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Backup Weak Tenant', + 'name' => 'Backup Weak ManagedEnvironment', ]); [$user, $backupTenant] = createUserWithTenant($backupTenant, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($backupTenant); - $recoveryTenant = Tenant::factory()->create([ + $recoveryTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $backupTenant->workspace_id, - 'name' => 'Recovery Weak Tenant', + 'name' => 'Recovery Weak ManagedEnvironment', ]); createUserWithTenant($recoveryTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($recoveryTenant); diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewEmptyStatesTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewEmptyStatesTest.php index e9c48bb3..77e41b1f 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewEmptyStatesTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewEmptyStatesTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -36,7 +36,7 @@ }); it('does not render a calm state when governance risk exists even if operations are quiet', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'readonly'); [$profile, $snapshot] = seedActiveBaselineForTenant($tenant); seedBaselineCompareRun($tenant, $profile, $snapshot, workspaceOverviewCompareCoverage()); @@ -59,7 +59,7 @@ it('renders the healthy calm state only when visible governance and activity are genuinely quiet', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($tenant); $backupSet = workspaceOverviewSeedHealthyBackup($tenant, [ @@ -79,14 +79,14 @@ it('suppresses calmness when backup or recovery attention exists and keeps the checked domains explicit', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - $backupTenant = Tenant::factory()->create(['status' => 'active']); + $backupTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $backupTenant] = createUserWithTenant($backupTenant, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($backupTenant); - $recoveryTenant = Tenant::factory()->create([ + $recoveryTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $backupTenant->workspace_id, - 'name' => 'Recovery Tenant', + 'name' => 'Recovery ManagedEnvironment', ]); createUserWithTenant($recoveryTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($recoveryTenant); diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewGovernanceAttentionTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewGovernanceAttentionTest.php index 20d2be95..f032fb96 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewGovernanceAttentionTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewGovernanceAttentionTest.php @@ -6,14 +6,14 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\OperationRunType; use App\Support\Workspaces\WorkspaceOverviewBuilder; it('prioritizes governance-critical tenants above activity-only and alert-only items', function (): void { - $tenantGovernance = Tenant::factory()->create(['status' => 'active']); + $tenantGovernance = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantGovernance] = createUserWithTenant($tenantGovernance, role: 'owner', workspaceRole: 'readonly'); [$profile, $snapshot] = seedActiveBaselineForTenant($tenantGovernance); seedBaselineCompareRun($tenantGovernance, $profile, $snapshot, workspaceOverviewCompareCoverage()); @@ -28,10 +28,10 @@ 'due_at' => now()->subDay(), ]); - $tenantActivity = Tenant::factory()->create([ + $tenantActivity = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantGovernance->workspace_id, - 'name' => 'Busy Tenant', + 'name' => 'Busy ManagedEnvironment', ]); createUserWithTenant($tenantActivity, $user, role: 'owner', workspaceRole: 'readonly'); [$activityProfile, $activitySnapshot] = seedActiveBaselineForTenant($tenantActivity); @@ -42,17 +42,17 @@ workspaceOverviewSeedRestoreHistory($tenantActivity, $tenantActivityBackup, 'completed'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantActivity->getKey(), + 'managed_environment_id' => (int) $tenantActivity->getKey(), 'workspace_id' => (int) $tenantActivity->workspace_id, 'type' => OperationRunType::InventorySync->value, 'status' => OperationRunStatus::Running->value, 'outcome' => OperationRunOutcome::Pending->value, ]); - $tenantAlerts = Tenant::factory()->create([ + $tenantAlerts = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantGovernance->workspace_id, - 'name' => 'Alerts Tenant', + 'name' => 'Alerts ManagedEnvironment', ]); createUserWithTenant($tenantAlerts, $user, role: 'owner', workspaceRole: 'readonly'); [$alertsProfile, $alertsSnapshot] = seedActiveBaselineForTenant($tenantAlerts); @@ -63,7 +63,7 @@ workspaceOverviewSeedRestoreHistory($tenantAlerts, $tenantAlertsBackup, 'completed'); AlertDelivery::factory()->create([ - 'tenant_id' => (int) $tenantAlerts->getKey(), + 'managed_environment_id' => (int) $tenantAlerts->getKey(), 'workspace_id' => (int) $tenantAlerts->workspace_id, 'status' => AlertDelivery::STATUS_FAILED, 'created_at' => now(), @@ -81,7 +81,7 @@ }); it('surfaces expiring governance and stale compare posture as governance attention without a false calm state', function (): void { - $tenantExpiring = Tenant::factory()->create(['status' => 'active']); + $tenantExpiring = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantExpiring] = createUserWithTenant($tenantExpiring, role: 'owner', workspaceRole: 'readonly'); [$expiringProfile, $expiringSnapshot] = seedActiveBaselineForTenant($tenantExpiring); seedBaselineCompareRun($tenantExpiring, $expiringProfile, $expiringSnapshot, workspaceOverviewCompareCoverage()); @@ -92,12 +92,12 @@ $finding = Finding::factory()->riskAccepted()->create([ 'workspace_id' => (int) $tenantExpiring->workspace_id, - 'tenant_id' => (int) $tenantExpiring->getKey(), + 'managed_environment_id' => (int) $tenantExpiring->getKey(), ]); FindingException::query()->create([ 'workspace_id' => (int) $tenantExpiring->workspace_id, - 'tenant_id' => (int) $tenantExpiring->getKey(), + 'managed_environment_id' => (int) $tenantExpiring->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -114,10 +114,10 @@ 'evidence_summary' => ['reference_count' => 0], ]); - $tenantStale = Tenant::factory()->create([ + $tenantStale = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantExpiring->workspace_id, - 'name' => 'Stale Tenant', + 'name' => 'Stale ManagedEnvironment', ]); createUserWithTenant($tenantStale, $user, role: 'owner', workspaceRole: 'readonly'); [$staleProfile, $staleSnapshot] = seedActiveBaselineForTenant($tenantStale); @@ -144,7 +144,7 @@ }); it('ranks lapsed governance and failed compare posture ahead of high-severity findings', function (): void { - $tenantLapsed = Tenant::factory()->create(['status' => 'active']); + $tenantLapsed = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantLapsed] = createUserWithTenant($tenantLapsed, role: 'owner', workspaceRole: 'readonly'); [$lapsedProfile, $lapsedSnapshot] = seedActiveBaselineForTenant($tenantLapsed); seedBaselineCompareRun($tenantLapsed, $lapsedProfile, $lapsedSnapshot, workspaceOverviewCompareCoverage()); @@ -155,13 +155,13 @@ Finding::factory()->riskAccepted()->create([ 'workspace_id' => (int) $tenantLapsed->workspace_id, - 'tenant_id' => (int) $tenantLapsed->getKey(), + 'managed_environment_id' => (int) $tenantLapsed->getKey(), ]); - $tenantFailedCompare = Tenant::factory()->create([ + $tenantFailedCompare = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantLapsed->workspace_id, - 'name' => 'Failed Compare Tenant', + 'name' => 'Failed Compare ManagedEnvironment', ]); createUserWithTenant($tenantFailedCompare, $user, role: 'owner', workspaceRole: 'readonly'); [$failedProfile, $failedSnapshot] = seedActiveBaselineForTenant($tenantFailedCompare); @@ -177,10 +177,10 @@ ]); workspaceOverviewSeedRestoreHistory($tenantFailedCompare, $tenantFailedBackup, 'completed'); - $tenantHighSeverity = Tenant::factory()->create([ + $tenantHighSeverity = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantLapsed->workspace_id, - 'name' => 'High Severity Tenant', + 'name' => 'High Severity ManagedEnvironment', ]); createUserWithTenant($tenantHighSeverity, $user, role: 'owner', workspaceRole: 'readonly'); [$highProfile, $highSnapshot] = seedActiveBaselineForTenant($tenantHighSeverity); @@ -208,7 +208,7 @@ }); it('keeps governance-first ordering while inserting backup and recovery attention ahead of activity-only items', function (): void { - $governanceTenant = Tenant::factory()->create(['status' => 'active']); + $governanceTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $governanceTenant] = createUserWithTenant($governanceTenant, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($governanceTenant); $governanceBackup = workspaceOverviewSeedHealthyBackup($governanceTenant, [ @@ -222,18 +222,18 @@ 'due_at' => now()->subDay(), ]); - $backupTenant = Tenant::factory()->create([ + $backupTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $governanceTenant->workspace_id, - 'name' => 'Backup Tenant', + 'name' => 'Backup ManagedEnvironment', ]); createUserWithTenant($backupTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($backupTenant); - $recoveryTenant = Tenant::factory()->create([ + $recoveryTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $governanceTenant->workspace_id, - 'name' => 'Recovery Tenant', + 'name' => 'Recovery ManagedEnvironment', ]); createUserWithTenant($recoveryTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($recoveryTenant); @@ -242,10 +242,10 @@ ]); workspaceOverviewSeedRestoreHistory($recoveryTenant, $recoveryBackup, 'follow_up'); - $operationsTenant = Tenant::factory()->create([ + $operationsTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $governanceTenant->workspace_id, - 'name' => 'Operations Tenant', + 'name' => 'Operations ManagedEnvironment', ]); createUserWithTenant($operationsTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($operationsTenant); @@ -255,7 +255,7 @@ workspaceOverviewSeedRestoreHistory($operationsTenant, $operationsBackup, 'completed'); OperationRun::factory()->create([ - 'tenant_id' => (int) $operationsTenant->getKey(), + 'managed_environment_id' => (int) $operationsTenant->getKey(), 'workspace_id' => (int) $operationsTenant->workspace_id, 'type' => OperationRunType::InventorySync->value, 'status' => OperationRunStatus::Running->value, diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewLandingTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewLandingTest.php index 1db52e79..7cb9a8cd 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewLandingTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewLandingTest.php @@ -10,7 +10,7 @@ it('renders the workspace overview when a workspace is already selected', function (): void { $workspace = Workspace::factory()->create(['name' => 'Contoso Workspace']); [$user] = createUserWithTenant( - tenant: \App\Models\Tenant::factory()->create([ + tenant: \App\Models\ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $workspace->getKey(), ]), diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewOperationsTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewOperationsTest.php index aef7d0e2..3bd8f096 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewOperationsTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewOperationsTest.php @@ -3,28 +3,28 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; it('shows only recent operations from the current users authorized tenant slice and does not enable polling', function (): void { - $tenantA = Tenant::factory()->create(['status' => 'active']); + $tenantA = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner', workspaceRole: 'readonly'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Forbidden Tenant', + 'name' => 'Forbidden ManagedEnvironment', ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'initiator_name' => 'Accessible run', ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'policy.sync', 'initiator_name' => 'Forbidden run', @@ -35,7 +35,7 @@ ->get('/admin') ->assertOk() ->assertSee('Inventory sync') - ->assertDontSee('Forbidden Tenant') + ->assertDontSee('Forbidden ManagedEnvironment') ->assertDontSee('Policy sync'); expect((string) $response->getContent())->not->toContain('wire:poll'); @@ -47,7 +47,7 @@ seedBaselineCompareRun($tenant, $profile, $snapshot, workspaceOverviewCompareCoverage()); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => \App\Support\OperationRunStatus::Running->value, @@ -57,7 +57,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'restore.execute', 'status' => \App\Support\OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewPermissionVisibilityTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewPermissionVisibilityTest.php index 9ee60df1..eeaca3ff 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewPermissionVisibilityTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewPermissionVisibilityTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; use App\Support\Workspaces\WorkspaceOverviewBuilder; @@ -15,13 +15,13 @@ }); it('keeps switch workspace visible while hiding manage workspaces and unauthorized tenant counts for readonly members', function (): void { - $tenantA = Tenant::factory()->create(['status' => 'active']); + $tenantA = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner', workspaceRole: 'readonly'); - Tenant::factory()->create([ + ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Inaccessible Tenant', + 'name' => 'Inaccessible ManagedEnvironment', ]); $workspace = $tenantA->workspace()->firstOrFail(); @@ -35,7 +35,7 @@ }); it('keeps governance attention visible but non-clickable when the tenant membership does not grant drill-through capability', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($tenant); $backupSet = workspaceOverviewSeedHealthyBackup($tenant, [ @@ -52,7 +52,7 @@ mock(CapabilityResolver::class, function ($mock) use ($tenant): void { $mock->shouldReceive('primeMemberships')->once(); $mock->shouldReceive('can') - ->andReturnUsing(static function (\App\Models\User $user, Tenant $resolvedTenant, string $capability) use ($tenant): bool { + ->andReturnUsing(static function (\App\Models\User $user, ManagedEnvironment $resolvedTenant, string $capability) use ($tenant): bool { expect((int) $resolvedTenant->getKey())->toBe((int) $tenant->getKey()); return match ($capability) { @@ -74,7 +74,7 @@ it('omits hidden-tenant backup and recovery issues from workspace counts and calmness claims', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - $visibleTenant = Tenant::factory()->create(['status' => 'active']); + $visibleTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $visibleTenant] = createUserWithTenant($visibleTenant, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($visibleTenant); $visibleBackup = workspaceOverviewSeedHealthyBackup($visibleTenant, [ @@ -82,17 +82,17 @@ ]); workspaceOverviewSeedRestoreHistory($visibleTenant, $visibleBackup, 'completed'); - $hiddenBackupTenant = Tenant::factory()->create([ + $hiddenBackupTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, - 'name' => 'Hidden Backup Tenant', + 'name' => 'Hidden Backup ManagedEnvironment', ]); workspaceOverviewSeedQuietTenantTruth($hiddenBackupTenant); - $hiddenRecoveryTenant = Tenant::factory()->create([ + $hiddenRecoveryTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, - 'name' => 'Hidden Recovery Tenant', + 'name' => 'Hidden Recovery ManagedEnvironment', ]); workspaceOverviewSeedQuietTenantTruth($hiddenRecoveryTenant); $hiddenRecoveryBackup = workspaceOverviewSeedHealthyBackup($hiddenRecoveryTenant, [ @@ -110,20 +110,20 @@ ->and($overview['calmness']['is_calm'])->toBeTrue() ->and($overview['calmness']['body'])->toContain('visible workspace') ->and(collect($overview['attention_items'])->pluck('tenant_label')->all()) - ->not->toContain('Hidden Backup Tenant', 'Hidden Recovery Tenant'); + ->not->toContain('Hidden Backup ManagedEnvironment', 'Hidden Recovery ManagedEnvironment'); }); it('keeps backup and recovery items tenant-safe when the tenant dashboard remains membership-accessible', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - $backupTenant = Tenant::factory()->create(['status' => 'active']); + $backupTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $backupTenant] = createUserWithTenant($backupTenant, role: 'readonly', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($backupTenant); - $recoveryTenant = Tenant::factory()->create([ + $recoveryTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $backupTenant->workspace_id, - 'name' => 'Recovery Tenant', + 'name' => 'Recovery ManagedEnvironment', ]); createUserWithTenant($recoveryTenant, $user, role: 'readonly', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($recoveryTenant); @@ -135,14 +135,14 @@ mock(CapabilityResolver::class, function ($mock) use ($backupTenant, $recoveryTenant): void { $mock->shouldReceive('primeMemberships')->once(); $mock->shouldReceive('isMember') - ->andReturnUsing(static function ($user, Tenant $tenant) use ($backupTenant, $recoveryTenant): bool { + ->andReturnUsing(static function ($user, ManagedEnvironment $tenant) use ($backupTenant, $recoveryTenant): bool { expect([(int) $backupTenant->getKey(), (int) $recoveryTenant->getKey()]) ->toContain((int) $tenant->getKey()); return true; }); $mock->shouldReceive('can') - ->andReturnUsing(static function ($user, Tenant $tenant, string $capability) use ($backupTenant, $recoveryTenant): bool { + ->andReturnUsing(static function ($user, ManagedEnvironment $tenant, string $capability) use ($backupTenant, $recoveryTenant): bool { expect([(int) $backupTenant->getKey(), (int) $recoveryTenant->getKey()]) ->toContain((int) $tenant->getKey()); diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewRecoveryAttentionTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewRecoveryAttentionTest.php index 54f21052..bc2fd538 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewRecoveryAttentionTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewRecoveryAttentionTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceOverviewBuilder; use Carbon\CarbonImmutable; @@ -13,17 +13,17 @@ it('orders backup-health and recovery-evidence attention by severity and suppresses calm recovery history', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - $absentTenant = Tenant::factory()->create([ + $absentTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Absent Backup Tenant', + 'name' => 'Absent Backup ManagedEnvironment', ]); [$user, $absentTenant] = createUserWithTenant($absentTenant, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($absentTenant); - $staleTenant = Tenant::factory()->create([ + $staleTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $absentTenant->workspace_id, - 'name' => 'Stale Backup Tenant', + 'name' => 'Stale Backup ManagedEnvironment', ]); createUserWithTenant($staleTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($staleTenant); @@ -32,10 +32,10 @@ 'completed_at' => now()->subDays(2), ]); - $degradedTenant = Tenant::factory()->create([ + $degradedTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $absentTenant->workspace_id, - 'name' => 'Degraded Backup Tenant', + 'name' => 'Degraded Backup ManagedEnvironment', ]); createUserWithTenant($degradedTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($degradedTenant); @@ -51,10 +51,10 @@ 'assignments' => [], ]); - $weakenedTenant = Tenant::factory()->create([ + $weakenedTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $absentTenant->workspace_id, - 'name' => 'Weakened Recovery Tenant', + 'name' => 'Weakened Recovery ManagedEnvironment', ]); createUserWithTenant($weakenedTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($weakenedTenant); @@ -64,10 +64,10 @@ ]); workspaceOverviewSeedRestoreHistory($weakenedTenant, $weakenedBackup, 'follow_up'); - $unvalidatedTenant = Tenant::factory()->create([ + $unvalidatedTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $absentTenant->workspace_id, - 'name' => 'Unvalidated Recovery Tenant', + 'name' => 'Unvalidated Recovery ManagedEnvironment', ]); createUserWithTenant($unvalidatedTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($unvalidatedTenant); @@ -76,10 +76,10 @@ 'completed_at' => now()->subMinutes(20), ]); - $calmTenant = Tenant::factory()->create([ + $calmTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $absentTenant->workspace_id, - 'name' => 'Calm Tenant', + 'name' => 'Calm ManagedEnvironment', ]); createUserWithTenant($calmTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($calmTenant); diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php index 81218c5c..f3bf6558 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php @@ -6,7 +6,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceOverviewBuilder; use Carbon\CarbonImmutable; @@ -15,7 +15,7 @@ }); it('counts governance attention by affected tenant instead of raw issue totals', function (): void { - $tenantOverdue = Tenant::factory()->create(['status' => 'active']); + $tenantOverdue = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantOverdue] = createUserWithTenant($tenantOverdue, role: 'owner', workspaceRole: 'readonly'); [$overdueProfile, $overdueSnapshot] = seedActiveBaselineForTenant($tenantOverdue); seedBaselineCompareRun($tenantOverdue, $overdueProfile, $overdueSnapshot, workspaceOverviewCompareCoverage()); @@ -26,10 +26,10 @@ 'due_at' => now()->subDay(), ]); - $tenantExpiring = Tenant::factory()->create([ + $tenantExpiring = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantOverdue->workspace_id, - 'name' => 'Expiring Tenant', + 'name' => 'Expiring ManagedEnvironment', ]); createUserWithTenant($tenantExpiring, $user, role: 'owner', workspaceRole: 'readonly'); [$expiringProfile, $expiringSnapshot] = seedActiveBaselineForTenant($tenantExpiring); @@ -37,12 +37,12 @@ $finding = Finding::factory()->riskAccepted()->create([ 'workspace_id' => (int) $tenantExpiring->workspace_id, - 'tenant_id' => (int) $tenantExpiring->getKey(), + 'managed_environment_id' => (int) $tenantExpiring->getKey(), ]); FindingException::query()->create([ 'workspace_id' => (int) $tenantExpiring->workspace_id, - 'tenant_id' => (int) $tenantExpiring->getKey(), + 'managed_environment_id' => (int) $tenantExpiring->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -59,10 +59,10 @@ 'evidence_summary' => ['reference_count' => 0], ]); - $tenantStale = Tenant::factory()->create([ + $tenantStale = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantOverdue->workspace_id, - 'name' => 'Stale Tenant', + 'name' => 'Stale ManagedEnvironment', ]); createUserWithTenant($tenantStale, $user, role: 'owner', workspaceRole: 'readonly'); [$staleProfile, $staleSnapshot] = seedActiveBaselineForTenant($tenantStale); @@ -74,10 +74,10 @@ completedAt: now()->subDays(10), ); - $tenantFailedCompare = Tenant::factory()->create([ + $tenantFailedCompare = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantOverdue->workspace_id, - 'name' => 'Failed Compare Tenant', + 'name' => 'Failed Compare ManagedEnvironment', ]); createUserWithTenant($tenantFailedCompare, $user, role: 'owner', workspaceRole: 'readonly'); [$failedProfile, $failedSnapshot] = seedActiveBaselineForTenant($tenantFailedCompare); @@ -99,20 +99,20 @@ }); it('keeps activity and alerts metrics separate from governance risk', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'readonly'); [$profile, $snapshot] = seedActiveBaselineForTenant($tenant); seedBaselineCompareRun($tenant, $profile, $snapshot, workspaceOverviewCompareCoverage()); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => \App\Support\OperationRunStatus::Running->value, 'outcome' => \App\Support\OperationRunOutcome::Pending->value, ]); AlertDelivery::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => AlertDelivery::STATUS_FAILED, 'created_at' => now(), @@ -133,9 +133,9 @@ it('counts backup and recovery attention tenants separately and chooses precise or fallback destinations', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - $recoveryTenantA = Tenant::factory()->create([ + $recoveryTenantA = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Recovery Tenant A', + 'name' => 'Recovery ManagedEnvironment A', ]); [$user, $recoveryTenantA] = createUserWithTenant($recoveryTenantA, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($recoveryTenantA); @@ -144,10 +144,10 @@ ]); workspaceOverviewSeedRestoreHistory($recoveryTenantA, $recoveryTenantABackup, 'follow_up'); - $recoveryTenantB = Tenant::factory()->create([ + $recoveryTenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $recoveryTenantA->workspace_id, - 'name' => 'Recovery Tenant B', + 'name' => 'Recovery ManagedEnvironment B', ]); createUserWithTenant($recoveryTenantB, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($recoveryTenantB); @@ -156,10 +156,10 @@ ]); workspaceOverviewSeedRestoreHistory($recoveryTenantB, $recoveryTenantBBackup, 'failed'); - $backupTenantA = Tenant::factory()->create([ + $backupTenantA = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $recoveryTenantA->workspace_id, - 'name' => 'Backup Tenant A', + 'name' => 'Backup ManagedEnvironment A', ]); createUserWithTenant($backupTenantA, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($backupTenantA); @@ -168,10 +168,10 @@ ]); workspaceOverviewSeedRestoreHistory($backupTenantA, $backupTenantABackup, 'completed'); - $backupTenantB = Tenant::factory()->create([ + $backupTenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $recoveryTenantA->workspace_id, - 'name' => 'Backup Tenant B', + 'name' => 'Backup ManagedEnvironment B', ]); createUserWithTenant($backupTenantB, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($backupTenantB); @@ -187,10 +187,10 @@ ]); workspaceOverviewSeedRestoreHistory($backupTenantB, $backupTenantBBackup, 'completed'); - $calmTenant = Tenant::factory()->create([ + $calmTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $recoveryTenantA->workspace_id, - 'name' => 'Calm Tenant', + 'name' => 'Calm ManagedEnvironment', ]); createUserWithTenant($calmTenant, $user, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($calmTenant); @@ -226,7 +226,7 @@ it('keeps backup and recovery attention counts at zero for calm visible tenants', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 9, 9, 0, 0, 'UTC')); - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'readonly'); workspaceOverviewSeedQuietTenantTruth($tenant); $backupSet = workspaceOverviewSeedHealthyBackup($tenant, [ diff --git a/apps/platform/tests/Feature/Filament/WorkspaceOverviewTriageReviewProgressTest.php b/apps/platform/tests/Feature/Filament/WorkspaceOverviewTriageReviewProgressTest.php index 9120e9f2..409cf1f3 100644 --- a/apps/platform/tests/Feature/Filament/WorkspaceOverviewTriageReviewProgressTest.php +++ b/apps/platform/tests/Feature/Filament/WorkspaceOverviewTriageReviewProgressTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Support\BackupHealth\TenantBackupHealthAssessment; use App\Support\PortfolioTriage\PortfolioArrivalContextToken; @@ -19,14 +19,14 @@ it('counts triage review progress only for the current visible affected set', function (): void { CarbonImmutable::setTestNow(CarbonImmutable::create(2026, 4, 10, 8, 0, 0, 'UTC')); - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Overview Anchor Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Overview Anchor ManagedEnvironment'); $anchorBackup = $this->seedPortfolioBackupConcern($anchorTenant, TenantBackupHealthAssessment::POSTURE_HEALTHY); workspaceOverviewSeedRestoreHistory($anchorTenant, $anchorBackup, 'completed'); - $reviewedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Overview Reviewed Tenant'); - $followUpTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Overview Follow-up Tenant'); - $changedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Overview Changed Tenant'); - $calmTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Overview Calm Tenant'); + $reviewedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Overview Reviewed ManagedEnvironment'); + $followUpTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Overview Follow-up ManagedEnvironment'); + $changedTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Overview Changed ManagedEnvironment'); + $calmTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Overview Calm ManagedEnvironment'); foreach ([$reviewedTenant, $followUpTenant, $changedTenant] as $tenant) { $backupSet = $this->seedPortfolioBackupConcern($tenant, TenantBackupHealthAssessment::POSTURE_STALE); @@ -58,7 +58,7 @@ }); it('omits triage review progress when the visible workspace slice is calm', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Calm Overview Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Calm Overview ManagedEnvironment'); $backupSet = $this->seedPortfolioBackupConcern($tenant, TenantBackupHealthAssessment::POSTURE_HEALTHY); workspaceOverviewSeedRestoreHistory($tenant, $backupSet, 'completed'); diff --git a/apps/platform/tests/Feature/Findings/Concerns/InteractsWithFindingsWorkflow.php b/apps/platform/tests/Feature/Findings/Concerns/InteractsWithFindingsWorkflow.php index 967f157a..b6439065 100644 --- a/apps/platform/tests/Feature/Findings/Concerns/InteractsWithFindingsWorkflow.php +++ b/apps/platform/tests/Feature/Findings/Concerns/InteractsWithFindingsWorkflow.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Audit\AuditActionId; use Filament\Facades\Filament; @@ -14,7 +14,7 @@ trait InteractsWithFindingsWorkflow { /** - * @return array{0: User, 1: Tenant} + * @return array{0: User, 1: ManagedEnvironment} */ protected function actingAsFindingOperator(string $role = 'owner'): array { @@ -29,7 +29,7 @@ protected function actingAsFindingOperator(string $role = 'owner'): array /** * @param array $attributes */ - protected function makeFindingForWorkflow(Tenant $tenant, string $status = Finding::STATUS_NEW, array $attributes = []): Finding + protected function makeFindingForWorkflow(ManagedEnvironment $tenant, string $status = Finding::STATUS_NEW, array $attributes = []): Finding { $factory = Finding::factory()->for($tenant); @@ -51,7 +51,7 @@ protected function latestFindingAudit(Finding $finding, string|AuditActionId $ac $actionValue = $action instanceof AuditActionId ? $action->value : $action; return AuditLog::query() - ->where('tenant_id', (int) $finding->tenant_id) + ->where('managed_environment_id', (int) $finding->managed_environment_id) ->where('resource_type', 'finding') ->where('resource_id', (string) $finding->getKey()) ->where('action', $actionValue) diff --git a/apps/platform/tests/Feature/Findings/DriftStaleAutoResolveTest.php b/apps/platform/tests/Feature/Findings/DriftStaleAutoResolveTest.php index d53682b0..f46cc4e1 100644 --- a/apps/platform/tests/Feature/Findings/DriftStaleAutoResolveTest.php +++ b/apps/platform/tests/Feature/Findings/DriftStaleAutoResolveTest.php @@ -25,7 +25,7 @@ $scopeKey = 'baseline_profile:'.$profile->getKey(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -34,7 +34,7 @@ CarbonImmutable::setTestNow($observedAt); $staleFinding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => $scopeKey, @@ -46,7 +46,7 @@ ]); $seenFinding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => $scopeKey, @@ -85,7 +85,7 @@ $scopeKey = 'baseline_profile:'.$profile->getKey(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -94,7 +94,7 @@ CarbonImmutable::setTestNow($observedAt); $staleFinding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', 'scope_key' => $scopeKey, diff --git a/apps/platform/tests/Feature/Findings/FindingAdminTenantParityTest.php b/apps/platform/tests/Feature/Findings/FindingAdminTenantParityTest.php index f3bbb2cd..cd6a022f 100644 --- a/apps/platform/tests/Feature/Findings/FindingAdminTenantParityTest.php +++ b/apps/platform/tests/Feature/Findings/FindingAdminTenantParityTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\FindingResource; use App\Filament\Resources\FindingResource\Pages\ListFindings; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -14,9 +14,9 @@ uses(RefreshDatabase::class); it('scopes the admin findings list to the remembered canonical tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'manager'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'manager'); $findingA = Finding::factory()->for($tenantA)->create([ @@ -45,9 +45,9 @@ }); it('returns not found for admin finding detail outside the remembered canonical tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'manager'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'manager'); $findingA = Finding::factory()->for($tenantA)->create(); diff --git a/apps/platform/tests/Feature/Findings/FindingAuditBackstopTest.php b/apps/platform/tests/Feature/Findings/FindingAuditBackstopTest.php index e37840a1..9188f02d 100644 --- a/apps/platform/tests/Feature/Findings/FindingAuditBackstopTest.php +++ b/apps/platform/tests/Feature/Findings/FindingAuditBackstopTest.php @@ -4,7 +4,7 @@ use App\Models\AuditLog; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Audit\AuditRecorder; use App\Services\Findings\FindingWorkflowService; use App\Support\Audit\AuditActionId; @@ -25,7 +25,7 @@ $service->close($finding->refresh(), $tenant, $user, Finding::CLOSE_REASON_DUPLICATE); expect(AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('resource_type', 'finding') ->where('resource_id', (string) $finding->getKey()) ->count())->toBe(5); @@ -48,7 +48,7 @@ }); it('deduplicates repeated finding audit writes for the same successful mutation payload', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $finding = Finding::factory()->for($tenant)->resolved()->create(); $recorder = app(AuditRecorder::class); @@ -86,7 +86,7 @@ expect((int) $first->getKey())->toBe((int) $second->getKey()) ->and(AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', AuditActionId::FindingResolved->value) ->where('resource_type', 'finding') ->where('resource_id', (string) $finding->getKey()) @@ -94,7 +94,7 @@ }); it('stores system-origin audit metadata without raw evidence payloads', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $finding = Finding::factory()->for($tenant)->resolved()->create([ 'evidence_jsonb' => [ 'secret' => 'should-never-appear', diff --git a/apps/platform/tests/Feature/Findings/FindingAuditLogTest.php b/apps/platform/tests/Feature/Findings/FindingAuditLogTest.php index 5c0f68bb..88a2a93c 100644 --- a/apps/platform/tests/Feature/Findings/FindingAuditLogTest.php +++ b/apps/platform/tests/Feature/Findings/FindingAuditLogTest.php @@ -28,7 +28,7 @@ $service->resolve($finding->refresh(), $tenant, $user, Finding::RESOLVE_REASON_REMEDIATED); $audit = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('resource_type', 'finding') ->where('resource_id', (string) $finding->getKey()) ->where('action', 'finding.resolved') @@ -69,7 +69,7 @@ ); $audit = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'finding.assigned') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Findings/FindingAutomationWorkflowTest.php b/apps/platform/tests/Feature/Findings/FindingAutomationWorkflowTest.php index d7278ae8..5b33a60b 100644 --- a/apps/platform/tests/Feature/Findings/FindingAutomationWorkflowTest.php +++ b/apps/platform/tests/Feature/Findings/FindingAutomationWorkflowTest.php @@ -61,7 +61,7 @@ function automationBaselineCompareDriftItem(int $baselineProfileId, int $compare */ function invokeAutomationBaselineCompareUpsertFindings( CompareBaselineToTenantJob $job, - \App\Models\Tenant $tenant, + \App\Models\ManagedEnvironment $tenant, BaselineProfile $profile, string $scopeKey, array $driftResults, @@ -84,7 +84,7 @@ function invokeAutomationBaselineCompareUpsertFindings( $scopeKey = 'baseline_profile:'.$profile->getKey(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -93,7 +93,7 @@ function invokeAutomationBaselineCompareUpsertFindings( CarbonImmutable::setTestNow($observedAt); $finding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, 'source' => 'baseline.compare', @@ -165,7 +165,7 @@ function invokeAutomationBaselineCompareUpsertFindings( ]); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->firstOrFail(); @@ -248,7 +248,7 @@ function invokeAutomationBaselineCompareUpsertFindings( ]); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_ENTRA_ADMIN_ROLES) ->where('subject_external_id', 'user-1:def-ga') ->firstOrFail(); @@ -276,7 +276,7 @@ function invokeAutomationBaselineCompareUpsertFindings( $scopeKey = 'baseline_profile:'.$profile->getKey(); $run1 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -291,7 +291,7 @@ function invokeAutomationBaselineCompareUpsertFindings( ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->where('subject_external_id', 'policy-audit-recur') ->firstOrFail(); @@ -303,7 +303,7 @@ function invokeAutomationBaselineCompareUpsertFindings( ])->save(); $run2 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); diff --git a/apps/platform/tests/Feature/Findings/FindingBulkActionsTest.php b/apps/platform/tests/Feature/Findings/FindingBulkActionsTest.php index 4a9426de..36d0d500 100644 --- a/apps/platform/tests/Feature/Findings/FindingBulkActionsTest.php +++ b/apps/platform/tests/Feature/Findings/FindingBulkActionsTest.php @@ -15,7 +15,7 @@ function findingBulkAuditResourceIds(int $tenantId, string $action): array { return AuditLog::query() - ->where('tenant_id', $tenantId) + ->where('managed_environment_id', $tenantId) ->where('action', $action) ->pluck('resource_id') ->map(static fn (string $resourceId): int => (int) $resourceId) diff --git a/apps/platform/tests/Feature/Findings/FindingExceptionAuthorizationTest.php b/apps/platform/tests/Feature/Findings/FindingExceptionAuthorizationTest.php index 9b4f889a..b8a5dfcc 100644 --- a/apps/platform/tests/Feature/Findings/FindingExceptionAuthorizationTest.php +++ b/apps/platform/tests/Feature/Findings/FindingExceptionAuthorizationTest.php @@ -33,7 +33,7 @@ it('returns 404 for non-members on tenant exception routes', function (): void { [$owner, $tenant] = createUserWithTenant(role: 'owner'); - $tenantInSameWorkspace = \App\Models\Tenant::factory()->create([ + $tenantInSameWorkspace = \App\Models\ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); [$outsider] = createUserWithTenant(tenant: $tenantInSameWorkspace, role: 'owner'); @@ -41,7 +41,7 @@ $finding = Finding::factory()->for($tenant)->create(); $exception = FindingException::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $owner->getKey(), 'owner_user_id' => (int) $owner->getKey(), diff --git a/apps/platform/tests/Feature/Findings/FindingExceptionDecisionRegisterBoundariesTest.php b/apps/platform/tests/Feature/Findings/FindingExceptionDecisionRegisterBoundariesTest.php index 54781569..b1fac71d 100644 --- a/apps/platform/tests/Feature/Findings/FindingExceptionDecisionRegisterBoundariesTest.php +++ b/apps/platform/tests/Feature/Findings/FindingExceptionDecisionRegisterBoundariesTest.php @@ -6,13 +6,13 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\FindingExceptionDecision; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; it('keeps the decision register read-only with one dominant row action', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'owner'); @@ -22,7 +22,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -36,7 +36,7 @@ $decision = $exception->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $user->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_REQUESTED, 'reason' => 'Read only boundary test', @@ -58,9 +58,9 @@ }); it('omits terminal decisions outside the 30 calendar day recently closed window', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'owner'); @@ -71,7 +71,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -88,7 +88,7 @@ $decision = $exception->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $user->getKey(), 'decision_type' => $status === FindingException::STATUS_REJECTED ? FindingExceptionDecision::TYPE_REJECTED diff --git a/apps/platform/tests/Feature/Findings/FindingExceptionDecisionRegisterNavigationTest.php b/apps/platform/tests/Feature/Findings/FindingExceptionDecisionRegisterNavigationTest.php index 6a8dbb67..ada58350 100644 --- a/apps/platform/tests/Feature/Findings/FindingExceptionDecisionRegisterNavigationTest.php +++ b/apps/platform/tests/Feature/Findings/FindingExceptionDecisionRegisterNavigationTest.php @@ -7,16 +7,16 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\FindingExceptionDecision; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Navigation\CanonicalNavigationContext; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Livewire\Livewire; it('embeds decision register navigation context into open decision links', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'owner'); @@ -30,7 +30,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -44,7 +44,7 @@ $decision = $exception->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $user->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_REQUESTED, 'reason' => 'Decision register continuity', @@ -58,7 +58,7 @@ canonicalRouteName: DecisionRegister::getRouteName(), tenantId: (int) $tenant->getKey(), backLinkUrl: DecisionRegister::getUrl(panel: 'admin', parameters: [ - 'tenant_id' => (string) $tenant->getKey(), + 'managed_environment_id' => (string) $tenant->getKey(), ]), ); @@ -73,7 +73,7 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); $component = Livewire::withQueryParams([ - 'tenant_id' => (string) $tenant->getKey(), + 'managed_environment_id' => (string) $tenant->getKey(), ]) ->actingAs($user) ->test(DecisionRegister::class) diff --git a/apps/platform/tests/Feature/Findings/FindingExceptionDetailDecisionSummaryTest.php b/apps/platform/tests/Feature/Findings/FindingExceptionDetailDecisionSummaryTest.php index cbe25b9d..567d659e 100644 --- a/apps/platform/tests/Feature/Findings/FindingExceptionDetailDecisionSummaryTest.php +++ b/apps/platform/tests/Feature/Findings/FindingExceptionDetailDecisionSummaryTest.php @@ -7,7 +7,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\FindingExceptionDecision; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Navigation\CanonicalNavigationContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -16,9 +16,9 @@ uses(RefreshDatabase::class); it('adds a decision register back action while keeping existing detail actions in place', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'owner'); @@ -26,7 +26,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -45,7 +45,7 @@ $decision = $exception->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $user->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_APPROVED, 'reason' => 'Approved for detail continuity test', @@ -63,7 +63,7 @@ canonicalRouteName: DecisionRegister::getRouteName(), tenantId: (int) $tenant->getKey(), backLinkUrl: DecisionRegister::getUrl(panel: 'admin', parameters: [ - 'tenant_id' => (string) $tenant->getKey(), + 'managed_environment_id' => (string) $tenant->getKey(), ]), ); diff --git a/apps/platform/tests/Feature/Findings/FindingExceptionPolicyTest.php b/apps/platform/tests/Feature/Findings/FindingExceptionPolicyTest.php index 53225a7e..f1c8d07a 100644 --- a/apps/platform/tests/Feature/Findings/FindingExceptionPolicyTest.php +++ b/apps/platform/tests/Feature/Findings/FindingExceptionPolicyTest.php @@ -17,7 +17,7 @@ $finding = Finding::factory()->for($tenant)->create(); $exception = FindingException::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $owner->getKey(), 'owner_user_id' => (int) $owner->getKey(), diff --git a/apps/platform/tests/Feature/Findings/FindingExceptionRegisterTest.php b/apps/platform/tests/Feature/Findings/FindingExceptionRegisterTest.php index 5e0d5278..85069e65 100644 --- a/apps/platform/tests/Feature/Findings/FindingExceptionRegisterTest.php +++ b/apps/platform/tests/Feature/Findings/FindingExceptionRegisterTest.php @@ -29,7 +29,7 @@ return FindingException::query()->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $requester->getKey(), 'owner_user_id' => (int) $requester->getKey(), @@ -88,7 +88,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $requester->getKey(), 'owner_user_id' => (int) $requester->getKey(), @@ -158,7 +158,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $requester->getKey(), 'owner_user_id' => (int) $requester->getKey(), @@ -191,7 +191,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $requester->getKey(), 'owner_user_id' => (int) $requester->getKey(), @@ -220,7 +220,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $requester->getKey(), 'owner_user_id' => (int) $requester->getKey(), @@ -267,7 +267,7 @@ $createException = fn (string $status, string $validity) => FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) Finding::factory()->for($tenant)->create()->getKey(), 'requested_by_user_id' => (int) $requester->getKey(), 'owner_user_id' => (int) $requester->getKey(), @@ -306,7 +306,7 @@ $createException = fn (string $status, string $validity) => FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) Finding::factory()->for($tenant)->create()->getKey(), 'requested_by_user_id' => (int) $requester->getKey(), 'owner_user_id' => (int) $requester->getKey(), diff --git a/apps/platform/tests/Feature/Findings/FindingExceptionRenewalTest.php b/apps/platform/tests/Feature/Findings/FindingExceptionRenewalTest.php index c0243a48..531cf3b2 100644 --- a/apps/platform/tests/Feature/Findings/FindingExceptionRenewalTest.php +++ b/apps/platform/tests/Feature/Findings/FindingExceptionRenewalTest.php @@ -20,7 +20,7 @@ uses(RefreshDatabase::class); /** - * @return array{0: User, 1: User, 2: \App\Models\Tenant, 3: Finding, 4: FindingExceptionService, 5: FindingException} + * @return array{0: User, 1: User, 2: \App\Models\ManagedEnvironment, 3: Finding, 4: FindingExceptionService, 5: FindingException} */ function seedApprovedFindingExceptionWindow(): array { diff --git a/apps/platform/tests/Feature/Findings/FindingOutcomeSummaryReportingTest.php b/apps/platform/tests/Feature/Findings/FindingOutcomeSummaryReportingTest.php index c3914e80..a4f29cae 100644 --- a/apps/platform/tests/Feature/Findings/FindingOutcomeSummaryReportingTest.php +++ b/apps/platform/tests/Feature/Findings/FindingOutcomeSummaryReportingTest.php @@ -17,7 +17,7 @@ uses(RefreshDatabase::class); -function seedFindingOutcomeMatrix(\App\Models\Tenant $tenant): array +function seedFindingOutcomeMatrix(\App\Models\ManagedEnvironment $tenant): array { return [ 'pending_verification' => Finding::factory()->for($tenant)->create([ @@ -39,12 +39,12 @@ function seedFindingOutcomeMatrix(\App\Models\Tenant $tenant): array ]; } -function materializeFindingOutcomeSnapshot(\App\Models\Tenant $tenant): EvidenceSnapshot +function materializeFindingOutcomeSnapshot(\App\Models\ManagedEnvironment $tenant): EvidenceSnapshot { $payload = app(EvidenceSnapshotService::class)->buildSnapshotPayload($tenant); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'fingerprint' => $payload['fingerprint'], @@ -55,7 +55,7 @@ function materializeFindingOutcomeSnapshot(\App\Models\Tenant $tenant): Evidence foreach ($payload['items'] as $item) { $snapshot->items()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => $item['dimension_key'], 'state' => $item['state'], diff --git a/apps/platform/tests/Feature/Findings/FindingRbacTest.php b/apps/platform/tests/Feature/Findings/FindingRbacTest.php index bf800b98..8060a6b8 100644 --- a/apps/platform/tests/Feature/Findings/FindingRbacTest.php +++ b/apps/platform/tests/Feature/Findings/FindingRbacTest.php @@ -20,7 +20,7 @@ uses(RefreshDatabase::class); it('returns 404 for non-members on findings pages', function (): void { - $tenant = \App\Models\Tenant::factory()->create(); + $tenant = \App\Models\ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant(role: 'owner'); $finding = Finding::factory()->for($tenant)->create(); @@ -76,7 +76,7 @@ $this->actingAs($user); Filament::setTenant($tenant, true); - $foreignTenant = \App\Models\Tenant::factory()->create(); + $foreignTenant = \App\Models\ManagedEnvironment::factory()->create(); $foreignFinding = Finding::factory()->for($foreignTenant)->create([ 'status' => Finding::STATUS_NEW, ]); @@ -90,11 +90,11 @@ }); it('denies finding view and triage as not found when tenant context workspace does not match the record workspace', function (): void { - $tenant = \App\Models\Tenant::factory()->create(); + $tenant = \App\Models\ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $finding = Finding::make([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id + 999, 'status' => Finding::STATUS_NEW, ]); diff --git a/apps/platform/tests/Feature/Findings/FindingRecurrenceTest.php b/apps/platform/tests/Feature/Findings/FindingRecurrenceTest.php index 3d50f2e6..d190b312 100644 --- a/apps/platform/tests/Feature/Findings/FindingRecurrenceTest.php +++ b/apps/platform/tests/Feature/Findings/FindingRecurrenceTest.php @@ -6,7 +6,7 @@ use App\Models\BaselineProfile; use App\Models\Finding; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Findings\FindingSlaPolicy; use App\Support\Audit\AuditActionId; use Carbon\CarbonImmutable; @@ -24,7 +24,7 @@ */ function invokeBaselineCompareUpsertFindings( CompareBaselineToTenantJob $job, - Tenant $tenant, + ManagedEnvironment $tenant, BaselineProfile $profile, string $scopeKey, array $driftResults, @@ -169,7 +169,7 @@ function baselineCompareRbacDriftItem( CarbonImmutable::setTestNow($observedAt1); $run1 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -194,7 +194,7 @@ function baselineCompareRbacDriftItem( expect($upsert1['created_count'])->toBe(1); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) @@ -221,7 +221,7 @@ function baselineCompareRbacDriftItem( CarbonImmutable::setTestNow($observedAt2); $run2 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -280,7 +280,7 @@ function baselineCompareRbacDriftItem( CarbonImmutable::setTestNow($observedAt1); $run1 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -303,7 +303,7 @@ function baselineCompareRbacDriftItem( ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) @@ -321,7 +321,7 @@ function baselineCompareRbacDriftItem( CarbonImmutable::setTestNow($observedAt2); $run2 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -368,7 +368,7 @@ function baselineCompareRbacDriftItem( CarbonImmutable::setTestNow($observedAt1); $run1 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -391,7 +391,7 @@ function baselineCompareRbacDriftItem( ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) @@ -409,7 +409,7 @@ function baselineCompareRbacDriftItem( CarbonImmutable::setTestNow($observedAt2); $run2 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -457,7 +457,7 @@ function baselineCompareRbacDriftItem( CarbonImmutable::setTestNow($observedAt1); $run1 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -480,7 +480,7 @@ function baselineCompareRbacDriftItem( ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->where('source', 'baseline.compare') ->where('scope_key', $scopeKey) @@ -498,7 +498,7 @@ function baselineCompareRbacDriftItem( CarbonImmutable::setTestNow($observedAt2); $run2 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); diff --git a/apps/platform/tests/Feature/Findings/FindingRelatedNavigationTest.php b/apps/platform/tests/Feature/Findings/FindingRelatedNavigationTest.php index b76ab7be..012b8858 100644 --- a/apps/platform/tests/Feature/Findings/FindingRelatedNavigationTest.php +++ b/apps/platform/tests/Feature/Findings/FindingRelatedNavigationTest.php @@ -30,12 +30,12 @@ ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Windows Lockdown', ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 3, ]); diff --git a/apps/platform/tests/Feature/Findings/FindingRiskGovernanceProjectionTest.php b/apps/platform/tests/Feature/Findings/FindingRiskGovernanceProjectionTest.php index b4b3dc81..66f89102 100644 --- a/apps/platform/tests/Feature/Findings/FindingRiskGovernanceProjectionTest.php +++ b/apps/platform/tests/Feature/Findings/FindingRiskGovernanceProjectionTest.php @@ -29,7 +29,7 @@ FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $requester->getKey(), 'owner_user_id' => (int) $requester->getKey(), diff --git a/apps/platform/tests/Feature/Findings/FindingWorkflowConcurrencyTest.php b/apps/platform/tests/Feature/Findings/FindingWorkflowConcurrencyTest.php index c8cc2691..60c65a28 100644 --- a/apps/platform/tests/Feature/Findings/FindingWorkflowConcurrencyTest.php +++ b/apps/platform/tests/Feature/Findings/FindingWorkflowConcurrencyTest.php @@ -57,7 +57,7 @@ function concurrencyBaselineCompareDriftItem(int $baselineProfileId, int $compar */ function invokeConcurrencyBaselineCompareUpsertFindings( CompareBaselineToTenantJob $job, - \App\Models\Tenant $tenant, + \App\Models\ManagedEnvironment $tenant, BaselineProfile $profile, string $scopeKey, array $driftResults, @@ -80,7 +80,7 @@ function invokeConcurrencyBaselineCompareUpsertFindings( $scopeKey = 'baseline_profile:'.$profile->getKey(); $run1 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -95,7 +95,7 @@ function invokeConcurrencyBaselineCompareUpsertFindings( ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->firstOrFail(); @@ -103,7 +103,7 @@ function invokeConcurrencyBaselineCompareUpsertFindings( app(FindingWorkflowService::class)->resolve($finding, $tenant, $user, Finding::RESOLVE_REASON_REMEDIATED); $run2 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -135,7 +135,7 @@ function invokeConcurrencyBaselineCompareUpsertFindings( $scopeKey = 'baseline_profile:'.$profile->getKey(); $run1 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); @@ -150,7 +150,7 @@ function invokeConcurrencyBaselineCompareUpsertFindings( ); $finding = Finding::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('source', 'baseline.compare') ->where('subject_external_id', 'policy-closed') ->firstOrFail(); @@ -159,7 +159,7 @@ function invokeConcurrencyBaselineCompareUpsertFindings( app(FindingWorkflowService::class)->close($finding, $tenant, $user, Finding::CLOSE_REASON_DUPLICATE); $run2 = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', ]); diff --git a/apps/platform/tests/Feature/Findings/FindingWorkflowGuardTest.php b/apps/platform/tests/Feature/Findings/FindingWorkflowGuardTest.php index 0a70c68a..cd42d296 100644 --- a/apps/platform/tests/Feature/Findings/FindingWorkflowGuardTest.php +++ b/apps/platform/tests/Feature/Findings/FindingWorkflowGuardTest.php @@ -48,7 +48,7 @@ expect($finding->refresh()->status)->toBe(Finding::STATUS_NEW) ->and(AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('resource_type', 'finding') ->where('resource_id', (string) $finding->getKey()) ->count())->toBe(0); diff --git a/apps/platform/tests/Feature/Findings/FindingWorkflowRowActionsTest.php b/apps/platform/tests/Feature/Findings/FindingWorkflowRowActionsTest.php index e353f0b8..cb3b1bf1 100644 --- a/apps/platform/tests/Feature/Findings/FindingWorkflowRowActionsTest.php +++ b/apps/platform/tests/Feature/Findings/FindingWorkflowRowActionsTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\FindingResource\Pages\ListFindings; use App\Models\Finding; use App\Models\FindingException; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -191,10 +191,10 @@ }); it('returns 404 when a forged foreign-tenant assign row action is mounted', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -221,10 +221,10 @@ }); it('keeps the admin workflow surface scoped to the canonical tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); diff --git a/apps/platform/tests/Feature/Findings/FindingWorkflowUiEnforcementTest.php b/apps/platform/tests/Feature/Findings/FindingWorkflowUiEnforcementTest.php index 9180f66d..ba44e6f1 100644 --- a/apps/platform/tests/Feature/Findings/FindingWorkflowUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Findings/FindingWorkflowUiEnforcementTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\FindingResource\Pages\ListFindings; use App\Filament\Resources\FindingResource\Pages\ViewFinding; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Livewire\Livewire; @@ -61,10 +61,10 @@ }); it('returns 404 when forged foreign-tenant workflow actions are mounted for protected actions', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); diff --git a/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php b/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php index 8c69209c..ed95e74b 100644 --- a/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php +++ b/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneClassificationTest.php @@ -4,8 +4,8 @@ use App\Models\AuditLog; use App\Models\Finding; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Services\Findings\FindingAssignmentHygieneService; use App\Support\Audit\AuditActionId; @@ -17,7 +17,7 @@ function assignmentHygieneServiceContext(string $role = 'readonly', string $workspaceRole = 'readonly'): array { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: $role, workspaceRole: $workspaceRole); return [ @@ -28,7 +28,7 @@ function assignmentHygieneServiceContext(string $role = 'readonly', string $work ]; } -function assignmentHygieneFinding(Tenant $tenant, array $attributes = []): Finding +function assignmentHygieneFinding(ManagedEnvironment $tenant, array $attributes = []): Finding { return Finding::factory()->for($tenant)->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, @@ -41,7 +41,7 @@ function recordAssignmentHygieneWorkflowAudit(Finding $finding, string $action, { return AuditLog::query()->create([ 'workspace_id' => (int) $finding->workspace_id, - 'tenant_id' => (int) $finding->tenant_id, + 'managed_environment_id' => (int) $finding->managed_environment_id, 'action' => $action, 'status' => 'success', 'resource_type' => 'finding', @@ -56,8 +56,8 @@ function recordAssignmentHygieneWorkflowAudit(Finding $finding, string $action, $lostMember = User::factory()->create(['name' => 'Lost Member']); createUserWithTenant($tenant, $lostMember, role: 'readonly', workspaceRole: 'readonly'); - TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $lostMember->getKey()) ->delete(); @@ -188,8 +188,8 @@ function recordAssignmentHygieneWorkflowAudit(Finding $finding, string $action, $lostMember = User::factory()->create(['name' => 'Lost Worker']); createUserWithTenant($tenant, $lostMember, role: 'readonly', workspaceRole: 'readonly'); - TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $lostMember->getKey()) ->delete(); diff --git a/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneOverviewSignalTest.php b/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneOverviewSignalTest.php index e1f806c1..ddb5262a 100644 --- a/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneOverviewSignalTest.php +++ b/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneOverviewSignalTest.php @@ -5,8 +5,8 @@ use App\Filament\Pages\Findings\FindingsHygieneReport; use App\Models\AuditLog; use App\Models\Finding; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; @@ -23,13 +23,13 @@ function findingsHygieneOverviewContext(string $role = 'readonly', string $workspaceRole = 'readonly'): array { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: $role, workspaceRole: $workspaceRole); return [$user, $tenant, $tenant->workspace()->firstOrFail()]; } -function makeFindingsHygieneOverviewFinding(Tenant $tenant, array $attributes = []): Finding +function makeFindingsHygieneOverviewFinding(ManagedEnvironment $tenant, array $attributes = []): Finding { $subjectDisplayName = $attributes['subject_display_name'] ?? null; unset($attributes['subject_display_name']); @@ -52,7 +52,7 @@ function recordFindingsHygieneOverviewAudit(Finding $finding, string $action, Ca { return AuditLog::query()->create([ 'workspace_id' => (int) $finding->workspace_id, - 'tenant_id' => (int) $finding->tenant_id, + 'managed_environment_id' => (int) $finding->managed_environment_id, 'action' => $action, 'status' => 'success', 'resource_type' => 'finding', @@ -69,8 +69,8 @@ function recordFindingsHygieneOverviewAudit(Finding $finding, string $action, Ca $lostMember = User::factory()->create(['name' => 'Lost Member']); createUserWithTenant($tenant, $lostMember, role: 'readonly', workspaceRole: 'readonly'); - TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $lostMember->getKey()) ->delete(); @@ -117,17 +117,17 @@ function recordFindingsHygieneOverviewAudit(Finding $finding, string $action, Ca it('keeps the overview signal calm and suppresses hidden-tenant hygiene issues from counts and copy', function (): void { [$user, $visibleTenant, $workspace] = findingsHygieneOverviewContext(); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, - 'name' => 'Hidden Tenant', + 'name' => 'Hidden ManagedEnvironment', ]); createUserWithTenant($hiddenTenant, $user, role: 'readonly', workspaceRole: 'readonly'); $lostMember = User::factory()->create(['name' => 'Hidden Lost Member']); createUserWithTenant($hiddenTenant, $lostMember, role: 'readonly', workspaceRole: 'readonly'); - TenantMembership::query() - ->where('tenant_id', (int) $hiddenTenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $hiddenTenant->getKey()) ->where('user_id', (int) $lostMember->getKey()) ->delete(); @@ -140,14 +140,14 @@ function recordFindingsHygieneOverviewAudit(Finding $finding, string $action, Ca mock(CapabilityResolver::class, function ($mock) use ($visibleTenant, $hiddenTenant): void { $mock->shouldReceive('primeMemberships')->atLeast()->once(); $mock->shouldReceive('isMember') - ->andReturnUsing(static function (User $user, Tenant $tenant) use ($visibleTenant, $hiddenTenant): bool { + ->andReturnUsing(static function (User $user, ManagedEnvironment $tenant) use ($visibleTenant, $hiddenTenant): bool { expect([(int) $visibleTenant->getKey(), (int) $hiddenTenant->getKey()]) ->toContain((int) $tenant->getKey()); return true; }); $mock->shouldReceive('can') - ->andReturnUsing(static function (User $user, Tenant $tenant, string $capability) use ($visibleTenant, $hiddenTenant): bool { + ->andReturnUsing(static function (User $user, ManagedEnvironment $tenant, string $capability) use ($visibleTenant, $hiddenTenant): bool { expect([(int) $visibleTenant->getKey(), (int) $hiddenTenant->getKey()]) ->toContain((int) $tenant->getKey()); diff --git a/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php b/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php index c75093d7..45cc59d5 100644 --- a/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php +++ b/apps/platform/tests/Feature/Findings/FindingsAssignmentHygieneReportTest.php @@ -5,8 +5,8 @@ use App\Filament\Pages\Findings\FindingsHygieneReport; use App\Models\AuditLog; use App\Models\Finding; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -25,7 +25,7 @@ function findingsHygieneActingUser(string $role = 'readonly', string $workspaceRole = 'readonly'): array { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: $role, workspaceRole: $workspaceRole); test()->actingAs($user); @@ -50,7 +50,7 @@ function findingsHygienePage(?User $user = null, array $query = []) return $factory->test(FindingsHygieneReport::class); } -function makeFindingsHygieneFinding(Tenant $tenant, array $attributes = []): Finding +function makeFindingsHygieneFinding(ManagedEnvironment $tenant, array $attributes = []): Finding { $subjectDisplayName = $attributes['subject_display_name'] ?? null; unset($attributes['subject_display_name']); @@ -73,7 +73,7 @@ function recordFindingsHygieneAudit(Finding $finding, string $action, CarbonImmu { return AuditLog::query()->create([ 'workspace_id' => (int) $finding->workspace_id, - 'tenant_id' => (int) $finding->tenant_id, + 'managed_environment_id' => (int) $finding->managed_environment_id, 'action' => $action, 'status' => 'success', 'resource_type' => 'finding', @@ -147,8 +147,8 @@ function recordFindingsHygieneAudit(Finding $finding, string $action, CarbonImmu $lostMember = User::factory()->create(['name' => 'Lost Member']); createUserWithTenant($tenant, $lostMember, role: 'readonly', workspaceRole: 'readonly'); - TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $lostMember->getKey()) ->delete(); @@ -184,27 +184,27 @@ function recordFindingsHygieneAudit(Finding $finding, string $action, CarbonImmu }); it('suppresses hidden-tenant rows, counts, and tenant filter values inside an otherwise available report', function (): void { - $visibleTenant = Tenant::factory()->create(['status' => 'active', 'name' => 'Visible Tenant']); + $visibleTenant = ManagedEnvironment::factory()->create(['status' => 'active', 'name' => 'Visible ManagedEnvironment']); [$user, $visibleTenant] = createUserWithTenant($visibleTenant, role: 'readonly', workspaceRole: 'readonly'); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, - 'name' => 'Hidden Tenant', + 'name' => 'Hidden ManagedEnvironment', ]); createUserWithTenant($hiddenTenant, $user, role: 'readonly', workspaceRole: 'readonly'); $visibleAssignee = User::factory()->create(['name' => 'Visible Assignee']); createUserWithTenant($visibleTenant, $visibleAssignee, role: 'readonly', workspaceRole: 'readonly'); - TenantMembership::query() - ->where('tenant_id', (int) $visibleTenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $visibleTenant->getKey()) ->where('user_id', (int) $visibleAssignee->getKey()) ->delete(); $hiddenAssignee = User::factory()->create(['name' => 'Hidden Assignee']); createUserWithTenant($hiddenTenant, $hiddenAssignee, role: 'readonly', workspaceRole: 'readonly'); - TenantMembership::query() - ->where('tenant_id', (int) $hiddenTenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $hiddenTenant->getKey()) ->where('user_id', (int) $hiddenAssignee->getKey()) ->delete(); @@ -223,7 +223,7 @@ function recordFindingsHygieneAudit(Finding $finding, string $action, CarbonImmu mock(CapabilityResolver::class, function ($mock) use ($visibleTenant, $hiddenTenant): void { $mock->shouldReceive('primeMemberships')->atLeast()->once(); $mock->shouldReceive('can') - ->andReturnUsing(static function (User $user, Tenant $tenant, string $capability) use ($visibleTenant, $hiddenTenant): bool { + ->andReturnUsing(static function (User $user, ManagedEnvironment $tenant, string $capability) use ($visibleTenant, $hiddenTenant): bool { expect([(int) $visibleTenant->getKey(), (int) $hiddenTenant->getKey()]) ->toContain((int) $tenant->getKey()); @@ -239,7 +239,7 @@ function recordFindingsHygieneAudit(Finding $finding, string $action, CarbonImmu $component = findingsHygienePage($user) ->assertCanSeeTableRecords([$visibleFinding]) ->assertCanNotSeeTableRecords([$hiddenFinding]) - ->assertDontSee('Hidden Tenant'); + ->assertDontSee('Hidden ManagedEnvironment'); expect($component->instance()->summaryCounts()) ->toBe([ @@ -257,7 +257,7 @@ function recordFindingsHygieneAudit(Finding $finding, string $action, CarbonImmu ], [ 'key' => 'tenant', - 'label' => 'Tenant', + 'label' => 'ManagedEnvironment', 'fixed' => false, 'options' => [ ['value' => (string) $visibleTenant->getKey(), 'label' => $visibleTenant->name], @@ -273,8 +273,8 @@ function recordFindingsHygieneAudit(Finding $finding, string $action, CarbonImmu $lostMember = User::factory()->create(['name' => 'Lost Worker']); createUserWithTenant($tenant, $lostMember, role: 'readonly', workspaceRole: 'readonly'); - TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $lostMember->getKey()) ->delete(); @@ -354,24 +354,24 @@ function recordFindingsHygieneAudit(Finding $finding, string $action, CarbonImmu it('explains when the active tenant prefilter hides otherwise visible hygiene issues and clears it in place', function (): void { [$user, $tenantA] = findingsHygieneActingUser(); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant($tenantB, $user, role: 'readonly', workspaceRole: 'readonly'); $lostMember = User::factory()->create(['name' => 'Lost Member']); createUserWithTenant($tenantA, $lostMember, role: 'readonly', workspaceRole: 'readonly'); - TenantMembership::query() - ->where('tenant_id', (int) $tenantA->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenantA->getKey()) ->where('user_id', (int) $lostMember->getKey()) ->delete(); $tenantAIssue = makeFindingsHygieneFinding($tenantA, [ 'owner_user_id' => (int) $user->getKey(), 'assignee_user_id' => (int) $lostMember->getKey(), - 'subject_display_name' => 'Tenant A Issue', + 'subject_display_name' => 'ManagedEnvironment A Issue', ]); session()->put(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY, [ @@ -379,7 +379,7 @@ function recordFindingsHygieneAudit(Finding $finding, string $action, CarbonImmu ]); $component = findingsHygienePage($user) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantB->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantB->getKey()) ->assertCanNotSeeTableRecords([$tenantAIssue]) ->assertSee('No hygiene issues match this tenant scope') ->assertActionVisible('clear_tenant_filter'); diff --git a/apps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.php b/apps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.php index 173d4d89..1a46337b 100644 --- a/apps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.php +++ b/apps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.php @@ -6,7 +6,7 @@ use App\Filament\Pages\Findings\MyFindingsInbox; use App\Models\AuditLog; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Findings\FindingWorkflowService; use App\Support\Audit\AuditActionId; @@ -14,7 +14,7 @@ use Livewire\Livewire; it('mounts the claim confirmation and moves the finding into my findings without changing owner or lifecycle', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'manager', workspaceRole: 'manager'); $owner = User::factory()->create(); @@ -45,7 +45,7 @@ ->and($finding->status)->toBe(Finding::STATUS_REOPENED); $audit = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('resource_type', 'finding') ->where('resource_id', (string) $finding->getKey()) ->where('action', AuditActionId::FindingAssigned->value) @@ -62,7 +62,7 @@ }); it('refuses a stale claim after another operator already claimed the finding first', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$operatorA, $tenant] = createUserWithTenant($tenant, role: 'manager', workspaceRole: 'manager'); $operatorB = User::factory()->create(); @@ -95,7 +95,7 @@ expect( AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('resource_type', 'finding') ->where('resource_id', (string) $finding->getKey()) ->where('action', AuditActionId::FindingAssigned->value) diff --git a/apps/platform/tests/Feature/Findings/FindingsIntakeQueueNavigationContextTest.php b/apps/platform/tests/Feature/Findings/FindingsIntakeQueueNavigationContextTest.php index ba5b2476..f3f2bcb8 100644 --- a/apps/platform/tests/Feature/Findings/FindingsIntakeQueueNavigationContextTest.php +++ b/apps/platform/tests/Feature/Findings/FindingsIntakeQueueNavigationContextTest.php @@ -5,16 +5,16 @@ use App\Filament\Pages\Findings\FindingsIntakeQueue; use App\Filament\Pages\Governance\GovernanceInbox; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Navigation\CanonicalNavigationContext; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Livewire\Livewire; it('keeps findings intake secondary when opened from the governance inbox', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'owner'); @@ -39,7 +39,7 @@ tenantId: (int) $tenant->getKey(), familyKey: 'intake_findings', backLinkUrl: GovernanceInbox::getUrl(panel: 'admin', parameters: [ - 'tenant_id' => (string) $tenant->getKey(), + 'managed_environment_id' => (string) $tenant->getKey(), 'family' => 'intake_findings', ]), ); @@ -50,7 +50,7 @@ ])) ->actingAs($user) ->test(FindingsIntakeQueue::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenant->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenant->getKey()) ->assertActionVisible('return_to_governance_inbox') ->assertCanSeeTableRecords([$finding]) ->assertSee('Shared unassigned work') diff --git a/apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php b/apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php index 1dcac3ff..1dbd9a8d 100644 --- a/apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php +++ b/apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Findings\FindingsIntakeQueue; use App\Filament\Resources\FindingResource; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -13,7 +13,7 @@ function findingsIntakeActingUser(string $role = 'owner', string $workspaceRole = 'readonly'): array { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: $role, workspaceRole: $workspaceRole); test()->actingAs($user); @@ -38,7 +38,7 @@ function findingsIntakePage(?User $user = null, array $query = []) return $factory->test(FindingsIntakeQueue::class); } -function makeIntakeFinding(Tenant $tenant, array $attributes = []): Finding +function makeIntakeFinding(ManagedEnvironment $tenant, array $attributes = []): Finding { return Finding::factory()->for($tenant)->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, @@ -51,19 +51,19 @@ function makeIntakeFinding(Tenant $tenant, array $attributes = []): Finding it('shows only visible unassigned open findings and exposes fixed queue view counts', function (): void { [$user, $tenantA] = findingsIntakeActingUser(); - $tenantA->forceFill(['name' => 'Alpha Tenant'])->save(); + $tenantA->forceFill(['name' => 'Alpha ManagedEnvironment'])->save(); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Tenant Bravo', + 'name' => 'ManagedEnvironment Bravo', ]); createUserWithTenant($tenantB, $user, role: 'readonly', workspaceRole: 'readonly'); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Hidden Tenant', + 'name' => 'Hidden ManagedEnvironment', ]); $otherAssignee = User::factory()->create(); @@ -143,10 +143,10 @@ function makeIntakeFinding(Tenant $tenant, array $attributes = []): Finding it('defaults to the active tenant prefilter and lets the operator clear it without dropping intake scope', function (): void { [$user, $tenantA] = findingsIntakeActingUser(); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant($tenantB, $user, role: 'readonly', workspaceRole: 'readonly'); @@ -164,7 +164,7 @@ function makeIntakeFinding(Tenant $tenant, array $attributes = []): Finding ]); $component = findingsIntakePage($user) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantB->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantB->getKey()) ->assertCanSeeTableRecords([$findingB]) ->assertCanNotSeeTableRecords([$findingA]) ->assertActionVisible('clear_tenant_filter'); @@ -194,10 +194,10 @@ function makeIntakeFinding(Tenant $tenant, array $attributes = []): Finding it('keeps the needs triage view active when clearing the tenant prefilter', function (): void { [$user, $tenantA] = findingsIntakeActingUser(); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant($tenantB, $user, role: 'readonly', workspaceRole: 'readonly'); @@ -220,7 +220,7 @@ function makeIntakeFinding(Tenant $tenant, array $attributes = []): Finding ]); $component = findingsIntakePage($user, ['view' => 'needs_triage']) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantB->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantB->getKey()) ->assertCanSeeTableRecords([$tenantBTriage]) ->assertCanNotSeeTableRecords([$tenantATriage, $tenantBBacklog]); @@ -322,10 +322,10 @@ function makeIntakeFinding(Tenant $tenant, array $attributes = []): Finding it('renders both intake empty-state branches with the correct single recovery action', function (): void { [$user, $tenantA] = findingsIntakeActingUser(); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Work Tenant', + 'name' => 'Work ManagedEnvironment', ]); createUserWithTenant($tenantB, $user, role: 'readonly', workspaceRole: 'readonly'); diff --git a/apps/platform/tests/Feature/Findings/FindingsListFiltersTest.php b/apps/platform/tests/Feature/Findings/FindingsListFiltersTest.php index 9c8134f8..ed94b21b 100644 --- a/apps/platform/tests/Feature/Findings/FindingsListFiltersTest.php +++ b/apps/platform/tests/Feature/Findings/FindingsListFiltersTest.php @@ -69,7 +69,7 @@ function findingFilterIndicatorLabels($component): array \App\Models\FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $healthyAccepted->getKey(), 'requested_by_user_id' => (int) $requester->getKey(), 'owner_user_id' => (int) $requester->getKey(), @@ -375,7 +375,7 @@ function findingFilterIndicatorLabels($component): array \App\Models\FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $healthyAccepted->getKey(), 'requested_by_user_id' => (int) $requester->getKey(), 'owner_user_id' => (int) $requester->getKey(), diff --git a/apps/platform/tests/Feature/Findings/FindingsNotificationEventTest.php b/apps/platform/tests/Feature/Findings/FindingsNotificationEventTest.php index 64283a1d..fb9c1354 100644 --- a/apps/platform/tests/Feature/Findings/FindingsNotificationEventTest.php +++ b/apps/platform/tests/Feature/Findings/FindingsNotificationEventTest.php @@ -51,7 +51,7 @@ function runEvaluateAlertsForWorkspace(int $workspaceId): void { $operationRun = OperationRun::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'alerts.evaluate', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, diff --git a/apps/platform/tests/Feature/Findings/FindingsNotificationRoutingTest.php b/apps/platform/tests/Feature/Findings/FindingsNotificationRoutingTest.php index 136417d1..a6602245 100644 --- a/apps/platform/tests/Feature/Findings/FindingsNotificationRoutingTest.php +++ b/apps/platform/tests/Feature/Findings/FindingsNotificationRoutingTest.php @@ -4,7 +4,7 @@ use App\Models\AlertRule; use App\Models\Finding; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Notifications\Findings\FindingEventNotification; use App\Services\Auth\CapabilityResolver; @@ -109,8 +109,8 @@ function dispatchedFindingNotificationsFor(User $user): \Illuminate\Support\Coll 'assignee_user_id' => (int) $assignee->getKey(), ]); - TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $assignee->getKey()) ->delete(); diff --git a/apps/platform/tests/Feature/Findings/MyFindingsInboxNavigationContextTest.php b/apps/platform/tests/Feature/Findings/MyFindingsInboxNavigationContextTest.php index 41647011..5bdd826b 100644 --- a/apps/platform/tests/Feature/Findings/MyFindingsInboxNavigationContextTest.php +++ b/apps/platform/tests/Feature/Findings/MyFindingsInboxNavigationContextTest.php @@ -5,16 +5,16 @@ use App\Filament\Pages\Findings\MyFindingsInbox; use App\Filament\Pages\Governance\GovernanceInbox; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Navigation\CanonicalNavigationContext; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Livewire\Livewire; it('keeps my findings secondary when opened from the governance inbox', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'owner'); @@ -38,7 +38,7 @@ tenantId: (int) $tenant->getKey(), familyKey: 'assigned_findings', backLinkUrl: GovernanceInbox::getUrl(panel: 'admin', parameters: [ - 'tenant_id' => (string) $tenant->getKey(), + 'managed_environment_id' => (string) $tenant->getKey(), 'family' => 'assigned_findings', ]), ); @@ -48,7 +48,7 @@ ])) ->actingAs($user) ->test(MyFindingsInbox::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenant->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenant->getKey()) ->assertActionVisible('return_to_governance_inbox') ->assertCanSeeTableRecords([Finding::query()->where('subject_external_id', 'assigned-from-governance')->firstOrFail()]) ->assertSee('Assigned to me only') diff --git a/apps/platform/tests/Feature/Findings/MyWorkInboxTest.php b/apps/platform/tests/Feature/Findings/MyWorkInboxTest.php index f5f61c5e..ebe81743 100644 --- a/apps/platform/tests/Feature/Findings/MyWorkInboxTest.php +++ b/apps/platform/tests/Feature/Findings/MyWorkInboxTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Findings\MyFindingsInbox; use App\Filament\Resources\FindingResource; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -13,7 +13,7 @@ function myWorkInboxActingUser(string $role = 'owner', string $workspaceRole = 'readonly'): array { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: $role, workspaceRole: $workspaceRole); test()->actingAs($user); @@ -36,7 +36,7 @@ function myWorkInboxPage(?User $user = null, array $query = []) return $factory->test(MyFindingsInbox::class); } -function makeAssignedFindingForInbox(Tenant $tenant, User $assignee, array $attributes = []): Finding +function makeAssignedFindingForInbox(ManagedEnvironment $tenant, User $assignee, array $attributes = []): Finding { return Finding::factory()->for($tenant)->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, @@ -49,19 +49,19 @@ function makeAssignedFindingForInbox(Tenant $tenant, User $assignee, array $attr it('shows only visible assigned open findings and exposes the fixed filter contract', function (): void { [$user, $tenantA] = myWorkInboxActingUser(); - $tenantA->forceFill(['name' => 'Alpha Tenant'])->save(); + $tenantA->forceFill(['name' => 'Alpha ManagedEnvironment'])->save(); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Tenant Bravo', + 'name' => 'ManagedEnvironment Bravo', ]); createUserWithTenant($tenantB, $user, role: 'readonly', workspaceRole: 'readonly'); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Hidden Tenant', + 'name' => 'Hidden ManagedEnvironment', ]); $otherAssignee = User::factory()->create(); @@ -122,10 +122,10 @@ function makeAssignedFindingForInbox(Tenant $tenant, User $assignee, array $attr ], [ 'key' => 'tenant', - 'label' => 'Tenant', + 'label' => 'ManagedEnvironment', 'fixed' => false, 'options' => [ - ['value' => (string) $tenantA->getKey(), 'label' => 'Alpha Tenant'], + ['value' => (string) $tenantA->getKey(), 'label' => 'Alpha ManagedEnvironment'], ['value' => (string) $tenantB->getKey(), 'label' => $tenantB->name], ], ], @@ -153,10 +153,10 @@ function makeAssignedFindingForInbox(Tenant $tenant, User $assignee, array $attr it('defaults to the active tenant prefilter and lets the operator clear it without dropping personal scope', function (): void { [$user, $tenantA] = myWorkInboxActingUser(); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant($tenantB, $user, role: 'readonly', workspaceRole: 'readonly'); @@ -174,7 +174,7 @@ function makeAssignedFindingForInbox(Tenant $tenant, User $assignee, array $attr ]); $component = myWorkInboxPage($user) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantB->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantB->getKey()) ->assertCanSeeTableRecords([$findingB]) ->assertCanNotSeeTableRecords([$findingA]) ->assertActionVisible('clear_tenant_filter'); @@ -271,10 +271,10 @@ function makeAssignedFindingForInbox(Tenant $tenant, User $assignee, array $attr it('renders the tenant-prefilter empty-state branch and offers only a clear-filter recovery action', function (): void { [$user, $tenantA] = myWorkInboxActingUser(); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Work Tenant', + 'name' => 'Work ManagedEnvironment', ]); createUserWithTenant($tenantB, $user, role: 'readonly', workspaceRole: 'readonly'); diff --git a/apps/platform/tests/Feature/FoundationBackupTest.php b/apps/platform/tests/Feature/FoundationBackupTest.php index 7e1aa98f..47718dce 100644 --- a/apps/platform/tests/Feature/FoundationBackupTest.php +++ b/apps/platform/tests/Feature/FoundationBackupTest.php @@ -3,19 +3,19 @@ use App\Models\BackupItem; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\BackupService; use App\Services\Intune\FoundationSnapshotService; use App\Services\Intune\PolicySnapshotService; use Mockery\MockInterface; beforeEach(function () { - $this->tenant = Tenant::factory()->create(['status' => 'active']); + $this->tenant = ManagedEnvironment::factory()->create(['status' => 'active']); ensureDefaultProviderConnection($this->tenant); $this->policy = Policy::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_type' => 'deviceConfiguration', 'platform' => 'windows', 'display_name' => 'Test Policy', @@ -124,7 +124,7 @@ $this->mock(FoundationSnapshotService::class, function (MockInterface $mock) { $mock->shouldReceive('fetchAll') ->twice() - ->andReturnUsing(function (Tenant $tenant, string $foundationType): array { + ->andReturnUsing(function (ManagedEnvironment $tenant, string $foundationType): array { return match ($foundationType) { 'intuneRoleDefinition' => [ 'items' => [[ @@ -219,6 +219,6 @@ expect($assignmentItem->policy_id)->not->toBeNull(); expect($assignmentItem->policy_version_id)->not->toBeNull(); expect($assignmentItem->resolvedDisplayName())->toBe('Helpdesk Assignment'); - expect(Policy::query()->where('tenant_id', $this->tenant->id)->where('policy_type', 'intuneRoleDefinition')->count())->toBe(1); - expect(PolicyVersion::query()->where('tenant_id', $this->tenant->id)->where('policy_type', 'intuneRoleAssignment')->count())->toBe(1); + expect(Policy::query()->where('managed_environment_id', $this->tenant->id)->where('policy_type', 'intuneRoleDefinition')->count())->toBe(1); + expect(PolicyVersion::query()->where('managed_environment_id', $this->tenant->id)->where('policy_type', 'intuneRoleAssignment')->count())->toBe(1); }); diff --git a/apps/platform/tests/Feature/Governance/DecisionRegisterAuthorizationTest.php b/apps/platform/tests/Feature/Governance/DecisionRegisterAuthorizationTest.php index 268c9902..2a9c24d2 100644 --- a/apps/platform/tests/Feature/Governance/DecisionRegisterAuthorizationTest.php +++ b/apps/platform/tests/Feature/Governance/DecisionRegisterAuthorizationTest.php @@ -6,7 +6,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\FindingExceptionDecision; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -60,7 +60,7 @@ }); it('returns 403 for workspace members with no visible decisions in the default unfiltered register', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly', workspaceRole: 'readonly'); $this->actingAs($user) @@ -70,7 +70,7 @@ }); it('hides the decision register page when the default workspace register would resolve to 403', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly', workspaceRole: 'readonly'); $response = $this->actingAs($user) @@ -84,22 +84,22 @@ }); it('returns 404 for explicit tenant filters outside the actor scope', function (): void { - $visibleTenant = Tenant::factory()->create(['status' => 'active']); + $visibleTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $visibleTenant] = createUserWithTenant($visibleTenant, role: 'readonly', workspaceRole: 'readonly'); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, ]); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $visibleTenant->workspace_id]) - ->get(DecisionRegister::getUrl(panel: 'admin').'?tenant_id='.(string) $hiddenTenant->getKey()) + ->get(DecisionRegister::getUrl(panel: 'admin').'?managed_environment_id='.(string) $hiddenTenant->getKey()) ->assertNotFound(); }); it('allows readonly tenant members to open the decision register when visible decisions exist', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly', workspaceRole: 'readonly'); decisionRegisterAuthException( @@ -119,7 +119,7 @@ }); it('registers the decision register page once visible open decisions exist', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly', workspaceRole: 'readonly'); decisionRegisterAuthException( @@ -142,7 +142,7 @@ }); function decisionRegisterAuthException( - Tenant $tenant, + ManagedEnvironment $tenant, User $actor, string $status, string $validityState, @@ -155,7 +155,7 @@ function decisionRegisterAuthException( $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $actor->getKey(), 'owner_user_id' => (int) $actor->getKey(), @@ -169,7 +169,7 @@ function decisionRegisterAuthException( $decision = $exception->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $actor->getKey(), 'decision_type' => $decisionType, 'reason' => $decisionReason, diff --git a/apps/platform/tests/Feature/Governance/DecisionRegisterPageTest.php b/apps/platform/tests/Feature/Governance/DecisionRegisterPageTest.php index 6672eeef..65f61c51 100644 --- a/apps/platform/tests/Feature/Governance/DecisionRegisterPageTest.php +++ b/apps/platform/tests/Feature/Governance/DecisionRegisterPageTest.php @@ -6,7 +6,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\FindingExceptionDecision; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -14,17 +14,17 @@ uses(RefreshDatabase::class); it('renders open and recently closed decision rows for visible tenants only', function (): void { - $visibleTenant = Tenant::factory()->create([ + $visibleTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Visible Tenant', + 'name' => 'Visible ManagedEnvironment', 'external_id' => 'visible-tenant', ]); [$user, $visibleTenant] = createUserWithTenant($visibleTenant, role: 'readonly', workspaceRole: 'readonly'); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, - 'name' => 'Hidden Tenant', + 'name' => 'Hidden ManagedEnvironment', 'external_id' => 'hidden-tenant', ]); @@ -74,7 +74,7 @@ ->get(DecisionRegister::getUrl(panel: 'admin')) ->assertOk() ->assertSee('Decision register') - ->assertSee('Visible Tenant') + ->assertSee('Visible ManagedEnvironment') ->assertSee('Review approval') ->assertSee('Open decision') ->assertDontSee('Recently rejected closure reason') @@ -89,17 +89,17 @@ }); it('shows truthful filtered empty states for tenant and register-state filters', function (): void { - $alphaTenant = Tenant::factory()->create([ + $alphaTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); [$user, $alphaTenant] = createUserWithTenant($alphaTenant, role: 'owner', workspaceRole: 'owner'); - $bravoTenant = Tenant::factory()->create([ + $bravoTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $alphaTenant->workspace_id, - 'name' => 'Bravo Tenant', + 'name' => 'Bravo ManagedEnvironment', 'external_id' => 'bravo-tenant', ]); @@ -118,7 +118,7 @@ $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $alphaTenant->workspace_id]) - ->get(DecisionRegister::getUrl(panel: 'admin').'?tenant_id='.(string) $alphaTenant->getKey()) + ->get(DecisionRegister::getUrl(panel: 'admin').'?managed_environment_id='.(string) $alphaTenant->getKey()) ->assertOk() ->assertSee('This tenant filter is hiding other visible decision follow-through') ->assertSee('Clear tenant filter'); @@ -135,7 +135,7 @@ * @param array $decisionAttributes */ function decisionRegisterPageException( - Tenant $tenant, + ManagedEnvironment $tenant, User $actor, string $status, string $validityState, @@ -150,7 +150,7 @@ function decisionRegisterPageException( $exception = FindingException::query()->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $actor->getKey(), 'owner_user_id' => (int) $actor->getKey(), @@ -164,7 +164,7 @@ function decisionRegisterPageException( $decision = $exception->decisions()->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $actor->getKey(), 'decision_type' => $decisionType, 'reason' => $decisionReason, diff --git a/apps/platform/tests/Feature/Governance/GovernanceInboxAuthorizationTest.php b/apps/platform/tests/Feature/Governance/GovernanceInboxAuthorizationTest.php index 2b83361f..237941a8 100644 --- a/apps/platform/tests/Feature/Governance/GovernanceInboxAuthorizationTest.php +++ b/apps/platform/tests/Feature/Governance/GovernanceInboxAuthorizationTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\Governance\GovernanceInbox; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -73,7 +73,7 @@ }); it('allows readonly tenant members to open the governance inbox through operations-family visibility', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly', workspaceRole: 'readonly'); $this->actingAs($user) @@ -84,16 +84,16 @@ }); it('returns 404 for explicit tenant filters outside the actor scope', function (): void { - $visibleTenant = Tenant::factory()->create(['status' => 'active']); + $visibleTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $visibleTenant] = createUserWithTenant($visibleTenant, role: 'readonly', workspaceRole: 'readonly'); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $visibleTenant->workspace_id, ]); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $visibleTenant->workspace_id]) - ->get(GovernanceInbox::getUrl(panel: 'admin').'?tenant_id='.(string) $hiddenTenant->getKey()) + ->get(GovernanceInbox::getUrl(panel: 'admin').'?managed_environment_id='.(string) $hiddenTenant->getKey()) ->assertNotFound(); }); \ No newline at end of file diff --git a/apps/platform/tests/Feature/Governance/GovernanceInboxNavigationContextConvergenceTest.php b/apps/platform/tests/Feature/Governance/GovernanceInboxNavigationContextConvergenceTest.php index 7b466d79..fe48f140 100644 --- a/apps/platform/tests/Feature/Governance/GovernanceInboxNavigationContextConvergenceTest.php +++ b/apps/platform/tests/Feature/Governance/GovernanceInboxNavigationContextConvergenceTest.php @@ -5,13 +5,13 @@ use App\Filament\Pages\Governance\GovernanceInbox; use App\Models\Finding; use App\Models\FindingException; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; it('launches the finding exceptions lane with tenant and family return context', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'manager'); @@ -26,7 +26,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -40,14 +40,14 @@ $response = $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) - ->get(GovernanceInbox::getUrl(panel: 'admin').'?tenant_id='.(string) $tenant->getKey().'&family=finding_exceptions'); + ->get(GovernanceInbox::getUrl(panel: 'admin').'?managed_environment_id='.(string) $tenant->getKey().'&family=finding_exceptions'); $response->assertOk() ->assertSee('Finding exceptions') ->assertSee('Open finding exceptions') ->assertSee('Governance convergence request') ->assertSee('nav%5Bfamily_key%5D=finding_exceptions', false) - ->assertSee('nav%5Bback_url%5D='.urlencode(GovernanceInbox::getUrl(panel: 'admin').'?tenant_id='.(string) $tenant->getKey().'&family=finding_exceptions'), false) + ->assertSee('nav%5Bback_url%5D='.urlencode(GovernanceInbox::getUrl(panel: 'admin').'?managed_environment_id='.(string) $tenant->getKey().'&family=finding_exceptions'), false) ->assertSee('exception='.(string) $exception->getKey(), false) ->assertDontSee('Open my findings') ->assertDontSee('Open findings intake'); diff --git a/apps/platform/tests/Feature/Governance/GovernanceInboxNavigationContextTest.php b/apps/platform/tests/Feature/Governance/GovernanceInboxNavigationContextTest.php index 506e626e..fbb03b1d 100644 --- a/apps/platform/tests/Feature/Governance/GovernanceInboxNavigationContextTest.php +++ b/apps/platform/tests/Feature/Governance/GovernanceInboxNavigationContextTest.php @@ -6,7 +6,7 @@ use App\Filament\Pages\Governance\GovernanceInbox; use App\Models\Finding; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Navigation\CanonicalNavigationContext; use App\Support\OperationRunLinks; use App\Support\OperationRunOutcome; @@ -15,9 +15,9 @@ use Filament\Facades\Filament; it('embeds canonical governance inbox navigation context into source links', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'owner'); diff --git a/apps/platform/tests/Feature/Governance/GovernanceInboxPageTest.php b/apps/platform/tests/Feature/Governance/GovernanceInboxPageTest.php index 52610a5d..1d294905 100644 --- a/apps/platform/tests/Feature/Governance/GovernanceInboxPageTest.php +++ b/apps/platform/tests/Feature/Governance/GovernanceInboxPageTest.php @@ -7,7 +7,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Support\BackupHealth\TenantBackupHealthResolver; use App\Support\OperationRunOutcome; @@ -17,17 +17,17 @@ use App\Support\Workspaces\WorkspaceContext; it('renders visible governance attention sections on the governance inbox page', function (): void { - $alphaTenant = Tenant::factory()->create([ + $alphaTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); [$user, $alphaTenant] = createUserWithTenant($alphaTenant, role: 'owner', workspaceRole: 'owner'); - $bravoTenant = Tenant::factory()->create([ + $bravoTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $alphaTenant->workspace_id, - 'name' => 'Bravo Tenant', + 'name' => 'Bravo ManagedEnvironment', 'external_id' => 'bravo-tenant', ]); @@ -57,7 +57,7 @@ FindingException::query()->create([ 'workspace_id' => (int) $alphaTenant->workspace_id, - 'tenant_id' => (int) $alphaTenant->getKey(), + 'managed_environment_id' => (int) $alphaTenant->getKey(), 'finding_id' => (int) $exceptionFinding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -78,7 +78,7 @@ ]); AlertDelivery::factory()->create([ - 'tenant_id' => null, + 'managed_environment_id' => null, 'workspace_id' => (int) $alphaTenant->workspace_id, 'status' => AlertDelivery::STATUS_FAILED, 'payload' => [ @@ -122,17 +122,17 @@ }); it('renders honest empty states for tenant and family filtering on the governance inbox page', function (): void { - $alphaTenant = Tenant::factory()->create([ + $alphaTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); [$user, $alphaTenant] = createUserWithTenant($alphaTenant, role: 'owner', workspaceRole: 'owner'); - $bravoTenant = Tenant::factory()->create([ + $bravoTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $alphaTenant->workspace_id, - 'name' => 'Bravo Tenant', + 'name' => 'Bravo ManagedEnvironment', 'external_id' => 'bravo-tenant', ]); @@ -146,21 +146,21 @@ ->create(); AlertDelivery::factory()->create([ - 'tenant_id' => null, + 'managed_environment_id' => null, 'workspace_id' => (int) $alphaTenant->workspace_id, 'status' => AlertDelivery::STATUS_FAILED, ]); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $alphaTenant->workspace_id]) - ->get(GovernanceInbox::getUrl(panel: 'admin').'?tenant_id='.(string) $alphaTenant->getKey()) + ->get(GovernanceInbox::getUrl(panel: 'admin').'?managed_environment_id='.(string) $alphaTenant->getKey()) ->assertOk() ->assertSee('This tenant filter is hiding other visible attention') ->assertSee('Clear tenant filter'); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $alphaTenant->workspace_id]) - ->get(GovernanceInbox::getUrl(panel: 'admin').'?tenant_id='.(string) $alphaTenant->getKey().'&family=alert_delivery_failures') + ->get(GovernanceInbox::getUrl(panel: 'admin').'?managed_environment_id='.(string) $alphaTenant->getKey().'&family=alert_delivery_failures') ->assertOk() ->assertSee('Alert delivery failures') ->assertSee('No failed alert deliveries match this tenant filter right now.') @@ -168,9 +168,9 @@ }); it('omits the finding exceptions lane when the workspace capability is not visible', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'readonly'); @@ -190,7 +190,7 @@ FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $exceptionFinding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), diff --git a/apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php b/apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php index a999727f..74c8e80e 100644 --- a/apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php +++ b/apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php @@ -94,8 +94,8 @@ use App\Models\ProviderConnection; use App\Models\RestoreRun; use App\Models\ReviewPack; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -193,7 +193,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser expect($tenantResource?->hasPanelScope(ActionSurfacePanelScope::Admin))->toBeTrue(); expect($policyResource)->not->toBeNull(); - expect($policyResource?->hasPanelScope(ActionSurfacePanelScope::Tenant))->toBeTrue(); + expect($policyResource?->hasPanelScope(ActionSurfacePanelScope::ManagedEnvironment))->toBeTrue(); }); it('requires non-empty reasons for every baseline exemption', function (): void { @@ -255,7 +255,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); @@ -323,7 +323,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Nightly backup', 'is_enabled' => true, 'timezone' => 'UTC', @@ -387,7 +387,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Nightly backup', 'is_enabled' => true, 'timezone' => 'UTC', @@ -425,17 +425,17 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'metadata' => [], ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $backupItem = BackupItem::factory()->for($backupSet)->for($tenant)->create([ @@ -496,8 +496,8 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser $tenant->getKey() => ['role' => 'readonly'], ]); - $membership = TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + $membership = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $member->getKey()) ->firstOrFail(); @@ -577,11 +577,11 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'created_by' => 'versions-surface@example.test', 'metadata' => [], @@ -635,7 +635,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser ->get(TenantResource::getUrl('memberships', ['record' => $tenant->getRouteKey()], panel: 'admin')) ->assertOk() ->assertSee('Manage tenant memberships') - ->assertSee('Tenant access is managed here. Use the tenant overview for provider state, verification, and operational context.') + ->assertSee('ManagedEnvironment access is managed here. Use the tenant overview for provider state, verification, and operational context.') ->assertSee('Back to tenant overview') ->assertDontSeeLivewire(\App\Filament\Widgets\Tenant\RecentOperationsSummary::class) ->assertDontSeeLivewire(\App\Filament\Widgets\Tenant\TenantVerificationReport::class) @@ -663,7 +663,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser }); it('keeps tenant detail header actions aligned with the shared administrative family while preserving workflow-heavy exceptions', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createMinimalUserWithTenant( tenant: $tenant, role: 'owner', @@ -671,7 +671,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser ); ProviderConnection::factory()->platform()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'is_default' => true, @@ -762,12 +762,12 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Backup Items Surface Policy', ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); BackupItem::factory()->for($backupSet)->for($tenant)->create([ @@ -1275,7 +1275,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser ->assertTableEmptyStateActionsExistInOrder(['create_first_snapshot']); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -1336,7 +1336,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -1375,12 +1375,12 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'status' => 'completed', ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'status' => 'completed', 'deleted_at' => null, @@ -1494,11 +1494,11 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'metadata' => [], ]); @@ -1526,9 +1526,9 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser }); it('uses canonical tenantless View run links on representative operation links', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, ]); @@ -1549,7 +1549,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', @@ -1617,7 +1617,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -1634,7 +1634,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser $finding = Finding::factory()->for($tenant)->create(); $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -1694,7 +1694,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -1870,9 +1870,9 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser 'name' => 'System Directory Workspace', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'System Directory Tenant', + 'name' => 'System Directory ManagedEnvironment', ]); actionSurfaceSystemPanelContext([ @@ -1909,10 +1909,10 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser }); it('keeps system access logs scan-only without row or bulk actions', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $log = AuditLog::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'action' => 'platform.auth.login', 'status' => 'success', @@ -1942,7 +1942,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser Filament::setTenant($tenant, true); $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); $livewire = Livewire::test(ListInventoryItems::class); @@ -1995,7 +1995,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $policy = Policy::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-action-surface-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy Action Surface', @@ -2124,7 +2124,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner', ensureDefaultMicrosoftProviderConnection: false); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'is_enabled' => true, @@ -2178,7 +2178,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser [$user, $tenant] = createMinimalUserWithTenant(role: 'owner', ensureDefaultMicrosoftProviderConnection: false); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'is_enabled' => true, @@ -2243,7 +2243,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser ]); $delivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), ]); @@ -2279,13 +2279,13 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser Queue::assertPushed(SyncPoliciesJob::class); $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'policy.sync') ->latest('id') ->first(); expect($run)->not->toBeNull(); - expect((int) $run?->tenant_id)->toBe((int) $tenant->getKey()); + expect((int) $run?->managed_environment_id)->toBe((int) $tenant->getKey()); expect((int) $run?->workspace_id)->toBe((int) $tenant->workspace_id); expect((string) $run?->initiator_name)->toBe((string) $user->name); }); @@ -2379,7 +2379,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $approver->getKey(), 'owner_user_id' => (int) $approver->getKey(), @@ -2442,7 +2442,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); diff --git a/apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php b/apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php index 4fa1b68d..05bf8a97 100644 --- a/apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php +++ b/apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php @@ -118,7 +118,7 @@ function actionSurfaceComponent(string $className): ActionSurfaceDiscoveredCompo return new ActionSurfaceDiscoveredComponent( className: $className, componentType: ActionSurfaceComponentType::Resource, - panelScopes: [ActionSurfacePanelScope::Tenant], + panelScopes: [ActionSurfacePanelScope::ManagedEnvironment], ); } diff --git a/apps/platform/tests/Feature/Guards/AdminTenantResolverGuardTest.php b/apps/platform/tests/Feature/Guards/AdminTenantResolverGuardTest.php index 73e34734..a4e72413 100644 --- a/apps/platform/tests/Feature/Guards/AdminTenantResolverGuardTest.php +++ b/apps/platform/tests/Feature/Guards/AdminTenantResolverGuardTest.php @@ -89,12 +89,12 @@ function adminTenantResolverExceptionFiles(): array expect($resolverContents)->not->toBeFalse() ->and($resolverContents)->toContain('tenantOwnedPanelContext(request())') - ->and($resolverContents)->toContain('Tenant::current()'); + ->and($resolverContents)->toContain('ManagedEnvironment::current()'); expect($contents)->not->toBeFalse() ->and($contents)->toContain('use ResolvesPanelTenantContext;') ->and($contents)->not->toContain('activeEntitledTenant(request())') - ->and($contents)->not->toContain('Tenant::current()'); + ->and($contents)->not->toContain('ManagedEnvironment::current()'); }); it('keeps first-slice admin trusted-state surfaces inside the canonical admin resolver guard inventory', function (): void { diff --git a/apps/platform/tests/Feature/Guards/AdminWorkspaceRoutesGuardTest.php b/apps/platform/tests/Feature/Guards/AdminWorkspaceRoutesGuardTest.php index dfa8fe48..4cd33f04 100644 --- a/apps/platform/tests/Feature/Guards/AdminWorkspaceRoutesGuardTest.php +++ b/apps/platform/tests/Feature/Guards/AdminWorkspaceRoutesGuardTest.php @@ -3,10 +3,10 @@ declare(strict_types=1); use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; it('returns 404 for platform-guard sessions on admin workspace-scoped routes', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $workspace = $tenant->workspace; expect($workspace)->not->toBeNull(); diff --git a/apps/platform/tests/Feature/Guards/NoLegacyTenantGraphOptionsTest.php b/apps/platform/tests/Feature/Guards/NoLegacyTenantGraphOptionsTest.php index 57df4f65..5455d61f 100644 --- a/apps/platform/tests/Feature/Guards/NoLegacyTenantGraphOptionsTest.php +++ b/apps/platform/tests/Feature/Guards/NoLegacyTenantGraphOptionsTest.php @@ -2,7 +2,7 @@ use Illuminate\Support\Collection; -it('Spec088 blocks legacy Tenant::graphOptions call sites in app/', function (): void { +it('Spec088 blocks legacy ManagedEnvironment::graphOptions call sites in app/', function (): void { $root = base_path(); $self = realpath(__FILE__); @@ -22,8 +22,8 @@ $forbiddenPatterns = [ '/\$tenant->graphOptions\s*\(/', - // Avoid failing on the kill-switch error message string in app/Models/Tenant.php. - '/(? $files */ @@ -95,7 +95,7 @@ $howToFix = <<<'TXT' Legacy tenant Graph options accessor usage detected. -Do not call `$tenant->graphOptions()` or `Tenant::graphOptions()` anywhere under `app/`. +Do not call `$tenant->graphOptions()` or `ManagedEnvironment::graphOptions()` anywhere under `app/`. Use provider connection resolution instead: - `ProviderConnectionResolver::resolveDefault($tenant, 'microsoft')` diff --git a/apps/platform/tests/Feature/Guards/NoPlatformCredentialFallbackTest.php b/apps/platform/tests/Feature/Guards/NoPlatformCredentialFallbackTest.php index 12a0dae5..2184e7d6 100644 --- a/apps/platform/tests/Feature/Guards/NoPlatformCredentialFallbackTest.php +++ b/apps/platform/tests/Feature/Guards/NoPlatformCredentialFallbackTest.php @@ -34,7 +34,7 @@ } if ($relativePath === 'app/Filament/Resources/TenantResource.php') { - preg_match('/public static function adminConsentUrl\(Tenant \$tenant\): \?string\s*\{(?P.*?)^ \}/ms', $contents, $matches); + preg_match('/public static function adminConsentUrl\(ManagedEnvironment \$tenant\): \?string\s*\{(?P.*?)^ \}/ms', $contents, $matches); $contents = is_string($matches['body'] ?? null) ? (string) $matches['body'] : ''; } @@ -85,7 +85,7 @@ } if ($relativePath === 'app/Filament/Resources/TenantResource.php') { - preg_match('/public static function adminConsentUrl\(Tenant \$tenant\): \?string\s*\{(?P.*?)^ \}/ms', $contents, $matches); + preg_match('/public static function adminConsentUrl\(ManagedEnvironment \$tenant\): \?string\s*\{(?P.*?)^ \}/ms', $contents, $matches); $contents = is_string($matches['body'] ?? null) ? (string) $matches['body'] : ''; } diff --git a/apps/platform/tests/Feature/Guards/NoTenantCredentialRuntimeReadsSpec081Test.php b/apps/platform/tests/Feature/Guards/NoTenantCredentialRuntimeReadsSpec081Test.php index 0826930e..dc43b3f6 100644 --- a/apps/platform/tests/Feature/Guards/NoTenantCredentialRuntimeReadsSpec081Test.php +++ b/apps/platform/tests/Feature/Guards/NoTenantCredentialRuntimeReadsSpec081Test.php @@ -21,7 +21,7 @@ $allowlist = [ // Model cast declaration only (not a runtime write path). - 'app/Models/Tenant.php', + 'app/Models/ManagedEnvironment.php', ]; $forbiddenPatterns = [ @@ -124,7 +124,7 @@ $allowlist = [ // NOTE: Shrink this list while finishing Spec081 service cutovers. - 'app/Models/Tenant.php', + 'app/Models/ManagedEnvironment.php', 'app/Services/Intune/TenantConfigService.php', 'app/Services/Intune/TenantPermissionService.php', 'app/Console/Commands/ReclassifyEnrollmentConfigurations.php', @@ -213,7 +213,7 @@ ); }); -it('Spec081 blocks Tenant::graphOptions helper usage in cutover runtime services and workers', function (): void { +it('Spec081 blocks ManagedEnvironment::graphOptions helper usage in cutover runtime services and workers', function (): void { $root = base_path(); $files = [ @@ -245,20 +245,20 @@ continue; } - if (! preg_match('/\$tenant->graphOptions\(|Tenant::graphOptions\(/', $contents)) { + if (! preg_match('/\$tenant->graphOptions\(|ManagedEnvironment::graphOptions\(/', $contents)) { continue; } $lines = preg_split('/\R/', $contents) ?: []; foreach ($lines as $index => $line) { - if (preg_match('/\$tenant->graphOptions\(|Tenant::graphOptions\(/', $line)) { + if (preg_match('/\$tenant->graphOptions\(|ManagedEnvironment::graphOptions\(/', $line)) { $hits[] = $relativePath.':'.($index + 1).' -> '.trim($line); } } } - expect($hits)->toBeEmpty("Tenant::graphOptions usage detected in cutover runtime paths:\n".implode("\n", $hits)); + expect($hits)->toBeEmpty("ManagedEnvironment::graphOptions usage detected in cutover runtime paths:\n".implode("\n", $hits)); }); it('Spec081 enforces ProviderGateway as the single runtime entry point for provider credential reads', function (): void { diff --git a/apps/platform/tests/Feature/Guards/OperationRunLinkContractGuardTest.php b/apps/platform/tests/Feature/Guards/OperationRunLinkContractGuardTest.php index cd120840..5c0f067c 100644 --- a/apps/platform/tests/Feature/Guards/OperationRunLinkContractGuardTest.php +++ b/apps/platform/tests/Feature/Guards/OperationRunLinkContractGuardTest.php @@ -40,8 +40,8 @@ function operationRunLinkContractAllowlist(): array return [ $paths['admin_panel_provider'] => 'Admin panel navigation is bootstrapping infrastructure and intentionally links to the canonical collection route before request-scoped navigation context exists.', - $paths['tenant_panel_provider'] => 'Tenant panel navigation is bootstrapping infrastructure and intentionally links to the canonical collection route before tenant-specific helper context is owned by the source surface.', - $paths['ensure_filament_tenant_selected'] => 'Tenant-selection middleware owns redirect/navigation fallback infrastructure and must not fabricate source-surface navigation context.', + $paths['tenant_panel_provider'] => 'ManagedEnvironment panel navigation is bootstrapping infrastructure and intentionally links to the canonical collection route before tenant-specific helper context is owned by the source surface.', + $paths['ensure_filament_tenant_selected'] => 'ManagedEnvironment-selection middleware owns redirect/navigation fallback infrastructure and must not fabricate source-surface navigation context.', $paths['clear_tenant_context_controller'] => 'Clear-tenant redirects preserve an explicit redirect contract and cannot depend on UI helper context.', ]; } diff --git a/apps/platform/tests/Feature/Guards/ProviderConnectionNeutralityGuardTest.php b/apps/platform/tests/Feature/Guards/ProviderConnectionNeutralityGuardTest.php index ec941bb3..8b8bc04d 100644 --- a/apps/platform/tests/Feature/Guards/ProviderConnectionNeutralityGuardTest.php +++ b/apps/platform/tests/Feature/Guards/ProviderConnectionNeutralityGuardTest.php @@ -17,7 +17,7 @@ $forbiddenFragments = [ 'Entra tenant ID', - 'Entra Tenant ID', + 'Entra ManagedEnvironment ID', 'Directory (tenant) ID', 'No Microsoft connections found', 'Graph API calls', diff --git a/apps/platform/tests/Feature/Hardening/BlockedWriteAuditLogTest.php b/apps/platform/tests/Feature/Hardening/BlockedWriteAuditLogTest.php index 0b0f7f20..6b723098 100644 --- a/apps/platform/tests/Feature/Hardening/BlockedWriteAuditLogTest.php +++ b/apps/platform/tests/Feature/Hardening/BlockedWriteAuditLogTest.php @@ -22,7 +22,7 @@ 'rbac_last_checked_at' => null, ]); - $backupSet = BackupSet::factory()->create(['tenant_id' => $tenant->id]); + $backupSet = BackupSet::factory()->create(['managed_environment_id' => $tenant->id]); $this->actingAs($user); $tenant->makeCurrent(); @@ -41,7 +41,7 @@ } $auditLog = AuditLog::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('action', 'intune_rbac.write_blocked') ->first(); @@ -63,7 +63,7 @@ 'rbac_last_checked_at' => now(), ]); - $backupSet = BackupSet::factory()->create(['tenant_id' => $tenant->id]); + $backupSet = BackupSet::factory()->create(['managed_environment_id' => $tenant->id]); $this->actingAs($user); $tenant->makeCurrent(); @@ -82,7 +82,7 @@ } $auditLog = AuditLog::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('action', 'intune_rbac.write_blocked') ->first(); @@ -106,7 +106,7 @@ 'rbac_last_checked_at' => now(), ]); - $backupSet = BackupSet::factory()->create(['tenant_id' => $tenant->id]); + $backupSet = BackupSet::factory()->create(['managed_environment_id' => $tenant->id]); $this->actingAs($user); $tenant->makeCurrent(); @@ -125,7 +125,7 @@ } $auditLog = AuditLog::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('action', 'intune_rbac.write_blocked') ->first(); diff --git a/apps/platform/tests/Feature/Hardening/ExecuteRestoreRunJobGateTest.php b/apps/platform/tests/Feature/Hardening/ExecuteRestoreRunJobGateTest.php index e94e6168..16c022f8 100644 --- a/apps/platform/tests/Feature/Hardening/ExecuteRestoreRunJobGateTest.php +++ b/apps/platform/tests/Feature/Hardening/ExecuteRestoreRunJobGateTest.php @@ -3,7 +3,7 @@ use App\Jobs\ExecuteRestoreRunJob; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\AuditLogger; use App\Services\Intune\RestoreService; use App\Services\OperationRunService; @@ -20,20 +20,20 @@ }); test('execute restore run job marks run failed when rbac_status is not_configured', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'not_configured', 'rbac_last_checked_at' => null, ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'requested_by' => 'actor@example.com', 'is_dry_run' => false, @@ -75,20 +75,20 @@ }); test('execute restore run job marks run failed when rbac_status is stale', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now()->subHours(48), ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'requested_by' => 'actor@example.com', 'is_dry_run' => false, diff --git a/apps/platform/tests/Feature/Hardening/RestoreAssignmentsJobGateTest.php b/apps/platform/tests/Feature/Hardening/RestoreAssignmentsJobGateTest.php index 199a9ab3..d197e8fa 100644 --- a/apps/platform/tests/Feature/Hardening/RestoreAssignmentsJobGateTest.php +++ b/apps/platform/tests/Feature/Hardening/RestoreAssignmentsJobGateTest.php @@ -3,7 +3,7 @@ use App\Jobs\RestoreAssignmentsJob; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\AssignmentRestoreService; use App\Services\OperationRunService; use App\Support\OperationRunOutcome; @@ -20,20 +20,20 @@ }); test('restore assignments job marks run failed when rbac is stale', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now()->subHours(48), ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'requested_by' => 'actor@example.com', 'is_dry_run' => false, @@ -92,20 +92,20 @@ }); test('restore assignments job marks run failed when rbac is not configured', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => null, 'rbac_last_checked_at' => null, ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'requested_by' => 'actor@example.com', 'is_dry_run' => false, diff --git a/apps/platform/tests/Feature/Hardening/RestoreRunActionDisabledStateTest.php b/apps/platform/tests/Feature/Hardening/RestoreRunActionDisabledStateTest.php index 9b58cf16..c0178ec9 100644 --- a/apps/platform/tests/Feature/Hardening/RestoreRunActionDisabledStateTest.php +++ b/apps/platform/tests/Feature/Hardening/RestoreRunActionDisabledStateTest.php @@ -17,10 +17,10 @@ 'rbac_last_checked_at' => null, ]); - $backupSet = BackupSet::factory()->create(['tenant_id' => $tenant->id]); + $backupSet = BackupSet::factory()->create(['managed_environment_id' => $tenant->id]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', ]); @@ -41,10 +41,10 @@ 'rbac_last_checked_at' => now()->subMinutes(30), ]); - $backupSet = BackupSet::factory()->create(['tenant_id' => $tenant->id]); + $backupSet = BackupSet::factory()->create(['managed_environment_id' => $tenant->id]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', ]); @@ -65,10 +65,10 @@ 'rbac_last_checked_at' => null, ]); - $backupSet = BackupSet::factory()->create(['tenant_id' => $tenant->id]); + $backupSet = BackupSet::factory()->create(['managed_environment_id' => $tenant->id]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', ]); diff --git a/apps/platform/tests/Feature/Hardening/RestoreStartGateBypassTest.php b/apps/platform/tests/Feature/Hardening/RestoreStartGateBypassTest.php index c4b2c8a9..403bd24d 100644 --- a/apps/platform/tests/Feature/Hardening/RestoreStartGateBypassTest.php +++ b/apps/platform/tests/Feature/Hardening/RestoreStartGateBypassTest.php @@ -1,7 +1,7 @@ set('tenantpilot.hardening.intune_write_gate.enabled', false); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => null, 'rbac_last_checked_at' => null, ]); @@ -19,7 +19,7 @@ ->once() ->withArgs(function (string $message, array $context) use ($tenant): bool { return str_contains($message, 'write gate is disabled') - && ($context['tenant_id'] ?? null) === $tenant->getKey() + && ($context['managed_environment_id'] ?? null) === $tenant->getKey() && ($context['operation_type'] ?? null) === 'restore.execute'; }); @@ -34,7 +34,7 @@ test('wouldBlock returns false when gate is disabled', function () { config()->set('tenantpilot.hardening.intune_write_gate.enabled', false); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => null, 'rbac_last_checked_at' => null, ]); diff --git a/apps/platform/tests/Feature/Hardening/RestoreStartGateNotConfiguredTest.php b/apps/platform/tests/Feature/Hardening/RestoreStartGateNotConfiguredTest.php index 77687942..0e75fcb9 100644 --- a/apps/platform/tests/Feature/Hardening/RestoreStartGateNotConfiguredTest.php +++ b/apps/platform/tests/Feature/Hardening/RestoreStartGateNotConfiguredTest.php @@ -2,7 +2,7 @@ use App\Contracts\Hardening\WriteGateInterface; use App\Exceptions\Hardening\ProviderAccessHardeningRequired; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); @@ -13,7 +13,7 @@ }); test('gate blocks when rbac_status is null', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => null, 'rbac_last_checked_at' => null, ]); @@ -33,7 +33,7 @@ }); test('gate blocks when rbac_status is not_configured', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'not_configured', 'rbac_last_checked_at' => null, ]); @@ -50,7 +50,7 @@ }); test('wouldBlock returns true when rbac_status is null', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => null, 'rbac_last_checked_at' => null, ]); @@ -59,7 +59,7 @@ }); test('wouldBlock returns true when rbac_status is not_configured', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'not_configured', 'rbac_last_checked_at' => null, ]); diff --git a/apps/platform/tests/Feature/Hardening/RestoreStartGatePassesTest.php b/apps/platform/tests/Feature/Hardening/RestoreStartGatePassesTest.php index 2b72295b..f1b58c25 100644 --- a/apps/platform/tests/Feature/Hardening/RestoreStartGatePassesTest.php +++ b/apps/platform/tests/Feature/Hardening/RestoreStartGatePassesTest.php @@ -1,7 +1,7 @@ create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now()->subHours(1), ]); @@ -26,7 +26,7 @@ }); test('wouldBlock returns false when rbac_status is ok and fresh', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now()->subMinutes(30), ]); @@ -35,7 +35,7 @@ }); test('gate passes for configured status with fresh timestamp', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'configured', 'rbac_last_checked_at' => now()->subHours(1), ]); @@ -49,7 +49,7 @@ }); test('gate passes for manual_assignment_required with fresh timestamp', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'manual_assignment_required', 'rbac_last_checked_at' => now()->subHours(1), ]); diff --git a/apps/platform/tests/Feature/Hardening/RestoreStartGateStaleTest.php b/apps/platform/tests/Feature/Hardening/RestoreStartGateStaleTest.php index e7637335..6f0f8e64 100644 --- a/apps/platform/tests/Feature/Hardening/RestoreStartGateStaleTest.php +++ b/apps/platform/tests/Feature/Hardening/RestoreStartGateStaleTest.php @@ -2,7 +2,7 @@ use App\Contracts\Hardening\WriteGateInterface; use App\Exceptions\Hardening\ProviderAccessHardeningRequired; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); @@ -13,7 +13,7 @@ }); test('gate blocks when rbac_status is ok but rbac_last_checked_at is stale', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now()->subHours(25), ]); @@ -30,7 +30,7 @@ }); test('gate blocks when rbac_status is ok but rbac_last_checked_at is null', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => null, ]); @@ -46,7 +46,7 @@ }); test('gate blocks at exact threshold boundary', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now()->subHours(24), ]); @@ -64,7 +64,7 @@ test('gate respects custom freshness threshold', function () { config()->set('tenantpilot.hardening.intune_write_gate.freshness_threshold_hours', 1); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now()->subHours(2), ]); diff --git a/apps/platform/tests/Feature/Hardening/RestoreStartGateUnhealthyTest.php b/apps/platform/tests/Feature/Hardening/RestoreStartGateUnhealthyTest.php index 0454482b..39986c0d 100644 --- a/apps/platform/tests/Feature/Hardening/RestoreStartGateUnhealthyTest.php +++ b/apps/platform/tests/Feature/Hardening/RestoreStartGateUnhealthyTest.php @@ -2,7 +2,7 @@ use App\Contracts\Hardening\WriteGateInterface; use App\Exceptions\Hardening\ProviderAccessHardeningRequired; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); @@ -13,7 +13,7 @@ }); test('gate blocks when rbac_status is degraded', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'degraded', 'rbac_last_checked_at' => now(), ]); @@ -30,7 +30,7 @@ }); test('gate blocks when rbac_status is failed', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'failed', 'rbac_last_checked_at' => now(), ]); @@ -46,7 +46,7 @@ }); test('gate blocks when rbac_status is error', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'error', 'rbac_last_checked_at' => now(), ]); @@ -62,7 +62,7 @@ }); test('wouldBlock returns true for all unhealthy statuses', function (string $status) { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => $status, 'rbac_last_checked_at' => now(), ]); diff --git a/apps/platform/tests/Feature/Intune/PolicySnapshotFingerprintIsolationTest.php b/apps/platform/tests/Feature/Intune/PolicySnapshotFingerprintIsolationTest.php index e7e4c585..663e55e2 100644 --- a/apps/platform/tests/Feature/Intune/PolicySnapshotFingerprintIsolationTest.php +++ b/apps/platform/tests/Feature/Intune/PolicySnapshotFingerprintIsolationTest.php @@ -14,12 +14,12 @@ [$userB, $tenantB] = createUserWithTenant(role: 'owner'); $policyA = Policy::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'policy_type' => 'settingsCatalogPolicy', ]); $policyB = Policy::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'policy_type' => 'settingsCatalogPolicy', ]); diff --git a/apps/platform/tests/Feature/Intune/PolicySnapshotRedactionTest.php b/apps/platform/tests/Feature/Intune/PolicySnapshotRedactionTest.php index 1c16f73c..ebc46682 100644 --- a/apps/platform/tests/Feature/Intune/PolicySnapshotRedactionTest.php +++ b/apps/platform/tests/Feature/Intune/PolicySnapshotRedactionTest.php @@ -18,7 +18,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'settingsCatalogPolicy', 'platform' => 'windows10', ]); diff --git a/apps/platform/tests/Feature/Inventory/InventoryLinksNonUuidIdsTest.php b/apps/platform/tests/Feature/Inventory/InventoryLinksNonUuidIdsTest.php index 1293e94e..74df0d25 100644 --- a/apps/platform/tests/Feature/Inventory/InventoryLinksNonUuidIdsTest.php +++ b/apps/platform/tests/Feature/Inventory/InventoryLinksNonUuidIdsTest.php @@ -2,7 +2,7 @@ use App\Models\InventoryItem; use App\Models\InventoryLink; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Inventory\DependencyExtractionService; use App\Support\Enums\RelationshipType; use Illuminate\Support\Facades\DB; @@ -10,7 +10,7 @@ it('stores non-UUID identifiers in inventory_links on PostgreSQL', function () { $driver = DB::getDriverName(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $item = InventoryItem::factory()->for($tenant)->create([ 'external_id' => '11111111-1111-1111-1111-111111111111', ]); @@ -36,7 +36,7 @@ expect( InventoryLink::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('source_type', 'inventory_item') ->where('source_id', $item->external_id) ->where('relationship_type', RelationshipType::ScopedBy->value) diff --git a/apps/platform/tests/Feature/Inventory/InventorySyncButtonTest.php b/apps/platform/tests/Feature/Inventory/InventorySyncButtonTest.php index 628fd119..7419428e 100644 --- a/apps/platform/tests/Feature/Inventory/InventorySyncButtonTest.php +++ b/apps/platform/tests/Feature/Inventory/InventorySyncButtonTest.php @@ -4,7 +4,7 @@ use App\Jobs\RunInventorySyncJob; use App\Livewire\BulkOperationProgress; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Inventory\InventorySyncService; use App\Services\OperationRunService; use App\Support\OpsUx\OpsUxBrowserEvents; @@ -33,7 +33,7 @@ Queue::assertPushed(RunInventorySyncJob::class); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('user_id', $user->id) ->where('type', 'inventory.sync') ->latest('id') @@ -69,7 +69,7 @@ Queue::assertPushed(RunInventorySyncJob::class); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'inventory.sync') ->latest('id') ->first(); @@ -100,7 +100,7 @@ ->assertHasNoActionErrors(); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'inventory.sync') ->latest('id') ->first(); @@ -131,7 +131,7 @@ ->assertHasNoActionErrors(); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'inventory.sync') ->latest('id') ->first(); @@ -188,7 +188,7 @@ ->assertHasNoActionErrors(); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'inventory.sync') ->latest('id') ->first(); @@ -202,7 +202,7 @@ Queue::fake(); [$user, $tenantA] = createUserWithTenant(role: 'owner'); - $tenantB = Tenant::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); $this->actingAs($user); Filament::setTenant($tenantA, true); @@ -211,13 +211,13 @@ $allTypes = $sync->defaultSelectionPayload()['policy_types']; Livewire::test(ListInventoryItems::class) - ->callAction('run_inventory_sync', data: ['tenant_id' => $tenantB->getKey(), 'policy_types' => $allTypes]) + ->callAction('run_inventory_sync', data: ['managed_environment_id' => $tenantB->getKey(), 'policy_types' => $allTypes]) ->assertSuccessful(); Queue::assertNothingPushed(); - expect(OperationRun::query()->where('tenant_id', $tenantB->id)->where('type', 'inventory.sync')->exists())->toBeFalse(); - expect(OperationRun::query()->where('tenant_id', $tenantB->id)->exists())->toBeFalse(); + expect(OperationRun::query()->where('managed_environment_id', $tenantB->id)->where('type', 'inventory.sync')->exists())->toBeFalse(); + expect(OperationRun::query()->where('managed_environment_id', $tenantB->id)->exists())->toBeFalse(); }); it('blocks dispatch when a matching run is already pending or running', function () { @@ -253,7 +253,7 @@ ->callAction('run_inventory_sync', data: ['policy_types' => $computed['selection']['policy_types']]); Queue::assertNothingPushed(); - expect(OperationRun::query()->where('tenant_id', $tenant->id)->where('type', 'inventory.sync')->count())->toBe(1); + expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->where('type', 'inventory.sync')->count())->toBe(1); }); it('disables inventory sync start action for readonly users', function () { @@ -268,5 +268,5 @@ ->assertActionDisabled('run_inventory_sync'); Queue::assertNothingPushed(); - expect(OperationRun::query()->where('tenant_id', $tenant->id)->where('type', 'inventory.sync')->exists())->toBeFalse(); + expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->where('type', 'inventory.sync')->exists())->toBeFalse(); }); diff --git a/apps/platform/tests/Feature/Inventory/InventorySyncServiceTest.php b/apps/platform/tests/Feature/Inventory/InventorySyncServiceTest.php index 84b75edc..fdcb9666 100644 --- a/apps/platform/tests/Feature/Inventory/InventorySyncServiceTest.php +++ b/apps/platform/tests/Feature/Inventory/InventorySyncServiceTest.php @@ -8,7 +8,7 @@ use App\Models\PolicyVersion; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Inventory\InventoryMetaSanitizer; @@ -78,23 +78,23 @@ public function request(string $method, string $path, array $options = []): Grap * @param array $selection * @return array{opRun: \App\Models\OperationRun, result: array, selection: array, selection_hash: string} */ -function executeInventorySyncNow(Tenant $tenant, array $selection): array +function executeInventorySyncNow(ManagedEnvironment $tenant, array $selection): array { $service = app(InventorySyncService::class); $opService = app(OperationRunService::class); $defaultConnection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('is_default', true) ->first(); if (! $defaultConnection instanceof ProviderConnection) { $defaultConnection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => $tenant->tenant_id, + 'entra_tenant_id' => $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); @@ -151,7 +151,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array } test('inventory sync upserts and updates last_seen fields without duplicates', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); app()->instance(GraphClientInterface::class, fakeGraphClient([ 'deviceConfiguration' => [ @@ -169,14 +169,14 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array $runA = executeInventorySyncNow($tenant, $selection); expect($runA['result']['status'] ?? null)->toBe('success'); - $item = \App\Models\InventoryItem::query()->where('tenant_id', $tenant->id)->first(); + $item = \App\Models\InventoryItem::query()->where('managed_environment_id', $tenant->id)->first(); expect($item)->not->toBeNull(); expect($item->external_id)->toBe('cfg-1'); expect($item->last_seen_operation_run_id)->toBe($runA['opRun']->id); $runB = executeInventorySyncNow($tenant, $selection); - $items = \App\Models\InventoryItem::query()->where('tenant_id', $tenant->id)->get(); + $items = \App\Models\InventoryItem::query()->where('managed_environment_id', $tenant->id)->get(); expect($items)->toHaveCount(1); $items->first()->refresh(); @@ -184,7 +184,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array }); test('inventory sync includes foundation types when include_foundations is true', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); app()->instance(GraphClientInterface::class, fakeGraphClient([ 'deviceConfiguration' => [], @@ -209,21 +209,21 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array expect($run['result']['status'] ?? null)->toBe('success'); expect(\App\Models\InventoryItem::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'roleScopeTag') ->where('external_id', 'tag-1') ->where('category', 'Foundations') ->exists())->toBeTrue(); expect(\App\Models\InventoryItem::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'assignmentFilter') ->where('external_id', 'filter-1') ->where('category', 'Foundations') ->exists())->toBeTrue(); expect(\App\Models\InventoryItem::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'notificationMessageTemplate') ->where('external_id', 'tmpl-1') ->where('category', 'Foundations') @@ -231,7 +231,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array }); test('inventory sync captures RBAC foundation rows with sanitized metadata and coverage status', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant, 'microsoft'); @@ -253,7 +253,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array [ 'id' => 'role-assignment-1', 'displayName' => 'Help Desk Assignment', - 'description' => 'Tenant-wide assignment', + 'description' => 'ManagedEnvironment-wide assignment', 'members' => ['group-1', 'group-2'], 'scopeMembers' => ['scope-member-1'], 'resourceScopes' => ['scope-1', 'scope-2'], @@ -273,7 +273,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array ]); $definition = InventoryItem::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'intuneRoleDefinition') ->where('external_id', 'role-def-1') ->first(); @@ -286,7 +286,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array ]); $assignment = InventoryItem::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'intuneRoleAssignment') ->where('external_id', 'role-assignment-1') ->first(); @@ -304,7 +304,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array $coverage = $run->context['inventory']['coverage']['foundation_types'] ?? []; $definitionPolicy = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'intuneRoleDefinition') ->where('external_id', 'role-def-1') ->first(); @@ -324,7 +324,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array }); test('inventory sync does not sync foundation types when include_foundations is false', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); app()->instance(GraphClientInterface::class, fakeGraphClient([ 'roleScopeTag' => [ @@ -342,13 +342,13 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array expect($run['result']['status'] ?? null)->toBe('success'); expect(\App\Models\InventoryItem::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'roleScopeTag') ->exists())->toBeFalse(); }); test('foundation inventory items store sanitized meta_jsonb after sync (no payload dump)', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); app()->instance(GraphClientInterface::class, fakeGraphClient([ 'deviceConfiguration' => [], @@ -373,7 +373,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array expect($run['result']['status'] ?? null)->toBe('success'); $foundationItem = \App\Models\InventoryItem::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'roleScopeTag') ->where('external_id', 'tag-1') ->first(); @@ -390,8 +390,8 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array }); test('inventory sync run counts include foundations when enabled and exclude them when disabled (deterministic)', function () { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); app()->instance(GraphClientInterface::class, fakeGraphClient([ 'deviceConfiguration' => [ @@ -440,7 +440,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array }); test('configuration policy inventory filtering: settings catalog is not stored as security baseline', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $settingsCatalogLookalike = [ 'id' => 'pol-1', @@ -476,26 +476,26 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array executeInventorySyncNow($tenant, $selection); expect(\App\Models\InventoryItem::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'securityBaselinePolicy') ->where('external_id', 'pol-1') ->exists())->toBeFalse(); expect(\App\Models\InventoryItem::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'settingsCatalogPolicy') ->where('external_id', 'pol-1') ->exists())->toBeTrue(); expect(\App\Models\InventoryItem::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'securityBaselinePolicy') ->where('external_id', 'pol-2') ->exists())->toBeTrue(); }); test('meta whitelist drops unknown keys without failing', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $sanitizer = app(InventoryMetaSanitizer::class); @@ -509,7 +509,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array ]); $item = \App\Models\InventoryItem::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_type' => 'deviceConfiguration', 'external_id' => 'cfg-1', 'display_name' => 'Config 1', @@ -527,7 +527,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array }); test('inventory missing is derived from latest completed run and low confidence on partial runs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $selection = [ 'policy_types' => ['deviceConfiguration'], @@ -568,7 +568,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array }); test('selection isolation: run for selection Y does not affect selection X missing', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $selectionX = [ 'policy_types' => ['deviceConfiguration'], @@ -603,7 +603,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array }); test('lock prevents overlapping runs for same tenant and selection', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); app()->instance(GraphClientInterface::class, fakeGraphClient([ 'deviceConfiguration' => [], @@ -630,7 +630,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array }); test('inventory sync does not create snapshot or backup rows', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $baseline = [ 'policy_versions' => PolicyVersion::query()->count(), @@ -657,7 +657,7 @@ function executeInventorySyncNow(Tenant $tenant, array $selection): array }); test('run error persistence is safe and does not include bearer tokens', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $throwable = new RuntimeException('Graph failed: Bearer abc.def.ghi'); diff --git a/apps/platform/tests/Feature/Inventory/InventorySyncStartSurfaceTest.php b/apps/platform/tests/Feature/Inventory/InventorySyncStartSurfaceTest.php index b922549b..345293ea 100644 --- a/apps/platform/tests/Feature/Inventory/InventorySyncStartSurfaceTest.php +++ b/apps/platform/tests/Feature/Inventory/InventorySyncStartSurfaceTest.php @@ -39,7 +39,7 @@ ]); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'inventory.sync') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/InventoryItemDependenciesTest.php b/apps/platform/tests/Feature/InventoryItemDependenciesTest.php index 936f1315..f302e3c5 100644 --- a/apps/platform/tests/Feature/InventoryItemDependenciesTest.php +++ b/apps/platform/tests/Feature/InventoryItemDependenciesTest.php @@ -3,12 +3,12 @@ use App\Filament\Resources\InventoryItemResource; use App\Models\InventoryItem; use App\Models\InventoryLink; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Support\Str; -function inventoryItemAdminSession(Tenant $tenant): array +function inventoryItemAdminSession(ManagedEnvironment $tenant): array { return [ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, @@ -26,7 +26,7 @@ function inventoryItemAdminSession(Tenant $tenant): array /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); @@ -36,7 +36,7 @@ function inventoryItemAdminSession(Tenant $tenant): array // Create a missing edge and assert badge appears InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'missing', @@ -62,19 +62,19 @@ function inventoryItemAdminSession(Tenant $tenant): array /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); $inboundSource = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), 'display_name' => 'Inbound Source', ]); // Outbound only InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'missing', @@ -87,7 +87,7 @@ function inventoryItemAdminSession(Tenant $tenant): array // Inbound only InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $inboundSource->external_id, 'target_type' => 'inventory_item', @@ -115,13 +115,13 @@ function inventoryItemAdminSession(Tenant $tenant): array /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); // Two outbound edges with different relationship types. InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'missing', @@ -131,7 +131,7 @@ function inventoryItemAdminSession(Tenant $tenant): array ]); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'missing', @@ -157,27 +157,27 @@ function inventoryItemAdminSession(Tenant $tenant): array /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); - $otherTenant = Tenant::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); - // Same source_id, but different tenant_id: must not be rendered. + // Same source_id, but different managed_environment_id: must not be rendered. InventoryLink::factory()->create([ - 'tenant_id' => $otherTenant->getKey(), + 'managed_environment_id' => $otherTenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'missing', 'target_id' => null, 'relationship_type' => 'assigned_to', - 'metadata' => ['last_known_name' => 'Other Tenant Edge'], + 'metadata' => ['last_known_name' => 'Other ManagedEnvironment Edge'], ]); $url = InventoryItemResource::getUrl('view', ['record' => $item], panel: 'admin').'?tenant='.(string) $tenant->external_id; $this->withSession($session)->get($url) ->assertOk() - ->assertDontSee('Other Tenant Edge'); + ->assertDontSee('Other ManagedEnvironment Edge'); }); it('shows masked identifier when last known name is missing', function () { @@ -188,12 +188,12 @@ function inventoryItemAdminSession(Tenant $tenant): array /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'foundation_object', @@ -219,26 +219,26 @@ function inventoryItemAdminSession(Tenant $tenant): array /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); $scopeTag = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_type' => 'roleScopeTag', 'external_id' => '6', 'display_name' => 'Finance', ]); $assignmentFilter = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_type' => 'assignmentFilter', 'external_id' => '62fb77f0-0000-0000-0000-000000000000', 'display_name' => 'VIP Devices', ]); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'foundation_object', @@ -251,7 +251,7 @@ function inventoryItemAdminSession(Tenant $tenant): array ]); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'foundation_object', @@ -264,7 +264,7 @@ function inventoryItemAdminSession(Tenant $tenant): array ]); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'foundation_object', @@ -301,19 +301,19 @@ function inventoryItemAdminSession(Tenant $tenant): array /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); $scopeTag = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_type' => 'roleScopeTag', 'external_id' => '6', 'display_name' => 'Finance', ]); InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'foundation_object', @@ -332,11 +332,11 @@ function inventoryItemAdminSession(Tenant $tenant): array }); it('blocks guest access to inventory item dependencies view', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); diff --git a/apps/platform/tests/Feature/Jobs/AppProtectionPolicySyncFilteringTest.php b/apps/platform/tests/Feature/Jobs/AppProtectionPolicySyncFilteringTest.php index 9b96067b..a1021306 100644 --- a/apps/platform/tests/Feature/Jobs/AppProtectionPolicySyncFilteringTest.php +++ b/apps/platform/tests/Feature/Jobs/AppProtectionPolicySyncFilteringTest.php @@ -1,7 +1,7 @@ 'test-tenant', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'test-tenant', + 'name' => 'Test ManagedEnvironment', 'metadata' => [], 'is_current' => true, ]); @@ -58,7 +58,7 @@ public function request(string $method, string $path, array $options = []): Grap ensureDefaultProviderConnection($tenant); Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'config-1', 'policy_type' => 'appProtectionPolicy', 'display_name' => 'Config 1 (legacy)', @@ -91,13 +91,13 @@ public function request(string $method, string $path, array $options = []): Grap app(PolicySyncService::class)->syncPolicies($tenant); $existingConfig = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'appProtectionPolicy') ->where('external_id', 'config-1') ->firstOrFail(); expect($existingConfig->ignored_at)->toBeNull(); expect($existingConfig->missing_from_provider_at)->not->toBeNull(); - expect(Policy::where('tenant_id', $tenant->id)->where('external_id', 'config-skip')->exists())->toBeFalse(); - expect(Policy::where('tenant_id', $tenant->id)->where('external_id', 'policy-2')->whereNull('ignored_at')->whereNull('missing_from_provider_at')->exists())->toBeTrue(); + expect(Policy::where('managed_environment_id', $tenant->id)->where('external_id', 'config-skip')->exists())->toBeFalse(); + expect(Policy::where('managed_environment_id', $tenant->id)->where('external_id', 'policy-2')->whereNull('ignored_at')->whereNull('missing_from_provider_at')->exists())->toBeTrue(); }); diff --git a/apps/platform/tests/Feature/Jobs/PolicySyncIgnoredRevivalTest.php b/apps/platform/tests/Feature/Jobs/PolicySyncIgnoredRevivalTest.php index 5c6d6e6b..76f07383 100644 --- a/apps/platform/tests/Feature/Jobs/PolicySyncIgnoredRevivalTest.php +++ b/apps/platform/tests/Feature/Jobs/PolicySyncIgnoredRevivalTest.php @@ -1,7 +1,7 @@ 'test-tenant', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'test-tenant', + 'name' => 'Test ManagedEnvironment', 'metadata' => [], 'is_current' => true, ]); @@ -59,7 +59,7 @@ public function request(string $method, string $path, array $options = []): Grap // Create an ignored policy $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-123', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Test Policy', @@ -96,9 +96,9 @@ public function request(string $method, string $path, array $options = []): Grap }); test('sync updates ignored policies without reviving them', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'test-tenant-2', - 'name' => 'Test Tenant 2', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'test-tenant-2', + 'name' => 'Test ManagedEnvironment 2', 'metadata' => [], 'is_current' => true, ]); @@ -107,7 +107,7 @@ public function request(string $method, string $path, array $options = []): Grap // Create multiple ignored policies Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-abc', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Old Policy ABC', @@ -116,7 +116,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-def', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Old Policy DEF', diff --git a/apps/platform/tests/Feature/Jobs/PolicySyncProviderMissingSemanticsTest.php b/apps/platform/tests/Feature/Jobs/PolicySyncProviderMissingSemanticsTest.php index 0dc86afe..f0fe563d 100644 --- a/apps/platform/tests/Feature/Jobs/PolicySyncProviderMissingSemanticsTest.php +++ b/apps/platform/tests/Feature/Jobs/PolicySyncProviderMissingSemanticsTest.php @@ -4,7 +4,7 @@ use App\Models\Policy; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphLogger; use App\Services\Graph\GraphResponse; @@ -16,20 +16,20 @@ uses(RefreshDatabase::class); -function tenantWithDefaultMicrosoftConnectionForProviderMissing(array $attributes = []): Tenant +function tenantWithDefaultMicrosoftConnectionForProviderMissing(array $attributes = []): ManagedEnvironment { - $tenant = Tenant::factory()->create($attributes + [ + $tenant = ManagedEnvironment::factory()->create($attributes + [ 'status' => 'active', 'app_client_id' => null, 'app_client_secret' => null, ]); $connection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', - 'entra_tenant_id' => (string) ($tenant->tenant_id ?: 'tenant-'.$tenant->getKey()), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?: 'tenant-'.$tenant->getKey()), ]); ProviderCredential::factory()->create([ @@ -48,7 +48,7 @@ function tenantWithDefaultMicrosoftConnectionForProviderMissing(array $attribute $tenant = tenantWithDefaultMicrosoftConnectionForProviderMissing(); $present = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-present', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Old present', @@ -57,7 +57,7 @@ function tenantWithDefaultMicrosoftConnectionForProviderMissing(array $attribute ]); $missing = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-missing', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Missing from provider', @@ -100,7 +100,7 @@ function tenantWithDefaultMicrosoftConnectionForProviderMissing(array $attribute ->and($missing->visibilityState())->toBe(Policy::VISIBILITY_PROVIDER_MISSING); expect(AuditLog::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('action', AuditActionId::PolicyProviderMissingDetected->value) ->where('resource_id', (string) $missing->getKey()) ->exists())->toBeTrue(); @@ -110,7 +110,7 @@ function tenantWithDefaultMicrosoftConnectionForProviderMissing(array $attribute $tenant = tenantWithDefaultMicrosoftConnectionForProviderMissing(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-returned', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Returned policy', @@ -150,7 +150,7 @@ function tenantWithDefaultMicrosoftConnectionForProviderMissing(array $attribute ->and($policy->visibilityState())->toBe(Policy::VISIBILITY_IGNORED_LOCALLY); expect(AuditLog::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('action', AuditActionId::PolicyProviderMissingCleared->value) ->where('resource_id', (string) $policy->getKey()) ->exists())->toBeTrue(); diff --git a/apps/platform/tests/Feature/Localization/AuthAndSystemSurfaceLocalizationTest.php b/apps/platform/tests/Feature/Localization/AuthAndSystemSurfaceLocalizationTest.php index 872a4286..ee460ad9 100644 --- a/apps/platform/tests/Feature/Localization/AuthAndSystemSurfaceLocalizationTest.php +++ b/apps/platform/tests/Feature/Localization/AuthAndSystemSurfaceLocalizationTest.php @@ -10,7 +10,7 @@ ->get('/admin/login') ->assertSuccessful() ->assertSee('Mit Microsoft anmelden') - ->assertSee('Tenant-Admin-Zugriff erfordert eine Tenant-Mitgliedschaft'); + ->assertSee('ManagedEnvironment-Admin-Zugriff erfordert eine ManagedEnvironment-Mitgliedschaft'); }); it('keeps system plane resolution independent from user and workspace preferences', function (): void { diff --git a/apps/platform/tests/Feature/Localization/CustomerReviewSurfaceLocalizationTest.php b/apps/platform/tests/Feature/Localization/CustomerReviewSurfaceLocalizationTest.php index 60498187..e8eca321 100644 --- a/apps/platform/tests/Feature/Localization/CustomerReviewSurfaceLocalizationTest.php +++ b/apps/platform/tests/Feature/Localization/CustomerReviewSurfaceLocalizationTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\TenantReviewResource; use App\Filament\Resources\TenantReviewResource\Pages\ViewTenantReview; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\TenantReviewStatus; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -18,7 +18,7 @@ uses(RefreshDatabase::class); it('renders the customer review workspace in german for the effective locale', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Lokalisierter Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Lokalisierter ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $user->forceFill(['preferred_locale' => 'de'])->save(); @@ -41,7 +41,7 @@ ->test(CustomerReviewWorkspace::class) ->assertCanSeeTableRecords([$tenant->fresh()]) ->assertSee('Kundensicherer Governance-Paket-Index') - ->assertSee('Prüfen Sie für jeden berechtigten Tenant den executive-fähigen Status des Governance-Pakets und öffnen Sie bei Bedarf die kundensichere Detailansicht.') + ->assertSee('Prüfen Sie für jeden berechtigten ManagedEnvironment den executive-fähigen Status des Governance-Pakets und öffnen Sie bei Bedarf die kundensichere Detailansicht.') ->assertSee('Jede Zeile ist ein Einstieg in die Detailansicht: Dort sehen Sie Paketstatus, Executive-Einstieg, Nachweise, aktuelle Risiken und den nächsten kundensicheren Schritt.') ->assertSee('Dieser Workspace fasst die aktuelle Review- und Nachweislage für die Service-Auslieferung zusammen. Er ersetzt weder ein formales Auditurteil noch eine Zertifizierung oder rechtliche Attestierung.') ->assertSee('Governance-Paket') @@ -54,7 +54,7 @@ it('renders the customer review detail surface in german for the effective locale', function (): void { Storage::fake('exports'); - $tenant = Tenant::factory()->create(['name' => 'Lokalisierter Detail-Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Lokalisierter Detail-ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $user->forceFill(['preferred_locale' => 'de'])->save(); @@ -70,7 +70,7 @@ Storage::disk('exports')->put('review-packs/customer-review-localization-test.zip', 'PK-test'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), diff --git a/apps/platform/tests/Feature/Localization/LocalePreferenceFlowTest.php b/apps/platform/tests/Feature/Localization/LocalePreferenceFlowTest.php index 0e18eb0a..afd2ed6f 100644 --- a/apps/platform/tests/Feature/Localization/LocalePreferenceFlowTest.php +++ b/apps/platform/tests/Feature/Localization/LocalePreferenceFlowTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Reviews\CustomerReviewWorkspace; use App\Services\Localization\LocaleResolver; use App\Services\Settings\SettingsWriter; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; it('allows users to save and clear a personal locale preference over workspace default', function (): void { @@ -89,7 +89,7 @@ }); it('returns to the customer review workspace filter when the locale override changes', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $workspaceUrl = CustomerReviewWorkspace::tenantPrefilterUrl($tenant); diff --git a/apps/platform/tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php b/apps/platform/tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php new file mode 100644 index 00000000..c8a98d5e --- /dev/null +++ b/apps/platform/tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php @@ -0,0 +1,70 @@ +toBeFalse(); +}); + +it('does not import App Models Tenant or bind Filament tenancy to Tenant class', function (): void { + $finder = Finder::create() + ->files() + ->name('*.php') + ->in([ + app_path(), + base_path('database'), + base_path('tests'), + ]); + + $violations = []; + $legacyPanelTenantNeedle = '->tenant('.'Tenant::class'; + + foreach ($finder as $file) { + $contents = $file->getContents(); + + if (preg_match('/^use\s+App\\\\Models\\\\Tenant;$/m', $contents) === 1) { + $violations[] = $file->getRelativePathname().': imports App\\Models\\Tenant'; + } + + if (str_contains($contents, $legacyPanelTenantNeedle)) { + $violations[] = $file->getRelativePathname().': binds Filament tenancy to Tenant::class'; + } + } + + expect($violations)->toBe([]); +}); + +it('keeps the fresh schema on managed environment table names only', function (): void { + expect(Schema::hasTable('tenants'))->toBeFalse() + ->and(Schema::hasTable('tenant_user'))->toBeFalse() + ->and(Schema::hasTable('tenant_memberships'))->toBeFalse() + ->and(Schema::hasTable('user_tenant_preferences'))->toBeFalse() + ->and(Schema::hasTable('managed_environments'))->toBeTrue() + ->and(Schema::hasTable('managed_environment_user'))->toBeTrue() + ->and(Schema::hasTable('managed_environment_memberships'))->toBeTrue() + ->and(Schema::hasTable('user_managed_environment_preferences'))->toBeTrue(); +}); + +it('keeps first-slice core tables on managed_environment_id instead of tenant_id', function (): void { + foreach (TenantOwnedModelFamilies::firstSlice() as $family) { + $table = $family['table']; + + expect(Schema::hasColumn($table, 'tenant_id')) + ->toBeFalse("{$table} must not expose tenant_id after the managed-environment cutover"); + + expect(Schema::hasColumn($table, 'managed_environment_id')) + ->toBeTrue("{$table} must expose managed_environment_id after the managed-environment cutover"); + } +}); + +it('keeps managed environment as the panel tenant model', function (): void { + $panel = Filament\Facades\Filament::getPanel('tenant'); + + expect($panel->getTenantModel())->toBe(ManagedEnvironment::class); +}); diff --git a/apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentAuthorizationTest.php b/apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentAuthorizationTest.php new file mode 100644 index 00000000..309a9112 --- /dev/null +++ b/apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentAuthorizationTest.php @@ -0,0 +1,63 @@ +actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]); + + $this + ->get(route('admin.provider-connections.legacy-index', ['tenant' => $environment])) + ->assertRedirect('/admin/provider-connections?managed_environment_id='.$environment->slug); +}); + +it('hides managed-environment routes from workspace members without environment membership', function (): void { + $workspace = Workspace::factory()->create(); + $environment = ManagedEnvironment::factory()->create([ + 'workspace_id' => (int) $workspace->getKey(), + ]); + $user = User::factory()->create(); + + WorkspaceMembership::factory()->create([ + 'workspace_id' => (int) $workspace->getKey(), + 'user_id' => (int) $user->getKey(), + 'role' => 'manager', + ]); + + $this->actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $workspace->getKey(), + ]); + + $this + ->get(route('admin.provider-connections.legacy-index', ['tenant' => $environment])) + ->assertNotFound(); +}); + +it('hides managed-environment routes when the current workspace differs', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner'); + $otherWorkspace = Workspace::factory()->create(); + + WorkspaceMembership::factory()->create([ + 'workspace_id' => (int) $otherWorkspace->getKey(), + 'user_id' => (int) $user->getKey(), + 'role' => 'owner', + ]); + + $this->actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $otherWorkspace->getKey(), + ]); + + $this + ->get(route('admin.provider-connections.legacy-index', ['tenant' => $environment])) + ->assertNotFound(); +}); diff --git a/apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php b/apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php new file mode 100644 index 00000000..e6cdab2e --- /dev/null +++ b/apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php @@ -0,0 +1,71 @@ +archived()->create([ + 'workspace_id' => (int) $environment->workspace_id, + 'name' => 'Archived environment', + ]); + $user->tenants()->syncWithoutDetaching([ + $archived->getKey() => ['role' => 'owner'], + ]); + + $otherWorkspace = Workspace::factory()->create(); + $otherEnvironment = ManagedEnvironment::factory()->create([ + 'workspace_id' => (int) $otherWorkspace->getKey(), + 'name' => 'Other workspace environment', + ]); + $user->tenants()->syncWithoutDetaching([ + $otherEnvironment->getKey() => ['role' => 'owner'], + ]); + + $this->actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]); + + $tenants = Livewire::actingAs($user) + ->test(ChooseTenant::class) + ->instance() + ->getTenants(); + + expect($tenants->pluck('id')->all())->toBe([(int) $environment->getKey()]); +}); + +it('persists managed-environment context and redirects into the temporary tenant shell', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); + + $this->actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]); + + Livewire::actingAs($user) + ->test(ChooseTenant::class) + ->call('selectTenant', (int) $environment->getKey()) + ->assertRedirect(TenantDashboard::getUrl(panel: 'tenant', tenant: $environment)); + + expect(session(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY))->toBe([ + (string) $environment->workspace_id => (int) $environment->getKey(), + ]); +}); + +it('keeps route builders on managed-environment slug for the temporary shell', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); + + $this->actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]); + + expect(TenantDashboard::getUrl(panel: 'tenant', tenant: $environment)) + ->toContain('/admin/t/'.$environment->slug); +}); diff --git a/apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php b/apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php new file mode 100644 index 00000000..5c775ac7 --- /dev/null +++ b/apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php @@ -0,0 +1,66 @@ +get(route('admin.local.smoke-login', [ + 'email' => $user->email, + 'workspace' => $environment->workspace->slug, + 'tenant' => $environment->slug, + 'redirect' => '/admin/t/'.$environment->slug, + ])) + ->assertRedirect('/admin/t/'.$environment->slug) + ->assertSessionHas('current_workspace_id', (int) $environment->workspace_id); +}); + +it('returns not found when route binding targets an environment outside the requested workspace', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner'); + $otherWorkspace = Workspace::factory()->create(); + + WorkspaceMembership::factory()->create([ + 'workspace_id' => (int) $otherWorkspace->getKey(), + 'user_id' => (int) $user->getKey(), + 'role' => 'owner', + ]); + + $this->actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $otherWorkspace->getKey(), + ]); + + $this + ->get(route('admin.provider-connections.legacy-index', ['tenant' => $environment])) + ->assertNotFound(); +}); + +it('returns not found when a workspace member lacks managed-environment membership', function (): void { + $workspace = Workspace::factory()->create(); + $environment = ManagedEnvironment::factory()->create([ + 'workspace_id' => (int) $workspace->getKey(), + ]); + $user = User::factory()->create(); + + WorkspaceMembership::factory()->create([ + 'workspace_id' => (int) $workspace->getKey(), + 'user_id' => (int) $user->getKey(), + 'role' => 'manager', + ]); + + $this + ->get(route('admin.local.smoke-login', [ + 'email' => $user->email, + 'workspace' => $workspace->slug, + 'tenant' => $environment->slug, + 'redirect' => '/admin/t/'.$environment->slug, + ])) + ->assertNotFound(); +}); diff --git a/apps/platform/tests/Feature/ManagedTenantOnboardingWizardTest.php b/apps/platform/tests/Feature/ManagedTenantOnboardingWizardTest.php index d5c97f55..4b54459f 100644 --- a/apps/platform/tests/Feature/ManagedTenantOnboardingWizardTest.php +++ b/apps/platform/tests/Feature/ManagedTenantOnboardingWizardTest.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantPermission; use App\Models\TenantOnboardingSession; use App\Models\User; @@ -41,7 +41,7 @@ function managedReadinessPermissionKeys(): array }, $configured))); } -function seedManagedReadinessPermissions(Tenant $tenant, ?int $staleDays = null, ?string $missingKey = null): ?string +function seedManagedReadinessPermissions(ManagedEnvironment $tenant, ?int $staleDays = null, ?string $missingKey = null): ?string { $keys = managedReadinessPermissionKeys(); $missingKey ??= $keys[0] ?? null; @@ -52,7 +52,7 @@ function seedManagedReadinessPermissions(Tenant $tenant, ?int $staleDays = null, } TenantPermission::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'permission_key' => $key, 'status' => 'granted', @@ -78,10 +78,10 @@ function createManagedReadinessBlockerDraft(string $state): array 'role' => 'owner', ]); - $tenant = Tenant::factory()->onboarding()->create([ + $tenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => fake()->uuid(), - 'name' => 'Blocker Tenant '.str_replace('_', ' ', $state), + 'managed_environment_id' => fake()->uuid(), + 'name' => 'Blocker ManagedEnvironment '.str_replace('_', ' ', $state), ]); $user->tenants()->syncWithoutDetaching([ @@ -90,9 +90,9 @@ function createManagedReadinessBlockerDraft(string $state): array $connectionState = [ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Blocker connection', 'is_default' => true, ]; @@ -124,7 +124,7 @@ function createManagedReadinessBlockerDraft(string $state): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Blocked->value, @@ -154,7 +154,7 @@ function createManagedReadinessBlockerDraft(string $state): array 'updated_by' => $user, 'current_step' => 'verify', 'state' => array_filter([ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => $run instanceof OperationRun ? (int) $run->getKey() : null, @@ -197,7 +197,7 @@ function createManagedReadinessBlockerDraft(string $state): array ->test(ManagedTenantOnboardingWizard::class) ->assertForbidden(); - expect(Tenant::query()->count())->toBe(0); + expect(ManagedEnvironment::query()->count())->toBe(0); expect(TenantOnboardingSession::query()->count())->toBe(0); }); @@ -228,20 +228,20 @@ function createManagedReadinessBlockerDraft(string $state): array 'notes' => 'Initial onboarding', ]); - $tenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('slug', $entraTenantId)->firstOrFail(); expect((int) $tenant->workspace_id)->toBe((int) $workspace->getKey()); - expect($tenant->status)->toBe(Tenant::STATUS_ONBOARDING); + expect($tenant->status)->toBe(ManagedEnvironment::STATUS_ONBOARDING); - $this->assertDatabaseHas('tenant_memberships', [ - 'tenant_id' => (int) $tenant->getKey(), + $this->assertDatabaseHas('managed_environment_memberships', [ + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'role' => 'owner', ]); $this->assertDatabaseHas('managed_tenant_onboarding_sessions', [ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $entraTenantId, 'current_step' => 'identify', ]); @@ -262,7 +262,7 @@ function createManagedReadinessBlockerDraft(string $state): array $this->actingAs($user) ->get('/admin/onboarding') ->assertSuccessful() - ->assertSee('Tenant ID (GUID)') + ->assertSee('ManagedEnvironment ID (GUID)') ->assertSee('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', false); }); @@ -285,7 +285,7 @@ function createManagedReadinessBlockerDraft(string $state): array ->call('identifyManagedTenant', [ 'entra_tenant_id' => $entraTenantId, 'environment' => 'prod', - 'name' => 'Target Scope Tenant', + 'name' => 'Target Scope ManagedEnvironment', ]) ->set('data.connection_mode', 'new') ->assertSee('Target scope ID') @@ -309,16 +309,16 @@ function createManagedReadinessBlockerDraft(string $state): array $entraTenantId = 'abababab-abab-abab-abab-abababababab'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $entraTenantId, - 'status' => Tenant::STATUS_ONBOARDING, - 'name' => 'Activation Ready Tenant', + 'managed_environment_id' => $entraTenantId, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'name' => 'Activation Ready ManagedEnvironment', ]); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Platform onboarding connection', @@ -328,7 +328,7 @@ function createManagedReadinessBlockerDraft(string $state): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -336,7 +336,7 @@ function createManagedReadinessBlockerDraft(string $state): array 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ 'entra_tenant_id' => $entraTenantId, - 'entra_tenant_name' => 'Activation Ready Tenant', + 'entra_tenant_name' => 'Activation Ready ManagedEnvironment', ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ [ @@ -356,7 +356,7 @@ function createManagedReadinessBlockerDraft(string $state): array TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $entraTenantId, 'current_step' => 'bootstrap', 'state' => [ @@ -372,7 +372,7 @@ function createManagedReadinessBlockerDraft(string $state): array ->get('/admin/onboarding') ->assertSuccessful() ->assertSee('Skipped - No bootstrap actions selected') - ->assertSee('Tenant status will be set to Active.') + ->assertSee('ManagedEnvironment status will be set to Active.') ->assertSee('The provider connection will be used for provider API calls.'); }); @@ -390,11 +390,11 @@ function createManagedReadinessBlockerDraft(string $state): array $entraTenantId = 'cdcdcdcd-cdcd-cdcd-cdcd-cdcdcdcdcdcd'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $entraTenantId, - 'status' => Tenant::STATUS_ONBOARDING, - 'name' => 'Bootstrap Selected Tenant', + 'managed_environment_id' => $entraTenantId, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'name' => 'Bootstrap Selected ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -403,7 +403,7 @@ function createManagedReadinessBlockerDraft(string $state): array $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Platform onboarding connection', @@ -413,7 +413,7 @@ function createManagedReadinessBlockerDraft(string $state): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -421,7 +421,7 @@ function createManagedReadinessBlockerDraft(string $state): array 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ 'entra_tenant_id' => $entraTenantId, - 'entra_tenant_name' => 'Bootstrap Selected Tenant', + 'entra_tenant_name' => 'Bootstrap Selected ManagedEnvironment', ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ [ @@ -441,7 +441,7 @@ function createManagedReadinessBlockerDraft(string $state): array $session = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $entraTenantId, 'current_step' => 'complete', 'state' => [ @@ -480,11 +480,11 @@ function createManagedReadinessBlockerDraft(string $state): array $entraTenantId = 'efefefef-efef-efef-efef-efefefefefef'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $entraTenantId, - 'status' => Tenant::STATUS_ONBOARDING, - 'name' => 'Bootstrap Blocked Tenant', + 'managed_environment_id' => $entraTenantId, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'name' => 'Bootstrap Blocked ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -493,7 +493,7 @@ function createManagedReadinessBlockerDraft(string $state): array $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Platform onboarding connection', @@ -503,7 +503,7 @@ function createManagedReadinessBlockerDraft(string $state): array $verificationRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -511,7 +511,7 @@ function createManagedReadinessBlockerDraft(string $state): array 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ 'entra_tenant_id' => $entraTenantId, - 'entra_tenant_name' => 'Bootstrap Blocked Tenant', + 'entra_tenant_name' => 'Bootstrap Blocked ManagedEnvironment', ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ [ @@ -531,7 +531,7 @@ function createManagedReadinessBlockerDraft(string $state): array $bootstrapRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'inventory.sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Blocked->value, @@ -545,7 +545,7 @@ function createManagedReadinessBlockerDraft(string $state): array $session = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $entraTenantId, 'current_step' => 'complete', 'state' => [ @@ -601,11 +601,11 @@ function createManagedReadinessBlockerDraft(string $state): array $entraTenantId = 'dededede-dede-dede-dede-dededededede'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $entraTenantId, - 'status' => Tenant::STATUS_ONBOARDING, - 'name' => 'Persist Bootstrap Tenant', + 'managed_environment_id' => $entraTenantId, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'name' => 'Persist Bootstrap ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -614,7 +614,7 @@ function createManagedReadinessBlockerDraft(string $state): array $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Platform onboarding connection', @@ -624,7 +624,7 @@ function createManagedReadinessBlockerDraft(string $state): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -648,7 +648,7 @@ function createManagedReadinessBlockerDraft(string $state): array $session = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $entraTenantId, 'current_step' => 'bootstrap', 'state' => [ @@ -685,10 +685,10 @@ function createManagedReadinessBlockerDraft(string $state): array $tenantGuid = '12121212-1212-1212-1212-121212121212'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $tenantGuid, - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => $tenantGuid, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, 'name' => 'Acme', ]); @@ -698,7 +698,7 @@ function createManagedReadinessBlockerDraft(string $state): array $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'display_name' => 'Platform onboarding connection', @@ -708,7 +708,7 @@ function createManagedReadinessBlockerDraft(string $state): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -736,7 +736,7 @@ function createManagedReadinessBlockerDraft(string $state): array $session = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $tenantGuid, 'current_step' => 'complete', 'state' => [ @@ -784,9 +784,9 @@ function createManagedReadinessBlockerDraft(string $state): array 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -795,11 +795,11 @@ function createManagedReadinessBlockerDraft(string $state): array $draft = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => 999999, ], @@ -835,7 +835,7 @@ function createManagedReadinessBlockerDraft(string $state): array $component->call('identifyManagedTenant', [ 'entra_tenant_id' => $entraTenantId, 'environment' => 'prod', - 'name' => 'Dedicated Tenant', + 'name' => 'Dedicated ManagedEnvironment', ]); $component @@ -849,11 +849,11 @@ function createManagedReadinessBlockerDraft(string $state): array 'is_default' => true, ]); - $tenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('slug', $entraTenantId)->firstOrFail(); $connection = \App\Models\ProviderConnection::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->firstOrFail(); @@ -881,7 +881,7 @@ function createManagedReadinessBlockerDraft(string $state): array $component->call('identifyManagedTenant', [ 'entra_tenant_id' => $entraTenantId, 'environment' => 'prod', - 'name' => 'Managed Tenant', + 'name' => 'Managed ManagedEnvironment', ]); $component @@ -924,7 +924,7 @@ function createManagedReadinessBlockerDraft(string $state): array 'name' => 'Acme', ]); - expect(Tenant::query()->where('tenant_id', $entraTenantId)->count())->toBe(1); + expect(ManagedEnvironment::query()->where('slug', $entraTenantId)->count())->toBe(1); expect(TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) ->where('entra_tenant_id', $entraTenantId) @@ -952,10 +952,10 @@ function createManagedReadinessBlockerDraft(string $state): array 'role' => 'owner', ]); - Tenant::factory()->create([ + ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'tenant_id' => $entraTenantId, - 'status' => Tenant::STATUS_ACTIVE, + 'managed_environment_id' => $entraTenantId, + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspaceB->getKey()); @@ -1025,10 +1025,10 @@ function createManagedReadinessBlockerDraft(string $state): array 'role' => 'owner', ]); - $tenant = Tenant::factory()->onboarding()->create([ + $tenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '31313131-3131-3131-3131-313131313131', - 'name' => 'No Check Tenant', + 'managed_environment_id' => '31313131-3131-3131-3131-313131313131', + 'name' => 'No Check ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -1037,9 +1037,9 @@ function createManagedReadinessBlockerDraft(string $state): array $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'No check connection', 'is_default' => true, ]); @@ -1051,7 +1051,7 @@ function createManagedReadinessBlockerDraft(string $state): array 'updated_by' => $user, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), ], @@ -1084,10 +1084,10 @@ function createManagedReadinessBlockerDraft(string $state): array 'role' => 'owner', ]); - $tenant = Tenant::factory()->onboarding()->create([ + $tenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '32323232-3232-3232-3232-323232323232', - 'name' => 'Ready Readiness Tenant', + 'managed_environment_id' => '32323232-3232-3232-3232-323232323232', + 'name' => 'Ready Readiness ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -1098,16 +1098,16 @@ function createManagedReadinessBlockerDraft(string $state): array $connection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Ready connection', 'is_default' => true, ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -1136,7 +1136,7 @@ function createManagedReadinessBlockerDraft(string $state): array 'updated_by' => $user, 'current_step' => 'complete', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -1218,10 +1218,10 @@ function createManagedReadinessBlockerDraft(string $state): array 'role' => 'owner', ]); - $tenant = Tenant::factory()->onboarding()->create([ + $tenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '52525252-5252-5252-5252-525252525252', - 'name' => 'Stale Evidence Tenant', + 'managed_environment_id' => '52525252-5252-5252-5252-525252525252', + 'name' => 'Stale Evidence ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -1232,16 +1232,16 @@ function createManagedReadinessBlockerDraft(string $state): array $connection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Stale readiness connection', 'is_default' => true, ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -1270,7 +1270,7 @@ function createManagedReadinessBlockerDraft(string $state): array 'updated_by' => $user, 'current_step' => 'complete', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -1299,10 +1299,10 @@ function createManagedReadinessBlockerDraft(string $state): array 'role' => 'owner', ]); - $tenant = Tenant::factory()->onboarding()->create([ + $tenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '53535353-5353-5353-5353-535353535353', - 'name' => 'Mismatched Evidence Tenant', + 'managed_environment_id' => '53535353-5353-5353-5353-535353535353', + 'name' => 'Mismatched Evidence ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -1313,23 +1313,23 @@ function createManagedReadinessBlockerDraft(string $state): array $oldConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => '54545454-5454-5454-5454-545454545454', 'display_name' => 'Previous connection', ]); $selectedConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Selected connection', 'is_default' => true, ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -1358,7 +1358,7 @@ function createManagedReadinessBlockerDraft(string $state): array 'updated_by' => $user, 'current_step' => 'complete', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $selectedConnection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -1396,7 +1396,7 @@ function createManagedReadinessBlockerDraft(string $state): array 'entra_tenant_id' => '88888888-8888-8888-8888-888888888888', 'state' => [ 'entra_tenant_id' => '88888888-8888-8888-8888-888888888888', - 'tenant_name' => 'Existing Draft Tenant', + 'tenant_name' => 'Existing Draft ManagedEnvironment', ], ]); @@ -1416,7 +1416,7 @@ function createManagedReadinessBlockerDraft(string $state): array ->call('identifyManagedTenant', [ 'entra_tenant_id' => '88888888-8888-8888-8888-888888888888', 'environment' => 'prod', - 'name' => 'Existing Draft Tenant', + 'name' => 'Existing Draft ManagedEnvironment', ]) ->assertRedirect(route('admin.onboarding.draft', ['onboardingDraft' => $existingDraft->getKey()])); @@ -1487,25 +1487,25 @@ function createManagedReadinessBlockerDraft(string $state): array $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]); - $component->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']); - $component->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']); + $component->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']); + $component->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']); - expect(Tenant::query()->where('tenant_id', $tenantGuid)->count())->toBe(1); + expect(ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->count())->toBe(1); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail(); expect(TenantOnboardingSession::query() ->where('workspace_id', $workspace->getKey()) - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->count())->toBe(1); $this->assertDatabaseHas('managed_tenant_onboarding_sessions', [ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); }); -it('returns 404 and does not create anything when tenant_id exists in another workspace', function (): void { +it('returns 404 and does not create anything when managed_environment_id exists in another workspace', function (): void { $workspaceA = Workspace::factory()->create(); $workspaceB = Workspace::factory()->create(); @@ -1519,9 +1519,9 @@ function createManagedReadinessBlockerDraft(string $state): array $tenantGuid = '33333333-3333-3333-3333-333333333333'; - Tenant::factory()->create([ + ManagedEnvironment::factory()->create([ 'workspace_id' => $workspaceA->getKey(), - 'tenant_id' => $tenantGuid, + 'managed_environment_id' => $tenantGuid, 'name' => 'Acme', 'status' => 'active', ]); @@ -1529,14 +1529,14 @@ function createManagedReadinessBlockerDraft(string $state): array $this->actingAs($user); Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspaceB]) - ->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']) + ->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']) ->assertStatus(404); - expect(Tenant::query()->where('tenant_id', $tenantGuid)->count())->toBe(1); + expect(ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->count())->toBe(1); expect(TenantOnboardingSession::query() ->where('workspace_id', $workspaceB->getKey()) - ->whereIn('tenant_id', Tenant::query()->where('tenant_id', $tenantGuid)->pluck('id')) + ->whereIn('managed_environment_id', ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->pluck('id')) ->count())->toBe(0); }); @@ -1552,15 +1552,15 @@ function createManagedReadinessBlockerDraft(string $state): array $tenantGuid = '77777777-7777-7777-7777-777777777777'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => null, - 'tenant_id' => $tenantGuid, + 'managed_environment_id' => $tenantGuid, 'name' => 'Acme', 'status' => 'active', ]); - \App\Models\TenantMembership::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + \App\Models\ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'role' => 'owner', 'source' => 'manual', @@ -1570,24 +1570,24 @@ function createManagedReadinessBlockerDraft(string $state): array $this->assertDatabaseHas('tenants', [ 'id' => (int) $tenant->getKey(), 'workspace_id' => null, - 'tenant_id' => $tenantGuid, + 'managed_environment_id' => $tenantGuid, ]); - $this->assertDatabaseHas('tenant_memberships', [ - 'tenant_id' => (int) $tenant->getKey(), + $this->assertDatabaseHas('managed_environment_memberships', [ + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), ]); $this->actingAs($user); Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]) - ->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']) + ->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']) ->assertOk(); $this->assertDatabaseHas('tenants', [ 'id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $tenantGuid, + 'managed_environment_id' => $tenantGuid, ]); }); @@ -1603,15 +1603,15 @@ function createManagedReadinessBlockerDraft(string $state): array $tenantGuid = '99999999-9999-9999-9999-999999999999'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), - 'tenant_id' => $tenantGuid, + 'managed_environment_id' => $tenantGuid, 'name' => 'Acme', 'status' => 'pending', ]); $default = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'display_name' => 'Default', @@ -1619,7 +1619,7 @@ function createManagedReadinessBlockerDraft(string $state): array ]); $other = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft_alt', 'entra_tenant_id' => $tenantGuid, 'display_name' => 'Other', @@ -1630,13 +1630,13 @@ function createManagedReadinessBlockerDraft(string $state): array $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]); - $component->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']); + $component->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']); $component->assertSet('selectedProviderConnectionId', (int) $default->getKey()); $session = TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->firstOrFail(); expect($session->state['provider_connection_id'] ?? null)->toBe((int) $default->getKey()); @@ -1665,12 +1665,12 @@ function createManagedReadinessBlockerDraft(string $state): array $tenantGuid = '77777777-7777-7777-7777-777777777777'; $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]); - $component->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']); + $component->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'is_default' => true, ]); @@ -1684,7 +1684,7 @@ function createManagedReadinessBlockerDraft(string $state): array ->assertSee('Open operation'); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->count())->toBe(1); @@ -1699,7 +1699,7 @@ function createManagedReadinessBlockerDraft(string $state): array $session = TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->firstOrFail(); expect($session->state['verification_operation_run_id'] ?? null)->not->toBeNull(); @@ -1723,7 +1723,7 @@ function createManagedReadinessBlockerDraft(string $state): array $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]); $component - ->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']) + ->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']) ->call('createProviderConnection', [ 'display_name' => 'Onboarding Connection', 'client_id' => 'client-id-1', @@ -1732,10 +1732,10 @@ function createManagedReadinessBlockerDraft(string $state): array ]) ->assertDontSee($secret); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail(); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('entra_tenant_id', $tenantGuid) ->firstOrFail(); @@ -1745,7 +1745,7 @@ function createManagedReadinessBlockerDraft(string $state): array $session = TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->firstOrFail(); $state = $session->state ?? []; @@ -1771,12 +1771,12 @@ function createManagedReadinessBlockerDraft(string $state): array $tenantGuid = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'; $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]); - $component->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']); + $component->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'is_default' => true, @@ -1786,7 +1786,7 @@ function createManagedReadinessBlockerDraft(string $state): array $component->call('startVerification'); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->firstOrFail(); @@ -1823,12 +1823,12 @@ function createManagedReadinessBlockerDraft(string $state): array $this->actingAs($initiator); $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]); - $component->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']); + $component->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'is_default' => true, @@ -1836,7 +1836,7 @@ function createManagedReadinessBlockerDraft(string $state): array $session = TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->firstOrFail(); $session->update([ @@ -1868,19 +1868,19 @@ function createManagedReadinessBlockerDraft(string $state): array $tenantGuid = 'dddddddd-dddd-dddd-dddd-dddddddddddd'; $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]); - $component->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']); + $component->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'is_default' => true, ]); $run = OperationRun::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', @@ -1894,7 +1894,7 @@ function createManagedReadinessBlockerDraft(string $state): array $session = TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->firstOrFail(); $session->update([ @@ -1932,19 +1932,19 @@ function createManagedReadinessBlockerDraft(string $state): array $tenantGuid = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'; $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]); - $component->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']); + $component->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'is_default' => true, ]); $verificationRun = OperationRun::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', @@ -1958,7 +1958,7 @@ function createManagedReadinessBlockerDraft(string $state): array $session = TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->firstOrFail(); $session->update([ @@ -1977,12 +1977,12 @@ function createManagedReadinessBlockerDraft(string $state): array Bus::assertNotDispatched(\App\Jobs\ProviderComplianceSnapshotJob::class); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'inventory.sync') ->count())->toBe(1); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'compliance.snapshot') ->count())->toBe(0); @@ -2019,19 +2019,19 @@ function createManagedReadinessBlockerDraft(string $state): array $tenantGuid = 'ffffffff-ffff-ffff-ffff-ffffffffffff'; $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]); - $component->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']); + $component->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'is_default' => true, ]); $verificationRun = OperationRun::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', @@ -2045,7 +2045,7 @@ function createManagedReadinessBlockerDraft(string $state): array $session = TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->firstOrFail(); $session->update([ @@ -2058,7 +2058,7 @@ function createManagedReadinessBlockerDraft(string $state): array $component->call('startBootstrap', ['inventory.sync', 'compliance.snapshot']); $inventoryRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'inventory.sync') ->latest('id') ->firstOrFail(); @@ -2074,7 +2074,7 @@ function createManagedReadinessBlockerDraft(string $state): array Bus::assertDispatchedTimes(\App\Jobs\ProviderComplianceSnapshotJob::class, 1); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'compliance.snapshot') ->count())->toBe(1); @@ -2101,17 +2101,17 @@ function createManagedReadinessBlockerDraft(string $state): array $tenantGuid = '88888888-8888-8888-8888-888888888888'; $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]); - $component->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']); + $component->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'is_default' => true, ]); OperationRun::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory.sync', @@ -2128,7 +2128,7 @@ function createManagedReadinessBlockerDraft(string $state): array $component->call('startVerification'); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->count())->toBe(0); @@ -2152,19 +2152,19 @@ function createManagedReadinessBlockerDraft(string $state): array $tenantGuid = '99999999-9999-9999-9999-999999999999'; $component = Livewire::test(\App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard::class, ['workspace' => $workspace]); - $component->call('identifyManagedTenant', ['tenant_id' => $tenantGuid, 'name' => 'Acme']); + $component->call('identifyManagedTenant', ['managed_environment_id' => $tenantGuid, 'name' => 'Acme']); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('managed_environment_id', $tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'is_default' => true, ]); $staleRun = OperationRun::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, @@ -2193,7 +2193,7 @@ function createManagedReadinessBlockerDraft(string $state): array expect($report['checks'][0]['message'] ?? null)->toBe('Run was queued but never started. A queue worker may not be running.'); $newRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->firstOrFail(); @@ -2246,9 +2246,9 @@ function createManagedReadinessBlockerDraft(string $state): array it('keeps filament tenant routing key stable (external_id resolves /admin/t/{tenant})', function (): void { [$user, $tenant] = createUserWithTenant( - Tenant::factory()->create([ + ManagedEnvironment::factory()->create([ 'workspace_id' => null, - 'tenant_id' => '11111111-1111-1111-1111-111111111111', + 'managed_environment_id' => '11111111-1111-1111-1111-111111111111', ]), role: 'owner', ); @@ -2259,7 +2259,7 @@ function createManagedReadinessBlockerDraft(string $state): array $tenant->refresh(); - expect($tenant->external_id)->toBe($tenant->tenant_id); + expect($tenant->external_id)->toBe($tenant->managed_environment_id); }); it('can persist a tenant onboarding session row', function (): void { @@ -2267,7 +2267,7 @@ function createManagedReadinessBlockerDraft(string $state): array $session = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'current_step' => 'identify', 'state' => ['example' => 'value'], 'started_by_user_id' => (int) $user->getKey(), @@ -2278,7 +2278,7 @@ function createManagedReadinessBlockerDraft(string $state): array $this->assertDatabaseHas('managed_tenant_onboarding_sessions', [ 'id' => $session->getKey(), 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'current_step' => 'identify', ]); }); diff --git a/apps/platform/tests/Feature/ManagedTenants/AuthorizationSemanticsTest.php b/apps/platform/tests/Feature/ManagedTenants/AuthorizationSemanticsTest.php index 4026878c..98b0f62f 100644 --- a/apps/platform/tests/Feature/ManagedTenants/AuthorizationSemanticsTest.php +++ b/apps/platform/tests/Feature/ManagedTenants/AuthorizationSemanticsTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\EvidenceSnapshotResource; use App\Filament\Resources\TenantResource; use App\Models\EvidenceSnapshot; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -16,7 +16,7 @@ use Illuminate\Support\Facades\Gate; it('returns 403 for a member without managed-tenant manage capability when accessing edit', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'readonly'); $this->actingAs($user) @@ -26,7 +26,7 @@ it('returns 404 for a non-member attempting to access a workspace managed-tenant list', function (): void { $workspace = Workspace::factory()->create(); - Tenant::factory()->create(['workspace_id' => $workspace->getKey()]); + ManagedEnvironment::factory()->create(['workspace_id' => $workspace->getKey()]); $user = User::factory()->create(); @@ -46,7 +46,7 @@ }); it('returns 403 for an in-scope tenant member without evidence view capability on the evidence list', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'owner'); Gate::define(Capabilities::EVIDENCE_VIEW, fn (): bool => false); @@ -57,9 +57,9 @@ }); it('returns 404 for a non-member attempting to access an evidence snapshot detail route', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -75,15 +75,15 @@ }); it('suppresses non-entitled tenants from the workspace evidence overview', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantDenied = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantDenied = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantDenied, user: $user, role: 'owner'); - Gate::define(Capabilities::EVIDENCE_VIEW, fn (User $actor, Tenant $tenant): bool => (int) $tenant->getKey() === (int) $tenantA->getKey()); + Gate::define(Capabilities::EVIDENCE_VIEW, fn (User $actor, ManagedEnvironment $tenant): bool => (int) $tenant->getKey() === (int) $tenantA->getKey()); $allowedSnapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -92,7 +92,7 @@ ]); $deniedSnapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenantDenied->getKey(), + 'managed_environment_id' => (int) $tenantDenied->getKey(), 'workspace_id' => (int) $tenantDenied->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Missing->value, diff --git a/apps/platform/tests/Feature/ManagedTenants/OnboardingRedirectTest.php b/apps/platform/tests/Feature/ManagedTenants/OnboardingRedirectTest.php index d0001103..46a0d131 100644 --- a/apps/platform/tests/Feature/ManagedTenants/OnboardingRedirectTest.php +++ b/apps/platform/tests/Feature/ManagedTenants/OnboardingRedirectTest.php @@ -2,10 +2,10 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; it('does not provide legacy onboarding entry points under /admin/new', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'owner'); $workspace = $tenant->workspace; diff --git a/apps/platform/tests/Feature/Models/TenantGraphOptionsKillSwitchTest.php b/apps/platform/tests/Feature/Models/TenantGraphOptionsKillSwitchTest.php index fc3ea27d..70395f1a 100644 --- a/apps/platform/tests/Feature/Models/TenantGraphOptionsKillSwitchTest.php +++ b/apps/platform/tests/Feature/Models/TenantGraphOptionsKillSwitchTest.php @@ -1,12 +1,12 @@ create([ +it('throws when ManagedEnvironment::graphOptions is called', function (): void { + $tenant = ManagedEnvironment::factory()->create([ 'app_client_id' => 'legacy-client-id', 'app_client_secret' => 'legacy-client-secret', ]); diff --git a/apps/platform/tests/Feature/Monitoring/ArtifactTruthRunDetailTest.php b/apps/platform/tests/Feature/Monitoring/ArtifactTruthRunDetailTest.php index 17446fc6..e31fc85d 100644 --- a/apps/platform/tests/Feature/Monitoring/ArtifactTruthRunDetailTest.php +++ b/apps/platform/tests/Feature/Monitoring/ArtifactTruthRunDetailTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\Operations\TenantlessOperationRunViewer; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Evidence\EvidenceCompletenessState; use App\Support\Evidence\EvidenceSnapshotStatus; use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter; @@ -16,7 +16,7 @@ uses(RefreshDatabase::class, BuildsGovernanceArtifactTruthFixtures::class); it('shows artifact truth for artifact-targeted runs when the produced evidence snapshot is degraded', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = $this->makeArtifactTruthRun($tenant, 'tenant.evidence.snapshot.generate'); @@ -51,14 +51,14 @@ }); it('shows missing-artifact guidance when a blocked artifact run never produced a record', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = $this->makeArtifactTruthRun( tenant: $tenant, type: 'tenant.review.compose', context: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ], attributes: [ diff --git a/apps/platform/tests/Feature/Monitoring/AuditCoverageGovernanceTest.php b/apps/platform/tests/Feature/Monitoring/AuditCoverageGovernanceTest.php index 2593dc49..9a2f9207 100644 --- a/apps/platform/tests/Feature/Monitoring/AuditCoverageGovernanceTest.php +++ b/apps/platform/tests/Feature/Monitoring/AuditCoverageGovernanceTest.php @@ -26,7 +26,7 @@ ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'audit-policy-a', 'policy_type' => 'deviceConfiguration', @@ -55,13 +55,13 @@ ); $started = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'baseline.capture.started') ->latest('id') ->first(); $completed = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'baseline.capture.completed') ->latest('id') ->first(); @@ -126,7 +126,7 @@ ); $completed = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'baseline.capture.completed') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Monitoring/AuditCoverageOperationsTest.php b/apps/platform/tests/Feature/Monitoring/AuditCoverageOperationsTest.php index 8293345c..8b84cb1f 100644 --- a/apps/platform/tests/Feature/Monitoring/AuditCoverageOperationsTest.php +++ b/apps/platform/tests/Feature/Monitoring/AuditCoverageOperationsTest.php @@ -87,7 +87,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', diff --git a/apps/platform/tests/Feature/Monitoring/AuditLogInspectFlowTest.php b/apps/platform/tests/Feature/Monitoring/AuditLogInspectFlowTest.php index 03921094..3831edb1 100644 --- a/apps/platform/tests/Feature/Monitoring/AuditLogInspectFlowTest.php +++ b/apps/platform/tests/Feature/Monitoring/AuditLogInspectFlowTest.php @@ -16,7 +16,7 @@ $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -54,7 +54,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'baseline_compare', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -62,7 +62,7 @@ $withRunLink = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -77,7 +77,7 @@ $withoutRunLink = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -115,7 +115,7 @@ $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -128,11 +128,11 @@ 'recorded_at' => now(), ]); - $foreignTenant = \App\Models\Tenant::factory()->create(); + $foreignTenant = \App\Models\ManagedEnvironment::factory()->create(); $foreignAudit = AuditLog::query()->create([ 'workspace_id' => (int) $foreignTenant->workspace_id, - 'tenant_id' => (int) $foreignTenant->getKey(), + 'managed_environment_id' => (int) $foreignTenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -166,7 +166,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'baseline_compare', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -174,7 +174,7 @@ $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -207,7 +207,7 @@ $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', diff --git a/apps/platform/tests/Feature/Monitoring/AuditLogSupportAccessHistoryTest.php b/apps/platform/tests/Feature/Monitoring/AuditLogSupportAccessHistoryTest.php index 9d817594..ec264f8b 100644 --- a/apps/platform/tests/Feature/Monitoring/AuditLogSupportAccessHistoryTest.php +++ b/apps/platform/tests/Feature/Monitoring/AuditLogSupportAccessHistoryTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Monitoring\AuditLog as AuditLogPage; use App\Models\AuditLog; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Audit\AuditActionId; use App\Support\Workspaces\WorkspaceContext; use Carbon\CarbonImmutable; @@ -17,7 +17,7 @@ $supportAccess = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'actor_email' => 'support@example.com', 'actor_name' => 'Support', 'actor_type' => 'platform', @@ -33,7 +33,7 @@ $unrelated = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'action' => 'workspace.selected', 'status' => 'success', 'summary' => 'Workspace selected', @@ -41,10 +41,10 @@ 'recorded_at' => now()->addSecond(), ]); - $foreignTenant = Tenant::factory()->create(); + $foreignTenant = ManagedEnvironment::factory()->create(); $foreign = AuditLog::query()->create([ 'workspace_id' => (int) $foreignTenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'action' => AuditActionId::SupportAccessRequested->value, 'status' => 'success', 'summary' => 'Support access requested for Foreign workspace', @@ -71,7 +71,7 @@ AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'actor_email' => 'support@example.com', 'actor_name' => 'Support', 'actor_type' => 'platform', @@ -87,7 +87,7 @@ AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'action' => 'workspace.selected', 'status' => 'success', 'summary' => 'Workspace selected', diff --git a/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueHierarchyTest.php b/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueHierarchyTest.php index 10cca344..19ec27ae 100644 --- a/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueHierarchyTest.php +++ b/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueHierarchyTest.php @@ -18,7 +18,7 @@ FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $approver->getKey(), 'owner_user_id' => (int) $approver->getKey(), @@ -49,7 +49,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $approver->getKey(), 'owner_user_id' => (int) $approver->getKey(), @@ -95,14 +95,14 @@ it('falls back to quiet monitoring when the requested exception is invalid or unauthorized', function (): void { [$approver, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); - $foreignTenant = \App\Models\Tenant::factory()->create(); + $foreignTenant = \App\Models\ManagedEnvironment::factory()->create(); [$foreignRequester] = createUserWithTenant(tenant: $foreignTenant, role: 'owner'); $foreignFinding = Finding::factory()->for($foreignTenant)->create(); $foreignException = FindingException::query()->create([ 'workspace_id' => (int) $foreignTenant->workspace_id, - 'tenant_id' => (int) $foreignTenant->getKey(), + 'managed_environment_id' => (int) $foreignTenant->getKey(), 'finding_id' => (int) $foreignFinding->getKey(), 'requested_by_user_id' => (int) $foreignRequester->getKey(), 'owner_user_id' => (int) $foreignRequester->getKey(), diff --git a/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueNavigationContextTest.php b/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueNavigationContextTest.php index a0ef2c0b..8a735da0 100644 --- a/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueNavigationContextTest.php +++ b/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueNavigationContextTest.php @@ -6,16 +6,16 @@ use App\Filament\Pages\Monitoring\FindingExceptionsQueue; use App\Models\Finding; use App\Models\FindingException; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Navigation\CanonicalNavigationContext; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Livewire\Livewire; it('keeps the finding exceptions queue secondary when opened from the governance inbox', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'manager'); @@ -30,7 +30,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -53,7 +53,7 @@ tenantId: (int) $tenant->getKey(), familyKey: 'finding_exceptions', backLinkUrl: GovernanceInbox::getUrl(panel: 'admin', parameters: [ - 'tenant_id' => (string) $tenant->getKey(), + 'managed_environment_id' => (string) $tenant->getKey(), 'family' => 'finding_exceptions', ]), ); @@ -64,7 +64,7 @@ ])) ->actingAs($user) ->test(FindingExceptionsQueue::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenant->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenant->getKey()) ->assertSet('selectedFindingExceptionId', (int) $exception->getKey()) ->assertActionVisible('return_to_governance_inbox') ->assertActionVisible('open_selected_exception') @@ -76,10 +76,10 @@ expect($component->instance()->selectedExceptionUrl()) ->toContain('nav%5Bsource_surface%5D=governance.inbox') ->toContain('nav%5Bfamily_key%5D=finding_exceptions') - ->toContain('nav%5Btenant_id%5D='.(string) $tenant->getKey()); + ->toContain('nav%5Bmanaged_environment_id%5D='.(string) $tenant->getKey()); expect($component->instance()->selectedFindingUrl()) ->toContain('nav%5Bsource_surface%5D=governance.inbox') ->toContain('nav%5Bfamily_key%5D=finding_exceptions') - ->toContain('nav%5Btenant_id%5D='.(string) $tenant->getKey()); + ->toContain('nav%5Bmanaged_environment_id%5D='.(string) $tenant->getKey()); }); diff --git a/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueTest.php b/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueTest.php index 75abd811..c4f4018b 100644 --- a/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueTest.php +++ b/apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueTest.php @@ -15,22 +15,22 @@ it('shows only entitled tenants in the canonical queue and supports tenant and validity filters', function (): void { [$approver, $tenantA] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); - $tenantB = \App\Models\Tenant::factory()->create([ + $tenantB = \App\Models\ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $approver, role: 'owner', workspaceRole: 'manager'); - $tenantC = \App\Models\Tenant::factory()->create([ + $tenantC = \App\Models\ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); - $makeException = function (\App\Models\Tenant $tenant, array $attributes): FindingException { + $makeException = function (\App\Models\ManagedEnvironment $tenant, array $attributes): FindingException { [$requester] = createUserWithTenant(tenant: $tenant, role: 'owner'); $finding = Finding::factory()->for($tenant)->create(); return FindingException::query()->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $requester->getKey(), 'owner_user_id' => (int) $requester->getKey(), @@ -71,7 +71,7 @@ Livewire::test(FindingExceptionsQueue::class) ->assertCanSeeTableRecords([$expiring, $rejected]) ->assertCanNotSeeTableRecords([$unauthorized]) - ->filterTable('tenant_id', (string) $tenantB->getKey()) + ->filterTable('managed_environment_id', (string) $tenantB->getKey()) ->assertCanSeeTableRecords([$rejected]) ->assertCanNotSeeTableRecords([$expiring]) ->filterTable('status', FindingException::STATUS_REJECTED) @@ -81,7 +81,7 @@ 'tenant' => (string) $tenantB->external_id, ]) ->test(FindingExceptionsQueue::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantB->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantB->getKey()) ->assertActionVisible('view_tenant_register'); $filtersComponent = Livewire::test(FindingExceptionsQueue::class); diff --git a/apps/platform/tests/Feature/Monitoring/GovernanceOperationRunSummariesTest.php b/apps/platform/tests/Feature/Monitoring/GovernanceOperationRunSummariesTest.php index b66791e4..90c12091 100644 --- a/apps/platform/tests/Feature/Monitoring/GovernanceOperationRunSummariesTest.php +++ b/apps/platform/tests/Feature/Monitoring/GovernanceOperationRunSummariesTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Operations\TenantlessOperationRunViewer; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Baselines\BaselineReasonCodes; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -27,7 +27,7 @@ function governanceVisibleText(Testable $component): string return trim((string) preg_replace('/\s+/', ' ', strip_tags($html))); } -function governanceRunViewer(TestCase $testCase, $user, Tenant $tenant, OperationRun $run): Testable +function governanceRunViewer(TestCase $testCase, $user, ManagedEnvironment $tenant, OperationRun $run): Testable { Filament::setTenant(null, true); $testCase->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]); @@ -38,11 +38,11 @@ function governanceRunViewer(TestCase $testCase, $user, Tenant $tenant, Operatio } it('renders a summary-first hierarchy for zero-output baseline compare runs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', @@ -80,11 +80,11 @@ function governanceRunViewer(TestCase $testCase, $user, Tenant $tenant, Operatio }); it('keeps blocked baseline capture summaries ahead of diagnostics without adding new run-detail actions', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_capture', 'status' => 'completed', @@ -120,7 +120,7 @@ function governanceRunViewer(TestCase $testCase, $user, Tenant $tenant, Operatio }); it('shows processing outcome separately from artifact impact for stale evidence snapshot runs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = $this->makeArtifactTruthRun($tenant, 'tenant.evidence.snapshot.generate'); @@ -141,7 +141,7 @@ function governanceRunViewer(TestCase $testCase, $user, Tenant $tenant, Operatio }); it('preserves a dominant cause plus secondary causes for degraded review composition runs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = $this->makeArtifactTruthRun($tenant, 'tenant.review.compose'); @@ -178,11 +178,11 @@ function governanceRunViewer(TestCase $testCase, $user, Tenant $tenant, Operatio }); it('shows failed-latest-inventory baseline capture summaries before diagnostics', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_capture', 'status' => 'completed', @@ -215,11 +215,11 @@ function governanceRunViewer(TestCase $testCase, $user, Tenant $tenant, Operatio }); it('shows zero-subject baseline capture summaries before diagnostics', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_capture', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Monitoring/GovernanceRunExplanationFallbackTest.php b/apps/platform/tests/Feature/Monitoring/GovernanceRunExplanationFallbackTest.php index 959529f7..5360bfdf 100644 --- a/apps/platform/tests/Feature/Monitoring/GovernanceRunExplanationFallbackTest.php +++ b/apps/platform/tests/Feature/Monitoring/GovernanceRunExplanationFallbackTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\Operations\TenantlessOperationRunViewer; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -13,14 +13,14 @@ uses(BuildsGovernanceArtifactTruthFixtures::class); it('renders blocked governance runs with explanation-first fallback copy when no artifact record exists', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = $this->makeArtifactTruthRun( tenant: $tenant, type: 'tenant.review.compose', context: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'reason_code' => 'review_missing_sections', ], diff --git a/apps/platform/tests/Feature/Monitoring/HeaderContextBarTest.php b/apps/platform/tests/Feature/Monitoring/HeaderContextBarTest.php index 802f74cb..33fd3216 100644 --- a/apps/platform/tests/Feature/Monitoring/HeaderContextBarTest.php +++ b/apps/platform/tests/Feature/Monitoring/HeaderContextBarTest.php @@ -4,12 +4,12 @@ use App\Filament\Pages\ChooseWorkspace; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; it('renders the tenant context picker on tenantless Monitoring → Operations', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $workspaceName = $tenant->workspace?->name; @@ -45,7 +45,7 @@ ->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, ]) - ->post(route('admin.select-tenant'), ['tenant_id' => (int) $tenant->getKey()]) + ->post(route('admin.select-tenant'), ['managed_environment_id' => (int) $tenant->getKey()]) ->assertRedirect(); }); @@ -70,7 +70,7 @@ }); it('keeps tenant-scoped pages selector read-only while exposing the clear tenant scope action', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $this->actingAs($user) @@ -84,15 +84,15 @@ }); it('renders routed tenant resource view pages with a clear tenant scope action but no inline selector list', function (): void { - $currentTenant = Tenant::factory()->create([ + $currentTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'name' => 'YPTW2', 'environment' => 'dev', ]); [$user, $currentTenant] = createUserWithTenant($currentTenant, role: 'owner'); - $routedTenant = Tenant::factory()->create([ - 'status' => Tenant::STATUS_ONBOARDING, + $routedTenant = ManagedEnvironment::factory()->create([ + 'status' => ManagedEnvironment::STATUS_ONBOARDING, 'workspace_id' => (int) $currentTenant->workspace_id, 'name' => 'Test', 'environment' => 'dev', @@ -117,10 +117,10 @@ }); it('filters the header tenant picker to tenants the user can access', function (): void { - $tenantA = Tenant::factory()->create(['status' => 'active']); + $tenantA = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner', workspaceRole: 'readonly'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, 'name' => 'ZZZ-UNAUTHORIZED-TENANT-NAME-12345', @@ -139,10 +139,10 @@ }); it('keeps the header tenant picker limited to tenant-entitled active tenants for workspace owners', function (): void { - $tenantA = Tenant::factory()->create(['status' => 'active']); + $tenantA = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner', workspaceRole: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, 'name' => 'ZZZ-UNASSIGNED-TENANT-NAME-12345', @@ -161,15 +161,15 @@ }); it('hides onboarding tenants from the header tenant picker even for workspace owners', function (): void { - $tenantA = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create([ 'status' => 'active', 'name' => 'YPTW2', 'environment' => 'other', ]); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner', workspaceRole: 'owner'); - $onboardingTenant = Tenant::factory()->create([ - 'status' => Tenant::STATUS_ONBOARDING, + $onboardingTenant = ManagedEnvironment::factory()->create([ + 'status' => ManagedEnvironment::STATUS_ONBOARDING, 'workspace_id' => (int) $tenantA->workspace_id, 'name' => 'YPTW2', 'environment' => 'dev', @@ -188,10 +188,10 @@ }); it('does not implicitly switch tenant when opening canonical operation deep links', function (): void { - $tenantA = Tenant::factory()->create(['status' => 'active']); + $tenantA = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -201,14 +201,14 @@ ]); $runA = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'initiator_name' => 'TenantA', ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', 'initiator_name' => 'TenantB', @@ -238,20 +238,20 @@ }); it('shows explicit mismatch context on canonical run pages while keeping the current header tenant label', function (): void { - $runTenant = Tenant::factory()->create([ - 'name' => 'Run Tenant', + $runTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Run ManagedEnvironment', ]); [$user, $runTenant] = createUserWithTenant($runTenant, role: 'owner'); - $currentTenant = Tenant::factory()->create([ - 'name' => 'Current Tenant', + $currentTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Current ManagedEnvironment', 'workspace_id' => (int) $runTenant->workspace_id, ]); createUserWithTenant($currentTenant, $user, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $runTenant->getKey(), + 'managed_environment_id' => (int) $runTenant->getKey(), 'workspace_id' => (int) $runTenant->workspace_id, 'type' => 'policy.sync', ]); @@ -264,19 +264,19 @@ ]) ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertOk() - ->assertSee('Tenant scope: Current Tenant') + ->assertSee('ManagedEnvironment scope: Current ManagedEnvironment') ->assertSee('Current tenant context differs from this operation') - ->assertSee('Operation tenant: Run Tenant.'); + ->assertSee('Operation tenant: Run ManagedEnvironment.'); }); it('shows canonical workspace framing on canonical run pages with no selected tenant context', function (): void { - $tenant = Tenant::factory()->create([ - 'name' => 'Workspace Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'Workspace ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', ]); diff --git a/apps/platform/tests/Feature/Monitoring/MonitoringOperationsTest.php b/apps/platform/tests/Feature/Monitoring/MonitoringOperationsTest.php index 58e59f28..b9154491 100644 --- a/apps/platform/tests/Feature/Monitoring/MonitoringOperationsTest.php +++ b/apps/platform/tests/Feature/Monitoring/MonitoringOperationsTest.php @@ -14,7 +14,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', @@ -57,7 +57,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'running', @@ -67,7 +67,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'restore.execute', 'status' => 'completed', @@ -95,7 +95,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Monitoring/MonitoringPageStateContractTest.php b/apps/platform/tests/Feature/Monitoring/MonitoringPageStateContractTest.php index 135de7b7..7e6ea055 100644 --- a/apps/platform/tests/Feature/Monitoring/MonitoringPageStateContractTest.php +++ b/apps/platform/tests/Feature/Monitoring/MonitoringPageStateContractTest.php @@ -40,7 +40,7 @@ function monitoringPageStateFieldSummary(array $contract): array [ 'surfaceKey' => 'operations', 'surfaceType' => 'simple_monitoring', - 'shareableStateKeys' => ['tenant_id', 'tenant_scope', 'problemClass', 'activeTab'], + 'shareableStateKeys' => ['managed_environment_id', 'tenant_scope', 'problemClass', 'activeTab'], 'localOnlyStateKeys' => [], 'inspectContract' => [ 'primaryModel' => 'none', @@ -49,7 +49,7 @@ function monitoringPageStateFieldSummary(array $contract): array 'shareable' => false, ], 'stateFields' => [ - 'tenant_id' => ['stateClass' => 'contextual_prefilter', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true], + 'managed_environment_id' => ['stateClass' => 'contextual_prefilter', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true], 'tenant_scope' => ['stateClass' => 'contextual_prefilter', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true], 'problemClass' => ['stateClass' => 'contextual_prefilter', 'queryRole' => 'scoped_deeplink', 'shareable' => true, 'restorableOnRefresh' => true], 'activeTab' => ['stateClass' => 'active', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true], @@ -73,7 +73,7 @@ function monitoringPageStateFieldSummary(array $contract): array 'stateFields' => [ 'event' => ['stateClass' => 'inspect', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true], 'supportAccess' => ['stateClass' => 'contextual_prefilter', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true], - 'tenant_id' => ['stateClass' => 'contextual_prefilter', 'queryRole' => 'durable_restorable', 'shareable' => false, 'restorableOnRefresh' => true], + 'managed_environment_id' => ['stateClass' => 'contextual_prefilter', 'queryRole' => 'durable_restorable', 'shareable' => false, 'restorableOnRefresh' => true], 'tableSearch' => ['stateClass' => 'shareable_restorable', 'queryRole' => 'unsupported', 'shareable' => false, 'restorableOnRefresh' => true], ], ], @@ -104,7 +104,7 @@ function monitoringPageStateFieldSummary(array $contract): array [ 'surfaceKey' => 'evidence_overview', 'surfaceType' => 'simple_monitoring', - 'shareableStateKeys' => ['tenant_id', 'search'], + 'shareableStateKeys' => ['managed_environment_id', 'search'], 'localOnlyStateKeys' => [], 'inspectContract' => [ 'primaryModel' => 'none', @@ -113,7 +113,7 @@ function monitoringPageStateFieldSummary(array $contract): array 'shareable' => false, ], 'stateFields' => [ - 'tenant_id' => ['stateClass' => 'contextual_prefilter', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true], + 'managed_environment_id' => ['stateClass' => 'contextual_prefilter', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true], 'search' => ['stateClass' => 'contextual_prefilter', 'queryRole' => 'durable_restorable', 'shareable' => true, 'restorableOnRefresh' => true], 'tableFilters' => ['stateClass' => 'shareable_restorable', 'queryRole' => 'unsupported', 'shareable' => false, 'restorableOnRefresh' => true], 'tableSort' => ['stateClass' => 'shareable_restorable', 'queryRole' => 'unsupported', 'shareable' => false, 'restorableOnRefresh' => true], diff --git a/apps/platform/tests/Feature/Monitoring/OperationLifecycleAggregateVisibilityTest.php b/apps/platform/tests/Feature/Monitoring/OperationLifecycleAggregateVisibilityTest.php index 7273f8d4..eb34154d 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationLifecycleAggregateVisibilityTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationLifecycleAggregateVisibilityTest.php @@ -9,7 +9,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'running', @@ -19,7 +19,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'restore.execute', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Monitoring/OperationLifecycleFreshnessPresentationTest.php b/apps/platform/tests/Feature/Monitoring/OperationLifecycleFreshnessPresentationTest.php index 66c0087d..18bc3317 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationLifecycleFreshnessPresentationTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationLifecycleFreshnessPresentationTest.php @@ -9,7 +9,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $staleRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'running', @@ -19,7 +19,7 @@ ]); $reconciledRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'restore.execute', 'status' => 'completed', @@ -65,7 +65,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $staleRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'running', @@ -75,7 +75,7 @@ ]); $reconciledRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'restore.execute', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Monitoring/OperationRunBlockedSpec081Test.php b/apps/platform/tests/Feature/Monitoring/OperationRunBlockedSpec081Test.php index 02bb7a3f..f5c08ff4 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationRunBlockedSpec081Test.php +++ b/apps/platform/tests/Feature/Monitoring/OperationRunBlockedSpec081Test.php @@ -2,14 +2,14 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\OperationRunService; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\Providers\ProviderReasonCodes; it('Spec081 stores blocked operation runs with sanitized reason and link-only next steps', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $service = app(OperationRunService::class); $run = $service->ensureRunWithIdentity( diff --git a/apps/platform/tests/Feature/Monitoring/OperationRunResolvedReferencePresentationTest.php b/apps/platform/tests/Feature/Monitoring/OperationRunResolvedReferencePresentationTest.php index e6e6ebfa..56017f03 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationRunResolvedReferencePresentationTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationRunResolvedReferencePresentationTest.php @@ -4,7 +4,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunLinks; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -32,14 +32,14 @@ }); it('keeps archived run references viewable with lifecycle-aware framing', function (): void { - $activeTenant = Tenant::factory()->create([ - 'name' => 'Active Tenant', + $activeTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Active ManagedEnvironment', ]); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); $this->actingAs($user); - $archivedTenant = Tenant::factory()->create([ - 'name' => 'Archived Tenant', + $archivedTenant = ManagedEnvironment::factory()->create([ + 'name' => 'Archived ManagedEnvironment', 'workspace_id' => (int) $activeTenant->workspace_id, ]); @@ -59,7 +59,7 @@ ->assertSee('Operation tenant is not available in the current tenant selector') ->assertSee('This tenant is currently archived') ->assertSee('Back to Operations') - ->assertDontSee('← Back to Archived Tenant'); + ->assertDontSee('← Back to Archived ManagedEnvironment'); }); it('resolves legacy operation values to canonical operation metadata on read paths', function (): void { diff --git a/apps/platform/tests/Feature/Monitoring/OperationsActionsEnqueueRunTest.php b/apps/platform/tests/Feature/Monitoring/OperationsActionsEnqueueRunTest.php index 58c2a188..007fb341 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationsActionsEnqueueRunTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationsActionsEnqueueRunTest.php @@ -10,7 +10,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', diff --git a/apps/platform/tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php b/apps/platform/tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php index cd70533a..5ca3af5c 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Monitoring\Operations; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Navigation\CanonicalNavigationContext; use App\Support\OperationRunLinks; use App\Support\Workspaces\WorkspaceContext; @@ -16,10 +16,10 @@ uses(RefreshDatabase::class); it('serves /admin/operations without tenant context (workspace-wide)', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -29,14 +29,14 @@ ]); $runA = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'initiator_name' => 'TenantA', ]); $runB = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', 'initiator_name' => 'TenantB', @@ -55,11 +55,11 @@ }); it('serves /admin/operations/{run} with and without tenant context', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', ]); @@ -83,17 +83,17 @@ }); it('keeps operation detail accessible when the active tenant context does not match the run tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $runB = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', ]); @@ -108,13 +108,13 @@ }); it('keeps canonical operation detail accessible for selector-excluded tenant runs', function (): void { - $tenant = Tenant::factory()->create([ - 'status' => Tenant::STATUS_ONBOARDING, + $tenant = ManagedEnvironment::factory()->create([ + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', ]); @@ -130,10 +130,10 @@ }); it('defaults the tenant filter from tenant context and can be cleared', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -143,14 +143,14 @@ ]); $runA = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'initiator_name' => 'TenantA', ]); $runB = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', 'initiator_name' => 'TenantB', @@ -169,11 +169,11 @@ ->test(Operations::class) ->assertCanSeeTableRecords([$runA]) ->assertCanNotSeeTableRecords([$runB]) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()); + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()); $component ->callAction('operate_hub_show_all_tenants') - ->assertSet('tableFilters.tenant_id.value', null) + ->assertSet('tableFilters.managed_environment_id.value', null) ->assertRedirect('/admin/operations'); Filament::setTenant(null, true); @@ -185,7 +185,7 @@ }); it('shows an explicit back-link when canonical context is present on the operations index', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); Filament::setTenant($tenant, true); @@ -209,7 +209,7 @@ }); it('keeps the canonical back-link action after Livewire hydration on the operations index', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); Filament::setTenant($tenant, true); @@ -221,7 +221,7 @@ 'nav' => [ 'source_surface' => 'finding.list_row', 'canonical_route_name' => 'admin.operations.index', - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'back_label' => 'Back to findings', 'back_url' => '/admin/findings?tenant='.$tenant->external_id, ], @@ -237,7 +237,7 @@ }); it('has reserved Monitoring placeholder pages for Alerts and Audit Log', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); Filament::setTenant(null, true); diff --git a/apps/platform/tests/Feature/Monitoring/OperationsDashboardDrillthroughTest.php b/apps/platform/tests/Feature/Monitoring/OperationsDashboardDrillthroughTest.php index d3ae09bb..f56ebb62 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationsDashboardDrillthroughTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationsDashboardDrillthroughTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Monitoring\Operations; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunLinks; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; @@ -13,16 +13,16 @@ use Livewire\Livewire; it('preserves tenant context and healthy activity semantics for dashboard operations drill-throughs', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $healthyActive = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Running->value, @@ -32,7 +32,7 @@ ]); $staleActive = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -41,7 +41,7 @@ ]); $otherTenantActive = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Running->value, @@ -55,28 +55,28 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); Livewire::withQueryParams([ - 'tenant_id' => (string) $tenantA->getKey(), + 'managed_environment_id' => (string) $tenantA->getKey(), 'activeTab' => 'active', ]) ->actingAs($user) ->test(Operations::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()) ->assertSet('activeTab', 'active') ->assertCanSeeTableRecords([$healthyActive]) ->assertCanNotSeeTableRecords([$staleActive, $otherTenantActive]); }); it('uses the stale-attention dashboard landing for likely stale active runs', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $staleRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -85,7 +85,7 @@ ]); $terminalRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -93,7 +93,7 @@ ]); $otherTenantStale = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -106,29 +106,29 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); Livewire::withQueryParams([ - 'tenant_id' => (string) $tenantA->getKey(), + 'managed_environment_id' => (string) $tenantA->getKey(), 'activeTab' => OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION, 'problemClass' => OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION, ]) ->actingAs($user) ->test(Operations::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()) ->assertSet('activeTab', OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION) ->assertCanSeeTableRecords([$staleRun]) ->assertCanNotSeeTableRecords([$terminalRun, $otherTenantStale]); }); it('uses the terminal follow-up landing for failed, warning, and blocked runs without mixing in stale active work', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $partialRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -136,7 +136,7 @@ ]); $failedRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -144,7 +144,7 @@ ]); $blockedRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -152,7 +152,7 @@ ]); $staleRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -161,7 +161,7 @@ ]); $healthyActive = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -170,7 +170,7 @@ ]); $otherTenantFailed = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -182,23 +182,23 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); Livewire::withQueryParams([ - 'tenant_id' => (string) $tenantA->getKey(), + 'managed_environment_id' => (string) $tenantA->getKey(), 'activeTab' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, 'problemClass' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, ]) ->actingAs($user) ->test(Operations::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()) ->assertSet('activeTab', OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP) ->assertCanSeeTableRecords([$partialRun, $failedRun, $blockedRun]) ->assertCanNotSeeTableRecords([$healthyActive, $otherTenantFailed]); }); it('allows workspace-originated operations drill-through to clear tenant context and show workspace-wide terminal follow-up', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); @@ -210,7 +210,7 @@ ]); $otherTenantFailed = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'policy.sync', 'status' => OperationRunStatus::Completed->value, @@ -218,7 +218,7 @@ ]); $healthyActive = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Running->value, @@ -238,18 +238,18 @@ ]) ->actingAs($user) ->test(Operations::class) - ->assertSet('tableFilters.tenant_id.value', null) + ->assertSet('tableFilters.managed_environment_id.value', null) ->assertSet('activeTab', OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP) ->assertCanSeeTableRecords([$workspaceRun, $otherTenantFailed]) ->assertCanNotSeeTableRecords([$healthyActive]); }); it('builds canonical dashboard operations URLs with tenant and tab continuity', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); expect(OperationRunLinks::index($tenant, activeTab: 'active')) ->toBe(route('admin.operations.index', [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'activeTab' => 'active', ])) ->and(OperationRunLinks::index( @@ -258,7 +258,7 @@ problemClass: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, )) ->toBe(route('admin.operations.index', [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'activeTab' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, 'problemClass' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, ])) @@ -275,15 +275,15 @@ }); it('ignores unauthorized requested tenant filters while keeping canonical tab continuity', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $foreignTenant = Tenant::factory()->create([ + $foreignTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Running->value, @@ -297,16 +297,16 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); $component = Livewire::withQueryParams([ - 'tenant_id' => (string) $foreignTenant->getKey(), + 'managed_environment_id' => (string) $foreignTenant->getKey(), 'activeTab' => 'active', ]) ->actingAs($user) ->test(Operations::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()) ->assertSet('activeTab', 'active'); expect(urldecode($component->instance()->tabUrl(OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP))) ->toContain('activeTab='.OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP) ->toContain('problemClass='.OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP) - ->not->toContain('tenant_id='.(int) $foreignTenant->getKey()); + ->not->toContain('managed_environment_id='.(int) $foreignTenant->getKey()); }); diff --git a/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyRenderTest.php b/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyRenderTest.php index 2e51ad69..90156280 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyRenderTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyRenderTest.php @@ -11,7 +11,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'restore.execute', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyRenderingSpec081Test.php b/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyRenderingSpec081Test.php index 719c5924..bf448b51 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyRenderingSpec081Test.php +++ b/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyRenderingSpec081Test.php @@ -11,7 +11,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'blocked', diff --git a/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyTest.php b/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyTest.php index 368e1dfe..262ebaa2 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationsDbOnlyTest.php @@ -9,7 +9,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', @@ -46,7 +46,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', diff --git a/apps/platform/tests/Feature/Monitoring/OperationsHeaderHierarchyTest.php b/apps/platform/tests/Feature/Monitoring/OperationsHeaderHierarchyTest.php index 9a8b043d..83cff425 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationsHeaderHierarchyTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationsHeaderHierarchyTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Navigation\CanonicalNavigationContext; use App\Support\OperationRunLinks; use App\Support\Workspaces\WorkspaceContext; @@ -13,11 +13,11 @@ uses(RefreshDatabase::class); it('renders the operations landing as a quiet monitoring surface', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', ]); @@ -37,7 +37,7 @@ }); it('surfaces canonical return context separately from the operations work lane', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $context = new CanonicalNavigationContext( diff --git a/apps/platform/tests/Feature/Monitoring/OperationsKpiHeaderTenantContextTest.php b/apps/platform/tests/Feature/Monitoring/OperationsKpiHeaderTenantContextTest.php index 9339d050..744bcd71 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationsKpiHeaderTenantContextTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationsKpiHeaderTenantContextTest.php @@ -4,7 +4,7 @@ use App\Filament\Widgets\Operations\OperationsKpiHeader; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\Workspaces\WorkspaceContext; @@ -28,24 +28,24 @@ function operationsKpiValues($component): array } it('filters operations KPI stats by remembered tenant when filament tenant is absent', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -54,7 +54,7 @@ function operationsKpiValues($component): array ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -78,24 +78,24 @@ function operationsKpiValues($component): array }); it('prefers the filament tenant over remembered tenant in conflicting KPI context', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, diff --git a/apps/platform/tests/Feature/Monitoring/OperationsRelatedNavigationTest.php b/apps/platform/tests/Feature/Monitoring/OperationsRelatedNavigationTest.php index 6b65ea74..48f7a37c 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationsRelatedNavigationTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationsRelatedNavigationTest.php @@ -13,7 +13,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Nightly backup', ]); diff --git a/apps/platform/tests/Feature/Monitoring/OperationsTenantScopeTest.php b/apps/platform/tests/Feature/Monitoring/OperationsTenantScopeTest.php index 16f96d04..b07d0e7c 100644 --- a/apps/platform/tests/Feature/Monitoring/OperationsTenantScopeTest.php +++ b/apps/platform/tests/Feature/Monitoring/OperationsTenantScopeTest.php @@ -2,7 +2,7 @@ use App\Filament\Pages\Monitoring\Operations; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Support\Facades\Http; @@ -13,8 +13,8 @@ }); it('defaults Monitoring → Operations list to the active tenant when tenant context is set', function () { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenantA, role: 'owner'); @@ -25,7 +25,7 @@ ]); $runA = OperationRun::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', @@ -33,7 +33,7 @@ ]); $runB = OperationRun::factory()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'type' => 'inventory_sync', 'status' => 'queued', 'outcome' => 'pending', @@ -49,19 +49,19 @@ ->test(Operations::class) ->assertCanSeeTableRecords([$runA]) ->assertCanNotSeeTableRecords([$runB]) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()); + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenantA->workspace_id]) ->get('/admin/operations') ->assertOk() ->assertSee('Policy sync') - ->assertSee('Tenant scope: '.$tenantA->name); + ->assertSee('ManagedEnvironment scope: '.$tenantA->name); }); it('defaults Monitoring → Operations list to the remembered tenant when Filament tenant is not available', function () { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenantA, role: 'owner'); @@ -72,7 +72,7 @@ ]); $runA = OperationRun::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', @@ -80,7 +80,7 @@ ]); $runB = OperationRun::factory()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'type' => 'inventory_sync', 'status' => 'queued', 'outcome' => 'pending', @@ -99,19 +99,19 @@ ->test(Operations::class) ->assertCanSeeTableRecords([$runA]) ->assertCanNotSeeTableRecords([$runB]) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()); + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => $workspaceId]) ->get('/admin/operations') ->assertOk() - ->assertSee('Tenant scope: '.$tenantA->name) + ->assertSee('ManagedEnvironment scope: '.$tenantA->name) ->assertSee('Policy sync'); }); it('scopes Monitoring → Operations tabs to the active tenant', function () { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenantA, role: 'owner'); @@ -122,7 +122,7 @@ ]); $runActiveA = OperationRun::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', @@ -130,7 +130,7 @@ ]); $runStaleA = OperationRun::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'type' => 'inventory_sync', 'status' => 'queued', 'outcome' => 'pending', @@ -139,7 +139,7 @@ ]); $runSucceededA = OperationRun::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'type' => 'policy.sync', 'status' => 'completed', 'outcome' => 'succeeded', @@ -147,7 +147,7 @@ ]); $runPartialA = OperationRun::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'type' => 'policy.sync', 'status' => 'completed', 'outcome' => 'partially_succeeded', @@ -155,7 +155,7 @@ ]); $runBlockedA = OperationRun::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'type' => 'policy.sync', 'status' => 'completed', 'outcome' => 'blocked', @@ -163,7 +163,7 @@ ]); $runFailedA = OperationRun::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'type' => 'policy.sync', 'status' => 'completed', 'outcome' => 'failed', @@ -171,7 +171,7 @@ ]); $runActiveB = OperationRun::factory()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'type' => 'inventory_sync', 'status' => 'queued', 'outcome' => 'pending', @@ -179,7 +179,7 @@ ]); $runFailedB = OperationRun::factory()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'type' => 'inventory_sync', 'status' => 'completed', 'outcome' => 'failed', @@ -233,13 +233,13 @@ }); it('prevents cross-workspace access to Monitoring → Operations detail', function () { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); $runB = OperationRun::factory()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'type' => 'inventory_sync', 'status' => 'queued', 'outcome' => 'pending', diff --git a/apps/platform/tests/Feature/MonitoringOperationsTest.php b/apps/platform/tests/Feature/MonitoringOperationsTest.php index 92366769..2fd8e308 100644 --- a/apps/platform/tests/Feature/MonitoringOperationsTest.php +++ b/apps/platform/tests/Feature/MonitoringOperationsTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Support\Verification\VerificationReportWriter; @@ -11,11 +11,11 @@ use Filament\Facades\Filament; it('allows access to Monitoring → Operations for workspace members', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', @@ -34,11 +34,11 @@ }); it('renders Monitoring → Operations pages DB-only (never calls Graph)', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', @@ -70,10 +70,10 @@ }); it('keeps the operations list workspace-scoped when tenant context is set', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -83,14 +83,14 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'initiator_name' => 'TenantA', ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', 'initiator_name' => 'TenantB', @@ -106,11 +106,11 @@ }); it('allows readonly users to view operations list and detail', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', @@ -145,11 +145,11 @@ }); it('renders shared verification family markers on monitoring operation detail for workspace members', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Navigation/RelatedNavigationResolverMemoizationTest.php b/apps/platform/tests/Feature/Navigation/RelatedNavigationResolverMemoizationTest.php index c6e4e0fc..6a0a0a58 100644 --- a/apps/platform/tests/Feature/Navigation/RelatedNavigationResolverMemoizationTest.php +++ b/apps/platform/tests/Feature/Navigation/RelatedNavigationResolverMemoizationTest.php @@ -37,11 +37,11 @@ ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), ]); @@ -127,7 +127,7 @@ }); it('keeps related-navigation target routes tenant-safe for non-members and capability-limited members', function (): void { - $workspaceTenant = \App\Models\Tenant::factory()->create(); + $workspaceTenant = \App\Models\ManagedEnvironment::factory()->create(); [$member, $workspaceTenant] = createMinimalUserWithTenant(tenant: $workspaceTenant, role: 'readonly'); $nonMember = \App\Models\User::factory()->create(); diff --git a/apps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php b/apps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php index afc1b739..d3f83878 100644 --- a/apps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php +++ b/apps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\FindingResource; use App\Models\AlertRule; use App\Models\Finding; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Notifications\Findings\FindingEventNotification; use App\Services\Auth\CapabilityResolver; @@ -116,8 +116,8 @@ function spec230ExpectedNotificationIcon(string $status): string $url = data_get($assignee->notifications()->latest('id')->first(), 'data.actions.0.url'); - TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('user_id', (int) $assignee->getKey()) ->delete(); diff --git a/apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php b/apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php index bdfa860b..0abdd723 100644 --- a/apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php +++ b/apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php @@ -93,7 +93,7 @@ function spec230ExpectedNotificationIcon(string $status): string $this->actingAs($user); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', @@ -125,7 +125,7 @@ function spec230ExpectedNotificationIcon(string $status): string $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', @@ -152,7 +152,7 @@ function spec230ExpectedNotificationIcon(string $status): string Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory_sync', @@ -200,7 +200,7 @@ function spec230ExpectedNotificationIcon(string $status): string $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', @@ -241,7 +241,7 @@ function spec230ExpectedNotificationIcon(string $status): string Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, @@ -279,7 +279,7 @@ function spec230ExpectedNotificationIcon(string $status): string Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => null, 'initiator_name' => 'System', @@ -312,7 +312,7 @@ function spec230ExpectedNotificationIcon(string $status): string ]); $run = OperationRun::factory()->create([ - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'inventory_sync', 'status' => 'completed', 'outcome' => 'succeeded', @@ -342,7 +342,7 @@ function spec230ExpectedNotificationIcon(string $status): string Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'backup_set.update', @@ -417,7 +417,7 @@ function spec230ExpectedNotificationIcon(string $status): string $this->actingAs($user); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, diff --git a/apps/platform/tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php b/apps/platform/tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php index d8d31e0e..e5cf7986 100644 --- a/apps/platform/tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php +++ b/apps/platform/tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php @@ -85,7 +85,7 @@ function spec230AssertSharedNotificationPayload(array $payload, array $expected) }, emitQueuedNotification: true); $completedRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $owner->getKey(), 'initiator_name' => $owner->name, @@ -167,7 +167,7 @@ function spec230AssertSharedNotificationPayload(array $payload, array $expected) $tenantlessQueuedRun = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'user_id' => (int) $owner->getKey(), 'initiator_name' => $owner->name, 'type' => 'provider.connection.check', @@ -179,7 +179,7 @@ function spec230AssertSharedNotificationPayload(array $payload, array $expected) $tenantlessCompletedRun = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'user_id' => (int) $owner->getKey(), 'initiator_name' => $owner->name, 'type' => 'provider.connection.check', diff --git a/apps/platform/tests/Feature/Onboarding/AdminConsentCallbackPlatformConnectionTest.php b/apps/platform/tests/Feature/Onboarding/AdminConsentCallbackPlatformConnectionTest.php index 02a9f660..efc56e98 100644 --- a/apps/platform/tests/Feature/Onboarding/AdminConsentCallbackPlatformConnectionTest.php +++ b/apps/platform/tests/Feature/Onboarding/AdminConsentCallbackPlatformConnectionTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Providers\ProviderConnectionType; use App\Support\Providers\ProviderConsentStatus; use App\Support\Providers\ProviderReasonCodes; @@ -13,18 +13,18 @@ uses(RefreshDatabase::class); it('stores a successful callback as a platform connection with separate consent and verification states', function (): void { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-platform-ok', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-platform-ok', 'name' => 'Contoso Platform', ]); $this->get(route('admin.consent.callback', [ - 'tenant' => $tenant->tenant_id, + 'tenant' => $tenant->managed_environment_id, 'admin_consent' => 'true', ]))->assertOk(); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('entra_tenant_id', $tenant->graphTenantId()) ->firstOrFail(); @@ -38,18 +38,18 @@ }); it('stores callback failures without promoting the platform connection to a verified state', function (): void { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-platform-error', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-platform-error', 'name' => 'Fabrikam Platform', ]); $this->get(route('admin.consent.callback', [ - 'tenant' => $tenant->tenant_id, + 'tenant' => $tenant->managed_environment_id, 'error' => 'access_denied', ]))->assertOk(); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('entra_tenant_id', $tenant->graphTenantId()) ->firstOrFail(); diff --git a/apps/platform/tests/Feature/Onboarding/ManagedTenantOnboardingEntitlementTest.php b/apps/platform/tests/Feature/Onboarding/ManagedTenantOnboardingEntitlementTest.php index 73ede644..44bddaf8 100644 --- a/apps/platform/tests/Feature/Onboarding/ManagedTenantOnboardingEntitlementTest.php +++ b/apps/platform/tests/Feature/Onboarding/ManagedTenantOnboardingEntitlementTest.php @@ -7,7 +7,7 @@ use App\Models\OperationRun; use App\Models\PlatformUser; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -22,7 +22,7 @@ use Livewire\Livewire; /** - * @return array{workspace: Workspace, user: User, tenant: Tenant, draft: TenantOnboardingSession, component: \Livewire\Features\SupportTesting\Testable} + * @return array{workspace: Workspace, user: User, tenant: ManagedEnvironment, draft: TenantOnboardingSession, component: \Livewire\Features\SupportTesting\Testable} */ function readyOnboardingEntitlementContext( int $activeTenantCount = 0, @@ -37,9 +37,9 @@ function readyOnboardingEntitlementContext( $workspace = Workspace::factory()->create(); $user = User::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); createUserWithTenant( @@ -51,24 +51,24 @@ function readyOnboardingEntitlementContext( ); if ($activeTenantCount > 0) { - Tenant::factory()->count($activeTenantCount)->create([ + ManagedEnvironment::factory()->count($activeTenantCount)->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ACTIVE, + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); } $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Ready connection', 'is_default' => true, 'consent_status' => 'granted', ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', @@ -79,7 +79,7 @@ function readyOnboardingEntitlementContext( 'module' => 'health_check', 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ], ], ]); @@ -91,7 +91,7 @@ function readyOnboardingEntitlementContext( 'updated_by' => $user, 'current_step' => 'bootstrap', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -166,7 +166,7 @@ function readyOnboardingEntitlementContext( $context['tenant']->refresh(); - expect($context['tenant']->status)->toBe(Tenant::STATUS_ACTIVE) + expect($context['tenant']->status)->toBe(ManagedEnvironment::STATUS_ACTIVE) ->and(AuditLog::query() ->where('workspace_id', (int) $context['workspace']->getKey()) ->where('action', 'managed_tenant_onboarding.activation') @@ -194,7 +194,7 @@ function readyOnboardingEntitlementContext( $context['tenant']->refresh(); - expect($context['tenant']->status)->toBe(Tenant::STATUS_ONBOARDING) + expect($context['tenant']->status)->toBe(ManagedEnvironment::STATUS_ONBOARDING) ->and(AuditLog::query() ->where('workspace_id', (int) $context['workspace']->getKey()) ->where('action', 'managed_tenant_onboarding.activation') @@ -226,7 +226,7 @@ function readyOnboardingEntitlementContext( $context['tenant']->refresh(); - expect($context['tenant']->status)->toBe(Tenant::STATUS_ACTIVE); + expect($context['tenant']->status)->toBe(ManagedEnvironment::STATUS_ACTIVE); }); it('allows onboarding activation while a workspace is in trial', function (): void { @@ -242,7 +242,7 @@ function readyOnboardingEntitlementContext( $context['tenant']->refresh(); - expect($context['tenant']->status)->toBe(Tenant::STATUS_ACTIVE) + expect($context['tenant']->status)->toBe(ManagedEnvironment::STATUS_ACTIVE) ->and(AuditLog::query() ->where('workspace_id', (int) $context['workspace']->getKey()) ->where('action', 'managed_tenant_onboarding.activation') @@ -268,7 +268,7 @@ function readyOnboardingEntitlementContext( $context['tenant']->refresh(); - expect($context['tenant']->status)->toBe(Tenant::STATUS_ACTIVE); + expect($context['tenant']->status)->toBe(ManagedEnvironment::STATUS_ACTIVE); }); it('blocks onboarding activation with a grace commercial-state reason before tenant mutation', function (): void { @@ -286,7 +286,7 @@ function readyOnboardingEntitlementContext( $context['tenant']->refresh(); - expect($context['tenant']->status)->toBe(Tenant::STATUS_ONBOARDING) + expect($context['tenant']->status)->toBe(ManagedEnvironment::STATUS_ONBOARDING) ->and(AuditLog::query() ->where('workspace_id', (int) $context['workspace']->getKey()) ->where('action', 'managed_tenant_onboarding.activation') @@ -307,7 +307,7 @@ function readyOnboardingEntitlementContext( $context['tenant']->refresh(); - expect($context['tenant']->status)->toBe(Tenant::STATUS_ONBOARDING) + expect($context['tenant']->status)->toBe(ManagedEnvironment::STATUS_ONBOARDING) ->and(AuditLog::query() ->where('workspace_id', (int) $context['workspace']->getKey()) ->where('action', 'managed_tenant_onboarding.activation') diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingActivationTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingActivationTest.php index 744984cd..7d37d53c 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingActivationTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingActivationTest.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -42,10 +42,10 @@ 'name' => 'Acme', ]); - $tenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('slug', $entraTenantId)->firstOrFail(); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Acme connection', @@ -54,7 +54,7 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', @@ -90,7 +90,7 @@ ->assertStatus(403); $tenant->refresh(); - expect($tenant->status)->not->toBe(Tenant::STATUS_ACTIVE); + expect($tenant->status)->not->toBe(ManagedEnvironment::STATUS_ACTIVE); }); it('requires an override reason when verification is blocked and records an audit event when overridden', function (): void { @@ -126,10 +126,10 @@ $component->call('startVerification'); - $tenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('slug', $entraTenantId)->firstOrFail(); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->firstOrFail(); @@ -150,7 +150,7 @@ ->call('completeOnboarding'); $tenant->refresh(); - expect($tenant->status)->toBe(Tenant::STATUS_ACTIVE); + expect($tenant->status)->toBe(ManagedEnvironment::STATUS_ACTIVE); expect(AuditLog::query() ->where('workspace_id', (int) $workspace->getKey()) @@ -186,11 +186,11 @@ 'name' => 'Blocked By Report', ]); - $tenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('slug', $entraTenantId)->firstOrFail(); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Blocked by report connection', @@ -199,7 +199,7 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', @@ -246,7 +246,7 @@ $component->call('completeOnboarding'); $tenant->refresh(); - expect($tenant->status)->not->toBe(Tenant::STATUS_ACTIVE); + expect($tenant->status)->not->toBe(ManagedEnvironment::STATUS_ACTIVE); $component ->set('data.override_blocked', true) @@ -254,7 +254,7 @@ ->call('completeOnboarding'); $tenant->refresh(); - expect($tenant->status)->toBe(Tenant::STATUS_ACTIVE); + expect($tenant->status)->toBe(ManagedEnvironment::STATUS_ACTIVE); }); it('does not activate or write activation audit history when the workspace changes after mount', function (): void { @@ -264,9 +264,9 @@ $workspaceB = Workspace::factory()->create(); $user = User::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); createUserWithTenant( @@ -285,16 +285,16 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Ready connection', 'is_default' => true, 'consent_status' => 'granted', ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspaceA->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', @@ -305,7 +305,7 @@ 'module' => 'health_check', 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ], ], ]); @@ -317,7 +317,7 @@ 'updated_by' => $user, 'current_step' => 'bootstrap', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -336,7 +336,7 @@ $tenant->refresh(); - expect($tenant->status)->toBe(Tenant::STATUS_ONBOARDING) + expect($tenant->status)->toBe(ManagedEnvironment::STATUS_ONBOARDING) ->and(AuditLog::query() ->where('workspace_id', (int) $workspaceA->getKey()) ->whereIn('action', [ diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingDraftAccessTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingDraftAccessTest.php index 319c7dd0..8c6af1e9 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingDraftAccessTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingDraftAccessTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -87,9 +87,9 @@ it('returns 404 when the actor can access the workspace but lacks tenant entitlement for an identified draft', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $owner = User::factory()->create(); $workspaceOnlyUser = User::factory()->create(); @@ -122,9 +122,9 @@ it('returns 403 for an in-scope member with tenant entitlement but without onboarding capability', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $readonlyUser = User::factory()->create(); @@ -152,9 +152,9 @@ it('renders shared verification family markers for an entitled requested verify draft', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(); @@ -168,16 +168,16 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Requested verify connection', 'is_default' => true, ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'blocked', @@ -206,7 +206,7 @@ 'updated_by' => $user, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -227,16 +227,16 @@ it('mounts the requested draft with canonical persisted continuity state even when other drafts exist', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, - 'tenant_id' => '23232323-2323-2323-2323-232323232323', - 'name' => 'Canonical Continuity Tenant', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'managed_environment_id' => '23232323-2323-2323-2323-232323232323', + 'name' => 'Canonical Continuity ManagedEnvironment', ]); - $otherTenant = Tenant::factory()->create([ + $otherTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, - 'name' => 'Other Draft Tenant', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'name' => 'Other Draft ManagedEnvironment', ]); $user = User::factory()->create(); @@ -254,9 +254,9 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Canonical continuity connection', 'is_default' => true, ]); @@ -276,7 +276,7 @@ 'updated_by' => $user, 'current_step' => 'bootstrap', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'environment' => 'prod', 'notes' => 'Canonical persisted note', @@ -302,17 +302,17 @@ it('refreshes continuity state from the requested draft even when public draft state is forged before refresh', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, - 'tenant_id' => '24242424-2424-2424-2424-242424242424', - 'name' => 'Requested Draft Tenant', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'managed_environment_id' => '24242424-2424-2424-2424-242424242424', + 'name' => 'Requested Draft ManagedEnvironment', ]); - $otherTenant = Tenant::factory()->create([ + $otherTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, - 'tenant_id' => '25252525-2525-2525-2525-252525252525', - 'name' => 'Forged Draft Tenant', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'managed_environment_id' => '25252525-2525-2525-2525-252525252525', + 'name' => 'Forged Draft ManagedEnvironment', ]); $user = User::factory()->create(); @@ -330,18 +330,18 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Requested connection', 'is_default' => true, ]); $otherConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $otherTenant->getKey(), + 'managed_environment_id' => (int) $otherTenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $otherTenant->tenant_id, + 'entra_tenant_id' => (string) $otherTenant->managed_environment_id, 'display_name' => 'Forged connection', 'is_default' => true, ]); @@ -353,7 +353,7 @@ 'updated_by' => $user, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), ], @@ -366,7 +366,7 @@ 'updated_by' => $user, 'current_step' => 'connection', 'state' => [ - 'entra_tenant_id' => (string) $otherTenant->tenant_id, + 'entra_tenant_id' => (string) $otherTenant->managed_environment_id, 'tenant_name' => (string) $otherTenant->name, 'provider_connection_id' => (int) $otherConnection->getKey(), ], diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php index 24296260..83c55ac9 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php @@ -6,7 +6,7 @@ use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\OperationRunOutcome; @@ -17,10 +17,10 @@ it('allows another authorized operator to load a shared draft and see attribution', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, - 'name' => 'Shared Tenant', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'name' => 'Shared ManagedEnvironment', ]); $creator = User::factory()->create(['name' => 'Draft Creator']); $manager = User::factory()->create(['name' => 'Workspace Manager']); @@ -47,7 +47,7 @@ 'started_by' => $creator, 'updated_by' => $manager, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -64,9 +64,9 @@ it('allows a manager to cancel a shared onboarding draft', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $creator = User::factory()->create(); $manager = User::factory()->create(); @@ -109,13 +109,13 @@ it('cancels the route-bound draft even when public onboarding draft state is forged', function (): void { $workspace = Workspace::factory()->create(); - $primaryTenant = Tenant::factory()->create([ + $primaryTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); - $secondaryTenant = Tenant::factory()->create([ + $secondaryTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(); @@ -163,17 +163,17 @@ it('keeps rendering the route-bound draft after forged continuity state is refreshed', function (): void { $workspace = Workspace::factory()->create(); - $primaryTenant = Tenant::factory()->create([ + $primaryTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, - 'name' => 'Primary Continuity Tenant', - 'tenant_id' => '35353535-3535-3535-3535-353535353535', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'name' => 'Primary Continuity ManagedEnvironment', + 'managed_environment_id' => '35353535-3535-3535-3535-353535353535', ]); - $secondaryTenant = Tenant::factory()->create([ + $secondaryTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, - 'name' => 'Secondary Continuity Tenant', - 'tenant_id' => '36363636-3636-3636-3636-363636363636', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'name' => 'Secondary Continuity ManagedEnvironment', + 'managed_environment_id' => '36363636-3636-3636-3636-363636363636', ]); $user = User::factory()->create(['name' => 'Continuity Owner']); @@ -195,7 +195,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $primaryTenant->tenant_id, + 'entra_tenant_id' => (string) $primaryTenant->managed_environment_id, 'tenant_name' => (string) $primaryTenant->name, ], ]); @@ -206,7 +206,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $secondaryTenant->tenant_id, + 'entra_tenant_id' => (string) $secondaryTenant->managed_environment_id, 'tenant_name' => (string) $secondaryTenant->name, ], ]); @@ -222,15 +222,15 @@ ->call('refreshCheckpointLifecycle') ->assertSet('onboardingSessionId', (int) $primaryDraft->getKey()) ->assertSet('managedTenantId', (int) $primaryTenant->getKey()) - ->assertSee('Primary Continuity Tenant') - ->assertDontSee('Secondary Continuity Tenant'); + ->assertSee('Primary Continuity ManagedEnvironment') + ->assertDontSee('Secondary Continuity ManagedEnvironment'); }); it('resolves the cancel draft header action as enabled for managers with cancel capability', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(); @@ -261,9 +261,9 @@ it('keeps destructive draft actions confirmation protected and capability gated', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $manager = User::factory()->create(); @@ -308,9 +308,9 @@ it('returns 404 for non-members when requesting a shared onboarding draft', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $creator = User::factory()->create(); $nonMember = User::factory()->create(); @@ -339,9 +339,9 @@ it('returns 403 for readonly members even when they have tenant access', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $readonly = User::factory()->create(); @@ -369,10 +369,10 @@ it('keeps readiness routes hidden from non-members and wrong workspaces while capability denials stay forbidden', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, - 'name' => 'Readiness Authorization Tenant', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'name' => 'Readiness Authorization ManagedEnvironment', ]); $owner = User::factory()->create(); $nonMember = User::factory()->create(); @@ -408,7 +408,7 @@ 'started_by' => $owner, 'updated_by' => $owner, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -434,9 +434,9 @@ it('returns 403 for readonly members on cancelled draft summaries so delete controls never render', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_DRAFT, + 'status' => ManagedEnvironment::STATUS_DRAFT, ]); $readonly = User::factory()->create(); @@ -465,7 +465,7 @@ it('returns 404 for workspace members without linked archived tenant entitlement', function (): void { $workspace = Workspace::factory()->create(); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $creator = User::factory()->create(); @@ -491,7 +491,7 @@ 'started_by' => $creator, 'updated_by' => $creator, 'state' => [ - 'entra_tenant_id' => (string) $archivedTenant->tenant_id, + 'entra_tenant_id' => (string) $archivedTenant->managed_environment_id, 'tenant_name' => (string) $archivedTenant->name, ], ]); @@ -505,9 +505,9 @@ it('shows a non-editable summary for entitled operators when the linked tenant is already archived', function (): void { $workspace = Workspace::factory()->create(); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Archived Linked Tenant', + 'name' => 'Archived Linked ManagedEnvironment', ]); $user = User::factory()->create(); @@ -525,7 +525,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $archivedTenant->tenant_id, + 'entra_tenant_id' => (string) $archivedTenant->managed_environment_id, 'tenant_name' => (string) $archivedTenant->name, ], ]); @@ -545,7 +545,7 @@ $workspace = Workspace::factory()->create(); $user = User::factory()->create(); - $tenant = Tenant::factory()->onboarding()->create([ + $tenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -561,23 +561,23 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ @@ -603,7 +603,7 @@ 'updated_by' => $user, 'current_step' => 'bootstrap', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -623,7 +623,7 @@ $workspace = Workspace::factory()->create(); $user = User::factory()->create(); - $tenant = Tenant::factory()->onboarding()->create([ + $tenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -639,23 +639,23 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ @@ -681,7 +681,7 @@ 'updated_by' => $user, 'current_step' => 'bootstrap', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -698,5 +698,5 @@ $tenant->refresh(); - expect($tenant->status)->toBe(Tenant::STATUS_ACTIVE); + expect($tenant->status)->toBe(ManagedEnvironment::STATUS_ACTIVE); }); diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php index 7103d974..40b383b3 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -88,8 +88,8 @@ }); it('shows a linked tenant action when the onboarding draft has a viewable tenant record', function (): void { - $tenant = Tenant::factory()->onboarding()->create([ - 'name' => 'Linked Onboarding Tenant', + $tenant = ManagedEnvironment::factory()->onboarding()->create([ + 'name' => 'Linked Onboarding ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); @@ -99,7 +99,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -112,8 +112,8 @@ }); it('keeps the linked tenant action visible for entitled operators on archived tenant summaries', function (): void { - $tenant = Tenant::factory()->archived()->create([ - 'name' => 'Archived Summary Tenant', + $tenant = ManagedEnvironment::factory()->archived()->create([ + 'name' => 'Archived Summary ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); @@ -123,7 +123,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -330,10 +330,10 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->onboarding()->create([ + $tenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => 'aaaaaaaa-1111-1111-1111-111111111111', - 'name' => 'Activation Ready Tenant', + 'managed_environment_id' => 'aaaaaaaa-1111-1111-1111-111111111111', + 'name' => 'Activation Ready ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -342,23 +342,23 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ @@ -384,7 +384,7 @@ 'updated_by' => $user, 'current_step' => 'bootstrap', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -403,8 +403,8 @@ }); it('warns instead of completing onboarding when the workflow is not ready', function (): void { - $tenant = Tenant::factory()->onboarding()->create([ - 'name' => 'Verification Pending Tenant', + $tenant = ManagedEnvironment::factory()->onboarding()->create([ + 'name' => 'Verification Pending ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); @@ -415,7 +415,7 @@ 'updated_by' => $user, 'current_step' => 'connection', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -430,14 +430,14 @@ $tenant->refresh(); $draft->refresh(); - expect($tenant->status)->toBe(Tenant::STATUS_ONBOARDING) + expect($tenant->status)->toBe(ManagedEnvironment::STATUS_ONBOARDING) ->and($draft->completed_at)->toBeNull() ->and($draft->current_step)->toBe('connection'); }); it('returns a linked onboarding tenant to draft when its last onboarding draft is cancelled', function (): void { - $tenant = Tenant::factory()->onboarding()->create([ - 'name' => 'Cancelled Linked Tenant', + $tenant = ManagedEnvironment::factory()->onboarding()->create([ + 'name' => 'Cancelled Linked ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); @@ -447,7 +447,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'environment' => 'dev', ], @@ -463,11 +463,11 @@ $tenant->refresh(); - expect($tenant->status)->toBe(Tenant::STATUS_DRAFT); + expect($tenant->status)->toBe(ManagedEnvironment::STATUS_DRAFT); expect(AuditLog::query() ->where('workspace_id', (int) $tenant->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', AuditActionId::TenantReturnedToDraft->value) ->exists())->toBeTrue(); }); diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingDraftMultiTabTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingDraftMultiTabTest.php index 4522bbfd..7a126fe1 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingDraftMultiTabTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingDraftMultiTabTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\Workspaces\WorkspaceContext; @@ -12,9 +12,9 @@ it('rejects stale same-draft writes when the draft is open in two tabs', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(); @@ -28,18 +28,18 @@ $firstConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'First Connection', 'is_default' => true, ]); $secondConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'dummy', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Second Connection', 'is_default' => false, ]); @@ -51,7 +51,7 @@ 'updated_by' => $user, 'current_step' => 'connection', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $firstConnection->getKey(), ], diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingDraftPickerTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingDraftPickerTest.php index 86b8c564..f046794f 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingDraftPickerTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingDraftPickerTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantPermission; use App\Models\User; use App\Models\Workspace; @@ -14,7 +14,7 @@ use App\Support\Verification\VerificationReportWriter; use App\Support\Workspaces\WorkspaceContext; -function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): void +function seedPickerReadinessPermissions(ManagedEnvironment $tenant, ?int $staleDays = null): void { $configured = array_merge( config('intune_permissions.permissions', []), @@ -33,7 +33,7 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): } TenantPermission::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'permission_key' => trim($key), 'status' => 'granted', @@ -171,15 +171,15 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): 'role' => 'owner', ]); - $blockedTenant = Tenant::factory()->onboarding()->create([ + $blockedTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '41414141-4141-4141-4141-414141414141', - 'name' => 'Needs Connection Tenant', + 'managed_environment_id' => '41414141-4141-4141-4141-414141414141', + 'name' => 'Needs Connection ManagedEnvironment', ]); - $readyTenant = Tenant::factory()->onboarding()->create([ + $readyTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '42424242-4242-4242-4242-424242424242', - 'name' => 'Ready Picker Tenant', + 'managed_environment_id' => '42424242-4242-4242-4242-424242424242', + 'name' => 'Ready Picker ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -191,16 +191,16 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): $connection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $readyTenant->getKey(), + 'managed_environment_id' => (int) $readyTenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $readyTenant->tenant_id, + 'entra_tenant_id' => (string) $readyTenant->managed_environment_id, 'display_name' => 'Ready picker connection', 'is_default' => true, ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $readyTenant->getKey(), + 'managed_environment_id' => (int) $readyTenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -229,7 +229,7 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): 'updated_by' => $user, 'current_step' => 'connection', 'state' => [ - 'entra_tenant_id' => (string) $blockedTenant->tenant_id, + 'entra_tenant_id' => (string) $blockedTenant->managed_environment_id, 'tenant_name' => (string) $blockedTenant->name, ], ]); @@ -241,7 +241,7 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): 'updated_by' => $user, 'current_step' => 'complete', 'state' => [ - 'entra_tenant_id' => (string) $readyTenant->tenant_id, + 'entra_tenant_id' => (string) $readyTenant->managed_environment_id, 'tenant_name' => (string) $readyTenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), @@ -253,8 +253,8 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): $this->actingAs($user) ->get(route('admin.onboarding')) ->assertSuccessful() - ->assertSee('Needs Connection Tenant') - ->assertSee('Ready Picker Tenant') + ->assertSee('Needs Connection ManagedEnvironment') + ->assertSee('Ready Picker ManagedEnvironment') ->assertSee('Compact readiness') ->assertSee('Provider connection required') ->assertSee('Connect provider') @@ -274,15 +274,15 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): 'role' => 'owner', ]); - $staleTenant = Tenant::factory()->onboarding()->create([ + $staleTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '44444444-4444-4444-4444-444444444444', - 'name' => 'Picker Stale Tenant', + 'managed_environment_id' => '44444444-4444-4444-4444-444444444444', + 'name' => 'Picker Stale ManagedEnvironment', ]); - $mismatchTenant = Tenant::factory()->onboarding()->create([ + $mismatchTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '45454545-4545-4545-4545-454545454545', - 'name' => 'Picker Mismatch Tenant', + 'managed_environment_id' => '45454545-4545-4545-4545-454545454545', + 'name' => 'Picker Mismatch ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -295,31 +295,31 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): $staleConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $staleTenant->getKey(), + 'managed_environment_id' => (int) $staleTenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $staleTenant->tenant_id, + 'entra_tenant_id' => (string) $staleTenant->managed_environment_id, 'display_name' => 'Stale picker connection', 'is_default' => true, ]); $oldMismatchConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $mismatchTenant->getKey(), + 'managed_environment_id' => (int) $mismatchTenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => '46464646-4646-4646-4646-464646464646', 'display_name' => 'Old mismatch picker connection', ]); $selectedMismatchConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $mismatchTenant->getKey(), + 'managed_environment_id' => (int) $mismatchTenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $mismatchTenant->tenant_id, + 'entra_tenant_id' => (string) $mismatchTenant->managed_environment_id, 'display_name' => 'Selected mismatch picker connection', 'is_default' => true, ]); $staleRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $staleTenant->getKey(), + 'managed_environment_id' => (int) $staleTenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -342,7 +342,7 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): ]); $mismatchRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $mismatchTenant->getKey(), + 'managed_environment_id' => (int) $mismatchTenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -371,7 +371,7 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): 'updated_by' => $user, 'current_step' => 'complete', 'state' => [ - 'entra_tenant_id' => (string) $staleTenant->tenant_id, + 'entra_tenant_id' => (string) $staleTenant->managed_environment_id, 'tenant_name' => (string) $staleTenant->name, 'provider_connection_id' => (int) $staleConnection->getKey(), 'verification_operation_run_id' => (int) $staleRun->getKey(), @@ -385,7 +385,7 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): 'updated_by' => $user, 'current_step' => 'complete', 'state' => [ - 'entra_tenant_id' => (string) $mismatchTenant->tenant_id, + 'entra_tenant_id' => (string) $mismatchTenant->managed_environment_id, 'tenant_name' => (string) $mismatchTenant->name, 'provider_connection_id' => (int) $selectedMismatchConnection->getKey(), 'verification_operation_run_id' => (int) $mismatchRun->getKey(), @@ -397,8 +397,8 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): $this->actingAs($user) ->get(route('admin.onboarding')) ->assertSuccessful() - ->assertSee('Picker Stale Tenant') - ->assertSee('Picker Mismatch Tenant') + ->assertSee('Picker Stale ManagedEnvironment') + ->assertSee('Picker Mismatch ManagedEnvironment') ->assertSee('Permission data is older than the 30-day freshness window.') ->assertSee('Verification evidence belongs to a different provider connection.') ->assertSee('Rerun verification'); @@ -420,7 +420,7 @@ function seedPickerReadinessPermissions(Tenant $tenant, ?int $staleDays = null): 'updated_by' => $user, 'state' => [ 'entra_tenant_id' => '43434343-4343-4343-4343-434343434343', - 'tenant_name' => 'Single Redirect Tenant', + 'tenant_name' => 'Single Redirect ManagedEnvironment', ], ]); diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingDraftRoutingTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingDraftRoutingTest.php index cfbbce62..a44ae114 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingDraftRoutingTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingDraftRoutingTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -60,11 +60,11 @@ it('loads a concrete draft route with confirmed persisted state', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '22222222-2222-2222-2222-222222222222', + 'managed_environment_id' => '22222222-2222-2222-2222-222222222222', 'name' => 'Contoso GmbH', - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(); @@ -83,7 +83,7 @@ 'updated_by' => $user, 'current_step' => 'connection', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'environment' => 'prod', 'primary_domain' => 'contoso.example', @@ -119,7 +119,7 @@ 'updated_by' => $user, 'state' => [ 'entra_tenant_id' => '77777777-7777-7777-7777-777777777777', - 'tenant_name' => 'Single Draft Tenant', + 'tenant_name' => 'Single Draft ManagedEnvironment', 'environment' => 'prod', ], ]); @@ -148,7 +148,7 @@ 'updated_by' => $user, 'state' => [ 'entra_tenant_id' => '88888888-8888-8888-8888-888888888888', - 'tenant_name' => 'First Draft Tenant', + 'tenant_name' => 'First Draft ManagedEnvironment', 'environment' => 'prod', ], ]); @@ -159,7 +159,7 @@ 'updated_by' => $user, 'state' => [ 'entra_tenant_id' => '99999999-9999-9999-9999-999999999999', - 'tenant_name' => 'Second Draft Tenant', + 'tenant_name' => 'Second Draft ManagedEnvironment', 'environment' => 'staging', ], ]); @@ -187,7 +187,7 @@ ->call('identifyManagedTenant', [ 'entra_tenant_id' => '33333333-3333-3333-3333-333333333333', 'environment' => 'prod', - 'name' => 'Canonical Draft Tenant', + 'name' => 'Canonical Draft ManagedEnvironment', ]) ->assertRedirect(route('admin.onboarding.draft', [ 'onboardingDraft' => TenantOnboardingSession::query() diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingFoundationsTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingFoundationsTest.php index 833cb1d7..337fee61 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingFoundationsTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingFoundationsTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Auth\WorkspaceRoleCapabilityMap; use App\Support\Auth\Capabilities; @@ -28,21 +28,21 @@ }); it('supports the v1 managed tenant lifecycle statuses', function (): void { - $draft = Tenant::factory()->create(['status' => Tenant::STATUS_DRAFT]); - $onboarding = Tenant::factory()->create(['status' => Tenant::STATUS_ONBOARDING]); - $active = Tenant::factory()->create(['status' => Tenant::STATUS_ACTIVE]); + $draft = ManagedEnvironment::factory()->create(['status' => ManagedEnvironment::STATUS_DRAFT]); + $onboarding = ManagedEnvironment::factory()->create(['status' => ManagedEnvironment::STATUS_ONBOARDING]); + $active = ManagedEnvironment::factory()->create(['status' => ManagedEnvironment::STATUS_ACTIVE]); - expect(Tenant::activeQuery()->pluck('id')->all())->toContain((int) $active->getKey()); - expect(Tenant::activeQuery()->pluck('id')->all())->not->toContain((int) $draft->getKey()); - expect(Tenant::activeQuery()->pluck('id')->all())->not->toContain((int) $onboarding->getKey()); + expect(ManagedEnvironment::activeQuery()->pluck('id')->all())->toContain((int) $active->getKey()); + expect(ManagedEnvironment::activeQuery()->pluck('id')->all())->not->toContain((int) $draft->getKey()); + expect(ManagedEnvironment::activeQuery()->pluck('id')->all())->not->toContain((int) $onboarding->getKey()); $onboarding->delete(); $onboarding->refresh(); - expect($onboarding->status)->toBe(Tenant::STATUS_ARCHIVED); + expect($onboarding->status)->toBe(ManagedEnvironment::STATUS_ARCHIVED); $onboarding->restore(); $onboarding->refresh(); - expect($onboarding->status)->toBe(Tenant::STATUS_ACTIVE); + expect($onboarding->status)->toBe(ManagedEnvironment::STATUS_ACTIVE); }); diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingIdentifyTenantTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingIdentifyTenantTest.php index 777e1a50..9a0b4d88 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingIdentifyTenantTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingIdentifyTenantTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -45,9 +45,9 @@ 'notes' => 'Initial onboarding', ]); - expect(Tenant::query()->where('tenant_id', $entraTenantId)->count())->toBe(1); + expect(ManagedEnvironment::query()->where('slug', $entraTenantId)->count())->toBe(1); - $tenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('slug', $entraTenantId)->firstOrFail(); expect((int) $tenant->workspace_id)->toBe((int) $workspace->getKey()); @@ -78,10 +78,10 @@ 'role' => 'owner', ]); - Tenant::factory()->create([ + ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'tenant_id' => $entraTenantId, - 'status' => Tenant::STATUS_ACTIVE, + 'managed_environment_id' => $entraTenantId, + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspaceB->getKey()); diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingInlineConnectionEditTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingInlineConnectionEditTest.php index bf529b56..cf495f1f 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingInlineConnectionEditTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingInlineConnectionEditTest.php @@ -7,7 +7,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -28,10 +28,10 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '11111111-1111-1111-1111-111111111111', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '11111111-1111-1111-1111-111111111111', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -40,9 +40,9 @@ $connection = ProviderConnection::factory()->dedicated()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Acme connection', 'is_default' => true, ]); @@ -57,8 +57,8 @@ $session = TenantOnboardingSession::create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'connection', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -78,17 +78,17 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '22222222-2222-2222-2222-222222222222', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '22222222-2222-2222-2222-222222222222', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $connection = ProviderConnection::factory()->dedicated()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Acme connection', 'is_default' => true, ]); @@ -103,8 +103,8 @@ $session = TenantOnboardingSession::create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'connection', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -132,10 +132,10 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '33333333-3333-3333-3333-333333333333', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '33333333-3333-3333-3333-333333333333', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -144,9 +144,9 @@ $connection = ProviderConnection::factory()->dedicated()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Acme connection', 'is_default' => true, ]); @@ -162,15 +162,15 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'type' => 'provider.connection.check', ]); $session = TenantOnboardingSession::create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -209,7 +209,7 @@ expect($session->state['connection_recently_updated'] ?? null)->toBeTrue(); $audit = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.updated') ->latest('id') ->first(); @@ -232,10 +232,10 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '66666666-6666-6666-6666-666666666666', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '66666666-6666-6666-6666-666666666666', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -244,9 +244,9 @@ $connection = ProviderConnection::factory()->dedicated()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Acme connection', 'is_default' => true, ]); @@ -261,8 +261,8 @@ $session = TenantOnboardingSession::create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'connection', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -302,10 +302,10 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '77777777-7777-7777-7777-777777777777', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '77777777-7777-7777-7777-777777777777', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -314,9 +314,9 @@ $connection = ProviderConnection::factory()->dedicated()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Acme connection', 'is_default' => true, ]); @@ -334,8 +334,8 @@ $session = TenantOnboardingSession::create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'connection', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -362,7 +362,7 @@ expect($connection->credential?->payload['client_secret'] ?? null)->toBe($newSecret); $audit = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.updated') ->latest('id') ->first(); @@ -386,10 +386,10 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '88888888-1111-1111-1111-111111111111', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '88888888-1111-1111-1111-111111111111', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -398,17 +398,17 @@ $connection = ProviderConnection::factory()->platform()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Platform connection', 'is_default' => true, ]); $session = TenantOnboardingSession::create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'connection', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -448,10 +448,10 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '99999999-1111-1111-1111-111111111111', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '99999999-1111-1111-1111-111111111111', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -460,17 +460,17 @@ $connection = ProviderConnection::factory()->platform()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Platform connection', 'is_default' => true, ]); $session = TenantOnboardingSession::create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'connection', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -504,27 +504,27 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '44444444-4444-4444-4444-444444444444', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '44444444-4444-4444-4444-444444444444', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], ]); - $otherTenant = Tenant::factory()->create([ + $otherTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '55555555-5555-5555-5555-555555555555', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '55555555-5555-5555-5555-555555555555', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $connection = ProviderConnection::factory()->dedicated()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $otherTenant->getKey(), + 'managed_environment_id' => (int) $otherTenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $otherTenant->tenant_id, + 'entra_tenant_id' => (string) $otherTenant->managed_environment_id, 'display_name' => 'Other tenant connection', 'is_default' => true, ]); @@ -539,8 +539,8 @@ $session = TenantOnboardingSession::create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'connection', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionPlatformDefaultTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionPlatformDefaultTest.php index 130db7b0..bef8b2c6 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionPlatformDefaultTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionPlatformDefaultTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -52,11 +52,11 @@ 'is_default' => true, ]); - $tenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('slug', $entraTenantId)->firstOrFail(); $connection = ProviderConnection::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('entra_tenant_id', $entraTenantId) ->firstOrFail(); @@ -69,7 +69,7 @@ $session = TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereNull('completed_at') ->firstOrFail(); diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionTest.php index 16953cb0..c4fabbc3 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -36,11 +36,11 @@ 'name' => 'Acme', ]); - $tenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $tenant = ManagedEnvironment::query()->where('slug', $entraTenantId)->firstOrFail(); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Acme (onboarding)', @@ -79,27 +79,27 @@ $component->call('identifyManagedTenant', [ 'entra_tenant_id' => $entraTenantId, 'environment' => 'prod', - 'name' => 'Primary Tenant', + 'name' => 'Primary ManagedEnvironment', ]); - $primaryTenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $primaryTenant = ManagedEnvironment::query()->where('slug', $entraTenantId)->firstOrFail(); - $otherTenant = Tenant::factory()->create([ + $otherTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '55555555-5555-5555-5555-555555555555', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '55555555-5555-5555-5555-555555555555', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $otherConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $otherTenant->getKey(), + 'managed_environment_id' => (int) $otherTenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $otherTenant->tenant_id, + 'entra_tenant_id' => (string) $otherTenant->managed_environment_id, 'display_name' => 'Other tenant connection', 'is_default' => true, ]); - expect((int) $otherConnection->tenant_id)->not->toBe((int) $primaryTenant->getKey()); + expect((int) $otherConnection->managed_environment_id)->not->toBe((int) $primaryTenant->getKey()); $component ->call('selectProviderConnection', (int) $otherConnection->getKey()) @@ -127,7 +127,7 @@ $component->call('identifyManagedTenant', [ 'entra_tenant_id' => $entraTenantId, 'environment' => 'prod', - 'name' => 'Primary Tenant', + 'name' => 'Primary ManagedEnvironment', ]); $primarySession = TenantOnboardingSession::query() @@ -135,16 +135,16 @@ ->where('entra_tenant_id', $entraTenantId) ->firstOrFail(); - $otherTenant = Tenant::factory()->create([ + $otherTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '65656565-6565-6565-6565-656565656565', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '65656565-6565-6565-6565-656565656565', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $otherDraft = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $otherTenant->getKey(), - 'entra_tenant_id' => (string) $otherTenant->tenant_id, + 'managed_environment_id' => (int) $otherTenant->getKey(), + 'entra_tenant_id' => (string) $otherTenant->managed_environment_id, 'current_step' => 'connection', 'state' => [], 'started_by_user_id' => (int) $user->getKey(), @@ -153,9 +153,9 @@ $otherConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $otherTenant->getKey(), + 'managed_environment_id' => (int) $otherTenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $otherTenant->tenant_id, + 'entra_tenant_id' => (string) $otherTenant->managed_environment_id, 'display_name' => 'Forged tenant connection', 'is_default' => true, ]); diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingRbacSemanticsTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingRbacSemanticsTest.php index 17684a45..4ce9a247 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingRbacSemanticsTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingRbacSemanticsTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -48,9 +48,9 @@ $workspaceB = Workspace::factory()->create(); $user = User::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); createUserWithTenant( @@ -69,18 +69,18 @@ $firstConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'First connection', 'is_default' => true, ]); $secondConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'dummy', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Second connection', 'is_default' => false, ]); @@ -92,7 +92,7 @@ 'updated_by' => $user, 'current_step' => 'connection', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $firstConnection->getKey(), ], diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingVerificationAssistTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingVerificationAssistTest.php index f2e606ea..fcaae14f 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingVerificationAssistTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingVerificationAssistTest.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantPermission; use App\Models\User; use App\Models\WorkspaceMembership; @@ -36,7 +36,7 @@ function assistConfiguredPermissionKeys(): array } function seedAssistPermissionInventory( - Tenant $tenant, + ManagedEnvironment $tenant, ?string $missingKey = null, ?int $staleDays = null, array $errorKeys = [], @@ -47,7 +47,7 @@ function seedAssistPermissionInventory( } TenantPermission::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'permission_key' => $key, 'status' => in_array($key, $errorKeys, true) ? 'error' : 'granted', @@ -58,7 +58,7 @@ function seedAssistPermissionInventory( } /** - * @return array{0:User,1:Tenant,2:\App\Models\TenantOnboardingSession,3:ProviderConnection,4:OperationRun,5:?string} + * @return array{0:User,1:ManagedEnvironment,2:\App\Models\TenantOnboardingSession,3:ProviderConnection,4:OperationRun,5:?string} */ function createVerificationAssistDraft( string $state = 'blocked', @@ -76,9 +76,9 @@ function createVerificationAssistDraft( $verifiedConnection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Verified connection', 'is_default' => true, 'consent_status' => 'granted', @@ -89,9 +89,9 @@ function createVerificationAssistDraft( if ($staleVerificationRun) { $selectedConnection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'dummy', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Current selected connection', 'is_default' => false, 'consent_status' => 'granted', @@ -168,14 +168,14 @@ function createVerificationAssistDraft( $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => $outcome, 'context' => [ 'provider_connection_id' => (int) $verifiedConnection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [$check]), @@ -189,7 +189,7 @@ function createVerificationAssistDraft( 'updated_by' => $user, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $selectedConnection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingVerificationClustersTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingVerificationClustersTest.php index 30645166..96c78777 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingVerificationClustersTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingVerificationClustersTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\ProviderConnectionResource; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -31,9 +31,9 @@ $entraTenantId = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $entraTenantId, + 'managed_environment_id' => $entraTenantId, 'external_id' => 'tenant-clusters-a', 'status' => 'onboarding', ]); @@ -89,7 +89,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'succeeded', @@ -104,7 +104,7 @@ TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $entraTenantId, 'current_step' => 'verify', 'state' => [ @@ -142,9 +142,9 @@ $entraTenantId = 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $entraTenantId, + 'managed_environment_id' => $entraTenantId, 'external_id' => 'tenant-clusters-b', 'status' => 'onboarding', ]); @@ -157,7 +157,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'succeeded', @@ -172,7 +172,7 @@ $session = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $entraTenantId, 'current_step' => 'verify', 'state' => [ @@ -207,9 +207,9 @@ $entraTenantId = 'dddddddd-dddd-dddd-dddd-dddddddddddd'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $entraTenantId, + 'managed_environment_id' => $entraTenantId, 'external_id' => 'tenant-clusters-d', 'status' => 'onboarding', ]); @@ -222,7 +222,7 @@ $previousRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'succeeded', @@ -239,7 +239,7 @@ $currentRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'failed', @@ -253,7 +253,7 @@ $session = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $entraTenantId, 'current_step' => 'verify', 'state' => [ @@ -291,9 +291,9 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => 'cccccccc-cccc-cccc-cccc-cccccccccccc', + 'managed_environment_id' => 'cccccccc-cccc-cccc-cccc-cccccccccccc', 'external_id' => 'tenant-clusters-c', 'status' => 'onboarding', ]); @@ -304,9 +304,9 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ]); $verificationReport = VerificationReportWriter::build('provider.connection.check', [ @@ -338,13 +338,13 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'blocked', 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => $verificationReport, @@ -353,8 +353,8 @@ TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'verification_operation_run_id' => (int) $run->getKey(), diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingVerificationTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingVerificationTest.php index aed2bace..92b0f6fc 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingVerificationTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingVerificationTest.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -54,10 +54,10 @@ 'is_default' => true, ]); - $tenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $tenant = ManagedEnvironment::query()->forTenant($entraTenantId)->firstOrFail(); ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->update([ 'consent_status' => 'granted', 'last_error_reason_code' => null, @@ -68,12 +68,12 @@ $component->call('startVerification'); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->count())->toBe(1); $runId = (int) OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->value('id'); @@ -130,14 +130,14 @@ $component->call('identifyManagedTenant', [ 'entra_tenant_id' => $entraTenantId, 'environment' => 'prod', - 'name' => 'Blocked Tenant', + 'name' => 'Blocked ManagedEnvironment', ]); - $tenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $tenant = ManagedEnvironment::query()->forTenant($entraTenantId)->firstOrFail(); $connection = ProviderConnection::factory()->dedicated()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Blocked connection', @@ -149,7 +149,7 @@ $component->call('startVerification'); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); @@ -186,9 +186,9 @@ $workspaceB = Workspace::factory()->create(); $user = User::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); createUserWithTenant( @@ -207,9 +207,9 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Verified connection', 'is_default' => true, ]); @@ -221,7 +221,7 @@ 'updated_by' => $user, 'current_step' => 'connection', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), ], @@ -238,7 +238,7 @@ $component->call('startVerification')->assertNotFound(); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->exists())->toBeFalse() ->and(AuditLog::query() @@ -264,9 +264,9 @@ $entraTenantId = '99999999-9999-9999-9999-999999999999'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $entraTenantId, + 'managed_environment_id' => $entraTenantId, 'status' => 'onboarding', ]); @@ -276,7 +276,7 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Contoso platform connection', @@ -285,7 +285,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'succeeded', @@ -313,7 +313,7 @@ TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $entraTenantId, 'current_step' => 'verify', 'state' => [ @@ -359,10 +359,10 @@ $entraTenantId = '20202020-2020-2020-2020-202020202020'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $entraTenantId, - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => $entraTenantId, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -371,7 +371,7 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Blocked queued verification connection', @@ -380,7 +380,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', @@ -390,7 +390,7 @@ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider_connection_id' => (int) $connection->getKey(), 'entra_tenant_id' => $entraTenantId, ], @@ -408,7 +408,7 @@ providerConnectionId: (int) $connection->getKey(), targetScope: [ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider_connection_id' => (int) $connection->getKey(), 'entra_tenant_id' => $entraTenantId, ], @@ -430,7 +430,7 @@ TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $entraTenantId, 'current_step' => 'verify', 'state' => [ @@ -462,9 +462,9 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -473,15 +473,15 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'is_default' => true, 'consent_status' => 'granted', ]); $session = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -501,7 +501,7 @@ $activeRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'running', 'outcome' => 'pending', @@ -527,7 +527,7 @@ $completedRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'succeeded', @@ -583,11 +583,11 @@ 'is_default' => true, ]); - $tenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $tenant = ManagedEnvironment::query()->forTenant($entraTenantId)->firstOrFail(); $otherConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'dummy', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Dummy connection', @@ -632,30 +632,30 @@ $component->call('identifyManagedTenant', [ 'entra_tenant_id' => $entraTenantId, 'environment' => 'prod', - 'name' => 'Primary Tenant', + 'name' => 'Primary ManagedEnvironment', ]); - $primaryTenant = Tenant::query()->where('tenant_id', $entraTenantId)->firstOrFail(); + $primaryTenant = ManagedEnvironment::query()->forTenant($entraTenantId)->firstOrFail(); - $otherTenant = Tenant::factory()->create([ + $otherTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => '18181818-1818-1818-1818-181818181818', - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => '18181818-1818-1818-1818-181818181818', + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $otherConnection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $otherTenant->getKey(), + 'managed_environment_id' => (int) $otherTenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $otherTenant->tenant_id, + 'entra_tenant_id' => (string) $otherTenant->managed_environment_id, 'display_name' => 'Forged verification connection', 'is_default' => true, ]); $otherDraft = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $otherTenant->getKey(), - 'entra_tenant_id' => (string) $otherTenant->tenant_id, + 'managed_environment_id' => (int) $otherTenant->getKey(), + 'entra_tenant_id' => (string) $otherTenant->managed_environment_id, 'current_step' => 'connection', 'state' => [ 'provider_connection_id' => (int) $otherConnection->getKey(), @@ -671,11 +671,11 @@ ->call('startVerification'); expect(OperationRun::query() - ->where('tenant_id', (int) $otherTenant->getKey()) + ->where('managed_environment_id', (int) $otherTenant->getKey()) ->where('type', 'provider.connection.check') ->exists())->toBeFalse() ->and(OperationRun::query() - ->where('tenant_id', (int) $primaryTenant->getKey()) + ->where('managed_environment_id', (int) $primaryTenant->getKey()) ->where('type', 'provider.connection.check') ->exists())->toBeFalse(); }); @@ -694,10 +694,10 @@ $entraTenantId = '13131313-1313-1313-1313-131313131313'; - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => $entraTenantId, - 'status' => Tenant::STATUS_ONBOARDING, + 'managed_environment_id' => $entraTenantId, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -706,7 +706,7 @@ $microsoftConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Microsoft connection', @@ -715,7 +715,7 @@ $otherConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'dummy', 'entra_tenant_id' => $entraTenantId, 'display_name' => 'Dummy connection', @@ -724,7 +724,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'succeeded', @@ -738,7 +738,7 @@ $session = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'entra_tenant_id' => $entraTenantId, 'current_step' => 'verify', 'state' => [ diff --git a/apps/platform/tests/Feature/Onboarding/OnboardingVerificationV1_5UxTest.php b/apps/platform/tests/Feature/Onboarding/OnboardingVerificationV1_5UxTest.php index 72064c96..0eca9d0e 100644 --- a/apps/platform/tests/Feature/Onboarding/OnboardingVerificationV1_5UxTest.php +++ b/apps/platform/tests/Feature/Onboarding/OnboardingVerificationV1_5UxTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\VerificationCheckAcknowledgement; @@ -26,9 +26,9 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -37,14 +37,14 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'is_default' => true, ]); TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -63,7 +63,7 @@ $runningRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'running', 'outcome' => 'pending', @@ -74,7 +74,7 @@ TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->update([ 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -92,7 +92,7 @@ $completedRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'succeeded', @@ -104,7 +104,7 @@ TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->update([ 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -132,9 +132,9 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -143,7 +143,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'is_default' => true, ]); @@ -213,7 +213,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'failed', @@ -225,7 +225,7 @@ VerificationCheckAcknowledgement::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'operation_run_id' => (int) $run->getKey(), 'check_key' => 'acknowledged_fail', 'ack_reason' => 'Known issue accepted.', @@ -235,8 +235,8 @@ TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), diff --git a/apps/platform/tests/Feature/Onboarding/ProductKnowledgeOnboardingHelpTest.php b/apps/platform/tests/Feature/Onboarding/ProductKnowledgeOnboardingHelpTest.php index aa06b1a0..de4b3ad1 100644 --- a/apps/platform/tests/Feature/Onboarding/ProductKnowledgeOnboardingHelpTest.php +++ b/apps/platform/tests/Feature/Onboarding/ProductKnowledgeOnboardingHelpTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\WorkspaceMembership; @@ -19,11 +19,11 @@ uses(RefreshDatabase::class); /** - * @return array{0: User, 1: Tenant, 2: TenantOnboardingSession} + * @return array{0: User, 1: ManagedEnvironment, 2: TenantOnboardingSession} */ function createProductKnowledgeOnboardingDraft(string $state, string $workspaceRole = 'owner', string $tenantRole = 'owner'): array { - $tenant = Tenant::factory()->onboarding()->create(); + $tenant = ManagedEnvironment::factory()->onboarding()->create(); [$user, $tenant] = createUserWithTenant( tenant: $tenant, @@ -36,9 +36,9 @@ function createProductKnowledgeOnboardingDraft(string $state, string $workspaceR $verificationConnection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Verification connection', 'is_default' => true, 'consent_status' => 'granted', @@ -87,9 +87,9 @@ function createProductKnowledgeOnboardingDraft(string $state, string $workspaceR } elseif ($state === 'verification_stale') { $selectedConnection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'dummy', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'display_name' => 'Currently selected connection', 'is_default' => false, 'consent_status' => 'granted', @@ -126,14 +126,14 @@ function createProductKnowledgeOnboardingDraft(string $state, string $workspaceR $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => $outcome, 'context' => [ 'provider_connection_id' => (int) $verificationConnection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', $checks), @@ -146,9 +146,9 @@ function createProductKnowledgeOnboardingDraft(string $state, string $workspaceR 'started_by' => $user, 'updated_by' => $user, 'current_step' => 'verify', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $selectedConnection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), diff --git a/apps/platform/tests/Feature/Onboarding/ProductTelemetryOnboardingCaptureTest.php b/apps/platform/tests/Feature/Onboarding/ProductTelemetryOnboardingCaptureTest.php index 24968855..f35a4278 100644 --- a/apps/platform/tests/Feature/Onboarding/ProductTelemetryOnboardingCaptureTest.php +++ b/apps/platform/tests/Feature/Onboarding/ProductTelemetryOnboardingCaptureTest.php @@ -5,7 +5,7 @@ use App\Models\OperationRun; use App\Models\ProductUsageEvent; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Onboarding\OnboardingDraftMutationService; use App\Support\Onboarding\OnboardingCheckpoint; use App\Support\Onboarding\OnboardingLifecycleState; @@ -17,16 +17,16 @@ uses(RefreshDatabase::class); it('records onboarding checkpoint telemetry after a tenant-linked checkpoint transition persists', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $verificationRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, @@ -44,7 +44,7 @@ 'updated_by' => $user, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $verificationRun->getKey(), @@ -62,7 +62,7 @@ expect($event->event_name)->toBe(ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED) ->and($event->workspace_id)->toBe((int) $tenant->workspace_id) - ->and($event->tenant_id)->toBe((int) $tenant->getKey()) + ->and($event->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($event->user_id)->toBe((int) $user->getKey()) ->and($event->subject_type)->toBe('tenant_onboarding_session') ->and($event->subject_id)->toBe((string) $draft->getKey()) @@ -85,7 +85,7 @@ 'current_step' => 'identify', 'state' => [ 'entra_tenant_id' => fake()->uuid(), - 'tenant_name' => 'Pre Tenant Draft', + 'tenant_name' => 'Pre ManagedEnvironment Draft', ], ]); diff --git a/apps/platform/tests/Feature/Onboarding/TenantLifecyclePresentationCopyTest.php b/apps/platform/tests/Feature/Onboarding/TenantLifecyclePresentationCopyTest.php index f6c321cd..d46a510b 100644 --- a/apps/platform/tests/Feature/Onboarding/TenantLifecyclePresentationCopyTest.php +++ b/apps/platform/tests/Feature/Onboarding/TenantLifecyclePresentationCopyTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -23,9 +23,9 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->active()->create([ + $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => $workspace->getKey(), - 'name' => 'Active Card Tenant', + 'name' => 'Active Card ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -36,16 +36,16 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]) ->get('/admin/choose-tenant') ->assertSuccessful() - ->assertSee('Active Card Tenant') + ->assertSee('Active Card ManagedEnvironment') ->assertSee('Active') ->assertSee('Active tenant available for normal operations.'); }); it('labels the onboarding linked tenant action with the canonical lifecycle name', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->onboarding()->create([ + $tenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Onboarding Linked Tenant', + 'name' => 'Onboarding Linked ManagedEnvironment', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); @@ -57,7 +57,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); diff --git a/apps/platform/tests/Feature/OperationRunServiceTest.php b/apps/platform/tests/Feature/OperationRunServiceTest.php index 5489f4d0..02335f20 100644 --- a/apps/platform/tests/Feature/OperationRunServiceTest.php +++ b/apps/platform/tests/Feature/OperationRunServiceTest.php @@ -1,7 +1,7 @@ create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $service = operationRunService(); @@ -22,7 +22,7 @@ function operationRunService(): OperationRunService $this->assertDatabaseHas('operation_runs', [ 'id' => $run->getKey(), - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'test.action', 'status' => 'queued', 'initiator_name' => $user->name, @@ -30,7 +30,7 @@ function operationRunService(): OperationRunService }); it('reuses an active run (idempotent)', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $service = operationRunService(); @@ -42,7 +42,7 @@ function operationRunService(): OperationRunService }); it('dedupes assignment run identities by type and scope', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $service = operationRunService(); @@ -113,7 +113,7 @@ function operationRunService(): OperationRunService }); it('does not replace the initiator when deduping', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $userA = User::factory()->create(); $userB = User::factory()->create(); @@ -128,7 +128,7 @@ function operationRunService(): OperationRunService }); it('hashes inputs deterministically regardless of key order', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $service = operationRunService(); $runA = $service->ensureRun($tenant, 'test.action', ['b' => 2, 'a' => 1]); @@ -138,7 +138,7 @@ function operationRunService(): OperationRunService }); it('hashes list inputs deterministically regardless of list order', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $service = operationRunService(); $runA = $service->ensureRun($tenant, 'test.action', ['ids' => [2, 1]]); @@ -148,7 +148,7 @@ function operationRunService(): OperationRunService }); it('handles unique-index race collisions by returning the active run', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $service = operationRunService(); $fired = false; @@ -165,7 +165,7 @@ function operationRunService(): OperationRunService OperationRun::withoutEvents(function () use ($model, $tenant): void { OperationRun::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => $model->tenant_id, + 'managed_environment_id' => $model->managed_environment_id, 'user_id' => $model->user_id, 'initiator_name' => $model->initiator_name, 'type' => $model->type, @@ -185,12 +185,12 @@ function operationRunService(): OperationRunService } expect($run)->toBeInstanceOf(OperationRun::class); - expect(OperationRun::query()->where('tenant_id', $tenant->getKey())->where('type', 'test.race')->count()) + expect(OperationRun::query()->where('managed_environment_id', $tenant->getKey())->where('type', 'test.race')->count()) ->toBe(1); }); it('creates a new run after the previous one completed', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $service = operationRunService(); @@ -204,7 +204,7 @@ function operationRunService(): OperationRunService }); it('reuses the same run even after completion when using strict identity', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $service = operationRunService(); @@ -229,7 +229,7 @@ function operationRunService(): OperationRunService }); it('handles strict unique-index race collisions by returning the existing run', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $service = operationRunService(); $fired = false; @@ -246,7 +246,7 @@ function operationRunService(): OperationRunService OperationRun::withoutEvents(function () use ($model, $tenant): void { OperationRun::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => $model->tenant_id, + 'managed_environment_id' => $model->managed_environment_id, 'user_id' => $model->user_id, 'initiator_name' => $model->initiator_name, 'type' => $model->type, @@ -271,12 +271,12 @@ function operationRunService(): OperationRunService } expect($run)->toBeInstanceOf(OperationRun::class); - expect(OperationRun::query()->where('tenant_id', $tenant->getKey())->where('type', 'backup_schedule_run')->count()) + expect(OperationRun::query()->where('managed_environment_id', $tenant->getKey())->where('type', 'backup_schedule_run')->count()) ->toBe(1); }); it('updates run lifecycle fields and summaries', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $service = operationRunService(); @@ -297,7 +297,7 @@ function operationRunService(): OperationRunService }); it('sanitizes failure messages and redacts obvious secrets', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $service = operationRunService(); $run = $service->ensureRun($tenant, 'test.action', []); diff --git a/apps/platform/tests/Feature/OperationalControls/OperationalControlAuthorizationSemanticsTest.php b/apps/platform/tests/Feature/OperationalControls/OperationalControlAuthorizationSemanticsTest.php index 20461d5b..5c51b76c 100644 --- a/apps/platform/tests/Feature/OperationalControls/OperationalControlAuthorizationSemanticsTest.php +++ b/apps/platform/tests/Feature/OperationalControls/OperationalControlAuthorizationSemanticsTest.php @@ -10,7 +10,7 @@ use App\Models\OperationalControlActivation; use App\Models\PlatformUser; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Auth\PlatformCapabilities; use Filament\Facades\Filament; @@ -26,9 +26,9 @@ function seedRestoreAuthorizationContext(): array { - $tenant = Tenant::factory()->create([ - 'tenant_id' => fake()->uuid(), - 'name' => 'Authorization Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => fake()->uuid(), + 'name' => 'Authorization ManagedEnvironment', 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), ]); @@ -37,7 +37,7 @@ function seedRestoreAuthorizationContext(): array ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => fake()->uuid(), 'policy_type' => 'deviceConfiguration', 'display_name' => 'Authorization Restore Policy', @@ -45,14 +45,14 @@ function seedRestoreAuthorizationContext(): array ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Authorization Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -129,7 +129,7 @@ function seedRestoreAuthorizationContext(): array ->fillForm([ 'is_dry_run' => false, 'acknowledged_impact' => true, - 'tenant_confirm' => 'Authorization Tenant', + 'tenant_confirm' => 'Authorization ManagedEnvironment', ]) ->call('create') ->assertNotified('Restore execution paused'); diff --git a/apps/platform/tests/Feature/Operations/AssignmentFetchOperationRunFailureTest.php b/apps/platform/tests/Feature/Operations/AssignmentFetchOperationRunFailureTest.php index 51677e04..55316a0f 100644 --- a/apps/platform/tests/Feature/Operations/AssignmentFetchOperationRunFailureTest.php +++ b/apps/platform/tests/Feature/Operations/AssignmentFetchOperationRunFailureTest.php @@ -2,7 +2,7 @@ use App\Models\OperationRun; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Graph\ScopeTagResolver; @@ -60,14 +60,14 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon } }); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-assignment-fetch-failure', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-assignment-fetch-failure', 'status' => 'active', ]); ensureDefaultProviderConnection($tenant); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-assignment-fetch-failure', 'policy_type' => 'settingsCatalogPolicy', 'platform' => 'windows', @@ -111,7 +111,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon expect($backupItem?->metadata['assignments_fetch_failed'] ?? false)->toBeTrue(); $assignmentFetchRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'assignments.fetch') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Operations/AssignmentFetchOperationRunTest.php b/apps/platform/tests/Feature/Operations/AssignmentFetchOperationRunTest.php index b9082c93..f7c1d6cf 100644 --- a/apps/platform/tests/Feature/Operations/AssignmentFetchOperationRunTest.php +++ b/apps/platform/tests/Feature/Operations/AssignmentFetchOperationRunTest.php @@ -2,7 +2,7 @@ use App\Models\OperationRun; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\AssignmentFetcher; use App\Services\Graph\AssignmentFilterResolver; use App\Services\Graph\GroupResolver; @@ -15,14 +15,14 @@ uses(RefreshDatabase::class); test('backup capture with assignments writes an assignment fetch operation run keyed by backup item', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-assignment-fetch-run', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-assignment-fetch-run', 'status' => 'active', ]); ensureDefaultProviderConnection($tenant); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-assignment-fetch-run', 'policy_type' => 'settingsCatalogPolicy', 'platform' => 'windows', @@ -97,7 +97,7 @@ expect($backupItem)->not->toBeNull(); $assignmentFetchRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'assignments.fetch') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Operations/AssignmentJobDedupeTest.php b/apps/platform/tests/Feature/Operations/AssignmentJobDedupeTest.php index 3601d29a..f9b3aa60 100644 --- a/apps/platform/tests/Feature/Operations/AssignmentJobDedupeTest.php +++ b/apps/platform/tests/Feature/Operations/AssignmentJobDedupeTest.php @@ -5,7 +5,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\AssignmentBackupService; use App\Services\AssignmentRestoreService; use App\Services\OperationRunService; @@ -15,13 +15,13 @@ uses(RefreshDatabase::class); test('fetch assignment job dedupes dispatch and execution, and reuses recent completion during cooldown', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $backupItem = BackupItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'policy_type' => 'settingsCatalogPolicy', 'policy_identifier' => 'policy-fetch-dedupe', @@ -89,12 +89,15 @@ }); test('restore assignment job dedupes dispatch and execution, and reuses recent completion during cooldown', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create([ + 'rbac_status' => 'ok', + 'rbac_last_checked_at' => now(), + ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), ]); diff --git a/apps/platform/tests/Feature/Operations/AssignmentRestoreOperationRunFailureTest.php b/apps/platform/tests/Feature/Operations/AssignmentRestoreOperationRunFailureTest.php index eb41e664..7158b959 100644 --- a/apps/platform/tests/Feature/Operations/AssignmentRestoreOperationRunFailureTest.php +++ b/apps/platform/tests/Feature/Operations/AssignmentRestoreOperationRunFailureTest.php @@ -4,7 +4,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -60,23 +60,23 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon } }); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-assignment-restore-failure', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-assignment-restore-failure', ]); ensureDefaultProviderConnection($tenant); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-assignment-restore-failure', 'policy_type' => 'settingsCatalogPolicy', ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $backupItem = BackupItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_identifier' => (string) $policy->external_id, @@ -113,7 +113,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ); $assignmentRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'assignments.restore') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Operations/AssignmentRestoreOperationRunTest.php b/apps/platform/tests/Feature/Operations/AssignmentRestoreOperationRunTest.php index c7e53277..cdcc2e99 100644 --- a/apps/platform/tests/Feature/Operations/AssignmentRestoreOperationRunTest.php +++ b/apps/platform/tests/Feature/Operations/AssignmentRestoreOperationRunTest.php @@ -4,7 +4,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -47,23 +47,23 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon } }); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-assignment-restore-success', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-assignment-restore-success', ]); ensureDefaultProviderConnection($tenant); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-assignment-restore-success', 'policy_type' => 'settingsCatalogPolicy', ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $backupItem = BackupItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_identifier' => (string) $policy->external_id, @@ -100,7 +100,7 @@ public function getServicePrincipalPermissions(array $options = []): GraphRespon ); $assignmentRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'assignments.restore') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Operations/AssignmentRunSummaryCountsTest.php b/apps/platform/tests/Feature/Operations/AssignmentRunSummaryCountsTest.php index 8efd9486..7f2eb606 100644 --- a/apps/platform/tests/Feature/Operations/AssignmentRunSummaryCountsTest.php +++ b/apps/platform/tests/Feature/Operations/AssignmentRunSummaryCountsTest.php @@ -6,7 +6,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\AssignmentBackupService; use App\Services\AssignmentRestoreService; use App\Services\OperationRunService; @@ -15,13 +15,13 @@ uses(RefreshDatabase::class); test('fetch assignment job persists terminal summary counts and overwrites previous values', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $backupItem = BackupItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'policy_type' => 'settingsCatalogPolicy', 'policy_identifier' => 'policy-fetch-summary', @@ -79,13 +79,16 @@ }); test('restore assignment job persists terminal summary counts and overwrites previous values', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create([ + 'rbac_status' => 'ok', + 'rbac_last_checked_at' => now(), + ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), ]); diff --git a/apps/platform/tests/Feature/Operations/BaselineOperationRunGuardTest.php b/apps/platform/tests/Feature/Operations/BaselineOperationRunGuardTest.php index b1ddddc6..f166f827 100644 --- a/apps/platform/tests/Feature/Operations/BaselineOperationRunGuardTest.php +++ b/apps/platform/tests/Feature/Operations/BaselineOperationRunGuardTest.php @@ -31,7 +31,7 @@ createInventorySyncOperationRunWithCoverage($tenant, ['deviceConfiguration' => 'succeeded']); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => OperationRunType::BaselineCompare->value, diff --git a/apps/platform/tests/Feature/Operations/BulkOperationExecutionReauthorizationTest.php b/apps/platform/tests/Feature/Operations/BulkOperationExecutionReauthorizationTest.php index 782906f3..81625b58 100644 --- a/apps/platform/tests/Feature/Operations/BulkOperationExecutionReauthorizationTest.php +++ b/apps/platform/tests/Feature/Operations/BulkOperationExecutionReauthorizationTest.php @@ -24,7 +24,7 @@ function runQueuedBulkJobThroughMiddleware(object $job, Closure $terminal): mixe [$user, $tenant] = createUserWithTenant(role: 'owner'); $policies = Policy::factory()->count(2)->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $selection = app(BulkSelectionIdentity::class)->fromIds($policies->pluck('id')->all()); @@ -33,7 +33,7 @@ function runQueuedBulkJobThroughMiddleware(object $job, Closure $terminal): mixe tenant: $tenant, type: 'policy.delete', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selection, dispatcher: static fn (): null => null, @@ -59,7 +59,7 @@ function runQueuedBulkJobThroughMiddleware(object $job, Closure $terminal): mixe [$user, $tenant] = createUserWithTenant(role: 'owner'); $policies = Policy::factory()->count(2)->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $selection = app(BulkSelectionIdentity::class)->fromIds($policies->pluck('id')->all()); @@ -68,7 +68,7 @@ function runQueuedBulkJobThroughMiddleware(object $job, Closure $terminal): mixe tenant: $tenant, type: 'policy.delete', targetScope: [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], selectionIdentity: $selection, dispatcher: static fn (): null => null, @@ -85,7 +85,7 @@ function runQueuedBulkJobThroughMiddleware(object $job, Closure $terminal): mixe operationRun: $run, ); - $user->tenantMemberships()->where('tenant_id', $tenant->getKey())->update(['role' => 'readonly']); + $user->tenantMemberships()->where('managed_environment_id', $tenant->getKey())->update(['role' => 'readonly']); app(CapabilityResolver::class)->clearCache(); $terminalInvoked = false; @@ -104,7 +104,7 @@ function (BulkPolicyDeleteJob $job) use (&$terminalInvoked): void { ->and($run->status)->toBe('completed') ->and($run->outcome)->toBe('blocked') ->and($run->context['reason_code'] ?? null)->toBe('missing_capability') - ->and($run->context['execution_legitimacy']['target_scope']['tenant_id'] ?? null)->toBe((int) $tenant->getKey()); + ->and($run->context['execution_legitimacy']['target_scope']['managed_environment_id'] ?? null)->toBe((int) $tenant->getKey()); Queue::assertNothingPushed(); }); diff --git a/apps/platform/tests/Feature/Operations/ExecuteRestoreRunExecutionReauthorizationTest.php b/apps/platform/tests/Feature/Operations/ExecuteRestoreRunExecutionReauthorizationTest.php index 65e8e2a7..69400150 100644 --- a/apps/platform/tests/Feature/Operations/ExecuteRestoreRunExecutionReauthorizationTest.php +++ b/apps/platform/tests/Feature/Operations/ExecuteRestoreRunExecutionReauthorizationTest.php @@ -26,7 +26,7 @@ function runQueuedRestoreJobThroughMiddleware(object $job, Closure $terminal): m } it('blocks restore execution when the tenant becomes non-operable before start', function (): void { - $tenant = \App\Models\Tenant::factory()->create([ + $tenant = \App\Models\ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), ]); @@ -40,7 +40,7 @@ function runQueuedRestoreJobThroughMiddleware(object $job, Closure $terminal): m ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'requested_by' => 'actor@example.com', 'is_dry_run' => false, @@ -94,7 +94,7 @@ function (ExecuteRestoreRunJob $job) use (&$terminalInvoked): mixed { }); it('allows restore execution when legitimacy still holds', function (): void { - $tenant = \App\Models\Tenant::factory()->create([ + $tenant = \App\Models\ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), ]); @@ -108,7 +108,7 @@ function (ExecuteRestoreRunJob $job) use (&$terminalInvoked): mixed { ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'requested_by' => 'actor@example.com', 'is_dry_run' => false, diff --git a/apps/platform/tests/Feature/Operations/OperationLifecycleReconciliationTest.php b/apps/platform/tests/Feature/Operations/OperationLifecycleReconciliationTest.php index 4147ca8f..41bb22db 100644 --- a/apps/platform/tests/Feature/Operations/OperationLifecycleReconciliationTest.php +++ b/apps/platform/tests/Feature/Operations/OperationLifecycleReconciliationTest.php @@ -14,7 +14,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $staleQueued = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'policy.sync', @@ -25,7 +25,7 @@ ]); $staleRunning = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -36,7 +36,7 @@ ]); $freshRunning = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -71,7 +71,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'policy.sync', diff --git a/apps/platform/tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php b/apps/platform/tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php index a49ce045..1cd6620c 100644 --- a/apps/platform/tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php +++ b/apps/platform/tests/Feature/Operations/OperationRunBlockedExecutionPresentationTest.php @@ -15,7 +15,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory_sync', diff --git a/apps/platform/tests/Feature/Operations/OperationRunFailedJobBridgeTest.php b/apps/platform/tests/Feature/Operations/OperationRunFailedJobBridgeTest.php index 3c7cd3d6..05e857aa 100644 --- a/apps/platform/tests/Feature/Operations/OperationRunFailedJobBridgeTest.php +++ b/apps/platform/tests/Feature/Operations/OperationRunFailedJobBridgeTest.php @@ -18,7 +18,7 @@ class FakeMaxAttemptsExceededException extends RuntimeException {} [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'policy.sync', @@ -45,7 +45,7 @@ public function __construct(public OperationRun $operationRun) {} [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', diff --git a/apps/platform/tests/Feature/Operations/ProductTelemetryOperationStartCaptureTest.php b/apps/platform/tests/Feature/Operations/ProductTelemetryOperationStartCaptureTest.php index cea28824..c09426c6 100644 --- a/apps/platform/tests/Feature/Operations/ProductTelemetryOperationStartCaptureTest.php +++ b/apps/platform/tests/Feature/Operations/ProductTelemetryOperationStartCaptureTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\ProductUsageEvent; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\OperationRunService; use App\Support\OperationRunType; use App\Support\ProductTelemetry\ProductUsageEventCatalog; @@ -12,7 +12,7 @@ uses(RefreshDatabase::class); it('records telemetry for user-initiated tenant-bound operation starts only once per created run', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $service = app(OperationRunService::class); @@ -44,7 +44,7 @@ $serializedEvent = json_encode($event->toArray(), JSON_THROW_ON_ERROR); expect($event->event_name)->toBe(ProductUsageEventCatalog::OPERATIONS_STARTED) - ->and($event->tenant_id)->toBe((int) $tenant->getKey()) + ->and($event->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($event->workspace_id)->toBe((int) $tenant->workspace_id) ->and($event->user_id)->toBe((int) $user->getKey()) ->and($event->subject_type)->toBe('operation_run') @@ -58,7 +58,7 @@ }); it('does not record telemetry for system-initiated operation starts', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); app(OperationRunService::class)->ensureRun( tenant: $tenant, diff --git a/apps/platform/tests/Feature/Operations/ProviderBackedRunReasonAlignmentTest.php b/apps/platform/tests/Feature/Operations/ProviderBackedRunReasonAlignmentTest.php index 979d902d..4a993fb5 100644 --- a/apps/platform/tests/Feature/Operations/ProviderBackedRunReasonAlignmentTest.php +++ b/apps/platform/tests/Feature/Operations/ProviderBackedRunReasonAlignmentTest.php @@ -21,7 +21,7 @@ function makeProviderBlockedRun(): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory_sync', @@ -34,7 +34,7 @@ function makeProviderBlockedRun(): array 'reason_code' => ProviderReasonCodes::ProviderConnectionMissing, 'blocked_by' => 'provider_preflight', 'target_scope' => [ - 'entra_tenant_id' => $tenant->tenant_id, + 'entra_tenant_id' => $tenant->managed_environment_id, ], ], ]); @@ -83,7 +83,7 @@ function makeProviderBlockedRun(): array $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => null, 'initiator_name' => 'Scheduled automation', 'type' => 'inventory_sync', @@ -96,7 +96,7 @@ function makeProviderBlockedRun(): array 'reason_code' => ProviderReasonCodes::ProviderConnectionMissing, 'blocked_by' => 'provider_preflight', 'target_scope' => [ - 'entra_tenant_id' => $tenant->tenant_id, + 'entra_tenant_id' => $tenant->managed_environment_id, ], ], ]); diff --git a/apps/platform/tests/Feature/Operations/QueuedExecutionAuditTrailTest.php b/apps/platform/tests/Feature/Operations/QueuedExecutionAuditTrailTest.php index 3f893330..7cbea24a 100644 --- a/apps/platform/tests/Feature/Operations/QueuedExecutionAuditTrailTest.php +++ b/apps/platform/tests/Feature/Operations/QueuedExecutionAuditTrailTest.php @@ -15,7 +15,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, @@ -39,7 +39,7 @@ providerConnectionId: 123, targetScope: [ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider_connection_id' => 123, ], ); diff --git a/apps/platform/tests/Feature/Operations/QueuedExecutionContractMatrixTest.php b/apps/platform/tests/Feature/Operations/QueuedExecutionContractMatrixTest.php index 14cbb645..9ff705f0 100644 --- a/apps/platform/tests/Feature/Operations/QueuedExecutionContractMatrixTest.php +++ b/apps/platform/tests/Feature/Operations/QueuedExecutionContractMatrixTest.php @@ -30,7 +30,7 @@ function runQueuedContractMatrixJobThroughMiddleware(object $job, Closure $termi [$user, $tenant] = createUserWithTenant(role: 'owner'); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -53,7 +53,7 @@ function runQueuedContractMatrixJobThroughMiddleware(object $job, Closure $termi operationRun: $run, ); - $user->tenantMemberships()->where('tenant_id', $tenant->getKey())->update(['role' => 'readonly']); + $user->tenantMemberships()->where('managed_environment_id', $tenant->getKey())->update(['role' => 'readonly']); app(CapabilityResolver::class)->clearCache(); $terminalInvoked = false; @@ -98,7 +98,7 @@ function () use (&$terminalInvoked): string { operationRun: $run, ); - $user->tenantMemberships()->where('tenant_id', $tenant->getKey())->update(['role' => 'readonly']); + $user->tenantMemberships()->where('managed_environment_id', $tenant->getKey())->update(['role' => 'readonly']); app(CapabilityResolver::class)->clearCache(); $terminalInvoked = false; @@ -124,7 +124,7 @@ function () use (&$terminalInvoked): string { [, $tenant] = createUserWithTenant(role: 'owner'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Queued legitimacy contract', 'is_enabled' => true, 'timezone' => 'UTC', @@ -202,7 +202,7 @@ function () use (&$terminalInvoked): string { ); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', diff --git a/apps/platform/tests/Feature/Operations/QueuedExecutionMiddlewareOrderingTest.php b/apps/platform/tests/Feature/Operations/QueuedExecutionMiddlewareOrderingTest.php index 0297a01a..678776f7 100644 --- a/apps/platform/tests/Feature/Operations/QueuedExecutionMiddlewareOrderingTest.php +++ b/apps/platform/tests/Feature/Operations/QueuedExecutionMiddlewareOrderingTest.php @@ -17,7 +17,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -36,7 +36,7 @@ providerConnectionId: null, targetScope: [ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider_connection_id' => null, ], ); @@ -94,7 +94,7 @@ public function __construct(public OperationRun $operationRun) {} [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -113,7 +113,7 @@ public function __construct(public OperationRun $operationRun) {} providerConnectionId: null, targetScope: [ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider_connection_id' => null, ], ); @@ -169,7 +169,7 @@ public function __construct(public OperationRun $operationRun) {} [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'restore.execute', @@ -188,7 +188,7 @@ public function __construct(public OperationRun $operationRun) {} providerConnectionId: null, targetScope: [ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider_connection_id' => null, ], ); diff --git a/apps/platform/tests/Feature/Operations/QueuedExecutionRetryReauthorizationTest.php b/apps/platform/tests/Feature/Operations/QueuedExecutionRetryReauthorizationTest.php index 38e45a68..ad6936b2 100644 --- a/apps/platform/tests/Feature/Operations/QueuedExecutionRetryReauthorizationTest.php +++ b/apps/platform/tests/Feature/Operations/QueuedExecutionRetryReauthorizationTest.php @@ -30,7 +30,7 @@ function runQueuedRetryJobThroughMiddleware(object $job, Closure $terminal): mix type: 'policy.delete', inputs: [ 'target_scope' => [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], ], initiator: $user, @@ -49,10 +49,11 @@ protected function process(OperationRunService $runs): void {} initiator: $user, authorityMode: ExecutionAuthorityMode::ActorBound, requiredCapability: 'tenant.manage', + workspaceRequiredCapability: null, providerConnectionId: null, targetScope: [ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider_connection_id' => null, ], ); diff --git a/apps/platform/tests/Feature/Operations/ReconcileAdapterRunsJobTrackingTest.php b/apps/platform/tests/Feature/Operations/ReconcileAdapterRunsJobTrackingTest.php index 28595623..102da3f4 100644 --- a/apps/platform/tests/Feature/Operations/ReconcileAdapterRunsJobTrackingTest.php +++ b/apps/platform/tests/Feature/Operations/ReconcileAdapterRunsJobTrackingTest.php @@ -29,7 +29,7 @@ protected function reconcile(AdapterRunReconciler $reconciler): array $run = OperationRun::query() ->where('workspace_id', (int) $workspace->getKey()) - ->whereNull('tenant_id') + ->whereNull('managed_environment_id') ->where('type', 'ops.reconcile_adapter_runs') ->first(); @@ -59,7 +59,7 @@ protected function reconcile(AdapterRunReconciler $reconciler): array $run = OperationRun::query() ->where('workspace_id', (int) $workspace->getKey()) - ->whereNull('tenant_id') + ->whereNull('managed_environment_id') ->where('type', 'ops.reconcile_adapter_runs') ->first(); diff --git a/apps/platform/tests/Feature/Operations/RestoreLinkedOperationDetailTest.php b/apps/platform/tests/Feature/Operations/RestoreLinkedOperationDetailTest.php index cbc09066..0cb603a7 100644 --- a/apps/platform/tests/Feature/Operations/RestoreLinkedOperationDetailTest.php +++ b/apps/platform/tests/Feature/Operations/RestoreLinkedOperationDetailTest.php @@ -19,11 +19,11 @@ $this->actingAs($user); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $operationRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'restore.execute', @@ -33,7 +33,7 @@ ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'operation_run_id' => $operationRun->id, 'status' => 'completed', @@ -67,6 +67,6 @@ ->test(TenantlessOperationRunViewer::class, ['run' => $operationRun]) ->assertSee('Restore continuation') ->assertSee('Follow-up required') - ->assertSee('Tenant-wide recovery is not proven.') + ->assertSee('ManagedEnvironment-wide recovery is not proven.') ->assertSee('Open restore run'); }); diff --git a/apps/platform/tests/Feature/Operations/RunInventorySyncExecutionReauthorizationTest.php b/apps/platform/tests/Feature/Operations/RunInventorySyncExecutionReauthorizationTest.php index 45895ed1..ffaf5e51 100644 --- a/apps/platform/tests/Feature/Operations/RunInventorySyncExecutionReauthorizationTest.php +++ b/apps/platform/tests/Feature/Operations/RunInventorySyncExecutionReauthorizationTest.php @@ -42,7 +42,7 @@ function runQueuedInventoryJobThroughMiddleware(object $job, Closure $terminal): ]); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'inventory.sync') ->latest('id') ->first(); @@ -80,7 +80,7 @@ function runQueuedInventoryJobThroughMiddleware(object $job, Closure $terminal): expect($capturedJob)->toBeInstanceOf(RunInventorySyncJob::class); - $user->tenantMemberships()->where('tenant_id', $tenant->getKey())->update(['role' => 'readonly']); + $user->tenantMemberships()->where('managed_environment_id', $tenant->getKey())->update(['role' => 'readonly']); app(CapabilityResolver::class)->clearCache(); $terminalInvoked = false; diff --git a/apps/platform/tests/Feature/Operations/SystemRunBlockedExecutionNotificationTest.php b/apps/platform/tests/Feature/Operations/SystemRunBlockedExecutionNotificationTest.php index 8847abac..4127d31b 100644 --- a/apps/platform/tests/Feature/Operations/SystemRunBlockedExecutionNotificationTest.php +++ b/apps/platform/tests/Feature/Operations/SystemRunBlockedExecutionNotificationTest.php @@ -9,7 +9,7 @@ [, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => null, 'initiator_name' => 'System', diff --git a/apps/platform/tests/Feature/Operations/TenantlessOperationRunViewerTest.php b/apps/platform/tests/Feature/Operations/TenantlessOperationRunViewerTest.php index fb0a19e0..c8ff834a 100644 --- a/apps/platform/tests/Feature/Operations/TenantlessOperationRunViewerTest.php +++ b/apps/platform/tests/Feature/Operations/TenantlessOperationRunViewerTest.php @@ -6,7 +6,7 @@ use App\Models\BaselineProfile; use App\Models\BaselineSnapshot; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -40,7 +40,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -61,7 +61,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -86,7 +86,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -140,7 +140,7 @@ it('returns 403 for members missing the required capability for the operation type', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -162,7 +162,7 @@ session()->forget(WorkspaceContext::SESSION_KEY); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -175,11 +175,11 @@ }); it('shows blocked execution guidance in the canonical tenantless viewer', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -218,11 +218,11 @@ }); it('keeps reconciled lifecycle runs viewable for entitled members', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'restore.execute', @@ -274,8 +274,8 @@ it('keeps a canonical run viewer accessible when the remembered tenant differs from the run tenant', function (): void { $workspace = Workspace::factory()->create(); - $tenantA = Tenant::factory()->for($workspace)->create(); - $tenantB = Tenant::factory()->for($workspace)->create(); + $tenantA = ManagedEnvironment::factory()->for($workspace)->create(); + $tenantB = ManagedEnvironment::factory()->for($workspace)->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ @@ -294,7 +294,7 @@ } $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -317,12 +317,12 @@ }); it('keeps tenantless run viewing accessible while another tenant is selected', function (): void { - $selectedTenant = Tenant::factory()->create(); + $selectedTenant = ManagedEnvironment::factory()->create(); [$user, $selectedTenant] = createUserWithTenant(tenant: $selectedTenant, role: 'owner'); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $selectedTenant->workspace_id, - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -344,14 +344,14 @@ }); it('keeps a canonical run viewer accessible when remembered tenant context is cleared as stale', function (): void { - $runTenant = Tenant::factory()->active()->create([ - 'name' => 'Viewer Run Tenant', + $runTenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Viewer Run ManagedEnvironment', ]); [$user, $runTenant] = createUserWithTenant(tenant: $runTenant, role: 'owner'); - $rememberedTenant = Tenant::factory()->onboarding()->create([ + $rememberedTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $runTenant->workspace_id, - 'name' => 'Viewer Onboarding Tenant', + 'name' => 'Viewer Onboarding ManagedEnvironment', ]); createUserWithTenant( @@ -363,7 +363,7 @@ ); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $runTenant->getKey(), + 'managed_environment_id' => (int) $runTenant->getKey(), 'workspace_id' => (int) $runTenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -387,14 +387,14 @@ }); it('keeps a canonical run viewer accessible when the run tenant is selector-ineligible but the remembered context is valid', function (): void { - $rememberedTenant = Tenant::factory()->active()->create([ - 'name' => 'Viewer Active Tenant', + $rememberedTenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Viewer Active ManagedEnvironment', ]); [$user, $rememberedTenant] = createUserWithTenant(tenant: $rememberedTenant, role: 'owner'); - $runTenant = Tenant::factory()->onboarding()->create([ + $runTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $rememberedTenant->workspace_id, - 'name' => 'Viewer Onboarding Tenant', + 'name' => 'Viewer Onboarding ManagedEnvironment', ]); createUserWithTenant( @@ -406,7 +406,7 @@ ); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $runTenant->getKey(), + 'managed_environment_id' => (int) $runTenant->getKey(), 'workspace_id' => (int) $rememberedTenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Queued->value, @@ -446,7 +446,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -475,7 +475,7 @@ it('renders explicit back-link lineage when opened from a canonical source context', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $user = User::factory()->create(); @@ -495,7 +495,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'backup_set.update', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -519,7 +519,7 @@ it('keeps the explicit back-link action after Livewire hydration', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $user = User::factory()->create(); @@ -539,7 +539,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'baseline_compare', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -552,7 +552,7 @@ 'nav' => [ 'source_surface' => 'finding.detail_section', 'canonical_route_name' => 'admin.operations.view', - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'back_label' => 'Back to finding', 'back_url' => '/admin/findings/42?tenant='.$tenant->external_id, ], @@ -576,7 +576,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -596,11 +596,11 @@ }); it('surfaces resumable follow-up separately from navigation and drilldown lanes', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => OperationRunStatus::Completed->value, @@ -628,7 +628,7 @@ }); it('keeps operations-list navigation out of the related drilldown lane', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $profile = BaselineProfile::factory()->active()->create([ @@ -641,7 +641,7 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => OperationRunStatus::Completed->value, @@ -687,7 +687,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => $status, 'outcome' => OperationRunOutcome::Pending->value, @@ -727,7 +727,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -756,7 +756,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => $outcome, @@ -775,11 +775,11 @@ ]); it('renders human-readable per-type inventory coverage in the canonical tenantless viewer', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/OpsUx/ActiveRunsTest.php b/apps/platform/tests/Feature/OpsUx/ActiveRunsTest.php index 341fe9ba..373a6df6 100644 --- a/apps/platform/tests/Feature/OpsUx/ActiveRunsTest.php +++ b/apps/platform/tests/Feature/OpsUx/ActiveRunsTest.php @@ -3,14 +3,14 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OpsUx\ActiveRuns; it('returns false when tenant has no active runs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'inventory_sync', 'status' => 'completed', 'outcome' => 'succeeded', @@ -21,10 +21,10 @@ }); it('returns true when tenant has queued runs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'inventory_sync', 'status' => 'queued', 'outcome' => 'pending', @@ -36,10 +36,10 @@ }); it('returns true when tenant has running runs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'inventory_sync', 'status' => 'running', 'outcome' => 'pending', @@ -51,10 +51,10 @@ }); it('returns false when tenant only has likely stale runs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'inventory_sync', 'status' => 'queued', 'outcome' => 'pending', @@ -67,11 +67,11 @@ }); it('is tenant scoped (other tenant active runs do not count)', function (): void { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); OperationRun::factory()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'type' => 'inventory_sync', 'status' => 'running', 'outcome' => 'pending', diff --git a/apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php b/apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php index 22c2a89b..0dd0a91c 100644 --- a/apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php +++ b/apps/platform/tests/Feature/OpsUx/ActivityFeedbackSurfaceTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\InventoryItemResource; use App\Livewire\BulkOperationProgress; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OpsUx\OperationRunUrl; use Filament\Facades\Filament; use Livewire\Livewire; @@ -15,7 +15,7 @@ Filament::setTenant(null, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -41,7 +41,7 @@ session()->forget(\App\Support\Workspaces\WorkspaceContext::SESSION_KEY); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -61,7 +61,7 @@ it('does not expose another tenant run through the selected tenant shell', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); - $foreignTenant = Tenant::factory()->create([ + $foreignTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); @@ -69,7 +69,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $foreignTenant->getKey(), + 'managed_environment_id' => (int) $foreignTenant->getKey(), 'workspace_id' => (int) $foreignTenant->workspace_id, 'type' => 'policy.sync', 'status' => 'running', @@ -97,7 +97,7 @@ foreach (range(0, 3) as $offset) { $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -141,7 +141,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -176,7 +176,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -217,7 +217,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -254,7 +254,7 @@ Filament::setTenant($tenant, true); $runningRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -264,7 +264,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -299,7 +299,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -334,7 +334,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -371,7 +371,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'baseline_capture', @@ -414,7 +414,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'tenant.review.compose', @@ -453,7 +453,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'cross_tenant_promotion.execute', @@ -487,7 +487,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -523,7 +523,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -557,7 +557,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -581,7 +581,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -597,7 +597,7 @@ $content = $response->getContent(); - expect(strpos($content, 'Tenant-Dashboard'))->toBeLessThan(strpos($content, 'Active operations')) + expect(strpos($content, 'ManagedEnvironment-Dashboard'))->toBeLessThan(strpos($content, 'Active operations')) ->and($content)->not->toContain('fixed bottom-4 right-4 z-[999999] w-96 space-y-2'); })->group('ops-ux'); @@ -608,7 +608,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', diff --git a/apps/platform/tests/Feature/OpsUx/AdapterRunReconcilerTest.php b/apps/platform/tests/Feature/OpsUx/AdapterRunReconcilerTest.php index cd15f5bf..230f96a1 100644 --- a/apps/platform/tests/Feature/OpsUx/AdapterRunReconcilerTest.php +++ b/apps/platform/tests/Feature/OpsUx/AdapterRunReconcilerTest.php @@ -12,11 +12,11 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->getKey(), 'status' => 'completed', 'is_dry_run' => false, @@ -39,7 +39,7 @@ ]); $opRun = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'restore.execute', @@ -56,7 +56,7 @@ $result = app(AdapterRunReconciler::class)->reconcile([ 'type' => 'restore.execute', - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'older_than_minutes' => 10, 'limit' => 10, 'dry_run' => false, @@ -86,11 +86,11 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->getKey(), 'status' => 'completed', 'is_dry_run' => false, @@ -101,7 +101,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'restore.execute', @@ -116,7 +116,7 @@ $reconciler = app(AdapterRunReconciler::class); $first = $reconciler->reconcile([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'older_than_minutes' => 10, 'limit' => 10, 'dry_run' => false, @@ -125,7 +125,7 @@ expect($first['reconciled'] ?? null)->toBe(1); $second = $reconciler->reconcile([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'older_than_minutes' => 10, 'limit' => 10, 'dry_run' => false, @@ -139,11 +139,11 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->getKey(), 'status' => 'completed', 'is_dry_run' => false, @@ -156,7 +156,7 @@ ]); $opRun = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'restore.execute', @@ -169,7 +169,7 @@ ]); app(AdapterRunReconciler::class)->reconcile([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'older_than_minutes' => 10, 'limit' => 10, 'dry_run' => false, diff --git a/apps/platform/tests/Feature/OpsUx/BackupSetDeleteBulkJobTest.php b/apps/platform/tests/Feature/OpsUx/BackupSetDeleteBulkJobTest.php index d6c5cd25..511fa391 100644 --- a/apps/platform/tests/Feature/OpsUx/BackupSetDeleteBulkJobTest.php +++ b/apps/platform/tests/Feature/OpsUx/BackupSetDeleteBulkJobTest.php @@ -16,14 +16,14 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'backup_set.delete', 'status' => 'queued', 'summary_counts' => [], 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], ], ]); @@ -53,18 +53,18 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $active = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'deleted_at' => null, ]); $alreadyArchived = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'deleted_at' => null, ]); $alreadyArchived->delete(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'backup_set.delete', 'status' => 'running', @@ -75,7 +75,7 @@ ], 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], ], ]); diff --git a/apps/platform/tests/Feature/OpsUx/BulkEnqueueIdempotencyTest.php b/apps/platform/tests/Feature/OpsUx/BulkEnqueueIdempotencyTest.php index d96f51cd..20f72b38 100644 --- a/apps/platform/tests/Feature/OpsUx/BulkEnqueueIdempotencyTest.php +++ b/apps/platform/tests/Feature/OpsUx/BulkEnqueueIdempotencyTest.php @@ -3,14 +3,14 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Services\Operations\BulkSelectionIdentity; it('reuses an active bulk run without dispatching twice', function (): void { $entraTenantId = '00000000-0000-0000-0000-000000000001'; - $tenant = Tenant::factory()->create(['tenant_id' => $entraTenantId]); + $tenant = ManagedEnvironment::factory()->create(['managed_environment_id' => $entraTenantId]); $user = User::factory()->create(); $selectionIdentity = app(BulkSelectionIdentity::class)->fromIds(['a', 'b', 'c']); @@ -44,12 +44,12 @@ expect($runA->getKey())->toBe($runB->getKey()); expect($dispatchCount)->toBe(1); - expect(OperationRun::query()->where('tenant_id', $tenant->id)->count())->toBe(1); + expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->count())->toBe(1); })->group('ops-ux'); it('passes the OperationRun to the dispatcher when accepted', function (): void { $entraTenantId = '00000000-0000-0000-0000-000000000001'; - $tenant = Tenant::factory()->create(['tenant_id' => $entraTenantId]); + $tenant = ManagedEnvironment::factory()->create(['managed_environment_id' => $entraTenantId]); $user = User::factory()->create(); $selectionIdentity = app(BulkSelectionIdentity::class)->fromIds(['a']); diff --git a/apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php b/apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php index 26990144..a9c88366 100644 --- a/apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php +++ b/apps/platform/tests/Feature/OpsUx/BulkOperationProgressDbOnlyTest.php @@ -2,13 +2,13 @@ use App\Livewire\BulkOperationProgress; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Filament\Facades\Filament; use Livewire\Livewire; it('keeps the Ops UX progress widget DB-only (no outbound HTTP) and tenant-scoped', function () { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenantA, role: 'owner'); @@ -17,7 +17,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'type' => 'policy.sync', 'status' => 'running', 'outcome' => 'pending', @@ -25,7 +25,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'type' => 'inventory_sync', 'status' => 'running', 'outcome' => 'pending', @@ -51,7 +51,7 @@ Filament::setTenant(null, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'running', @@ -73,7 +73,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'queued', @@ -100,7 +100,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', @@ -137,7 +137,7 @@ ->assertDontSee('Inventory sync'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', @@ -166,7 +166,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'running', @@ -175,7 +175,7 @@ ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', @@ -202,7 +202,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'queued', @@ -232,7 +232,7 @@ ->assertDontSee('10 / 10 processed (100%)'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'running', diff --git a/apps/platform/tests/Feature/OpsUx/BulkTenantIsolationTest.php b/apps/platform/tests/Feature/OpsUx/BulkTenantIsolationTest.php index eca32bff..07798e1e 100644 --- a/apps/platform/tests/Feature/OpsUx/BulkTenantIsolationTest.php +++ b/apps/platform/tests/Feature/OpsUx/BulkTenantIsolationTest.php @@ -1,12 +1,12 @@ create([ - 'tenant_id' => 'tenant-a', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-a', 'external_id' => 'tenant-a', ]); diff --git a/apps/platform/tests/Feature/OpsUx/CanonicalViewRunLinksTest.php b/apps/platform/tests/Feature/OpsUx/CanonicalViewRunLinksTest.php index 430de3dd..91eb138b 100644 --- a/apps/platform/tests/Feature/OpsUx/CanonicalViewRunLinksTest.php +++ b/apps/platform/tests/Feature/OpsUx/CanonicalViewRunLinksTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunLinks; use App\Support\OpsUx\OperationRunUrl; use App\Support\System\SystemOperationRunLinks; @@ -46,7 +46,7 @@ })->group('ops-ux'); it('normalizes tenant-scoped callers onto the canonical tenantless run route', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->for($tenant)->create(); $expectedUrl = route('admin.operations.view', ['run' => (int) $run->getKey()]); @@ -56,11 +56,11 @@ })->group('ops-ux'); it('preserves tenant prefilter, requested tab, and problem class on canonical operations collection links', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); expect(OperationRunLinks::index($tenant, activeTab: 'active')) ->toBe(route('admin.operations.index', [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'activeTab' => 'active', ])) ->and(OperationRunLinks::index( @@ -69,7 +69,7 @@ problemClass: OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION, )) ->toBe(route('admin.operations.index', [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'activeTab' => OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION, 'problemClass' => OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION, ])) @@ -79,18 +79,18 @@ problemClass: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, )) ->toBe(route('admin.operations.index', [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'activeTab' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, 'problemClass' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, ])); })->group('ops-ux'); it('preserves helper-owned operation type filters on canonical operations collection links', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); expect(OperationRunLinks::index($tenant, operationType: 'inventory_sync')) ->toBe(route('admin.operations.index', [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'tableFilters' => [ 'type' => [ 'value' => 'inventory.sync', @@ -100,7 +100,7 @@ })->group('ops-ux'); it('keeps the thin operation URL delegate on the canonical admin helpers', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->for($tenant)->create(); expect(OperationRunUrl::view($run, $tenant)) diff --git a/apps/platform/tests/Feature/OpsUx/FailureSanitizationTest.php b/apps/platform/tests/Feature/OpsUx/FailureSanitizationTest.php index 8a4b9f2e..e89ec842 100644 --- a/apps/platform/tests/Feature/OpsUx/FailureSanitizationTest.php +++ b/apps/platform/tests/Feature/OpsUx/FailureSanitizationTest.php @@ -1,11 +1,11 @@ create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); /** @var OperationRunService $runs */ diff --git a/apps/platform/tests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php b/apps/platform/tests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php index d0d3665b..04b27e9c 100644 --- a/apps/platform/tests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php +++ b/apps/platform/tests/Feature/OpsUx/NonLeakageWorkspaceOperationsTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -24,13 +24,13 @@ 'role' => 'owner', ]); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $workspaceB->getKey(), ]); $runB = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $workspaceB->getKey(), 'type' => 'policy.sync', 'initiator_name' => 'WorkspaceB', diff --git a/apps/platform/tests/Feature/OpsUx/NotificationViewRunLinkTest.php b/apps/platform/tests/Feature/OpsUx/NotificationViewRunLinkTest.php index 02c4dfe1..6f2a2cf3 100644 --- a/apps/platform/tests/Feature/OpsUx/NotificationViewRunLinkTest.php +++ b/apps/platform/tests/Feature/OpsUx/NotificationViewRunLinkTest.php @@ -14,7 +14,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory_sync', @@ -50,7 +50,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'policy.delete', diff --git a/apps/platform/tests/Feature/OpsUx/OperateHubShellTest.php b/apps/platform/tests/Feature/OpsUx/OperateHubShellTest.php index f9faef48..f0902d56 100644 --- a/apps/platform/tests/Feature/OpsUx/OperateHubShellTest.php +++ b/apps/platform/tests/Feature/OpsUx/OperateHubShellTest.php @@ -9,7 +9,7 @@ use App\Filament\Resources\RestoreRunResource; use App\Models\AuditLog; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -23,7 +23,7 @@ [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', 'status' => 'completed', @@ -45,14 +45,14 @@ ->get(route('admin.operations.index')) ->assertOk() ->assertSee('All tenants') - ->assertDontSee('Scope: Tenant') + ->assertDontSee('Scope: ManagedEnvironment') ->assertDontSee('Scope: Workspace'); $this->withSession($session) ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertOk() ->assertSee('All tenants') - ->assertDontSee('Scope: Tenant') + ->assertDontSee('Scope: ManagedEnvironment') ->assertDontSee('Scope: Workspace'); $this->withSession($session) @@ -60,14 +60,14 @@ ->get(AlertsCluster::getUrl(panel: 'admin')) ->assertOk() ->assertSee('All tenants') - ->assertDontSee('Scope: Tenant') + ->assertDontSee('Scope: ManagedEnvironment') ->assertDontSee('Scope: Workspace'); $this->withSession($session) ->get(route('admin.monitoring.audit-log')) ->assertOk() ->assertSee('All tenants') - ->assertDontSee('Scope: Tenant') + ->assertDontSee('Scope: ManagedEnvironment') ->assertDontSee('Scope: Workspace'); }); @@ -78,7 +78,7 @@ [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', @@ -112,7 +112,7 @@ [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', @@ -141,12 +141,12 @@ it('shows no tenant return affordance when active and last tenant contexts are not entitled', function (): void { [$user, $entitledTenant] = createMinimalUserWithTenant(role: 'owner'); - $nonEntitledTenant = Tenant::factory()->create([ + $nonEntitledTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $entitledTenant->workspace_id, ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $entitledTenant->getKey(), + 'managed_environment_id' => (int) $entitledTenant->getKey(), 'workspace_id' => (int) $entitledTenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', @@ -174,7 +174,7 @@ [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', @@ -213,7 +213,7 @@ })->group('ops-ux'); it('returns 404 for non-entitled tenant dashboard direct access', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ @@ -239,7 +239,7 @@ ->assertForbidden(); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->exists())->toBeFalse(); })->group('ops-ux'); @@ -263,10 +263,10 @@ })->group('ops-ux'); it('prefers the filament tenant over remembered workspace tenant state when both are entitled', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createMinimalUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -286,12 +286,12 @@ })->group('ops-ux'); it('prefers the current filament tenant over remembered tenant state on canonical run routes', function (): void { - $runTenant = Tenant::factory()->create([ + $runTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => null, ]); [$user, $runTenant] = createMinimalUserWithTenant(tenant: $runTenant, role: 'owner'); - $currentTenant = Tenant::factory()->create([ + $currentTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $runTenant->workspace_id, ]); @@ -299,7 +299,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $runTenant->workspace_id, - 'tenant_id' => (int) $runTenant->getKey(), + 'managed_environment_id' => (int) $runTenant->getKey(), 'type' => 'policy.sync', ]); @@ -325,14 +325,14 @@ })->group('ops-ux'); it('keeps an administratively discoverable current tenant context on canonical run routes even when it is selector-ineligible', function (): void { - $runTenant = Tenant::factory()->active()->create([ - 'name' => 'Canonical Run Tenant', + $runTenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Canonical Run ManagedEnvironment', ]); [$user, $runTenant] = createMinimalUserWithTenant(tenant: $runTenant, role: 'owner'); - $currentTenant = Tenant::factory()->onboarding()->create([ + $currentTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $runTenant->workspace_id, - 'name' => 'Current Onboarding Tenant', + 'name' => 'Current Onboarding ManagedEnvironment', ]); createMinimalUserWithTenant( @@ -345,7 +345,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $runTenant->workspace_id, - 'tenant_id' => (int) $runTenant->getKey(), + 'managed_environment_id' => (int) $runTenant->getKey(), 'type' => 'policy.sync', ]); @@ -373,7 +373,7 @@ it('clears stale remembered tenant ids when the remembered tenant is no longer entitled', function (): void { [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); - $staleTenant = Tenant::factory()->create([ + $staleTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); @@ -395,14 +395,14 @@ })->group('ops-ux'); it('prefers the routed tenant over remembered workspace tenant state when a tenant route parameter is present', function (): void { - $rememberedTenant = Tenant::factory()->create([ + $rememberedTenant = ManagedEnvironment::factory()->create([ 'name' => 'YPTW2', 'environment' => 'dev', 'status' => 'active', ]); [$user, $rememberedTenant] = createMinimalUserWithTenant(tenant: $rememberedTenant, role: 'owner'); - $routedTenant = Tenant::factory()->create([ + $routedTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $rememberedTenant->workspace_id, 'name' => 'Phoenicon', 'environment' => 'dev', @@ -433,18 +433,18 @@ })->group('ops-ux'); it('prefers the routed tenant resource record over active tenant state on admin tenant view routes', function (): void { - $rememberedTenant = Tenant::factory()->create([ + $rememberedTenant = ManagedEnvironment::factory()->create([ 'name' => 'YPTW2', 'environment' => 'dev', 'status' => 'active', ]); [$user, $rememberedTenant] = createMinimalUserWithTenant(tenant: $rememberedTenant, role: 'owner'); - $routedTenant = Tenant::factory()->create([ + $routedTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $rememberedTenant->workspace_id, 'name' => 'Test', 'environment' => 'dev', - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); createMinimalUserWithTenant(tenant: $routedTenant, user: $user, role: 'owner'); @@ -480,8 +480,8 @@ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, ])->get(route('admin.operations.index')) ->assertOk() - ->assertSee('Tenant scope: '.$tenant->name) - ->assertDontSee('Scope: Tenant') + ->assertSee('ManagedEnvironment scope: '.$tenant->name) + ->assertDontSee('Scope: ManagedEnvironment') ->assertDontSee('Scope: Workspace') ->assertDontSee('All tenants'); })->group('ops-ux'); @@ -490,7 +490,7 @@ [$user, $tenant] = createMinimalUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', @@ -537,7 +537,7 @@ ])->get(AlertRuleResource::getUrl(panel: 'admin')) ->assertOk() ->assertDontSee('Filtered by tenant') - ->assertDontSee('Scope: Tenant') + ->assertDontSee('Scope: ManagedEnvironment') ->assertDontSee('Scope: Workspace'); })->group('ops-ux'); @@ -552,7 +552,7 @@ ])->get(AlertDestinationResource::getUrl(panel: 'admin')) ->assertOk() ->assertDontSee('Filtered by tenant') - ->assertDontSee('Scope: Tenant') + ->assertDontSee('Scope: ManagedEnvironment') ->assertDontSee('Scope: Workspace'); })->group('ops-ux'); @@ -571,18 +571,18 @@ ])->get(AlertRuleResource::getUrl(panel: 'admin')) ->assertOk() ->assertDontSee('Filtered by tenant') - ->assertDontSee('Scope: Tenant'); + ->assertDontSee('Scope: ManagedEnvironment'); })->group('ops-ux'); it('treats selector-ineligible remembered tenants as no selected tenant on canonical viewer routes', function (): void { - $runTenant = Tenant::factory()->active()->create([ - 'name' => 'Canonical Run Tenant', + $runTenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Canonical Run ManagedEnvironment', ]); [$user, $runTenant] = createMinimalUserWithTenant(tenant: $runTenant, role: 'owner'); - $rememberedTenant = Tenant::factory()->onboarding()->create([ + $rememberedTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $runTenant->workspace_id, - 'name' => 'Stale Onboarding Tenant', + 'name' => 'Stale Onboarding ManagedEnvironment', ]); createMinimalUserWithTenant( @@ -594,7 +594,7 @@ ); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $runTenant->getKey(), + 'managed_environment_id' => (int) $runTenant->getKey(), 'workspace_id' => (int) $runTenant->workspace_id, 'type' => 'policy.sync', ]); diff --git a/apps/platform/tests/Feature/OpsUx/OperationRunNotificationRedactionTest.php b/apps/platform/tests/Feature/OpsUx/OperationRunNotificationRedactionTest.php index 6f3e4d76..6cdbb6b0 100644 --- a/apps/platform/tests/Feature/OpsUx/OperationRunNotificationRedactionTest.php +++ b/apps/platform/tests/Feature/OpsUx/OperationRunNotificationRedactionTest.php @@ -13,7 +13,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory_sync', diff --git a/apps/platform/tests/Feature/OpsUx/OperationRunSummaryCountsIncrementTest.php b/apps/platform/tests/Feature/OpsUx/OperationRunSummaryCountsIncrementTest.php index 0b143089..899ee661 100644 --- a/apps/platform/tests/Feature/OpsUx/OperationRunSummaryCountsIncrementTest.php +++ b/apps/platform/tests/Feature/OpsUx/OperationRunSummaryCountsIncrementTest.php @@ -13,7 +13,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'policy.delete', @@ -51,7 +51,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'backup_set.update', diff --git a/apps/platform/tests/Feature/OpsUx/PolicyVersionForceDeleteBulkJobTest.php b/apps/platform/tests/Feature/OpsUx/PolicyVersionForceDeleteBulkJobTest.php index aae5bc29..df2ef875 100644 --- a/apps/platform/tests/Feature/OpsUx/PolicyVersionForceDeleteBulkJobTest.php +++ b/apps/platform/tests/Feature/OpsUx/PolicyVersionForceDeleteBulkJobTest.php @@ -17,14 +17,14 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'policy_version.force_delete', 'status' => 'queued', 'summary_counts' => [], 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], ], ]); @@ -54,25 +54,25 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $archived = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'deleted_at' => now(), ]); $active = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 2, 'deleted_at' => null, ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'policy_version.force_delete', 'status' => 'running', @@ -83,7 +83,7 @@ ], 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], ], ]); diff --git a/apps/platform/tests/Feature/OpsUx/PolicyVersionPruneBulkJobTest.php b/apps/platform/tests/Feature/OpsUx/PolicyVersionPruneBulkJobTest.php index 108d9498..73339589 100644 --- a/apps/platform/tests/Feature/OpsUx/PolicyVersionPruneBulkJobTest.php +++ b/apps/platform/tests/Feature/OpsUx/PolicyVersionPruneBulkJobTest.php @@ -17,14 +17,14 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'policy_version.prune', 'status' => 'queued', 'summary_counts' => [], 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], ], ]); @@ -55,11 +55,11 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $eligible = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), @@ -67,7 +67,7 @@ ]); $notEligibleCurrent = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 2, 'captured_at' => now()->subDays(120), @@ -75,7 +75,7 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'policy_version.prune', 'status' => 'running', @@ -86,7 +86,7 @@ ], 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], ], ]); diff --git a/apps/platform/tests/Feature/OpsUx/ProgressWidgetFiltersTest.php b/apps/platform/tests/Feature/OpsUx/ProgressWidgetFiltersTest.php index d1ec64bb..29453a74 100644 --- a/apps/platform/tests/Feature/OpsUx/ProgressWidgetFiltersTest.php +++ b/apps/platform/tests/Feature/OpsUx/ProgressWidgetFiltersTest.php @@ -15,21 +15,21 @@ createUserWithTenant(tenant: $tenant, user: $otherUser, role: 'owner'); OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'status' => 'queued', 'outcome' => 'pending', ]); OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $otherUser->id, 'status' => 'running', 'outcome' => 'pending', ]); OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'status' => 'completed', 'outcome' => 'succeeded', @@ -52,7 +52,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => $tenant->workspace_id, 'user_id' => $user->id, 'type' => $operationType, diff --git a/apps/platform/tests/Feature/OpsUx/ProgressWidgetOverflowTest.php b/apps/platform/tests/Feature/OpsUx/ProgressWidgetOverflowTest.php index 0b65fdb9..8fade8c7 100644 --- a/apps/platform/tests/Feature/OpsUx/ProgressWidgetOverflowTest.php +++ b/apps/platform/tests/Feature/OpsUx/ProgressWidgetOverflowTest.php @@ -12,7 +12,7 @@ Filament::setTenant($tenant, true); OperationRun::factory()->count(2)->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'queued', @@ -21,7 +21,7 @@ ]); OperationRun::factory()->count(2)->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'queued', diff --git a/apps/platform/tests/Feature/OpsUx/Regression/BackupRetentionTerminalNotificationTest.php b/apps/platform/tests/Feature/OpsUx/Regression/BackupRetentionTerminalNotificationTest.php index fd950a36..2a4b5f90 100644 --- a/apps/platform/tests/Feature/OpsUx/Regression/BackupRetentionTerminalNotificationTest.php +++ b/apps/platform/tests/Feature/OpsUx/Regression/BackupRetentionTerminalNotificationTest.php @@ -12,7 +12,7 @@ [$user, $tenant] = createUserWithTenant(role: 'manager'); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Retention Regression', 'is_enabled' => true, 'timezone' => 'UTC', @@ -26,7 +26,7 @@ $sets = collect(range(1, 4))->map(function (int $index) use ($tenant): BackupSet { return BackupSet::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Retention Set '.$index, 'status' => 'completed', 'item_count' => 0, @@ -39,7 +39,7 @@ foreach ($sets as $set) { OperationRun::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => null, 'initiator_name' => 'System', 'type' => 'backup_schedule_run', @@ -62,7 +62,7 @@ ApplyBackupScheduleRetentionJob::dispatchSync((int) $schedule->getKey()); $retentionRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::BackupScheduleRetention->value) ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/OpsUx/Regression/BackupScheduleRunNotificationTest.php b/apps/platform/tests/Feature/OpsUx/Regression/BackupScheduleRunNotificationTest.php index a917900c..2aec8dcf 100644 --- a/apps/platform/tests/Feature/OpsUx/Regression/BackupScheduleRunNotificationTest.php +++ b/apps/platform/tests/Feature/OpsUx/Regression/BackupScheduleRunNotificationTest.php @@ -32,7 +32,7 @@ Filament::setTenant($tenant, true); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'OpsUx Regression Schedule', 'is_enabled' => true, 'timezone' => 'UTC', @@ -65,7 +65,7 @@ public function syncPoliciesWithReport($tenant, ?array $supportedTypes = null): }); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'status' => 'completed', 'item_count' => 0, ]); diff --git a/apps/platform/tests/Feature/OpsUx/Regression/RestoreRunTerminalNotificationTest.php b/apps/platform/tests/Feature/OpsUx/Regression/RestoreRunTerminalNotificationTest.php index 1efd1bb3..59355e11 100644 --- a/apps/platform/tests/Feature/OpsUx/Regression/RestoreRunTerminalNotificationTest.php +++ b/apps/platform/tests/Feature/OpsUx/Regression/RestoreRunTerminalNotificationTest.php @@ -13,17 +13,22 @@ it('persists exactly one canonical terminal notification for initiated restore execution runs', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); + $tenant->forceFill([ + 'rbac_status' => 'ok', + 'rbac_last_checked_at' => now(), + ])->saveQuietly(); + $this->actingAs($user); $tenant->makeCurrent(); Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'requested_by' => $user->email, 'status' => 'queued', diff --git a/apps/platform/tests/Feature/OpsUx/RestoreExecuteOperationRunSyncTest.php b/apps/platform/tests/Feature/OpsUx/RestoreExecuteOperationRunSyncTest.php index 7e400ce8..734e7cc0 100644 --- a/apps/platform/tests/Feature/OpsUx/RestoreExecuteOperationRunSyncTest.php +++ b/apps/platform/tests/Feature/OpsUx/RestoreExecuteOperationRunSyncTest.php @@ -6,17 +6,17 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; it('syncs a completed restore run to a completed operation run', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'backup_set_id' => $backupSet->getKey(), 'status' => 'completed', 'is_dry_run' => false, @@ -39,7 +39,7 @@ app(SyncRestoreRunToOperationRun::class)->handle($restoreRun); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'restore.execute') ->where('context->restore_run_id', $restoreRun->getKey()) ->first(); diff --git a/apps/platform/tests/Feature/OpsUx/RestoreExecutionOperationRunSyncTest.php b/apps/platform/tests/Feature/OpsUx/RestoreExecutionOperationRunSyncTest.php index 44f87aa8..2c74ffa5 100644 --- a/apps/platform/tests/Feature/OpsUx/RestoreExecutionOperationRunSyncTest.php +++ b/apps/platform/tests/Feature/OpsUx/RestoreExecutionOperationRunSyncTest.php @@ -11,14 +11,19 @@ it('syncs restore execution into OperationRun even if restore status updates bypass model events', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); + $tenant->forceFill([ + 'rbac_status' => 'ok', + 'rbac_last_checked_at' => now(), + ])->saveQuietly(); + $this->actingAs($user); $backupSet = \App\Models\BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'queued', 'started_at' => null, diff --git a/apps/platform/tests/Feature/OpsUx/RestoreRunDeleteBulkJobTest.php b/apps/platform/tests/Feature/OpsUx/RestoreRunDeleteBulkJobTest.php index d599ee76..797e9eb3 100644 --- a/apps/platform/tests/Feature/OpsUx/RestoreRunDeleteBulkJobTest.php +++ b/apps/platform/tests/Feature/OpsUx/RestoreRunDeleteBulkJobTest.php @@ -16,14 +16,14 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'restore_run.delete', 'status' => 'queued', 'summary_counts' => [], 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], ], ]); @@ -53,25 +53,25 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $deletable = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'status' => 'completed', 'deleted_at' => null, ]); $alreadyArchived = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'status' => 'completed', 'deleted_at' => now(), ]); $notDeletable = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'status' => 'running', 'deleted_at' => null, ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'restore_run.delete', 'status' => 'running', @@ -82,7 +82,7 @@ ], 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? $tenant->external_id), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? $tenant->external_id), ], ], ]); diff --git a/apps/platform/tests/Feature/OpsUx/RunEnqueuedBrowserEventTest.php b/apps/platform/tests/Feature/OpsUx/RunEnqueuedBrowserEventTest.php index 77cb6b8e..0488770d 100644 --- a/apps/platform/tests/Feature/OpsUx/RunEnqueuedBrowserEventTest.php +++ b/apps/platform/tests/Feature/OpsUx/RunEnqueuedBrowserEventTest.php @@ -1,5 +1,6 @@ dispatched)->toBe([OpsUxBrowserEvents::RunEnqueued]); - expect($fakeLivewire->lastEvent?->to)->not->toBeNull(); + expect($fakeLivewire->dispatched)->toBe([ + OpsUxBrowserEvents::RunEnqueued, + OpsUxBrowserEvents::RunEnqueued, + ]); + expect($fakeLivewire->lastEvent?->to)->toBe(InventoryKpiHeader::class); expect($fakeLivewire->lastEvent?->params)->toHaveKey('tenantId'); })->group('ops-ux'); diff --git a/apps/platform/tests/Feature/OpsUx/SummaryCountsWhitelistTest.php b/apps/platform/tests/Feature/OpsUx/SummaryCountsWhitelistTest.php index 3153849d..1450e728 100644 --- a/apps/platform/tests/Feature/OpsUx/SummaryCountsWhitelistTest.php +++ b/apps/platform/tests/Feature/OpsUx/SummaryCountsWhitelistTest.php @@ -13,7 +13,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory_sync', @@ -54,7 +54,7 @@ $this->actingAs($user); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'policy.delete', @@ -94,7 +94,7 @@ $this->actingAs($user); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'policy.delete', diff --git a/apps/platform/tests/Feature/OpsUx/TenantSyncBulkJobTest.php b/apps/platform/tests/Feature/OpsUx/TenantSyncBulkJobTest.php index b795fbc7..7f91491b 100644 --- a/apps/platform/tests/Feature/OpsUx/TenantSyncBulkJobTest.php +++ b/apps/platform/tests/Feature/OpsUx/TenantSyncBulkJobTest.php @@ -5,7 +5,7 @@ use App\Jobs\BulkTenantSyncJob; use App\Jobs\Operations\TenantSyncWorkerJob; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\PolicySyncService; use App\Services\OperationRunService; use App\Services\Operations\TargetScopeConcurrencyLimiter; @@ -19,14 +19,14 @@ [$user, $tenantContext] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenantContext->id, + 'managed_environment_id' => $tenantContext->id, 'user_id' => $user->id, 'type' => 'tenant.sync', 'status' => 'queued', 'summary_counts' => [], 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) ($tenantContext->tenant_id ?? $tenantContext->external_id), + 'entra_tenant_id' => (string) ($tenantContext->managed_environment_id ?? $tenantContext->external_id), ], ], ]); @@ -55,17 +55,17 @@ it('syncs eligible tenants and updates summary counts', function (): void { [$user, $tenantContext] = createUserWithTenant(role: 'owner'); - $eligible = Tenant::factory()->create([ + $eligible = ManagedEnvironment::factory()->create([ 'status' => 'active', 'deleted_at' => null, ]); - $inactive = Tenant::factory()->create([ - 'status' => Tenant::STATUS_ARCHIVED, + $inactive = ManagedEnvironment::factory()->create([ + 'status' => ManagedEnvironment::STATUS_ARCHIVED, 'deleted_at' => null, ]); - $unauthorized = Tenant::factory()->create([ + $unauthorized = ManagedEnvironment::factory()->create([ 'status' => 'active', 'deleted_at' => null, ]); @@ -112,7 +112,7 @@ public function forceRelease(): void ->andReturn($lock); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenantContext->id, + 'managed_environment_id' => $tenantContext->id, 'user_id' => $user->id, 'type' => 'tenant.sync', 'status' => 'running', @@ -123,7 +123,7 @@ public function forceRelease(): void ], 'context' => [ 'target_scope' => [ - 'entra_tenant_id' => (string) ($tenantContext->tenant_id ?? $tenantContext->external_id), + 'entra_tenant_id' => (string) ($tenantContext->managed_environment_id ?? $tenantContext->external_id), ], ], ]); diff --git a/apps/platform/tests/Feature/OpsUx/TerminalNotificationFailureMessageTest.php b/apps/platform/tests/Feature/OpsUx/TerminalNotificationFailureMessageTest.php index 646ba3c9..5a561284 100644 --- a/apps/platform/tests/Feature/OpsUx/TerminalNotificationFailureMessageTest.php +++ b/apps/platform/tests/Feature/OpsUx/TerminalNotificationFailureMessageTest.php @@ -16,7 +16,7 @@ str_repeat('x', 400); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory_sync', diff --git a/apps/platform/tests/Feature/OpsUx/TerminalNotificationIdempotencyTest.php b/apps/platform/tests/Feature/OpsUx/TerminalNotificationIdempotencyTest.php index 1861edaa..4a71a4c4 100644 --- a/apps/platform/tests/Feature/OpsUx/TerminalNotificationIdempotencyTest.php +++ b/apps/platform/tests/Feature/OpsUx/TerminalNotificationIdempotencyTest.php @@ -13,7 +13,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory_sync', diff --git a/apps/platform/tests/Feature/PermissionPosture/GeneratePermissionPostureFindingsJobTest.php b/apps/platform/tests/Feature/PermissionPosture/GeneratePermissionPostureFindingsJobTest.php index 3de1cb05..68f9b4d6 100644 --- a/apps/platform/tests/Feature/PermissionPosture/GeneratePermissionPostureFindingsJobTest.php +++ b/apps/platform/tests/Feature/PermissionPosture/GeneratePermissionPostureFindingsJobTest.php @@ -7,7 +7,7 @@ use App\Models\Finding; use App\Models\OperationRun; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\PermissionPosture\FindingGeneratorContract; use App\Support\OperationCatalog; use App\Support\OperationRunOutcome; @@ -42,7 +42,7 @@ function buildJobComparison(array $permissions = [], string $overallStatus = 'mi ); $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', OperationCatalog::TYPE_PERMISSION_POSTURE_CHECK) ->first(); @@ -53,7 +53,7 @@ function buildJobComparison(array $permissions = [], string $overallStatus = 'mi // (2) Skips tenant without provider connection it('skips tenant without provider connection', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); // Ensure workspace is set $workspace = \App\Models\Workspace::factory()->create(); @@ -72,9 +72,9 @@ function buildJobComparison(array $permissions = [], string $overallStatus = 'mi app(\App\Services\OperationRunService::class), ); - expect(Finding::query()->where('tenant_id', $tenant->getKey())->count())->toBe(0) - ->and(StoredReport::query()->where('tenant_id', $tenant->getKey())->count())->toBe(0) - ->and(OperationRun::query()->where('tenant_id', $tenant->getKey())->where('type', OperationCatalog::TYPE_PERMISSION_POSTURE_CHECK)->count())->toBe(0); + expect(Finding::query()->where('managed_environment_id', $tenant->getKey())->count())->toBe(0) + ->and(StoredReport::query()->where('managed_environment_id', $tenant->getKey())->count())->toBe(0) + ->and(OperationRun::query()->where('managed_environment_id', $tenant->getKey())->where('type', OperationCatalog::TYPE_PERMISSION_POSTURE_CHECK)->count())->toBe(0); }); // (3) Records summary counts on OperationRun @@ -93,7 +93,7 @@ function buildJobComparison(array $permissions = [], string $overallStatus = 'mi ); $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', OperationCatalog::TYPE_PERMISSION_POSTURE_CHECK) ->first(); @@ -129,7 +129,7 @@ function buildJobComparison(array $permissions = [], string $overallStatus = 'mi } $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', OperationCatalog::TYPE_PERMISSION_POSTURE_CHECK) ->first(); diff --git a/apps/platform/tests/Feature/PermissionPosture/PermissionPostureFindingGeneratorTest.php b/apps/platform/tests/Feature/PermissionPosture/PermissionPostureFindingGeneratorTest.php index c6cbd5b8..c8df9e07 100644 --- a/apps/platform/tests/Feature/PermissionPosture/PermissionPostureFindingGeneratorTest.php +++ b/apps/platform/tests/Feature/PermissionPosture/PermissionPostureFindingGeneratorTest.php @@ -53,7 +53,7 @@ function errorPermission(string $key, array $features = []): array ->and($result->findingsCreated)->toBe(1); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->first(); @@ -85,7 +85,7 @@ function errorPermission(string $key, array $features = []): array missingPermission('Perm.A'), ])); - expect(Finding::query()->where('tenant_id', $tenant->getKey())->where('status', Finding::STATUS_NEW)->count())->toBe(1); + expect(Finding::query()->where('managed_environment_id', $tenant->getKey())->where('status', Finding::STATUS_NEW)->count())->toBe(1); // Second run: granted $result = $generator->generate($tenant, buildComparison([ @@ -95,7 +95,7 @@ function errorPermission(string $key, array $features = []): array expect($result->findingsResolved)->toBe(1); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->first(); @@ -111,7 +111,7 @@ function errorPermission(string $key, array $features = []): array $generator->generate($tenant, buildComparison([missingPermission('Perm.A')])); - $finding = Finding::query()->where('tenant_id', $tenant->getKey())->first(); + $finding = Finding::query()->where('managed_environment_id', $tenant->getKey())->first(); $finding->forceFill([ 'status' => Finding::STATUS_TRIAGED, 'triaged_at' => now(), @@ -140,9 +140,9 @@ function errorPermission(string $key, array $features = []): array ->and($result2->findingsCreated)->toBe(0) ->and($result2->findingsUnchanged)->toBe(1); - expect(Finding::query()->where('tenant_id', $tenant->getKey())->count())->toBe(1); + expect(Finding::query()->where('managed_environment_id', $tenant->getKey())->count())->toBe(1); - $finding = Finding::query()->where('tenant_id', $tenant->getKey())->first(); + $finding = Finding::query()->where('managed_environment_id', $tenant->getKey())->first(); expect($finding->times_seen)->toBe(2) ->and($finding->last_seen_at?->toIso8601String())->toBe('2026-02-24T11:00:00+00:00'); @@ -158,7 +158,7 @@ function errorPermission(string $key, array $features = []): array missingPermission('Perm.A', ['policy-sync', 'backup']), ])); - $finding = Finding::query()->where('tenant_id', $tenant->getKey())->firstOrFail(); + $finding = Finding::query()->where('managed_environment_id', $tenant->getKey())->firstOrFail(); $expectedDueAt = $finding->due_at?->toIso8601String(); expect($finding->sla_days)->toBe(7) @@ -197,13 +197,13 @@ function errorPermission(string $key, array $features = []): array CarbonImmutable::setTestNow(CarbonImmutable::parse('2026-02-24T10:00:00Z')); $generator->generate($tenant, buildComparison([missingPermission('Perm.A', ['policy-sync', 'backup'])])); - $initial = Finding::query()->where('tenant_id', $tenant->getKey())->first(); + $initial = Finding::query()->where('managed_environment_id', $tenant->getKey())->first(); $initialDueAt = $initial->due_at; CarbonImmutable::setTestNow(CarbonImmutable::parse('2026-02-25T10:00:00Z')); $generator->generate($tenant, buildComparison([grantedPermission('Perm.A')], 'granted')); - $finding = Finding::query()->where('tenant_id', $tenant->getKey())->first(); + $finding = Finding::query()->where('managed_environment_id', $tenant->getKey())->first(); expect($finding->status)->toBe(Finding::STATUS_RESOLVED); CarbonImmutable::setTestNow(CarbonImmutable::parse('2026-02-26T10:00:00Z')); @@ -237,7 +237,7 @@ function errorPermission(string $key, array $features = []): array expect($result->errorsRecorded)->toBe(1); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->first(); @@ -251,7 +251,7 @@ function errorPermission(string $key, array $features = []): array missingPermission('Perm.Error'), ])); - expect(Finding::query()->where('tenant_id', $tenant->getKey())->count())->toBe(2); + expect(Finding::query()->where('managed_environment_id', $tenant->getKey())->count())->toBe(2); }); // (7) Severity derivation @@ -269,7 +269,7 @@ function errorPermission(string $key, array $features = []): array ])); $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->whereNull('resolved_at') ->first(); @@ -299,7 +299,7 @@ function errorPermission(string $key, array $features = []): array expect($report)->not->toBeNull() ->and($report->report_type)->toBe(StoredReport::REPORT_TYPE_PERMISSION_POSTURE) - ->and($report->tenant_id)->toBe($tenant->getKey()) + ->and($report->managed_environment_id)->toBe($tenant->getKey()) ->and($report->payload['posture_score'])->toBe(50) ->and($report->payload['required_count'])->toBe(2) ->and($report->payload['granted_count'])->toBe(1) @@ -313,7 +313,7 @@ function errorPermission(string $key, array $features = []): array $generator = app(PermissionPostureFindingGenerator::class); $generator->generate($tenant, buildComparison([missingPermission('Perm.A')])); - expect(Finding::query()->where('tenant_id', $tenant->getKey())->where('status', Finding::STATUS_NEW)->count())->toBe(1); + expect(Finding::query()->where('managed_environment_id', $tenant->getKey())->where('status', Finding::STATUS_NEW)->count())->toBe(1); $result = $generator->generate($tenant, buildComparison([grantedPermission('Perm.A')], 'granted')); @@ -343,12 +343,12 @@ function errorPermission(string $key, array $features = []): array missingPermission('CustomPerm.ReadWrite.All', ['feature-x']), ])); - $finding = Finding::query()->where('tenant_id', $tenant->getKey())->first(); + $finding = Finding::query()->where('managed_environment_id', $tenant->getKey())->first(); expect($finding->subject_external_id)->toBe('CustomPerm.ReadWrite.All'); }); -// (12) All findings are scoped to tenant_id -it('scopes all findings to tenant_id', function (): void { +// (12) All findings are scoped to managed_environment_id +it('scopes all findings to managed_environment_id', function (): void { [$user1, $tenant1] = createUserWithTenant(); [$user2, $tenant2] = createUserWithTenant(); $generator = app(PermissionPostureFindingGenerator::class); @@ -356,8 +356,8 @@ function errorPermission(string $key, array $features = []): array $generator->generate($tenant1, buildComparison([missingPermission('Perm.A')])); $generator->generate($tenant2, buildComparison([missingPermission('Perm.A')])); - expect(Finding::query()->where('tenant_id', $tenant1->getKey())->count())->toBe(1) - ->and(Finding::query()->where('tenant_id', $tenant2->getKey())->count())->toBe(1); + expect(Finding::query()->where('managed_environment_id', $tenant1->getKey())->count())->toBe(1) + ->and(Finding::query()->where('managed_environment_id', $tenant2->getKey())->count())->toBe(1); }); // (13) subject_type and subject_external_id set correctly @@ -371,7 +371,7 @@ function errorPermission(string $key, array $features = []): array ])); $findings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->get(); @@ -392,7 +392,7 @@ function errorPermission(string $key, array $features = []): array missingPermission('Perm.B'), ])); - expect(Finding::query()->where('tenant_id', $tenant->getKey())->where('status', Finding::STATUS_NEW)->count())->toBe(2); + expect(Finding::query()->where('managed_environment_id', $tenant->getKey())->where('status', Finding::STATUS_NEW)->count())->toBe(2); // Run 2: Perm.B is no longer in the registry (only Perm.A remains) $result = $generator->generate($tenant, buildComparison([ @@ -402,7 +402,7 @@ function errorPermission(string $key, array $features = []): array expect($result->findingsResolved)->toBeGreaterThanOrEqual(1); $stale = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->whereJsonContains('evidence_jsonb->permission_key', 'Perm.B') ->first(); diff --git a/apps/platform/tests/Feature/PermissionPosture/PermissionPostureIntegrationTest.php b/apps/platform/tests/Feature/PermissionPosture/PermissionPostureIntegrationTest.php index 59d00089..4bdda6c3 100644 --- a/apps/platform/tests/Feature/PermissionPosture/PermissionPostureIntegrationTest.php +++ b/apps/platform/tests/Feature/PermissionPosture/PermissionPostureIntegrationTest.php @@ -44,7 +44,7 @@ // --- Findings --- $findings = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->get(); @@ -53,7 +53,7 @@ // --- StoredReport --- $report = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_PERMISSION_POSTURE) ->first(); @@ -65,7 +65,7 @@ // --- OperationRun --- $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', OperationCatalog::TYPE_PERMISSION_POSTURE_CHECK) ->first(); @@ -114,7 +114,7 @@ // Verify the resolved finding $resolvedFinding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->where('status', Finding::STATUS_RESOLVED) ->first(); @@ -141,7 +141,7 @@ // Verify the finding was created and has proper data for alert pipeline $finding = Finding::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('finding_type', Finding::FINDING_TYPE_PERMISSION_POSTURE) ->where('status', Finding::STATUS_NEW) ->first(); diff --git a/apps/platform/tests/Feature/PermissionPosture/StoredReportModelTest.php b/apps/platform/tests/Feature/PermissionPosture/StoredReportModelTest.php index b53aee20..9a47145d 100644 --- a/apps/platform/tests/Feature/PermissionPosture/StoredReportModelTest.php +++ b/apps/platform/tests/Feature/PermissionPosture/StoredReportModelTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\PermissionPosture\FindingGeneratorContract; use App\Services\PermissionPosture\PostureScoreCalculator; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -31,15 +31,15 @@ it('belongs to a tenant', function (): void { $report = StoredReport::factory()->create(); - expect($report->tenant)->toBeInstanceOf(Tenant::class) - ->and($report->tenant->getKey())->toBe($report->tenant_id); + expect($report->tenant)->toBeInstanceOf(ManagedEnvironment::class) + ->and($report->tenant->getKey())->toBe($report->managed_environment_id); }); it('belongs to a workspace via DerivesWorkspaceIdFromTenant', function (): void { [$user, $tenant] = createUserWithTenant(); $report = StoredReport::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); expect($report->workspace_id)->toBe($tenant->workspace_id); @@ -69,7 +69,7 @@ $generator->generate($tenant, $comparison); $report = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_PERMISSION_POSTURE) ->first(); @@ -100,7 +100,7 @@ $result = $generator->generate($tenant, $comparison); $report = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_PERMISSION_POSTURE) ->first(); @@ -116,25 +116,25 @@ // Create reports at different timestamps $first = StoredReport::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'created_at' => now()->subHours(3), ]); $second = StoredReport::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'created_at' => now()->subHours(1), ]); $third = StoredReport::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'created_at' => now(), ]); $results = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_PERMISSION_POSTURE) ->orderByDesc('created_at') ->pluck('id'); @@ -145,22 +145,22 @@ ->and($results[2])->toBe($first->getKey()); }); -it('reports queryable by tenant_id and report_type', function (): void { +it('reports queryable by managed_environment_id and report_type', function (): void { [$user, $tenantA] = createUserWithTenant(); [$user2, $tenantB] = createUserWithTenant(); StoredReport::factory()->count(2)->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, ]); StoredReport::factory()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, ]); $tenantAReports = StoredReport::query() - ->where('tenant_id', $tenantA->getKey()) + ->where('managed_environment_id', $tenantA->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_PERMISSION_POSTURE) ->count(); @@ -173,28 +173,28 @@ [$user, $tenant] = createUserWithTenant(); StoredReport::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, ]); StoredReport::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => 'compliance_summary', 'payload' => ['compliant' => 5, 'noncompliant' => 2], ]); $postureReports = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', StoredReport::REPORT_TYPE_PERMISSION_POSTURE) ->count(); $complianceReports = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('report_type', 'compliance_summary') ->count(); $allReports = StoredReport::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->count(); expect($postureReports)->toBe(1) diff --git a/apps/platform/tests/Feature/PlatformRelocation/PanelRouteSmokeTest.php b/apps/platform/tests/Feature/PlatformRelocation/PanelRouteSmokeTest.php index b3236f69..bc9a8eb6 100644 --- a/apps/platform/tests/Feature/PlatformRelocation/PanelRouteSmokeTest.php +++ b/apps/platform/tests/Feature/PlatformRelocation/PanelRouteSmokeTest.php @@ -1,7 +1,7 @@ create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant(role: 'owner'); $this->actingAs($user) diff --git a/apps/platform/tests/Feature/PolicyCaptureSnapshotIdempotencyTest.php b/apps/platform/tests/Feature/PolicyCaptureSnapshotIdempotencyTest.php index b47938c0..92de4f05 100644 --- a/apps/platform/tests/Feature/PolicyCaptureSnapshotIdempotencyTest.php +++ b/apps/platform/tests/Feature/PolicyCaptureSnapshotIdempotencyTest.php @@ -35,7 +35,7 @@ ]); expect(OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'policy.capture_snapshot') ->count())->toBe(1); diff --git a/apps/platform/tests/Feature/PolicyCaptureSnapshotQueuedTest.php b/apps/platform/tests/Feature/PolicyCaptureSnapshotQueuedTest.php index e85bb501..24f573fe 100644 --- a/apps/platform/tests/Feature/PolicyCaptureSnapshotQueuedTest.php +++ b/apps/platform/tests/Feature/PolicyCaptureSnapshotQueuedTest.php @@ -37,7 +37,7 @@ Queue::assertPushed(CapturePolicySnapshotJob::class); $run = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'policy.capture_snapshot') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/PolicySyncEnrollmentConfigurationTypeCollisionTest.php b/apps/platform/tests/Feature/PolicySyncEnrollmentConfigurationTypeCollisionTest.php index ab5ca327..a718ef86 100644 --- a/apps/platform/tests/Feature/PolicySyncEnrollmentConfigurationTypeCollisionTest.php +++ b/apps/platform/tests/Feature/PolicySyncEnrollmentConfigurationTypeCollisionTest.php @@ -1,7 +1,7 @@ 'tenant-sync-collision', - 'name' => 'Tenant Sync Collision', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-sync-collision', + 'name' => 'ManagedEnvironment Sync Collision', 'metadata' => [], 'is_current' => true, ]); @@ -23,7 +23,7 @@ // Simulate an older bug: ESP row was synced under enrollmentRestriction. $wrong = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'esp-1', 'policy_type' => 'enrollmentRestriction', 'display_name' => 'ESP Misclassified', @@ -74,9 +74,9 @@ }); test('policy sync classifies ESP items without relying on Graph isof filter', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-sync-esp-no-filter', - 'name' => 'Tenant Sync ESP No Filter', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-sync-esp-no-filter', + 'name' => 'ManagedEnvironment Sync ESP No Filter', 'metadata' => [], 'is_current' => true, ]); @@ -141,20 +141,20 @@ ]); $espIds = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'windowsEnrollmentStatusPage') ->pluck('external_id') ->all(); $restrictionIds = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'enrollmentRestriction') ->orderBy('external_id') ->pluck('external_id') ->all(); $platformRestrictionIds = Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'deviceEnrollmentPlatformRestrictionsConfiguration') ->orderBy('external_id') ->pluck('external_id') @@ -166,9 +166,9 @@ }); test('policy sync classifies enrollment configuration subtypes separately', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-sync-enrollment-subtypes', - 'name' => 'Tenant Sync Enrollment Subtypes', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-sync-enrollment-subtypes', + 'name' => 'ManagedEnvironment Sync Enrollment Subtypes', 'metadata' => [], 'is_current' => true, ]); @@ -234,19 +234,19 @@ ]); expect(Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'deviceEnrollmentLimitConfiguration') ->pluck('external_id') ->all())->toMatchArray(['limit-1']); expect(Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'deviceEnrollmentPlatformRestrictionsConfiguration') ->pluck('external_id') ->all())->toMatchArray(['platform-1']); expect(Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('policy_type', 'deviceEnrollmentNotificationConfiguration') ->pluck('external_id') ->all())->toMatchArray(['notify-1']); diff --git a/apps/platform/tests/Feature/PolicySyncServiceReportTest.php b/apps/platform/tests/Feature/PolicySyncServiceReportTest.php index 69c78ea8..b4f310c9 100644 --- a/apps/platform/tests/Feature/PolicySyncServiceReportTest.php +++ b/apps/platform/tests/Feature/PolicySyncServiceReportTest.php @@ -5,7 +5,7 @@ use App\Models\Policy; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphLogger; use App\Services\Graph\GraphResponse; @@ -13,20 +13,20 @@ use function Pest\Laravel\mock; -function tenantWithDefaultMicrosoftConnectionForPolicySyncReport(array $attributes = []): Tenant +function tenantWithDefaultMicrosoftConnectionForPolicySyncReport(array $attributes = []): ManagedEnvironment { - $tenant = Tenant::factory()->create($attributes + [ + $tenant = ManagedEnvironment::factory()->create($attributes + [ 'status' => 'active', 'app_client_id' => null, 'app_client_secret' => null, ]); $connection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', - 'entra_tenant_id' => (string) ($tenant->tenant_id ?: 'tenant-'.$tenant->getKey()), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?: 'tenant-'.$tenant->getKey()), ]); ProviderCredential::factory()->create([ @@ -81,7 +81,7 @@ function tenantWithDefaultMicrosoftConnectionForPolicySyncReport(array $attribut expect($result['failures'])->toBeArray(); expect(count($result['synced']))->toBe(1); - expect(Policy::query()->where('tenant_id', $tenant->id)->count())->toBe(1); + expect(Policy::query()->where('managed_environment_id', $tenant->id)->count())->toBe(1); expect(count($result['failures']))->toBe(1); expect($result['failures'][0]['policy_type'])->toBe('endpointSecurityPolicy'); diff --git a/apps/platform/tests/Feature/PolicySyncServiceTest.php b/apps/platform/tests/Feature/PolicySyncServiceTest.php index 1e18a588..feaec8a6 100644 --- a/apps/platform/tests/Feature/PolicySyncServiceTest.php +++ b/apps/platform/tests/Feature/PolicySyncServiceTest.php @@ -4,7 +4,7 @@ use App\Models\PolicyVersion; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphLogger; use App\Services\Graph\GraphResponse; @@ -12,20 +12,20 @@ use function Pest\Laravel\mock; -function tenantWithDefaultMicrosoftConnectionForPolicySync(array $attributes = []): Tenant +function tenantWithDefaultMicrosoftConnectionForPolicySync(array $attributes = []): ManagedEnvironment { - $tenant = Tenant::factory()->create($attributes + [ + $tenant = ManagedEnvironment::factory()->create($attributes + [ 'status' => 'active', 'app_client_id' => null, 'app_client_secret' => null, ]); $connection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', - 'entra_tenant_id' => (string) ($tenant->tenant_id ?: 'tenant-'.$tenant->getKey()), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?: 'tenant-'.$tenant->getKey()), ]); ProviderCredential::factory()->create([ @@ -44,7 +44,7 @@ function tenantWithDefaultMicrosoftConnectionForPolicySync(array $attributes = [ $tenant = tenantWithDefaultMicrosoftConnectionForPolicySync(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'appProtectionPolicy', 'ignored_at' => null, @@ -144,7 +144,7 @@ function tenantWithDefaultMicrosoftConnectionForPolicySync(array $attributes = [ ['type' => 'windowsDriverUpdateProfile', 'platform' => 'windows'], ]); - expect(Policy::query()->where('tenant_id', $tenant->id)->where('policy_type', 'windowsDriverUpdateProfile')->count()) + expect(Policy::query()->where('managed_environment_id', $tenant->id)->where('policy_type', 'windowsDriverUpdateProfile')->count()) ->toBe(1); }); @@ -193,7 +193,7 @@ function tenantWithDefaultMicrosoftConnectionForPolicySync(array $attributes = [ ['type' => 'managedDeviceAppConfiguration', 'platform' => 'mobile'], ]); - expect(Policy::query()->where('tenant_id', $tenant->id)->where('policy_type', 'managedDeviceAppConfiguration')->count()) + expect(Policy::query()->where('managed_environment_id', $tenant->id)->where('policy_type', 'managedDeviceAppConfiguration')->count()) ->toBe(1); }); @@ -267,13 +267,13 @@ function tenantWithDefaultMicrosoftConnectionForPolicySync(array $attributes = [ 'securityBaselinePolicy', ]); - expect(Policy::query()->where('tenant_id', $tenant->id)->where('policy_type', 'settingsCatalogPolicy')->count()) + expect(Policy::query()->where('managed_environment_id', $tenant->id)->where('policy_type', 'settingsCatalogPolicy')->count()) ->toBe(1); - expect(Policy::query()->where('tenant_id', $tenant->id)->where('policy_type', 'endpointSecurityPolicy')->count()) + expect(Policy::query()->where('managed_environment_id', $tenant->id)->where('policy_type', 'endpointSecurityPolicy')->count()) ->toBe(1); - expect(Policy::query()->where('tenant_id', $tenant->id)->where('policy_type', 'securityBaselinePolicy')->count()) + expect(Policy::query()->where('managed_environment_id', $tenant->id)->where('policy_type', 'securityBaselinePolicy')->count()) ->toBe(1); }); @@ -281,7 +281,7 @@ function tenantWithDefaultMicrosoftConnectionForPolicySync(array $attributes = [ $tenant = tenantWithDefaultMicrosoftConnectionForPolicySync(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'esp-1', 'policy_type' => 'settingsCatalogPolicy', 'platform' => 'windows', @@ -290,7 +290,7 @@ function tenantWithDefaultMicrosoftConnectionForPolicySync(array $attributes = [ ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'policy_type' => 'settingsCatalogPolicy', 'platform' => 'windows', @@ -336,14 +336,14 @@ function tenantWithDefaultMicrosoftConnectionForPolicySync(array $attributes = [ ]); expect(Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('external_id', 'esp-1') ->whereNull('ignored_at') ->whereNull('missing_from_provider_at') ->count())->toBe(1); expect(Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('external_id', 'esp-1') ->where('policy_type', 'endpointSecurityPolicy') ->whereNull('ignored_at') @@ -351,7 +351,7 @@ function tenantWithDefaultMicrosoftConnectionForPolicySync(array $attributes = [ ->count())->toBe(1); expect(Policy::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('external_id', 'esp-1') ->where('policy_type', 'settingsCatalogPolicy') ->whereNotNull('missing_from_provider_at') diff --git a/apps/platform/tests/Feature/PolicySyncStartSurfaceTest.php b/apps/platform/tests/Feature/PolicySyncStartSurfaceTest.php index ea42e853..90623633 100644 --- a/apps/platform/tests/Feature/PolicySyncStartSurfaceTest.php +++ b/apps/platform/tests/Feature/PolicySyncStartSurfaceTest.php @@ -44,7 +44,7 @@ function getPolicyEmptyStateAction(Testable $component, string $name): ?Action sort($requestedTypes); $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'policy.sync') ->latest('id') ->first(); @@ -84,7 +84,7 @@ function getPolicyEmptyStateAction(Testable $component, string $name): ?Action Queue::assertPushed(SyncPoliciesJob::class, 1); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'policy.sync') ->count())->toBe(1); }); @@ -100,7 +100,7 @@ function getPolicyEmptyStateAction(Testable $component, string $name): ?Action Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'ignored_at' => null, ]); @@ -109,7 +109,7 @@ function getPolicyEmptyStateAction(Testable $component, string $name): ?Action ->assertHasNoTableActionErrors(); $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'policy.sync_one') ->latest('id') ->first(); @@ -141,7 +141,7 @@ function getPolicyEmptyStateAction(Testable $component, string $name): ?Action Filament::setTenant($tenant, true); $policies = Policy::factory()->count(2)->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'ignored_at' => null, ]); @@ -157,7 +157,7 @@ function getPolicyEmptyStateAction(Testable $component, string $name): ?Action ->all(); $run = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'policy.sync') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/PolicyTypes017Test.php b/apps/platform/tests/Feature/PolicyTypes017Test.php index 2d475d88..3d1cbdf9 100644 --- a/apps/platform/tests/Feature/PolicyTypes017Test.php +++ b/apps/platform/tests/Feature/PolicyTypes017Test.php @@ -4,7 +4,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -95,28 +95,28 @@ public function request(string $method, string $path, array $options = []): Grap } it('creates backup items for the new 017 policy types', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $tenant->makeCurrent(); $user = User::factory()->create(); $this->actingAs($user); $mam = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'mam-1', 'policy_type' => 'mamAppConfiguration', 'platform' => 'mobile', ]); $esp = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'esp-1', 'policy_type' => 'endpointSecurityPolicy', 'platform' => 'windows', ]); $sb = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'sb-1', 'policy_type' => 'securityBaselinePolicy', 'platform' => 'windows', @@ -157,7 +157,7 @@ public function request(string $method, string $path, array $options = []): Grap }; $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'snapshot' => $snapshot, 'assignments' => null, @@ -207,16 +207,16 @@ public function request(string $method, string $path, array $options = []): Grap it('uses configured restore modes in preview for the new 017 policy types', function () { $this->mock(GraphClientInterface::class); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'status' => 'completed', 'item_count' => 3, ]); BackupItem::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'mam-1', @@ -229,7 +229,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); BackupItem::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'esp-1', @@ -243,7 +243,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); BackupItem::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'sb-1', diff --git a/apps/platform/tests/Feature/PolicyVersionViewAssignmentsTest.php b/apps/platform/tests/Feature/PolicyVersionViewAssignmentsTest.php index 916a078e..796ba902 100644 --- a/apps/platform/tests/Feature/PolicyVersionViewAssignmentsTest.php +++ b/apps/platform/tests/Feature/PolicyVersionViewAssignmentsTest.php @@ -2,16 +2,16 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; beforeEach(function () { putenv('INTUNE_TENANT_ID'); unset($_ENV['INTUNE_TENANT_ID'], $_SERVER['INTUNE_TENANT_ID']); - $this->tenant = Tenant::factory()->create(); + $this->tenant = ManagedEnvironment::factory()->create(); $this->policy = Policy::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, ]); $this->user = User::factory()->create(); [$this->user, $this->tenant] = createUserWithTenant($this->tenant, $this->user, role: 'owner'); @@ -19,7 +19,7 @@ it('displays policy version page', function () { $version = PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_id' => $this->policy->id, 'version_number' => 1, ]); @@ -36,7 +36,7 @@ it('displays assignments widget when version has assignments', function () { $version = PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_id' => $this->policy->id, 'version_number' => 1, 'assignments' => [ @@ -85,7 +85,7 @@ it('displays empty state when version has no assignments', function () { $version = PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_id' => $this->policy->id, 'version_number' => 1, 'assignments' => null, @@ -104,7 +104,7 @@ it('shows empty assignments message when assignments were fetched', function () { $version = PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_id' => $this->policy->id, 'version_number' => 1, 'assignments' => null, @@ -127,12 +127,12 @@ it('shows a dedicated RBAC explanation instead of a Graph error for role definitions', function () { $policy = Policy::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_type' => 'intuneRoleDefinition', ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => 'intuneRoleDefinition', @@ -159,7 +159,7 @@ it('shows compliance notifications when present', function () { $version = PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_id' => $this->policy->id, 'version_number' => 1, 'policy_type' => 'deviceCompliancePolicy', @@ -194,7 +194,7 @@ it('uses a default label when compliance rule name is missing', function () { $version = PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_id' => $this->policy->id, 'version_number' => 1, 'policy_type' => 'deviceCompliancePolicy', @@ -229,7 +229,7 @@ it('renders structured normalized settings for compliance policy versions', function () { $version = PolicyVersion::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_id' => $this->policy->id, 'version_number' => 1, 'policy_type' => 'deviceCompliancePolicy', diff --git a/apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareAuthorizationTest.php b/apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareAuthorizationTest.php index b9847d95..1fee2f38 100644 --- a/apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareAuthorizationTest.php +++ b/apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareAuthorizationTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\CrossTenantComparePage; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -49,7 +49,7 @@ it('returns 404 when the requested target tenant is outside the actor scope', function (): void { $fixture = $this->makeCrossTenantCompareFixture(); - $hiddenTarget = Tenant::factory()->create([ + $hiddenTarget = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $fixture['workspace']->getKey(), 'name' => 'Hidden Target', ]); diff --git a/apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareLaunchContextTest.php b/apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareLaunchContextTest.php index e95c9513..332f8d05 100644 --- a/apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareLaunchContextTest.php +++ b/apps/platform/tests/Feature/PortfolioCompare/CrossTenantCompareLaunchContextTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\TenantResource; use App\Jobs\Operations\CrossTenantPromotionExecutionJob; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Auth\CapabilityResolver; use App\Services\Auth\WorkspaceCapabilityResolver; use App\Support\Auth\Capabilities; @@ -31,8 +31,8 @@ function crossTenantCompareLaunchQuery(string $url): array } it('launches cross-tenant compare from the tenant registry with target prefill and return context', function (): void { - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Tenant'); - $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor ManagedEnvironment'); + $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target ManagedEnvironment'); $backupSet = $this->seedPortfolioBackupConcern($targetTenant, TenantBackupHealthAssessment::POSTURE_STALE); $this->seedPortfolioRecoveryConcern($targetTenant, RestoreResultAttention::STATE_COMPLETED_WITH_FOLLOW_UP, $backupSet); @@ -57,7 +57,7 @@ function crossTenantCompareLaunchQuery(string $url): array 'target_tenant_id' => (string) $targetTenant->getKey(), ]) ->and(data_get($query, 'nav.source_surface'))->toBe('tenant_registry') - ->and(data_get($query, 'nav.tenant_id'))->toBe((string) $targetTenant->getKey()) + ->and(data_get($query, 'nav.managed_environment_id'))->toBe((string) $targetTenant->getKey()) ->and(data_get($query, 'nav.back_label'))->toBe('Back to tenant registry') ->and($backUrl)->toContain('backup_posture[0]='.TenantBackupHealthAssessment::POSTURE_STALE) ->and($backUrl)->toContain('recovery_evidence[0]='.TenantRecoveryTriagePresentation::RECOVERY_EVIDENCE_WEAKENED) @@ -74,8 +74,8 @@ function crossTenantCompareLaunchQuery(string $url): array }); it('launches cross-tenant compare from an exact-two bulk selection with both tenants prefilled', function (): void { - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Tenant'); - $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor ManagedEnvironment'); + $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target ManagedEnvironment'); $anchorBackupSet = $this->seedPortfolioBackupConcern($anchorTenant, TenantBackupHealthAssessment::POSTURE_STALE); $this->seedPortfolioRecoveryConcern($anchorTenant, RestoreResultAttention::STATE_COMPLETED_WITH_FOLLOW_UP, $anchorBackupSet); @@ -111,7 +111,7 @@ function crossTenantCompareLaunchQuery(string $url): array ]) ->and(data_get($query, 'nav.source_surface'))->toBe('tenant_registry') ->and(data_get($query, 'nav.back_label'))->toBe('Back to tenant registry') - ->and(data_get($query, 'nav.tenant_id'))->toBeNull() + ->and(data_get($query, 'nav.managed_environment_id'))->toBeNull() ->and($backUrl)->toContain('backup_posture[0]='.TenantBackupHealthAssessment::POSTURE_STALE) ->and($backUrl)->toContain('recovery_evidence[0]='.TenantRecoveryTriagePresentation::RECOVERY_EVIDENCE_WEAKENED) ->and($backUrl)->toContain('triage_sort='.TenantRecoveryTriagePresentation::TRIAGE_SORT_WORST_FIRST); @@ -128,10 +128,10 @@ function crossTenantCompareLaunchQuery(string $url): array Queue::fake(); [$user, $anchorTenant] = $this->makePortfolioTriageActor( - tenantName: 'Anchor Tenant', + tenantName: 'Anchor ManagedEnvironment', workspaceRole: 'owner', ); - $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target Tenant'); + $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target ManagedEnvironment'); createMinimalUserWithTenant( tenant: $targetTenant, user: $user, @@ -199,9 +199,9 @@ function crossTenantCompareLaunchQuery(string $url): array }); it('rejects the bulk compare action until exactly two active tenants are selected', function (): void { - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Tenant'); - $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target Tenant'); - $thirdTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Third Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor ManagedEnvironment'); + $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target ManagedEnvironment'); + $thirdTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Third ManagedEnvironment'); $this->portfolioTriageRegistryList($user, $anchorTenant) ->selectTableRecords([$anchorTenant]) @@ -217,11 +217,11 @@ function crossTenantCompareLaunchQuery(string $url): array }); it('rejects the bulk compare action when a selected tenant is not active', function (): void { - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Tenant'); - $onboardingTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Onboarding Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor ManagedEnvironment'); + $onboardingTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Onboarding ManagedEnvironment'); $onboardingTenant->forceFill([ - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ])->save(); $this->portfolioTriageRegistryList($user, $anchorTenant) @@ -232,8 +232,8 @@ function crossTenantCompareLaunchQuery(string $url): array }); it('hides the compare launch action when workspace baseline view capability is missing', function (): void { - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Tenant'); - $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor ManagedEnvironment'); + $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target ManagedEnvironment'); $resolver = \Mockery::mock(WorkspaceCapabilityResolver::class); $resolver->shouldReceive('isMember')->andReturnTrue(); @@ -245,14 +245,14 @@ function crossTenantCompareLaunchQuery(string $url): array }); it('hides the compare launch action when the actor lacks tenant view on the launched tenant', function (): void { - [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor Tenant'); - $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target Tenant'); + [$user, $anchorTenant] = $this->makePortfolioTriageActor('Anchor ManagedEnvironment'); + $targetTenant = $this->makePortfolioTriagePeer($user, $anchorTenant, 'Target ManagedEnvironment'); $resolver = \Mockery::mock(CapabilityResolver::class); $resolver->shouldReceive('primeMemberships')->andReturnNull(); $resolver->shouldReceive('isMember')->andReturnTrue(); $resolver->shouldReceive('can')->andReturnUsing(function (mixed $actor, mixed $tenant, string $capability) use ($targetTenant): bool { - if ($tenant instanceof Tenant + if ($tenant instanceof ManagedEnvironment && (int) $tenant->getKey() === (int) $targetTenant->getKey() && $capability === Capabilities::TENANT_VIEW) { return false; diff --git a/apps/platform/tests/Feature/PortfolioCompare/CrossTenantPromotionExecutionAuditTest.php b/apps/platform/tests/Feature/PortfolioCompare/CrossTenantPromotionExecutionAuditTest.php index 8a536e75..7acd6b3f 100644 --- a/apps/platform/tests/Feature/PortfolioCompare/CrossTenantPromotionExecutionAuditTest.php +++ b/apps/platform/tests/Feature/PortfolioCompare/CrossTenantPromotionExecutionAuditTest.php @@ -102,7 +102,7 @@ ->once() ->andReturnUsing(function ($tenant, $backupSet, array $selectedItemIds) { return RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'requested_items' => $selectedItemIds, 'results' => [ diff --git a/apps/platform/tests/Feature/PortfolioCompare/CrossTenantPromotionExecutionAuthorizationTest.php b/apps/platform/tests/Feature/PortfolioCompare/CrossTenantPromotionExecutionAuthorizationTest.php index b5dbea31..c26ec15e 100644 --- a/apps/platform/tests/Feature/PortfolioCompare/CrossTenantPromotionExecutionAuthorizationTest.php +++ b/apps/platform/tests/Feature/PortfolioCompare/CrossTenantPromotionExecutionAuthorizationTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\CrossTenantComparePage; use App\Models\OperationRun; use App\Models\OperationalControlActivation; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Auth\CapabilityResolver; use App\Support\PortfolioCompare\CrossTenantComparePreviewBuilder; use App\Support\PortfolioCompare\CrossTenantCompareSelection; @@ -89,7 +89,7 @@ snapshot: ['settings' => [['key' => 'stale', 'value' => 1]]], ); - $staleTarget = Tenant::factory()->create([ + $staleTarget = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $fixture['workspace']->getKey(), 'name' => 'Stale Target', ]); @@ -163,7 +163,7 @@ it('returns 404 and does not queue a promotion run when the requested target tenant is outside the actor scope', function (): void { $fixture = $this->makeCrossTenantCompareFixture(); - $hiddenTarget = Tenant::factory()->create([ + $hiddenTarget = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $fixture['workspace']->getKey(), 'name' => 'Hidden Promotion Target', ]); diff --git a/apps/platform/tests/Feature/ProviderConnections/AuthorizationSemanticsTest.php b/apps/platform/tests/Feature/ProviderConnections/AuthorizationSemanticsTest.php index 450af020..d159b561 100644 --- a/apps/platform/tests/Feature/ProviderConnections/AuthorizationSemanticsTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/AuthorizationSemanticsTest.php @@ -3,15 +3,15 @@ declare(strict_types=1); use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; it('enforces 404 for non-members and 403 for missing manage capability on mutations', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', ]); @@ -25,6 +25,6 @@ [$readonly] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $this->actingAs($readonly) - ->get('/admin/provider-connections/create?tenant_id='.(string) $tenant->external_id) + ->get('/admin/provider-connections/create?managed_environment_id='.(string) $tenant->external_id) ->assertForbidden(); }); diff --git a/apps/platform/tests/Feature/ProviderConnections/CapabilityForbiddenTest.php b/apps/platform/tests/Feature/ProviderConnections/CapabilityForbiddenTest.php index fe36b3a4..2c3eae86 100644 --- a/apps/platform/tests/Feature/ProviderConnections/CapabilityForbiddenTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/CapabilityForbiddenTest.php @@ -13,7 +13,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', ]); diff --git a/apps/platform/tests/Feature/ProviderConnections/CredentialLeakGuardTest.php b/apps/platform/tests/Feature/ProviderConnections/CredentialLeakGuardTest.php index b7ac6caa..56f0c77e 100644 --- a/apps/platform/tests/Feature/ProviderConnections/CredentialLeakGuardTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/CredentialLeakGuardTest.php @@ -13,7 +13,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', diff --git a/apps/platform/tests/Feature/ProviderConnections/DisabledActionsTooltipTest.php b/apps/platform/tests/Feature/ProviderConnections/DisabledActionsTooltipTest.php index ab03a234..de9290ce 100644 --- a/apps/platform/tests/Feature/ProviderConnections/DisabledActionsTooltipTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/DisabledActionsTooltipTest.php @@ -14,7 +14,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'is_enabled' => false, 'provider' => 'microsoft', ]); diff --git a/apps/platform/tests/Feature/ProviderConnections/LegacyRedirectTest.php b/apps/platform/tests/Feature/ProviderConnections/LegacyRedirectTest.php index 008d9a80..7e1931d7 100644 --- a/apps/platform/tests/Feature/ProviderConnections/LegacyRedirectTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/LegacyRedirectTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; @@ -12,29 +12,29 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', ]); $this->actingAs($user) ->get('/admin/tenants/'.$tenant->external_id.'/provider-connections') ->assertStatus(302) - ->assertRedirect('/admin/provider-connections?tenant_id='.$tenant->external_id); + ->assertRedirect('/admin/provider-connections?managed_environment_id='.$tenant->external_id); $this->actingAs($user) ->get('/admin/tenants/'.$tenant->external_id.'/provider-connections/create') ->assertStatus(302) - ->assertRedirect('/admin/provider-connections/create?tenant_id='.$tenant->external_id); + ->assertRedirect('/admin/provider-connections/create?managed_environment_id='.$tenant->external_id); $this->actingAs($user) ->get('/admin/tenants/'.$tenant->external_id.'/provider-connections/'.$connection->getKey().'/edit') ->assertStatus(302) - ->assertRedirect('/admin/provider-connections/'.$connection->getKey().'/edit?tenant_id='.$tenant->external_id); + ->assertRedirect('/admin/provider-connections/'.$connection->getKey().'/edit?managed_environment_id='.$tenant->external_id); }); it('redirects non-workspace-members on legacy routes', function (): void { $user = User::factory()->create(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $this->actingAs($user) ->get('/admin/tenants/'.$tenant->external_id.'/provider-connections') @@ -42,8 +42,8 @@ }); it('returns 404 without location header for non-tenant members on legacy routes', function (): void { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); diff --git a/apps/platform/tests/Feature/ProviderConnections/ManageCapabilityEnforcementTest.php b/apps/platform/tests/Feature/ProviderConnections/ManageCapabilityEnforcementTest.php index 352b7a19..9bc6e2af 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ManageCapabilityEnforcementTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/ManageCapabilityEnforcementTest.php @@ -9,12 +9,12 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', ]); $this->actingAs($user) - ->get('/admin/provider-connections/create?tenant_id='.(string) $tenant->external_id) + ->get('/admin/provider-connections/create?managed_environment_id='.(string) $tenant->external_id) ->assertForbidden(); $this->actingAs($user) diff --git a/apps/platform/tests/Feature/ProviderConnections/MvpProviderScopeTest.php b/apps/platform/tests/Feature/ProviderConnections/MvpProviderScopeTest.php index 648795f5..c72a585f 100644 --- a/apps/platform/tests/Feature/ProviderConnections/MvpProviderScopeTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/MvpProviderScopeTest.php @@ -25,7 +25,7 @@ ->assertHasNoFormErrors(); $created = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('display_name', 'MVP Scope Connection') ->first(); diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderComplianceSnapshotJobTest.php b/apps/platform/tests/Feature/ProviderConnections/ProviderComplianceSnapshotJobTest.php index eac9f0bd..81c9d5d8 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderComplianceSnapshotJobTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderComplianceSnapshotJobTest.php @@ -51,7 +51,7 @@ public function request(string $method, string $path, array $options = []): Grap [$user, $tenant] = createUserWithTenant(role: 'operator'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), ]); @@ -65,7 +65,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'compliance.snapshot', diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionAuthorizationSpec081Test.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionAuthorizationSpec081Test.php index af6aa3e0..786d23bf 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionAuthorizationSpec081Test.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionAuthorizationSpec081Test.php @@ -4,17 +4,17 @@ use App\Filament\Resources\ProviderConnectionResource; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; it('Spec081 returns 404 for non-members on provider connection management routes', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', ]); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); @@ -32,7 +32,7 @@ [$user, $tenant] = createUserWithTenant(role: 'readonly'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php index 800b8212..1de9e74e 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php @@ -2,7 +2,7 @@ use App\Filament\Resources\ProviderConnectionResource; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceMembership; use App\Support\Workspaces\WorkspaceContext; @@ -11,7 +11,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'display_name' => 'Contoso', ]); @@ -36,7 +36,7 @@ $createPath = parse_url($createUrl, PHP_URL_PATH) ?: $createUrl; $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); $this->actingAs($user) @@ -64,7 +64,7 @@ $createPath = parse_url($createUrl, PHP_URL_PATH) ?: $createUrl; $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); $this->actingAs($user) @@ -86,12 +86,12 @@ }); test('provider connection edit is not accessible cross-tenant', function () { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); $connectionB = ProviderConnection::factory()->create([ - 'tenant_id' => $tenantB->getKey(), - 'display_name' => 'Tenant B Connection', + 'managed_environment_id' => $tenantB->getKey(), + 'display_name' => 'ManagedEnvironment B Connection', ]); $user = User::factory()->create(); @@ -113,12 +113,12 @@ }); test('provider connection view is not accessible cross-tenant', function () { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); $connectionB = ProviderConnection::factory()->create([ - 'tenant_id' => $tenantB->getKey(), - 'display_name' => 'Tenant B Connection', + 'managed_environment_id' => $tenantB->getKey(), + 'display_name' => 'ManagedEnvironment B Connection', ]); $user = User::factory()->create(); diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionCutoverSpec081Test.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionCutoverSpec081Test.php index 17a3103f..731be08b 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionCutoverSpec081Test.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionCutoverSpec081Test.php @@ -4,7 +4,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\ProviderOperationStartGate; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; @@ -13,7 +13,7 @@ use Illuminate\Support\Facades\DB; it('Spec081 blocks provider operation starts when default connection is missing', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $dispatched = 0; $result = app(ProviderOperationStartGate::class)->start( @@ -35,10 +35,10 @@ }); it('Spec081 blocks provider operation starts when default connection has no credential', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', @@ -59,12 +59,12 @@ }); it('Spec081 returns deterministic invalid reason when data corruption creates multiple defaults', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); DB::statement('DROP INDEX IF EXISTS provider_connections_default_unique'); $first = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', @@ -74,7 +74,7 @@ ]); $second = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionDedicatedAuthorizationTest.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionDedicatedAuthorizationTest.php index 6915ddd0..f4f002dd 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionDedicatedAuthorizationTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionDedicatedAuthorizationTest.php @@ -14,7 +14,7 @@ $connection = ProviderConnection::factory()->platform()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', ]); @@ -32,7 +32,7 @@ $connection = ProviderConnection::factory()->platform()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', ]); @@ -53,7 +53,7 @@ $connection = ProviderConnection::factory()->platform()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', ]); diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionDefaultInvariantSpec081Test.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionDefaultInvariantSpec081Test.php index ae083f3a..5cc4cff2 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionDefaultInvariantSpec081Test.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionDefaultInvariantSpec081Test.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Support\Facades\DB; it('Spec081 keeps the partial unique default index for provider connections', function (): void { @@ -27,16 +27,16 @@ }); it('Spec081 makeDefault preserves one default per tenant and provider', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $first = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, ]); $second = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => false, ]); @@ -44,7 +44,7 @@ $second->makeDefault(); $defaults = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('is_default', true) ->pluck('id') diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php index 03db9c53..65b65f74 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php @@ -20,7 +20,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'is_enabled' => false, @@ -36,7 +36,7 @@ $connection->refresh(); $audit = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.enabled') ->latest('id') ->first(); @@ -63,7 +63,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'is_enabled' => false, @@ -84,7 +84,7 @@ $connection->refresh(); $audit = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.enabled') ->latest('id') ->first(); @@ -108,7 +108,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'is_enabled' => true, @@ -121,7 +121,7 @@ $connection->refresh(); $audit = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', 'provider_connection.disabled') ->latest('id') ->first(); @@ -139,13 +139,13 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckJobTest.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckJobTest.php index fdbe3644..3bd335b9 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckJobTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckJobTest.php @@ -51,7 +51,7 @@ public function request(string $method, string $path, array $options = []): Grap [$user, $tenant] = createUserWithTenant(role: 'operator'); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'is_enabled' => true, @@ -67,7 +67,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', @@ -157,7 +157,7 @@ public function request(string $method, string $path, array $options = []): Grap [$user, $tenant] = createUserWithTenant(role: 'operator'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'is_enabled' => true, @@ -174,7 +174,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', @@ -270,7 +270,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'is_enabled' => true, @@ -287,7 +287,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', @@ -361,7 +361,7 @@ public function request(string $method, string $path, array $options = []): Grap [$user, $tenant] = createUserWithTenant(role: 'operator'); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'is_enabled' => true, @@ -377,7 +377,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php index efa0df1f..eca22fb2 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php @@ -29,7 +29,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'is_enabled' => true, @@ -39,7 +39,7 @@ ->callTableAction('check_connection', $connection); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); @@ -75,7 +75,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'is_enabled' => true, @@ -87,7 +87,7 @@ $component->callTableAction('check_connection', $connection); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'provider.connection.check') ->count())->toBe(1); @@ -104,7 +104,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->platform()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'is_enabled' => true, @@ -117,5 +117,5 @@ ->assertTableActionDisabled('compliance_snapshot', $connection); Queue::assertNothingPushed(); - expect(OperationRun::query()->where('tenant_id', $tenant->getKey())->count())->toBe(0); + expect(OperationRun::query()->where('managed_environment_id', $tenant->getKey())->count())->toBe(0); }); diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionMigrationClassificationTest.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionMigrationClassificationTest.php index 73ca65ab..a542eb87 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionMigrationClassificationTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionMigrationClassificationTest.php @@ -4,7 +4,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Providers\ProviderCredentialKind; use App\Support\Providers\ProviderCredentialSource; use App\Support\Providers\ProviderReasonCodes; @@ -16,32 +16,32 @@ config()->set('graph.client_id', 'platform-client-id'); config()->set('graph.client_secret', 'platform-client-secret'); - $platformTenant = Tenant::factory()->create([ - 'tenant_id' => 'platform-classification-tenant-id', + $platformTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'platform-classification-tenant-id', 'app_client_id' => null, 'app_client_secret' => null, ]); $platformConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ - 'tenant_id' => (int) $platformTenant->getKey(), + 'managed_environment_id' => (int) $platformTenant->getKey(), 'workspace_id' => (int) $platformTenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'platform-classification-tenant-id', - 'is_default' => true, + 'is_default' => false, ]); - $dedicatedTenant = Tenant::factory()->create([ - 'tenant_id' => 'dedicated-classification-tenant-id', + $dedicatedTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'dedicated-classification-tenant-id', 'app_client_id' => null, 'app_client_secret' => null, ]); $dedicatedConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ - 'tenant_id' => (int) $dedicatedTenant->getKey(), + 'managed_environment_id' => (int) $dedicatedTenant->getKey(), 'workspace_id' => (int) $dedicatedTenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'dedicated-classification-tenant-id', - 'is_default' => true, + 'is_default' => false, ]); $dedicatedCredential = ProviderCredential::factory()->create([ @@ -54,14 +54,14 @@ ], ]); - $hybridTenant = Tenant::factory()->create([ - 'tenant_id' => 'hybrid-classification-tenant-id', + $hybridTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'hybrid-classification-tenant-id', 'app_client_id' => 'legacy-tenant-client-id', 'app_client_secret' => 'legacy-tenant-client-secret', ]); $hybridConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ - 'tenant_id' => (int) $hybridTenant->getKey(), + 'managed_environment_id' => (int) $hybridTenant->getKey(), 'workspace_id' => (int) $hybridTenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'hybrid-classification-tenant-id', diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionNeutralitySpec238Test.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionNeutralitySpec238Test.php index 9227d9bb..f57565c5 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionNeutralitySpec238Test.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionNeutralitySpec238Test.php @@ -15,20 +15,20 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Neutral connection', 'entra_tenant_id' => '44444444-4444-4444-4444-444444444444', ]); $this->actingAs($user) - ->get(ProviderConnectionResource::getUrl('create', ['tenant_id' => $tenant->external_id], panel: 'admin')) + ->get(ProviderConnectionResource::getUrl('create', ['managed_environment_id' => $tenant->external_id], panel: 'admin')) ->assertOk() ->assertSee('Target scope ID') ->assertSee('Target scope') ->assertDontSee('Entra tenant ID'); $this->actingAs($user) - ->get(ProviderConnectionResource::getUrl('edit', ['record' => $connection, 'tenant_id' => $tenant->external_id], panel: 'admin')) + ->get(ProviderConnectionResource::getUrl('edit', ['record' => $connection, 'managed_environment_id' => $tenant->external_id], panel: 'admin')) ->assertOk() ->assertSee('Target scope ID') ->assertSee('Target scope') @@ -40,7 +40,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Scope-visible connection', 'entra_tenant_id' => '55555555-5555-5555-5555-555555555555', 'consent_status' => 'granted', @@ -63,7 +63,7 @@ ->and($table->getColumn('entra_tenant_id')?->getLabel())->toBe('Microsoft tenant ID'); $this->actingAs($user) - ->get(ProviderConnectionResource::getUrl('view', ['record' => $connection, 'tenant_id' => $tenant->external_id], panel: 'admin')) + ->get(ProviderConnectionResource::getUrl('view', ['record' => $connection, 'managed_environment_id' => $tenant->external_id], panel: 'admin')) ->assertOk() ->assertSee('Target scope') ->assertSee('Provider identity details') @@ -96,7 +96,7 @@ $connection = ProviderConnection::factory()->consentGranted()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'contoso', 'display_name' => 'Unsupported provider connection', 'entra_tenant_id' => '66666666-6666-6666-6666-666666666666', diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php index 20976e0a..88726753 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php @@ -18,7 +18,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Contoso', 'provider' => 'microsoft', 'is_default' => true, @@ -53,7 +53,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Truthful Connection', 'provider' => 'microsoft', 'is_default' => true, @@ -83,7 +83,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Editable Truthful Connection', 'provider' => 'microsoft', 'is_default' => true, @@ -113,7 +113,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Unknown Verification Connection', 'provider' => 'microsoft', 'is_default' => true, @@ -145,7 +145,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Disabled But Consented', 'provider' => 'microsoft', 'is_default' => true, @@ -164,14 +164,12 @@ ->assertSee('Disabled') ->assertSee('Granted') ->assertSee('Healthy') - ->assertDontSee('Connected') - ->assertDontSee('OK'); + ->assertDontSee('Connected'); $this->get(ProviderConnectionResource::getUrl('view', ['record' => $connection], tenant: $tenant)) ->assertOk() ->assertSee('Disabled') ->assertSee('Granted') ->assertSee('Healthy') - ->assertDontSee('Connected') - ->assertDontSee('OK'); + ->assertDontSee('Connected'); }); diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionViewsDbOnlyRenderingSpec081Test.php b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionViewsDbOnlyRenderingSpec081Test.php index 0cd6d7e2..11bf5050 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionViewsDbOnlyRenderingSpec081Test.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderConnectionViewsDbOnlyRenderingSpec081Test.php @@ -12,7 +12,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Spec081 Connection', 'provider' => 'microsoft', 'is_enabled' => true, @@ -57,7 +57,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); TenantPermission::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'permission_key' => 'DeviceManagementConfiguration.ReadWrite.All', 'status' => 'granted', 'details' => ['source' => 'spec081-test'], diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderCredentialSecurityTest.php b/apps/platform/tests/Feature/ProviderConnections/ProviderCredentialSecurityTest.php index 24d8e20a..c1408d7f 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderCredentialSecurityTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderCredentialSecurityTest.php @@ -9,7 +9,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); $this->actingAs($user); diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderDispatchGateStartSurfaceTest.php b/apps/platform/tests/Feature/ProviderConnections/ProviderDispatchGateStartSurfaceTest.php index 8e0dc0f1..ab5659e1 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderDispatchGateStartSurfaceTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderDispatchGateStartSurfaceTest.php @@ -25,7 +25,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -36,14 +36,14 @@ $component->callTableAction('compliance_snapshot', $connection); $inventoryRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'inventory.sync') ->latest('id') ->first(); expect($inventoryRun)->not->toBeNull(); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'compliance.snapshot') ->count())->toBe(0); @@ -66,7 +66,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'consent_status' => 'granted', 'is_default' => true, @@ -76,7 +76,7 @@ ->callTableAction('check_connection', $connection); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderGatewayRuntimeSmokeSpec081Test.php b/apps/platform/tests/Feature/ProviderConnections/ProviderGatewayRuntimeSmokeSpec081Test.php index 9fd7de15..d6ddb67e 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderGatewayRuntimeSmokeSpec081Test.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderGatewayRuntimeSmokeSpec081Test.php @@ -8,7 +8,7 @@ use App\Models\Policy; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -25,14 +25,14 @@ uses(RefreshDatabase::class); /** - * @return array{tenant: Tenant, connection: ProviderConnection, client_id: string, client_secret: string} + * @return array{tenant: ManagedEnvironment, connection: ProviderConnection, client_id: string, client_secret: string} */ function spec081TenantWithDefaultMicrosoftConnection(string $tenantId): array { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ - 'tenant_id' => $tenantId, + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => $tenantId, 'status' => 'active', 'app_client_id' => null, 'app_client_secret' => null, @@ -40,7 +40,7 @@ function spec081TenantWithDefaultMicrosoftConnection(string $tenantId): array ]); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'is_default' => true, @@ -95,7 +95,7 @@ function spec081TenantWithDefaultMicrosoftConnection(string $tenantId): array ]; $opRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $setup['tenant']->getKey(), + 'managed_environment_id' => (int) $setup['tenant']->getKey(), 'workspace_id' => (int) $setup['tenant']->workspace_id, 'type' => OperationRunType::InventorySync->value, ]); @@ -143,7 +143,7 @@ function spec081TenantWithDefaultMicrosoftConnection(string $tenantId): array $setup = spec081TenantWithDefaultMicrosoftConnection('tenant-spec081-snapshot'); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $setup['tenant']->getKey(), + 'managed_environment_id' => (int) $setup['tenant']->getKey(), 'external_id' => 'cfg-snapshot-spec081', 'policy_type' => 'deviceConfiguration', 'platform' => 'windows', @@ -181,12 +181,12 @@ function spec081TenantWithDefaultMicrosoftConnection(string $tenantId): array $setup = spec081TenantWithDefaultMicrosoftConnection('tenant-spec081-restore'); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $setup['tenant']->getKey(), + 'managed_environment_id' => (int) $setup['tenant']->getKey(), 'status' => 'completed', ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $setup['tenant']->getKey(), + 'managed_environment_id' => (int) $setup['tenant']->getKey(), 'external_id' => 'cfg-restore-spec081', 'policy_type' => 'deviceConfiguration', 'platform' => 'windows', @@ -194,7 +194,7 @@ function spec081TenantWithDefaultMicrosoftConnection(string $tenantId): array ]); $backupItem = BackupItem::factory()->create([ - 'tenant_id' => (int) $setup['tenant']->getKey(), + 'managed_environment_id' => (int) $setup['tenant']->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_identifier' => 'cfg-restore-spec081', diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderOperationBlockedGuidanceSpec081Test.php b/apps/platform/tests/Feature/ProviderConnections/ProviderOperationBlockedGuidanceSpec081Test.php index 8a650088..2e120f9f 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderOperationBlockedGuidanceSpec081Test.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderOperationBlockedGuidanceSpec081Test.php @@ -23,7 +23,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'consent_status' => 'granted', 'is_default' => true, @@ -33,7 +33,7 @@ ->callTableAction('check_connection', $connection); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); @@ -72,7 +72,7 @@ ->callAction('verify'); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/ProviderConnections/ProviderOperationConcurrencyTest.php b/apps/platform/tests/Feature/ProviderConnections/ProviderOperationConcurrencyTest.php index 53e6eb12..25d15f6d 100644 --- a/apps/platform/tests/Feature/ProviderConnections/ProviderOperationConcurrencyTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/ProviderOperationConcurrencyTest.php @@ -31,7 +31,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -42,7 +42,7 @@ $component->callTableAction('inventory_sync', $connection); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'inventory.sync') ->latest('id') ->first(); @@ -58,7 +58,7 @@ ]); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'inventory.sync') ->count())->toBe(1); @@ -84,7 +84,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -95,7 +95,7 @@ ->callAction('inventory_sync'); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'inventory.sync') ->latest('id') ->first(); @@ -132,7 +132,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -143,7 +143,7 @@ $component->callTableAction('compliance_snapshot', $connection); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'compliance.snapshot') ->latest('id') ->first(); @@ -159,7 +159,7 @@ ]); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'compliance.snapshot') ->count())->toBe(1); @@ -176,7 +176,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -188,7 +188,7 @@ $component->callTableAction('compliance_snapshot', $connection); $inventoryRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'inventory.sync') ->latest('id') ->first(); @@ -196,7 +196,7 @@ expect($inventoryRun)->not->toBeNull(); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'compliance.snapshot') ->count())->toBe(0); diff --git a/apps/platform/tests/Feature/ProviderConnections/RecordAccessNotFoundTest.php b/apps/platform/tests/Feature/ProviderConnections/RecordAccessNotFoundTest.php index a58aea51..34dbe82e 100644 --- a/apps/platform/tests/Feature/ProviderConnections/RecordAccessNotFoundTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/RecordAccessNotFoundTest.php @@ -3,11 +3,11 @@ declare(strict_types=1); use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; it('returns 404 for direct provider connection record access by non-tenant members', function (): void { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -15,7 +15,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenantB->workspace_id, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'provider' => 'microsoft', ]); diff --git a/apps/platform/tests/Feature/ProviderConnections/RequiredFiltersTest.php b/apps/platform/tests/Feature/ProviderConnections/RequiredFiltersTest.php index 5c091072..97f580d1 100644 --- a/apps/platform/tests/Feature/ProviderConnections/RequiredFiltersTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/RequiredFiltersTest.php @@ -12,7 +12,7 @@ $defaultConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Default Connection', 'provider' => 'microsoft', 'is_default' => true, @@ -20,7 +20,7 @@ $nonDefaultConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Non Default Connection', 'provider' => 'microsoft', 'is_default' => false, diff --git a/apps/platform/tests/Feature/ProviderConnections/TenantFilterOverrideTest.php b/apps/platform/tests/Feature/ProviderConnections/TenantFilterOverrideTest.php index 68929c88..6b2ca626 100644 --- a/apps/platform/tests/Feature/ProviderConnections/TenantFilterOverrideTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/TenantFilterOverrideTest.php @@ -4,12 +4,12 @@ use App\Filament\Resources\ProviderConnectionResource\Pages\ListProviderConnections; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Livewire\Livewire; -it('uses tenant_id query override for authorized tenants', function (): void { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create([ +it('uses managed_environment_id query override for authorized tenants', function (): void { + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -18,28 +18,28 @@ ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'display_name' => 'A Connection', 'provider' => 'microsoft', ]); ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenantB->workspace_id, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'display_name' => 'B Connection', 'provider' => 'microsoft', ]); $this->actingAs($user) - ->get('/admin/provider-connections?tenant_id='.(string) $tenantB->external_id) + ->get('/admin/provider-connections?managed_environment_id='.(string) $tenantB->external_id) ->assertOk() ->assertSee('B Connection') ->assertDontSee('A Connection'); }); -it('returns empty list for unauthorized tenant_id query override', function (): void { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create([ +it('returns empty list for unauthorized managed_environment_id query override', function (): void { + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -47,28 +47,28 @@ ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'display_name' => 'A Connection', 'provider' => 'microsoft', ]); ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenantB->workspace_id, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'display_name' => 'B Connection', 'provider' => 'microsoft', ]); $this->actingAs($user) - ->get('/admin/provider-connections?tenant_id='.(string) $tenantB->external_id) + ->get('/admin/provider-connections?managed_environment_id='.(string) $tenantB->external_id) ->assertOk() ->assertDontSee('A Connection') ->assertDontSee('B Connection'); }); it('keeps composed list filters inside the authorized tenant override scope', function (): void { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -77,7 +77,7 @@ $tenantAConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'display_name' => 'A Connected', 'provider' => 'microsoft', 'consent_status' => 'granted', @@ -86,7 +86,7 @@ $tenantBConnected = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenantB->workspace_id, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'display_name' => 'B Connected', 'provider' => 'microsoft', 'consent_status' => 'granted', @@ -95,7 +95,7 @@ $tenantBFailed = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenantB->workspace_id, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'display_name' => 'B Failed', 'provider' => 'microsoft', 'consent_status' => 'granted', @@ -105,7 +105,7 @@ $this->actingAs($user); Livewire::withQueryParams([ - 'tenant_id' => (string) $tenantB->external_id, + 'managed_environment_id' => (string) $tenantB->external_id, ])->test(ListProviderConnections::class) ->filterTable('verification_status', 'healthy') ->assertCanSeeTableRecords([$tenantBConnected]) diff --git a/apps/platform/tests/Feature/ProviderConnections/TenantlessListScopingTest.php b/apps/platform/tests/Feature/ProviderConnections/TenantlessListScopingTest.php index c494032f..9d1d3a32 100644 --- a/apps/platform/tests/Feature/ProviderConnections/TenantlessListScopingTest.php +++ b/apps/platform/tests/Feature/ProviderConnections/TenantlessListScopingTest.php @@ -3,11 +3,11 @@ declare(strict_types=1); use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; it('scopes canonical provider connections list by tenant membership', function (): void { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -15,21 +15,21 @@ ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'tenant_id' => (int) $tenantA->getKey(), - 'display_name' => 'Tenant A Connection', + 'managed_environment_id' => (int) $tenantA->getKey(), + 'display_name' => 'ManagedEnvironment A Connection', 'provider' => 'microsoft', ]); ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenantB->workspace_id, - 'tenant_id' => (int) $tenantB->getKey(), - 'display_name' => 'Tenant B Connection', + 'managed_environment_id' => (int) $tenantB->getKey(), + 'display_name' => 'ManagedEnvironment B Connection', 'provider' => 'microsoft', ]); $this->actingAs($user) ->get('/admin/provider-connections') ->assertOk() - ->assertSee('Tenant A Connection') - ->assertDontSee('Tenant B Connection'); + ->assertSee('ManagedEnvironment A Connection') + ->assertDontSee('ManagedEnvironment B Connection'); }); diff --git a/apps/platform/tests/Feature/Providers/MicrosoftGraphOptionsResolverTest.php b/apps/platform/tests/Feature/Providers/MicrosoftGraphOptionsResolverTest.php index 939e6cad..18c7274c 100644 --- a/apps/platform/tests/Feature/Providers/MicrosoftGraphOptionsResolverTest.php +++ b/apps/platform/tests/Feature/Providers/MicrosoftGraphOptionsResolverTest.php @@ -2,7 +2,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\MicrosoftGraphOptionsResolver; use App\Services\Providers\ProviderConfigurationRequiredException; use App\Support\Providers\ProviderReasonCodes; @@ -11,7 +11,7 @@ uses(RefreshDatabase::class); it('throws when no default provider connection exists', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $resolver = app(MicrosoftGraphOptionsResolver::class); @@ -29,10 +29,10 @@ }); it('throws when default provider connection needs consent', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'provider' => 'microsoft', 'is_default' => true, @@ -53,10 +53,10 @@ }); it('builds graph options from default provider connection credentials', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'entra-tenant-id', diff --git a/apps/platform/tests/Feature/Providers/ProviderBoundaryHardeningTest.php b/apps/platform/tests/Feature/Providers/ProviderBoundaryHardeningTest.php index d913564d..ffa771e4 100644 --- a/apps/platform/tests/Feature/Providers/ProviderBoundaryHardeningTest.php +++ b/apps/platform/tests/Feature/Providers/ProviderBoundaryHardeningTest.php @@ -2,7 +2,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Providers\MicrosoftGraphOptionsResolver; @@ -12,9 +12,9 @@ uses(RefreshDatabase::class); it('preserves current Microsoft-backed gateway runtime behavior through the provider-owned seam', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'entra-tenant-id', @@ -83,9 +83,9 @@ public function request(string $method, string $path, array $options = []): Grap }); it('preserves Microsoft graph option resolution for default provider connections', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'default-entra-tenant-id', diff --git a/apps/platform/tests/Feature/Providers/UnsupportedProviderBoundaryPathTest.php b/apps/platform/tests/Feature/Providers/UnsupportedProviderBoundaryPathTest.php index d335d771..a782ff83 100644 --- a/apps/platform/tests/Feature/Providers/UnsupportedProviderBoundaryPathTest.php +++ b/apps/platform/tests/Feature/Providers/UnsupportedProviderBoundaryPathTest.php @@ -1,7 +1,7 @@ create(); + $tenant = ManagedEnvironment::factory()->create(); ProviderConnection::factory()->dedicated()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'entra-tenant-id', diff --git a/apps/platform/tests/Feature/Rbac/ActionSurfaceRbacSemanticsTest.php b/apps/platform/tests/Feature/Rbac/ActionSurfaceRbacSemanticsTest.php index 82ca55cf..63ed8e14 100644 --- a/apps/platform/tests/Feature/Rbac/ActionSurfaceRbacSemanticsTest.php +++ b/apps/platform/tests/Feature/Rbac/ActionSurfaceRbacSemanticsTest.php @@ -9,7 +9,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -31,12 +31,12 @@ 'role' => 'owner', ]); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceB->getKey(), ]); $runB = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $workspaceB->getKey(), 'type' => 'policy.sync', 'status' => 'queued', @@ -59,7 +59,7 @@ $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $approver->getKey(), 'owner_user_id' => (int) $approver->getKey(), @@ -92,15 +92,15 @@ }); it('drops unauthorized requested tenant filters on operations instead of honoring cross-tenant query state', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $unauthorizedTenant = Tenant::factory()->create([ + $unauthorizedTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Running->value, @@ -114,22 +114,22 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); Livewire::withQueryParams([ - 'tenant_id' => (string) $unauthorizedTenant->getKey(), + 'managed_environment_id' => (string) $unauthorizedTenant->getKey(), 'activeTab' => 'active', ]) ->actingAs($user) ->test(Operations::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()) ->assertSet('activeTab', 'active'); }); it('falls back to an unselected audit history when the requested event is outside the accessible scope', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); - $foreignTenant = Tenant::factory()->create(); + $foreignTenant = ManagedEnvironment::factory()->create(); $foreignAudit = AuditLog::query()->create([ 'workspace_id' => (int) $foreignTenant->workspace_id, - 'tenant_id' => (int) $foreignTenant->getKey(), + 'managed_environment_id' => (int) $foreignTenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', @@ -156,13 +156,13 @@ it('falls back to an unselected queue state when the requested exception is outside the accessible tenant set', function (): void { [$approver, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); - $foreignTenant = Tenant::factory()->create(); + $foreignTenant = ManagedEnvironment::factory()->create(); [$foreignRequester] = createUserWithTenant(tenant: $foreignTenant, role: 'owner'); $foreignFinding = Finding::factory()->for($foreignTenant)->create(); $foreignException = FindingException::query()->create([ 'workspace_id' => (int) $foreignTenant->workspace_id, - 'tenant_id' => (int) $foreignTenant->getKey(), + 'managed_environment_id' => (int) $foreignTenant->getKey(), 'finding_id' => (int) $foreignFinding->getKey(), 'requested_by_user_id' => (int) $foreignRequester->getKey(), 'owner_user_id' => (int) $foreignRequester->getKey(), diff --git a/apps/platform/tests/Feature/Rbac/AdminGlobalSearchContextSafetyTest.php b/apps/platform/tests/Feature/Rbac/AdminGlobalSearchContextSafetyTest.php index 9ac04ee1..c5b25b0f 100644 --- a/apps/platform/tests/Feature/Rbac/AdminGlobalSearchContextSafetyTest.php +++ b/apps/platform/tests/Feature/Rbac/AdminGlobalSearchContextSafetyTest.php @@ -11,7 +11,7 @@ use App\Models\EntraGroup; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\WorkspaceIsolation\TenantOwnedModelFamilies; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -25,10 +25,10 @@ function adminGlobalSearchTitles($results): array } it('does not collapse administratively discoverable tenant results because remembered tenant context is selector-ineligible', function (): void { - $activeTenant = Tenant::factory()->active()->create(['name' => 'Search Safety Active']); + $activeTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Search Safety Active']); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, 'name' => 'Search Safety Onboarding', ]); @@ -59,10 +59,10 @@ function adminGlobalSearchTitles($results): array }); it('keeps representative first-slice admin global-search behavior aligned to the family registry postures', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); diff --git a/apps/platform/tests/Feature/Rbac/AdminTenantOwnedPolicyContextTest.php b/apps/platform/tests/Feature/Rbac/AdminTenantOwnedPolicyContextTest.php index 5994e869..eb0f7a42 100644 --- a/apps/platform/tests/Feature/Rbac/AdminTenantOwnedPolicyContextTest.php +++ b/apps/platform/tests/Feature/Rbac/AdminTenantOwnedPolicyContextTest.php @@ -5,7 +5,7 @@ use App\Models\BackupSchedule; use App\Models\EntraGroup; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Auth\Access\AuthorizationException; @@ -15,9 +15,9 @@ uses(RefreshDatabase::class); it('keeps EntraGroupPolicy scoped to the remembered canonical admin tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $groupA = EntraGroup::factory()->for($tenantA)->create(); @@ -46,13 +46,13 @@ }); it('keeps BackupSchedulePolicy scoped to the remembered canonical admin tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $scheduleA = BackupSchedule::create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'name' => 'Allowed schedule', 'is_enabled' => true, 'timezone' => 'UTC', @@ -65,7 +65,7 @@ ]); $scheduleB = BackupSchedule::create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'name' => 'Blocked schedule', 'is_enabled' => true, 'timezone' => 'UTC', @@ -100,9 +100,9 @@ }); it('keeps FindingPolicy scoped to the remembered canonical admin tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'manager'); - $tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); + $tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'manager'); $findingA = Finding::factory()->for($tenantA)->create(); @@ -131,11 +131,11 @@ }); it('keeps in-scope capability denials forbidden while wrong-tenant denials stay not found', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$readonly, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $schedule = BackupSchedule::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Readonly schedule', 'is_enabled' => true, 'timezone' => 'UTC', diff --git a/apps/platform/tests/Feature/Rbac/BackupItemsRelationManagerSemanticsTest.php b/apps/platform/tests/Feature/Rbac/BackupItemsRelationManagerSemanticsTest.php index fba9e986..ae3a9941 100644 --- a/apps/platform/tests/Feature/Rbac/BackupItemsRelationManagerSemanticsTest.php +++ b/apps/platform/tests/Feature/Rbac/BackupItemsRelationManagerSemanticsTest.php @@ -26,7 +26,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $backupItem = BackupItem::factory()->for($backupSet)->for($tenant)->create(); @@ -53,7 +53,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $backupItem = BackupItem::factory()->for($backupSet)->for($tenant)->create(); @@ -73,7 +73,7 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'role-def-1', 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -82,7 +82,7 @@ ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => 'intuneRoleDefinition', 'platform' => 'all', @@ -92,7 +92,7 @@ ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $backupItem = BackupItem::factory()->for($backupSet)->for($tenant)->create([ @@ -131,12 +131,12 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); - $foreignTenant = \App\Models\Tenant::factory()->create(); + $foreignTenant = \App\Models\ManagedEnvironment::factory()->create(); $foreignBackupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $foreignTenant->getKey(), + 'managed_environment_id' => (int) $foreignTenant->getKey(), ]); $foreignBackupItem = BackupItem::factory()->for($foreignBackupSet)->for($foreignTenant)->create(); diff --git a/apps/platform/tests/Feature/Rbac/BackupItemsRelationManagerUiEnforcementTest.php b/apps/platform/tests/Feature/Rbac/BackupItemsRelationManagerUiEnforcementTest.php index d2cc4875..58edb945 100644 --- a/apps/platform/tests/Feature/Rbac/BackupItemsRelationManagerUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Rbac/BackupItemsRelationManagerUiEnforcementTest.php @@ -26,7 +26,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', ]); @@ -53,7 +53,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', ]); @@ -77,7 +77,7 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Test backup', ]); @@ -110,15 +110,15 @@ Filament::setTenant($tenant, true); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Primary backup', ]); $inScopeItem = BackupItem::factory()->for($backupSet)->for($tenant)->create(); - $foreignTenant = \App\Models\Tenant::factory()->create(); + $foreignTenant = \App\Models\ManagedEnvironment::factory()->create(); $foreignBackupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $foreignTenant->getKey(), + 'managed_environment_id' => (int) $foreignTenant->getKey(), 'name' => 'Foreign backup', ]); $foreignBackupItem = BackupItem::factory()->for($foreignBackupSet)->for($foreignTenant)->create(); diff --git a/apps/platform/tests/Feature/Rbac/BackupQualityVisibilityTest.php b/apps/platform/tests/Feature/Rbac/BackupQualityVisibilityTest.php index a58bfeae..2a2d6e87 100644 --- a/apps/platform/tests/Feature/Rbac/BackupQualityVisibilityTest.php +++ b/apps/platform/tests/Feature/Rbac/BackupQualityVisibilityTest.php @@ -33,14 +33,14 @@ ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Readonly policy', 'policy_type' => 'settingsCatalogPolicy', 'platform' => 'windows', ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'snapshot' => [], 'metadata' => [ diff --git a/apps/platform/tests/Feature/Rbac/CreateRestoreRunAuthorizationTest.php b/apps/platform/tests/Feature/Rbac/CreateRestoreRunAuthorizationTest.php index cb96bb33..3312f780 100644 --- a/apps/platform/tests/Feature/Rbac/CreateRestoreRunAuthorizationTest.php +++ b/apps/platform/tests/Feature/Rbac/CreateRestoreRunAuthorizationTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Resources\RestoreRunResource\Pages\CreateRestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -14,7 +14,7 @@ describe('Create restore run page authorization', function () { it('returns 404 for non-members (deny as not found)', function () { $user = User::factory()->create(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $this->actingAs($user); $tenant->makeCurrent(); diff --git a/apps/platform/tests/Feature/Rbac/DashboardRecoveryPostureVisibilityTest.php b/apps/platform/tests/Feature/Rbac/DashboardRecoveryPostureVisibilityTest.php index 228e4f2f..3dd83592 100644 --- a/apps/platform/tests/Feature/Rbac/DashboardRecoveryPostureVisibilityTest.php +++ b/apps/platform/tests/Feature/Rbac/DashboardRecoveryPostureVisibilityTest.php @@ -9,7 +9,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; use App\Support\Rbac\UiTooltips; @@ -19,7 +19,7 @@ use function Pest\Laravel\mock; -function seedRecoveryVisibilityScenario(Tenant $tenant): RestoreRun +function seedRecoveryVisibilityScenario(ManagedEnvironment $tenant): RestoreRun { $backupSet = BackupSet::factory()->for($tenant)->recentCompleted()->create([ 'name' => 'Recovery visibility backup', @@ -42,7 +42,7 @@ function seedRecoveryVisibilityScenario(Tenant $tenant): RestoreRun } it('keeps recovery drillthrough inspectable for readonly tenant members', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'readonly'); $restoreRun = seedRecoveryVisibilityScenario($tenant); @@ -81,10 +81,10 @@ function seedRecoveryVisibilityScenario(Tenant $tenant): RestoreRun mock(CapabilityResolver::class, function ($mock) use ($tenant): void { $mock->shouldReceive('primeMemberships')->andReturnNull(); $mock->shouldReceive('isMember') - ->andReturnUsing(static fn ($user, Tenant $resolvedTenant): bool => (int) $resolvedTenant->getKey() === (int) $tenant->getKey()); + ->andReturnUsing(static fn ($user, ManagedEnvironment $resolvedTenant): bool => (int) $resolvedTenant->getKey() === (int) $tenant->getKey()); $mock->shouldReceive('can') - ->andReturnUsing(static function ($user, Tenant $resolvedTenant, string $capability) use ($tenant): bool { + ->andReturnUsing(static function ($user, ManagedEnvironment $resolvedTenant, string $capability) use ($tenant): bool { expect((int) $resolvedTenant->getKey())->toBe((int) $tenant->getKey()); return match ($capability) { @@ -117,8 +117,8 @@ function seedRecoveryVisibilityScenario(Tenant $tenant): RestoreRun }); it('keeps dashboard and restore-history recovery surfaces deny-as-not-found for non-members', function (): void { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'owner'); $restoreRun = seedRecoveryVisibilityScenario($tenant); diff --git a/apps/platform/tests/Feature/Rbac/DenialDiagnosticsTest.php b/apps/platform/tests/Feature/Rbac/DenialDiagnosticsTest.php index 20399c9f..59df3933 100644 --- a/apps/platform/tests/Feature/Rbac/DenialDiagnosticsTest.php +++ b/apps/platform/tests/Feature/Rbac/DenialDiagnosticsTest.php @@ -21,7 +21,7 @@ } return ($context['capability'] ?? null) === Capabilities::TENANT_MANAGE - && ($context['tenant_id'] ?? null) === (int) $tenant->getKey() + && ($context['managed_environment_id'] ?? null) === (int) $tenant->getKey() && ($context['actor_user_id'] ?? null) === (int) $user->getKey(); }) ->once(); diff --git a/apps/platform/tests/Feature/Rbac/EditProviderConnectionUiEnforcementTest.php b/apps/platform/tests/Feature/Rbac/EditProviderConnectionUiEnforcementTest.php index c76afd01..e04446a2 100644 --- a/apps/platform/tests/Feature/Rbac/EditProviderConnectionUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Rbac/EditProviderConnectionUiEnforcementTest.php @@ -16,7 +16,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'is_enabled' => false, ]); @@ -32,7 +32,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'is_enabled' => false, ]); diff --git a/apps/platform/tests/Feature/Rbac/EditTenantArchiveUiEnforcementTest.php b/apps/platform/tests/Feature/Rbac/EditTenantArchiveUiEnforcementTest.php index 48d8cd90..c8a770cc 100644 --- a/apps/platform/tests/Feature/Rbac/EditTenantArchiveUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Rbac/EditTenantArchiveUiEnforcementTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Resources\TenantResource\Pages\EditTenant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Filament\Actions\Action; use Filament\Actions\ActionGroup; use Filament\Facades\Filament; @@ -23,7 +23,7 @@ function editTenantUiHeaderActions(Testable $component): array describe('Edit tenant archive action UI enforcement', function () { it('shows archive action as visible but disabled for manager members', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant(tenant: $tenant, role: 'manager'); $this->actingAs($user); @@ -57,7 +57,7 @@ function editTenantUiHeaderActions(Testable $component): array }); it('allows owner members to archive tenant', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user); @@ -90,7 +90,7 @@ function editTenantUiHeaderActions(Testable $component): array }); it('hides the archive action once the tenant is already archived', function () { - $tenant = Tenant::factory()->archived()->create(); + $tenant = ManagedEnvironment::factory()->archived()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); $this->actingAs($user); @@ -102,7 +102,7 @@ function editTenantUiHeaderActions(Testable $component): array }); it('uses restore naming and confirmation copy for archived tenants', function () { - $tenant = Tenant::factory()->archived()->create(); + $tenant = ManagedEnvironment::factory()->archived()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); $this->actingAs($user); diff --git a/apps/platform/tests/Feature/Rbac/FilamentManageEnforcementTest.php b/apps/platform/tests/Feature/Rbac/FilamentManageEnforcementTest.php index b9918469..6be00060 100644 --- a/apps/platform/tests/Feature/Rbac/FilamentManageEnforcementTest.php +++ b/apps/platform/tests/Feature/Rbac/FilamentManageEnforcementTest.php @@ -22,7 +22,7 @@ Filament::setTenant($tenant, true); $set = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup 1', 'status' => 'completed', 'item_count' => 0, @@ -56,7 +56,7 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'ignored_at' => null, ]); @@ -67,7 +67,7 @@ 'backup_name' => 'Readonly Export', ]); - expect(OperationRun::query()->where('tenant_id', $tenant->id)->where('type', 'policy.export')->exists())->toBeFalse(); + expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->where('type', 'policy.export')->exists())->toBeFalse(); }); test('operator users cannot access the restore run wizard (create)', function () { @@ -86,14 +86,14 @@ Filament::setTenant($tenant, true); $set = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup for Restore Run', 'status' => 'completed', 'item_count' => 0, ]); $run = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $set->id, 'status' => 'completed', 'is_dry_run' => true, diff --git a/apps/platform/tests/Feature/Rbac/InventoryItemResourceAuthorizationTest.php b/apps/platform/tests/Feature/Rbac/InventoryItemResourceAuthorizationTest.php index 043565bf..ae8d1276 100644 --- a/apps/platform/tests/Feature/Rbac/InventoryItemResourceAuthorizationTest.php +++ b/apps/platform/tests/Feature/Rbac/InventoryItemResourceAuthorizationTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\InventoryItemResource\Pages\ListInventoryItems; use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Inventory\InventoryCoverage as InventoryCoveragePayload; use App\Support\Workspaces\WorkspaceContext; @@ -16,7 +16,7 @@ describe('Inventory item resource authorization', function () { it('is not visible for non-members', function () { $user = User::factory()->create(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $this->actingAs($user); $tenant->makeCurrent(); @@ -35,13 +35,13 @@ it('prevents viewing inventory items from other tenants', function () { [$user, $tenant] = createUserWithTenant(role: 'owner'); - $otherTenant = Tenant::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); $this->actingAs($user); $tenant->makeCurrent(); $record = InventoryItem::factory()->create([ - 'tenant_id' => $otherTenant->getKey(), + 'managed_environment_id' => $otherTenant->getKey(), ]); expect(InventoryItemResource::canView($record))->toBeFalse(); @@ -54,39 +54,39 @@ $tenant->makeCurrent(); $record = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), ]); expect(InventoryItemResource::canView($record))->toBeTrue(); }); it('keeps composed persisted inventory filters scoped to the active tenant', function () { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $tenantAFresh = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), - 'display_name' => 'Tenant A Fresh Windows', + 'managed_environment_id' => (int) $tenantA->getKey(), + 'display_name' => 'ManagedEnvironment A Fresh Windows', 'platform' => 'windows', 'last_seen_at' => now(), ]); $tenantAStale = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), - 'display_name' => 'Tenant A Stale Windows', + 'managed_environment_id' => (int) $tenantA->getKey(), + 'display_name' => 'ManagedEnvironment A Stale Windows', 'platform' => 'windows', 'last_seen_at' => now()->subDays(3), ]); $tenantBStale = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), - 'display_name' => 'Tenant B Stale Windows', + 'managed_environment_id' => (int) $tenantB->getKey(), + 'display_name' => 'ManagedEnvironment B Stale Windows', 'platform' => 'windows', 'last_seen_at' => now()->subDays(3), ]); @@ -109,24 +109,24 @@ }); it('keeps persisted admin inventory search and filters inside the remembered canonical tenant after tenant changes', function () { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $tenantARecord = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'display_name' => 'Shared Windows Device', 'platform' => 'windows', 'last_seen_at' => now()->subDays(3), ]); $tenantBRecord = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'display_name' => 'Shared Windows Device', 'platform' => 'windows', 'last_seen_at' => now()->subDays(3), @@ -162,11 +162,11 @@ }); it('shows coverage truth without a basis-run link for readonly members missing inventory-sync capability', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Rbac/OnboardingWizardUiEnforcementTest.php b/apps/platform/tests/Feature/Rbac/OnboardingWizardUiEnforcementTest.php index c3285f94..eb0b6652 100644 --- a/apps/platform/tests/Feature/Rbac/OnboardingWizardUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Rbac/OnboardingWizardUiEnforcementTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\TenantPermission; use App\Models\User; @@ -39,9 +39,9 @@ it('denies dedicated provider connection creation for manager members', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(); @@ -60,7 +60,7 @@ 'updated_by' => $user, 'current_step' => 'connection', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -86,9 +86,9 @@ $workspace = Workspace::factory()->create(); $user = User::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); createUserWithTenant( @@ -103,14 +103,14 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ]); TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'connection', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -121,7 +121,7 @@ $draft = TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->firstOrFail(); Livewire::actingAs($user) @@ -131,7 +131,7 @@ ->call('startVerification'); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); @@ -171,7 +171,7 @@ foreach ($permissionKeys as $key) { TenantPermission::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'permission_key' => $key, 'status' => 'granted', @@ -182,23 +182,23 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ @@ -219,8 +219,8 @@ $draft = TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), @@ -240,7 +240,7 @@ $workspace = Workspace::factory()->create(); $user = User::factory()->create(); - $tenant = Tenant::factory()->onboarding()->create([ + $tenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -256,23 +256,23 @@ $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'is_default' => true, 'consent_status' => 'granted', ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', [ @@ -298,7 +298,7 @@ 'updated_by' => $user, 'current_step' => 'bootstrap', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), diff --git a/apps/platform/tests/Feature/Rbac/PolicyVersionMaintenanceAuthorizationTest.php b/apps/platform/tests/Feature/Rbac/PolicyVersionMaintenanceAuthorizationTest.php index 4f1a51f9..8092bfd2 100644 --- a/apps/platform/tests/Feature/Rbac/PolicyVersionMaintenanceAuthorizationTest.php +++ b/apps/platform/tests/Feature/Rbac/PolicyVersionMaintenanceAuthorizationTest.php @@ -15,10 +15,10 @@ Filament::setTenant($tenant, true); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, ]); @@ -36,10 +36,10 @@ Filament::setTenant($tenant, true); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), @@ -52,7 +52,7 @@ ]); expect(OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'policy_version.prune') ->exists())->toBeFalse(); diff --git a/apps/platform/tests/Feature/Rbac/PolicyVersionsRestoreToIntuneUiEnforcementTest.php b/apps/platform/tests/Feature/Rbac/PolicyVersionsRestoreToIntuneUiEnforcementTest.php index b36d1000..2099b928 100644 --- a/apps/platform/tests/Feature/Rbac/PolicyVersionsRestoreToIntuneUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Rbac/PolicyVersionsRestoreToIntuneUiEnforcementTest.php @@ -22,11 +22,11 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'metadata' => [], ]); @@ -46,11 +46,11 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'metadata' => ['source' => 'metadata_only'], ]); @@ -70,11 +70,11 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'metadata' => [], ]); @@ -100,15 +100,15 @@ Filament::setTenant($tenant, true); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); - $foreignTenant = \App\Models\Tenant::factory()->create(); + $foreignTenant = \App\Models\ManagedEnvironment::factory()->create(); $foreignPolicy = Policy::factory()->create([ - 'tenant_id' => $foreignTenant->id, + 'managed_environment_id' => $foreignTenant->id, ]); $foreignVersion = PolicyVersion::factory()->create([ - 'tenant_id' => $foreignTenant->id, + 'managed_environment_id' => $foreignTenant->id, 'policy_id' => $foreignPolicy->id, 'metadata' => [], ]); diff --git a/apps/platform/tests/Feature/Rbac/TenantActionSurfaceConsistencyTest.php b/apps/platform/tests/Feature/Rbac/TenantActionSurfaceConsistencyTest.php index 907e237b..55f2bc96 100644 --- a/apps/platform/tests/Feature/Rbac/TenantActionSurfaceConsistencyTest.php +++ b/apps/platform/tests/Feature/Rbac/TenantActionSurfaceConsistencyTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\TenantResource\Pages\EditTenant; use App\Filament\Resources\TenantResource\Pages\ListTenants; use App\Filament\Resources\TenantResource\Pages\ViewTenant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Ui\ActionSurface\Enums\ActionSurfaceSlot; use App\Support\Workspaces\WorkspaceContext; use Filament\Actions\ActionGroup; @@ -22,7 +22,7 @@ function tenantActionSurfaceSearchTitles($results): array } it('keeps onboarding lifecycle actions consistent across list, view, and edit surfaces', function (): void { - $tenant = Tenant::factory()->onboarding()->create(); + $tenant = ManagedEnvironment::factory()->onboarding()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); createOnboardingDraft([ @@ -31,7 +31,7 @@ function tenantActionSurfaceSearchTitles($results): array 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -64,7 +64,7 @@ function tenantActionSurfaceSearchTitles($results): array }); it('keeps active lifecycle actions consistent across list, view, and edit surfaces', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -95,7 +95,7 @@ function tenantActionSurfaceSearchTitles($results): array }); it('keeps draft lifecycle actions consistent across list, view, and edit surfaces', function (): void { - $tenant = Tenant::factory()->draft()->create(); + $tenant = ManagedEnvironment::factory()->draft()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); createOnboardingDraft([ @@ -104,7 +104,7 @@ function tenantActionSurfaceSearchTitles($results): array 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -137,7 +137,7 @@ function tenantActionSurfaceSearchTitles($results): array }); it('keeps archived lifecycle actions consistent across list, view, and edit surfaces', function (): void { - $tenant = Tenant::factory()->archived()->create(); + $tenant = ManagedEnvironment::factory()->archived()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -161,18 +161,18 @@ function tenantActionSurfaceSearchTitles($results): array }); it('keeps tenant global search aligned with administrative discoverability across lifecycles', function (): void { - $active = Tenant::factory()->active()->create(['name' => 'Surface Search Active']); + $active = ManagedEnvironment::factory()->active()->create(['name' => 'Surface Search Active']); [$user, $active] = createUserWithTenant(tenant: $active, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); - $draft = Tenant::factory()->draft()->create([ + $draft = ManagedEnvironment::factory()->draft()->create([ 'workspace_id' => (int) $active->workspace_id, 'name' => 'Surface Search Draft', ]); - $onboarding = Tenant::factory()->onboarding()->create([ + $onboarding = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $active->workspace_id, 'name' => 'Surface Search Onboarding', ]); - $archived = Tenant::factory()->archived()->create([ + $archived = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $active->workspace_id, 'name' => 'Surface Search Archived', ]); @@ -199,16 +199,16 @@ function tenantActionSurfaceSearchTitles($results): array }); it('keeps list-row lifecycle actions independent from the selected header tenant context', function (): void { - $selectedTenant = Tenant::factory()->active()->create(['name' => 'Selected Header Tenant']); + $selectedTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Selected Header ManagedEnvironment']); [$user, $selectedTenant] = createUserWithTenant(tenant: $selectedTenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $selectedTenant->workspace_id, - 'name' => 'Independent Onboarding Tenant', + 'name' => 'Independent Onboarding ManagedEnvironment', ]); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $selectedTenant->workspace_id, - 'name' => 'Independent Archived Tenant', + 'name' => 'Independent Archived ManagedEnvironment', ]); createUserWithTenant(tenant: $onboardingTenant, user: $user, role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); @@ -220,7 +220,7 @@ function tenantActionSurfaceSearchTitles($results): array 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $onboardingTenant->tenant_id, + 'entra_tenant_id' => (string) $onboardingTenant->managed_environment_id, 'tenant_name' => (string) $onboardingTenant->name, ], ]); @@ -238,7 +238,7 @@ function tenantActionSurfaceSearchTitles($results): array }); it('documents the tenant row-click and More-menu contract for lifecycle actions', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); createOnboardingDraft([ @@ -248,7 +248,7 @@ function tenantActionSurfaceSearchTitles($results): array 'updated_by' => $user, 'status' => 'completed', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); diff --git a/apps/platform/tests/Feature/Rbac/TenantDashboardArrivalContextVisibilityTest.php b/apps/platform/tests/Feature/Rbac/TenantDashboardArrivalContextVisibilityTest.php index 077d0623..6fe04c05 100644 --- a/apps/platform/tests/Feature/Rbac/TenantDashboardArrivalContextVisibilityTest.php +++ b/apps/platform/tests/Feature/Rbac/TenantDashboardArrivalContextVisibilityTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\TenantDashboard; use App\Filament\Resources\RestoreRunResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; use App\Support\PortfolioTriage\PortfolioArrivalContextToken; @@ -17,7 +17,7 @@ uses(BuildsPortfolioTriageFixtures::class); -function tenantDashboardVisibilityArrivalUrl(\App\Models\Tenant $tenant): string +function tenantDashboardVisibilityArrivalUrl(\App\Models\ManagedEnvironment $tenant): string { return TenantDashboard::getUrl([ PortfolioArrivalContextToken::QUERY_PARAMETER => PortfolioArrivalContextToken::encode([ @@ -36,7 +36,7 @@ function tenantDashboardVisibilityArrivalUrl(\App\Models\Tenant $tenant): string } it('shows an actionable follow-up link for in-scope members who can open the target surface', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Visible Arrival Tenant', role: 'readonly'); + [$user, $tenant] = $this->makePortfolioTriageActor('Visible Arrival ManagedEnvironment', role: 'readonly'); $restoreRun = $this->seedPortfolioRecoveryConcern($tenant, RestoreResultAttention::STATE_FAILED); $this->actingAs($user); @@ -54,7 +54,7 @@ function tenantDashboardVisibilityArrivalUrl(\App\Models\Tenant $tenant): string }); it('keeps the arrival block truthful while degrading the CTA for in-scope members without follow-up capability', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Restricted Arrival Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Restricted Arrival ManagedEnvironment'); $restoreRun = $this->seedPortfolioRecoveryConcern($tenant, RestoreResultAttention::STATE_FAILED); $this->actingAs($user); @@ -87,8 +87,8 @@ function tenantDashboardVisibilityArrivalUrl(\App\Models\Tenant $tenant): string }); it('keeps tenant-dashboard arrival routes deny-as-not-found for non-members', function (): void { - $tenant = Tenant::factory()->create(); - [$user] = $this->makePortfolioTriageActor('Other Tenant'); + $tenant = ManagedEnvironment::factory()->create(); + [$user] = $this->makePortfolioTriageActor('Other ManagedEnvironment'); $this->seedPortfolioRecoveryConcern($tenant, RestoreResultAttention::STATE_FAILED); $this->actingAs($user); diff --git a/apps/platform/tests/Feature/Rbac/TenantLifecycleActionNamingTest.php b/apps/platform/tests/Feature/Rbac/TenantLifecycleActionNamingTest.php index bcdf77e1..b5cc155c 100644 --- a/apps/platform/tests/Feature/Rbac/TenantLifecycleActionNamingTest.php +++ b/apps/platform/tests/Feature/Rbac/TenantLifecycleActionNamingTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\TenantResource\Pages\EditTenant; use App\Filament\Resources\TenantResource\Pages\ListTenants; use App\Filament\Resources\TenantResource\Pages\ViewTenant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Actions\Action; use Filament\Facades\Filament; @@ -15,7 +15,7 @@ uses(RefreshDatabase::class); it('labels the onboarding entry action as resume onboarding when exactly one resumable draft exists', function (): void { - $tenant = Tenant::factory()->onboarding()->create(); + $tenant = ManagedEnvironment::factory()->onboarding()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); createOnboardingDraft([ @@ -24,7 +24,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -37,7 +37,7 @@ }); it('uses archive consistently across list, view, and edit surfaces', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -58,7 +58,7 @@ }); it('uses restore consistently across list, view, and edit surfaces', function (): void { - $tenant = Tenant::factory()->archived()->create(); + $tenant = ManagedEnvironment::factory()->archived()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -79,7 +79,7 @@ }); it('does not fall back to deactivate terminology on lifecycle actions', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); diff --git a/apps/platform/tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php b/apps/platform/tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php index 8b68708f..ded08a81 100644 --- a/apps/platform/tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php +++ b/apps/platform/tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\TenantResource\Pages\ListTenants; use App\Filament\Resources\TenantResource\Pages\ViewTenant; use App\Models\AuditLog; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Audit\WorkspaceAuditLogger; use App\Support\Audit\AuditActionId; use App\Support\Workspaces\WorkspaceContext; @@ -27,7 +27,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -52,12 +52,12 @@ ->firstWhere('key', 'related_onboarding')['value'] ?? null) ->toBe('Resume onboarding'); })->with([ - 'draft' => [fn (): Tenant => Tenant::factory()->draft()->create()], - 'onboarding' => [fn (): Tenant => Tenant::factory()->onboarding()->create()], + 'draft' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->draft()->create()], + 'onboarding' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create()], ]); it('shows archive only for active tenants on list and detail surfaces', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -77,7 +77,7 @@ }); it('shows restore only for archived tenants on list and detail surfaces', function (): void { - $tenant = Tenant::factory()->archived()->create(); + $tenant = ManagedEnvironment::factory()->archived()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -127,14 +127,14 @@ $view->assertActionHidden('verify'); } })->with([ - 'draft' => [fn (): Tenant => Tenant::factory()->draft()->create(), false], - 'onboarding' => [fn (): Tenant => Tenant::factory()->onboarding()->create(), false], - 'active' => [fn (): Tenant => Tenant::factory()->active()->create(), true], - 'archived' => [fn (): Tenant => Tenant::factory()->archived()->create(), false], + 'draft' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->draft()->create(), false], + 'onboarding' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create(), false], + 'active' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->active()->create(), true], + 'archived' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->archived()->create(), false], ]); it('keeps lifecycle actions visible but disabled for in-scope members without mutation capability', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'manager'); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -146,14 +146,14 @@ }); it('shows capability-denied actions as disabled but keeps lifecycle-denied actions hidden', function (): void { - $activeTenant = Tenant::factory()->active()->create([ - 'name' => 'Capability Denied Active Tenant', + $activeTenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Capability Denied Active ManagedEnvironment', ]); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'manager', ensureDefaultMicrosoftProviderConnection: false); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Lifecycle Denied Onboarding Tenant', + 'name' => 'Lifecycle Denied Onboarding ManagedEnvironment', ]); createUserWithTenant( @@ -170,7 +170,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $onboardingTenant->tenant_id, + 'entra_tenant_id' => (string) $onboardingTenant->managed_environment_id, 'tenant_name' => (string) $onboardingTenant->name, ], ]); @@ -208,17 +208,17 @@ ->get(TenantResource::getUrl('view', ['record' => $tenant])) ->assertNotFound(); })->with([ - 'draft' => [fn (): Tenant => Tenant::factory()->draft()->create()], - 'onboarding' => [fn (): Tenant => Tenant::factory()->onboarding()->create()], - 'active' => [fn (): Tenant => Tenant::factory()->active()->create()], - 'archived' => [fn (): Tenant => Tenant::factory()->archived()->create()], + 'draft' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->draft()->create()], + 'onboarding' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create()], + 'active' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->active()->create()], + 'archived' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->archived()->create()], ]); it('keeps tenant detail lifecycle actions bound to the viewed record instead of the selected header tenant', function (): void { - $selectedTenant = Tenant::factory()->active()->create(); + $selectedTenant = ManagedEnvironment::factory()->active()->create(); [$user, $selectedTenant] = createUserWithTenant(tenant: $selectedTenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $selectedTenant->workspace_id, ]); @@ -242,10 +242,10 @@ }); it('refuses lifecycle-invalid archive and restore mutations without changing tenant state', function (): void { - $activeTenant = Tenant::factory()->active()->create(); + $activeTenant = ManagedEnvironment::factory()->active()->create(); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, ]); @@ -269,7 +269,7 @@ expect($activeTenant->trashed())->toBeFalse() ->and($onboardingTenant->trashed())->toBeFalse() - ->and($onboardingTenant->status)->toBe(Tenant::STATUS_ONBOARDING) + ->and($onboardingTenant->status)->toBe(ManagedEnvironment::STATUS_ONBOARDING) ->and(AuditLog::query() ->whereIn('action', [ AuditActionId::TenantArchived->value, diff --git a/apps/platform/tests/Feature/Rbac/TenantMembershipsRelationManagerUiEnforcementTest.php b/apps/platform/tests/Feature/Rbac/TenantMembershipsRelationManagerUiEnforcementTest.php index 0dd683fe..72a5da61 100644 --- a/apps/platform/tests/Feature/Rbac/TenantMembershipsRelationManagerUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Rbac/TenantMembershipsRelationManagerUiEnforcementTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\TenantResource\Pages\EditTenant; use App\Filament\Resources\TenantResource\RelationManagers\TenantMembershipsRelationManager; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Actions\Action; use Filament\Facades\Filament; @@ -13,9 +13,9 @@ uses(RefreshDatabase::class); -describe('Tenant memberships relation manager UI enforcement', function () { +describe('ManagedEnvironment memberships relation manager UI enforcement', function () { it('shows membership actions as visible but disabled for manager members', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant(tenant: $tenant, role: 'manager'); $this->actingAs($user); diff --git a/apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php b/apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php index cde7594e..6163b219 100644 --- a/apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php +++ b/apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\TenantRequiredPermissions; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantPermission; use App\Models\User; use App\Models\Workspace; @@ -14,14 +14,14 @@ it('keeps the route tenant authoritative when tenant-like query values are present', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); - $otherTenant = Tenant::factory()->create([ + $otherTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'name' => 'Foreign Query Tenant', + 'name' => 'Foreign Query ManagedEnvironment', 'external_id' => 'foreign-query-tenant', ]); $response = $this->actingAs($user) - ->get("/admin/tenants/{$tenant->external_id}/required-permissions?tenant={$otherTenant->external_id}&tenant_id={$otherTenant->getKey()}&status=all") + ->get("/admin/tenants/{$tenant->external_id}/required-permissions?tenant={$otherTenant->external_id}&managed_environment_id={$otherTenant->getKey()}&status=all") ->assertSuccessful(); $response @@ -34,29 +34,29 @@ config()->set('intune_permissions.permissions', [ [ - 'key' => 'Tenant.Read.All', + 'key' => 'ManagedEnvironment.Read.All', 'type' => 'application', - 'description' => 'Tenant read permission', + 'description' => 'ManagedEnvironment read permission', 'features' => ['backup'], ], ]); config()->set('entra_permissions.permissions', []); TenantPermission::create([ - 'tenant_id' => (int) $tenant->getKey(), - 'permission_key' => 'Tenant.Read.All', + 'managed_environment_id' => (int) $tenant->getKey(), + 'permission_key' => 'ManagedEnvironment.Read.All', 'status' => 'granted', 'details' => ['source' => 'db'], 'last_checked_at' => now(), ]); $response = $this->actingAs($user) - ->get("/admin/tenants/{$tenant->external_id}/required-permissions?status=present&type=application&search=Tenant") + ->get("/admin/tenants/{$tenant->external_id}/required-permissions?status=present&type=application&search=ManagedEnvironment") ->assertSuccessful(); $response ->assertSee($tenant->getFilamentName()) - ->assertSee('Tenant.Read.All'); + ->assertSee('ManagedEnvironment.Read.All'); }); it('returns 404 when the current workspace no longer matches the tenant route scope', function (): void { @@ -64,7 +64,7 @@ $workspaceB = Workspace::factory()->create(); $user = User::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), 'external_id' => 'tenant-required-permissions-404', ]); @@ -92,25 +92,25 @@ it('seeds native table state from deeplink filters without letting query values redefine the route tenant', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); - $otherTenant = Tenant::factory()->create([ + $otherTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'name' => 'Ignored Query Tenant', + 'name' => 'Ignored Query ManagedEnvironment', 'external_id' => 'ignored-query-tenant', ]); config()->set('intune_permissions.permissions', [ [ - 'key' => 'Tenant.Read.All', + 'key' => 'ManagedEnvironment.Read.All', 'type' => 'application', - 'description' => 'Tenant read permission', + 'description' => 'ManagedEnvironment read permission', 'features' => ['backup'], ], ]); config()->set('entra_permissions.permissions', []); TenantPermission::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), - 'permission_key' => 'Tenant.Read.All', + 'managed_environment_id' => (int) $tenant->getKey(), + 'permission_key' => 'ManagedEnvironment.Read.All', 'status' => 'granted', 'details' => ['source' => 'db'], 'last_checked_at' => now(), @@ -122,18 +122,18 @@ $component = Livewire::withQueryParams([ 'tenant' => $tenant->external_id, - 'tenant_id' => (string) $otherTenant->getKey(), + 'managed_environment_id' => (string) $otherTenant->getKey(), 'status' => 'present', 'type' => 'application', 'features' => ['backup'], - 'search' => 'Tenant', + 'search' => 'ManagedEnvironment', ])->test(TenantRequiredPermissions::class); $component ->assertSet('tableFilters.status.value', 'present') ->assertSet('tableFilters.type.value', 'application') ->assertSet('tableFilters.features.values', ['backup']) - ->assertSet('tableSearch', 'Tenant'); + ->assertSet('tableSearch', 'ManagedEnvironment'); expect($component->instance()->currentTenant()?->is($tenant))->toBeTrue(); }); diff --git a/apps/platform/tests/Feature/Rbac/TenantResourceAuthorizationTest.php b/apps/platform/tests/Feature/Rbac/TenantResourceAuthorizationTest.php index 460e3930..358fddc6 100644 --- a/apps/platform/tests/Feature/Rbac/TenantResourceAuthorizationTest.php +++ b/apps/platform/tests/Feature/Rbac/TenantResourceAuthorizationTest.php @@ -5,13 +5,13 @@ use App\Filament\Resources\TenantResource; use App\Filament\Resources\TenantResource\Pages\ListTenants; use App\Filament\Resources\TenantResource\Pages\ViewTenant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Livewire\Livewire; -describe('Tenant resource authorization', function () { +describe('ManagedEnvironment resource authorization', function () { it('cannot be created by non-members', function () { $user = User::factory()->create(); @@ -54,7 +54,7 @@ it('cannot edit tenants it cannot access', function () { [$user] = createUserWithTenant(role: 'manager'); - $otherTenant = Tenant::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); $this->actingAs($user); @@ -63,7 +63,7 @@ it('returns not found for tenant detail pages outside the actor tenant scope', function (): void { [$user] = createUserWithTenant(role: 'owner', ensureDefaultMicrosoftProviderConnection: false); - $otherTenant = Tenant::factory()->active()->create(); + $otherTenant = ManagedEnvironment::factory()->active()->create(); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $otherTenant->workspace_id]) @@ -73,7 +73,7 @@ it('returns not found for numeric tenant detail paths outside the actor tenant scope', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner', ensureDefaultMicrosoftProviderConnection: false); - $otherTenant = Tenant::factory()->active()->create(); + $otherTenant = ManagedEnvironment::factory()->active()->create(); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) @@ -90,21 +90,21 @@ expect(TenantResource::canEdit($otherTenant))->toBeFalse() ->and(TenantResource::canDelete($otherTenant))->toBeFalse(); })->with([ - 'draft' => [fn (): Tenant => Tenant::factory()->draft()->create()], - 'onboarding' => [fn (): Tenant => Tenant::factory()->onboarding()->create()], - 'active' => [fn (): Tenant => Tenant::factory()->active()->create()], - 'archived' => [fn (): Tenant => Tenant::factory()->archived()->create()], + 'draft' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->draft()->create()], + 'onboarding' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create()], + 'active' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->active()->create()], + 'archived' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->archived()->create()], ]); it('keeps onboarding and archived tenants manageable when the actor is entitled', function () { - $onboardingTenant = Tenant::factory()->onboarding()->create(); + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create(); [$user, $onboardingTenant] = createUserWithTenant( tenant: $onboardingTenant, role: 'manager', ensureDefaultMicrosoftProviderConnection: false, ); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $onboardingTenant->workspace_id, ]); @@ -116,7 +116,7 @@ ensureDefaultMicrosoftProviderConnection: false, ); - $archivedTenant = Tenant::withTrashed()->findOrFail((int) $archivedTenant->getKey()); + $archivedTenant = ManagedEnvironment::withTrashed()->findOrFail((int) $archivedTenant->getKey()); $this->actingAs($user); @@ -127,14 +127,14 @@ }); it('keeps mutation capability checks separate from lifecycle-specific action visibility', function (): void { - $onboardingTenant = Tenant::factory()->onboarding()->create(); + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create(); [$user, $onboardingTenant] = createUserWithTenant( tenant: $onboardingTenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false, ); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $onboardingTenant->workspace_id, ]); @@ -146,7 +146,7 @@ ensureDefaultMicrosoftProviderConnection: false, ); - $archivedTenant = Tenant::withTrashed()->findOrFail((int) $archivedTenant->getKey()); + $archivedTenant = ManagedEnvironment::withTrashed()->findOrFail((int) $archivedTenant->getKey()); $this->actingAs($user); @@ -165,7 +165,7 @@ }); it('resolves archive and verify actions as enabled for owners on active tenant surfaces', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -192,7 +192,7 @@ }); it('keeps lifecycle mutation actions visible but disabled for managers without delete capability', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'manager', ensureDefaultMicrosoftProviderConnection: false); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); diff --git a/apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php b/apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php index 5a0a3dc0..ad8fbfed 100644 --- a/apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php +++ b/apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\TenantDashboard; use App\Filament\Widgets\Tenant\TenantTriageArrivalContinuity; use App\Models\AuditLog; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Models\User; use App\Support\Audit\AuditActionId; @@ -20,7 +20,7 @@ uses(BuildsPortfolioTriageFixtures::class); -function triageReviewArrivalState(Tenant $tenant): array +function triageReviewArrivalState(ManagedEnvironment $tenant): array { return [ 'sourceSurface' => PortfolioArrivalContextToken::SOURCE_TENANT_REGISTRY, @@ -35,7 +35,7 @@ function triageReviewArrivalState(Tenant $tenant): array ]; } -function triageReviewDashboardWidget(User $user, Tenant $tenant, array $state): mixed +function triageReviewDashboardWidget(User $user, ManagedEnvironment $tenant, array $state): mixed { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -48,11 +48,11 @@ function triageReviewDashboardWidget(User $user, Tenant $tenant, array $state): } it('returns 404 for non-members on the tenant dashboard triage route', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->seedPortfolioBackupConcern($tenant, TenantBackupHealthAssessment::POSTURE_STALE); - $foreignTenant = Tenant::factory()->create([ + $foreignTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenant->workspace_id, ]); @@ -67,7 +67,7 @@ function triageReviewDashboardWidget(User $user, Tenant $tenant, array $state): }); it('shows review actions as disabled for readonly members and still rejects a bypassed mutation with 403', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $this->seedPortfolioBackupConcern($tenant, TenantBackupHealthAssessment::POSTURE_STALE); @@ -111,7 +111,7 @@ function triageReviewDashboardWidget(User $user, Tenant $tenant, array $state): }); it('writes review progress and audit state only after the preview-confirmed action executes', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Authorization Success Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Authorization Success ManagedEnvironment'); $this->seedPortfolioBackupConcern($tenant, TenantBackupHealthAssessment::POSTURE_STALE); $component = triageReviewDashboardWidget($user, $tenant, triageReviewArrivalState($tenant)) @@ -126,13 +126,13 @@ function triageReviewDashboardWidget(User $user, Tenant $tenant, array $state): ->callMountedAction(); expect(TenantTriageReview::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('current_state', TenantTriageReview::STATE_FOLLOW_UP_NEEDED) ->whereNull('resolved_at') ->exists())->toBeTrue() ->and(AuditLog::query() ->where('workspace_id', (int) $tenant->workspace_id) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('action', AuditActionId::TenantTriageReviewMarkedFollowUpNeeded->value) ->exists())->toBeTrue(); diff --git a/apps/platform/tests/Feature/Rbac/UiEnforcementMemberDisabledTest.php b/apps/platform/tests/Feature/Rbac/UiEnforcementMemberDisabledTest.php index af7ed3bb..755d29c6 100644 --- a/apps/platform/tests/Feature/Rbac/UiEnforcementMemberDisabledTest.php +++ b/apps/platform/tests/Feature/Rbac/UiEnforcementMemberDisabledTest.php @@ -7,7 +7,7 @@ use Livewire\Livewire; /** - * Tests for US1: Tenant member sees consistent disabled UX + * Tests for US1: ManagedEnvironment member sees consistent disabled UX * * These tests verify that UiEnforcement correctly handles: * - Members WITH capability → action enabled, can execute diff --git a/apps/platform/tests/Feature/Rbac/UiEnforcementNonMemberHiddenTest.php b/apps/platform/tests/Feature/Rbac/UiEnforcementNonMemberHiddenTest.php index 762f66c4..ebf4f050 100644 --- a/apps/platform/tests/Feature/Rbac/UiEnforcementNonMemberHiddenTest.php +++ b/apps/platform/tests/Feature/Rbac/UiEnforcementNonMemberHiddenTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\PolicyResource\Pages\ListPolicies; use App\Filament\Resources\TenantResource\Pages\ListTenants as ListTenantsPage; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Support\Facades\Queue; @@ -34,8 +34,8 @@ }); it('hides non-member tenants from the tenant management list before lifecycle actions can be discovered', function (): void { - $visibleTenant = Tenant::factory()->active()->create(); - $hiddenTenant = Tenant::factory()->archived()->create([ + $visibleTenant = ManagedEnvironment::factory()->active()->create(); + $hiddenTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $visibleTenant->workspace_id, ]); @@ -56,8 +56,8 @@ }); it('hides sync action for users who are not members of the tenant', function () { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); // Create user with a valid workspace context, but without membership to $tenant [$user] = createUserWithTenant(tenant: $otherTenant, role: 'owner'); @@ -72,7 +72,7 @@ it('hides sync action for authenticated users accessing wrong tenant', function () { // User is member of tenantA but accessing tenantB [$user, $tenantA] = createUserWithTenant(role: 'owner'); - $tenantB = Tenant::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); // User has no membership to tenantB $this->actingAs($user) @@ -89,8 +89,8 @@ }); it('blocks action execution for non-members (no side effects)', function () { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); // Create user with a valid workspace context, but without membership to $tenant [$user] = createUserWithTenant(tenant: $otherTenant, role: 'owner'); @@ -102,7 +102,7 @@ // Verify no side effects Queue::assertNothingPushed(); - expect(OperationRun::query()->where('tenant_id', $tenant->getKey())->count())->toBe(0); + expect(OperationRun::query()->where('managed_environment_id', $tenant->getKey())->count())->toBe(0); }); }); @@ -140,7 +140,7 @@ // Verify no side effects Queue::assertNothingPushed(); - expect(OperationRun::query()->where('tenant_id', $tenant->getKey())->count())->toBe(0); + expect(OperationRun::query()->where('managed_environment_id', $tenant->getKey())->count())->toBe(0); }); it('hides action in UI after membership revocation on re-render', function () { diff --git a/apps/platform/tests/Feature/ReclassifyEnrollmentConfigurationsCommandTest.php b/apps/platform/tests/Feature/ReclassifyEnrollmentConfigurationsCommandTest.php index 918a91d8..a782e9f3 100644 --- a/apps/platform/tests/Feature/ReclassifyEnrollmentConfigurationsCommandTest.php +++ b/apps/platform/tests/Feature/ReclassifyEnrollmentConfigurationsCommandTest.php @@ -2,7 +2,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use Carbon\CarbonImmutable; @@ -12,9 +12,9 @@ uses(RefreshDatabase::class); test('reclassify command moves ESP versions out of enrollmentRestriction', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-reclassify', - 'name' => 'Tenant Reclassify', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-reclassify', + 'name' => 'ManagedEnvironment Reclassify', 'metadata' => [], 'is_current' => true, ]); @@ -22,7 +22,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'esp-1', 'policy_type' => 'enrollmentRestriction', 'display_name' => 'ESP Misclassified', @@ -30,7 +30,7 @@ ]); $version = PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => 'enrollmentRestriction', @@ -44,7 +44,7 @@ ], ]); - $this->artisan('intune:reclassify-enrollment-configurations', ['--tenant' => $tenant->tenant_id]) + $this->artisan('intune:reclassify-enrollment-configurations', ['--tenant' => $tenant->managed_environment_id]) ->assertSuccessful(); $version->refresh(); @@ -53,7 +53,7 @@ expect($version->policy_type)->toBe('enrollmentRestriction'); expect($policy->policy_type)->toBe('enrollmentRestriction'); - $this->artisan('intune:reclassify-enrollment-configurations', ['--tenant' => $tenant->tenant_id, '--write' => true]) + $this->artisan('intune:reclassify-enrollment-configurations', ['--tenant' => $tenant->managed_environment_id, '--write' => true]) ->assertSuccessful(); $version->refresh(); @@ -65,9 +65,9 @@ }); test('reclassify command can detect ESP even when a policy has no versions', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-reclassify-no-versions', - 'name' => 'Tenant Reclassify (No Versions)', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-reclassify-no-versions', + 'name' => 'ManagedEnvironment Reclassify (No Versions)', 'metadata' => [], 'is_current' => true, ]); @@ -75,7 +75,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'esp-2', 'policy_type' => 'enrollmentRestriction', 'display_name' => 'ESP Misclassified (No Versions)', @@ -93,13 +93,13 @@ ])); }); - $this->artisan('intune:reclassify-enrollment-configurations', ['--tenant' => $tenant->tenant_id]) + $this->artisan('intune:reclassify-enrollment-configurations', ['--tenant' => $tenant->managed_environment_id]) ->assertSuccessful(); $policy->refresh(); expect($policy->policy_type)->toBe('enrollmentRestriction'); - $this->artisan('intune:reclassify-enrollment-configurations', ['--tenant' => $tenant->tenant_id, '--write' => true]) + $this->artisan('intune:reclassify-enrollment-configurations', ['--tenant' => $tenant->managed_environment_id, '--write' => true]) ->assertSuccessful(); $policy->refresh(); @@ -108,9 +108,9 @@ }); test('reclassify command marks duplicate wrong rows provider missing instead of ignored', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-reclassify-duplicate', - 'name' => 'Tenant Reclassify Duplicate', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-reclassify-duplicate', + 'name' => 'ManagedEnvironment Reclassify Duplicate', 'metadata' => [], 'is_current' => true, ]); @@ -118,7 +118,7 @@ $tenant->makeCurrent(); $wrong = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'esp-duplicate', 'policy_type' => 'enrollmentRestriction', 'display_name' => 'ESP Duplicate Wrong', @@ -126,7 +126,7 @@ ]); Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'esp-duplicate', 'policy_type' => 'windowsEnrollmentStatusPage', 'display_name' => 'ESP Duplicate Correct', @@ -134,7 +134,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $wrong->id, 'version_number' => 1, 'policy_type' => 'enrollmentRestriction', @@ -148,7 +148,7 @@ ], ]); - $this->artisan('intune:reclassify-enrollment-configurations', ['--tenant' => $tenant->tenant_id, '--write' => true]) + $this->artisan('intune:reclassify-enrollment-configurations', ['--tenant' => $tenant->managed_environment_id, '--write' => true]) ->assertSuccessful(); $wrong->refresh(); diff --git a/apps/platform/tests/Feature/Reports/ProductTelemetryReportCaptureTest.php b/apps/platform/tests/Feature/Reports/ProductTelemetryReportCaptureTest.php index efe30435..adc872a6 100644 --- a/apps/platform/tests/Feature/Reports/ProductTelemetryReportCaptureTest.php +++ b/apps/platform/tests/Feature/Reports/ProductTelemetryReportCaptureTest.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\ProductUsageEvent; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\EntraAdminRoles\EntraAdminRolesReportService; use App\Services\EntraAdminRoles\HighPrivilegeRoleCatalog; use App\Services\Graph\GraphClientInterface; @@ -101,7 +101,7 @@ function buildTelemetryReportService(): EntraAdminRolesReportService } it('records telemetry when a user-initiated Entra admin roles report is created', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); ensureDefaultProviderConnection($tenant); @@ -129,7 +129,7 @@ function buildTelemetryReportService(): EntraAdminRolesReportService }); it('records telemetry when a user-initiated permission posture report is created', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $run = OperationRun::factory()->forTenant($tenant)->create([ @@ -166,7 +166,7 @@ function buildTelemetryReportService(): EntraAdminRolesReportService }); it('records telemetry when a user requests a review pack generation', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); seedTenantReviewEvidence($tenant); diff --git a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php index 93d4e4c5..3655d0c1 100644 --- a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php +++ b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -19,7 +19,7 @@ it('returns 404 for workspace members without tenant entitlement on the canonical route', function (): void { $user = User::factory()->create(); $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -40,7 +40,7 @@ it('returns 404 for non-workspace-members with stale session', function (): void { $user = User::factory()->create(); $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -55,7 +55,7 @@ it('returns 404 when the route tenant is invalid instead of falling back to the current tenant context', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); - Tenant::query()->whereKey((int) $tenant->getKey())->update(['is_current' => true]); + ManagedEnvironment::query()->whereKey((int) $tenant->getKey())->update(['is_current' => true]); $this->actingAs($user) ->get('/admin/tenants/invalid-tenant-id/required-permissions') diff --git a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsCopyActionsTest.php b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsCopyActionsTest.php index 851c2dcb..cefc698b 100644 --- a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsCopyActionsTest.php +++ b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsCopyActionsTest.php @@ -2,10 +2,10 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; it('renders guidance, admin consent link, re-run verification, and copy actions on the required permissions page', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'external_id' => 'tenant-copy-actions-a', 'app_client_id' => null, ]); diff --git a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsFiltersTest.php b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsFiltersTest.php index 909996d5..84b6308f 100644 --- a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsFiltersTest.php +++ b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsFiltersTest.php @@ -33,7 +33,7 @@ config()->set('entra_permissions.permissions', []); TenantPermission::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'permission_key' => 'Alpha.Read.All', 'status' => 'granted', 'details' => ['source' => 'db'], @@ -41,7 +41,7 @@ ]); TenantPermission::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'permission_key' => 'Beta.Read.All', 'status' => 'granted', 'details' => ['source' => 'db'], @@ -49,7 +49,7 @@ ]); TenantPermission::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'permission_key' => 'Gamma.Manage.All', 'status' => 'granted', 'details' => ['source' => 'db'], diff --git a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsOverviewTest.php b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsOverviewTest.php index 916f18f1..80b735d6 100644 --- a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsOverviewTest.php +++ b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsOverviewTest.php @@ -18,7 +18,7 @@ } TenantPermission::create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'permission_key' => $grantedKey, 'status' => 'granted', 'details' => ['source' => 'db'], diff --git a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsSidebarTest.php b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsSidebarTest.php index 9bf79f10..ae20a97f 100644 --- a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsSidebarTest.php +++ b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsSidebarTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -41,7 +41,7 @@ $response->assertOk(); - // Tenant-scoped nav groups/items must NOT appear + // ManagedEnvironment-scoped nav groups/items must NOT appear $response->assertDontSee('>Inventory', false); $response->assertDontSee('>Backups & Restore', false); }); @@ -58,7 +58,7 @@ $response->assertSee('Operations', false); $response->assertSee('Audit Log', false); - // Tenant nav absent + // ManagedEnvironment nav absent $response->assertDontSee('>Directory', false); $response->assertDontSee('>Governance', false); }); @@ -66,7 +66,7 @@ it('returns 404 for non-workspace-members with stale session (FR-002 regression guard)', function (): void { $user = User::factory()->create(); $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -82,7 +82,7 @@ it('returns 404 for workspace members without tenant entitlement after middleware change (FR-002 regression guard)', function (): void { $user = User::factory()->create(); $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -120,7 +120,7 @@ $response->assertOk(); - // Tenant-scoped nav groups MUST be present on tenant pages (Inventory group) + // ManagedEnvironment-scoped nav groups MUST be present on tenant pages (Inventory group) $response->assertSee('Inventory', false); }); @@ -155,7 +155,7 @@ // Workspace nav present (sidebar fix working) $response->assertSee('Operations', false); - // Tenant nav absent (sidebar fix working) + // ManagedEnvironment nav absent (sidebar fix working) $response->assertDontSee('>Inventory', false); }); @@ -163,14 +163,14 @@ $workspace = Workspace::factory()->create(); $user = User::factory()->create(); - $currentTenant = Tenant::factory()->create([ + $currentTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'name' => 'YPTW2', 'environment' => 'dev', 'status' => 'active', ]); - $routedTenant = Tenant::factory()->create([ + $routedTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'name' => 'Phoenicon', 'environment' => 'dev', diff --git a/apps/platform/tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php b/apps/platform/tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php index 5444396a..d0acceb6 100644 --- a/apps/platform/tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php +++ b/apps/platform/tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php @@ -13,7 +13,7 @@ use App\Models\PlatformUser; use App\Models\Policy; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\Audit\AuditActionId; @@ -35,10 +35,10 @@ function seedOperationalRestoreExecutionContext(bool $withProviderConnection = t { $workspace ??= Workspace::factory()->create(['name' => 'Restore Workspace']); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => fake()->uuid(), - 'name' => 'Restore Tenant', + 'managed_environment_id' => fake()->uuid(), + 'name' => 'Restore ManagedEnvironment', 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), ]); @@ -50,7 +50,7 @@ function seedOperationalRestoreExecutionContext(bool $withProviderConnection = t } $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => fake()->uuid(), 'policy_type' => 'deviceConfiguration', 'display_name' => 'Restore Policy', @@ -58,14 +58,14 @@ function seedOperationalRestoreExecutionContext(bool $withProviderConnection = t ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Restore Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -119,7 +119,7 @@ function seedOperationalRestoreExecutionContext(bool $withProviderConnection = t ->fillForm([ 'is_dry_run' => false, 'acknowledged_impact' => true, - 'tenant_confirm' => 'Restore Tenant', + 'tenant_confirm' => 'Restore ManagedEnvironment', ]) ->call('create') ->assertNotified('Restore execution paused'); @@ -134,7 +134,7 @@ function seedOperationalRestoreExecutionContext(bool $withProviderConnection = t expect($audit)->not->toBeNull() ->and($audit?->workspace_id)->toBe((int) $tenant->workspace_id) - ->and($audit?->tenant_id)->toBe((int) $tenant->getKey()) + ->and($audit?->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($audit?->status)->toBe('blocked') ->and($audit?->metadata['control_key'] ?? null)->toBe('restore.execute'); @@ -158,7 +158,7 @@ function seedOperationalRestoreExecutionContext(bool $withProviderConnection = t ]); $restoreRun = RestoreRun::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'operation_run_id' => (int) $operationRun->getKey(), 'requested_by' => $user->email, @@ -238,18 +238,18 @@ function seedOperationalRestoreExecutionContext(bool $withProviderConnection = t ->fillForm([ 'is_dry_run' => false, 'acknowledged_impact' => true, - 'tenant_confirm' => 'Restore Tenant', + 'tenant_confirm' => 'Restore ManagedEnvironment', ]) ->call('create') ->assertHasNoFormErrors(); $restoreRun = RestoreRun::query() - ->where('tenant_id', (int) $allowedTenant->getKey()) + ->where('managed_environment_id', (int) $allowedTenant->getKey()) ->latest('id') ->first(); $operationRun = OperationRun::query() - ->where('tenant_id', (int) $allowedTenant->getKey()) + ->where('managed_environment_id', (int) $allowedTenant->getKey()) ->where('type', 'restore.execute') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Restore/RestoreRunProviderStartTest.php b/apps/platform/tests/Feature/Restore/RestoreRunProviderStartTest.php index aaa299d4..d7c0795f 100644 --- a/apps/platform/tests/Feature/Restore/RestoreRunProviderStartTest.php +++ b/apps/platform/tests/Feature/Restore/RestoreRunProviderStartTest.php @@ -8,7 +8,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Providers\ProviderReasonCodes; use App\Support\RestoreRunStatus; @@ -26,9 +26,9 @@ function seedRestoreStartContext(bool $withProviderConnection = true): array { - $tenant = Tenant::create([ - 'tenant_id' => fake()->uuid(), - 'name' => 'Restore Tenant', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => fake()->uuid(), + 'name' => 'Restore ManagedEnvironment', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -41,7 +41,7 @@ function seedRestoreStartContext(bool $withProviderConnection = true): array } $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => fake()->uuid(), 'policy_type' => 'deviceConfiguration', 'display_name' => 'Device Config Policy', @@ -49,14 +49,14 @@ function seedRestoreStartContext(bool $withProviderConnection = true): array ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -105,14 +105,14 @@ function seedRestoreStartContext(bool $withProviderConnection = true): array ->fillForm([ 'is_dry_run' => false, 'acknowledged_impact' => true, - 'tenant_confirm' => 'Restore Tenant', + 'tenant_confirm' => 'Restore ManagedEnvironment', ]) ->call('create') ->assertHasNoFormErrors(); $restoreRun = RestoreRun::query()->latest('id')->first(); $operationRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'restore.execute') ->latest('id') ->first(); @@ -136,7 +136,7 @@ function seedRestoreStartContext(bool $withProviderConnection = true): array $this->actingAs($user); $run = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'failed', 'is_dry_run' => false, @@ -147,10 +147,10 @@ function seedRestoreStartContext(bool $withProviderConnection = true): array Livewire::test(ListRestoreRuns::class) ->callTableAction('rerun', $run); - expect(RestoreRun::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(1); + expect(RestoreRun::query()->where('managed_environment_id', (int) $tenant->getKey())->count())->toBe(1); $operationRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'restore.execute') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/RestoreAdapterTest.php b/apps/platform/tests/Feature/RestoreAdapterTest.php index 0863774f..aa19ccd7 100644 --- a/apps/platform/tests/Feature/RestoreAdapterTest.php +++ b/apps/platform/tests/Feature/RestoreAdapterTest.php @@ -10,14 +10,14 @@ ]); expect(OperationRun::query() - ->where('tenant_id', $restoreRun->tenant_id) + ->where('managed_environment_id', $restoreRun->managed_environment_id) ->where('type', 'restore.execute') ->count())->toBe(0); $restoreRun->update(['status' => RestoreRunStatus::Previewed->value]); $opRun = OperationRun::query() - ->where('tenant_id', $restoreRun->tenant_id) + ->where('managed_environment_id', $restoreRun->managed_environment_id) ->where('type', 'restore.execute') ->latest('id') ->first(); @@ -44,7 +44,7 @@ ]); $opRun = OperationRun::query() - ->where('tenant_id', $restoreRun->tenant_id) + ->where('managed_environment_id', $restoreRun->managed_environment_id) ->where('type', 'restore.execute') ->latest('id') ->first(); @@ -81,7 +81,7 @@ ]); $opRun = OperationRun::query() - ->where('tenant_id', $restoreRun->tenant_id) + ->where('managed_environment_id', $restoreRun->managed_environment_id) ->where('type', 'restore.execute') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/RestoreAssignmentApplicationTest.php b/apps/platform/tests/Feature/RestoreAssignmentApplicationTest.php index 8325536b..feef51a3 100644 --- a/apps/platform/tests/Feature/RestoreAssignmentApplicationTest.php +++ b/apps/platform/tests/Feature/RestoreAssignmentApplicationTest.php @@ -3,7 +3,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -75,16 +75,16 @@ public function request(string $method, string $path, array $options = []): Grap $client = new RestoreAssignmentGraphClient($applyResponse, $requestResponses); app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Alpha', @@ -92,14 +92,14 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -181,16 +181,16 @@ public function request(string $method, string $path, array $options = []): Grap $client = new RestoreAssignmentGraphClient($applyResponse, $requestResponses); app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Alpha', @@ -198,14 +198,14 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -269,16 +269,16 @@ public function request(string $method, string $path, array $options = []): Grap $client = new RestoreAssignmentGraphClient($applyResponse, $requestResponses); app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], ]); ensureDefaultProviderConnection($tenant); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'scp-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog Alpha', @@ -286,14 +286,14 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 2, ]); $foundationItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'filter-old', @@ -304,7 +304,7 @@ public function request(string $method, string $path, array $options = []): Grap ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/RestoreAuditLoggingTest.php b/apps/platform/tests/Feature/RestoreAuditLoggingTest.php index 3294f399..fb0f0a7c 100644 --- a/apps/platform/tests/Feature/RestoreAuditLoggingTest.php +++ b/apps/platform/tests/Feature/RestoreAuditLoggingTest.php @@ -4,7 +4,7 @@ use App\Models\AuditLog; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\AuditLogger; use App\Services\Intune\RestoreService; use App\Services\OperationRunService; @@ -15,21 +15,23 @@ uses(RefreshDatabase::class); test('live restore execution emits an auditable event linked to the run', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-audit', - 'name' => 'Tenant Audit', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-audit', + 'name' => 'ManagedEnvironment Audit', 'metadata' => [], + 'rbac_status' => 'ok', + 'rbac_last_checked_at' => now(), ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'requested_by' => 'actor@example.com', 'is_dry_run' => false, @@ -68,7 +70,7 @@ $job->handle($restoreService, app(AuditLogger::class)); $audit = AuditLog::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('action', 'restore.started') ->where('metadata->restore_run_id', $restoreRun->id) ->latest('id') diff --git a/apps/platform/tests/Feature/RestoreGraphErrorMetadataTest.php b/apps/platform/tests/Feature/RestoreGraphErrorMetadataTest.php index 57649b31..ec8d4fd9 100644 --- a/apps/platform/tests/Feature/RestoreGraphErrorMetadataTest.php +++ b/apps/platform/tests/Feature/RestoreGraphErrorMetadataTest.php @@ -2,7 +2,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\RestoreService; @@ -64,7 +64,7 @@ public function request(string $method, string $path, array $options = []): Grap $client = new RestoreGraphErrorMetadataGraphClient; app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); $backupSet = BackupSet::factory()->for($tenant)->create([ diff --git a/apps/platform/tests/Feature/RestoreGroupMappingTest.php b/apps/platform/tests/Feature/RestoreGroupMappingTest.php index b11ca98f..47e551ae 100644 --- a/apps/platform/tests/Feature/RestoreGroupMappingTest.php +++ b/apps/platform/tests/Feature/RestoreGroupMappingTest.php @@ -5,7 +5,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GroupResolver; use App\Support\RestoreSafety\RestoreScopeFingerprint; @@ -22,9 +22,9 @@ }); test('restore wizard shows group mapping for unresolved groups', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -33,7 +33,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog', @@ -41,14 +41,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -106,9 +106,9 @@ }); test('restore wizard persists group mapping selections', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -117,7 +117,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog', @@ -125,14 +125,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -203,15 +203,15 @@ ]); $this->assertDatabaseHas('audit_logs', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'action' => 'restore.group_mapping.applied', ]); }); test('restore wizard can fill a group mapping entry from directory cache picker', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), diff --git a/apps/platform/tests/Feature/RestorePreviewDiffWizardTest.php b/apps/platform/tests/Feature/RestorePreviewDiffWizardTest.php index 91cd5e85..9ed1f52a 100644 --- a/apps/platform/tests/Feature/RestorePreviewDiffWizardTest.php +++ b/apps/platform/tests/Feature/RestorePreviewDiffWizardTest.php @@ -6,7 +6,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -20,9 +20,9 @@ }); test('restore wizard generates a normalized preview diff summary and persists it', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -31,7 +31,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Device Config Policy', @@ -39,7 +39,7 @@ ]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => $policy->policy_type, @@ -57,14 +57,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/RestoreRiskChecksWizardTest.php b/apps/platform/tests/Feature/RestoreRiskChecksWizardTest.php index 42dbc3f0..85ee6f34 100644 --- a/apps/platform/tests/Feature/RestoreRiskChecksWizardTest.php +++ b/apps/platform/tests/Feature/RestoreRiskChecksWizardTest.php @@ -5,7 +5,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GroupResolver; use Filament\Facades\Filament; @@ -21,9 +21,9 @@ }); test('restore wizard can run safety checks and persists results on the restore run', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -33,7 +33,7 @@ ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog', @@ -41,14 +41,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -144,9 +144,9 @@ }); test('restore wizard treats skipped orphaned groups as a warning instead of a blocker', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -156,7 +156,7 @@ ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Settings Catalog', @@ -164,14 +164,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -243,9 +243,9 @@ }); test('restore wizard keeps prior checks evidence visible and marks it invalidated after scope drift', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-drift', - 'name' => 'Tenant Drift', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-drift', + 'name' => 'ManagedEnvironment Drift', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -255,7 +255,7 @@ ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-drift', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Config Drift', @@ -263,14 +263,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 2, ]); $firstItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => 'policy-first', @@ -280,7 +280,7 @@ ]); $secondItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => 'policy-second', @@ -326,9 +326,9 @@ }); test('restore wizard flags metadata-only snapshots as blocking for restore-enabled types', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -338,7 +338,7 @@ ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'mamAppConfiguration', 'display_name' => 'MAM App Config', @@ -346,14 +346,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, diff --git a/apps/platform/tests/Feature/RestoreRunArchiveGuardTest.php b/apps/platform/tests/Feature/RestoreRunArchiveGuardTest.php index 0520342b..ef1a87ca 100644 --- a/apps/platform/tests/Feature/RestoreRunArchiveGuardTest.php +++ b/apps/platform/tests/Feature/RestoreRunArchiveGuardTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\RestoreRunResource\Pages\ListRestoreRuns; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -12,17 +12,17 @@ uses(RefreshDatabase::class); test('restore run archive action does not archive non-deletable runs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Set RR', 'status' => 'completed', 'item_count' => 0, ]); $running = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'running', 'is_dry_run' => true, diff --git a/apps/platform/tests/Feature/RestoreRunIdempotencyTest.php b/apps/platform/tests/Feature/RestoreRunIdempotencyTest.php index 6cfb078f..a8b9db1c 100644 --- a/apps/platform/tests/Feature/RestoreRunIdempotencyTest.php +++ b/apps/platform/tests/Feature/RestoreRunIdempotencyTest.php @@ -6,7 +6,7 @@ use App\Models\BackupSet; use App\Models\Policy; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\RestoreRunStatus; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -22,9 +22,9 @@ test('restore execution reuses active run for identical starts', function () { Bus::fake(); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-idempotency', - 'name' => 'Tenant Idempotency', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-idempotency', + 'name' => 'ManagedEnvironment Idempotency', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -33,7 +33,7 @@ $tenant->makeCurrent(); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'unknownPreviewOnlyType', 'display_name' => 'Preview-only policy', @@ -41,14 +41,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -93,7 +93,7 @@ ], 'preview_ran_at' => now()->toIso8601String(), 'acknowledged_impact' => true, - 'tenant_confirm' => 'Tenant Idempotency', + 'tenant_confirm' => 'ManagedEnvironment Idempotency', ]; $first = RestoreRunResource::createRestoreRun($data); diff --git a/apps/platform/tests/Feature/RestoreRunRerunTest.php b/apps/platform/tests/Feature/RestoreRunRerunTest.php index 319e9a91..bb5acb86 100644 --- a/apps/platform/tests/Feature/RestoreRunRerunTest.php +++ b/apps/platform/tests/Feature/RestoreRunRerunTest.php @@ -4,7 +4,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Filament\Tables\Filters\TrashedFilter; @@ -14,7 +14,10 @@ uses(RefreshDatabase::class); test('rerun action creates a new restore run with the same selections', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create([ + 'rbac_status' => 'ok', + 'rbac_last_checked_at' => now(), + ]); $backupSet = BackupSet::factory()->for($tenant)->create([ 'status' => 'completed', @@ -37,7 +40,7 @@ ->create(); $run = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'failed', 'is_dry_run' => true, @@ -74,7 +77,10 @@ }); test('rerun action is hidden for archived restore runs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create([ + 'rbac_status' => 'ok', + 'rbac_last_checked_at' => now(), + ]); $backupSet = BackupSet::factory()->for($tenant)->create([ 'status' => 'completed', @@ -82,7 +88,7 @@ ]); $run = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, diff --git a/apps/platform/tests/Feature/RestoreRunWizardExecuteTest.php b/apps/platform/tests/Feature/RestoreRunWizardExecuteTest.php index 12662ae5..7e8a76ae 100644 --- a/apps/platform/tests/Feature/RestoreRunWizardExecuteTest.php +++ b/apps/platform/tests/Feature/RestoreRunWizardExecuteTest.php @@ -7,7 +7,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\RestoreRunStatus; use App\Support\Workspaces\WorkspaceContext; @@ -24,9 +24,9 @@ }); test('restore run wizard blocks execution when confirmations are missing', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -36,7 +36,7 @@ ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Device Config Policy', @@ -44,14 +44,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -100,9 +100,9 @@ test('restore run wizard queues execution when gates are satisfied', function () { Bus::fake(); - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-2', - 'name' => 'Tenant Two', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-2', + 'name' => 'ManagedEnvironment Two', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -112,7 +112,7 @@ ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-2', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Device Config Policy', @@ -120,14 +120,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -167,7 +167,7 @@ ->fillForm([ 'is_dry_run' => false, 'acknowledged_impact' => true, - 'tenant_confirm' => 'Tenant Two', + 'tenant_confirm' => 'ManagedEnvironment Two', ]) ->call('create') ->assertHasNoFormErrors(); @@ -181,7 +181,7 @@ expect($run->metadata['confirmed_at'] ?? null)->toBeString(); $operationRun = OperationRun::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->where('type', 'restore.execute') ->latest('id') ->first(); @@ -201,9 +201,9 @@ }); test('restore run wizard blocks execution when scope drift invalidates preview and checks evidence', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-3', - 'name' => 'Tenant Three', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-3', + 'name' => 'ManagedEnvironment Three', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -213,7 +213,7 @@ ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-3', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Device Config Policy', @@ -221,14 +221,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 2, ]); $firstItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => 'policy-a', @@ -239,7 +239,7 @@ ]); $secondItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => 'policy-b', @@ -282,7 +282,7 @@ ->fillForm([ 'is_dry_run' => false, 'acknowledged_impact' => true, - 'tenant_confirm' => 'Tenant Three', + 'tenant_confirm' => 'ManagedEnvironment Three', ]) ->call('create'); @@ -290,13 +290,13 @@ }); test('admin restore run wizard ignores prefill query params for backup sets outside the canonical tenant', function () { - $tenantA = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create([ 'name' => 'Phoenicon', 'environment' => 'dev', ]); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, 'name' => 'YPTW2', 'environment' => 'dev', diff --git a/apps/platform/tests/Feature/RestoreRunWizardMetadataTest.php b/apps/platform/tests/Feature/RestoreRunWizardMetadataTest.php index bafc4896..6d53c626 100644 --- a/apps/platform/tests/Feature/RestoreRunWizardMetadataTest.php +++ b/apps/platform/tests/Feature/RestoreRunWizardMetadataTest.php @@ -4,7 +4,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -18,9 +18,9 @@ }); test('restore run stores wizard audit metadata and preserves it on completion', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', + 'name' => 'ManagedEnvironment One', 'metadata' => [], 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), @@ -30,14 +30,14 @@ ensureDefaultProviderConnection($tenant, 'microsoft'); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupItem = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'policy-1', @@ -92,6 +92,6 @@ expect($run->metadata['scope_mode'])->toBe('selected'); expect($run->metadata['environment'])->toBe('test'); - expect($run->metadata['highlander_label'])->toBe('Tenant One'); + expect($run->metadata['highlander_label'])->toBe('ManagedEnvironment One'); expect($run->metadata['scope_basis']['fingerprint'] ?? null)->toBeString(); }); diff --git a/apps/platform/tests/Feature/RestoreScopeTagMappingTest.php b/apps/platform/tests/Feature/RestoreScopeTagMappingTest.php index cfd95a48..03dec8d4 100644 --- a/apps/platform/tests/Feature/RestoreScopeTagMappingTest.php +++ b/apps/platform/tests/Feature/RestoreScopeTagMappingTest.php @@ -2,7 +2,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -61,7 +61,7 @@ public function request(string $method, string $path, array $options = []): Grap $client = new RestoreScopeTagGraphClient; app()->instance(GraphClientInterface::class, $client); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); diff --git a/apps/platform/tests/Feature/RestoreUnknownPolicyTypeSafetyTest.php b/apps/platform/tests/Feature/RestoreUnknownPolicyTypeSafetyTest.php index fc13ce64..c6537816 100644 --- a/apps/platform/tests/Feature/RestoreUnknownPolicyTypeSafetyTest.php +++ b/apps/platform/tests/Feature/RestoreUnknownPolicyTypeSafetyTest.php @@ -2,7 +2,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\RestoreService; @@ -81,7 +81,7 @@ public function request(string $method, string $path, array $options = []): Grap config()->set('tenantpilot.supported_policy_types', $supported); config()->set('graph_contracts.types.securityBaselinePolicy', []); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant); $backupSet = BackupSet::factory()->for($tenant)->create([ 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Retention/PruneBaselineEvidencePolicyVersionsTest.php b/apps/platform/tests/Feature/Retention/PruneBaselineEvidencePolicyVersionsTest.php index 1bae1b4e..6bc178ae 100644 --- a/apps/platform/tests/Feature/Retention/PruneBaselineEvidencePolicyVersionsTest.php +++ b/apps/platform/tests/Feature/Retention/PruneBaselineEvidencePolicyVersionsTest.php @@ -5,7 +5,7 @@ use App\Models\BaselineProfile; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Baselines\PolicyVersionCapturePurpose; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -14,10 +14,10 @@ it('prunes baseline-purpose policy versions past retention but keeps backups', function (): void { config()->set('tenantpilot.baselines.full_content_capture.retention_days', 30); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $profile = BaselineProfile::factory()->active()->create([ @@ -25,7 +25,7 @@ ]); $oldBaselineCompare = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 1, 'capture_purpose' => PolicyVersionCapturePurpose::BaselineCompare->value, @@ -34,7 +34,7 @@ ]); $oldBaselineCapture = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 2, 'capture_purpose' => PolicyVersionCapturePurpose::BaselineCapture->value, @@ -43,7 +43,7 @@ ]); $recentBaselineCompare = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 3, 'capture_purpose' => PolicyVersionCapturePurpose::BaselineCompare->value, @@ -52,7 +52,7 @@ ]); $oldBackup = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 4, 'capture_purpose' => PolicyVersionCapturePurpose::Backup->value, diff --git a/apps/platform/tests/Feature/ReviewPack/ReviewPackDownloadTest.php b/apps/platform/tests/Feature/ReviewPack/ReviewPackDownloadTest.php index d07cdfad..00907429 100644 --- a/apps/platform/tests/Feature/ReviewPack/ReviewPackDownloadTest.php +++ b/apps/platform/tests/Feature/ReviewPack/ReviewPackDownloadTest.php @@ -32,7 +32,7 @@ function createReadyPackWithFile(?array $packOverrides = []): array Storage::disk('exports')->put($filePath, 'PK-fake-zip-content'); $pack = ReviewPack::factory()->ready()->create(array_merge([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'file_path' => $filePath, @@ -148,7 +148,7 @@ function suspendReadyPackWorkspaceForDownloadTest(ReviewPack $pack): void [$user, $tenant] = createUserWithTenant(); $pack = ReviewPack::factory()->queued()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -204,7 +204,7 @@ function suspendReadyPackWorkspaceForDownloadTest(ReviewPack $pack): void [$user, $tenant] = createUserWithTenant(); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'file_path' => 'review-packs/does-not-exist.zip', diff --git a/apps/platform/tests/Feature/ReviewPack/ReviewPackEntitlementEnforcementTest.php b/apps/platform/tests/Feature/ReviewPack/ReviewPackEntitlementEnforcementTest.php index 63d0a98f..806d38dc 100644 --- a/apps/platform/tests/Feature/ReviewPack/ReviewPackEntitlementEnforcementTest.php +++ b/apps/platform/tests/Feature/ReviewPack/ReviewPackEntitlementEnforcementTest.php @@ -11,7 +11,7 @@ use App\Models\PlatformUser; use App\Models\ReviewPack; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Entitlements\WorkspaceCommercialLifecycleResolver; use App\Services\Evidence\EvidenceSnapshotService; @@ -29,27 +29,27 @@ Storage::fake('exports'); }); -function seedEntitlementReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot +function seedEntitlementReviewPackSnapshot(ManagedEnvironment $tenant): EvidenceSnapshot { StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => ['required_count' => 1, 'granted_count' => 1], ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'payload' => ['roles' => [['displayName' => 'Global Administrator']]], ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]); @@ -61,7 +61,7 @@ function seedEntitlementReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot $payload = $service->buildSnapshotPayload($tenant); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'fingerprint' => $payload['fingerprint'], @@ -72,7 +72,7 @@ function seedEntitlementReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot foreach ($payload['items'] as $item) { $snapshot->items()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => $item['dimension_key'], 'state' => $item['state'], @@ -91,7 +91,7 @@ function seedEntitlementReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot return $snapshot; } -function disableReviewPackGenerationForWorkspace(Tenant $tenant, User $user, string $reason): void +function disableReviewPackGenerationForWorkspace(ManagedEnvironment $tenant, User $user, string $reason): void { $writer = app(SettingsWriter::class); @@ -112,7 +112,7 @@ function disableReviewPackGenerationForWorkspace(Tenant $tenant, User $user, str ); } -function setReviewPackCommercialLifecycleState(Tenant $tenant, string $state, string $reason = 'Review pack commercial lifecycle test'): void +function setReviewPackCommercialLifecycleState(ManagedEnvironment $tenant, string $state, string $reason = 'Review pack commercial lifecycle test'): void { app(SettingsWriter::class)->updateWorkspaceCommercialLifecycle( actor: PlatformUser::factory()->create([ @@ -129,7 +129,7 @@ function setReviewPackCommercialLifecycleState(Tenant $tenant, string $state, st ); } -function setReviewPackSubscriptionState(Tenant $tenant, array $attributes): void +function setReviewPackSubscriptionState(ManagedEnvironment $tenant, array $attributes): void { app(SettingsWriter::class)->updateWorkspaceSubscription( actor: PlatformUser::factory()->create([ @@ -150,7 +150,7 @@ function setReviewPackSubscriptionState(Tenant $tenant, array $attributes): void seedEntitlementReviewPackSnapshot($tenant); disableReviewPackGenerationForWorkspace($tenant, $user, 'Workspace is temporarily limited to manual reporting only'); $initialRunCount = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->count(); @@ -159,7 +159,7 @@ function setReviewPackSubscriptionState(Tenant $tenant, array $attributes): void expect(ReviewPack::query()->count())->toBe(0) ->and(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->count())->toBe($initialRunCount); }); @@ -170,7 +170,7 @@ function setReviewPackSubscriptionState(Tenant $tenant, array $attributes): void $review = composeTenantReviewForTest($tenant, $user, $snapshot); disableReviewPackGenerationForWorkspace($tenant, $user, 'Workspace is temporarily limited to manual reporting only'); $initialRunCount = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->count(); @@ -179,17 +179,17 @@ function setReviewPackSubscriptionState(Tenant $tenant, array $attributes): void expect(ReviewPack::query()->count())->toBe(0) ->and(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->count())->toBe($initialRunCount); }); it('shows the blocked reason on the review pack card and keeps existing pack downloads accessible', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); disableReviewPackGenerationForWorkspace($tenant, $user, 'Workspace is temporarily limited to manual reporting only'); $initialRunCount = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->count(); @@ -205,7 +205,7 @@ function setReviewPackSubscriptionState(Tenant $tenant, array $attributes): void expect(ReviewPack::query()->count())->toBe(0) ->and(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->count())->toBe($initialRunCount); @@ -213,7 +213,7 @@ function setReviewPackSubscriptionState(Tenant $tenant, array $attributes): void Storage::disk('exports')->put($filePath, 'PK-test'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'file_path' => $filePath, @@ -268,7 +268,7 @@ function setReviewPackSubscriptionState(Tenant $tenant, array $attributes): void expect($pack)->toBeInstanceOf(ReviewPack::class) ->and(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->exists())->toBeTrue(); }); @@ -310,7 +310,7 @@ function setReviewPackSubscriptionState(Tenant $tenant, array $attributes): void seedEntitlementReviewPackSnapshot($tenant); setReviewPackCommercialLifecycleState($tenant, WorkspaceCommercialLifecycleResolver::STATE_SUSPENDED_READ_ONLY, 'Suspension'); $initialRunCount = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->count(); @@ -319,7 +319,7 @@ function setReviewPackSubscriptionState(Tenant $tenant, array $attributes): void expect(ReviewPack::query()->count())->toBe(0) ->and(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->count())->toBe($initialRunCount); diff --git a/apps/platform/tests/Feature/ReviewPack/ReviewPackGenerationTest.php b/apps/platform/tests/Feature/ReviewPack/ReviewPackGenerationTest.php index 23b1ac20..be52c487 100644 --- a/apps/platform/tests/Feature/ReviewPack/ReviewPackGenerationTest.php +++ b/apps/platform/tests/Feature/ReviewPack/ReviewPackGenerationTest.php @@ -12,7 +12,7 @@ use App\Models\PlatformUser; use App\Models\ReviewPack; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Notifications\OperationRunCompleted; use App\Notifications\OperationRunQueued; use App\Services\Entitlements\WorkspaceCommercialLifecycleResolver; @@ -38,31 +38,31 @@ }); it('treats only queued and generating review packs as active for card polling', function (string $status, ?string $expectedInterval): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $pack = match ($status) { ReviewPackStatus::Queued->value => ReviewPack::factory()->queued()->make([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]), ReviewPackStatus::Generating->value => ReviewPack::factory()->generating()->make([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]), ReviewPackStatus::Ready->value => ReviewPack::factory()->ready()->make([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]), ReviewPackStatus::Failed->value => ReviewPack::factory()->failed()->make([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]), ReviewPackStatus::Expired->value => ReviewPack::factory()->expired()->make([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]), default => ReviewPack::factory()->make([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => $status, ]), @@ -84,10 +84,10 @@ // ─── Helper ────────────────────────────────────────────────── -function seedTenantWithData(Tenant $tenant): void +function seedTenantWithData(ManagedEnvironment $tenant): void { StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => [ 'posture_score' => 86, @@ -100,7 +100,7 @@ function seedTenantWithData(Tenant $tenant): void ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'payload' => [ 'roles' => [ @@ -115,10 +115,10 @@ function seedTenantWithData(Tenant $tenant): void Finding::factory() ->count(3) - ->create(['tenant_id' => (int) $tenant->getKey()]); + ->create(['managed_environment_id' => (int) $tenant->getKey()]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]); @@ -126,14 +126,14 @@ function seedTenantWithData(Tenant $tenant): void OperationRun::factory()->forTenant($tenant)->create(); } -function createEvidenceSnapshotForReviewPack(Tenant $tenant): EvidenceSnapshot +function createEvidenceSnapshotForReviewPack(ManagedEnvironment $tenant): EvidenceSnapshot { /** @var EvidenceSnapshotService $service */ $service = app(EvidenceSnapshotService::class); $payload = $service->buildSnapshotPayload($tenant); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'fingerprint' => $payload['fingerprint'], @@ -144,7 +144,7 @@ function createEvidenceSnapshotForReviewPack(Tenant $tenant): EvidenceSnapshot foreach ($payload['items'] as $item) { $snapshot->items()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => $item['dimension_key'], 'state' => $item['state'], @@ -163,7 +163,7 @@ function createEvidenceSnapshotForReviewPack(Tenant $tenant): EvidenceSnapshot return $snapshot->load('items'); } -function suspendReviewPackGenerationWorkspaceForGenerationTest(Tenant $tenant): void +function suspendReviewPackGenerationWorkspaceForGenerationTest(ManagedEnvironment $tenant): void { app(SettingsWriter::class)->updateWorkspaceCommercialLifecycle( actor: PlatformUser::factory()->create([ @@ -403,7 +403,7 @@ public function incrementSummaryCounts(OperationRun $run, array $delta): Operati [$user, $tenant] = createUserWithTenant(); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => 'missing', @@ -412,7 +412,7 @@ public function incrementSummaryCounts(OperationRun $run, array $delta): Operati ]); $snapshot->items()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => 'findings_summary', 'state' => 'missing', @@ -656,7 +656,7 @@ public function incrementSummaryCounts(OperationRun $run, array $delta): Operati $pack2 = $service->generate($tenant, $user, $options); expect($pack2->getKey())->toBe($pack1->getKey()); - expect(ReviewPack::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(1); + expect(ReviewPack::query()->where('managed_environment_id', (int) $tenant->getKey())->count())->toBe(1); }); it('allows new generation when existing pack with same fingerprint is expired', function (): void { @@ -675,7 +675,7 @@ public function incrementSummaryCounts(OperationRun $run, array $delta): Operati $fingerprint = $service->computeFingerprint($tenant, ['include_pii' => true, 'include_operations' => true]); ReviewPack::factory()->expired()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -685,7 +685,7 @@ public function incrementSummaryCounts(OperationRun $run, array $delta): Operati // Should create a new pack since existing is expired $newPack = $service->generate($tenant, $user, $options); - expect(ReviewPack::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(2); + expect(ReviewPack::query()->where('managed_environment_id', (int) $tenant->getKey())->count())->toBe(2); expect($newPack->status)->toBe(ReviewPackStatus::Queued->value); }); @@ -696,9 +696,9 @@ public function incrementSummaryCounts(OperationRun $run, array $delta): Operati $snapshot = createEvidenceSnapshotForReviewPack($tenant); Notification::fake(); - StoredReport::query()->where('tenant_id', (int) $tenant->getKey())->delete(); - Finding::query()->where('tenant_id', (int) $tenant->getKey())->delete(); - OperationRun::query()->where('tenant_id', (int) $tenant->getKey())->delete(); + StoredReport::query()->where('managed_environment_id', (int) $tenant->getKey())->delete(); + Finding::query()->where('managed_environment_id', (int) $tenant->getKey())->delete(); + OperationRun::query()->where('managed_environment_id', (int) $tenant->getKey())->delete(); /** @var ReviewPackService $service */ $service = app(ReviewPackService::class); diff --git a/apps/platform/tests/Feature/ReviewPack/ReviewPackPruneTest.php b/apps/platform/tests/Feature/ReviewPack/ReviewPackPruneTest.php index 5ba24dbd..e0eba68b 100644 --- a/apps/platform/tests/Feature/ReviewPack/ReviewPackPruneTest.php +++ b/apps/platform/tests/Feature/ReviewPack/ReviewPackPruneTest.php @@ -21,7 +21,7 @@ Storage::disk('exports')->put($filePath, 'fake content'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => $tenant->workspace_id, 'initiated_by_user_id' => $user->id, 'file_path' => $filePath, @@ -43,7 +43,7 @@ Storage::disk('exports')->put($filePath, 'fake content'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => $tenant->workspace_id, 'initiated_by_user_id' => $user->id, 'file_path' => $filePath, @@ -64,7 +64,7 @@ $graceDays = config('tenantpilot.review_pack.hard_delete_grace_days', 30); $pack = ReviewPack::factory()->expired()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => $tenant->workspace_id, 'initiated_by_user_id' => $user->id, 'updated_at' => now()->subDays($graceDays + 5), @@ -80,7 +80,7 @@ [$user, $tenant] = createUserWithTenant(); $pack = ReviewPack::factory()->expired()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => $tenant->workspace_id, 'initiated_by_user_id' => $user->id, 'updated_at' => now()->subDays(5), @@ -97,7 +97,7 @@ // 2 packs past retention → expired ReviewPack::factory()->count(2)->ready()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => $tenant->workspace_id, 'initiated_by_user_id' => $user->id, 'expires_at' => now()->subDays(3), @@ -115,7 +115,7 @@ // 1 pack past retention → expired ReviewPack::factory()->ready()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => $tenant->workspace_id, 'initiated_by_user_id' => $user->id, 'expires_at' => now()->subDay(), @@ -123,7 +123,7 @@ // 1 expired pack past grace → hard-deleted ReviewPack::factory()->expired()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => $tenant->workspace_id, 'initiated_by_user_id' => $user->id, 'updated_at' => now()->subDays($graceDays + 10), @@ -140,7 +140,7 @@ $graceDays = config('tenantpilot.review_pack.hard_delete_grace_days', 30); $pack = ReviewPack::factory()->expired()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => $tenant->workspace_id, 'initiated_by_user_id' => $user->id, 'updated_at' => now()->subDays($graceDays + 10), diff --git a/apps/platform/tests/Feature/ReviewPack/ReviewPackRbacTest.php b/apps/platform/tests/Feature/ReviewPack/ReviewPackRbacTest.php index 72fead90..aa5b635b 100644 --- a/apps/platform/tests/Feature/ReviewPack/ReviewPackRbacTest.php +++ b/apps/platform/tests/Feature/ReviewPack/ReviewPackRbacTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\ReviewPackResource; use App\Filament\Resources\ReviewPackResource\Pages\ListReviewPacks; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\ReviewPackService; use App\Support\Auth\UiTooltips; use App\Support\ReviewPackStatus; @@ -37,8 +37,8 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? // ─── Non-Member Access ─────────────────────────────────────── it('returns 404 for non-member on list page', function (): void { - $targetTenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $targetTenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'owner'); @@ -48,13 +48,13 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? }); it('returns 404 for non-member on view page', function (): void { - $targetTenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $targetTenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'owner'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $targetTenant->getKey(), + 'managed_environment_id' => (int) $targetTenant->getKey(), ]); $this->actingAs($user) @@ -63,8 +63,8 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? }); it('returns 404 for non-member on download route', function (): void { - $targetTenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $targetTenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'owner'); @@ -72,7 +72,7 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? Storage::disk('exports')->put($filePath, 'PK-fake'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $targetTenant->getKey(), + 'managed_environment_id' => (int) $targetTenant->getKey(), 'file_path' => $filePath, 'file_disk' => 'exports', ]); @@ -85,7 +85,7 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? // ─── REVIEW_PACK_VIEW Member ──────────────────────────────── it('allows readonly member to access list page', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $this->actingAs($user) @@ -94,11 +94,11 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? }); it('allows readonly member to access view page', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -109,14 +109,14 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? }); it('allows readonly member to download via signed URL', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $filePath = 'review-packs/readonly-test.zip'; Storage::disk('exports')->put($filePath, 'PK-fake'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'file_path' => $filePath, @@ -129,7 +129,7 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? }); it('disables generate action for readonly member', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $tenant->makeCurrent(); @@ -149,11 +149,11 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? // ─── REVIEW_PACK_MANAGE Member ────────────────────────────── it('allows owner to generate a review pack', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -168,14 +168,14 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? }); it('allows owner to expire a ready pack', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $filePath = 'review-packs/expire-rbac.zip'; Storage::disk('exports')->put($filePath, 'PK-fake'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'file_path' => $filePath, @@ -195,14 +195,14 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? }); it('disables expire action for readonly member', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $filePath = 'review-packs/expire-readonly.zip'; Storage::disk('exports')->put($filePath, 'PK-fake'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'file_path' => $filePath, 'file_disk' => 'exports', @@ -220,11 +220,11 @@ function getReviewPackRbacEmptyStateAction(Testable $component, string $name): ? // ─── Signed URL Security ──────────────────────────────────── it('rejects unsigned download URL with 403', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); diff --git a/apps/platform/tests/Feature/ReviewPack/ReviewPackRedactionIntegrityTest.php b/apps/platform/tests/Feature/ReviewPack/ReviewPackRedactionIntegrityTest.php index da1e4c03..41040382 100644 --- a/apps/platform/tests/Feature/ReviewPack/ReviewPackRedactionIntegrityTest.php +++ b/apps/platform/tests/Feature/ReviewPack/ReviewPackRedactionIntegrityTest.php @@ -23,7 +23,7 @@ function createRedactionReviewPackSnapshot($tenant): EvidenceSnapshot { StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'payload' => [ 'roles' => [ @@ -33,12 +33,12 @@ function createRedactionReviewPackSnapshot($tenant): EvidenceSnapshot ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]); @@ -50,7 +50,7 @@ function createRedactionReviewPackSnapshot($tenant): EvidenceSnapshot $payload = $service->buildSnapshotPayload($tenant); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'fingerprint' => $payload['fingerprint'], @@ -61,7 +61,7 @@ function createRedactionReviewPackSnapshot($tenant): EvidenceSnapshot foreach ($payload['items'] as $item) { $snapshot->items()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => $item['dimension_key'], 'state' => $item['state'], @@ -84,7 +84,7 @@ function createRedactionReviewPackSnapshot($tenant): EvidenceSnapshot [$user, $tenant] = createUserWithTenant(); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => [ 'passwordMinimumLength' => 14, diff --git a/apps/platform/tests/Feature/ReviewPack/ReviewPackResourceTest.php b/apps/platform/tests/Feature/ReviewPack/ReviewPackResourceTest.php index 15ebbdf2..421b4280 100644 --- a/apps/platform/tests/Feature/ReviewPack/ReviewPackResourceTest.php +++ b/apps/platform/tests/Feature/ReviewPack/ReviewPackResourceTest.php @@ -11,7 +11,7 @@ use App\Models\OperationRun; use App\Models\ReviewPack; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Evidence\EvidenceSnapshotService; use App\Services\ReviewPackService; use App\Services\Settings\SettingsWriter; @@ -60,10 +60,10 @@ function getReviewPackHeaderAction(Testable $component, string $name): ?Action return null; } -function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot +function seedReviewPackEvidence(ManagedEnvironment $tenant): EvidenceSnapshot { StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => [ 'required_count' => 1, @@ -75,7 +75,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'payload' => [ 'roles' => [ @@ -85,12 +85,12 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]); @@ -102,7 +102,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot $payload = $service->buildSnapshotPayload($tenant); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'fingerprint' => $payload['fingerprint'], @@ -113,7 +113,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot foreach ($payload['items'] as $item) { $snapshot->items()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => $item['dimension_key'], 'state' => $item['state'], @@ -135,7 +135,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot // ─── List Page ─────────────────────────────────────────────── it('renders the list page for an authorized user', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user) @@ -144,19 +144,19 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('shows review packs belonging to the active tenant', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); - $otherTenant = Tenant::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $otherTenant->getKey(), + 'managed_environment_id' => (int) $otherTenant->getKey(), ]); setTenantPanelContext($tenant); @@ -167,7 +167,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('displays the empty state when no packs exist', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $tenant->makeCurrent(); @@ -181,7 +181,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot // ─── List Page Start CTA Placement ─────────────────────────── it('shows generate only in the empty state when no review packs exist', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $tenant->makeCurrent(); @@ -201,11 +201,11 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('shows generate in the header once review packs exist', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -219,7 +219,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('disables the generate_first action for a readonly user in the empty state', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $tenant->makeCurrent(); @@ -237,7 +237,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('disables review pack generation actions when the workspace entitlement blocks them', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); app(SettingsWriter::class)->updateWorkspaceSetting( @@ -275,7 +275,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot ->and($headerAction?->isVisible())->toBeFalse(); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -289,7 +289,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot it('reuses an existing ready pack instead of starting a new run', function (): void { Queue::fake(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = seedReviewPackEvidence($tenant); @@ -299,7 +299,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot ]); ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -330,11 +330,11 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot it('does not queue generation when no eligible evidence snapshot exists', function (): void { Queue::fake(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ReviewPack::factory()->failed()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -357,14 +357,14 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot // ─── Table Row Actions ─────────────────────────────────────── it('shows the download action for a ready pack', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $filePath = 'review-packs/test.zip'; Storage::disk('exports')->put($filePath, 'PK-fake'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'file_path' => $filePath, @@ -379,14 +379,14 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('keeps expire grouped under More while still allowing owners to expire a ready pack', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $filePath = 'review-packs/expire-test.zip'; Storage::disk('exports')->put($filePath, 'PK-fake'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'file_path' => $filePath, @@ -432,7 +432,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot // ─── View Page ─────────────────────────────────────────────── it('renders the view page for a ready pack', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = seedReviewPackEvidence($tenant); $run = OperationRun::factory()->forTenant($tenant)->create([ @@ -440,7 +440,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot ]); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -482,7 +482,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('shows blocked publication truth when the source review is no longer publishable', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = seedReviewPackEvidence($tenant); $review = composeTenantReviewForTest($tenant, $user, $snapshot); @@ -495,7 +495,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot ]); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -519,7 +519,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('shows internal-only caveats for packs generated from stale source evidence before download', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = seedStaleTenantReviewEvidence($tenant); @@ -573,7 +573,7 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('keeps packs from partial evidence internal only instead of publishable', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = seedPartialTenantReviewEvidence($tenant); @@ -616,11 +616,11 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('shows download header action on view page for a ready pack', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -634,11 +634,11 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('shows regenerate header action on view page', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -652,11 +652,11 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('hides regenerate and raw pack diagnostics in the customer review pack flow', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'sha256' => hash('sha256', 'customer-pack-flow'), @@ -688,8 +688,8 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot // ─── Non-Member Access ─────────────────────────────────────── it('returns 404 for non-members on list page', function (): void { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'owner'); @@ -699,13 +699,13 @@ function seedReviewPackEvidence(Tenant $tenant): EvidenceSnapshot }); it('returns 404 for non-members on view page', function (): void { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'owner'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $this->actingAs($user) diff --git a/apps/platform/tests/Feature/ReviewPack/ReviewPackValidRiskAcceptanceTest.php b/apps/platform/tests/Feature/ReviewPack/ReviewPackValidRiskAcceptanceTest.php index b19f54da..177c56fe 100644 --- a/apps/platform/tests/Feature/ReviewPack/ReviewPackValidRiskAcceptanceTest.php +++ b/apps/platform/tests/Feature/ReviewPack/ReviewPackValidRiskAcceptanceTest.php @@ -30,12 +30,12 @@ createUserWithTenant(tenant: $tenant, user: $approver, role: 'owner', workspaceRole: 'manager'); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, ]); @@ -89,7 +89,7 @@ $payload = $snapshotService->buildSnapshotPayload($tenant); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'fingerprint' => $payload['fingerprint'], @@ -100,7 +100,7 @@ foreach ($payload['items'] as $item) { $snapshot->items()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => $item['dimension_key'], 'state' => $item['state'], diff --git a/apps/platform/tests/Feature/ReviewPack/ReviewPackWidgetTest.php b/apps/platform/tests/Feature/ReviewPack/ReviewPackWidgetTest.php index e18cefa8..3b341c6e 100644 --- a/apps/platform/tests/Feature/ReviewPack/ReviewPackWidgetTest.php +++ b/apps/platform/tests/Feature/ReviewPack/ReviewPackWidgetTest.php @@ -8,7 +8,7 @@ use App\Models\OperationRun; use App\Models\ReviewPack; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Evidence\EvidenceSnapshotService; use App\Support\Evidence\EvidenceSnapshotStatus; use App\Support\OperationRunOutcome; @@ -26,27 +26,27 @@ Storage::fake('exports'); }); -function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot +function seedWidgetReviewPackSnapshot(ManagedEnvironment $tenant): EvidenceSnapshot { StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => ['required_count' => 1, 'granted_count' => 1], ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'payload' => ['roles' => [['displayName' => 'Global Administrator']]], ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]); @@ -64,7 +64,7 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot $payload = $service->buildSnapshotPayload($tenant); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'fingerprint' => $payload['fingerprint'], @@ -75,7 +75,7 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot foreach ($payload['items'] as $item) { $snapshot->items()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => $item['dimension_key'], 'state' => $item['state'], @@ -97,7 +97,7 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot // ─── No Pack State ─────────────────────────────────────────── it('shows the generate CTA when no pack exists', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); setTenantPanelContext($tenant); @@ -112,14 +112,14 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot // ─── Ready State ───────────────────────────────────────────── it('shows download and generate buttons when a ready pack exists', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $filePath = 'review-packs/widget-test.zip'; Storage::disk('exports')->put($filePath, 'PK-test'); ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'file_path' => $filePath, @@ -138,11 +138,11 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot // ─── Generating State ──────────────────────────────────────── it('shows in-progress message for a generating pack', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ReviewPack::factory()->generating()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -158,11 +158,11 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot // ─── Queued State ──────────────────────────────────────────── it('shows in-progress message for a queued pack', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ReviewPack::factory()->queued()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -178,11 +178,11 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot // ─── Failed State ──────────────────────────────────────────── it('shows retry button for a failed pack', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ReviewPack::factory()->failed()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -196,11 +196,11 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot }); it('renders translated reason semantics for failed review-pack runs when available', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'tenant.review_pack.generate', 'status' => 'completed', @@ -216,7 +216,7 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot ]); ReviewPack::factory()->failed()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'operation_run_id' => (int) $run->getKey(), @@ -243,11 +243,11 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot // ─── Expired State ─────────────────────────────────────────── it('shows generate action for an expired pack', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ReviewPack::factory()->expired()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); @@ -263,7 +263,7 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot // ─── Generate Pack Livewire Action ────────────────────────── it('can trigger generatePack Livewire action', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); seedWidgetReviewPackSnapshot($tenant); @@ -274,5 +274,5 @@ function seedWidgetReviewPackSnapshot(Tenant $tenant): EvidenceSnapshot ->call('generatePack', true, true) ->assertHasNoErrors(); - expect(ReviewPack::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(1); + expect(ReviewPack::query()->where('managed_environment_id', (int) $tenant->getKey())->count())->toBe(1); }); diff --git a/apps/platform/tests/Feature/ReviewPack/TenantReviewDerivedReviewPackTest.php b/apps/platform/tests/Feature/ReviewPack/TenantReviewDerivedReviewPackTest.php index c47de33c..73d647d6 100644 --- a/apps/platform/tests/Feature/ReviewPack/TenantReviewDerivedReviewPackTest.php +++ b/apps/platform/tests/Feature/ReviewPack/TenantReviewDerivedReviewPackTest.php @@ -59,7 +59,7 @@ ->and(data_get($summary, 'delivery_bundle.executive_entrypoint_file'))->toBe(ReviewPackService::EXECUTIVE_ENTRYPOINT_FILENAME) ->and(data_get($summary, 'tenant_review_id'))->toBe((int) $review->getKey()) ->and(collect($sections)->pluck('section_key')->all())->not->toContain('operations_health') - ->and($executiveEntrypoint)->toContain('Tenant: [REDACTED]') + ->and($executiveEntrypoint)->toContain('ManagedEnvironment: [REDACTED]') ->and($executiveEntrypoint)->toContain('This executive entrypoint is the first file to read') ->and($executiveEntrypoint)->not->toContain((string) $review->fingerprint) ->and($executiveEntrypoint)->not->toContain((string) $review->evidenceSnapshot?->fingerprint); diff --git a/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceAuthorizationTest.php b/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceAuthorizationTest.php index 312bbe54..7d4d1f58 100644 --- a/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceAuthorizationTest.php +++ b/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceAuthorizationTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\Reviews\CustomerReviewWorkspace; use App\Models\AuditLog; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -41,7 +41,7 @@ }); it('allows entitled workspace members to access the customer review workspace', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $this->actingAs($user) @@ -61,12 +61,12 @@ }); it('returns 404 for explicit out-of-scope tenant targeting on the customer review workspace', function (): void { - $tenantAllowed = Tenant::factory()->create(['name' => 'Allowed Tenant']); + $tenantAllowed = ManagedEnvironment::factory()->create(['name' => 'Allowed ManagedEnvironment']); [$user, $tenantAllowed] = createUserWithTenant(tenant: $tenantAllowed, role: 'readonly'); - $tenantDenied = Tenant::factory()->create([ + $tenantDenied = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantAllowed->workspace_id, - 'name' => 'Denied Tenant', + 'name' => 'Denied ManagedEnvironment', ]); $otherOwner = User::factory()->create(); createUserWithTenant(tenant: $tenantDenied, user: $otherOwner, role: 'owner'); diff --git a/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php b/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php index e39f46fe..35e672e9 100644 --- a/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php +++ b/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php @@ -11,7 +11,7 @@ use App\Models\AuditLog; use App\Models\EvidenceSnapshot; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Support\Audit\AuditActionId; use App\Support\Evidence\EvidenceSnapshotStatus; @@ -27,7 +27,7 @@ }); it('renders a customer workspace link from tenant review detail context', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = seedTenantReviewEvidence($tenant); @@ -45,10 +45,10 @@ }); it('adds a customer workspace entry to evidence snapshot related context', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'summary' => [], @@ -63,7 +63,7 @@ }); it('renders a customer workspace link from review pack detail context', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = seedTenantReviewEvidence($tenant); @@ -77,7 +77,7 @@ Storage::disk('exports')->put('review-packs/customer-workspace-link.zip', 'PK-test'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -93,7 +93,7 @@ }); it('renders a customer workspace launch button on the tenant review pack widget', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = seedTenantReviewEvidence($tenant); @@ -107,7 +107,7 @@ Storage::disk('exports')->put('review-packs/widget-customer-workspace.zip', 'PK-test'); ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -125,7 +125,7 @@ }); it('keeps the linked tenant review detail read-only for a readonly-capable actor', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $snapshot = seedTenantReviewEvidence($tenant); @@ -139,7 +139,7 @@ Storage::disk('exports')->put('review-packs/customer-workspace-detail-download.zip', 'PK-test'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), diff --git a/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceNavigationContextTest.php b/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceNavigationContextTest.php index 230ca340..40d647da 100644 --- a/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceNavigationContextTest.php +++ b/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceNavigationContextTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Governance\GovernanceInbox; use App\Filament\Pages\Reviews\CustomerReviewWorkspace; use App\Filament\Resources\TenantReviewResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Navigation\CanonicalNavigationContext; use App\Support\TenantReviewStatus; use App\Support\Workspaces\WorkspaceContext; @@ -13,9 +13,9 @@ use Livewire\Livewire; it('keeps the customer review workspace secondary when opened from the governance inbox', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); @@ -40,7 +40,7 @@ tenantId: (int) $tenant->getKey(), familyKey: 'review_follow_up', backLinkUrl: GovernanceInbox::getUrl(panel: 'admin', parameters: [ - 'tenant_id' => (string) $tenant->getKey(), + 'managed_environment_id' => (string) $tenant->getKey(), 'family' => 'review_follow_up', ]), ); @@ -50,7 +50,7 @@ ])) ->actingAs($user) ->test(CustomerReviewWorkspace::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenant->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenant->getKey()) ->assertActionVisible('return_to_governance_inbox') ->assertCanSeeTableRecords([$tenant->fresh()]) ->assertSee(TenantReviewResource::tenantScopedUrl('view', ['record' => $review->fresh()], $tenant), false) diff --git a/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePackAccessTest.php b/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePackAccessTest.php index f74c44dc..98462362 100644 --- a/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePackAccessTest.php +++ b/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePackAccessTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\TenantReviewResource; use App\Models\PlatformUser; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\Entitlements\WorkspaceCommercialLifecycleResolver; use App\Services\Settings\SettingsWriter; @@ -20,7 +20,7 @@ uses(RefreshDatabase::class); -function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void +function suspendCustomerReviewWorkspacePackAccessWorkspace(ManagedEnvironment $tenant): void { app(SettingsWriter::class)->updateWorkspaceCommercialLifecycle( actor: PlatformUser::factory()->create([ @@ -38,7 +38,7 @@ function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void } it('keeps the latest released review as the only row action when a ready review pack exists', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $snapshot = seedTenantReviewEvidence($tenant); @@ -50,7 +50,7 @@ function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void ])->save(); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -76,7 +76,7 @@ function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void }); it('keeps the customer review workspace row action visible while suspended read-only', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $snapshot = seedTenantReviewEvidence($tenant); @@ -88,7 +88,7 @@ function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void ])->save(); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -115,7 +115,7 @@ function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void }); it('does not expose review-pack availability as a workspace row peer action', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $snapshot = seedTenantReviewEvidence($tenant); @@ -140,7 +140,7 @@ function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void }); it('shows a partial governance-package state when the released review basis is limitation-aware', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $snapshot = seedPartialTenantReviewEvidence($tenant); @@ -152,7 +152,7 @@ function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void ])->save(); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -176,11 +176,11 @@ function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void }); it('shows expired and capability-blocked governance-package states on the workspace row surface', function (): void { - $expiredTenant = Tenant::factory()->create(['name' => 'Expired Pack Tenant']); + $expiredTenant = ManagedEnvironment::factory()->create(['name' => 'Expired Pack ManagedEnvironment']); [$user, $expiredTenant] = createUserWithTenant(tenant: $expiredTenant, role: 'readonly'); - $blockedTenant = Tenant::factory()->create([ + $blockedTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $expiredTenant->workspace_id, - 'name' => 'Blocked Pack Tenant', + 'name' => 'Blocked Pack ManagedEnvironment', ]); createUserWithTenant(tenant: $blockedTenant, user: $user, role: 'readonly'); @@ -194,7 +194,7 @@ function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void ])->save(); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -205,7 +205,7 @@ function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void $review->forceFill(['current_export_review_pack_id' => (int) $pack->getKey()])->save(); } - Gate::define(Capabilities::REVIEW_PACK_VIEW, fn (User $actor, Tenant $tenant): bool => ! $tenant->is($blockedTenant)); + Gate::define(Capabilities::REVIEW_PACK_VIEW, fn (User $actor, ManagedEnvironment $tenant): bool => ! $tenant->is($blockedTenant)); $this->actingAs($user); setAdminPanelContext(); @@ -220,7 +220,7 @@ function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $tenant): void }); it('hides tenants without a published review from the workspace rows', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $snapshot = seedTenantReviewEvidence($tenant); diff --git a/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePageTest.php b/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePageTest.php index dd9f41e6..210859a9 100644 --- a/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePageTest.php +++ b/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePageTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\TenantReviewResource; use App\Models\Finding; use App\Models\FindingException; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Governance\Controls\ComplianceEvidenceMappingV1; use App\Support\TenantReviewStatus; @@ -17,18 +17,18 @@ uses(RefreshDatabase::class); it('lists only the latest published review per entitled tenant on the customer review workspace', function (): void { - $tenantA = Tenant::factory()->create(['name' => 'Alpha Tenant']); + $tenantA = ManagedEnvironment::factory()->create(['name' => 'Alpha ManagedEnvironment']); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'readonly'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'readonly'); - $tenantDenied = Tenant::factory()->create([ + $tenantDenied = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Denied Tenant', + 'name' => 'Denied ManagedEnvironment', ]); $otherOwner = User::factory()->create(); createUserWithTenant(tenant: $tenantDenied, user: $otherOwner, role: 'owner'); @@ -47,7 +47,7 @@ $newerInternalReview = $olderPublishedReview->replicate(); $newerInternalReview->forceFill([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'evidence_snapshot_id' => (int) $tenantASnapshot->getKey(), 'status' => TenantReviewStatus::Ready->value, @@ -58,7 +58,7 @@ $latestPublishedReview = $olderPublishedReview->replicate(); $latestPublishedReview->forceFill([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'evidence_snapshot_id' => (int) $tenantASnapshot->getKey(), 'status' => TenantReviewStatus::Published->value, @@ -118,12 +118,12 @@ }); it('excludes entitled tenants without a published review from customer workspace rows', function (): void { - $tenantPublished = Tenant::factory()->create(['name' => 'Published Tenant']); + $tenantPublished = ManagedEnvironment::factory()->create(['name' => 'Published ManagedEnvironment']); [$user, $tenantPublished] = createUserWithTenant(tenant: $tenantPublished, role: 'readonly'); - $tenantWithoutPublished = Tenant::factory()->create([ + $tenantWithoutPublished = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantPublished->workspace_id, - 'name' => 'No Published Tenant', + 'name' => 'No Published ManagedEnvironment', ]); createUserWithTenant(tenant: $tenantWithoutPublished, user: $user, role: 'readonly'); @@ -159,7 +159,7 @@ }); it('uses a page-level empty state when no entitled tenant has a released review', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Internal Only Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Internal Only ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $snapshot = seedTenantReviewEvidence($tenant); @@ -183,18 +183,18 @@ }); it('summarizes accepted-risk control interpretation and evidence proof availability in customer-safe workspace rows', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Governed Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Governed ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $owner = User::factory()->create(['name' => 'Risk Owner']); $finding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => Finding::STATUS_RISK_ACCEPTED, ]); FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'status' => FindingException::STATUS_ACTIVE, 'current_validity_state' => FindingException::VALIDITY_VALID, @@ -233,12 +233,12 @@ }); it('defaults the customer review workspace to the remembered tenant when tenant context is available', function (): void { - $tenantA = Tenant::factory()->create(['name' => 'Alpha Tenant']); + $tenantA = ManagedEnvironment::factory()->create(['name' => 'Alpha ManagedEnvironment']); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'readonly'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'readonly'); @@ -268,19 +268,19 @@ Livewire::actingAs($user) ->test(CustomerReviewWorkspace::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantB->getKey()) - ->filterTable('tenant_id', (string) $tenantB->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantB->getKey()) + ->filterTable('managed_environment_id', (string) $tenantB->getKey()) ->assertCanSeeTableRecords([$tenantB->fresh()]) ->assertCanNotSeeTableRecords([$tenantA->fresh()]); }); it('prefilters the customer review workspace from an explicit tenant query parameter and accepts external tenant identifiers', function (): void { - $tenantA = Tenant::factory()->create(['name' => 'Alpha Tenant']); + $tenantA = ManagedEnvironment::factory()->create(['name' => 'Alpha ManagedEnvironment']); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'readonly'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'readonly'); @@ -307,8 +307,8 @@ Livewire::withQueryParams(['tenant' => (string) $tenantA->external_id]) ->test(CustomerReviewWorkspace::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) - ->filterTable('tenant_id', (string) $tenantA->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()) + ->filterTable('managed_environment_id', (string) $tenantA->getKey()) ->assertCanSeeTableRecords([$tenantA->fresh()]) ->assertCanNotSeeTableRecords([$tenantB->fresh()]); }); diff --git a/apps/platform/tests/Feature/RunAuthorizationTenantIsolationTest.php b/apps/platform/tests/Feature/RunAuthorizationTenantIsolationTest.php index d84c17ce..74c638f5 100644 --- a/apps/platform/tests/Feature/RunAuthorizationTenantIsolationTest.php +++ b/apps/platform/tests/Feature/RunAuthorizationTenantIsolationTest.php @@ -7,7 +7,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -18,10 +18,10 @@ uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); test('operation runs default to the active tenant when tenant context is set', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -31,21 +31,21 @@ ]); $runA = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', - 'initiator_name' => 'Tenant A Scope', + 'initiator_name' => 'ManagedEnvironment A Scope', ]); $runB = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', 'status' => 'queued', 'outcome' => 'pending', - 'initiator_name' => 'Tenant B Scope', + 'initiator_name' => 'ManagedEnvironment B Scope', ]); Filament::setTenant($tenantA, true); @@ -57,7 +57,7 @@ ->test(Operations::class) ->assertCanSeeTableRecords([$runA]) ->assertCanNotSeeTableRecords([$runB]) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()); + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()); }); test('operation run view is not accessible cross-workspace', function (): void { @@ -72,13 +72,13 @@ 'role' => 'owner', ]); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $workspaceB->getKey(), ]); $runB = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $workspaceB->getKey(), 'type' => 'inventory_sync', 'status' => 'queued', @@ -92,10 +92,10 @@ }); test('readonly users can view operation runs in their workspace', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'queued', @@ -121,13 +121,13 @@ test('tenant-associated run viewer requires tenant entitlement even for workspace members', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'status' => 'active', ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'type' => 'provider.connection.check', 'status' => 'queued', @@ -150,13 +150,13 @@ test('baseline compare runs with RBAC context still require tenant entitlement', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'status' => 'active', ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'type' => 'baseline_compare', 'status' => 'completed', @@ -190,10 +190,10 @@ }); test('canonical run detail returns 403 for in-scope members missing the required capability', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'queued', @@ -211,10 +211,10 @@ }); test('reconciled lifecycle run detail keeps capability denial semantics', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'inventory_sync', 'status' => 'completed', @@ -247,10 +247,10 @@ }); test('tenant-scoped restore run actions return 404 for forged foreign-tenant run keys', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, ]); @@ -260,11 +260,11 @@ ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), ]); $foreignRun = RestoreRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), 'status' => 'completed', 'is_dry_run' => true, diff --git a/apps/platform/tests/Feature/RunStartAuthorizationTest.php b/apps/platform/tests/Feature/RunStartAuthorizationTest.php index 28e050b4..10de81c9 100644 --- a/apps/platform/tests/Feature/RunStartAuthorizationTest.php +++ b/apps/platform/tests/Feature/RunStartAuthorizationTest.php @@ -7,7 +7,7 @@ use App\Jobs\RunBackupScheduleJob; use App\Models\BackupSchedule; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Inventory\InventorySyncService; use Filament\Facades\Filament; use Illuminate\Support\Facades\Queue; @@ -19,7 +19,7 @@ Queue::fake(); [$user, $tenantA] = createUserWithTenant(role: 'owner'); - $tenantB = Tenant::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); $this->actingAs($user); Filament::setTenant($tenantA, true); @@ -28,13 +28,13 @@ $allTypes = $sync->defaultSelectionPayload()['policy_types']; Livewire::test(ListInventoryItems::class) - ->callAction('run_inventory_sync', data: ['tenant_id' => $tenantB->getKey(), 'policy_types' => $allTypes]) + ->callAction('run_inventory_sync', data: ['managed_environment_id' => $tenantB->getKey(), 'policy_types' => $allTypes]) ->assertSuccessful(); Queue::assertNothingPushed(); - expect(OperationRun::query()->where('tenant_id', $tenantB->id)->where('type', 'inventory_sync')->exists())->toBeFalse(); - expect(OperationRun::query()->where('tenant_id', $tenantB->id)->exists())->toBeFalse(); + expect(OperationRun::query()->where('managed_environment_id', $tenantB->id)->where('type', 'inventory_sync')->exists())->toBeFalse(); + expect(OperationRun::query()->where('managed_environment_id', $tenantB->id)->exists())->toBeFalse(); }); it('prevents run creation when a readonly member tries to start inventory sync', function () { @@ -50,11 +50,11 @@ Livewire::test(ListInventoryItems::class) ->assertActionVisible('run_inventory_sync') ->assertActionDisabled('run_inventory_sync') - ->callAction('run_inventory_sync', data: ['tenant_id' => $tenant->getKey(), 'policy_types' => $allTypes]); + ->callAction('run_inventory_sync', data: ['managed_environment_id' => $tenant->getKey(), 'policy_types' => $allTypes]); Queue::assertNothingPushed(); - expect(OperationRun::query()->where('tenant_id', $tenant->id)->where('type', 'inventory_sync')->exists())->toBeFalse(); - expect(OperationRun::query()->where('tenant_id', $tenant->id)->exists())->toBeFalse(); + expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->where('type', 'inventory_sync')->exists())->toBeFalse(); + expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->exists())->toBeFalse(); }); it('prevents run creation when a readonly member tries to start directory group sync', function () { @@ -70,7 +70,7 @@ ->callAction('sync_groups'); Queue::assertNotPushed(EntraGroupSyncJob::class); - expect(OperationRun::query()->where('tenant_id', $tenant->id)->exists())->toBeFalse(); + expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->exists())->toBeFalse(); }); it('prevents run creation when a readonly member tries to run a backup schedule now', function () { @@ -81,7 +81,7 @@ Filament::setTenant($tenant, true); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly', 'is_enabled' => true, 'timezone' => 'UTC', @@ -99,7 +99,7 @@ ->callTableAction('runNow', $schedule); Queue::assertNothingPushed(); - expect(OperationRun::query()->where('tenant_id', $tenant->id)->exists())->toBeFalse(); + expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->exists())->toBeFalse(); }); it('prevents run creation when a readonly member tries to retry a backup schedule', function () { @@ -110,7 +110,7 @@ Filament::setTenant($tenant, true); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Nightly', 'is_enabled' => true, 'timezone' => 'UTC', @@ -128,5 +128,5 @@ ->callTableAction('retry', $schedule); Queue::assertNothingPushed(); - expect(OperationRun::query()->where('tenant_id', $tenant->id)->exists())->toBeFalse(); + expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->exists())->toBeFalse(); }); diff --git a/apps/platform/tests/Feature/Scheduling/PruneOldOperationRunsScheduleTest.php b/apps/platform/tests/Feature/Scheduling/PruneOldOperationRunsScheduleTest.php index 0633f8c3..f251eb67 100644 --- a/apps/platform/tests/Feature/Scheduling/PruneOldOperationRunsScheduleTest.php +++ b/apps/platform/tests/Feature/Scheduling/PruneOldOperationRunsScheduleTest.php @@ -40,7 +40,7 @@ $createRun = function (Workspace $workspace, int $ageDays, string $identitySuffix): OperationRun { return OperationRun::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'user_id' => null, 'initiator_name' => 'System', 'type' => 'maintenance', diff --git a/apps/platform/tests/Feature/Seed/PoliciesSeederExternalIdTest.php b/apps/platform/tests/Feature/Seed/PoliciesSeederExternalIdTest.php index a7836511..ae69117f 100644 --- a/apps/platform/tests/Feature/Seed/PoliciesSeederExternalIdTest.php +++ b/apps/platform/tests/Feature/Seed/PoliciesSeederExternalIdTest.php @@ -1,12 +1,10 @@ set('tenantpilot.supported_policy_types', []); $_ENV['INTUNE_TENANT_ID'] = 'seed-tenant-id'; @@ -16,14 +14,9 @@ $this->artisan('db:seed', ['--class' => Database\Seeders\PoliciesSeeder::class]) ->assertExitCode(0); - $tenant = Tenant::query()->first(); + $tenant = ManagedEnvironment::query()->first(); expect($tenant)->not->toBeNull(); - expect($tenant?->tenant_id)->toBe('seed-tenant-id'); - - $externalId = (string) ($tenant?->external_id ?? ''); - - expect(Str::isUuid($externalId))->toBeTrue(); - expect(substr($externalId, 14, 1))->toBe('4'); - expect(in_array(strtolower(substr($externalId, 19, 1)), ['8', '9', 'a', 'b'], true))->toBeTrue(); + expect($tenant?->managed_environment_id)->toBe('seed-tenant-id'); + expect($tenant?->external_id)->toBe('seed-tenant-id'); }); diff --git a/apps/platform/tests/Feature/SettingsFoundation/RetentionFallbackUsesWorkspaceDefaultTest.php b/apps/platform/tests/Feature/SettingsFoundation/RetentionFallbackUsesWorkspaceDefaultTest.php index 38e12efb..6d6dd075 100644 --- a/apps/platform/tests/Feature/SettingsFoundation/RetentionFallbackUsesWorkspaceDefaultTest.php +++ b/apps/platform/tests/Feature/SettingsFoundation/RetentionFallbackUsesWorkspaceDefaultTest.php @@ -20,7 +20,7 @@ ]); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Nightly fallback', 'is_enabled' => true, 'timezone' => 'UTC', @@ -34,7 +34,7 @@ $sets = collect(range(1, 5))->map(function (int $index) use ($tenant): BackupSet { return BackupSet::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Set '.$index, 'status' => 'completed', 'item_count' => 0, @@ -47,7 +47,7 @@ foreach ($sets as $set) { OperationRun::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => null, 'initiator_name' => 'System', 'type' => 'backup_schedule_run', diff --git a/apps/platform/tests/Feature/SettingsFoundation/RetentionScheduleOverrideWinsTest.php b/apps/platform/tests/Feature/SettingsFoundation/RetentionScheduleOverrideWinsTest.php index 2aa4aa26..27c6aae0 100644 --- a/apps/platform/tests/Feature/SettingsFoundation/RetentionScheduleOverrideWinsTest.php +++ b/apps/platform/tests/Feature/SettingsFoundation/RetentionScheduleOverrideWinsTest.php @@ -20,7 +20,7 @@ ]); $schedule = BackupSchedule::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Nightly override', 'is_enabled' => true, 'timezone' => 'UTC', @@ -34,7 +34,7 @@ $sets = collect(range(1, 5))->map(function (int $index) use ($tenant): BackupSet { return BackupSet::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Set '.$index, 'status' => 'completed', 'item_count' => 0, @@ -47,7 +47,7 @@ foreach ($sets as $set) { OperationRun::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => null, 'initiator_name' => 'System', 'type' => 'backup_schedule_run', diff --git a/apps/platform/tests/Feature/SettingsFoundation/TenantOverrideScopeSafetyTest.php b/apps/platform/tests/Feature/SettingsFoundation/TenantOverrideScopeSafetyTest.php index 43a7e96a..b2be35b9 100644 --- a/apps/platform/tests/Feature/SettingsFoundation/TenantOverrideScopeSafetyTest.php +++ b/apps/platform/tests/Feature/SettingsFoundation/TenantOverrideScopeSafetyTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\AuditLog; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantSetting; use App\Models\User; use App\Models\Workspace; @@ -15,7 +15,7 @@ $workspaceA = Workspace::factory()->create(); $workspaceB = Workspace::factory()->create(); - $tenantInWorkspaceB = Tenant::factory()->create([ + $tenantInWorkspaceB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceB->getKey(), ]); diff --git a/apps/platform/tests/Feature/SettingsFoundation/WorkspaceSettingsAuditTest.php b/apps/platform/tests/Feature/SettingsFoundation/WorkspaceSettingsAuditTest.php index 27d22755..a99287f1 100644 --- a/apps/platform/tests/Feature/SettingsFoundation/WorkspaceSettingsAuditTest.php +++ b/apps/platform/tests/Feature/SettingsFoundation/WorkspaceSettingsAuditTest.php @@ -31,7 +31,7 @@ expect($audit)->not->toBeNull() ->and($audit?->workspace_id)->toBe((int) $workspace->getKey()) - ->and($audit?->tenant_id)->toBeNull() + ->and($audit?->managed_environment_id)->toBeNull() ->and($audit?->action)->toBe(AuditActionId::WorkspaceSettingUpdated->value) ->and(data_get($audit?->metadata, 'domain'))->toBe('backup') ->and(data_get($audit?->metadata, 'key'))->toBe('retention_keep_last_default') @@ -74,7 +74,7 @@ expect($audit)->not->toBeNull() ->and($audit?->workspace_id)->toBe((int) $workspace->getKey()) - ->and($audit?->tenant_id)->toBeNull() + ->and($audit?->managed_environment_id)->toBeNull() ->and(data_get($audit?->metadata, 'scope'))->toBe('workspace') ->and(data_get($audit?->metadata, 'before_value'))->toBe(48) ->and(data_get($audit?->metadata, 'after_value'))->toBe(30); @@ -102,7 +102,7 @@ expect($audit)->not->toBeNull() ->and($audit?->workspace_id)->toBe((int) $workspace->getKey()) - ->and($audit?->tenant_id)->toBeNull() + ->and($audit?->managed_environment_id)->toBeNull() ->and($audit?->action)->toBe(AuditActionId::WorkspaceSettingUpdated->value) ->and(data_get($audit?->metadata, 'domain'))->toBe('ai') ->and(data_get($audit?->metadata, 'key'))->toBe('policy_mode') @@ -145,7 +145,7 @@ expect($audit)->not->toBeNull() ->and($audit?->workspace_id)->toBe((int) $workspace->getKey()) - ->and($audit?->tenant_id)->toBeNull() + ->and($audit?->managed_environment_id)->toBeNull() ->and(data_get($audit?->metadata, 'domain'))->toBe('ai') ->and(data_get($audit?->metadata, 'key'))->toBe('policy_mode') ->and(data_get($audit?->metadata, 'scope'))->toBe('workspace') diff --git a/apps/platform/tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php b/apps/platform/tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php index e1c3bebc..9f5f6a35 100644 --- a/apps/platform/tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php +++ b/apps/platform/tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php @@ -6,7 +6,7 @@ use App\Filament\Resources\TenantResource; use App\Models\AuditLog; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -33,7 +33,7 @@ }); it('returns 404 for non-members on the workspace-managed tenants index', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $this->actingAs($user) @@ -58,11 +58,11 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get("/admin/tenants/{$tenant->external_id}") ->assertOk() - ->assertSee('/admin/provider-connections?tenant_id='.$tenant->external_id, false); + ->assertSee('/admin/provider-connections?managed_environment_id='.$tenant->external_id, false); }); it('returns 404 for non-members on the workspace-managed tenant view route', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $this->actingAs($user) @@ -83,10 +83,10 @@ it('requires tenant entitlement for the contracted tenant operational routes', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'external_id' => '11111111-1111-1111-1111-111111111111', - 'tenant_id' => '11111111-1111-1111-1111-111111111111', + 'managed_environment_id' => '11111111-1111-1111-1111-111111111111', ]); [$entitledUser] = createMinimalUserWithTenant(tenant: $tenant, role: 'readonly'); @@ -157,7 +157,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $this->followingRedirects() @@ -218,7 +218,7 @@ ); $actions = AuditLog::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereIn('action', [ AuditActionId::TenantMembershipAdd->value, AuditActionId::TenantMembershipRoleChange->value, diff --git a/apps/platform/tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php b/apps/platform/tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php index 05207e9d..d326ba70 100644 --- a/apps/platform/tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php +++ b/apps/platform/tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -16,7 +16,7 @@ }); it('does not set or clear tenant context on GET /admin/operations', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); Filament::setTenant($tenant, true); @@ -30,7 +30,7 @@ }); it('renders workspace scope label when no tenant context is active', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); Filament::setTenant(null, true); @@ -45,17 +45,17 @@ }); it('does not mutate remembered tenant context when opening a canonical operation run for another tenant', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory_sync', ]); diff --git a/apps/platform/tests/Feature/Spec085/DenyAsNotFoundSemanticsTest.php b/apps/platform/tests/Feature/Spec085/DenyAsNotFoundSemanticsTest.php index bfdb2d87..3e38aee0 100644 --- a/apps/platform/tests/Feature/Spec085/DenyAsNotFoundSemanticsTest.php +++ b/apps/platform/tests/Feature/Spec085/DenyAsNotFoundSemanticsTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\TenantDashboard; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\OperationRunOutcome; @@ -36,7 +36,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => null, + 'managed_environment_id' => null, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -63,10 +63,10 @@ }); it('returns 404 for non-entitled users on tenant dashboard direct access', function (): void { - $tenantA = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); diff --git a/apps/platform/tests/Feature/Spec085/OperationsIndexHeaderTest.php b/apps/platform/tests/Feature/Spec085/OperationsIndexHeaderTest.php index 6b71bd6f..297b727a 100644 --- a/apps/platform/tests/Feature/Spec085/OperationsIndexHeaderTest.php +++ b/apps/platform/tests/Feature/Spec085/OperationsIndexHeaderTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -15,7 +15,7 @@ }); it('renders tenant scope label and CTAs when tenant context is active and entitled', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); Filament::setTenant($tenant, true); @@ -24,16 +24,16 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get('/admin/operations') ->assertOk() - ->assertSee('Tenant scope: '.$tenant->name) + ->assertSee('ManagedEnvironment scope: '.$tenant->name) ->assertSee('Back to '.$tenant->name) ->assertSee('Show all tenants'); }); it('treats stale tenant context as workspace-wide without tenant identity hints', function (): void { - $entitledTenant = Tenant::factory()->create(); + $entitledTenant = ManagedEnvironment::factory()->create(); [$user, $entitledTenant] = createUserWithTenant($entitledTenant, role: 'owner', workspaceRole: 'readonly'); - $staleTenant = Tenant::factory()->create([ + $staleTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $entitledTenant->workspace_id, ]); @@ -50,7 +50,7 @@ }); it('clears filament tenant context and last-tenant session state via clear-tenant-context endpoint', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $workspaceId = (int) $tenant->workspace_id; @@ -79,14 +79,14 @@ ->get('/admin/operations') ->assertOk() ->assertSee('All tenants') - ->assertDontSee('Tenant scope: '.$tenant->name); + ->assertDontSee('ManagedEnvironment scope: '.$tenant->name); }); it('clears remembered tenant scope even when the stored tenant is no longer operable', function (): void { - $activeTenant = Tenant::factory()->create(); + $activeTenant = ManagedEnvironment::factory()->create(); [$user, $activeTenant] = createUserWithTenant($activeTenant, role: 'owner'); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, ]); diff --git a/apps/platform/tests/Feature/Spec085/RunDetailBackAffordanceTest.php b/apps/platform/tests/Feature/Spec085/RunDetailBackAffordanceTest.php index d08708dd..e1a077c1 100644 --- a/apps/platform/tests/Feature/Spec085/RunDetailBackAffordanceTest.php +++ b/apps/platform/tests/Feature/Spec085/RunDetailBackAffordanceTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\Workspaces\WorkspaceContext; @@ -18,12 +18,12 @@ }); it('shows back-to-tenant and show-all-operations when tenant context is active and entitled', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -41,12 +41,12 @@ }); it('shows only back-to-operations when no tenant context is active', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -64,16 +64,16 @@ }); it('treats stale tenant context as workspace-wide on run detail', function (): void { - $entitledTenant = Tenant::factory()->create(); + $entitledTenant = ManagedEnvironment::factory()->create(); [$user, $entitledTenant] = createUserWithTenant($entitledTenant, role: 'owner', workspaceRole: 'readonly'); - $staleTenant = Tenant::factory()->create([ + $staleTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $entitledTenant->workspace_id, ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $entitledTenant->workspace_id, - 'tenant_id' => (int) $entitledTenant->getKey(), + 'managed_environment_id' => (int) $entitledTenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, diff --git a/apps/platform/tests/Feature/Spec085/TenantNavigationMonitoringShortcutsTest.php b/apps/platform/tests/Feature/Spec085/TenantNavigationMonitoringShortcutsTest.php index 746bdde2..6e378683 100644 --- a/apps/platform/tests/Feature/Spec085/TenantNavigationMonitoringShortcutsTest.php +++ b/apps/platform/tests/Feature/Spec085/TenantNavigationMonitoringShortcutsTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -16,7 +16,7 @@ }); it('shows a Monitoring group with central shortcuts in the tenant sidebar', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $this->actingAs($user) diff --git a/apps/platform/tests/Feature/StoredReports/StoredReportDetailPresentationTest.php b/apps/platform/tests/Feature/StoredReports/StoredReportDetailPresentationTest.php index 8ab38c8e..150e19bf 100644 --- a/apps/platform/tests/Feature/StoredReports/StoredReportDetailPresentationTest.php +++ b/apps/platform/tests/Feature/StoredReports/StoredReportDetailPresentationTest.php @@ -5,29 +5,29 @@ use App\Filament\Resources\StoredReportResource; use App\Filament\Resources\StoredReportResource\Pages\ViewStoredReport; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; use Livewire\Livewire; uses(RefreshDatabase::class); -function storedReportDetailPermissionReport(Tenant $tenant, array $payload = [], array $attributes = []): StoredReport +function storedReportDetailPermissionReport(ManagedEnvironment $tenant, array $payload = [], array $attributes = []): StoredReport { return StoredReport::factory() ->permissionPosture($payload) ->create(array_merge([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'fingerprint' => 'permission-detail', ], $attributes)); } -function storedReportDetailEntraReport(Tenant $tenant, array $payload = [], array $attributes = []): StoredReport +function storedReportDetailEntraReport(ManagedEnvironment $tenant, array $payload = [], array $attributes = []): StoredReport { return StoredReport::factory() ->entraAdminRoles($payload) ->create(array_merge([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'fingerprint' => 'entra-detail', ], $attributes)); @@ -162,7 +162,7 @@ function storedReportDetailHeaderActionNames(ViewStoredReport $page): array [$user, $tenant] = createUserWithTenant(role: 'owner'); $unsupported = StoredReport::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'report_type' => 'future.report', 'payload' => ['summary' => 'Unsupported'], diff --git a/apps/platform/tests/Feature/StoredReports/StoredReportEntitlementEnforcementTest.php b/apps/platform/tests/Feature/StoredReports/StoredReportEntitlementEnforcementTest.php index b3beb16c..5797c9bd 100644 --- a/apps/platform/tests/Feature/StoredReports/StoredReportEntitlementEnforcementTest.php +++ b/apps/platform/tests/Feature/StoredReports/StoredReportEntitlementEnforcementTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\StoredReportResource; use App\Filament\Resources\StoredReportResource\Pages\ListStoredReports; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Services\Auth\RoleCapabilityMap; use App\Support\Auth\Capabilities; @@ -17,23 +17,23 @@ uses(RefreshDatabase::class); -function storedReportEntitlementPermissionReport(Tenant $tenant): StoredReport +function storedReportEntitlementPermissionReport(ManagedEnvironment $tenant): StoredReport { return StoredReport::factory() ->permissionPosture() ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'fingerprint' => 'permission-entitlement', ]); } -function storedReportEntitlementEntraReport(Tenant $tenant): StoredReport +function storedReportEntitlementEntraReport(ManagedEnvironment $tenant): StoredReport { return StoredReport::factory() ->entraAdminRoles() ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'fingerprint' => 'entra-entitlement', ]); @@ -50,7 +50,7 @@ function storedReportEntitlementEntraReport(Tenant $tenant): StoredReport it('returns 404 for non-members on stored-report collection and direct detail routes', function (): void { $user = \App\Models\User::factory()->create(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $report = storedReportEntitlementPermissionReport($tenant); $this->actingAs($user) @@ -108,7 +108,7 @@ function storedReportEntitlementEntraReport(Tenant $tenant): StoredReport [$user, $tenant] = createUserWithTenant(role: 'owner'); $unsupported = StoredReport::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'report_type' => 'future.report', 'payload' => ['name' => 'Unexpected'], @@ -124,7 +124,7 @@ function storedReportEntitlementEntraReport(Tenant $tenant): StoredReport $wrongWorkspace = Workspace::factory()->create(); $wrongWorkspaceReportId = DB::table('stored_reports')->insertGetId([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $wrongWorkspace->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => json_encode(['posture_score' => 1], JSON_THROW_ON_ERROR), diff --git a/apps/platform/tests/Feature/StoredReports/StoredReportResourceTest.php b/apps/platform/tests/Feature/StoredReports/StoredReportResourceTest.php index ba32f8d4..31268c94 100644 --- a/apps/platform/tests/Feature/StoredReports/StoredReportResourceTest.php +++ b/apps/platform/tests/Feature/StoredReports/StoredReportResourceTest.php @@ -5,7 +5,7 @@ use App\Filament\Resources\StoredReportResource; use App\Filament\Resources\StoredReportResource\Pages\ListStoredReports; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\DB; @@ -13,23 +13,23 @@ uses(RefreshDatabase::class); -function storedReportResourcePermissionReport(Tenant $tenant, array $payload = [], array $attributes = []): StoredReport +function storedReportResourcePermissionReport(ManagedEnvironment $tenant, array $payload = [], array $attributes = []): StoredReport { return StoredReport::factory() ->permissionPosture($payload) ->create(array_merge([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'fingerprint' => hash('sha256', 'permission-'.$tenant->getKey().'-'.microtime(true)), ], $attributes)); } -function storedReportResourceEntraReport(Tenant $tenant, array $payload = [], array $attributes = []): StoredReport +function storedReportResourceEntraReport(ManagedEnvironment $tenant, array $payload = [], array $attributes = []): StoredReport { return StoredReport::factory() ->entraAdminRoles($payload) ->create(array_merge([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'fingerprint' => hash('sha256', 'entra-'.$tenant->getKey().'-'.microtime(true)), ], $attributes)); @@ -51,7 +51,7 @@ function storedReportResourceEntraReport(Tenant $tenant, array $payload = [], ar it('lists only current supported tenant reports by default and can reveal history', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); - $otherTenant = Tenant::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); $historical = storedReportResourceEntraReport($tenant, [], [ 'created_at' => now()->subDays(2), @@ -71,7 +71,7 @@ function storedReportResourceEntraReport(Tenant $tenant, array $payload = [], ar ]); $wrongWorkspace = Workspace::factory()->create(); $wrongWorkspaceReportId = DB::table('stored_reports')->insertGetId([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $wrongWorkspace->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => json_encode([ @@ -87,7 +87,7 @@ function storedReportResourceEntraReport(Tenant $tenant, array $payload = [], ar storedReportResourcePermissionReport($otherTenant); StoredReport::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'report_type' => 'future.report', 'payload' => ['name' => 'Unexpected'], diff --git a/apps/platform/tests/Feature/SupportDiagnostics/OperationRunSupportDiagnosticActionTest.php b/apps/platform/tests/Feature/SupportDiagnostics/OperationRunSupportDiagnosticActionTest.php index b727a3f1..b2104964 100644 --- a/apps/platform/tests/Feature/SupportDiagnostics/OperationRunSupportDiagnosticActionTest.php +++ b/apps/platform/tests/Feature/SupportDiagnostics/OperationRunSupportDiagnosticActionTest.php @@ -10,7 +10,7 @@ use App\Models\ProviderConnection; use App\Models\ReviewPack; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Models\Workspace; @@ -36,13 +36,13 @@ function operationSupportDiagnosticsComponent(User $user, OperationRun $run): \L } it('opens a redacted support diagnostic bundle from the tenantless operation viewer', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Contoso Support Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Contoso Support ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $connection = ProviderConnection::factory() ->withCredential() ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Contoso Microsoft connection', 'verification_status' => ProviderVerificationStatus::Blocked->value, @@ -72,7 +72,7 @@ function operationSupportDiagnosticsComponent(User $user, OperationRun $run): \L ]); $finding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'current_operation_run_id' => (int) $run->getKey(), 'severity' => Finding::SEVERITY_HIGH, @@ -80,7 +80,7 @@ function operationSupportDiagnosticsComponent(User $user, OperationRun $run): \L ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => [ @@ -90,7 +90,7 @@ function operationSupportDiagnosticsComponent(User $user, OperationRun $run): \L ]); $evidenceSnapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'operation_run_id' => (int) $run->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), @@ -106,7 +106,7 @@ function operationSupportDiagnosticsComponent(User $user, OperationRun $run): \L ]); $review = TenantReview::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $evidenceSnapshot->getKey(), 'operation_run_id' => (int) $run->getKey(), @@ -114,7 +114,7 @@ function operationSupportDiagnosticsComponent(User $user, OperationRun $run): \L ]); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'operation_run_id' => (int) $run->getKey(), @@ -125,7 +125,7 @@ function operationSupportDiagnosticsComponent(User $user, OperationRun $run): \L AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'operation_run_id' => (int) $run->getKey(), 'action' => 'operation.failed', 'resource_type' => 'operation_run', @@ -151,7 +151,7 @@ function operationSupportDiagnosticsComponent(User $user, OperationRun $run): \L ->assertMountedActionModalSee('Contoso Microsoft connection') ->assertMountedActionModalSee('High finding #'.$finding->getKey()) ->assertMountedActionModalSee('permission posture report') - ->assertMountedActionModalSee('Tenant review #'.$review->getKey()) + ->assertMountedActionModalSee('ManagedEnvironment review #'.$review->getKey()) ->assertMountedActionModalSee('Review pack #'.$pack->getKey()) ->assertMountedActionModalSee('Operation failed') ->assertMountedActionModalSee('default-redacted') @@ -164,7 +164,7 @@ function operationSupportDiagnosticsComponent(User $user, OperationRun $run): \L it('keeps tenantless operation detail deny-as-not-found for workspace members without tenant entitlement', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -177,7 +177,7 @@ function operationSupportDiagnosticsComponent(User $user, OperationRun $run): \L ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/SupportDiagnostics/ProductKnowledgeAuthorizationTest.php b/apps/platform/tests/Feature/SupportDiagnostics/ProductKnowledgeAuthorizationTest.php index 6eea034d..228d3c38 100644 --- a/apps/platform/tests/Feature/SupportDiagnostics/ProductKnowledgeAuthorizationTest.php +++ b/apps/platform/tests/Feature/SupportDiagnostics/ProductKnowledgeAuthorizationTest.php @@ -6,7 +6,7 @@ use App\Filament\Pages\TenantDashboard; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -17,7 +17,7 @@ use Filament\Facades\Filament; use Livewire\Livewire; -function productKnowledgeSupportDiagnosticsTenantAuthorizationComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function productKnowledgeSupportDiagnosticsTenantAuthorizationComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -36,7 +36,7 @@ function productKnowledgeSupportDiagnosticsOperationAuthorizationComponent(User } it('keeps tenant support diagnostics contextual help deny-as-not-found for workspace members without tenant entitlement', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ @@ -52,11 +52,11 @@ function productKnowledgeSupportDiagnosticsOperationAuthorizationComponent(User }); it('returns forbidden for entitled run viewers without support diagnostics capability when requesting the contextual-help bundle', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -72,13 +72,13 @@ function productKnowledgeSupportDiagnosticsOperationAuthorizationComponent(User }); it('omits support diagnostics contextual help when the dominant issue does not map to a catalog topic', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Fallback Support Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Fallback Support ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $connection = ProviderConnection::factory() ->withCredential() ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Fallback connection', 'last_error_reason_code' => 'ext.support.manual_lookup_needed', @@ -105,7 +105,7 @@ function productKnowledgeSupportDiagnosticsOperationAuthorizationComponent(User it('keeps operation-run support diagnostics deny-as-not-found for workspace members without tenant entitlement', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -118,7 +118,7 @@ function productKnowledgeSupportDiagnosticsOperationAuthorizationComponent(User ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/SupportDiagnostics/ProductKnowledgeSupportDiagnosticHelpTest.php b/apps/platform/tests/Feature/SupportDiagnostics/ProductKnowledgeSupportDiagnosticHelpTest.php index 902d9a30..d1c7cdf5 100644 --- a/apps/platform/tests/Feature/SupportDiagnostics/ProductKnowledgeSupportDiagnosticHelpTest.php +++ b/apps/platform/tests/Feature/SupportDiagnostics/ProductKnowledgeSupportDiagnosticHelpTest.php @@ -6,7 +6,7 @@ use App\Filament\Pages\TenantDashboard; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; @@ -17,7 +17,7 @@ use Filament\Facades\Filament; use Livewire\Livewire; -function productKnowledgeTenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function productKnowledgeTenantSupportDiagnosticsComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -36,11 +36,11 @@ function productKnowledgeOperationSupportDiagnosticsComponent(User $user, Operat } /** - * @return array{0: User, 1: Tenant, 2: OperationRun} + * @return array{0: User, 1: ManagedEnvironment, 2: OperationRun} */ function createProductKnowledgeSupportDiagnosticScenario(string $state): array { - $tenant = Tenant::factory()->create(['name' => 'Contoso Support Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Contoso Support ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $reasonCode = match ($state) { @@ -54,7 +54,7 @@ function createProductKnowledgeSupportDiagnosticScenario(string $state): array $connection = $reasonCode !== null ? ProviderConnection::factory()->withCredential()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Contoso Microsoft connection', 'verification_status' => $reasonCode === ProviderReasonCodes::UnknownError diff --git a/apps/platform/tests/Feature/SupportDiagnostics/ProductTelemetrySupportDiagnosticsCaptureTest.php b/apps/platform/tests/Feature/SupportDiagnostics/ProductTelemetrySupportDiagnosticsCaptureTest.php index fc981896..e9c8c9e7 100644 --- a/apps/platform/tests/Feature/SupportDiagnostics/ProductTelemetrySupportDiagnosticsCaptureTest.php +++ b/apps/platform/tests/Feature/SupportDiagnostics/ProductTelemetrySupportDiagnosticsCaptureTest.php @@ -6,7 +6,7 @@ use App\Filament\Pages\TenantDashboard; use App\Models\OperationRun; use App\Models\ProductUsageEvent; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; @@ -19,7 +19,7 @@ uses(RefreshDatabase::class); -function tenantDiagnosticsTelemetryComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function tenantDiagnosticsTelemetryComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -38,7 +38,7 @@ function operationDiagnosticsTelemetryComponent(User $user, OperationRun $run): } it('records telemetry when support diagnostics are opened from the tenant dashboard', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); tenantDiagnosticsTelemetryComponent($user, $tenant) @@ -49,7 +49,7 @@ function operationDiagnosticsTelemetryComponent(User $user, OperationRun $run): $serializedEvent = json_encode($event->toArray(), JSON_THROW_ON_ERROR); expect($event->event_name)->toBe(ProductUsageEventCatalog::SUPPORT_DIAGNOSTICS_OPENED) - ->and($event->tenant_id)->toBe((int) $tenant->getKey()) + ->and($event->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($event->workspace_id)->toBe((int) $tenant->workspace_id) ->and($event->user_id)->toBe((int) $user->getKey()) ->and($event->subject_type)->toBe('tenant') @@ -63,7 +63,7 @@ function operationDiagnosticsTelemetryComponent(User $user, OperationRun $run): }); it('records telemetry when support diagnostics are opened from the canonical operation viewer', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $run = OperationRun::factory()->forTenant($tenant)->create([ @@ -83,7 +83,7 @@ function operationDiagnosticsTelemetryComponent(User $user, OperationRun $run): $serializedEvent = json_encode($event->toArray(), JSON_THROW_ON_ERROR); expect($event->event_name)->toBe(ProductUsageEventCatalog::SUPPORT_DIAGNOSTICS_OPENED) - ->and($event->tenant_id)->toBe((int) $tenant->getKey()) + ->and($event->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($event->workspace_id)->toBe((int) $tenant->workspace_id) ->and($event->user_id)->toBe((int) $user->getKey()) ->and($event->subject_type)->toBe('operation_run') diff --git a/apps/platform/tests/Feature/SupportDiagnostics/SupportDiagnosticAuditTest.php b/apps/platform/tests/Feature/SupportDiagnostics/SupportDiagnosticAuditTest.php index e55009e2..b1f71de8 100644 --- a/apps/platform/tests/Feature/SupportDiagnostics/SupportDiagnosticAuditTest.php +++ b/apps/platform/tests/Feature/SupportDiagnostics/SupportDiagnosticAuditTest.php @@ -8,7 +8,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Audit\AuditActionId; use App\Support\OperationRunOutcome; @@ -22,7 +22,7 @@ use Illuminate\Support\Facades\Queue; use Livewire\Livewire; -function supportDiagnosticsTenantAuditComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function supportDiagnosticsTenantAuditComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -42,13 +42,13 @@ function supportDiagnosticsOperationAuditComponent(User $user, OperationRun $run function seedSupportDiagnosticsAuditFixture(string $role = 'owner'): array { - $tenant = Tenant::factory()->create(['name' => 'Audit Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Audit ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: $role); $connection = ProviderConnection::factory() ->withCredential() ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Audit connection', 'verification_status' => ProviderVerificationStatus::Blocked->value, @@ -75,7 +75,7 @@ function seedSupportDiagnosticsAuditFixture(string $role = 'owner'): array ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => [ @@ -85,7 +85,7 @@ function seedSupportDiagnosticsAuditFixture(string $role = 'owner'): array AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'operation_run_id' => (int) $run->getKey(), 'action' => 'operation.failed', 'resource_type' => 'operation_run', diff --git a/apps/platform/tests/Feature/SupportDiagnostics/SupportDiagnosticAuthorizationTest.php b/apps/platform/tests/Feature/SupportDiagnostics/SupportDiagnosticAuthorizationTest.php index 649abfcf..12e7eae6 100644 --- a/apps/platform/tests/Feature/SupportDiagnostics/SupportDiagnosticAuthorizationTest.php +++ b/apps/platform/tests/Feature/SupportDiagnostics/SupportDiagnosticAuthorizationTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Operations\TenantlessOperationRunViewer; use App\Filament\Pages\TenantDashboard; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -16,7 +16,7 @@ use Filament\Facades\Filament; use Livewire\Livewire; -function supportDiagnosticsTenantAuthorizationComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function supportDiagnosticsTenantAuthorizationComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -35,7 +35,7 @@ function supportDiagnosticsOperationAuthorizationComponent(User $user, Operation } it('keeps tenant support diagnostics deny-as-not-found for workspace members without tenant entitlement', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ @@ -51,7 +51,7 @@ function supportDiagnosticsOperationAuthorizationComponent(User $user, Operation }); it('returns forbidden for entitled tenant members without support diagnostics capability', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); supportDiagnosticsTenantAuthorizationComponent($user, $tenant) @@ -63,7 +63,7 @@ function supportDiagnosticsOperationAuthorizationComponent(User $user, Operation it('keeps operation-run support diagnostics deny-as-not-found for workspace members without tenant entitlement', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -76,7 +76,7 @@ function supportDiagnosticsOperationAuthorizationComponent(User $user, Operation ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -91,11 +91,11 @@ function supportDiagnosticsOperationAuthorizationComponent(User $user, Operation }); it('returns forbidden for entitled run viewers without support diagnostics capability', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/SupportDiagnostics/TenantSupportDiagnosticActionTest.php b/apps/platform/tests/Feature/SupportDiagnostics/TenantSupportDiagnosticActionTest.php index f437c963..bd8a0e6e 100644 --- a/apps/platform/tests/Feature/SupportDiagnostics/TenantSupportDiagnosticActionTest.php +++ b/apps/platform/tests/Feature/SupportDiagnostics/TenantSupportDiagnosticActionTest.php @@ -10,7 +10,7 @@ use App\Models\ProviderConnection; use App\Models\ReviewPack; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Models\WorkspaceMembership; @@ -25,7 +25,7 @@ use Filament\Actions\Action; use Livewire\Livewire; -function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function tenantSupportDiagnosticsComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -35,13 +35,13 @@ function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewir } it('opens a redacted tenant support diagnostic bundle from the tenant dashboard', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Contoso Support Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Contoso Support ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $connection = ProviderConnection::factory() ->withCredential() ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Contoso Microsoft connection', 'verification_status' => ProviderVerificationStatus::Blocked->value, @@ -67,7 +67,7 @@ function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewir ]); $finding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'current_operation_run_id' => (int) $run->getKey(), 'severity' => Finding::SEVERITY_HIGH, @@ -75,7 +75,7 @@ function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewir ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => [ @@ -85,7 +85,7 @@ function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewir ]); $evidenceSnapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'operation_run_id' => (int) $run->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), @@ -101,7 +101,7 @@ function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewir ]); $review = TenantReview::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $evidenceSnapshot->getKey(), 'operation_run_id' => (int) $run->getKey(), @@ -110,7 +110,7 @@ function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewir ]); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'operation_run_id' => (int) $run->getKey(), @@ -121,7 +121,7 @@ function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewir AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'operation_run_id' => (int) $run->getKey(), 'action' => 'operation.failed', 'resource_type' => 'operation_run', @@ -141,13 +141,13 @@ function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewir ->assertActionExists('openSupportDiagnostics', fn (Action $action): bool => $action->getLabel() === 'Open support diagnostics') ->mountAction('openSupportDiagnostics') ->assertMountedActionModalSee('Support diagnostics') - ->assertMountedActionModalSee('Contoso Support Tenant') + ->assertMountedActionModalSee('Contoso Support ManagedEnvironment') ->assertMountedActionModalSee('Permissions missing') ->assertMountedActionModalSee('provider app is missing required Microsoft Graph permissions') ->assertMountedActionModalSee('Operation #'.$run->getKey()) ->assertMountedActionModalSee('High finding #'.$finding->getKey()) ->assertMountedActionModalSee('permission posture report') - ->assertMountedActionModalSee('Tenant review #'.$review->getKey()) + ->assertMountedActionModalSee('ManagedEnvironment review #'.$review->getKey()) ->assertMountedActionModalSee('Review pack #'.$pack->getKey()) ->assertMountedActionModalSee('Operation failed') ->assertMountedActionModalSee('default-redacted') @@ -159,7 +159,7 @@ function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewir }); it('denies non-entitled tenant dashboard access as not found', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ @@ -176,7 +176,7 @@ function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewir }); it('shows support diagnostics as disabled for entitled members without the support capability', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); tenantSupportDiagnosticsComponent($user, $tenant) diff --git a/apps/platform/tests/Feature/SupportRequests/OperationRunSupportRequestActionTest.php b/apps/platform/tests/Feature/SupportRequests/OperationRunSupportRequestActionTest.php index 57cdba44..78b0ebcb 100644 --- a/apps/platform/tests/Feature/SupportRequests/OperationRunSupportRequestActionTest.php +++ b/apps/platform/tests/Feature/SupportRequests/OperationRunSupportRequestActionTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Operations\TenantlessOperationRunViewer; use App\Models\OperationRun; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -75,7 +75,7 @@ function operationSupportRequestHeaderMoreAction(\Livewire\Features\SupportTesti } it('creates a run-scoped support request from the tenantless operation viewer', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Contoso Support Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Contoso Support ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $run = OperationRun::factory() @@ -124,7 +124,7 @@ function operationSupportRequestHeaderMoreAction(\Livewire\Features\SupportTesti expect($supportRequest->internal_reference)->toMatch('/^SR-[0-9A-HJKMNP-TV-Z]{26}$/') ->and($supportRequest->workspace_id)->toBe((int) $tenant->workspace_id) - ->and($supportRequest->tenant_id)->toBe((int) $tenant->getKey()) + ->and($supportRequest->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($supportRequest->initiated_by_user_id)->toBe((int) $user->getKey()) ->and($supportRequest->primary_context_type)->toBe(SupportRequest::PRIMARY_CONTEXT_OPERATION_RUN) ->and($supportRequest->operation_run_id)->toBe((int) $run->getKey()) @@ -138,7 +138,7 @@ function operationSupportRequestHeaderMoreAction(\Livewire\Features\SupportTesti it('keeps tenantless operation detail deny-as-not-found for workspace members without tenant entitlement', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -151,7 +151,7 @@ function operationSupportRequestHeaderMoreAction(\Livewire\Features\SupportTesti ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/SupportRequests/OperationRunSupportRequestExternalHandoffTest.php b/apps/platform/tests/Feature/SupportRequests/OperationRunSupportRequestExternalHandoffTest.php index 34ce9748..8c096e46 100644 --- a/apps/platform/tests/Feature/SupportRequests/OperationRunSupportRequestExternalHandoffTest.php +++ b/apps/platform/tests/Feature/SupportRequests/OperationRunSupportRequestExternalHandoffTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Operations\TenantlessOperationRunViewer; use App\Models\OperationRun; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; @@ -40,11 +40,11 @@ function spec256RunHandoffComponent(User $user, OperationRun $run): \Livewire\Fe return Livewire::actingAs($user)->test(TenantlessOperationRunViewer::class, ['run' => $run]); } -function spec256OperationRun(Tenant $tenant): OperationRun +function spec256OperationRun(ManagedEnvironment $tenant): OperationRun { return OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -59,7 +59,7 @@ function spec256OperationRun(Tenant $tenant): OperationRun it('creates an external ticket from the operation-run support action', function (): void { spec256ConfigureRunSupportDesk(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $run = spec256OperationRun($tenant); @@ -92,7 +92,7 @@ function spec256OperationRun(Tenant $tenant): OperationRun it('links an existing external ticket from the operation-run support action without outbound create', function (): void { spec256ConfigureRunSupportDesk(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'manager'); $run = spec256OperationRun($tenant); @@ -120,7 +120,7 @@ function spec256OperationRun(Tenant $tenant): OperationRun it('keeps the internal run support request when external create fails', function (): void { spec256ConfigureRunSupportDesk(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = spec256OperationRun($tenant); diff --git a/apps/platform/tests/Feature/SupportRequests/SupportRequestAuditTest.php b/apps/platform/tests/Feature/SupportRequests/SupportRequestAuditTest.php index 65ca2a94..a9b5c858 100644 --- a/apps/platform/tests/Feature/SupportRequests/SupportRequestAuditTest.php +++ b/apps/platform/tests/Feature/SupportRequests/SupportRequestAuditTest.php @@ -8,7 +8,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Audit\AuditActionId; use App\Support\OperationRunOutcome; @@ -22,7 +22,7 @@ uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); -function supportRequestAuditTenantComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function supportRequestAuditTenantComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -41,13 +41,13 @@ function supportRequestAuditOperationComponent(User $user, OperationRun $run): \ } it('records a redacted audit entry for tenant-scoped support requests', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Audit Support Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Audit Support ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ProviderConnection::factory() ->withCredential() ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Audit Microsoft connection', 'verification_status' => ProviderVerificationStatus::Blocked->value, @@ -73,7 +73,7 @@ function supportRequestAuditOperationComponent(User $user, OperationRun $run): \ expect($audit)->not->toBeNull() ->and($audit?->workspace_id)->toBe((int) $tenant->workspace_id) - ->and($audit?->tenant_id)->toBe((int) $tenant->getKey()) + ->and($audit?->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($audit?->resource_type)->toBe('support_request') ->and($audit?->resource_id)->toBe((string) $supportRequest->getKey()) ->and($audit?->target_label)->toBe($supportRequest->internal_reference) @@ -87,11 +87,11 @@ function supportRequestAuditOperationComponent(User $user, OperationRun $run): \ }); it('records a redacted audit entry for run-scoped support requests', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -127,7 +127,7 @@ function supportRequestAuditOperationComponent(User $user, OperationRun $run): \ expect($audit)->not->toBeNull() ->and($audit?->workspace_id)->toBe((int) $tenant->workspace_id) - ->and($audit?->tenant_id)->toBe((int) $tenant->getKey()) + ->and($audit?->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($audit?->resource_type)->toBe('support_request') ->and($audit?->resource_id)->toBe((string) $supportRequest->getKey()) ->and($audit?->target_label)->toBe($supportRequest->internal_reference) @@ -141,11 +141,11 @@ function supportRequestAuditOperationComponent(User $user, OperationRun $run): \ }); it('creates distinct support references for duplicate submissions without outbound http or operation-run side effects', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/SupportRequests/SupportRequestAuthorizationTest.php b/apps/platform/tests/Feature/SupportRequests/SupportRequestAuthorizationTest.php index 2bc68a1f..d6daa287 100644 --- a/apps/platform/tests/Feature/SupportRequests/SupportRequestAuthorizationTest.php +++ b/apps/platform/tests/Feature/SupportRequests/SupportRequestAuthorizationTest.php @@ -6,7 +6,7 @@ use App\Filament\Pages\TenantDashboard; use App\Models\OperationRun; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; @@ -17,7 +17,7 @@ uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); -function supportRequestAuthorizationTenantComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function supportRequestAuthorizationTenantComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -36,7 +36,7 @@ function supportRequestAuthorizationOperationComponent(User $user, OperationRun } it('returns forbidden for entitled tenant members without support request capability', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); supportRequestAuthorizationTenantComponent($user, $tenant) @@ -49,11 +49,11 @@ function supportRequestAuthorizationOperationComponent(User $user, OperationRun }); it('returns forbidden for entitled run viewers without support request capability', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, diff --git a/apps/platform/tests/Feature/SupportRequests/SupportRequestExternalHandoffAuditTest.php b/apps/platform/tests/Feature/SupportRequests/SupportRequestExternalHandoffAuditTest.php index 50b3ee79..3ee06971 100644 --- a/apps/platform/tests/Feature/SupportRequests/SupportRequestExternalHandoffAuditTest.php +++ b/apps/platform/tests/Feature/SupportRequests/SupportRequestExternalHandoffAuditTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\TenantDashboard; use App\Models\AuditLog; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Audit\AuditActionId; use App\Support\Workspaces\WorkspaceContext; @@ -28,7 +28,7 @@ function spec256ConfigureAuditSupportDesk(array $overrides = []): void ]); } -function spec256AuditTenantComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function spec256AuditTenantComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -40,7 +40,7 @@ function spec256AuditTenantComponent(User $user, Tenant $tenant): \Livewire\Feat it('preserves support request created audit and records external ticket created audit', function (): void { spec256ConfigureAuditSupportDesk(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); Http::fake([ @@ -71,7 +71,7 @@ function spec256AuditTenantComponent(User $user, Tenant $tenant): \Livewire\Feat expect($createdAudit->resource_id)->toBe((string) $supportRequest->getKey()) ->and($externalAudit->resource_id)->toBe((string) $supportRequest->getKey()) - ->and($externalAudit->tenant_id)->toBe((int) $tenant->getKey()) + ->and($externalAudit->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($externalAudit->status)->toBe('success') ->and(data_get($externalAudit->metadata, 'internal_reference'))->toBe($supportRequest->internal_reference) ->and(data_get($externalAudit->metadata, 'external_handoff_mode'))->toBe(SupportRequest::EXTERNAL_HANDOFF_MODE_CREATE_EXTERNAL_TICKET) @@ -82,7 +82,7 @@ function spec256AuditTenantComponent(User $user, Tenant $tenant): \Livewire\Feat it('records external ticket linked audit without issuing outbound create', function (): void { spec256ConfigureAuditSupportDesk(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); Http::fake(); @@ -111,7 +111,7 @@ function spec256AuditTenantComponent(User $user, Tenant $tenant): \Livewire\Feat it('records external handoff failed audit with bounded failure metadata', function (): void { spec256ConfigureAuditSupportDesk(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'manager'); Http::fake([ diff --git a/apps/platform/tests/Feature/SupportRequests/SupportRequestExternalHandoffAuthorizationTest.php b/apps/platform/tests/Feature/SupportRequests/SupportRequestExternalHandoffAuthorizationTest.php index fe2afd64..7c46918f 100644 --- a/apps/platform/tests/Feature/SupportRequests/SupportRequestExternalHandoffAuthorizationTest.php +++ b/apps/platform/tests/Feature/SupportRequests/SupportRequestExternalHandoffAuthorizationTest.php @@ -6,7 +6,7 @@ use App\Filament\Pages\TenantDashboard; use App\Models\OperationRun; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceMembership; use App\Support\OperationRunOutcome; @@ -20,7 +20,7 @@ uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); -function spec256AuthorizationTenantComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function spec256AuthorizationTenantComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -38,11 +38,11 @@ function spec256AuthorizationOperationComponent(User $user, OperationRun $run): return Livewire::actingAs($user)->test(TenantlessOperationRunViewer::class, ['run' => $run]); } -function spec256AuthorizationRun(Tenant $tenant): OperationRun +function spec256AuthorizationRun(ManagedEnvironment $tenant): OperationRun { return OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -51,7 +51,7 @@ function spec256AuthorizationRun(Tenant $tenant): OperationRun } it('keeps external handoff actions forbidden for entitled tenant members without support-create capability', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); spec256AuthorizationTenantComponent($user, $tenant) @@ -64,7 +64,7 @@ function spec256AuthorizationRun(Tenant $tenant): OperationRun }); it('keeps external handoff actions forbidden for entitled run viewers without support-create capability', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $run = spec256AuthorizationRun($tenant); @@ -78,7 +78,7 @@ function spec256AuthorizationRun(Tenant $tenant): OperationRun }); it('does not reveal latest tenant handoff summaries to workspace members without tenant entitlement', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ @@ -89,7 +89,7 @@ function spec256AuthorizationRun(Tenant $tenant): OperationRun SupportRequest::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'primary_context_type' => SupportRequest::PRIMARY_CONTEXT_TENANT, 'external_handoff_mode' => SupportRequest::EXTERNAL_HANDOFF_MODE_LINK_EXISTING_TICKET, 'external_ticket_reference' => 'PSA-HIDDEN', @@ -104,7 +104,7 @@ function spec256AuthorizationRun(Tenant $tenant): OperationRun }); it('does not reveal latest run handoff summaries outside the run tenant entitlement', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ diff --git a/apps/platform/tests/Feature/SupportRequests/TenantSupportRequestActionTest.php b/apps/platform/tests/Feature/SupportRequests/TenantSupportRequestActionTest.php index fd7391ac..a1123493 100644 --- a/apps/platform/tests/Feature/SupportRequests/TenantSupportRequestActionTest.php +++ b/apps/platform/tests/Feature/SupportRequests/TenantSupportRequestActionTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\TenantDashboard; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceMembership; use App\Services\Auth\CapabilityResolver; @@ -17,7 +17,7 @@ uses(\Illuminate\Foundation\Testing\RefreshDatabase::class); -function tenantSupportRequestComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function tenantSupportRequestComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -27,7 +27,7 @@ function tenantSupportRequestComponent(User $user, Tenant $tenant): \Livewire\Fe } it('creates a tenant support request from the dashboard', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Contoso Support Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Contoso Support ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); tenantSupportRequestComponent($user, $tenant) @@ -50,7 +50,7 @@ function tenantSupportRequestComponent(User $user, Tenant $tenant): \Livewire\Fe expect($supportRequest->internal_reference)->toMatch('/^SR-[0-9A-HJKMNP-TV-Z]{26}$/') ->and($supportRequest->workspace_id)->toBe((int) $tenant->workspace_id) - ->and($supportRequest->tenant_id)->toBe((int) $tenant->getKey()) + ->and($supportRequest->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($supportRequest->initiated_by_user_id)->toBe((int) $user->getKey()) ->and($supportRequest->primary_context_type)->toBe(SupportRequest::PRIMARY_CONTEXT_TENANT) ->and($supportRequest->operation_run_id)->toBeNull() @@ -61,21 +61,21 @@ function tenantSupportRequestComponent(User $user, Tenant $tenant): \Livewire\Fe ->and($supportRequest->contact_name)->toBe('Ops On Call') ->and($supportRequest->contact_email)->toBe('ops@example.test') ->and(data_get($supportRequest->context_envelope, 'primary_context.type'))->toBe('tenant') - ->and(data_get($supportRequest->context_envelope, 'primary_context.tenant_id'))->toBe((int) $tenant->getKey()) + ->and(data_get($supportRequest->context_envelope, 'primary_context.managed_environment_id'))->toBe((int) $tenant->getKey()) ->and(data_get($supportRequest->context_envelope, 'diagnostic_snapshot'))->toBeArray(); }); it('stores canonical context only when the creator cannot view support diagnostics', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); mock(CapabilityResolver::class, function ($mock) use ($tenant): void { $mock->shouldReceive('primeMemberships')->andReturnNull(); $mock->shouldReceive('isMember') - ->andReturnUsing(static fn ($user, Tenant $resolvedTenant): bool => (int) $resolvedTenant->getKey() === (int) $tenant->getKey()); + ->andReturnUsing(static fn ($user, ManagedEnvironment $resolvedTenant): bool => (int) $resolvedTenant->getKey() === (int) $tenant->getKey()); $mock->shouldReceive('can') - ->andReturnUsing(static function ($user, Tenant $resolvedTenant, string $capability) use ($tenant): bool { + ->andReturnUsing(static function ($user, ManagedEnvironment $resolvedTenant, string $capability) use ($tenant): bool { expect((int) $resolvedTenant->getKey())->toBe((int) $tenant->getKey()); return match ($capability) { @@ -108,7 +108,7 @@ function tenantSupportRequestComponent(User $user, Tenant $tenant): \Livewire\Fe }); it('keeps tenant dashboard support requests deny-as-not-found for workspace members without tenant entitlement', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ @@ -124,7 +124,7 @@ function tenantSupportRequestComponent(User $user, Tenant $tenant): \Livewire\Fe }); it('returns forbidden for entitled tenant members without support request capability', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); tenantSupportRequestComponent($user, $tenant) diff --git a/apps/platform/tests/Feature/SupportRequests/TenantSupportRequestExternalHandoffTest.php b/apps/platform/tests/Feature/SupportRequests/TenantSupportRequestExternalHandoffTest.php index 3a5b4579..59495727 100644 --- a/apps/platform/tests/Feature/SupportRequests/TenantSupportRequestExternalHandoffTest.php +++ b/apps/platform/tests/Feature/SupportRequests/TenantSupportRequestExternalHandoffTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\TenantDashboard; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Http\Client\Request; @@ -27,7 +27,7 @@ function spec256ConfigureTenantSupportDesk(array $overrides = []): void ]); } -function spec256TenantHandoffComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable +function spec256TenantHandoffComponent(User $user, ManagedEnvironment $tenant): \Livewire\Features\SupportTesting\Testable { test()->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); @@ -39,7 +39,7 @@ function spec256TenantHandoffComponent(User $user, Tenant $tenant): \Livewire\Fe it('creates an external ticket from the tenant dashboard support action', function (): void { spec256ConfigureTenantSupportDesk(); - $tenant = Tenant::factory()->create(['name' => 'Spec 256 Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Spec 256 ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); Http::fake([ @@ -53,7 +53,7 @@ function spec256TenantHandoffComponent(User $user, Tenant $tenant): \Livewire\Fe ->mountAction('requestSupport') ->setActionData([ 'severity' => SupportRequest::SEVERITY_HIGH, - 'summary' => 'Tenant create external ticket handoff.', + 'summary' => 'ManagedEnvironment create external ticket handoff.', 'external_handoff_mode' => SupportRequest::EXTERNAL_HANDOFF_MODE_CREATE_EXTERNAL_TICKET, ]) ->callMountedAction() @@ -76,7 +76,7 @@ function spec256TenantHandoffComponent(User $user, Tenant $tenant): \Livewire\Fe it('links an existing external ticket from the tenant dashboard without creating a duplicate external ticket', function (): void { spec256ConfigureTenantSupportDesk(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); Http::fake(); @@ -85,7 +85,7 @@ function spec256TenantHandoffComponent(User $user, Tenant $tenant): \Livewire\Fe ->mountAction('requestSupport') ->setActionData([ 'severity' => SupportRequest::SEVERITY_NORMAL, - 'summary' => 'Tenant link existing external ticket.', + 'summary' => 'ManagedEnvironment link existing external ticket.', 'external_handoff_mode' => SupportRequest::EXTERNAL_HANDOFF_MODE_LINK_EXISTING_TICKET, 'external_ticket_reference' => 'PSA-256-LINK', 'external_ticket_url' => 'https://desk.example.test/tickets/PSA-256-LINK', @@ -107,7 +107,7 @@ function spec256TenantHandoffComponent(User $user, Tenant $tenant): \Livewire\Fe it('rejects invalid linked external ticket input before storing a tenant support request', function (): void { spec256ConfigureTenantSupportDesk(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); Http::fake(); @@ -116,7 +116,7 @@ function spec256TenantHandoffComponent(User $user, Tenant $tenant): \Livewire\Fe ->mountAction('requestSupport') ->setActionData([ 'severity' => SupportRequest::SEVERITY_NORMAL, - 'summary' => 'Tenant invalid link should not create support truth.', + 'summary' => 'ManagedEnvironment invalid link should not create support truth.', 'external_handoff_mode' => SupportRequest::EXTERNAL_HANDOFF_MODE_LINK_EXISTING_TICKET, 'external_ticket_reference' => 'not a ticket', ]) @@ -131,7 +131,7 @@ function spec256TenantHandoffComponent(User $user, Tenant $tenant): \Livewire\Fe it('keeps the internal tenant support request when external create fails', function (): void { spec256ConfigureTenantSupportDesk(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'manager'); Http::fake([ @@ -142,7 +142,7 @@ function spec256TenantHandoffComponent(User $user, Tenant $tenant): \Livewire\Fe ->mountAction('requestSupport') ->setActionData([ 'severity' => SupportRequest::SEVERITY_BLOCKING, - 'summary' => 'Tenant external desk timeout should keep internal support request.', + 'summary' => 'ManagedEnvironment external desk timeout should keep internal support request.', 'external_handoff_mode' => SupportRequest::EXTERNAL_HANDOFF_MODE_CREATE_EXTERNAL_TICKET, ]) ->callMountedAction() @@ -164,7 +164,7 @@ function spec256TenantHandoffComponent(User $user, Tenant $tenant): \Livewire\Fe 'enabled' => false, ]); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); Http::fake(); @@ -172,7 +172,7 @@ function spec256TenantHandoffComponent(User $user, Tenant $tenant): \Livewire\Fe spec256TenantHandoffComponent($user, $tenant) ->mountAction('requestSupport') ->setActionData([ - 'summary' => 'Tenant support stays internal when no support desk target exists.', + 'summary' => 'ManagedEnvironment support stays internal when no support desk target exists.', ]) ->callMountedAction() ->assertHasNoActionErrors(); diff --git a/apps/platform/tests/Feature/SyncPoliciesJobDispatchTest.php b/apps/platform/tests/Feature/SyncPoliciesJobDispatchTest.php index bc57b3e1..5f2f6d87 100644 --- a/apps/platform/tests/Feature/SyncPoliciesJobDispatchTest.php +++ b/apps/platform/tests/Feature/SyncPoliciesJobDispatchTest.php @@ -9,10 +9,10 @@ $operationRun = OperationRun::factory()->create(); - SyncPoliciesJob::dispatch((int) $operationRun->tenant_id, null, null, $operationRun); + SyncPoliciesJob::dispatch((int) $operationRun->managed_environment_id, null, null, $operationRun); Bus::assertDispatched(SyncPoliciesJob::class, function (SyncPoliciesJob $job) use ($operationRun): bool { - return $job->tenantId === (int) $operationRun->tenant_id + return $job->tenantId === (int) $operationRun->managed_environment_id && $job->types === null && $job->policyIds === null && (int) $job->operationRun?->getKey() === (int) $operationRun->getKey(); diff --git a/apps/platform/tests/Feature/SyncPoliciesJobGraphDisabledTest.php b/apps/platform/tests/Feature/SyncPoliciesJobGraphDisabledTest.php index e658f5f0..f84602f4 100644 --- a/apps/platform/tests/Feature/SyncPoliciesJobGraphDisabledTest.php +++ b/apps/platform/tests/Feature/SyncPoliciesJobGraphDisabledTest.php @@ -2,7 +2,7 @@ use App\Jobs\SyncPoliciesJob; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\PolicySyncService; use App\Services\OperationRunService; use App\Support\OperationRunOutcome; @@ -11,12 +11,12 @@ it('marks policy sync run failed when Graph is disabled', function () { config(['graph.enabled' => false]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'policy.sync', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, diff --git a/apps/platform/tests/Feature/SyncPoliciesJobSupportedTypesTest.php b/apps/platform/tests/Feature/SyncPoliciesJobSupportedTypesTest.php index c86b9b16..cab27f13 100644 --- a/apps/platform/tests/Feature/SyncPoliciesJobSupportedTypesTest.php +++ b/apps/platform/tests/Feature/SyncPoliciesJobSupportedTypesTest.php @@ -2,7 +2,7 @@ use App\Jobs\SyncPoliciesJob; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\PolicySyncService; @@ -51,7 +51,7 @@ public function request(string $method, string $path, array $options = []): Grap app()->instance(GraphClientInterface::class, new FakeGraphClient); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->for($tenant)->create([ 'type' => 'policy.sync', 'status' => OperationRunStatus::Queued->value, @@ -84,7 +84,7 @@ public function request(string $method, string $path, array $options = []): Grap app()->instance(GraphClientInterface::class, new FakeGraphClient); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->for($tenant)->create([ 'type' => 'policy.sync', 'status' => OperationRunStatus::Queued->value, @@ -105,7 +105,7 @@ public function request(string $method, string $path, array $options = []): Grap $service = mock(PolicySyncService::class); $service->shouldReceive('syncPoliciesWithReport') ->once() - ->withArgs(function (Tenant $tenantArg, array $supportedArg) use ($tenant, $supported) { + ->withArgs(function (ManagedEnvironment $tenantArg, array $supportedArg) use ($tenant, $supported) { expect($tenantArg->getKey())->toBe($tenant->getKey()); expect($supportedArg)->toBe($supported); diff --git a/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthAuthorizationTest.php b/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthAuthorizationTest.php index 56cb3ef4..c5272d3e 100644 --- a/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthAuthorizationTest.php +++ b/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthAuthorizationTest.php @@ -8,7 +8,7 @@ use App\Models\OperationRun; use App\Models\PlatformUser; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Auth\PlatformCapabilities; use App\Support\OperationRunOutcome; @@ -135,9 +135,9 @@ function seedOperationalAttentionWorkspace(string $workspaceName): void { $workspace = Workspace::factory()->create(['name' => $workspaceName]); - $tenant = Tenant::factory()->for($workspace)->create([ - 'name' => $workspaceName.' Tenant', - 'status' => Tenant::STATUS_ACTIVE, + $tenant = ManagedEnvironment::factory()->for($workspace)->create([ + 'name' => $workspaceName.' ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); OperationRun::factory() @@ -154,9 +154,9 @@ function seedOperationalAttentionWorkspace(string $workspaceName): void function seedProviderAttentionWorkspace(string $workspaceName): void { $workspace = Workspace::factory()->create(['name' => $workspaceName]); - $tenant = Tenant::factory()->for($workspace)->create([ - 'name' => $workspaceName.' Tenant', - 'status' => Tenant::STATUS_ACTIVE, + $tenant = ManagedEnvironment::factory()->for($workspace)->create([ + 'name' => $workspaceName.' ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); ProviderConnection::factory() diff --git a/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthDashboardWidgetsTest.php b/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthDashboardWidgetsTest.php index 612d3fc4..8a2ffb23 100644 --- a/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthDashboardWidgetsTest.php +++ b/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthDashboardWidgetsTest.php @@ -10,7 +10,7 @@ use App\Models\ProductUsageEvent; use App\Models\ProviderConnection; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Auth\PlatformCapabilities; use App\Support\OperationRunOutcome; @@ -105,7 +105,7 @@ function actingAsCustomerHealthSystemUser(): PlatformUser } /** - * @return array{workspace: Workspace, tenant: Tenant} + * @return array{workspace: Workspace, tenant: ManagedEnvironment} */ function seedCustomerHealthWorkspace( string $workspaceName, @@ -116,9 +116,9 @@ function seedCustomerHealthWorkspace( bool $failedRun = false, ): array { $workspace = Workspace::factory()->create(['name' => $workspaceName]); - $tenant = Tenant::factory()->for($workspace)->create([ - 'name' => $workspaceName.' Tenant', - 'status' => Tenant::STATUS_ACTIVE, + $tenant = ManagedEnvironment::factory()->for($workspace)->create([ + 'name' => $workspaceName.' ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); ProviderConnection::factory() diff --git a/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthDetailDecisionTest.php b/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthDetailDecisionTest.php index 9e699bf7..ee68bb64 100644 --- a/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthDetailDecisionTest.php +++ b/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthDetailDecisionTest.php @@ -8,7 +8,7 @@ use App\Models\ProductUsageEvent; use App\Models\ProviderConnection; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Auth\PlatformCapabilities; use App\Support\OperationRunOutcome; @@ -32,7 +32,7 @@ }); it('renders a decision-first customer health card on the tenant detail page before diagnostics', function (): void { - $fixture = createCustomerHealthDecisionFixture('Tenant Decision Workspace'); + $fixture = createCustomerHealthDecisionFixture('ManagedEnvironment Decision Workspace'); $platformUser = createDirectoryPlatformUser(); $response = $this->actingAs($platformUser, 'platform') @@ -95,14 +95,14 @@ function createDirectoryPlatformUser(): PlatformUser } /** - * @return array{workspace: Workspace, tenant: Tenant} + * @return array{workspace: Workspace, tenant: ManagedEnvironment} */ function createCustomerHealthDecisionFixture(string $workspaceName): array { $workspace = Workspace::factory()->create(['name' => $workspaceName]); - $tenant = Tenant::factory()->for($workspace)->create([ - 'name' => $workspaceName.' Tenant', - 'status' => Tenant::STATUS_ACTIVE, + $tenant = ManagedEnvironment::factory()->for($workspace)->create([ + 'name' => $workspaceName.' ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); ProviderConnection::factory() diff --git a/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthExplainabilityTest.php b/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthExplainabilityTest.php index 25abce13..ae4fc3c9 100644 --- a/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthExplainabilityTest.php +++ b/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthExplainabilityTest.php @@ -9,7 +9,7 @@ use App\Models\ProductUsageEvent; use App\Models\ProviderConnection; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Auth\PlatformCapabilities; use App\Support\OperationRunOutcome; @@ -54,7 +54,7 @@ $providerWorkspace = seedExplainabilityWorkspace('Beta Provider'); ProviderConnection::query() - ->where('tenant_id', (int) $providerWorkspace['tenant']->getKey()) + ->where('managed_environment_id', (int) $providerWorkspace['tenant']->getKey()) ->update([ 'is_enabled' => true, 'consent_status' => ProviderConsentStatus::Granted->value, @@ -116,14 +116,14 @@ function actingAsExplainabilitySystemUser(): PlatformUser } /** - * @return array{workspace: Workspace, tenant: Tenant} + * @return array{workspace: Workspace, tenant: ManagedEnvironment} */ function seedExplainabilityWorkspace(string $workspaceName): array { $workspace = Workspace::factory()->create(['name' => $workspaceName]); - $tenant = Tenant::factory()->for($workspace)->create([ - 'name' => $workspaceName.' Tenant', - 'status' => Tenant::STATUS_ACTIVE, + $tenant = ManagedEnvironment::factory()->for($workspace)->create([ + 'name' => $workspaceName.' ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); ProviderConnection::factory() diff --git a/apps/platform/tests/Feature/System/OpsControls/AiExecutionOperationalControlTest.php b/apps/platform/tests/Feature/System/OpsControls/AiExecutionOperationalControlTest.php index 735292c8..32f7b7c6 100644 --- a/apps/platform/tests/Feature/System/OpsControls/AiExecutionOperationalControlTest.php +++ b/apps/platform/tests/Feature/System/OpsControls/AiExecutionOperationalControlTest.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\OperationalControlActivation; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Audit\AuditActionId; use App\Support\Auth\PlatformCapabilities; @@ -37,8 +37,8 @@ function makeAiControlsManager(): PlatformUser $workspaceA = Workspace::factory()->create(['name' => 'Acme']); $workspaceB = Workspace::factory()->create(['name' => 'Bravo']); - Tenant::factory()->count(2)->create(['workspace_id' => (int) $workspaceA->getKey()]); - Tenant::factory()->count(1)->create(['workspace_id' => (int) $workspaceB->getKey()]); + ManagedEnvironment::factory()->count(2)->create(['workspace_id' => (int) $workspaceA->getKey()]); + ManagedEnvironment::factory()->count(1)->create(['workspace_id' => (int) $workspaceB->getKey()]); $user = makeAiControlsManager(); $this->actingAs($user, 'platform'); diff --git a/apps/platform/tests/Feature/System/OpsControls/OperationalControlManagementTest.php b/apps/platform/tests/Feature/System/OpsControls/OperationalControlManagementTest.php index 26248450..5247c7d6 100644 --- a/apps/platform/tests/Feature/System/OpsControls/OperationalControlManagementTest.php +++ b/apps/platform/tests/Feature/System/OpsControls/OperationalControlManagementTest.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\OperationalControlActivation; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Audit\AuditActionId; use App\Support\Auth\PlatformCapabilities; @@ -74,8 +74,8 @@ function makeControlsManager(): PlatformUser $workspaceA = Workspace::factory()->create(['name' => 'Acme']); $workspaceB = Workspace::factory()->create(['name' => 'Bravo']); - Tenant::factory()->count(2)->create(['workspace_id' => (int) $workspaceA->getKey()]); - Tenant::factory()->count(1)->create(['workspace_id' => (int) $workspaceB->getKey()]); + ManagedEnvironment::factory()->count(2)->create(['workspace_id' => (int) $workspaceA->getKey()]); + ManagedEnvironment::factory()->count(1)->create(['workspace_id' => (int) $workspaceB->getKey()]); $user = makeControlsManager(); $this->actingAs($user, 'platform'); @@ -147,7 +147,7 @@ function makeControlsManager(): PlatformUser expect($audits)->toHaveCount(3) ->and($audits->pluck('workspace_id')->unique()->all())->toBe([null]) - ->and($audits->pluck('tenant_id')->unique()->all())->toBe([null]) + ->and($audits->pluck('managed_environment_id')->unique()->all())->toBe([null]) ->and($audits[0]->action)->toBe(AuditActionId::OperationalControlPaused->value) ->and($audits[1]->action)->toBe(AuditActionId::OperationalControlUpdated->value) ->and($audits[2]->action)->toBe(AuditActionId::OperationalControlResumed->value); @@ -161,8 +161,8 @@ function makeControlsManager(): PlatformUser $workspaceA = Workspace::factory()->create(['name' => 'Acme']); $workspaceB = Workspace::factory()->create(['name' => 'Bravo']); - Tenant::factory()->count(2)->create(['workspace_id' => (int) $workspaceA->getKey()]); - Tenant::factory()->count(1)->create(['workspace_id' => (int) $workspaceB->getKey()]); + ManagedEnvironment::factory()->count(2)->create(['workspace_id' => (int) $workspaceA->getKey()]); + ManagedEnvironment::factory()->count(1)->create(['workspace_id' => (int) $workspaceB->getKey()]); $expired = OperationalControlActivation::factory()->workspaceScoped()->create([ 'control_key' => 'restore.execute', @@ -239,5 +239,5 @@ function makeControlsManager(): PlatformUser expect($audits)->toHaveCount(3) ->and($audits[0]->workspace_id)->toBe((int) $workspaceA->getKey()) - ->and($audits[0]->tenant_id)->toBeNull(); + ->and($audits[0]->managed_environment_id)->toBeNull(); }); \ No newline at end of file diff --git a/apps/platform/tests/Feature/System/ProductTelemetry/NoAdHocTelemetryBypassTest.php b/apps/platform/tests/Feature/System/ProductTelemetry/NoAdHocTelemetryBypassTest.php index 002812b4..a077c806 100644 --- a/apps/platform/tests/Feature/System/ProductTelemetry/NoAdHocTelemetryBypassTest.php +++ b/apps/platform/tests/Feature/System/ProductTelemetry/NoAdHocTelemetryBypassTest.php @@ -9,7 +9,7 @@ use App\Models\OperationRun; use App\Models\PlatformUser; use App\Models\ProductUsageEvent; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\PlatformCapabilities; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; @@ -28,7 +28,7 @@ }); it('does not emit telemetry or audit rows on passive dashboard and detail renders', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $run = OperationRun::factory()->forTenant($tenant)->create([ @@ -67,8 +67,8 @@ }); it('keeps the system dashboard aggregate-only without exposing raw telemetry identifiers', function (): void { - $tenant = Tenant::factory()->create([ - 'name' => 'NoLeak Tenant Name', + $tenant = ManagedEnvironment::factory()->create([ + 'name' => 'NoLeak ManagedEnvironment Name', ]); ProductUsageEvent::factory()->forEvent( @@ -79,7 +79,7 @@ 'include_pii' => false, ], )->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'subject_type' => 'review_pack', 'subject_id' => 'review-pack-raw-424242', @@ -100,5 +100,5 @@ ->assertSee('Product telemetry') ->assertSee('Review packs requested') ->assertDontSee('review-pack-raw-424242') - ->assertDontSee('NoLeak Tenant Name'); + ->assertDontSee('NoLeak ManagedEnvironment Name'); }); \ No newline at end of file diff --git a/apps/platform/tests/Feature/System/ProductTelemetry/ProductTelemetryDashboardWidgetTest.php b/apps/platform/tests/Feature/System/ProductTelemetry/ProductTelemetryDashboardWidgetTest.php index 3f0d4605..3fe2d169 100644 --- a/apps/platform/tests/Feature/System/ProductTelemetry/ProductTelemetryDashboardWidgetTest.php +++ b/apps/platform/tests/Feature/System/ProductTelemetry/ProductTelemetryDashboardWidgetTest.php @@ -5,7 +5,7 @@ use App\Filament\System\Widgets\ProductTelemetryKpis; use App\Models\PlatformUser; use App\Models\ProductUsageEvent; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Auth\PlatformCapabilities; use App\Support\ProductTelemetry\ProductUsageEventCatalog; @@ -60,7 +60,7 @@ function actingAsSystemConsoleUser(): PlatformUser } function seedProductTelemetryEvent( - Tenant $tenant, + ManagedEnvironment $tenant, User $user, string $eventName, array $metadata, @@ -71,7 +71,7 @@ function seedProductTelemetryEvent( return ProductUsageEvent::factory() ->forEvent($eventName, $metadata) ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'subject_type' => $subjectType, @@ -83,8 +83,8 @@ function seedProductTelemetryEvent( it('summarizes the five visible telemetry families and active workspaces for the selected window', function (): void { actingAsSystemConsoleUser(); - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); $userA = User::factory()->create(); $userB = User::factory()->create(); @@ -198,7 +198,7 @@ function seedProductTelemetryEvent( it('uses the injected dashboard window when the livewire request query is absent', function (): void { actingAsSystemConsoleUser(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); seedProductTelemetryEvent( diff --git a/apps/platform/tests/Feature/System/ProductTelemetry/ProductTelemetryRetentionTest.php b/apps/platform/tests/Feature/System/ProductTelemetry/ProductTelemetryRetentionTest.php index c911168d..246c9091 100644 --- a/apps/platform/tests/Feature/System/ProductTelemetry/ProductTelemetryRetentionTest.php +++ b/apps/platform/tests/Feature/System/ProductTelemetry/ProductTelemetryRetentionTest.php @@ -7,7 +7,7 @@ use App\Models\ProductUsageEvent; use App\Models\ReviewPack; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\ProductTelemetry\ProductUsageEventCatalog; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -17,14 +17,14 @@ it('prunes only product usage events older than the configured retention window', function (): void { config()->set('tenantpilot.product_usage_event_retention_days', 90); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $oldEvent = ProductUsageEvent::factory()->forEvent( ProductUsageEventCatalog::OPERATIONS_STARTED, ['operation_type' => 'review_pack.generate'], )->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'subject_type' => 'operation_run', @@ -36,7 +36,7 @@ ProductUsageEventCatalog::OPERATIONS_STARTED, ['operation_type' => 'review_pack.generate'], )->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'subject_type' => 'operation_run', @@ -49,19 +49,19 @@ ]); $storedReport = StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'created_at' => now()->subDays(120), ]); $reviewPack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'created_at' => now()->subDays(120), ]); $auditLog = AuditLog::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'action' => 'platform.test.audit', 'status' => 'success', @@ -82,14 +82,14 @@ }); it('honors the explicit days override when pruning product usage events', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $oldEvent = ProductUsageEvent::factory()->forEvent( ProductUsageEventCatalog::STORED_REPORT_CREATED, ['report_type' => 'permission_posture'], )->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'subject_type' => 'stored_report', @@ -101,7 +101,7 @@ ProductUsageEventCatalog::STORED_REPORT_CREATED, ['report_type' => 'permission_posture'], )->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'subject_type' => 'stored_report', diff --git a/apps/platform/tests/Feature/System/Spec113/AllowedTenantUniverseTest.php b/apps/platform/tests/Feature/System/Spec113/AllowedTenantUniverseTest.php index b0deb086..944e9d79 100644 --- a/apps/platform/tests/Feature/System/Spec113/AllowedTenantUniverseTest.php +++ b/apps/platform/tests/Feature/System/Spec113/AllowedTenantUniverseTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\System\AllowedTenantUniverse; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Validation\ValidationException; @@ -11,15 +11,15 @@ uses(RefreshDatabase::class); it('excludes the platform tenant from the allowed universe query (picker)', function () { - $platformTenant = Tenant::factory()->create([ - 'tenant_id' => null, + $platformTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); - $customerTenant = Tenant::factory()->create([ + $customerTenant = ManagedEnvironment::factory()->create([ 'external_id' => 'tenant-1', - 'name' => 'Tenant One', + 'name' => 'ManagedEnvironment One', ]); $universe = app(AllowedTenantUniverse::class); @@ -31,8 +31,8 @@ }); it('rejects attempts to target the platform tenant', function () { - $platformTenant = Tenant::factory()->create([ - 'tenant_id' => null, + $platformTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); @@ -46,15 +46,15 @@ }); it('resolves allowed tenant proposals by id and rejects the platform tenant', function () { - $platformTenant = Tenant::factory()->create([ - 'tenant_id' => null, + $platformTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); - $customerTenant = Tenant::factory()->create([ + $customerTenant = ManagedEnvironment::factory()->create([ 'external_id' => 'tenant-2', - 'name' => 'Tenant Two', + 'name' => 'ManagedEnvironment Two', ]); $universe = app(AllowedTenantUniverse::class); diff --git a/apps/platform/tests/Feature/System/Spec113/SystemLoginThrottleTest.php b/apps/platform/tests/Feature/System/Spec113/SystemLoginThrottleTest.php index 3516abb3..20d5156e 100644 --- a/apps/platform/tests/Feature/System/Spec113/SystemLoginThrottleTest.php +++ b/apps/platform/tests/Feature/System/Spec113/SystemLoginThrottleTest.php @@ -5,7 +5,7 @@ use App\Filament\System\Pages\Auth\Login; use App\Models\AuditLog; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; use Livewire\Livewire; @@ -18,8 +18,8 @@ }); it('throttles system login after repeated failures and still audits attempts', function () { - $platformTenant = Tenant::factory()->create([ - 'tenant_id' => null, + $platformTenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); @@ -50,14 +50,14 @@ ->assertHasErrors(['data.email']); $auditCount = AuditLog::query() - ->where('tenant_id', $platformTenant->getKey()) + ->where('managed_environment_id', $platformTenant->getKey()) ->where('action', 'platform.auth.login') ->count(); expect($auditCount)->toBe(11); $latestAudit = AuditLog::query() - ->where('tenant_id', $platformTenant->getKey()) + ->where('managed_environment_id', $platformTenant->getKey()) ->where('action', 'platform.auth.login') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/System/Spec114/AccessLogsTest.php b/apps/platform/tests/Feature/System/Spec114/AccessLogsTest.php index a7573ee6..ec3de033 100644 --- a/apps/platform/tests/Feature/System/Spec114/AccessLogsTest.php +++ b/apps/platform/tests/Feature/System/Spec114/AccessLogsTest.php @@ -4,7 +4,7 @@ use App\Models\AuditLog; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Audit\AuditActionId; use App\Support\Auth\PlatformCapabilities; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -12,12 +12,12 @@ uses(RefreshDatabase::class); it('lists platform auth access logs with success and failed statuses plus break-glass actions', function () { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'external_id' => 'platform', ]); AuditLog::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'action' => 'platform.auth.login', 'status' => 'success', @@ -26,7 +26,7 @@ ]); AuditLog::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'action' => 'platform.auth.login', 'status' => 'failed', @@ -35,7 +35,7 @@ ]); AuditLog::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'action' => 'platform.break_glass.enter', 'status' => 'success', @@ -44,7 +44,7 @@ ]); AuditLog::query()->create([ - 'tenant_id' => null, + 'managed_environment_id' => null, 'workspace_id' => (int) $tenant->workspace_id, 'action' => AuditActionId::SupportAccessRequested->value, 'status' => 'success', @@ -54,7 +54,7 @@ ]); AuditLog::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'action' => 'platform.unrelated.event', 'status' => 'success', diff --git a/apps/platform/tests/Feature/System/Spec114/DirectoryTenantsTest.php b/apps/platform/tests/Feature/System/Spec114/DirectoryTenantsTest.php index b4535dcb..5164bf22 100644 --- a/apps/platform/tests/Feature/System/Spec114/DirectoryTenantsTest.php +++ b/apps/platform/tests/Feature/System/Spec114/DirectoryTenantsTest.php @@ -4,7 +4,7 @@ use App\Models\PlatformUser; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Auth\PlatformCapabilities; use App\Support\Providers\ProviderConsentStatus; @@ -30,27 +30,27 @@ it('lists tenants in the system directory with canonical health rollups from default microsoft connections only', function () { $workspace = Workspace::factory()->create(['name' => 'Directory Workspace']); - $criticalTenant = Tenant::factory()->create([ + $criticalTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'A Critical Tenant', - 'status' => Tenant::STATUS_ACTIVE, + 'name' => 'A Critical ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); - $warningTenant = Tenant::factory()->create([ + $warningTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'B Warning Tenant', - 'status' => Tenant::STATUS_ACTIVE, + 'name' => 'B Warning ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); - $healthyTenant = Tenant::factory()->create([ + $healthyTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'C Healthy Tenant', - 'status' => Tenant::STATUS_ACTIVE, + 'name' => 'C Healthy ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $criticalTenant->getKey(), + 'managed_environment_id' => (int) $criticalTenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'is_enabled' => true, @@ -60,7 +60,7 @@ ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $warningTenant->getKey(), + 'managed_environment_id' => (int) $warningTenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'is_enabled' => true, @@ -70,7 +70,7 @@ ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $healthyTenant->getKey(), + 'managed_environment_id' => (int) $healthyTenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'is_enabled' => false, @@ -80,7 +80,7 @@ ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $healthyTenant->getKey(), + 'managed_environment_id' => (int) $healthyTenant->getKey(), 'provider' => 'microsoft', 'is_default' => false, 'is_enabled' => true, @@ -100,11 +100,11 @@ ->get('/system/directory/tenants') ->assertSuccessful() ->assertSeeInOrder([ - 'A Critical Tenant', + 'A Critical ManagedEnvironment', 'Critical', - 'B Warning Tenant', + 'B Warning ManagedEnvironment', 'Warn', - 'C Healthy Tenant', + 'C Healthy ManagedEnvironment', 'OK', ]); }); @@ -112,15 +112,15 @@ it('renders system tenant detail rows with lifecycle, consent, and verification only', function () { $workspace = Workspace::factory()->create(['name' => 'Directory Workspace']); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Directory Detail Tenant', - 'status' => Tenant::STATUS_ACTIVE, + 'name' => 'Directory Detail ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'display_name' => 'Disabled Default Connection', 'is_default' => true, diff --git a/apps/platform/tests/Feature/System/Spec114/DirectoryWorkspacesTest.php b/apps/platform/tests/Feature/System/Spec114/DirectoryWorkspacesTest.php index d2aecea8..d3b7aaa4 100644 --- a/apps/platform/tests/Feature/System/Spec114/DirectoryWorkspacesTest.php +++ b/apps/platform/tests/Feature/System/Spec114/DirectoryWorkspacesTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Auth\PlatformCapabilities; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -27,14 +27,14 @@ $workspaceA = Workspace::factory()->create(['name' => 'Alpha Workspace']); $workspaceB = Workspace::factory()->create(['name' => 'Bravo Workspace']); - Tenant::factory()->create([ + ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'name' => 'Tenant A', + 'name' => 'ManagedEnvironment A', ]); - Tenant::factory()->create([ + ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceB->getKey(), - 'name' => 'Tenant B', + 'name' => 'ManagedEnvironment B', ]); $platformUser = PlatformUser::factory()->create([ diff --git a/apps/platform/tests/Feature/System/Spec114/OpsFailuresViewTest.php b/apps/platform/tests/Feature/System/Spec114/OpsFailuresViewTest.php index 7c82a8b7..1eeb2ca9 100644 --- a/apps/platform/tests/Feature/System/Spec114/OpsFailuresViewTest.php +++ b/apps/platform/tests/Feature/System/Spec114/OpsFailuresViewTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Auth\PlatformCapabilities; use App\Support\OperationRunOutcome; @@ -68,7 +68,7 @@ }); it('renders governance artifact failures without resolving tenant artifact routes on the system panel', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $initiator = User::factory()->create(); $evidenceRun = $this->makeArtifactTruthRun( diff --git a/apps/platform/tests/Feature/System/Spec114/OpsTriageActionsTest.php b/apps/platform/tests/Feature/System/Spec114/OpsTriageActionsTest.php index 4a3efc4e..1c7bdb0d 100644 --- a/apps/platform/tests/Feature/System/Spec114/OpsTriageActionsTest.php +++ b/apps/platform/tests/Feature/System/Spec114/OpsTriageActionsTest.php @@ -10,7 +10,7 @@ use App\Models\AuditLog; use App\Models\OperationRun; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Auth\PlatformCapabilities; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; @@ -29,8 +29,8 @@ Filament::setCurrentPanel('system'); Filament::bootCurrentPanel(); - Tenant::factory()->create([ - 'tenant_id' => null, + ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', ]); }); diff --git a/apps/platform/tests/Feature/System/Spec195/SystemDirectoryResidualSurfaceTest.php b/apps/platform/tests/Feature/System/Spec195/SystemDirectoryResidualSurfaceTest.php index 9ed96518..b9cefe29 100644 --- a/apps/platform/tests/Feature/System/Spec195/SystemDirectoryResidualSurfaceTest.php +++ b/apps/platform/tests/Feature/System/Spec195/SystemDirectoryResidualSurfaceTest.php @@ -5,7 +5,7 @@ use App\Models\OperationRun; use App\Models\PlatformUser; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Auth\PlatformCapabilities; use App\Support\Providers\ProviderConsentStatus; @@ -18,7 +18,7 @@ it('requires directory-view capability on residual system directory detail pages', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -40,14 +40,14 @@ it('keeps the residual system tenant detail page read-mostly and contextual', function (): void { $workspace = Workspace::factory()->create(['name' => 'Residual Directory Workspace']); - $tenant = Tenant::factory()->active()->create([ + $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Residual Directory Tenant', + 'name' => 'Residual Directory ManagedEnvironment', ]); ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'display_name' => 'Residual Default Connection', 'is_default' => true, @@ -58,7 +58,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $platformUser = PlatformUser::factory()->create([ @@ -72,7 +72,7 @@ $this->actingAs($platformUser, 'platform') ->get(SystemDirectoryLinks::tenantDetail($tenant)) ->assertSuccessful() - ->assertSee('Residual Directory Tenant') + ->assertSee('Residual Directory ManagedEnvironment') ->assertSee('Residual Directory Workspace') ->assertSee('Connectivity signals') ->assertSee('Residual Default Connection') @@ -88,14 +88,14 @@ it('keeps the residual system workspace detail page read-mostly and link-driven', function (): void { $workspace = Workspace::factory()->create(['name' => 'Residual Workspace Detail']); - $tenant = Tenant::factory()->active()->create([ + $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Workspace Detail Tenant', + 'name' => 'Workspace Detail ManagedEnvironment', ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $platformUser = PlatformUser::factory()->create([ @@ -111,7 +111,7 @@ ->assertSuccessful() ->assertSee('Residual Workspace Detail') ->assertSee('Tenants summary') - ->assertSee('Workspace Detail Tenant') + ->assertSee('Workspace Detail ManagedEnvironment') ->assertSee(SystemDirectoryLinks::tenantDetail($tenant), false) ->assertSee('Open in /admin') ->assertSee(SystemDirectoryLinks::adminWorkspace($workspace), false) diff --git a/apps/platform/tests/Feature/System/SupportAccessRecoveryBoundaryTest.php b/apps/platform/tests/Feature/System/SupportAccessRecoveryBoundaryTest.php index 2d534f89..dd6a8051 100644 --- a/apps/platform/tests/Feature/System/SupportAccessRecoveryBoundaryTest.php +++ b/apps/platform/tests/Feature/System/SupportAccessRecoveryBoundaryTest.php @@ -7,7 +7,7 @@ use App\Models\AuditLog; use App\Models\PlatformUser; use App\Models\SupportAccessGrant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -20,8 +20,8 @@ Filament::setCurrentPanel('system'); Filament::bootCurrentPanel(); - Tenant::factory()->create([ - 'tenant_id' => null, + ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); diff --git a/apps/platform/tests/Feature/System/SupportAccessRequestFlowTest.php b/apps/platform/tests/Feature/System/SupportAccessRequestFlowTest.php index 20e4ba3e..d5060a79 100644 --- a/apps/platform/tests/Feature/System/SupportAccessRequestFlowTest.php +++ b/apps/platform/tests/Feature/System/SupportAccessRequestFlowTest.php @@ -6,7 +6,7 @@ use App\Models\AuditLog; use App\Models\PlatformUser; use App\Models\SupportAccessGrant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Services\Auth\BreakGlassSession; use App\Support\Audit\AuditActionId; @@ -88,8 +88,8 @@ function spec276_system_platform_user(array $extraCapabilities = []): PlatformUs }); it('activates ownerless workspace-recovery support access only through a break-glass waiver', function (): void { - Tenant::factory()->create([ - 'tenant_id' => null, + ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); diff --git a/apps/platform/tests/Feature/System/ViewWorkspaceEntitlementsTest.php b/apps/platform/tests/Feature/System/ViewWorkspaceEntitlementsTest.php index 14f2b433..5752ac0d 100644 --- a/apps/platform/tests/Feature/System/ViewWorkspaceEntitlementsTest.php +++ b/apps/platform/tests/Feature/System/ViewWorkspaceEntitlementsTest.php @@ -5,7 +5,7 @@ use App\Filament\System\Pages\Directory\ViewWorkspace; use App\Models\AuditLog; use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -34,9 +34,9 @@ 'role' => 'manager', ]); - Tenant::factory()->count(2)->create([ + ManagedEnvironment::factory()->count(2)->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ACTIVE, + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); $writer = app(SettingsWriter::class); diff --git a/apps/platform/tests/Feature/TenantRBAC/ArchivedTenantRouteAccessTest.php b/apps/platform/tests/Feature/TenantRBAC/ArchivedTenantRouteAccessTest.php index 400f8ac0..836096ac 100644 --- a/apps/platform/tests/Feature/TenantRBAC/ArchivedTenantRouteAccessTest.php +++ b/apps/platform/tests/Feature/TenantRBAC/ArchivedTenantRouteAccessTest.php @@ -2,7 +2,7 @@ use App\Filament\Resources\TenantResource; use App\Filament\Resources\TenantResource\Pages\ViewTenant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; use Filament\Actions\Action; @@ -23,7 +23,7 @@ }); it('returns 404 for non-members on the tenant dashboard route for archived tenants', function () { - $tenant = Tenant::factory()->create(['external_id' => 'archived-tenant-a']); + $tenant = ManagedEnvironment::factory()->create(['external_id' => 'archived-tenant-a']); $tenant->delete(); $user = User::factory()->create(); @@ -78,7 +78,7 @@ it('keeps archived tenant routes authoritative when another tenant is currently selected', function (): void { [$user, $selectedTenant] = createUserWithTenant(role: 'owner'); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $selectedTenant->workspace_id, ]); @@ -102,7 +102,7 @@ it('keeps onboarding admin tenant routes authoritative when another tenant is currently selected', function (): void { [$user, $selectedTenant] = createUserWithTenant(role: 'owner'); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $selectedTenant->workspace_id, ]); diff --git a/apps/platform/tests/Feature/TenantRBAC/BreakGlassRecoveryTest.php b/apps/platform/tests/Feature/TenantRBAC/BreakGlassRecoveryTest.php index 0376b31e..2488b833 100644 --- a/apps/platform/tests/Feature/TenantRBAC/BreakGlassRecoveryTest.php +++ b/apps/platform/tests/Feature/TenantRBAC/BreakGlassRecoveryTest.php @@ -1,7 +1,7 @@ create(); $this->actingAs($user); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $this->get('/admin/break-glass-recovery')->assertNotFound(); - expect(AuditLog::query()->where('tenant_id', $tenant->getKey())->where('action', 'tenant_membership.bootstrap_recover')->exists()) + expect(AuditLog::query()->where('managed_environment_id', $tenant->getKey())->where('action', 'tenant_membership.bootstrap_recover')->exists()) ->toBeFalse(); }); diff --git a/apps/platform/tests/Feature/TenantRBAC/LastOwnerGuardTest.php b/apps/platform/tests/Feature/TenantRBAC/LastOwnerGuardTest.php index 76513532..2af73f8d 100644 --- a/apps/platform/tests/Feature/TenantRBAC/LastOwnerGuardTest.php +++ b/apps/platform/tests/Feature/TenantRBAC/LastOwnerGuardTest.php @@ -1,6 +1,6 @@ where('tenant_id', $tenant->getKey()) + $membership = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', $tenant->getKey()) ->where('user_id', $actor->getKey()) ->firstOrFail(); @@ -24,8 +24,8 @@ it('prevents removing the last remaining owner', function () { [$actor, $tenant] = createUserWithTenant(role: 'owner'); - $membership = TenantMembership::query() - ->where('tenant_id', $tenant->getKey()) + $membership = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', $tenant->getKey()) ->where('user_id', $actor->getKey()) ->firstOrFail(); diff --git a/apps/platform/tests/Feature/TenantRBAC/MembershipAuditLogTest.php b/apps/platform/tests/Feature/TenantRBAC/MembershipAuditLogTest.php index 799d784a..c29e82be 100644 --- a/apps/platform/tests/Feature/TenantRBAC/MembershipAuditLogTest.php +++ b/apps/platform/tests/Feature/TenantRBAC/MembershipAuditLogTest.php @@ -18,7 +18,7 @@ $manager->removeMember($tenant, $actor, $membership); $actions = AuditLog::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereIn('action', [ 'tenant_membership.add', 'tenant_membership.role_change', @@ -32,7 +32,7 @@ expect($actions)->toContain('tenant_membership.remove'); $metadata = AuditLog::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->whereIn('action', [ 'tenant_membership.add', 'tenant_membership.role_change', diff --git a/apps/platform/tests/Feature/TenantRBAC/RoleDefinitionsSyncNowTest.php b/apps/platform/tests/Feature/TenantRBAC/RoleDefinitionsSyncNowTest.php index 7101b43e..da4ed3f0 100644 --- a/apps/platform/tests/Feature/TenantRBAC/RoleDefinitionsSyncNowTest.php +++ b/apps/platform/tests/Feature/TenantRBAC/RoleDefinitionsSyncNowTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\ProviderOperationStartResult; use App\Services\Directory\RoleDefinitionsSyncService; use App\Support\OperationRunLinks; @@ -15,8 +15,8 @@ it('starts a role definitions sync with an immediate canonical view link', function (): void { Bus::fake(); - /** @var Tenant $tenant */ - $tenant = Tenant::factory()->create([ + /** @var ManagedEnvironment $tenant */ + $tenant = ManagedEnvironment::factory()->create([ 'app_client_id' => 'client-123', 'app_client_secret' => 'secret', 'status' => 'active', diff --git a/apps/platform/tests/Feature/TenantRBAC/TenantBootstrapAssignTest.php b/apps/platform/tests/Feature/TenantRBAC/TenantBootstrapAssignTest.php index d903e4ad..0e8ce04a 100644 --- a/apps/platform/tests/Feature/TenantRBAC/TenantBootstrapAssignTest.php +++ b/apps/platform/tests/Feature/TenantRBAC/TenantBootstrapAssignTest.php @@ -2,8 +2,8 @@ use App\Filament\Pages\Tenancy\RegisterTenant; use App\Models\AuditLog; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,7 +13,7 @@ it('bootstraps tenant creator as owner and audits the assignment', function () { $user = User::factory()->create(); - $existingTenant = Tenant::factory()->create(); + $existingTenant = ManagedEnvironment::factory()->create(); $user->tenants()->syncWithoutDetaching([ $existingTenant->getKey() => ['role' => 'owner'], ]); @@ -27,16 +27,16 @@ Livewire::test(RegisterTenant::class) ->set('data.name', 'Acme') ->set('data.environment', 'other') - ->set('data.tenant_id', $tenantGuid) + ->set('data.managed_environment_id', $tenantGuid) ->set('data.domain', 'acme.example') ->call('register'); Filament::setCurrentPanel(null); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->forTenant($tenantGuid)->firstOrFail(); - $membership = TenantMembership::query() - ->where('tenant_id', $tenant->getKey()) + $membership = ManagedEnvironmentMembership::query() + ->where('managed_environment_id', $tenant->getKey()) ->where('user_id', $user->getKey()) ->firstOrFail(); @@ -44,7 +44,7 @@ expect($membership->source)->toBe('manual'); $audit = AuditLog::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('action', 'tenant_membership.bootstrap_assign') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/TenantRBAC/TenantDiagnosticsAccessTest.php b/apps/platform/tests/Feature/TenantRBAC/TenantDiagnosticsAccessTest.php index 8a2283b3..805a2a4d 100644 --- a/apps/platform/tests/Feature/TenantRBAC/TenantDiagnosticsAccessTest.php +++ b/apps/platform/tests/Feature/TenantRBAC/TenantDiagnosticsAccessTest.php @@ -1,11 +1,11 @@ create(['external_id' => 'tenant-diag-a']); + $tenant = ManagedEnvironment::factory()->create(['external_id' => 'tenant-diag-a']); $user = User::factory()->create(); $this->actingAs($user) @@ -35,8 +35,8 @@ $this->actingAs($user); Filament::setTenant($tenant, true); - TenantMembership::query() - ->where('tenant_id', (int) $tenant->getKey()) + ManagedEnvironmentMembership::query() + ->where('managed_environment_id', (int) $tenant->getKey()) ->update(['role' => 'readonly']); Livewire::test(TenantDiagnostics::class) diff --git a/apps/platform/tests/Feature/TenantRBAC/TenantGuidVsBigintGuardTest.php b/apps/platform/tests/Feature/TenantRBAC/TenantGuidVsBigintGuardTest.php index 3d2109cb..2ae5c0c7 100644 --- a/apps/platform/tests/Feature/TenantRBAC/TenantGuidVsBigintGuardTest.php +++ b/apps/platform/tests/Feature/TenantRBAC/TenantGuidVsBigintGuardTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\TenantDiagnostics; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; use Livewire\Livewire; @@ -16,7 +16,7 @@ // Ensure the tenant has a GUID-like external identifier (this is the tenant route key). $tenant->forceFill([ 'external_id' => '00000000-0000-0000-0000-000000000123', - 'tenant_id' => '00000000-0000-0000-0000-000000000123', + 'managed_environment_id' => '00000000-0000-0000-0000-000000000123', ])->save(); $this->actingAs($user); diff --git a/apps/platform/tests/Feature/TenantRBAC/TenantMembershipCrudTest.php b/apps/platform/tests/Feature/TenantRBAC/TenantMembershipCrudTest.php index 56bfda44..9df0669d 100644 --- a/apps/platform/tests/Feature/TenantRBAC/TenantMembershipCrudTest.php +++ b/apps/platform/tests/Feature/TenantRBAC/TenantMembershipCrudTest.php @@ -14,9 +14,9 @@ $membership = $manager->addMember($tenant, $actor, $member, 'readonly'); - $this->assertDatabaseHas('tenant_memberships', [ + $this->assertDatabaseHas('managed_environment_memberships', [ 'id' => $membership->getKey(), - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $member->getKey(), 'role' => 'readonly', 'source' => 'manual', @@ -28,8 +28,8 @@ $manager->removeMember($tenant, $actor, $updated); - $this->assertDatabaseMissing('tenant_memberships', [ - 'tenant_id' => $tenant->getKey(), + $this->assertDatabaseMissing('managed_environment_memberships', [ + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $member->getKey(), ]); }); diff --git a/apps/platform/tests/Feature/TenantRBAC/TenantRouteDenyAsNotFoundTest.php b/apps/platform/tests/Feature/TenantRBAC/TenantRouteDenyAsNotFoundTest.php index 5dc47841..254c1d2d 100644 --- a/apps/platform/tests/Feature/TenantRBAC/TenantRouteDenyAsNotFoundTest.php +++ b/apps/platform/tests/Feature/TenantRBAC/TenantRouteDenyAsNotFoundTest.php @@ -1,6 +1,6 @@ create(['external_id' => 'tenant-a']); + $tenant = ManagedEnvironment::factory()->create(['external_id' => 'tenant-a']); $user = User::factory()->create(); $this->actingAs($user) @@ -27,7 +27,7 @@ it('enforces panel boundary semantics between workspace routes and tenant routes', function () { [$user, $tenant] = createUserWithTenant(role: 'readonly'); - $otherTenant = Tenant::factory()->create([ + $otherTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'external_id' => 'boundary-tenant-b', ]); @@ -45,7 +45,7 @@ it('keeps non-member tenant-bound requests as 404 even when another tenant is selected', function () { [$user, $selectedTenant] = createUserWithTenant(role: 'readonly'); - $otherTenant = Tenant::factory()->active()->create([ + $otherTenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $selectedTenant->workspace_id, 'external_id' => 'hidden-tenant-b', ]); @@ -61,7 +61,7 @@ it('keeps non-member onboarding tenant admin routes as 404 even when another tenant is selected', function (): void { [$user, $selectedTenant] = createUserWithTenant(role: 'owner'); - $otherTenant = Tenant::factory()->onboarding()->create([ + $otherTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $selectedTenant->workspace_id, 'external_id' => 'hidden-onboarding-tenant-b', ]); diff --git a/apps/platform/tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php b/apps/platform/tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php index 2f308c9d..eabb447c 100644 --- a/apps/platform/tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php +++ b/apps/platform/tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php @@ -4,7 +4,7 @@ use App\Filament\Pages\ChooseTenant; use App\Filament\Resources\TenantResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; @@ -17,12 +17,12 @@ it('only returns active membership tenants for normal users', function (): void { $user = User::factory()->create(); - $allowed = Tenant::factory()->active()->create(['name' => 'Allowed']); - $onboarding = Tenant::factory()->onboarding()->create([ + $allowed = ManagedEnvironment::factory()->active()->create(['name' => 'Allowed']); + $onboarding = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $allowed->workspace_id, 'name' => 'Onboarding', ]); - $archived = Tenant::factory()->archived()->create([ + $archived = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $allowed->workspace_id, 'name' => 'Archived', ]); @@ -40,15 +40,15 @@ expect($tenants)->toHaveCount(1); expect($tenants->first()?->getKey())->toBe($allowed->getKey()); - expect($tenants->contains(fn (Tenant $tenant): bool => $tenant->name === 'Onboarding'))->toBeFalse(); - expect($tenants->contains(fn (Tenant $tenant): bool => $tenant->name === 'Archived'))->toBeFalse(); + expect($tenants->contains(fn (ManagedEnvironment $tenant): bool => $tenant->name === 'Onboarding'))->toBeFalse(); + expect($tenants->contains(fn (ManagedEnvironment $tenant): bool => $tenant->name === 'Archived'))->toBeFalse(); }); it('returns no tenants for users without active tenant memberships', function (): void { $user = User::factory()->create(); - $draft = Tenant::factory()->draft()->create(['name' => 'Draft']); - $archived = Tenant::factory()->archived()->create([ + $draft = ManagedEnvironment::factory()->draft()->create(['name' => 'Draft']); + $archived = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $draft->workspace_id, 'name' => 'Archived', ]); @@ -67,12 +67,12 @@ it('rejects selecting non-active memberships as tenant context', function (): void { $user = User::factory()->create(); - $active = Tenant::factory()->active()->create(['name' => 'Allowed']); - $onboarding = Tenant::factory()->onboarding()->create([ + $active = ManagedEnvironment::factory()->active()->create(['name' => 'Allowed']); + $onboarding = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $active->workspace_id, 'name' => 'Onboarding', ]); - $archived = Tenant::factory()->archived()->create([ + $archived = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $active->workspace_id, 'name' => 'Archived', ]); @@ -99,12 +99,12 @@ it('keeps tenant global-search broader than selector eligibility when the user only has administratively discoverable memberships', function (): void { $user = User::factory()->create(); - $draft = Tenant::factory()->draft()->create(['name' => 'Search Draft']); - $onboarding = Tenant::factory()->onboarding()->create([ + $draft = ManagedEnvironment::factory()->draft()->create(['name' => 'Search Draft']); + $onboarding = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $draft->workspace_id, 'name' => 'Search Onboarding', ]); - $archived = Tenant::factory()->archived()->create([ + $archived = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $draft->workspace_id, 'name' => 'Search Archived', ]); @@ -133,16 +133,16 @@ }); it('does not render onboarding or archived tenants in the header selector on workspace pages', function (): void { - $activeTenant = Tenant::factory()->active()->create(['name' => 'Header Active Tenant']); + $activeTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Header Active ManagedEnvironment']); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Header Onboarding Tenant', + 'name' => 'Header Onboarding ManagedEnvironment', ]); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Header Archived Tenant', + 'name' => 'Header Archived ManagedEnvironment', ]); createUserWithTenant(tenant: $onboardingTenant, user: $user, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); @@ -154,8 +154,8 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $activeTenant->workspace_id]) ->get(route('admin.operations.index')) ->assertSuccessful() - ->assertSee('Header Active Tenant') - ->assertDontSee('Header Onboarding Tenant') - ->assertDontSee('Header Archived Tenant') + ->assertSee('Header Active ManagedEnvironment') + ->assertDontSee('Header Onboarding ManagedEnvironment') + ->assertDontSee('Header Archived ManagedEnvironment') ->assertSee('No tenant selected'); }); diff --git a/apps/platform/tests/Feature/TenantReview/TenantReviewAuditLogTest.php b/apps/platform/tests/Feature/TenantReview/TenantReviewAuditLogTest.php index 8d147faa..18061b82 100644 --- a/apps/platform/tests/Feature/TenantReview/TenantReviewAuditLogTest.php +++ b/apps/platform/tests/Feature/TenantReview/TenantReviewAuditLogTest.php @@ -28,7 +28,7 @@ $review = $reviewService->compose($review); EvidenceSnapshot::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('status', 'active') ->update([ 'status' => 'expired', @@ -47,7 +47,7 @@ $published = $lifecycle->publish($review, $user, 'Publishing the current review pack.'); EvidenceSnapshot::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('status', 'active') ->update([ 'status' => 'expired', diff --git a/apps/platform/tests/Feature/TenantReview/TenantReviewCreationTest.php b/apps/platform/tests/Feature/TenantReview/TenantReviewCreationTest.php index c550c6bc..c4ba0dd0 100644 --- a/apps/platform/tests/Feature/TenantReview/TenantReviewCreationTest.php +++ b/apps/platform/tests/Feature/TenantReview/TenantReviewCreationTest.php @@ -27,7 +27,7 @@ ->and($review->summary['evidence_basis']['snapshot_id'])->toBe((int) $snapshot->getKey()); Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'severity' => Finding::SEVERITY_CRITICAL, ]); diff --git a/apps/platform/tests/Feature/TenantReview/TenantReviewCycleTest.php b/apps/platform/tests/Feature/TenantReview/TenantReviewCycleTest.php index c29cb501..ca70294b 100644 --- a/apps/platform/tests/Feature/TenantReview/TenantReviewCycleTest.php +++ b/apps/platform/tests/Feature/TenantReview/TenantReviewCycleTest.php @@ -15,7 +15,7 @@ ); EvidenceSnapshot::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('status', 'active') ->update([ 'status' => 'expired', diff --git a/apps/platform/tests/Feature/TenantReview/TenantReviewExplanationSurfaceTest.php b/apps/platform/tests/Feature/TenantReview/TenantReviewExplanationSurfaceTest.php index 810dda9b..53f6bfa2 100644 --- a/apps/platform/tests/Feature/TenantReview/TenantReviewExplanationSurfaceTest.php +++ b/apps/platform/tests/Feature/TenantReview/TenantReviewExplanationSurfaceTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Reviews\ReviewRegister; use App\Filament\Pages\Reviews\CustomerReviewWorkspace; use App\Filament\Resources\TenantReviewResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunLinks; use App\Support\ReasonTranslation\ReasonPresenter; use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter; @@ -17,7 +17,7 @@ uses(BuildsGovernanceArtifactTruthFixtures::class); it('reuses the same operator explanation on tenant review detail and review register surfaces', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = $this->makeArtifactTruthEvidenceSnapshot($tenant); @@ -66,7 +66,7 @@ }); it('keeps customer-workspace review detail customer-readable by hiding internal reason ownership and fingerprints', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $snapshot = seedTenantReviewEvidence($tenant); diff --git a/apps/platform/tests/Feature/TenantReview/TenantReviewExportOperationsUxTest.php b/apps/platform/tests/Feature/TenantReview/TenantReviewExportOperationsUxTest.php index 52d3cbe6..3b66af67 100644 --- a/apps/platform/tests/Feature/TenantReview/TenantReviewExportOperationsUxTest.php +++ b/apps/platform/tests/Feature/TenantReview/TenantReviewExportOperationsUxTest.php @@ -6,7 +6,7 @@ use App\Jobs\GenerateReviewPackJob; use App\Models\OperationRun; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Notifications\OperationRunCompleted; use App\Support\OperationRunOutcome; @@ -21,7 +21,7 @@ }); it('preserves executive-pack export visibility but disables it for readonly operators', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$owner, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); [$readonly] = createUserWithTenant(tenant: $tenant, user: User::factory()->create(), role: 'readonly'); $review = composeTenantReviewForTest($tenant, $owner); diff --git a/apps/platform/tests/Feature/TenantReview/TenantReviewRbacTest.php b/apps/platform/tests/Feature/TenantReview/TenantReviewRbacTest.php index c26dbaa6..54850c7d 100644 --- a/apps/platform/tests/Feature/TenantReview/TenantReviewRbacTest.php +++ b/apps/platform/tests/Feature/TenantReview/TenantReviewRbacTest.php @@ -5,13 +5,13 @@ use App\Filament\Resources\TenantReviewResource; use App\Filament\Resources\TenantReviewResource\Pages\ListTenantReviews; use App\Filament\Resources\TenantReviewResource\Pages\ViewTenantReview; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Auth\UiTooltips; use Livewire\Livewire; it('returns not found for non-members on the tenant review library and detail routes', function (): void { - $targetTenant = Tenant::factory()->create(); + $targetTenant = ManagedEnvironment::factory()->create(); [$member] = createUserWithTenant(role: 'owner'); $reviewOwner = User::factory()->create(); createUserWithTenant(tenant: $targetTenant, user: $reviewOwner, role: 'owner'); @@ -27,7 +27,7 @@ }); it('allows readonly members to inspect reviews but keeps create actions disabled', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$owner, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); [$readonly] = createUserWithTenant(tenant: $tenant, user: User::factory()->create(), role: 'readonly'); $review = composeTenantReviewForTest($tenant, $owner); diff --git a/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterPrefilterTest.php b/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterPrefilterTest.php index 436eae3e..f46a52ed 100644 --- a/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterPrefilterTest.php +++ b/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterPrefilterTest.php @@ -3,17 +3,17 @@ declare(strict_types=1); use App\Filament\Pages\Reviews\ReviewRegister; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Livewire\Livewire; it('defaults the canonical review register to the remembered tenant when tenant context is available', function (): void { - $tenantA = Tenant::factory()->create(['name' => 'Alpha Tenant']); + $tenantA = ManagedEnvironment::factory()->create(['name' => 'Alpha ManagedEnvironment']); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'readonly'); @@ -40,7 +40,7 @@ Livewire::actingAs($user) ->test(ReviewRegister::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantB->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantB->getKey()) ->assertCanSeeTableRecords([$reviewB]) ->assertCanNotSeeTableRecords([$reviewA]) ->assertSee('Publication blocked') @@ -49,12 +49,12 @@ }); it('prefilters the review register from a tenant query parameter and accepts external tenant identifiers', function (): void { - $tenantA = Tenant::factory()->create(['name' => 'Alpha Tenant']); + $tenantA = ManagedEnvironment::factory()->create(['name' => 'Alpha ManagedEnvironment']); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'readonly'); @@ -78,7 +78,7 @@ Livewire::withQueryParams(['tenant' => (string) $tenantA->external_id]) ->test(ReviewRegister::class) - ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) + ->assertSet('tableFilters.managed_environment_id.value', (string) $tenantA->getKey()) ->assertCanSeeTableRecords([$reviewA]) ->assertCanNotSeeTableRecords([$reviewB]) ->assertSee('Publication blocked') @@ -87,18 +87,18 @@ }); it('scopes canonical tenant filter options to entitled tenants only', function (): void { - $tenantA = Tenant::factory()->create(['name' => 'Alpha Tenant']); + $tenantA = ManagedEnvironment::factory()->create(['name' => 'Alpha ManagedEnvironment']); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'readonly'); - $tenantC = Tenant::factory()->create([ + $tenantC = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Gamma Tenant', + 'name' => 'Gamma ManagedEnvironment', ]); $this->actingAs($user); @@ -106,7 +106,7 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); $component = Livewire::actingAs($user)->test(ReviewRegister::class); - $tenantFilter = $component->instance()->getTable()->getFilters()['tenant_id'] ?? null; + $tenantFilter = $component->instance()->getTable()->getFilters()['managed_environment_id'] ?? null; expect($tenantFilter)->not->toBeNull() ->and($tenantFilter?->getOptions())->toBe([ diff --git a/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterRbacTest.php b/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterRbacTest.php index d3e36692..a95913f6 100644 --- a/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterRbacTest.php +++ b/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterRbacTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\Reviews\ReviewRegister; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -37,7 +37,7 @@ }); it('allows entitled workspace members to access the canonical review register', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); composeTenantReviewForTest($tenant, $user); @@ -48,7 +48,7 @@ }); it('shows artifact-truth rows only for entitled tenants on the canonical review register', function (): void { - $tenantAllowed = Tenant::factory()->create(['name' => 'Allowed Tenant']); + $tenantAllowed = ManagedEnvironment::factory()->create(['name' => 'Allowed ManagedEnvironment']); [$user, $tenantAllowed] = createUserWithTenant(tenant: $tenantAllowed, role: 'readonly'); $allowedReview = composeTenantReviewForTest( @@ -64,9 +64,9 @@ ), ); - $tenantDenied = Tenant::factory()->create([ + $tenantDenied = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantAllowed->workspace_id, - 'name' => 'Denied Tenant', + 'name' => 'Denied ManagedEnvironment', ]); [$otherOwner, $tenantDenied] = createUserWithTenant(tenant: $tenantDenied, role: 'owner'); $deniedReview = composeTenantReviewForTest($tenantDenied, $otherOwner); @@ -81,5 +81,5 @@ ->assertCanNotSeeTableRecords([$deniedReview]) ->assertSee('Publication blocked') ->assertSee('Resolve the review blockers before publication') - ->assertDontSee('Denied Tenant'); + ->assertDontSee('Denied ManagedEnvironment'); }); diff --git a/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterTest.php b/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterTest.php index bdecfcbf..8c4a9982 100644 --- a/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterTest.php +++ b/apps/platform/tests/Feature/TenantReview/TenantReviewRegisterTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\Reviews\ReviewRegister; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\TenantReviewCompletenessState; use App\Support\TenantReviewStatus; @@ -14,18 +14,18 @@ uses(BuildsGovernanceArtifactTruthFixtures::class); it('lists only entitled tenant reviews in the canonical review register and filters by tenant', function (): void { - $tenantA = Tenant::factory()->create(['name' => 'Alpha Tenant']); + $tenantA = ManagedEnvironment::factory()->create(['name' => 'Alpha ManagedEnvironment']); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'readonly'); - $tenantC = Tenant::factory()->create([ + $tenantC = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Gamma Tenant', + 'name' => 'Gamma ManagedEnvironment', ]); $foreignOwner = User::factory()->create(); createUserWithTenant(tenant: $tenantC, user: $foreignOwner, role: 'owner'); @@ -45,7 +45,7 @@ ->assertDontSee('Navigation lane') ->assertCanSeeTableRecords([$reviewA, $reviewB]) ->assertCanNotSeeTableRecords([$reviewC]) - ->filterTable('tenant_id', (string) $tenantB->getKey()) + ->filterTable('managed_environment_id', (string) $tenantB->getKey()) ->assertCanSeeTableRecords([$reviewB]) ->assertCanNotSeeTableRecords([$reviewA, $reviewC]); }); @@ -68,12 +68,12 @@ }); it('clears the remembered tenant prefilter from the review register', function (): void { - $tenantA = Tenant::factory()->create(['name' => 'Alpha Tenant']); + $tenantA = ManagedEnvironment::factory()->create(['name' => 'Alpha ManagedEnvironment']); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'name' => 'Beta Tenant', + 'name' => 'Beta ManagedEnvironment', ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); @@ -104,12 +104,12 @@ }); it('keeps stale and partial review rows aligned with tenant review detail trust', function (): void { - $staleTenant = Tenant::factory()->create(['name' => 'Stale Tenant']); + $staleTenant = ManagedEnvironment::factory()->create(['name' => 'Stale ManagedEnvironment']); [$user, $staleTenant] = createUserWithTenant(tenant: $staleTenant, role: 'owner'); - $partialTenant = Tenant::factory()->create([ + $partialTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $staleTenant->workspace_id, - 'name' => 'Partial Tenant', + 'name' => 'Partial ManagedEnvironment', ]); createUserWithTenant(tenant: $partialTenant, user: $user, role: 'owner'); diff --git a/apps/platform/tests/Feature/TenantReview/TenantReviewUiContractTest.php b/apps/platform/tests/Feature/TenantReview/TenantReviewUiContractTest.php index bbc5b047..60780f9d 100644 --- a/apps/platform/tests/Feature/TenantReview/TenantReviewUiContractTest.php +++ b/apps/platform/tests/Feature/TenantReview/TenantReviewUiContractTest.php @@ -8,7 +8,7 @@ use App\Filament\Resources\TenantReviewResource\Pages\ListTenantReviews; use App\Filament\Resources\TenantReviewResource\Pages\ViewTenantReview; use App\Models\ReviewPack; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantReview; use App\Models\User; use App\Support\TenantReviewStatus; @@ -93,7 +93,7 @@ function tenantReviewContractHeaderActions(Testable $component): array }); it('requires confirmation for destructive tenant-review actions and preserves disabled management visibility for readonly users', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$owner, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); [$readonly] = createUserWithTenant(tenant: $tenant, user: User::factory()->create(), role: 'readonly'); $review = composeTenantReviewForTest($tenant, $owner); @@ -170,7 +170,7 @@ function tenantReviewContractHeaderActions(Testable $component): array }); it('uses the current review-pack download as the only customer-workspace detail header action', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $snapshot = seedTenantReviewEvidence($tenant); @@ -184,7 +184,7 @@ function tenantReviewContractHeaderActions(Testable $component): array Storage::disk('exports')->put('review-packs/customer-detail-primary.zip', 'PK-test'); $pack = ReviewPack::factory()->ready()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'tenant_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), @@ -233,12 +233,12 @@ function tenantReviewContractHeaderActions(Testable $component): array }); it('shows publication truth and next-step guidance when a review is not yet publishable', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$owner, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = seedTenantReviewEvidence($tenant); $review = TenantReview::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'initiated_by_user_id' => (int) $owner->getKey(), @@ -268,7 +268,7 @@ function tenantReviewContractHeaderActions(Testable $component): array }); it('keeps executive posture from claiming publication readiness for internal-only reviews', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$owner, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $review = $this->makeInternalOnlyArtifactTruthReview($tenant, $owner); diff --git a/apps/platform/tests/Feature/Tenants/TenantProviderBackedActionStartTest.php b/apps/platform/tests/Feature/Tenants/TenantProviderBackedActionStartTest.php index 94778b9b..663208f1 100644 --- a/apps/platform/tests/Feature/Tenants/TenantProviderBackedActionStartTest.php +++ b/apps/platform/tests/Feature/Tenants/TenantProviderBackedActionStartTest.php @@ -22,7 +22,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('is_default', true) ->firstOrFail(); @@ -33,7 +33,7 @@ $component->callAction('verify'); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); @@ -50,7 +50,7 @@ ]); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->count())->toBe(1); @@ -70,7 +70,7 @@ ->callAction('verify'); $run = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); diff --git a/apps/platform/tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php b/apps/platform/tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php index 8e4fe5f2..68ae0937 100644 --- a/apps/platform/tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php +++ b/apps/platform/tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php @@ -13,11 +13,11 @@ $this->actingAs($user) ->get(TenantResource::getUrl('view', ['record' => $tenant], tenant: $tenant)) ->assertOk() - ->assertSee('/admin/provider-connections?tenant_id='.(string) $tenant->external_id, false); + ->assertSee('/admin/provider-connections?managed_environment_id='.(string) $tenant->external_id, false); }); it('keeps the canonical provider connections CTA when the tenant needs a default microsoft connection', function (): void { - $tenant = \App\Models\Tenant::factory()->active()->create(); + $tenant = \App\Models\ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant( tenant: $tenant, role: 'owner', @@ -26,7 +26,7 @@ \App\Models\ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'display_name' => 'Fallback Connection', 'is_default' => false, @@ -35,11 +35,11 @@ $this->actingAs($user) ->get(TenantResource::getUrl('view', ['record' => $tenant], tenant: $tenant)) ->assertOk() - ->assertSee('/admin/provider-connections?tenant_id='.(string) $tenant->external_id, false); + ->assertSee('/admin/provider-connections?managed_environment_id='.(string) $tenant->external_id, false); }); it('renders the tenant provider summary with lifecycle, consent, and verification only', function (): void { - $tenant = \App\Models\Tenant::factory()->active()->create(); + $tenant = \App\Models\ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant( tenant: $tenant, role: 'owner', @@ -48,7 +48,7 @@ ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'display_name' => 'Canonical Summary Connection', 'is_default' => true, diff --git a/apps/platform/tests/Feature/TermsAndConditionsPolicyTypeTest.php b/apps/platform/tests/Feature/TermsAndConditionsPolicyTypeTest.php index 77c79093..73d46be2 100644 --- a/apps/platform/tests/Feature/TermsAndConditionsPolicyTypeTest.php +++ b/apps/platform/tests/Feature/TermsAndConditionsPolicyTypeTest.php @@ -1,7 +1,7 @@ instance(GraphClientInterface::class, $client); - $tenant = Tenant::factory()->create(['tenant_id' => 'tenant-1']); + $tenant = ManagedEnvironment::factory()->create(['managed_environment_id' => 'tenant-1']); ensureDefaultProviderConnection($tenant); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'tc-1', 'policy_type' => 'termsAndConditions', 'platform' => 'all', ]); $backupSet = \App\Models\BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'status' => 'completed', 'item_count' => 1, ]); $backupItem = \App\Models\BackupItem::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, @@ -182,7 +182,7 @@ public function request(string $method, string $path, array $options = []): Grap }); it('syncs terms and conditions from graph', function () { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); ensureDefaultProviderConnection($tenant); $logger = mock(GraphLogger::class); @@ -215,6 +215,6 @@ public function request(string $method, string $path, array $options = []): Grap ['type' => 'termsAndConditions', 'platform' => 'all'], ]); - expect(Policy::query()->where('tenant_id', $tenant->id)->where('policy_type', 'termsAndConditions')->count()) + expect(Policy::query()->where('managed_environment_id', $tenant->id)->where('policy_type', 'termsAndConditions')->count()) ->toBe(1); }); diff --git a/apps/platform/tests/Feature/Verification/BlockedVerificationReportStubTest.php b/apps/platform/tests/Feature/Verification/BlockedVerificationReportStubTest.php index 855bb1f7..1deddad0 100644 --- a/apps/platform/tests/Feature/Verification/BlockedVerificationReportStubTest.php +++ b/apps/platform/tests/Feature/Verification/BlockedVerificationReportStubTest.php @@ -3,14 +3,14 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\ProviderOperationStartGate; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\Verification\VerificationReportSchema; it('stores a schema-valid blocked verification report stub for blocked provider connection checks', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $result = app(ProviderOperationStartGate::class)->start( tenant: $tenant, diff --git a/apps/platform/tests/Feature/Verification/IntuneRbacPermissionCoverageTest.php b/apps/platform/tests/Feature/Verification/IntuneRbacPermissionCoverageTest.php index 2cca359c..730711b1 100644 --- a/apps/platform/tests/Feature/Verification/IntuneRbacPermissionCoverageTest.php +++ b/apps/platform/tests/Feature/Verification/IntuneRbacPermissionCoverageTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Links\RequiredPermissionsLinks; use App\Support\Providers\ProviderReasonCodes; use App\Support\Verification\TenantPermissionCheckClusters; @@ -12,7 +12,7 @@ uses(RefreshDatabase::class); it('surfaces a dedicated RBAC permission reason when DeviceManagementRBAC.Read.All is missing', function (): void { - $tenant = Tenant::factory()->create(['external_id' => 'tenant-rbac-check']); + $tenant = ManagedEnvironment::factory()->create(['external_id' => 'tenant-rbac-check']); $checks = TenantPermissionCheckClusters::buildChecks($tenant, [ [ diff --git a/apps/platform/tests/Feature/Verification/PreviousVerificationReportResolverTest.php b/apps/platform/tests/Feature/Verification/PreviousVerificationReportResolverTest.php index ea611caa..60375deb 100644 --- a/apps/platform/tests/Feature/Verification/PreviousVerificationReportResolverTest.php +++ b/apps/platform/tests/Feature/Verification/PreviousVerificationReportResolverTest.php @@ -18,11 +18,11 @@ Filament::setTenant($tenant, true); $connectionId = (int) ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ])->getKey(); $previous = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, @@ -33,7 +33,7 @@ ]); $current = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, @@ -54,11 +54,11 @@ $tenant->makeCurrent(); Filament::setTenant($tenant, true); - $connectionA = (int) ProviderConnection::factory()->create(['tenant_id' => (int) $tenant->getKey()])->getKey(); - $connectionB = (int) ProviderConnection::factory()->create(['tenant_id' => (int) $tenant->getKey()])->getKey(); + $connectionA = (int) ProviderConnection::factory()->create(['managed_environment_id' => (int) $tenant->getKey()])->getKey(); + $connectionB = (int) ProviderConnection::factory()->create(['managed_environment_id' => (int) $tenant->getKey()])->getKey(); OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, @@ -69,7 +69,7 @@ ]); $current = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, @@ -93,13 +93,13 @@ Filament::setTenant($tenant, true); $connectionA = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), ]); $connectionB = ProviderConnection::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), ]); diff --git a/apps/platform/tests/Feature/Verification/ProviderConnectionHealthCheckWritesReportTest.php b/apps/platform/tests/Feature/Verification/ProviderConnectionHealthCheckWritesReportTest.php index dfa79ba5..c2dc1b38 100644 --- a/apps/platform/tests/Feature/Verification/ProviderConnectionHealthCheckWritesReportTest.php +++ b/apps/platform/tests/Feature/Verification/ProviderConnectionHealthCheckWritesReportTest.php @@ -19,7 +19,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), ]); @@ -27,14 +27,14 @@ ProviderCredential::factory()->create([ 'provider_connection_id' => (int) $connection->getKey(), 'payload' => [ - 'tenant_id' => (string) $connection->entra_tenant_id, + 'managed_environment_id' => (string) $connection->entra_tenant_id, 'client_id' => fake()->uuid(), 'client_secret' => fake()->sha1(), ], ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => 'running', @@ -101,7 +101,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), ]); @@ -109,14 +109,14 @@ ProviderCredential::factory()->create([ 'provider_connection_id' => (int) $connection->getKey(), 'payload' => [ - 'tenant_id' => (string) $connection->entra_tenant_id, + 'managed_environment_id' => (string) $connection->entra_tenant_id, 'client_id' => fake()->uuid(), 'client_secret' => fake()->sha1(), ], ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => 'running', @@ -192,7 +192,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), ]); @@ -200,14 +200,14 @@ ProviderCredential::factory()->create([ 'provider_connection_id' => (int) $connection->getKey(), 'payload' => [ - 'tenant_id' => (string) $connection->entra_tenant_id, + 'managed_environment_id' => (string) $connection->entra_tenant_id, 'client_id' => fake()->uuid(), 'client_secret' => fake()->sha1(), ], ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => 'running', @@ -264,14 +264,14 @@ expect($adminConsentCheck['reason_code'] ?? null)->toBe('rate_limited'); expect((string) ($adminConsentCheck['message'] ?? ''))->toContain('Unable to refresh observed permissions inventory'); - expect(TenantPermission::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(0); + expect(TenantPermission::query()->where('managed_environment_id', (int) $tenant->getKey())->count())->toBe(0); }); it('degrades permission clusters to warnings when live permissions refresh cannot map assignments', function (): void { [$user, $tenant] = createUserWithTenant(role: 'operator'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), ]); @@ -279,14 +279,14 @@ ProviderCredential::factory()->create([ 'provider_connection_id' => (int) $connection->getKey(), 'payload' => [ - 'tenant_id' => (string) $connection->entra_tenant_id, + 'managed_environment_id' => (string) $connection->entra_tenant_id, 'client_id' => fake()->uuid(), 'client_secret' => fake()->sha1(), ], ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => 'running', @@ -368,5 +368,5 @@ expect($adminConsentCheck['reason_code'] ?? null)->toBeIn(['provider_permission_denied', 'unknown_error']); expect((string) ($adminConsentCheck['message'] ?? ''))->toContain('Unable to refresh observed permissions inventory'); - expect(TenantPermission::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(0); + expect(TenantPermission::query()->where('managed_environment_id', (int) $tenant->getKey())->count())->toBe(0); }); diff --git a/apps/platform/tests/Feature/Verification/ProviderExecutionReauthorizationTest.php b/apps/platform/tests/Feature/Verification/ProviderExecutionReauthorizationTest.php index ac627cef..54b288bb 100644 --- a/apps/platform/tests/Feature/Verification/ProviderExecutionReauthorizationTest.php +++ b/apps/platform/tests/Feature/Verification/ProviderExecutionReauthorizationTest.php @@ -33,7 +33,7 @@ function runQueuedJobThroughMiddleware(object $job, Closure $terminal): mixed Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -43,7 +43,7 @@ function runQueuedJobThroughMiddleware(object $job, Closure $terminal): mixed ->callTableAction('check_connection', $connection); $opRun = OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); @@ -66,7 +66,7 @@ function runQueuedJobThroughMiddleware(object $job, Closure $terminal): mixed Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -85,7 +85,7 @@ function runQueuedJobThroughMiddleware(object $job, Closure $terminal): mixed expect($capturedJob)->toBeInstanceOf(ProviderConnectionHealthCheckJob::class); - $user->tenantMemberships()->where('tenant_id', $tenant->getKey())->update(['role' => 'readonly']); + $user->tenantMemberships()->where('managed_environment_id', $tenant->getKey())->update(['role' => 'readonly']); app(CapabilityResolver::class)->clearCache(); $terminalInvoked = false; @@ -117,7 +117,7 @@ function (ProviderConnectionHealthCheckJob $job) use (&$terminalInvoked): mixed Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -136,7 +136,7 @@ function (ProviderConnectionHealthCheckJob $job) use (&$terminalInvoked): mixed expect($capturedJob)->toBeInstanceOf(ProviderConnectionHealthCheckJob::class); - $user->tenantMemberships()->where('tenant_id', $tenant->getKey())->delete(); + $user->tenantMemberships()->where('managed_environment_id', $tenant->getKey())->delete(); app(CapabilityResolver::class)->clearCache(); $terminalInvoked = false; diff --git a/apps/platform/tests/Feature/Verification/VerificationAuthorizationTest.php b/apps/platform/tests/Feature/Verification/VerificationAuthorizationTest.php index 69ab87b6..b36fa934 100644 --- a/apps/platform/tests/Feature/Verification/VerificationAuthorizationTest.php +++ b/apps/platform/tests/Feature/Verification/VerificationAuthorizationTest.php @@ -5,7 +5,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Verification\StartVerification; use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Support\Facades\Queue; @@ -14,13 +14,13 @@ it('returns 404 for non-members on verification view and start', function (): void { Queue::fake(); - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'readonly'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'failed', @@ -39,7 +39,7 @@ ->assertStatus(404); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); expect(fn () => app(StartVerification::class)->providerConnectionCheck( @@ -55,7 +55,7 @@ [$user, $tenant] = createUserWithTenant(role: 'readonly'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', @@ -76,7 +76,7 @@ ->assertSee('Verification report'); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); expect(fn () => app(StartVerification::class)->providerConnectionCheck( @@ -92,7 +92,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $connection = ProviderConnection::factory()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -109,7 +109,7 @@ expect($result->status)->toBe('started'); expect($result->run->type)->toBe('provider.connection.check'); - expect($result->run->tenant_id)->toBe((int) $tenant->getKey()); + expect($result->run->managed_environment_id)->toBe((int) $tenant->getKey()); expect($result->run->context)->toMatchArray([ 'provider_connection_id' => (int) $connection->getKey(), ]); diff --git a/apps/platform/tests/Feature/Verification/VerificationCheckAcknowledgementTest.php b/apps/platform/tests/Feature/Verification/VerificationCheckAcknowledgementTest.php index a366fce7..75df553e 100644 --- a/apps/platform/tests/Feature/Verification/VerificationCheckAcknowledgementTest.php +++ b/apps/platform/tests/Feature/Verification/VerificationCheckAcknowledgementTest.php @@ -4,7 +4,7 @@ use App\Models\AuditLog; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Verification\VerificationCheckAcknowledgementService; use App\Support\Audit\AuditActionId; use App\Support\Verification\VerificationReportFingerprint; @@ -12,13 +12,13 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; it('returns 404 for non-members on verification check acknowledgement', function (): void { - $tenant = Tenant::factory()->create(); - $otherTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $otherTenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($otherTenant, role: 'readonly'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', 'status' => 'completed', @@ -47,7 +47,7 @@ [$user, $tenant] = createUserWithTenant(role: 'operator'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', 'status' => 'completed', @@ -76,7 +76,7 @@ [$user, $tenant] = createUserWithTenant(role: 'manager'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', 'status' => 'completed', @@ -165,7 +165,7 @@ expect($audit)->not->toBeNull(); expect($audit?->metadata)->toMatchArray([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'operation_run_id' => (int) $run->getKey(), 'report_id' => (int) $run->getKey(), 'flow' => 'provider.connection.check', diff --git a/apps/platform/tests/Feature/Verification/VerificationReportMissingOrMalformedTest.php b/apps/platform/tests/Feature/Verification/VerificationReportMissingOrMalformedTest.php index 70fb034c..5af9d289 100644 --- a/apps/platform/tests/Feature/Verification/VerificationReportMissingOrMalformedTest.php +++ b/apps/platform/tests/Feature/Verification/VerificationReportMissingOrMalformedTest.php @@ -15,7 +15,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', @@ -38,7 +38,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', diff --git a/apps/platform/tests/Feature/Verification/VerificationReportRedactionTest.php b/apps/platform/tests/Feature/Verification/VerificationReportRedactionTest.php index 2dba4508..1ccb6a68 100644 --- a/apps/platform/tests/Feature/Verification/VerificationReportRedactionTest.php +++ b/apps/platform/tests/Feature/Verification/VerificationReportRedactionTest.php @@ -23,7 +23,7 @@ ); $previousRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', @@ -40,7 +40,7 @@ $report['previous_report_id'] = (int) $previousRun->getKey(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', diff --git a/apps/platform/tests/Feature/Verification/VerificationReportViewerDbOnlyTest.php b/apps/platform/tests/Feature/Verification/VerificationReportViewerDbOnlyTest.php index a6406018..0fd30164 100644 --- a/apps/platform/tests/Feature/Verification/VerificationReportViewerDbOnlyTest.php +++ b/apps/platform/tests/Feature/Verification/VerificationReportViewerDbOnlyTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\Operations\TenantlessOperationRunViewer; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -34,7 +34,7 @@ ); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', @@ -75,7 +75,7 @@ Filament::setTenant($tenant, true); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', @@ -136,9 +136,9 @@ session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user->tenants()->syncWithoutDetaching([ @@ -147,7 +147,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'is_default' => true, ]); @@ -167,7 +167,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'failed', @@ -179,8 +179,8 @@ TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'managed_environment_id' => (int) $tenant->getKey(), + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), diff --git a/apps/platform/tests/Feature/Verification/VerificationStartAfterCompletionTest.php b/apps/platform/tests/Feature/Verification/VerificationStartAfterCompletionTest.php index dce54207..9fc58e75 100644 --- a/apps/platform/tests/Feature/Verification/VerificationStartAfterCompletionTest.php +++ b/apps/platform/tests/Feature/Verification/VerificationStartAfterCompletionTest.php @@ -23,7 +23,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -59,7 +59,7 @@ expect($second->run->getKey())->not->toBe($firstRun->getKey()); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'provider.connection.check') ->count())->toBe(2); diff --git a/apps/platform/tests/Feature/Verification/VerificationStartDedupeTest.php b/apps/platform/tests/Feature/Verification/VerificationStartDedupeTest.php index 1f6c7cbb..45973941 100644 --- a/apps/platform/tests/Feature/Verification/VerificationStartDedupeTest.php +++ b/apps/platform/tests/Feature/Verification/VerificationStartDedupeTest.php @@ -20,7 +20,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -50,7 +50,7 @@ expect($second->status)->toBe('deduped'); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'provider.connection.check') ->count())->toBe(1); @@ -67,7 +67,7 @@ Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => fake()->uuid(), 'consent_status' => 'granted', @@ -96,7 +96,7 @@ expect($second->status)->toBe('deduped'); expect(OperationRun::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('type', 'provider.connection.check') ->count())->toBe(1); diff --git a/apps/platform/tests/Feature/VersionCaptureMetadataOnlyTest.php b/apps/platform/tests/Feature/VersionCaptureMetadataOnlyTest.php index 78a12a1c..15fa45ea 100644 --- a/apps/platform/tests/Feature/VersionCaptureMetadataOnlyTest.php +++ b/apps/platform/tests/Feature/VersionCaptureMetadataOnlyTest.php @@ -2,7 +2,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\AssignmentFetcher; use App\Services\Graph\ScopeTagResolver; use App\Services\Intune\PolicySnapshotService; @@ -12,7 +12,7 @@ uses(RefreshDatabase::class); it('persists metadata-only snapshot metadata on captured versions', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::factory()->for($tenant)->create([ 'policy_type' => 'mamAppConfiguration', @@ -68,7 +68,7 @@ }); it('captures and reuses immutable RBAC foundation versions from payload snapshots', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $policy = Policy::factory()->for($tenant)->create([ 'policy_type' => 'intuneRoleDefinition', diff --git a/apps/platform/tests/Feature/VersionCaptureWithAssignmentsTest.php b/apps/platform/tests/Feature/VersionCaptureWithAssignmentsTest.php index 4cdbccfa..32662c67 100644 --- a/apps/platform/tests/Feature/VersionCaptureWithAssignmentsTest.php +++ b/apps/platform/tests/Feature/VersionCaptureWithAssignmentsTest.php @@ -1,7 +1,7 @@ tenant = Tenant::factory()->create(); + $this->tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($this->tenant, 'microsoft'); $this->policy = Policy::factory()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'external_id' => 'test-policy-id', ]); @@ -307,7 +307,7 @@ ]; $version = $this->policy->versions()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_id' => $this->policy->id, 'version_number' => 1, 'policy_type' => 'deviceManagementConfigurationPolicy', @@ -323,7 +323,7 @@ // Verify same assignments produce same hash $version2 = $this->policy->versions()->create([ - 'tenant_id' => $this->tenant->id, + 'managed_environment_id' => $this->tenant->id, 'policy_id' => $this->policy->id, 'version_number' => 2, 'policy_type' => 'deviceManagementConfigurationPolicy', diff --git a/apps/platform/tests/Feature/WorkspaceIsolation/AuditLogScopeInvariantTest.php b/apps/platform/tests/Feature/WorkspaceIsolation/AuditLogScopeInvariantTest.php index e03a87ad..1a610838 100644 --- a/apps/platform/tests/Feature/WorkspaceIsolation/AuditLogScopeInvariantTest.php +++ b/apps/platform/tests/Feature/WorkspaceIsolation/AuditLogScopeInvariantTest.php @@ -1,7 +1,7 @@ create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -21,7 +21,7 @@ status: 'success', ); - expect((int) $log->tenant_id)->toBe((int) $tenant->getKey()); + expect((int) $log->managed_environment_id)->toBe((int) $tenant->getKey()); expect((int) $log->workspace_id)->toBe((int) $workspace->getKey()); }); @@ -29,7 +29,7 @@ $workspace = Workspace::factory()->create(); $workspaceScoped = AuditLog::query()->create([ - 'tenant_id' => null, + 'managed_environment_id' => null, 'workspace_id' => (int) $workspace->getKey(), 'actor_id' => null, 'actor_email' => null, @@ -43,7 +43,7 @@ ]); $platformScoped = AuditLog::query()->create([ - 'tenant_id' => null, + 'managed_environment_id' => null, 'workspace_id' => null, 'actor_id' => null, 'actor_email' => null, @@ -67,12 +67,12 @@ $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); expect(fn () => DB::table('audit_logs')->insert([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => null, 'actor_id' => null, 'actor_email' => null, diff --git a/apps/platform/tests/Feature/WorkspaceIsolation/BackfillWorkspaceIdsCommandTest.php b/apps/platform/tests/Feature/WorkspaceIsolation/BackfillWorkspaceIdsCommandTest.php index 309c16c9..bbd820bc 100644 --- a/apps/platform/tests/Feature/WorkspaceIsolation/BackfillWorkspaceIdsCommandTest.php +++ b/apps/platform/tests/Feature/WorkspaceIsolation/BackfillWorkspaceIdsCommandTest.php @@ -2,20 +2,20 @@ use App\Models\AuditLog; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use Illuminate\Support\Facades\DB; it('backfills missing workspace_id values for tenant-owned rows', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); DB::table('policies')->insert([ [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => null, 'external_id' => 'legacy-policy-a', 'policy_type' => 'settingsCatalogPolicy', @@ -27,7 +27,7 @@ 'updated_at' => now(), ], [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => null, 'external_id' => 'legacy-policy-b', 'policy_type' => 'settingsCatalogPolicy', @@ -46,14 +46,14 @@ ])->assertSuccessful(); $missingAfter = DB::table('policies') - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereNull('workspace_id') ->count(); expect($missingAfter)->toBe(0); $workspaceIds = DB::table('policies') - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->pluck('workspace_id') ->map(static fn (mixed $workspaceId): int => (int) $workspaceId) ->unique() @@ -83,12 +83,12 @@ it('is idempotent when re-run after backfill', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); DB::table('policies')->insert([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => null, 'external_id' => 'legacy-policy-retry', 'policy_type' => 'settingsCatalogPolicy', @@ -107,7 +107,7 @@ ->assertSuccessful(); $missingAfter = DB::table('policies') - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereNull('workspace_id') ->count(); @@ -115,11 +115,11 @@ }); it('aborts and reports when tenant to workspace mapping is unresolvable', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $tenant->forceFill(['workspace_id' => null])->save(); DB::table('policies')->insert([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => null, 'external_id' => 'legacy-policy-unresolvable', 'policy_type' => 'settingsCatalogPolicy', @@ -136,7 +136,7 @@ ->assertFailed(); $missingAfter = DB::table('policies') - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->whereNull('workspace_id') ->count(); diff --git a/apps/platform/tests/Feature/WorkspaceIsolation/DerivesWorkspaceIdFromTenantTest.php b/apps/platform/tests/Feature/WorkspaceIsolation/DerivesWorkspaceIdFromTenantTest.php index 81655e14..3d4b714c 100644 --- a/apps/platform/tests/Feature/WorkspaceIsolation/DerivesWorkspaceIdFromTenantTest.php +++ b/apps/platform/tests/Feature/WorkspaceIsolation/DerivesWorkspaceIdFromTenantTest.php @@ -1,19 +1,19 @@ create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $policy = Policy::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'external_id' => 'policy-derived-workspace', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Derived Workspace Policy', @@ -27,12 +27,12 @@ $workspaceA = Workspace::factory()->create(); $workspaceB = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), ]); expect(fn () => Policy::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspaceB->getKey(), 'external_id' => 'policy-workspace-mismatch', 'policy_type' => 'settingsCatalogPolicy', @@ -41,32 +41,32 @@ ]))->toThrow(WorkspaceIsolationViolation::class); }); -it('rejects tenant_id changes after create', function (): void { +it('rejects managed_environment_id changes after create', function (): void { $workspaceA = Workspace::factory()->create(); $workspaceB = Workspace::factory()->create(); - $tenantA = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), ]); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceB->getKey(), ]); $policy = Policy::query()->create([ - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'external_id' => 'policy-tenant-immutable', 'policy_type' => 'settingsCatalogPolicy', - 'display_name' => 'Tenant Immutable Policy', + 'display_name' => 'ManagedEnvironment Immutable Policy', 'platform' => 'windows', ]); expect(fn () => $policy->update([ - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), ]))->toThrow(WorkspaceIsolationViolation::class); $policy->refresh(); - expect((int) $policy->tenant_id)->toBe((int) $tenantA->getKey()); + expect((int) $policy->managed_environment_id)->toBe((int) $tenantA->getKey()); expect((int) $policy->workspace_id)->toBe((int) $tenantA->workspace_id); }); diff --git a/apps/platform/tests/Feature/WorkspaceIsolation/TenantOwnedWorkspaceInvariantTest.php b/apps/platform/tests/Feature/WorkspaceIsolation/TenantOwnedWorkspaceInvariantTest.php index d8e2be37..3c13e120 100644 --- a/apps/platform/tests/Feature/WorkspaceIsolation/TenantOwnedWorkspaceInvariantTest.php +++ b/apps/platform/tests/Feature/WorkspaceIsolation/TenantOwnedWorkspaceInvariantTest.php @@ -11,7 +11,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantPermission; use App\Models\Workspace; use App\Support\WorkspaceIsolation\WorkspaceIsolationViolation; @@ -23,47 +23,47 @@ $workspaceA = Workspace::factory()->create(); $workspaceB = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspaceA->getKey(), ]); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceA->getKey(), ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceA->getKey(), ]); $cases = [ 'policies' => fn (int $workspaceId) => Policy::factory()->make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, ]), 'policy_versions' => fn (int $workspaceId) => PolicyVersion::factory()->make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, 'policy_id' => $policy->getKey(), ]), 'backup_sets' => fn (int $workspaceId) => BackupSet::factory()->make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, ]), 'backup_items' => fn (int $workspaceId) => BackupItem::factory()->make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, 'backup_set_id' => $backupSet->getKey(), 'policy_id' => $policy->getKey(), ]), 'restore_runs' => fn (int $workspaceId) => RestoreRun::factory()->make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, 'backup_set_id' => $backupSet->getKey(), ]), 'backup_schedules' => fn (int $workspaceId) => BackupSchedule::make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, 'name' => 'Weekly backup', 'is_enabled' => true, @@ -76,27 +76,27 @@ 'retention_keep_last' => 30, ]), 'inventory_items' => fn (int $workspaceId) => InventoryItem::factory()->make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, ]), 'inventory_links' => fn (int $workspaceId) => InventoryLink::factory()->make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, ]), 'entra_groups' => fn (int $workspaceId) => EntraGroup::factory()->make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, ]), 'findings' => fn (int $workspaceId) => Finding::factory()->make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, ]), 'entra_role_definitions' => fn (int $workspaceId) => EntraRoleDefinition::factory()->make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, ]), 'tenant_permissions' => fn (int $workspaceId) => TenantPermission::make([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceId, 'permission_key' => 'test.permission.'.uniqid(), 'status' => 'missing', @@ -111,7 +111,7 @@ }); $this->assertDatabaseHas($table, [ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspaceA->getKey(), ]); @@ -125,12 +125,12 @@ it('keeps RBAC foundation policy versions and backup items pinned to the tenant workspace', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), ]); $policy = Policy::query()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspace->getKey(), 'external_id' => 'role-def-1', 'policy_type' => 'intuneRoleDefinition', @@ -141,7 +141,7 @@ ]); $version = PolicyVersion::query()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspace->getKey(), 'policy_id' => $policy->getKey(), 'version_number' => 1, @@ -159,12 +159,12 @@ ]); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspace->getKey(), ]); $backupItem = BackupItem::query()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'workspace_id' => $workspace->getKey(), 'backup_set_id' => $backupSet->getKey(), 'policy_id' => $policy->getKey(), diff --git a/apps/platform/tests/Feature/Workspaces/ChooseTenantPageTest.php b/apps/platform/tests/Feature/Workspaces/ChooseTenantPageTest.php index b6ad454c..3c4ce4b1 100644 --- a/apps/platform/tests/Feature/Workspaces/ChooseTenantPageTest.php +++ b/apps/platform/tests/Feature/Workspaces/ChooseTenantPageTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -10,20 +10,20 @@ uses(RefreshDatabase::class); it('shows only active tenants and no-tenant helper copy on the choose-tenant page', function (): void { - $activeTenant = Tenant::factory()->active()->create(['name' => 'Choose Active Tenant']); + $activeTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Choose Active ManagedEnvironment']); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); - $otherActiveTenant = Tenant::factory()->active()->create([ + $otherActiveTenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Choose Other Active Tenant', + 'name' => 'Choose Other Active ManagedEnvironment', ]); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Choose Onboarding Tenant', + 'name' => 'Choose Onboarding ManagedEnvironment', ]); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Choose Archived Tenant', + 'name' => 'Choose Archived ManagedEnvironment', ]); createUserWithTenant(tenant: $otherActiveTenant, user: $user, role: 'owner'); @@ -36,16 +36,16 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $activeTenant->workspace_id]) ->get('/admin/choose-tenant') ->assertSuccessful() - ->assertSee('Choose Active Tenant') - ->assertSee('Choose Other Active Tenant') - ->assertDontSee('Choose Onboarding Tenant') - ->assertDontSee('Choose Archived Tenant') + ->assertSee('Choose Active ManagedEnvironment') + ->assertSee('Choose Other Active ManagedEnvironment') + ->assertDontSee('Choose Onboarding ManagedEnvironment') + ->assertDontSee('Choose Archived ManagedEnvironment') ->assertSee('Select the tenant for your normal active operating context.') ->assertSee('No tenant selected is still a valid workspace state'); }); it('shows a workspace-safe empty state when no selectable tenants remain', function (): void { - $onboardingTenant = Tenant::factory()->onboarding()->create(['name' => 'Only Onboarding Tenant']); + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create(['name' => 'Only Onboarding ManagedEnvironment']); [$user, $onboardingTenant] = createUserWithTenant( tenant: $onboardingTenant, role: 'owner', @@ -64,16 +64,16 @@ }); it('keeps selector eligibility narrower than managed-tenant administrative discoverability', function (): void { - $activeTenant = Tenant::factory()->active()->create(['name' => 'Selector Active Tenant']); + $activeTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Selector Active ManagedEnvironment']); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Selector Onboarding Tenant', + 'name' => 'Selector Onboarding ManagedEnvironment', ]); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, - 'name' => 'Selector Archived Tenant', + 'name' => 'Selector Archived ManagedEnvironment', ]); createUserWithTenant(tenant: $onboardingTenant, user: $user, role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); @@ -85,17 +85,17 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $activeTenant->workspace_id]) ->get('/admin/choose-tenant') ->assertSuccessful() - ->assertSee('Selector Active Tenant') - ->assertDontSee('Selector Onboarding Tenant') - ->assertDontSee('Selector Archived Tenant'); + ->assertSee('Selector Active ManagedEnvironment') + ->assertDontSee('Selector Onboarding ManagedEnvironment') + ->assertDontSee('Selector Archived ManagedEnvironment'); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $activeTenant->workspace_id]) ->get(route('admin.workspace.managed-tenants.index', ['workspace' => $activeTenant->workspace])) ->assertSuccessful() - ->assertSee('Selector Active Tenant') - ->assertSee('Selector Onboarding Tenant') - ->assertSee('Selector Archived Tenant'); + ->assertSee('Selector Active ManagedEnvironment') + ->assertSee('Selector Onboarding ManagedEnvironment') + ->assertSee('Selector Archived ManagedEnvironment'); }); it('redirects clear selected tenant from tenant-bound pages back to a workspace-safe managed-tenants page', function (): void { diff --git a/apps/platform/tests/Feature/Workspaces/ChooseWorkspacePageTest.php b/apps/platform/tests/Feature/Workspaces/ChooseWorkspacePageTest.php index fad51bcb..cd3f375d 100644 --- a/apps/platform/tests/Feature/Workspaces/ChooseWorkspacePageTest.php +++ b/apps/platform/tests/Feature/Workspaces/ChooseWorkspacePageTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\AuditLog; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -90,13 +90,13 @@ ]); // Create 2 active tenants. - Tenant::factory()->count(2)->create([ + ManagedEnvironment::factory()->count(2)->create([ 'workspace_id' => $workspace->getKey(), 'status' => 'active', ]); // Create 1 inactive tenant (should not count). - Tenant::factory()->create([ + ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), 'status' => 'pending_validation', ]); @@ -122,7 +122,7 @@ 'role' => 'owner', ]); - Tenant::factory()->create([ + ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), 'status' => 'active', ]); @@ -201,7 +201,7 @@ 'role' => 'owner', ]); - Tenant::factory()->count(2)->create([ + ManagedEnvironment::factory()->count(2)->create([ 'workspace_id' => $workspace->getKey(), 'status' => 'active', ]); diff --git a/apps/platform/tests/Feature/Workspaces/ChooseWorkspaceRedirectsToChooseTenantTest.php b/apps/platform/tests/Feature/Workspaces/ChooseWorkspaceRedirectsToChooseTenantTest.php index cec1b750..17838a93 100644 --- a/apps/platform/tests/Feature/Workspaces/ChooseWorkspaceRedirectsToChooseTenantTest.php +++ b/apps/platform/tests/Feature/Workspaces/ChooseWorkspaceRedirectsToChooseTenantTest.php @@ -4,8 +4,8 @@ use App\Filament\Pages\ChooseWorkspace; use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -42,13 +42,13 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => $workspace->getKey(), ]); - TenantMembership::query()->create([ - 'tenant_id' => $tenant->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', @@ -72,14 +72,14 @@ 'role' => 'owner', ]); - $tenants = Tenant::factory()->count(2)->create([ + $tenants = ManagedEnvironment::factory()->count(2)->create([ 'status' => 'active', 'workspace_id' => $workspace->getKey(), ]); foreach ($tenants as $tenant) { - TenantMembership::query()->create([ - 'tenant_id' => $tenant->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', diff --git a/apps/platform/tests/Feature/Workspaces/CreateWorkspaceCreatesMembershipTest.php b/apps/platform/tests/Feature/Workspaces/CreateWorkspaceCreatesMembershipTest.php index b20010a7..6c0ded01 100644 --- a/apps/platform/tests/Feature/Workspaces/CreateWorkspaceCreatesMembershipTest.php +++ b/apps/platform/tests/Feature/Workspaces/CreateWorkspaceCreatesMembershipTest.php @@ -3,8 +3,8 @@ declare(strict_types=1); use App\Filament\Resources\Workspaces\Pages\CreateWorkspace; -use App\Models\Tenant; -use App\Models\TenantMembership; +use App\Models\ManagedEnvironment; +use App\Models\ManagedEnvironmentMembership; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -27,12 +27,12 @@ app(WorkspaceContext::class)->setCurrentWorkspace($existingWorkspace, $user); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => $existingWorkspace->getKey(), 'status' => 'active', ]); - TenantMembership::query()->create([ - 'tenant_id' => $tenant->getKey(), + ManagedEnvironmentMembership::query()->create([ + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', 'source' => 'manual', diff --git a/apps/platform/tests/Feature/Workspaces/EnsureWorkspaceSelectedMiddlewareTest.php b/apps/platform/tests/Feature/Workspaces/EnsureWorkspaceSelectedMiddlewareTest.php index 4968a637..918e20fd 100644 --- a/apps/platform/tests/Feature/Workspaces/EnsureWorkspaceSelectedMiddlewareTest.php +++ b/apps/platform/tests/Feature/Workspaces/EnsureWorkspaceSelectedMiddlewareTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\AuditLog; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -93,10 +93,10 @@ 'role' => 'owner', ]); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => $workspace->getKey(), ]); - $archivedTenant = Tenant::factory()->archived()->create([ + $archivedTenant = ManagedEnvironment::factory()->archived()->create([ 'workspace_id' => $workspace->getKey(), ]); @@ -124,7 +124,7 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), 'status' => 'active', ]); diff --git a/apps/platform/tests/Feature/Workspaces/GlobalContextShellContractTest.php b/apps/platform/tests/Feature/Workspaces/GlobalContextShellContractTest.php index 5deb2125..ca6b84f2 100644 --- a/apps/platform/tests/Feature/Workspaces/GlobalContextShellContractTest.php +++ b/apps/platform/tests/Feature/Workspaces/GlobalContextShellContractTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -11,7 +11,7 @@ uses(RefreshDatabase::class); it('shows the routed workspace and tenant truth on tenant-panel entry without relying on session workspace state', function (): void { - $tenant = Tenant::factory()->active()->create(['name' => 'Tenant Panel Entry']); + $tenant = ManagedEnvironment::factory()->active()->create(['name' => 'ManagedEnvironment Panel Entry']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); session()->forget(WorkspaceContext::SESSION_KEY); @@ -20,7 +20,7 @@ ->get(TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant)) ->assertOk() ->assertSee($tenant->workspace()->firstOrFail()->name) - ->assertSee('Tenant Panel Entry') + ->assertSee('ManagedEnvironment Panel Entry') ->assertSee('Switch tenant') ->assertSee('Clear tenant scope') ->assertDontSee(__('localization.shell.search_tenants')) @@ -28,10 +28,10 @@ }); it('keeps workspace-scoped routes tenantless when a cross-workspace tenant hint is rejected', function (): void { - $workspaceTenant = Tenant::factory()->active()->create(['name' => 'Workspace Tenant']); + $workspaceTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Workspace ManagedEnvironment']); [$user, $workspaceTenant] = createUserWithTenant(tenant: $workspaceTenant, role: 'owner'); - $foreignTenant = Tenant::factory()->active()->create(['name' => 'Rejected Foreign Tenant']); + $foreignTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Rejected Foreign ManagedEnvironment']); createUserWithTenant(tenant: $foreignTenant, user: User::factory()->create(), role: 'owner'); $this->actingAs($user) @@ -39,5 +39,5 @@ ->get(route('admin.operations.index', ['tenant' => $foreignTenant->external_id])) ->assertOk() ->assertSee('No tenant selected') - ->assertDontSee('Tenant scope: Rejected Foreign Tenant'); + ->assertDontSee('ManagedEnvironment scope: Rejected Foreign ManagedEnvironment'); }); diff --git a/apps/platform/tests/Feature/Workspaces/ManagedTenantOnboardingProviderStartTest.php b/apps/platform/tests/Feature/Workspaces/ManagedTenantOnboardingProviderStartTest.php index 329d274b..44eb7d0c 100644 --- a/apps/platform/tests/Feature/Workspaces/ManagedTenantOnboardingProviderStartTest.php +++ b/apps/platform/tests/Feature/Workspaces/ManagedTenantOnboardingProviderStartTest.php @@ -6,7 +6,7 @@ use App\Jobs\ProviderInventorySyncJob; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\User; use App\Models\Workspace; @@ -44,17 +44,17 @@ 'notes' => 'Provider start test', ]); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->forTenant($tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'is_default' => true, ]); OperationRun::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory.sync', @@ -70,7 +70,7 @@ $component->call('startVerification'); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->count())->toBe(0); @@ -103,17 +103,17 @@ 'notes' => 'Provider start test', ]); - $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); + $tenant = ManagedEnvironment::query()->forTenant($tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'is_default' => true, ]); $verificationRun = OperationRun::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', @@ -127,7 +127,7 @@ $session = TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->firstOrFail(); $session->update([ @@ -140,13 +140,13 @@ $component->call('startBootstrap', ['inventory_sync', 'compliance.snapshot']); $inventoryRun = OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'inventory.sync') ->latest('id') ->firstOrFail(); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'compliance.snapshot') ->count())->toBe(0); @@ -158,7 +158,7 @@ $component->call('startBootstrap', ['inventory.sync', 'compliance.snapshot']); expect(OperationRun::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('type', 'compliance.snapshot') ->count())->toBe(1); diff --git a/apps/platform/tests/Feature/Workspaces/ManagedTenantsWorkspaceRoutingTest.php b/apps/platform/tests/Feature/Workspaces/ManagedTenantsWorkspaceRoutingTest.php index 1b3b43cb..55659c24 100644 --- a/apps/platform/tests/Feature/Workspaces/ManagedTenantsWorkspaceRoutingTest.php +++ b/apps/platform/tests/Feature/Workspaces/ManagedTenantsWorkspaceRoutingTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -51,11 +51,11 @@ 'role' => 'owner', ]); - $tenantInOther = Tenant::factory()->create([ + $tenantInOther = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $workspaceOther->getKey(), 'external_id' => 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', - 'tenant_id' => 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', + 'managed_environment_id' => 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', ]); $tenantInOther->makeCurrent(); @@ -81,10 +81,10 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'external_id' => '11111111-1111-1111-1111-111111111111', - 'tenant_id' => '11111111-1111-1111-1111-111111111111', + 'managed_environment_id' => '11111111-1111-1111-1111-111111111111', ]); $user->tenants()->syncWithoutDetaching([ @@ -114,10 +114,10 @@ 'role' => 'owner', ]); - $tenantInA = Tenant::factory()->create([ + $tenantInA = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), 'external_id' => 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', - 'tenant_id' => 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', + 'managed_environment_id' => 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', ]); $user->tenants()->syncWithoutDetaching([ diff --git a/apps/platform/tests/Feature/Workspaces/SelectTenantControllerTest.php b/apps/platform/tests/Feature/Workspaces/SelectTenantControllerTest.php index cf28c3e8..9c608cb4 100644 --- a/apps/platform/tests/Feature/Workspaces/SelectTenantControllerTest.php +++ b/apps/platform/tests/Feature/Workspaces/SelectTenantControllerTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -13,13 +13,13 @@ uses(RefreshDatabase::class); it('stores remembered context and redirects to the tenant dashboard for active tenants', function (): void { - $activeTenant = Tenant::factory()->active()->create(); + $activeTenant = ManagedEnvironment::factory()->active()->create(); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); $response = $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $activeTenant->workspace_id]) ->post(route('admin.select-tenant'), [ - 'tenant_id' => (int) $activeTenant->getKey(), + 'managed_environment_id' => (int) $activeTenant->getKey(), ]); $response->assertRedirect(TenantDashboard::getUrl(panel: 'tenant', tenant: $activeTenant)); @@ -29,10 +29,10 @@ }); it('returns 404 when selecting an onboarding tenant that is not eligible for the standard lane', function (): void { - $activeTenant = Tenant::factory()->active()->create(); + $activeTenant = ManagedEnvironment::factory()->active()->create(); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $activeTenant->workspace_id, ]); @@ -47,7 +47,7 @@ $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $activeTenant->workspace_id]) ->post(route('admin.select-tenant'), [ - 'tenant_id' => (int) $onboardingTenant->getKey(), + 'managed_environment_id' => (int) $onboardingTenant->getKey(), ]) ->assertNotFound(); @@ -73,7 +73,7 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->active()->create([ + $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspaceA->getKey(), ]); @@ -83,22 +83,22 @@ $this->actingAs($user) ->post(route('admin.select-tenant'), [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]) ->assertRedirect('/admin/choose-workspace'); }); it('returns 404 when selecting a tenant from another workspace', function (): void { - $activeTenant = Tenant::factory()->active()->create(['name' => 'Current Workspace Tenant']); + $activeTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Current Workspace ManagedEnvironment']); [$user, $activeTenant] = createUserWithTenant(tenant: $activeTenant, role: 'owner'); - $foreignTenant = Tenant::factory()->active()->create(['name' => 'Foreign Workspace Tenant']); + $foreignTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Foreign Workspace ManagedEnvironment']); createUserWithTenant(tenant: $foreignTenant, user: $user, role: 'owner'); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $activeTenant->workspace_id]) ->post(route('admin.select-tenant'), [ - 'tenant_id' => (int) $foreignTenant->getKey(), + 'managed_environment_id' => (int) $foreignTenant->getKey(), ]) ->assertNotFound(); @@ -116,14 +116,14 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->active()->create([ + $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]) ->post(route('admin.select-tenant'), [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]) ->assertNotFound(); }); diff --git a/apps/platform/tests/Feature/Workspaces/Spec195ManagedTenantsLandingTest.php b/apps/platform/tests/Feature/Workspaces/Spec195ManagedTenantsLandingTest.php index bd2acd11..f4b0ec53 100644 --- a/apps/platform/tests/Feature/Workspaces/Spec195ManagedTenantsLandingTest.php +++ b/apps/platform/tests/Feature/Workspaces/Spec195ManagedTenantsLandingTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\ChooseTenant; use App\Filament\Pages\Workspaces\ManagedTenantsLanding; use App\Filament\Resources\TenantResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -25,9 +25,9 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->active()->create([ + $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Spec195 Landing Tenant', + 'name' => 'Spec195 Landing ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -38,7 +38,7 @@ ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]) ->get(route('admin.workspace.managed-tenants.index', ['workspace' => $workspace])) ->assertSuccessful() - ->assertSee('Spec195 Landing Tenant') + ->assertSee('Spec195 Landing ManagedEnvironment') ->assertSee('Managed tenants') ->assertDontSee('No tenant selected'); }); @@ -53,9 +53,9 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->active()->create([ + $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Spec195 Routed Tenant', + 'name' => 'Spec195 Routed ManagedEnvironment', ]); $user->tenants()->syncWithoutDetaching([ @@ -91,9 +91,9 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->active()->create([ + $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Spec195 Guarded Tenant', + 'name' => 'Spec195 Guarded ManagedEnvironment', ]); $this->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]); diff --git a/apps/platform/tests/Feature/Workspaces/SwitchWorkspaceControllerTest.php b/apps/platform/tests/Feature/Workspaces/SwitchWorkspaceControllerTest.php index 3aaaaa3b..c97501e3 100644 --- a/apps/platform/tests/Feature/Workspaces/SwitchWorkspaceControllerTest.php +++ b/apps/platform/tests/Feature/Workspaces/SwitchWorkspaceControllerTest.php @@ -3,18 +3,18 @@ declare(strict_types=1); use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); it('ignores an intended tenant route that is not valid in the target workspace', function (): void { - $sourceTenant = Tenant::factory()->active()->create(['name' => 'Source Tenant']); + $sourceTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Source ManagedEnvironment']); [$user, $sourceTenant] = createUserWithTenant(tenant: $sourceTenant, role: 'owner'); - $targetWorkspaceTenant = Tenant::factory()->active()->create([ - 'name' => 'Target Tenant', + $targetWorkspaceTenant = ManagedEnvironment::factory()->active()->create([ + 'name' => 'Target ManagedEnvironment', ]); createUserWithTenant(tenant: $targetWorkspaceTenant, user: $user, role: 'owner'); diff --git a/apps/platform/tests/Feature/Workspaces/WorkspaceRedirectResolverTest.php b/apps/platform/tests/Feature/Workspaces/WorkspaceRedirectResolverTest.php index c0ed772c..f45ca399 100644 --- a/apps/platform/tests/Feature/Workspaces/WorkspaceRedirectResolverTest.php +++ b/apps/platform/tests/Feature/Workspaces/WorkspaceRedirectResolverTest.php @@ -5,7 +5,7 @@ use App\Filament\Pages\ChooseTenant; use App\Filament\Pages\ChooseWorkspace; use App\Filament\Pages\TenantDashboard; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -47,7 +47,7 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), 'status' => 'active', ]); @@ -73,12 +73,12 @@ 'role' => 'owner', ]); - $tenantA = Tenant::factory()->create([ + $tenantA = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), 'status' => 'active', ]); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), 'status' => 'active', ]); @@ -130,7 +130,7 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), 'status' => 'active', ]); @@ -156,7 +156,7 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => $workspace->getKey(), 'status' => 'active', ]); @@ -165,7 +165,7 @@ $tenant->getKey() => ['role' => 'owner'], ]); - $foreignTenant = Tenant::factory()->create([ + $foreignTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', ]); diff --git a/apps/platform/tests/Feature/Workspaces/WorkspacesResourceIsTenantlessTest.php b/apps/platform/tests/Feature/Workspaces/WorkspacesResourceIsTenantlessTest.php index afdc1356..18ebb200 100644 --- a/apps/platform/tests/Feature/Workspaces/WorkspacesResourceIsTenantlessTest.php +++ b/apps/platform/tests/Feature/Workspaces/WorkspacesResourceIsTenantlessTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -75,10 +75,10 @@ 'role' => 'owner', ]); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'external_id' => '11111111-1111-1111-1111-111111111111', - 'tenant_id' => '11111111-1111-1111-1111-111111111111', + 'managed_environment_id' => '11111111-1111-1111-1111-111111111111', ]); $user->tenants()->syncWithoutDetaching([ diff --git a/apps/platform/tests/Pest.php b/apps/platform/tests/Pest.php index 326e9b21..a1bf3eba 100644 --- a/apps/platform/tests/Pest.php +++ b/apps/platform/tests/Pest.php @@ -12,7 +12,7 @@ use App\Models\ProviderCredential; use App\Models\RestoreRun; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\TenantReview; use App\Models\User; @@ -123,6 +123,14 @@ beforeEach(function () { putenv('INTUNE_TENANT_ID'); unset($_ENV['INTUNE_TENANT_ID'], $_SERVER['INTUNE_TENANT_ID']); + + Filament::setCurrentPanel(null); + Filament::setTenant(null, true); +}); + +afterEach(function (): void { + Filament::setTenant(null, true); + Filament::setCurrentPanel(null); }); /* @@ -233,7 +241,7 @@ function mutateTrustedStatePayload(array $payload, array $overrides): array * @param array $data * @param list $errorKeys */ -function assertScopedSelectorRejected(mixed $component, string $action, array $data, array $errorKeys = ['tenant_id']): mixed +function assertScopedSelectorRejected(mixed $component, string $action, array $data, array $errorKeys = ['managed_environment_id']): mixed { return $component ->callAction($action, data: $data) @@ -285,7 +293,7 @@ function assertNoOutboundHttp(\Closure $callback): mixed /** * @param array $attributes */ -function createInventorySyncOperationRun(Tenant $tenant, array $attributes = []): \App\Models\OperationRun +function createInventorySyncOperationRun(ManagedEnvironment $tenant, array $attributes = []): \App\Models\OperationRun { $context = is_array($attributes['context'] ?? null) ? $attributes['context'] : []; @@ -370,7 +378,7 @@ function createInventorySyncOperationRun(Tenant $tenant, array $attributes = []) * @param array $attributes */ function createInventorySyncOperationRunWithCoverage( - Tenant $tenant, + ManagedEnvironment $tenant, array $statusByType, array $foundationTypes = [], array $attributes = [], @@ -523,10 +531,10 @@ function createUserWithTenantProfiles(): array } /** - * @return array{0: User, 1: Tenant} + * @return array{0: User, 1: ManagedEnvironment} */ function createMinimalUserWithTenant( - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?User $user = null, string $role = 'owner', ?string $workspaceRole = null, @@ -551,10 +559,10 @@ function createMinimalUserWithTenant( } /** - * @return array{0: User, 1: Tenant} + * @return array{0: User, 1: ManagedEnvironment} */ function createStandardUserWithTenant( - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?User $user = null, string $role = 'owner', ?string $workspaceRole = null, @@ -579,10 +587,10 @@ function createStandardUserWithTenant( } /** - * @return array{0: User, 1: Tenant} + * @return array{0: User, 1: ManagedEnvironment} */ function createFullUserWithTenant( - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?User $user = null, string $role = 'owner', ?string $workspaceRole = null, @@ -607,10 +615,10 @@ function createFullUserWithTenant( } /** - * @return array{0: User, 1: Tenant} + * @return array{0: User, 1: ManagedEnvironment} */ function createProviderEnabledUserWithTenant( - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?User $user = null, string $role = 'owner', ?string $workspaceRole = null, @@ -635,10 +643,10 @@ function createProviderEnabledUserWithTenant( } /** - * @return array{0: User, 1: Tenant} + * @return array{0: User, 1: ManagedEnvironment} */ function createCredentialEnabledUserWithTenant( - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?User $user = null, string $role = 'owner', ?string $workspaceRole = null, @@ -663,10 +671,10 @@ function createCredentialEnabledUserWithTenant( } /** - * @return array{0: User, 1: Tenant} + * @return array{0: User, 1: ManagedEnvironment} */ function createUiContextUserWithTenant( - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?User $user = null, string $role = 'owner', ?string $workspaceRole = null, @@ -691,10 +699,10 @@ function createUiContextUserWithTenant( } /** - * @return array{0: User, 1: Tenant} + * @return array{0: User, 1: ManagedEnvironment} */ function createHeavyUserWithTenant( - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?User $user = null, string $role = 'owner', ?string $workspaceRole = null, @@ -719,10 +727,10 @@ function createHeavyUserWithTenant( } /** - * @return array{0: User, 1: Tenant} + * @return array{0: User, 1: ManagedEnvironment} */ function createUserWithTenant( - ?Tenant $tenant = null, + ?ManagedEnvironment $tenant = null, ?User $user = null, string $role = 'owner', ?string $workspaceRole = null, @@ -736,7 +744,7 @@ function createUserWithTenant( $resolvedProfile = resolveCreateUserWithTenantProfile($fixtureProfile); $profile = $resolvedProfile['sideEffects']; $user ??= User::factory()->create(); - $tenant ??= Tenant::factory()->create(); + $tenant ??= ManagedEnvironment::factory()->create(); $workspaceRole ??= $role; @@ -813,7 +821,7 @@ function createUserWithTenant( /** * @return array{0: BaselineProfile, 1: BaselineSnapshot} */ -function seedActiveBaselineForTenant(Tenant $tenant): array +function seedActiveBaselineForTenant(ManagedEnvironment $tenant): array { $profile = BaselineProfile::factory()->active()->create([ 'workspace_id' => (int) $tenant->workspace_id, @@ -830,7 +838,7 @@ function seedActiveBaselineForTenant(Tenant $tenant): array BaselineTenantAssignment::query()->updateOrCreate([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ], [ 'baseline_profile_id' => (int) $profile->getKey(), 'override_scope_jsonb' => null, @@ -843,7 +851,7 @@ function seedActiveBaselineForTenant(Tenant $tenant): array * @param array $compareContext */ function seedBaselineCompareRun( - Tenant $tenant, + ManagedEnvironment $tenant, BaselineProfile $profile, BaselineSnapshot $snapshot, array $compareContext = [], @@ -854,7 +862,7 @@ function seedBaselineCompareRun( $completedAt ??= now(); return OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => $status, @@ -885,7 +893,7 @@ function workspaceOverviewCompareCoverage(): array ]; } -function workspaceOverviewSeedQuietTenantTruth(Tenant $tenant): void +function workspaceOverviewSeedQuietTenantTruth(ManagedEnvironment $tenant): void { [$profile, $snapshot] = seedActiveBaselineForTenant($tenant); @@ -897,7 +905,7 @@ function workspaceOverviewSeedQuietTenantTruth(Tenant $tenant): void * @param array $itemAttributes */ function workspaceOverviewSeedHealthyBackup( - Tenant $tenant, + ManagedEnvironment $tenant, array $backupSetAttributes = [], array $itemAttributes = [], ): BackupSet { @@ -925,7 +933,7 @@ function workspaceOverviewSeedHealthyBackup( * @param array $attributes */ function workspaceOverviewSeedRestoreHistory( - Tenant $tenant, + ManagedEnvironment $tenant, BackupSet $backupSet, string $state = 'completed', array $attributes = [], @@ -948,13 +956,13 @@ function workspaceOverviewSeedRestoreHistory( /** * @return array{tenant: string} */ -function filamentTenantRouteParams(Tenant $tenant): array +function filamentTenantRouteParams(ManagedEnvironment $tenant): array { return ['tenant' => (string) $tenant->external_id]; } function ensureDefaultProviderConnection( - Tenant $tenant, + ManagedEnvironment $tenant, string $provider = 'microsoft', string $connectionType = ProviderConnectionType::Dedicated->value, bool $ensureCredential = true, @@ -962,7 +970,7 @@ function ensureDefaultProviderConnection( $resolvedConnectionType = ProviderConnectionType::tryFrom($connectionType) ?? ProviderConnectionType::Dedicated; $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('provider', $provider) ->orderByDesc('is_default') ->orderBy('id') @@ -976,9 +984,9 @@ function ensureDefaultProviderConnection( } $connection = $connectionFactory->verifiedHealthy()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => $provider, - 'entra_tenant_id' => (string) ($tenant->tenant_id ?? fake()->uuid()), + 'entra_tenant_id' => (string) ($tenant->managed_environment_id ?? fake()->uuid()), 'connection_type' => $resolvedConnectionType->value, 'is_default' => true, ]); @@ -1017,7 +1025,7 @@ function ensureDefaultProviderConnection( } if ($entraTenantId === '') { - $updates['entra_tenant_id'] = (string) ($tenant->tenant_id ?? fake()->uuid()); + $updates['entra_tenant_id'] = (string) ($tenant->managed_environment_id ?? fake()->uuid()); } if (! array_key_exists('consent_granted_at', $updates)) { @@ -1087,7 +1095,7 @@ function ensureDefaultProviderConnection( * @param array $rolePayload */ function seedTenantReviewEvidence( - Tenant $tenant, + ManagedEnvironment $tenant, array $permissionPayload = [], array $rolePayload = [], int $findingCount = 3, @@ -1095,7 +1103,7 @@ function seedTenantReviewEvidence( int $operationRunCount = 1, ): EvidenceSnapshot { StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => array_replace_recursive([ 'posture_score' => 86, @@ -1108,7 +1116,7 @@ function seedTenantReviewEvidence( ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'payload' => array_replace_recursive([ 'roles' => [ @@ -1123,14 +1131,14 @@ function seedTenantReviewEvidence( Finding::factory() ->count($findingCount) ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); Finding::factory() ->count($driftCount) ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]); @@ -1145,7 +1153,7 @@ function seedTenantReviewEvidence( $payload = $service->buildSnapshotPayload($tenant); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'fingerprint' => $payload['fingerprint'], @@ -1156,7 +1164,7 @@ function seedTenantReviewEvidence( foreach ($payload['items'] as $item) { $snapshot->items()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => $item['dimension_key'], 'state' => $item['state'], @@ -1180,7 +1188,7 @@ function seedTenantReviewEvidence( * @param array $rolePayload */ function seedStaleTenantReviewEvidence( - Tenant $tenant, + ManagedEnvironment $tenant, array $permissionPayload = [], array $rolePayload = [], int $findingCount = 3, @@ -1212,7 +1220,7 @@ function seedStaleTenantReviewEvidence( * @param array $rolePayload */ function seedPartialTenantReviewEvidence( - Tenant $tenant, + ManagedEnvironment $tenant, array $permissionPayload = [], array $rolePayload = [], int $findingCount = 3, @@ -1239,7 +1247,7 @@ function seedPartialTenantReviewEvidence( ); } -function composeTenantReviewForTest(Tenant $tenant, User $user, ?EvidenceSnapshot $snapshot = null): TenantReview +function composeTenantReviewForTest(ManagedEnvironment $tenant, User $user, ?EvidenceSnapshot $snapshot = null): TenantReview { $snapshot ??= seedTenantReviewEvidence($tenant); @@ -1313,7 +1321,7 @@ function restateTenantReviewEvidenceSnapshot( return $snapshot->fresh('items'); } -function setTenantPanelContext(Tenant $tenant): void +function setTenantPanelContext(ManagedEnvironment $tenant): void { $tenant->makeCurrent(); Filament::setCurrentPanel('tenant'); @@ -1356,7 +1364,7 @@ function createOnboardingDraft(array $attributes = []): TenantOnboardingSession ->startedBy($startedBy) ->updatedBy($updatedBy); - if ($tenant instanceof Tenant) { + if ($tenant instanceof ManagedEnvironment) { $factory = $factory->forTenant($tenant); } @@ -1382,7 +1390,7 @@ function createOnboardingDraft(array $attributes = []): TenantOnboardingSession /** * @return list */ -function tenantActionCatalog(Tenant $tenant, TenantActionSurface $surface, ?User $user = null): array +function tenantActionCatalog(ManagedEnvironment $tenant, TenantActionSurface $surface, ?User $user = null): array { return app(TenantActionPolicySurface::class)->catalogForTenant($tenant, $surface, $user); } @@ -1399,12 +1407,12 @@ function tenantActionKeys(array $actions): array )); } -function ensureDefaultPlatformProviderConnection(Tenant $tenant, string $provider = 'microsoft'): ProviderConnection +function ensureDefaultPlatformProviderConnection(ManagedEnvironment $tenant, string $provider = 'microsoft'): ProviderConnection { return ensureDefaultProviderConnection($tenant, $provider, ProviderConnectionType::Platform->value); } -function ensureDefaultDedicatedProviderConnection(Tenant $tenant, string $provider = 'microsoft'): ProviderConnection +function ensureDefaultDedicatedProviderConnection(ManagedEnvironment $tenant, string $provider = 'microsoft'): ProviderConnection { return ensureDefaultProviderConnection($tenant, $provider, ProviderConnectionType::Dedicated->value); } diff --git a/apps/platform/tests/Unit/Alerts/AlertQuietHoursTest.php b/apps/platform/tests/Unit/Alerts/AlertQuietHoursTest.php index 869fc6f5..0d7b02b6 100644 --- a/apps/platform/tests/Unit/Alerts/AlertQuietHoursTest.php +++ b/apps/platform/tests/Unit/Alerts/AlertQuietHoursTest.php @@ -45,7 +45,7 @@ $dispatch->dispatchEvent($rule->workspace, [ 'event_type' => AlertRule::EVENT_HIGH_DRIFT, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => 'critical', 'fingerprint_key' => 'finding:quiet-1', 'title' => 'High drift detected', diff --git a/apps/platform/tests/Unit/Alerts/AlertRetryPolicyTest.php b/apps/platform/tests/Unit/Alerts/AlertRetryPolicyTest.php index 5a9d8636..499d1b50 100644 --- a/apps/platform/tests/Unit/Alerts/AlertRetryPolicyTest.php +++ b/apps/platform/tests/Unit/Alerts/AlertRetryPolicyTest.php @@ -29,7 +29,7 @@ $delivery = AlertDelivery::factory()->create([ 'workspace_id' => $workspaceId, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_QUEUED, diff --git a/apps/platform/tests/Unit/Alerts/AlertSuppressionTest.php b/apps/platform/tests/Unit/Alerts/AlertSuppressionTest.php index 3832b528..54387dbf 100644 --- a/apps/platform/tests/Unit/Alerts/AlertSuppressionTest.php +++ b/apps/platform/tests/Unit/Alerts/AlertSuppressionTest.php @@ -36,7 +36,7 @@ $event = [ 'event_type' => AlertRule::EVENT_HIGH_DRIFT, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'severity' => 'critical', 'fingerprint_key' => 'finding:123', 'title' => 'High drift detected', diff --git a/apps/platform/tests/Unit/AssignmentBackupServiceTest.php b/apps/platform/tests/Unit/AssignmentBackupServiceTest.php index 6c37ac0a..ca0cd5db 100644 --- a/apps/platform/tests/Unit/AssignmentBackupServiceTest.php +++ b/apps/platform/tests/Unit/AssignmentBackupServiceTest.php @@ -1,7 +1,7 @@ create([ - 'tenant_id' => 'tenant-123', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-123', 'external_id' => 'tenant-123', ]); ensureDefaultProviderConnection($tenant, 'microsoft'); $backupItem = BackupItem::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'metadata' => [], 'assignments' => null, ]); @@ -98,15 +98,15 @@ }); it('marks role definitions as not using standard policy assignments', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-123', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-123', 'external_id' => 'tenant-123', ]); ensureDefaultProviderConnection($tenant, 'microsoft'); $backupItem = BackupItem::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'metadata' => [ 'assignments_fetch_failed' => true, 'assignments_fetch_error' => 'old error', @@ -161,15 +161,15 @@ }); it('records orphaned assignment metadata when resolved groups are missing in the tenant', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-123', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-123', 'external_id' => 'tenant-123', ]); ensureDefaultProviderConnection($tenant, 'microsoft'); $backupItem = BackupItem::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'metadata' => [], 'assignments' => null, ]); @@ -209,7 +209,7 @@ $this->mock(AssignmentFilterResolver::class, function (MockInterface $mock) { $mock->shouldReceive('resolve') ->once() - ->with([], \Mockery::type(Tenant::class)) + ->with([], \Mockery::type(ManagedEnvironment::class)) ->andReturn([]); }); diff --git a/apps/platform/tests/Unit/AssignmentRestoreServiceTest.php b/apps/platform/tests/Unit/AssignmentRestoreServiceTest.php index 7f04b8ae..2d23dc05 100644 --- a/apps/platform/tests/Unit/AssignmentRestoreServiceTest.php +++ b/apps/platform/tests/Unit/AssignmentRestoreServiceTest.php @@ -1,6 +1,6 @@ create([ - 'tenant_id' => 'tenant-123', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-123', 'app_client_id' => null, 'app_client_secret' => null, ]); @@ -90,8 +90,8 @@ }); it('uses derived assign endpoints for app protection policies', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-123', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-123', 'app_client_id' => null, 'app_client_secret' => null, ]); @@ -135,8 +135,8 @@ }); it('maps assignment filter ids stored at the root of assignments', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-123', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-123', 'app_client_id' => null, 'app_client_secret' => null, ]); @@ -192,8 +192,8 @@ }); it('keeps assignment filters when mapping is missing but filter exists in target', function () { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-123', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-123', 'app_client_id' => null, 'app_client_secret' => null, ]); diff --git a/apps/platform/tests/Unit/Audit/AuditLogCompatibilityTest.php b/apps/platform/tests/Unit/Audit/AuditLogCompatibilityTest.php index 0c542226..bfb8a351 100644 --- a/apps/platform/tests/Unit/Audit/AuditLogCompatibilityTest.php +++ b/apps/platform/tests/Unit/Audit/AuditLogCompatibilityTest.php @@ -26,7 +26,7 @@ $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_email' => 'ops@example.com', 'action' => 'restore.failed', 'resource_type' => 'restore_run', @@ -50,7 +50,7 @@ $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'action' => 'backup.archived', 'resource_type' => 'backup_set', 'resource_id' => '999999', diff --git a/apps/platform/tests/Unit/Audit/AuditRecorderTest.php b/apps/platform/tests/Unit/Audit/AuditRecorderTest.php index 1779fbae..034acd13 100644 --- a/apps/platform/tests/Unit/Audit/AuditRecorderTest.php +++ b/apps/platform/tests/Unit/Audit/AuditRecorderTest.php @@ -16,7 +16,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'backup_create', @@ -42,7 +42,7 @@ )->refresh(); expect((int) $audit->workspace_id)->toBe((int) $tenant->workspace_id) - ->and((int) $audit->tenant_id)->toBe((int) $tenant->getKey()) + ->and((int) $audit->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($audit->actorSnapshot()->type)->toBe(AuditActorType::Human) ->and($audit->actorDisplayLabel())->toBe($user->name) ->and($audit->resource_type)->toBe('backup_set') diff --git a/apps/platform/tests/Unit/Auth/CapabilityResolverQueryCountTest.php b/apps/platform/tests/Unit/Auth/CapabilityResolverQueryCountTest.php index c05fdb7c..aac8b4b1 100644 --- a/apps/platform/tests/Unit/Auth/CapabilityResolverQueryCountTest.php +++ b/apps/platform/tests/Unit/Auth/CapabilityResolverQueryCountTest.php @@ -1,6 +1,6 @@ create(); +it('does not execute additional managed_environment_memberships queries after first resolve within a request', function () { + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->attach($tenant->getKey(), ['role' => TenantRole::Owner->value, 'source' => 'manual']); @@ -21,7 +21,7 @@ $membershipSelects = 0; DB::listen(function ($query) use (&$membershipSelects): void { - if (str_contains($query->sql, 'tenant_memberships')) { + if (str_contains($query->sql, 'managed_environment_memberships')) { $membershipSelects++; } }); diff --git a/apps/platform/tests/Unit/Auth/CapabilityResolverTest.php b/apps/platform/tests/Unit/Auth/CapabilityResolverTest.php index 0f229d44..4d5b7b9e 100644 --- a/apps/platform/tests/Unit/Auth/CapabilityResolverTest.php +++ b/apps/platform/tests/Unit/Auth/CapabilityResolverTest.php @@ -1,6 +1,6 @@ create(); + $tenant = ManagedEnvironment::factory()->create(); $owner = User::factory()->create(); $owner->tenants()->attach($tenant->getKey(), ['role' => TenantRole::Owner->value, 'source' => 'manual']); diff --git a/apps/platform/tests/Unit/Auth/UiEnforcementBulkPreflightQueryCountTest.php b/apps/platform/tests/Unit/Auth/UiEnforcementBulkPreflightQueryCountTest.php index 362b220c..ec261c0d 100644 --- a/apps/platform/tests/Unit/Auth/UiEnforcementBulkPreflightQueryCountTest.php +++ b/apps/platform/tests/Unit/Auth/UiEnforcementBulkPreflightQueryCountTest.php @@ -1,6 +1,6 @@ count(25)->create(); +it('preflights bulk selections with a set-based managed_environment_memberships query (no N+1)', function () { + $tenants = ManagedEnvironment::factory()->count(25)->create(); [$user] = createUserWithTenant($tenants->first(), role: 'owner'); foreach ($tenants->slice(1) as $tenant) { @@ -27,7 +27,7 @@ $membershipQueries = 0; DB::listen(function ($query) use (&$membershipQueries): void { - if (str_contains($query->sql, 'tenant_memberships')) { + if (str_contains($query->sql, 'managed_environment_memberships')) { $membershipQueries++; } }); diff --git a/apps/platform/tests/Unit/Auth/UiEnforcementTest.php b/apps/platform/tests/Unit/Auth/UiEnforcementTest.php index 4e8c1fba..00ae5afe 100644 --- a/apps/platform/tests/Unit/Auth/UiEnforcementTest.php +++ b/apps/platform/tests/Unit/Auth/UiEnforcementTest.php @@ -1,6 +1,6 @@ create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant(); $action = Action::make('test')->action(fn () => null); @@ -26,7 +26,7 @@ }); it('disables actions with the standard tooltip for members without the capability', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'readonly'); $action = Action::make('test')->action(fn () => null); @@ -44,7 +44,7 @@ }); it('enables actions for members with the capability', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'owner'); $action = Action::make('test')->action(fn () => null); @@ -62,7 +62,7 @@ }); it('preserveVisibility combines existing visibility with membership checks', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenant, role: 'owner'); $action = Action::make('test') @@ -81,8 +81,8 @@ }); it('disables bulk actions for mixed-authorization selections (capability preflight)', function () { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); [$user] = createUserWithTenant($tenantA, role: 'owner'); $user->tenants()->syncWithoutDetaching([ diff --git a/apps/platform/tests/Unit/Auth/UnknownCapabilityGuardTest.php b/apps/platform/tests/Unit/Auth/UnknownCapabilityGuardTest.php index 544b449b..4aa40e0b 100644 --- a/apps/platform/tests/Unit/Auth/UnknownCapabilityGuardTest.php +++ b/apps/platform/tests/Unit/Auth/UnknownCapabilityGuardTest.php @@ -1,6 +1,6 @@ create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->attach($tenant->getKey(), ['role' => TenantRole::Owner->value, 'source' => 'manual']); diff --git a/apps/platform/tests/Unit/Badges/GovernanceArtifactTruthTest.php b/apps/platform/tests/Unit/Badges/GovernanceArtifactTruthTest.php index 021a89b7..ab52aab2 100644 --- a/apps/platform/tests/Unit/Badges/GovernanceArtifactTruthTest.php +++ b/apps/platform/tests/Unit/Badges/GovernanceArtifactTruthTest.php @@ -4,7 +4,7 @@ use App\Models\BaselineProfile; use App\Models\BaselineSnapshot; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Badges\BadgeCatalog; use App\Support\Badges\BadgeDomain; @@ -36,7 +36,7 @@ ]); it('separates review existence from publication readiness', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = $this->makeArtifactTruthEvidenceSnapshot($tenant); $review = $this->makeArtifactTruthReview( @@ -61,7 +61,7 @@ }); it('marks ready review packs as publishable only when their source review stays publishable', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = $this->makeArtifactTruthEvidenceSnapshot($tenant); $review = $this->makeArtifactTruthReview($tenant, $user, $snapshot); @@ -115,7 +115,7 @@ }); it('maps shared operator explanations onto blocked tenant-review and incomplete baseline-snapshot truth envelopes', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = $this->makeArtifactTruthEvidenceSnapshot($tenant); $review = $this->makeArtifactTruthReview( diff --git a/apps/platform/tests/Unit/Baselines/BaselinePolicyVersionResolverTest.php b/apps/platform/tests/Unit/Baselines/BaselinePolicyVersionResolverTest.php index ed6644e3..0a3a9b83 100644 --- a/apps/platform/tests/Unit/Baselines/BaselinePolicyVersionResolverTest.php +++ b/apps/platform/tests/Unit/Baselines/BaselinePolicyVersionResolverTest.php @@ -2,7 +2,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Baselines\Evidence\BaselinePolicyVersionResolver; use App\Support\Baselines\BaselineSubjectKey; use Carbon\CarbonImmutable; @@ -15,7 +15,7 @@ }); test('resolves baseline policy version id within observed second', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $displayName = 'Policy Alpha'; $subjectKey = BaselineSubjectKey::fromDisplayName($displayName); @@ -23,7 +23,7 @@ expect($subjectKey)->not->toBeNull(); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'settingsCatalogPolicy', 'display_name' => $displayName, ]); @@ -31,7 +31,7 @@ $capturedAt = CarbonImmutable::parse('2026-03-05 12:00:00.123456'); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'version_number' => 1, @@ -49,10 +49,10 @@ }); test('returns null when no policy matches subject key', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Some Other Policy', ]); @@ -68,10 +68,10 @@ }); test('returns null when observed_at is invalid', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Policy Alpha', ]); @@ -91,7 +91,7 @@ }); test('uses a deterministic tie-breaker when multiple candidates exist', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $displayName = 'Policy Alpha'; $subjectKey = BaselineSubjectKey::fromDisplayName($displayName); @@ -99,13 +99,13 @@ expect($subjectKey)->not->toBeNull(); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'settingsCatalogPolicy', 'display_name' => $displayName, ]); $versionEarly = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'version_number' => 1, @@ -113,7 +113,7 @@ ]); $versionLate = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'version_number' => 2, @@ -133,10 +133,10 @@ }); test('resolves intune role definition versions by external-id identity', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'intuneRoleDefinition', 'external_id' => 'role-def-42', 'display_name' => 'Security Reader', @@ -145,7 +145,7 @@ $capturedAt = CarbonImmutable::parse('2026-03-08 12:00:00.123456'); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => (string) $policy->policy_type, 'version_number' => 1, diff --git a/apps/platform/tests/Unit/Baselines/CompareStrategyRegistryTest.php b/apps/platform/tests/Unit/Baselines/CompareStrategyRegistryTest.php index 72c048e3..04c52741 100644 --- a/apps/platform/tests/Unit/Baselines/CompareStrategyRegistryTest.php +++ b/apps/platform/tests/Unit/Baselines/CompareStrategyRegistryTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Baselines\BaselineScope; use App\Support\Baselines\Compare\CompareOrchestrationContext; use App\Support\Baselines\Compare\CompareStrategy; @@ -202,7 +202,7 @@ public function capabilities(): array public function compare( CompareOrchestrationContext $context, - Tenant $tenant, + ManagedEnvironment $tenant, array $baselineItems, array $currentItems, array $resolvedCurrentEvidence, diff --git a/apps/platform/tests/Unit/BulkActionPermissionTest.php b/apps/platform/tests/Unit/BulkActionPermissionTest.php index f020b6b3..bab925f9 100644 --- a/apps/platform/tests/Unit/BulkActionPermissionTest.php +++ b/apps/platform/tests/Unit/BulkActionPermissionTest.php @@ -2,7 +2,7 @@ use App\Filament\Resources\PolicyResource; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use Filament\Facades\Filament; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -10,14 +10,14 @@ uses(RefreshDatabase::class); test('policies bulk actions are available for authenticated users', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenant->getKey() => ['role' => 'owner'], ]); Filament::setTenant($tenant, true); - $policies = Policy::factory()->count(2)->create(['tenant_id' => $tenant->id]); + $policies = Policy::factory()->count(2)->create(['managed_environment_id' => $tenant->id]); Livewire::actingAs($user) ->test(PolicyResource\Pages\ListPolicies::class) diff --git a/apps/platform/tests/Unit/BulkBackupSetDeleteJobTest.php b/apps/platform/tests/Unit/BulkBackupSetDeleteJobTest.php index fc65583e..2fd84f6b 100644 --- a/apps/platform/tests/Unit/BulkBackupSetDeleteJobTest.php +++ b/apps/platform/tests/Unit/BulkBackupSetDeleteJobTest.php @@ -5,7 +5,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Services\Operations\TargetScopeConcurrencyLimiter; @@ -13,11 +13,11 @@ uses(RefreshDatabase::class); test('bulk backup set delete job archives sets and cascades to backup items', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $set = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 2, @@ -25,7 +25,7 @@ $items = collect(range(1, 2))->map(function (int $i) use ($tenant, $set) { return BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $set->id, 'policy_id' => null, 'policy_identifier' => 'policy-'.$i, @@ -37,7 +37,7 @@ }); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'backup_set.delete', @@ -68,18 +68,18 @@ }); test('bulk backup set delete job archives sets even when referenced by restore runs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $set = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $set->id, 'status' => 'completed', 'is_dry_run' => true, @@ -87,7 +87,7 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'backup_set.delete', diff --git a/apps/platform/tests/Unit/BulkBackupSetForceDeleteJobTest.php b/apps/platform/tests/Unit/BulkBackupSetForceDeleteJobTest.php index 6304b22a..fca28a0e 100644 --- a/apps/platform/tests/Unit/BulkBackupSetForceDeleteJobTest.php +++ b/apps/platform/tests/Unit/BulkBackupSetForceDeleteJobTest.php @@ -5,7 +5,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Services\Operations\TargetScopeConcurrencyLimiter; @@ -13,18 +13,18 @@ uses(RefreshDatabase::class); test('bulk backup set force delete job permanently deletes archived sets and their items', function () { - $tenant = Tenant::factory()->create(['is_current' => true]); + $tenant = ManagedEnvironment::factory()->create(['is_current' => true]); $user = User::factory()->create(); $set = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $item = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $set->id, 'policy_id' => null, 'policy_identifier' => 'policy-1', @@ -37,7 +37,7 @@ $set->delete(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'backup_set.force_delete', @@ -68,11 +68,11 @@ }); test('bulk backup set force delete job skips sets referenced by restore runs', function () { - $tenant = Tenant::factory()->create(['is_current' => true]); + $tenant = ManagedEnvironment::factory()->create(['is_current' => true]); $user = User::factory()->create(); $set = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, @@ -81,7 +81,7 @@ $set->delete(); RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $set->id, 'status' => 'completed', 'is_dry_run' => true, @@ -89,7 +89,7 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'backup_set.force_delete', diff --git a/apps/platform/tests/Unit/BulkBackupSetRestoreJobTest.php b/apps/platform/tests/Unit/BulkBackupSetRestoreJobTest.php index 8507e0ac..029e06c3 100644 --- a/apps/platform/tests/Unit/BulkBackupSetRestoreJobTest.php +++ b/apps/platform/tests/Unit/BulkBackupSetRestoreJobTest.php @@ -5,7 +5,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Services\Operations\TargetScopeConcurrencyLimiter; @@ -17,25 +17,25 @@ test('bulk backup set restore job initializes deduplicated totals only once across launcher replays', function () { Queue::fake(); - $tenant = Tenant::factory()->create(['is_current' => true]); + $tenant = ManagedEnvironment::factory()->create(['is_current' => true]); $user = User::factory()->create(); $firstSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'First backup', 'status' => 'completed', 'item_count' => 0, ]); $secondSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Second backup', 'status' => 'completed', 'item_count' => 0, ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'backup_set.restore', @@ -80,18 +80,18 @@ }); test('bulk backup set restore job restores archived sets and their items', function () { - $tenant = Tenant::factory()->create(['is_current' => true]); + $tenant = ManagedEnvironment::factory()->create(['is_current' => true]); $user = User::factory()->create(); $set = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $item = BackupItem::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $set->id, 'policy_id' => null, 'policy_identifier' => 'policy-1', @@ -108,7 +108,7 @@ expect(BackupItem::withTrashed()->find($item->id)?->trashed())->toBeTrue(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'backup_set.restore', @@ -141,18 +141,18 @@ }); test('bulk backup set restore job skips active sets', function () { - $tenant = Tenant::factory()->create(['is_current' => true]); + $tenant = ManagedEnvironment::factory()->create(['is_current' => true]); $user = User::factory()->create(); $set = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'backup_set.restore', diff --git a/apps/platform/tests/Unit/BulkOperationAbortMethodTest.php b/apps/platform/tests/Unit/BulkOperationAbortMethodTest.php index a5ad24a0..6936e598 100644 --- a/apps/platform/tests/Unit/BulkOperationAbortMethodTest.php +++ b/apps/platform/tests/Unit/BulkOperationAbortMethodTest.php @@ -1,18 +1,18 @@ create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'policy.delete', diff --git a/apps/platform/tests/Unit/BulkPolicyDeleteJobTest.php b/apps/platform/tests/Unit/BulkPolicyDeleteJobTest.php index 47f13100..d202621c 100644 --- a/apps/platform/tests/Unit/BulkPolicyDeleteJobTest.php +++ b/apps/platform/tests/Unit/BulkPolicyDeleteJobTest.php @@ -4,7 +4,7 @@ use App\Jobs\Operations\PolicyBulkDeleteWorkerJob; use App\Models\OperationRun; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -12,16 +12,16 @@ uses(RefreshDatabase::class); test('job processes bulk delete successfully', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); - $policies = Policy::factory()->count(3)->create(['tenant_id' => $tenant->id]); + $policies = Policy::factory()->count(3)->create(['managed_environment_id' => $tenant->id]); $policyIds = $policies->pluck('id')->toArray(); Bus::fake(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'policy.delete', @@ -55,10 +55,10 @@ }); test('job dispatches workers for all normalized IDs (including missing)', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); - $policies = Policy::factory()->count(2)->create(['tenant_id' => $tenant->id]); + $policies = Policy::factory()->count(2)->create(['managed_environment_id' => $tenant->id]); $policyIds = $policies->pluck('id')->toArray(); $policyIds[] = 99999; @@ -66,7 +66,7 @@ Bus::fake(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'policy.delete', diff --git a/apps/platform/tests/Unit/BulkPolicyExportJobTest.php b/apps/platform/tests/Unit/BulkPolicyExportJobTest.php index 1a281849..f4a98fa1 100644 --- a/apps/platform/tests/Unit/BulkPolicyExportJobTest.php +++ b/apps/platform/tests/Unit/BulkPolicyExportJobTest.php @@ -6,22 +6,22 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('job processes bulk export successfully', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); - $policies = Policy::factory()->count(3)->create(['tenant_id' => $tenant->id]); + $policies = Policy::factory()->count(3)->create(['managed_environment_id' => $tenant->id]); // Create versions for policies so they can be backed up $policies->each(function ($policy) use ($tenant) { PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'policy_type' => $policy->policy_type, 'version_number' => 1, @@ -33,7 +33,7 @@ $policyIds = $policies->pluck('id')->toArray(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'policy.export', @@ -62,19 +62,19 @@ // Verify BackupSet created $backupSet = BackupSet::where('name', 'My Bulk Backup')->first(); expect($backupSet)->not->toBeNull() - ->and($backupSet->tenant_id)->toBe($tenant->id); + ->and($backupSet->managed_environment_id)->toBe($tenant->id); // Verify BackupItems created expect(BackupItem::where('backup_set_id', $backupSet->id)->count())->toBe(3); }); test('job handles policies without versions gracefully', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); - $policyWithVersion = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policyWithVersion = Policy::factory()->create(['managed_environment_id' => $tenant->id]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policyWithVersion->id, 'policy_type' => $policyWithVersion->policy_type, 'version_number' => 1, @@ -82,12 +82,12 @@ 'captured_at' => now(), ]); - $policyNoVersion = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policyNoVersion = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $policyIds = [$policyWithVersion->id, $policyNoVersion->id]; $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'user_id' => $user->getKey(), 'initiator_name' => $user->name, 'type' => 'policy.export', diff --git a/apps/platform/tests/Unit/BulkPolicyVersionForceDeleteJobTest.php b/apps/platform/tests/Unit/BulkPolicyVersionForceDeleteJobTest.php index 04674da4..ae6ba914 100644 --- a/apps/platform/tests/Unit/BulkPolicyVersionForceDeleteJobTest.php +++ b/apps/platform/tests/Unit/BulkPolicyVersionForceDeleteJobTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Services\Operations\TargetScopeConcurrencyLimiter; @@ -13,13 +13,13 @@ uses(RefreshDatabase::class); test('worker force deletes archived versions and skips active versions', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $archived = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), @@ -27,14 +27,14 @@ $archived->delete(); $active = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 2, 'captured_at' => now()->subDays(10), ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'policy_version.force_delete', 'status' => 'running', @@ -78,11 +78,11 @@ }); test('worker records failure when policy version is missing', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'policy_version.force_delete', 'status' => 'running', diff --git a/apps/platform/tests/Unit/BulkPolicyVersionPruneJobTest.php b/apps/platform/tests/Unit/BulkPolicyVersionPruneJobTest.php index 3d44c3b9..b68506a3 100644 --- a/apps/platform/tests/Unit/BulkPolicyVersionPruneJobTest.php +++ b/apps/platform/tests/Unit/BulkPolicyVersionPruneJobTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Services\Operations\TargetScopeConcurrencyLimiter; @@ -12,39 +12,39 @@ uses(RefreshDatabase::class); test('worker prunes eligible versions and skips ineligible versions', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); - $policyA = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policyA = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $eligible = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policyA->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), ]); $current = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policyA->id, 'version_number' => 2, 'captured_at' => now()->subDays(120), ]); - $policyB = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policyB = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $tooRecent = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policyB->id, 'version_number' => 1, 'captured_at' => now()->subDays(10), ]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policyB->id, 'version_number' => 2, 'captured_at' => now()->subDays(10), ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'policy_version.prune', 'status' => 'running', @@ -98,11 +98,11 @@ }); test('worker records failure when version is missing', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'policy_version.prune', 'status' => 'running', @@ -136,12 +136,12 @@ }); test('worker skips already archived versions', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $archived = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), @@ -149,7 +149,7 @@ $archived->delete(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'policy_version.prune', 'status' => 'running', diff --git a/apps/platform/tests/Unit/BulkPolicyVersionRestoreJobTest.php b/apps/platform/tests/Unit/BulkPolicyVersionRestoreJobTest.php index 78c2b84b..e34eda64 100644 --- a/apps/platform/tests/Unit/BulkPolicyVersionRestoreJobTest.php +++ b/apps/platform/tests/Unit/BulkPolicyVersionRestoreJobTest.php @@ -4,19 +4,19 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('bulk policy version restore restores archived versions', function () { - $tenant = Tenant::factory()->create(['is_current' => true]); + $tenant = ManagedEnvironment::factory()->create(['is_current' => true]); $user = User::factory()->create(); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), @@ -26,7 +26,7 @@ expect($version->trashed())->toBeTrue(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'policy_version.restore', 'status' => 'queued', @@ -59,19 +59,19 @@ }); test('bulk policy version restore skips active versions', function () { - $tenant = Tenant::factory()->create(['is_current' => true]); + $tenant = ManagedEnvironment::factory()->create(['is_current' => true]); $user = User::factory()->create(); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'policy_version.restore', 'status' => 'queued', diff --git a/apps/platform/tests/Unit/BulkRestoreRunDeleteJobTest.php b/apps/platform/tests/Unit/BulkRestoreRunDeleteJobTest.php index 7ef9f0e4..9ed02f88 100644 --- a/apps/platform/tests/Unit/BulkRestoreRunDeleteJobTest.php +++ b/apps/platform/tests/Unit/BulkRestoreRunDeleteJobTest.php @@ -5,7 +5,7 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use App\Services\Operations\TargetScopeConcurrencyLimiter; @@ -14,13 +14,13 @@ uses(RefreshDatabase::class); test('bulk restore run delete enqueues worker jobs and sets total count', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); Bus::fake(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'restore_run.delete', 'status' => 'queued', @@ -33,14 +33,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $completed = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, @@ -48,7 +48,7 @@ ]); $failed = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'failed', 'is_dry_run' => true, @@ -71,11 +71,11 @@ }); test('worker soft deletes deletable restore runs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'restore_run.delete', 'status' => 'running', @@ -88,14 +88,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $completed = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, @@ -103,7 +103,7 @@ ]); $failed = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'failed', 'is_dry_run' => true, @@ -140,11 +140,11 @@ }); test('worker skips non-deletable restore runs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'restore_run.delete', 'status' => 'running', @@ -157,14 +157,14 @@ ]); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $running = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'running', 'is_dry_run' => true, diff --git a/apps/platform/tests/Unit/BulkRestoreRunRestoreJobTest.php b/apps/platform/tests/Unit/BulkRestoreRunRestoreJobTest.php index a13a4e7a..45a3c6b9 100644 --- a/apps/platform/tests/Unit/BulkRestoreRunRestoreJobTest.php +++ b/apps/platform/tests/Unit/BulkRestoreRunRestoreJobTest.php @@ -4,25 +4,25 @@ use App\Models\BackupSet; use App\Models\OperationRun; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('bulk restore run restore restores archived runs', function () { - $tenant = Tenant::factory()->create(['is_current' => true]); + $tenant = ManagedEnvironment::factory()->create(['is_current' => true]); $user = User::factory()->create(); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, @@ -33,7 +33,7 @@ expect($restoreRun->trashed())->toBeTrue(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'restore_run.restore', 'status' => 'queued', @@ -66,18 +66,18 @@ }); test('bulk restore run restore skips active runs', function () { - $tenant = Tenant::factory()->create(['is_current' => true]); + $tenant = ManagedEnvironment::factory()->create(['is_current' => true]); $user = User::factory()->create(); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $restoreRun = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, @@ -85,7 +85,7 @@ ]); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'user_id' => $user->id, 'type' => 'restore_run.restore', 'status' => 'queued', diff --git a/apps/platform/tests/Unit/CircuitBreakerTest.php b/apps/platform/tests/Unit/CircuitBreakerTest.php index e59cd2a5..6c3f92a0 100644 --- a/apps/platform/tests/Unit/CircuitBreakerTest.php +++ b/apps/platform/tests/Unit/CircuitBreakerTest.php @@ -4,20 +4,20 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Services\OperationRunService; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('bulk export aborts when more than half of items fail', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); // 4 items total -> failure threshold is floor(4/2)=2, so 3 failures triggers circuit breaker. - $okPolicy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $okPolicy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); PolicyVersion::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $okPolicy->id, 'policy_type' => $okPolicy->policy_type, 'version_number' => 1, @@ -25,9 +25,9 @@ 'captured_at' => now(), ]); - $failA = Policy::factory()->create(['tenant_id' => $tenant->id]); - $failB = Policy::factory()->create(['tenant_id' => $tenant->id]); - $failC = Policy::factory()->create(['tenant_id' => $tenant->id]); + $failA = Policy::factory()->create(['managed_environment_id' => $tenant->id]); + $failB = Policy::factory()->create(['managed_environment_id' => $tenant->id]); + $failC = Policy::factory()->create(['managed_environment_id' => $tenant->id]); /** @var OperationRunService $service */ $service = app(OperationRunService::class); @@ -58,7 +58,7 @@ expect($opRun->failure_summary)->not->toBeEmpty(); $this->assertDatabaseHas('backup_sets', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Circuit Breaker Backup', 'status' => 'failed', ]); diff --git a/apps/platform/tests/Unit/DependencyExtractionServiceTest.php b/apps/platform/tests/Unit/DependencyExtractionServiceTest.php index fc9173ec..31444f48 100644 --- a/apps/platform/tests/Unit/DependencyExtractionServiceTest.php +++ b/apps/platform/tests/Unit/DependencyExtractionServiceTest.php @@ -2,7 +2,7 @@ use App\Models\InventoryItem; use App\Models\InventoryLink; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Inventory\DependencyExtractionService; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Log; @@ -11,11 +11,11 @@ uses(RefreshDatabase::class); it('extracts deterministically and enforces unique key', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); @@ -36,7 +36,7 @@ expect($warnings1)->toBeArray()->toBeEmpty(); expect($warnings2)->toBeArray()->toBeEmpty(); - $edges = InventoryLink::query()->where('tenant_id', $tenant->getKey())->get(); + $edges = InventoryLink::query()->where('managed_environment_id', $tenant->getKey())->get(); expect($edges)->toHaveCount(4); // Ensure uniqueness by tuple (source, target, type) @@ -48,11 +48,11 @@ }); it('handles unsupported references by recording warnings (no edges)', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); @@ -82,10 +82,10 @@ }); it('deduplicates edges before upsert to avoid conflict errors', function () { - $tenant = \App\Models\Tenant::factory()->create(); + $tenant = \App\Models\ManagedEnvironment::factory()->create(); $item = \App\Models\InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_type' => 'settingsCatalogPolicy', 'external_id' => 'pol-dup-1', ]); @@ -105,7 +105,7 @@ expect($warnings)->toBeArray()->toBeEmpty(); $edges = \App\Models\InventoryLink::query() - ->where('tenant_id', $tenant->getKey()) + ->where('managed_environment_id', $tenant->getKey()) ->where('source_id', 'pol-dup-1') ->get(); diff --git a/apps/platform/tests/Unit/DependencyTargetResolverTest.php b/apps/platform/tests/Unit/DependencyTargetResolverTest.php index 154b8ed5..22f046ac 100644 --- a/apps/platform/tests/Unit/DependencyTargetResolverTest.php +++ b/apps/platform/tests/Unit/DependencyTargetResolverTest.php @@ -16,28 +16,28 @@ /** @var InventoryItem $item */ $item = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'external_id' => (string) Str::uuid(), ]); $scopeTag = InventoryItem::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'policy_type' => 'roleScopeTag', 'external_id' => '6', 'display_name' => 'Finance', ]); // Same external_id exists in another tenant; must never resolve across tenants. - $otherTenant = \App\Models\Tenant::factory()->create(); + $otherTenant = \App\Models\ManagedEnvironment::factory()->create(); InventoryItem::factory()->create([ - 'tenant_id' => $otherTenant->getKey(), + 'managed_environment_id' => $otherTenant->getKey(), 'policy_type' => 'roleScopeTag', 'external_id' => '6', 'display_name' => 'Other Finance', ]); $edge = InventoryLink::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => $item->external_id, 'target_type' => 'foundation_object', diff --git a/apps/platform/tests/Unit/DirectoryGroups/EntraGroupLabelResolverTest.php b/apps/platform/tests/Unit/DirectoryGroups/EntraGroupLabelResolverTest.php index 189f9eb4..1e177f34 100644 --- a/apps/platform/tests/Unit/DirectoryGroups/EntraGroupLabelResolverTest.php +++ b/apps/platform/tests/Unit/DirectoryGroups/EntraGroupLabelResolverTest.php @@ -1,7 +1,7 @@ create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); $entraId = '11111111-2222-3333-4444-555555555555'; EntraGroup::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'entra_id' => $entraId, 'display_name' => 'Alpha Team', ]); EntraGroup::factory()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'entra_id' => $entraId, 'display_name' => 'Beta Team', ]); @@ -41,7 +41,7 @@ }); it('returns a fallback without querying invalid UUIDs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $resolver = app(EntraGroupLabelResolver::class); diff --git a/apps/platform/tests/Unit/Entitlements/WorkspaceCommercialLifecycleResolverTest.php b/apps/platform/tests/Unit/Entitlements/WorkspaceCommercialLifecycleResolverTest.php index a281d1d8..f7d88e29 100644 --- a/apps/platform/tests/Unit/Entitlements/WorkspaceCommercialLifecycleResolverTest.php +++ b/apps/platform/tests/Unit/Entitlements/WorkspaceCommercialLifecycleResolverTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\PlatformUser; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -163,9 +163,9 @@ function setCommercialLifecycleState(Workspace $workspace, string $state, string [$workspace, $manager] = commercialLifecycleWorkspaceManager(); setCommercialLifecycleState($workspace, WorkspaceCommercialLifecycleResolver::STATE_GRACE, 'Grace should not bypass substrate'); - Tenant::factory()->create([ + ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ACTIVE, + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); app(SettingsWriter::class)->updateWorkspaceSetting( diff --git a/apps/platform/tests/Unit/Entitlements/WorkspaceEntitlementResolverTest.php b/apps/platform/tests/Unit/Entitlements/WorkspaceEntitlementResolverTest.php index 6fdd46be..711b210b 100644 --- a/apps/platform/tests/Unit/Entitlements/WorkspaceEntitlementResolverTest.php +++ b/apps/platform/tests/Unit/Entitlements/WorkspaceEntitlementResolverTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -128,9 +128,9 @@ function entitledWorkspaceManager(): array value: 'Temporary support-approved exception', ); - Tenant::factory()->count(2)->create([ + ManagedEnvironment::factory()->count(2)->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ACTIVE, + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); $decision = app(WorkspaceEntitlementResolver::class)->resolve( diff --git a/apps/platform/tests/Unit/EntraAdminRolesReportServiceTest.php b/apps/platform/tests/Unit/EntraAdminRolesReportServiceTest.php index e5a2bb40..6dc97320 100644 --- a/apps/platform/tests/Unit/EntraAdminRolesReportServiceTest.php +++ b/apps/platform/tests/Unit/EntraAdminRolesReportServiceTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\EntraAdminRoles\EntraAdminRolesReportService; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; @@ -11,7 +11,7 @@ uses(RefreshDatabase::class); it('requests principal expansion and uses principal display name when present', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant, 'microsoft'); $roleDefinitions = [ @@ -68,7 +68,7 @@ }); it('falls back to Unknown when principal details are missing upstream', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant, 'microsoft'); $roleDefinitions = [ diff --git a/apps/platform/tests/Unit/Evidence/EvidenceSnapshotResolverTest.php b/apps/platform/tests/Unit/Evidence/EvidenceSnapshotResolverTest.php index 8c6e7243..c6cf0737 100644 --- a/apps/platform/tests/Unit/Evidence/EvidenceSnapshotResolverTest.php +++ b/apps/platform/tests/Unit/Evidence/EvidenceSnapshotResolverTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\EvidenceSnapshot; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Evidence\EvidenceResolutionRequest; use App\Services\Evidence\EvidenceSnapshotResolver; use App\Support\Evidence\EvidenceCompletenessState; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); it('returns missing snapshot when no active snapshot exists', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $result = app(EvidenceSnapshotResolver::class)->resolve(new EvidenceResolutionRequest( workspaceId: (int) $tenant->workspace_id, @@ -25,10 +25,10 @@ }); it('resolves an eligible active snapshot', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, @@ -36,7 +36,7 @@ ]); $snapshot->items()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => 'findings_summary', 'state' => EvidenceCompletenessState::Complete->value, @@ -56,10 +56,10 @@ }); it('returns snapshot ineligible when a required dimension is stale', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $snapshot = EvidenceSnapshot::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Stale->value, @@ -67,7 +67,7 @@ ]); $snapshot->items()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => 'findings_summary', 'state' => EvidenceCompletenessState::Stale->value, diff --git a/apps/platform/tests/Unit/Factories/OperationRunFactoryTest.php b/apps/platform/tests/Unit/Factories/OperationRunFactoryTest.php index 5d28396d..7560ca95 100644 --- a/apps/platform/tests/Unit/Factories/OperationRunFactoryTest.php +++ b/apps/platform/tests/Unit/Factories/OperationRunFactoryTest.php @@ -12,7 +12,7 @@ it('keeps the default operation run factory path lean by avoiding implicit user creation', function (): void { $run = OperationRun::factory()->create(); - expect($run->tenant_id)->not->toBeNull() + expect($run->managed_environment_id)->not->toBeNull() ->and($run->workspace_id)->not->toBeNull() ->and($run->user_id)->toBeNull() ->and($run->initiator_name)->toBe('System'); @@ -35,6 +35,6 @@ ->tenantlessForWorkspace($workspace) ->create(); - expect($run->tenant_id)->toBeNull() + expect($run->managed_environment_id)->toBeNull() ->and($run->workspace_id)->toBe((int) $workspace->getKey()); }); \ No newline at end of file diff --git a/apps/platform/tests/Unit/Factories/TenantFactoryTest.php b/apps/platform/tests/Unit/Factories/TenantFactoryTest.php index 2f0186fd..ff23d4de 100644 --- a/apps/platform/tests/Unit/Factories/TenantFactoryTest.php +++ b/apps/platform/tests/Unit/Factories/TenantFactoryTest.php @@ -2,27 +2,27 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); it('can create tenants without provisioning a workspace graph when the minimal state is explicit', function (): void { - $tenant = Tenant::factory()->minimal()->create(); + $tenant = ManagedEnvironment::factory()->minimal()->create(); expect($tenant->workspace_id)->toBeNull(); }); it('keeps the default tenant factory path workspace-ready for existing callers', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); expect($tenant->workspace_id)->not->toBeNull(); }); it('restores default workspace provisioning after an explicit minimal tenant is created', function (): void { - Tenant::factory()->minimal()->create(); + ManagedEnvironment::factory()->minimal()->create(); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); expect($tenant->workspace_id)->not->toBeNull(); }); \ No newline at end of file diff --git a/apps/platform/tests/Unit/Filament/EditProviderConnectionTenantResolutionTest.php b/apps/platform/tests/Unit/Filament/EditProviderConnectionTenantResolutionTest.php index 07b11159..c93e60f0 100644 --- a/apps/platform/tests/Unit/Filament/EditProviderConnectionTenantResolutionTest.php +++ b/apps/platform/tests/Unit/Filament/EditProviderConnectionTenantResolutionTest.php @@ -3,14 +3,14 @@ declare(strict_types=1); use App\Filament\Resources\ProviderConnectionResource\Pages\EditProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); -test('EditProviderConnection prefers scoped tenant external id over Tenant::current', function (): void { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); +test('EditProviderConnection prefers scoped tenant external id over ManagedEnvironment::current', function (): void { + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); $tenantB->makeCurrent(); @@ -22,12 +22,12 @@ $resolvedTenant = $method->invoke($page); - expect($resolvedTenant)->toBeInstanceOf(Tenant::class); + expect($resolvedTenant)->toBeInstanceOf(ManagedEnvironment::class); expect($resolvedTenant->is($tenantA))->toBeTrue(); }); -test('EditProviderConnection falls back to Tenant::current when no scoped tenant is set', function (): void { - $tenantA = Tenant::factory()->create(); +test('EditProviderConnection falls back to ManagedEnvironment::current when no scoped tenant is set', function (): void { + $tenantA = ManagedEnvironment::factory()->create(); $tenantA->makeCurrent(); @@ -38,6 +38,6 @@ $resolvedTenant = $method->invoke($page); - expect($resolvedTenant)->toBeInstanceOf(Tenant::class); + expect($resolvedTenant)->toBeInstanceOf(ManagedEnvironment::class); expect($resolvedTenant->is($tenantA))->toBeTrue(); }); diff --git a/apps/platform/tests/Unit/Filament/ProviderConnectionResourceLivewireTenantInferenceTest.php b/apps/platform/tests/Unit/Filament/ProviderConnectionResourceLivewireTenantInferenceTest.php index 5967d1af..ea0331c6 100644 --- a/apps/platform/tests/Unit/Filament/ProviderConnectionResourceLivewireTenantInferenceTest.php +++ b/apps/platform/tests/Unit/Filament/ProviderConnectionResourceLivewireTenantInferenceTest.php @@ -3,14 +3,14 @@ declare(strict_types=1); use App\Filament\Resources\ProviderConnectionResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Http\Request; uses(RefreshDatabase::class); test('ProviderConnectionResource::getUrl infers tenant from referer during Livewire requests', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'external_id' => 'b0091e5d-944f-4a34-bcd9-12cbfb7b75cf', ]); @@ -25,17 +25,17 @@ $request->headers->set('referer', "http://localhost/admin/tenants/{$tenant->external_id}/provider-connections/1/edit"); app()->instance('request', $request); - expect(Tenant::query()->where('external_id', $tenant->external_id)->exists())->toBeTrue(); + expect(ManagedEnvironment::query()->where('slug', $tenant->external_id)->exists())->toBeTrue(); $method = new ReflectionMethod(ProviderConnectionResource::class, 'resolveScopedTenant'); $method->setAccessible(true); $resolvedTenant = $method->invoke(null); - expect($resolvedTenant)->toBeInstanceOf(Tenant::class); + expect($resolvedTenant)->toBeInstanceOf(ManagedEnvironment::class); expect($resolvedTenant->is($tenant))->toBeTrue(); $url = ProviderConnectionResource::getUrl('index'); expect($url)->toContain('/admin/provider-connections'); - expect($url)->toContain('tenant_id='.(string) $tenant->external_id); + expect($url)->toContain('managed_environment_id='.(string) $tenant->external_id); }); diff --git a/apps/platform/tests/Unit/Findings/FindingExceptionDecisionTest.php b/apps/platform/tests/Unit/Findings/FindingExceptionDecisionTest.php index 9f7b9d64..b4560e26 100644 --- a/apps/platform/tests/Unit/Findings/FindingExceptionDecisionTest.php +++ b/apps/platform/tests/Unit/Findings/FindingExceptionDecisionTest.php @@ -14,7 +14,7 @@ $finding = Finding::factory()->for($tenant)->create(); $exception = FindingException::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -27,7 +27,7 @@ ]); $decision = $exception->decisions()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $user->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_REQUESTED, 'reason' => 'Temporary exception request', @@ -44,7 +44,7 @@ $finding = Finding::factory()->for($tenant)->create(); $exception = FindingException::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -57,7 +57,7 @@ ]); $decision = $exception->decisions()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $user->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_REQUESTED, 'reason' => 'Temporary exception request', diff --git a/apps/platform/tests/Unit/Findings/FindingExceptionEvidenceReferenceTest.php b/apps/platform/tests/Unit/Findings/FindingExceptionEvidenceReferenceTest.php index d3101937..39e34224 100644 --- a/apps/platform/tests/Unit/Findings/FindingExceptionEvidenceReferenceTest.php +++ b/apps/platform/tests/Unit/Findings/FindingExceptionEvidenceReferenceTest.php @@ -14,7 +14,7 @@ $finding = Finding::factory()->for($tenant)->create(); $exception = FindingException::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -27,7 +27,7 @@ ]); $reference = $exception->evidenceReferences()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'source_type' => 'evidence_snapshot', 'source_id' => 'snapshot-001', 'source_fingerprint' => 'fp-001', @@ -42,5 +42,5 @@ ->and($freshReference?->summary_payload)->toBe(['summary' => 'Intelligible even if the live evidence disappears']) ->and($freshReference?->measured_at)->not->toBeNull() ->and($freshReference?->exception)->toBeInstanceOf(FindingException::class) - ->and($freshReference?->tenant)->toBeInstanceOf(\App\Models\Tenant::class); + ->and($freshReference?->tenant)->toBeInstanceOf(\App\Models\ManagedEnvironment::class); }); diff --git a/apps/platform/tests/Unit/Findings/FindingExceptionModelTest.php b/apps/platform/tests/Unit/Findings/FindingExceptionModelTest.php index 22edb50d..c845169e 100644 --- a/apps/platform/tests/Unit/Findings/FindingExceptionModelTest.php +++ b/apps/platform/tests/Unit/Findings/FindingExceptionModelTest.php @@ -15,7 +15,7 @@ $finding = Finding::factory()->for($tenant)->create(); $exception = FindingException::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -28,7 +28,7 @@ ]); $decision = $exception->decisions()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $user->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_REQUESTED, 'reason' => 'Temporary exception request', @@ -48,7 +48,7 @@ $finding = Finding::factory()->for($tenant)->create(); $exception = FindingException::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -61,7 +61,7 @@ ]); $decision = $exception->decisions()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $user->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_REQUESTED, 'reason' => 'Temporary exception request', diff --git a/apps/platform/tests/Unit/FoundationMappingServiceTest.php b/apps/platform/tests/Unit/FoundationMappingServiceTest.php index f7e9c109..58a46bea 100644 --- a/apps/platform/tests/Unit/FoundationMappingServiceTest.php +++ b/apps/platform/tests/Unit/FoundationMappingServiceTest.php @@ -2,7 +2,7 @@ use App\Models\BackupItem; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\FoundationMappingService; @@ -59,7 +59,7 @@ public function request(string $method, string $path, array $options = []): Grap } it('maps existing foundations by display name', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant, 'microsoft'); $backupSet = BackupSet::factory()->for($tenant)->create(); @@ -119,8 +119,8 @@ public function request(string $method, string $path, array $options = []): Grap 'update_strip_keys' => ['isBuiltIn'], ]); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-1', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-1', 'app_client_id' => 'client-1', 'app_client_secret' => 'secret-1', ]); @@ -195,7 +195,7 @@ public function request(string $method, string $path, array $options = []): Grap }); it('skips built-in scope tags', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant, 'microsoft'); $backupSet = BackupSet::factory()->for($tenant)->create(); @@ -239,7 +239,7 @@ public function request(string $method, string $path, array $options = []): Grap }); it('marks failures when foundation listing fails', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $backupSet = BackupSet::factory()->for($tenant)->create(); $item = BackupItem::factory() ->for($tenant) diff --git a/apps/platform/tests/Unit/FoundationSnapshotServiceTest.php b/apps/platform/tests/Unit/FoundationSnapshotServiceTest.php index 5bd93b5d..5a63acae 100644 --- a/apps/platform/tests/Unit/FoundationSnapshotServiceTest.php +++ b/apps/platform/tests/Unit/FoundationSnapshotServiceTest.php @@ -1,6 +1,6 @@ create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant, 'microsoft'); @@ -76,8 +76,8 @@ public function request(string $method, string $path, array $options = []): Grap 'allowed_select' => ['id', 'displayName'], ]); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-123', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-123', 'app_client_id' => 'client-123', 'app_client_secret' => 'secret-123', ]); @@ -129,8 +129,8 @@ public function request(string $method, string $path, array $options = []): Grap 'allowed_expand' => ['roleDefinition($select=id,displayName,description,isBuiltIn)'], ]); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-rbac-123', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-rbac-123', 'app_client_id' => 'client-rbac-123', 'app_client_secret' => 'secret-rbac-123', ]); diff --git a/apps/platform/tests/Unit/GraphClientEndpointResolutionTest.php b/apps/platform/tests/Unit/GraphClientEndpointResolutionTest.php index 8c0cf745..84574333 100644 --- a/apps/platform/tests/Unit/GraphClientEndpointResolutionTest.php +++ b/apps/platform/tests/Unit/GraphClientEndpointResolutionTest.php @@ -9,7 +9,7 @@ beforeEach(function () { config()->set('graph.base_url', 'https://graph.microsoft.com'); config()->set('graph.version', 'beta'); - config()->set('graph.tenant_id', 'tenant'); + config()->set('graph.managed_environment_id', 'tenant'); config()->set('graph.client_id', 'client'); config()->set('graph.client_secret', 'secret'); config()->set('graph.scope', 'https://graph.microsoft.com/.default'); diff --git a/apps/platform/tests/Unit/GraphClientScopeTest.php b/apps/platform/tests/Unit/GraphClientScopeTest.php index 044fabb5..e57c1bb6 100644 --- a/apps/platform/tests/Unit/GraphClientScopeTest.php +++ b/apps/platform/tests/Unit/GraphClientScopeTest.php @@ -12,7 +12,7 @@ Cache::flush(); Config::set('graph.scope', ''); - Config::set('graph.tenant_id', 'tenant-scope'); + Config::set('graph.managed_environment_id', 'tenant-scope'); Config::set('graph.client_id', 'client-id'); Config::set('graph.client_secret', 'client-secret'); diff --git a/apps/platform/tests/Unit/GraphContractFallbackTest.php b/apps/platform/tests/Unit/GraphContractFallbackTest.php index ee320a86..6904697e 100644 --- a/apps/platform/tests/Unit/GraphContractFallbackTest.php +++ b/apps/platform/tests/Unit/GraphContractFallbackTest.php @@ -16,7 +16,7 @@ config()->set('graph.base_url', 'https://graph.microsoft.com'); config()->set('graph.version', 'beta'); - config()->set('graph.tenant_id', 'tenant'); + config()->set('graph.managed_environment_id', 'tenant'); config()->set('graph.client_id', 'client'); config()->set('graph.client_secret', 'secret'); config()->set('graph.scope', 'https://graph.microsoft.com/.default'); diff --git a/apps/platform/tests/Unit/Hardening/IntuneRbacWriteGateNoHttpTest.php b/apps/platform/tests/Unit/Hardening/IntuneRbacWriteGateNoHttpTest.php index e759ae62..f570119b 100644 --- a/apps/platform/tests/Unit/Hardening/IntuneRbacWriteGateNoHttpTest.php +++ b/apps/platform/tests/Unit/Hardening/IntuneRbacWriteGateNoHttpTest.php @@ -2,7 +2,7 @@ use App\Contracts\Hardening\WriteGateInterface; use App\Exceptions\Hardening\ProviderAccessHardeningRequired; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Http; @@ -16,7 +16,7 @@ test('gate evaluation with not_configured status makes zero HTTP calls', function () { Http::fake(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'not_configured', 'rbac_last_checked_at' => null, ]); @@ -35,7 +35,7 @@ test('gate evaluation with unhealthy status makes zero HTTP calls', function () { Http::fake(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'failed', 'rbac_last_checked_at' => now(), ]); @@ -54,7 +54,7 @@ test('gate evaluation with stale status makes zero HTTP calls', function () { Http::fake(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now()->subHours(48), ]); @@ -73,7 +73,7 @@ test('gate evaluation with ok fresh status makes zero HTTP calls', function () { Http::fake(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now()->subMinutes(30), ]); diff --git a/apps/platform/tests/Unit/Intune/VersionServiceConcurrencyTest.php b/apps/platform/tests/Unit/Intune/VersionServiceConcurrencyTest.php index cbff0c5b..8702a561 100644 --- a/apps/platform/tests/Unit/Intune/VersionServiceConcurrencyTest.php +++ b/apps/platform/tests/Unit/Intune/VersionServiceConcurrencyTest.php @@ -2,7 +2,7 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\AssignmentFetcher; use App\Services\Graph\AssignmentFilterResolver; use App\Services\Graph\GroupResolver; @@ -17,7 +17,7 @@ uses(RefreshDatabase::class); it('retries and succeeds after a policy_versions unique collision during capture', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $policy = Policy::factory()->for($tenant)->create(); $policy->load('tenant'); @@ -45,7 +45,7 @@ PolicyVersion::withoutEvents(function () use ($model, &$collisionInserted): void { PolicyVersion::query()->create([ - 'tenant_id' => $model->tenant_id, + 'managed_environment_id' => $model->managed_environment_id, 'policy_id' => $model->policy_id, 'version_number' => $model->version_number, 'policy_type' => $model->policy_type, diff --git a/apps/platform/tests/Unit/InventoryLinkTest.php b/apps/platform/tests/Unit/InventoryLinkTest.php index b35a8d1a..6cc65fce 100644 --- a/apps/platform/tests/Unit/InventoryLinkTest.php +++ b/apps/platform/tests/Unit/InventoryLinkTest.php @@ -1,7 +1,7 @@ create(); + $tenant = ManagedEnvironment::factory()->create(); $data = [ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'source_type' => 'inventory_item', 'source_id' => (string) Str::uuid(), 'target_type' => 'foundation_object', @@ -29,23 +29,23 @@ }); it('scopes edges by tenant at query level', function () { - $tenantA = Tenant::factory()->create(); - $tenantB = Tenant::factory()->create(); + $tenantA = ManagedEnvironment::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); $sourceId = (string) Str::uuid(); InventoryLink::factory()->create([ - 'tenant_id' => $tenantA->getKey(), + 'managed_environment_id' => $tenantA->getKey(), 'source_id' => $sourceId, ]); InventoryLink::factory()->create([ - 'tenant_id' => $tenantB->getKey(), + 'managed_environment_id' => $tenantB->getKey(), 'source_id' => $sourceId, ]); - $edgesA = InventoryLink::query()->where('tenant_id', $tenantA->getKey())->get(); - $edgesB = InventoryLink::query()->where('tenant_id', $tenantB->getKey())->get(); + $edgesA = InventoryLink::query()->where('managed_environment_id', $tenantA->getKey())->get(); + $edgesB = InventoryLink::query()->where('managed_environment_id', $tenantB->getKey())->get(); expect($edgesA->count())->toBe(1); expect($edgesB->count())->toBe(1); diff --git a/apps/platform/tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php b/apps/platform/tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php new file mode 100644 index 00000000..2020f8ee --- /dev/null +++ b/apps/platform/tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php @@ -0,0 +1,94 @@ +actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]); + + $context = app(WorkspaceContext::class); + + expect($context->rememberTenantContext($environment, request()))->toBeTrue() + ->and($context->rememberedTenant(request())?->is($environment))->toBeTrue() + ->and($context->lastTenantId(request()))->toBe((int) $environment->getKey()); +}); + +it('rejects remembered managed environments from a different workspace', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner'); + $otherWorkspace = Workspace::factory()->create(); + + WorkspaceMembership::factory()->create([ + 'workspace_id' => (int) $otherWorkspace->getKey(), + 'user_id' => (int) $user->getKey(), + 'role' => 'owner', + ]); + + $this->actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $otherWorkspace->getKey(), + ]); + + $context = app(WorkspaceContext::class); + + expect($context->rememberTenantContext($environment, request()))->toBeFalse() + ->and($context->rememberedTenant(request()))->toBeNull(); +}); + +it('clears a remembered environment when the actor loses managed-environment membership', function (): void { + [$member, $environment] = createUserWithTenant(role: 'owner'); + $workspaceId = (int) $environment->workspace_id; + + $outsider = User::factory()->create(); + WorkspaceMembership::factory()->create([ + 'workspace_id' => $workspaceId, + 'user_id' => (int) $outsider->getKey(), + 'role' => 'manager', + ]); + + $this->actingAs($outsider)->withSession([ + WorkspaceContext::SESSION_KEY => $workspaceId, + WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [ + (string) $workspaceId => (int) $environment->getKey(), + ], + ]); + + unset($member); + + expect(app(WorkspaceContext::class)->rememberedTenant(request()))->toBeNull() + ->and(session(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY))->toBe([]); +}); + +it('resolves the current workspace from a managed environment only for members with target access', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner'); + + $this->actingAs($user); + + expect(app(WorkspaceContext::class)->currentWorkspaceOrTenantWorkspace($environment, request())?->getKey()) + ->toBe($environment->workspace_id); +}); + +it('404s when a managed environment is outside the current workspace boundary', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner'); + $otherWorkspace = Workspace::factory()->create(); + + WorkspaceMembership::factory()->create([ + 'workspace_id' => (int) $otherWorkspace->getKey(), + 'user_id' => (int) $user->getKey(), + 'role' => 'owner', + ]); + + $this->actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $otherWorkspace->getKey(), + ]); + + app(WorkspaceContext::class)->ensureTenantAccessibleInCurrentWorkspace($environment, $user, request()); +})->throws(Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class); diff --git a/apps/platform/tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php b/apps/platform/tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php new file mode 100644 index 00000000..15eae0c7 --- /dev/null +++ b/apps/platform/tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php @@ -0,0 +1,89 @@ +create(); + + $environment = ManagedEnvironment::factory()->create([ + 'workspace_id' => (int) $workspace->getKey(), + 'name' => 'Contoso Production', + 'display_name' => 'Contoso Prod', + 'slug' => 'contoso-prod', + 'kind' => 'production', + 'lifecycle_status' => ManagedEnvironment::STATUS_ACTIVE, + ]); + + expect($workspace->managedEnvironments()->whereKey($environment->getKey())->exists())->toBeTrue() + ->and($workspace->tenants()->whereKey($environment->getKey())->exists())->toBeTrue() + ->and($environment->workspace->is($workspace))->toBeTrue() + ->and($environment->getRouteKeyName())->toBe('slug') + ->and((new ManagedEnvironment)->resolveRouteBinding('contoso-prod')->is($environment))->toBeTrue() + ->and($environment->isSelectableAsContext())->toBeTrue() + ->and($environment->getFilamentName())->toBe('Contoso Prod (PRODUCTION)'); +}); + +it('keeps archived environments resolvable by route key but unavailable as active context', function (): void { + $environment = ManagedEnvironment::factory()->archived()->create([ + 'slug' => 'archived-environment', + ]); + + $resolved = (new ManagedEnvironment)->resolveRouteBinding('archived-environment'); + + expect($resolved)->toBeInstanceOf(ManagedEnvironment::class) + ->and($resolved->is($environment))->toBeTrue() + ->and($resolved->isSelectableAsContext())->toBeFalse(); +}); + +it('keeps provider-specific identity off managed environment columns', function (): void { + $columns = Schema::getColumnListing('managed_environments'); + + expect($columns)->not->toContain( + 'external_id', + 'tenant_id', + 'managed_environment_id', + 'status', + 'environment', + 'app_client_id', + 'app_client_secret', + 'app_certificate_thumbprint', + 'app_notes', + 'app_status', + 'domain', + 'entra_tenant_id', + 'graph_tenant_id', + ); +}); + +it('resolves Microsoft tenant identity through provider-owned seams only', function (): void { + $environment = ManagedEnvironment::factory()->create([ + 'slug' => 'provider-neutral-root', + ]); + + ProviderConnection::factory()->platform()->consentGranted()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'provider' => 'microsoft', + 'entra_tenant_id' => '11111111-1111-1111-1111-111111111111', + 'is_default' => true, + ]); + + expect($environment->refresh()->graphTenantId())->toBe('11111111-1111-1111-1111-111111111111') + ->and(fn () => $environment->graphOptions())->toThrow(BadMethodCallException::class); +}); + +it('treats managed_environment_id as a write-through alias for slug', function (): void { + $environment = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'alias-slug', + ]); + + expect($environment->slug)->toBe('alias-slug') + ->and($environment->managed_environment_id)->toBe('alias-slug') + ->and($environment->external_id)->toBe('alias-slug'); +}); diff --git a/apps/platform/tests/Unit/MicrosoftGraphClientTest.php b/apps/platform/tests/Unit/MicrosoftGraphClientTest.php index feae7356..357cf19f 100644 --- a/apps/platform/tests/Unit/MicrosoftGraphClientTest.php +++ b/apps/platform/tests/Unit/MicrosoftGraphClientTest.php @@ -10,7 +10,7 @@ it('returns a graph response when the HTTP client throws for a 400 response', function () { config()->set('graph.client_id', 'client-id'); config()->set('graph.client_secret', 'secret'); - config()->set('graph.tenant_id', 'tenant-id'); + config()->set('graph.managed_environment_id', 'tenant-id'); Http::fake(function () { $psrResponse = new PsrResponse(400, [], json_encode([ diff --git a/apps/platform/tests/Unit/Onboarding/OnboardingDraftResolverTest.php b/apps/platform/tests/Unit/Onboarding/OnboardingDraftResolverTest.php index 04804366..d6fc8dd7 100644 --- a/apps/platform/tests/Unit/Onboarding/OnboardingDraftResolverTest.php +++ b/apps/platform/tests/Unit/Onboarding/OnboardingDraftResolverTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -16,9 +16,9 @@ it('resolves an accessible draft and eager loads its related models', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(); @@ -95,9 +95,9 @@ it('throws authorization exceptions for in-scope members without onboarding capability', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $readonlyUser = User::factory()->create(); @@ -162,7 +162,7 @@ it('excludes linked drafts whose tenant lifecycle no longer allows onboarding resume', function (): void { $workspace = Workspace::factory()->create(); $user = User::factory()->create(); - $activeTenant = Tenant::factory()->active()->create([ + $activeTenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -188,7 +188,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $activeTenant->tenant_id, + 'entra_tenant_id' => (string) $activeTenant->managed_environment_id, 'tenant_name' => (string) $activeTenant->name, ], ]); @@ -200,9 +200,9 @@ it('resolves drafts that still contain legacy bootstrap operation state for read-side normalization', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'status' => Tenant::STATUS_ONBOARDING, + 'status' => ManagedEnvironment::STATUS_ONBOARDING, ]); $user = User::factory()->create(); diff --git a/apps/platform/tests/Unit/Onboarding/OnboardingDraftStageResolverTest.php b/apps/platform/tests/Unit/Onboarding/OnboardingDraftStageResolverTest.php index 18e24735..a823b4cc 100644 --- a/apps/platform/tests/Unit/Onboarding/OnboardingDraftStageResolverTest.php +++ b/apps/platform/tests/Unit/Onboarding/OnboardingDraftStageResolverTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Onboarding\OnboardingDraftStageResolver; use App\Support\Onboarding\OnboardingDraftStage; use App\Support\OperationRunOutcome; @@ -16,7 +16,7 @@ it('derives the identify stage when no confirmed tenant identity exists', function (): void { $draft = createOnboardingDraft([ 'entra_tenant_id' => '', - 'tenant_id' => null, + 'managed_environment_id' => null, 'state' => [], ]); @@ -37,10 +37,10 @@ }); it('derives the verify access stage when a provider connection is selected but verification is incomplete', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $draft = createOnboardingDraft([ @@ -48,7 +48,7 @@ 'tenant' => $tenant, 'current_step' => 'connection', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), ], @@ -73,10 +73,10 @@ }); it('derives the review stage when verification completed for the selected provider connection', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $draft = createOnboardingDraft([ @@ -84,7 +84,7 @@ 'tenant' => $tenant, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), ], @@ -92,7 +92,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $draft->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'context' => [ @@ -111,10 +111,10 @@ }); it('derives the bootstrap stage when bootstrap choices were already selected but not completed', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $draft = createOnboardingDraft([ @@ -122,7 +122,7 @@ 'tenant' => $tenant, 'current_step' => 'bootstrap', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'bootstrap_operation_types' => ['inventory_sync'], @@ -131,7 +131,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $draft->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'context' => [ diff --git a/apps/platform/tests/Unit/Onboarding/OnboardingLifecycleServiceTest.php b/apps/platform/tests/Unit/Onboarding/OnboardingLifecycleServiceTest.php index 40043848..3d53d382 100644 --- a/apps/platform/tests/Unit/Onboarding/OnboardingLifecycleServiceTest.php +++ b/apps/platform/tests/Unit/Onboarding/OnboardingLifecycleServiceTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Onboarding\OnboardingLifecycleService; use App\Support\Onboarding\OnboardingCheckpoint; use App\Support\Onboarding\OnboardingLifecycleState; @@ -15,10 +15,10 @@ uses(RefreshDatabase::class); it('marks a draft as action required when the provider connection changed before verification reruns', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $draft = createOnboardingDraft([ @@ -26,7 +26,7 @@ 'tenant' => $tenant, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'connection_recently_updated' => true, @@ -43,14 +43,14 @@ }); it('treats a missing persisted provider connection as connect-provider state instead of verify state', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $draft = createOnboardingDraft([ 'workspace' => $tenant->workspace, 'tenant' => $tenant, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => 42, ], @@ -66,10 +66,10 @@ }); it('marks a draft as ready for activation when verification succeeded for the selected connection', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $draft = createOnboardingDraft([ @@ -77,14 +77,14 @@ 'tenant' => $tenant, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), ], ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -109,14 +109,14 @@ }); it('marks a draft as bootstrapping while a selected bootstrap run is still active', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $verificationRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -126,7 +126,7 @@ ]); $bootstrapRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => OperationRunStatus::Running->value, 'outcome' => OperationRunOutcome::Pending->value, @@ -141,7 +141,7 @@ 'tenant' => $tenant, 'current_step' => 'bootstrap', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $verificationRun->getKey(), @@ -162,14 +162,14 @@ }); it('marks a draft as action required when a selected bootstrap run fails', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $verificationRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, @@ -179,7 +179,7 @@ ]); $bootstrapRun = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -194,7 +194,7 @@ 'tenant' => $tenant, 'current_step' => 'bootstrap', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $verificationRun->getKey(), @@ -215,10 +215,10 @@ }); it('applies the canonical lifecycle fields and normalizes the version floor', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), ]); $draft = createOnboardingDraft([ @@ -230,7 +230,7 @@ 'last_completed_checkpoint' => null, 'current_step' => 'verify', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'connection_recently_updated' => true, @@ -247,13 +247,13 @@ }); it('keeps linked archived tenants loaded while suppressing onboarding resume affordances', function (): void { - $tenant = Tenant::factory()->archived()->create(); + $tenant = ManagedEnvironment::factory()->archived()->create(); $draft = createOnboardingDraft([ 'workspace' => $tenant->workspace, 'tenant' => $tenant, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -261,7 +261,7 @@ $draft = $draft->fresh()->load('tenant'); $service = app(OnboardingLifecycleService::class); - expect($draft->tenant)->toBeInstanceOf(Tenant::class) + expect($draft->tenant)->toBeInstanceOf(ManagedEnvironment::class) ->and($draft->tenant?->trashed())->toBeTrue() ->and($draft->isWorkflowResumable())->toBeTrue() ->and($service->canResumeDraft($draft))->toBeFalse(); diff --git a/apps/platform/tests/Unit/Operations/QueuedExecutionLegitimacyGateTest.php b/apps/platform/tests/Unit/Operations/QueuedExecutionLegitimacyGateTest.php index 1e6bc4d3..165c78ee 100644 --- a/apps/platform/tests/Unit/Operations/QueuedExecutionLegitimacyGateTest.php +++ b/apps/platform/tests/Unit/Operations/QueuedExecutionLegitimacyGateTest.php @@ -19,7 +19,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -49,7 +49,7 @@ 'retryable' => false, 'target_scope' => [ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider_connection_id' => null, ], ]); @@ -63,14 +63,14 @@ ])->save(); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', @@ -107,14 +107,14 @@ ])->save(); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ]); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -148,7 +148,7 @@ [$user, $tenant] = createUserWithTenant(role: 'readonly'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'inventory_sync', @@ -176,7 +176,7 @@ [, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => null, 'type' => 'backup_schedule_run', @@ -201,7 +201,7 @@ [, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => null, 'type' => 'inventory_sync', @@ -231,7 +231,7 @@ ])->save(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'restore.execute', @@ -255,7 +255,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'readonly'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'promotion.execute', @@ -285,7 +285,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'policy.sync', @@ -306,7 +306,7 @@ [, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => null, 'type' => 'backup_schedule_run', @@ -329,7 +329,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'type' => 'promotion.execute', diff --git a/apps/platform/tests/Unit/Policies/ProviderConnectionPolicyDedicatedTest.php b/apps/platform/tests/Unit/Policies/ProviderConnectionPolicyDedicatedTest.php index b6e11e12..ca4234f2 100644 --- a/apps/platform/tests/Unit/Policies/ProviderConnectionPolicyDedicatedTest.php +++ b/apps/platform/tests/Unit/Policies/ProviderConnectionPolicyDedicatedTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceMembership; use App\Policies\ProviderConnectionPolicy; @@ -18,7 +18,7 @@ $connection = ProviderConnection::factory()->platform()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', ]); @@ -34,7 +34,7 @@ $connection = ProviderConnection::factory()->platform()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', ]); @@ -50,12 +50,12 @@ }); it('returns not found for non-members on dedicated override authorization checks', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $user = User::factory()->create(); $connection = ProviderConnection::factory()->platform()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', ]); @@ -71,7 +71,7 @@ it('returns not found when the provider connection is outside the active workspace', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'owner', ensureDefaultMicrosoftProviderConnection: false); - $tenantB = Tenant::factory()->create(); + $tenantB = ManagedEnvironment::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $tenantB->workspace_id, @@ -85,7 +85,7 @@ $connection = ProviderConnection::factory()->platform()->create([ 'workspace_id' => (int) $tenantB->workspace_id, - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'provider' => 'microsoft', ]); diff --git a/apps/platform/tests/Unit/Policies/ProviderConnectionPolicyTenantResolutionTest.php b/apps/platform/tests/Unit/Policies/ProviderConnectionPolicyTenantResolutionTest.php index 2788d57b..facbb36c 100644 --- a/apps/platform/tests/Unit/Policies/ProviderConnectionPolicyTenantResolutionTest.php +++ b/apps/platform/tests/Unit/Policies/ProviderConnectionPolicyTenantResolutionTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Policies\ProviderConnectionPolicy; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -13,7 +13,7 @@ test('provider connection policy resolves tenant from record when route tenant is missing', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'owner'); - $tenantB = Tenant::factory()->create([ + $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => $tenantA->workspace_id, ]); @@ -24,7 +24,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'provider' => 'microsoft', ]); diff --git a/apps/platform/tests/Unit/Policies/TenantOnboardingSessionPolicyTest.php b/apps/platform/tests/Unit/Policies/TenantOnboardingSessionPolicyTest.php index 4378a7f6..e081b74f 100644 --- a/apps/platform/tests/Unit/Policies/TenantOnboardingSessionPolicyTest.php +++ b/apps/platform/tests/Unit/Policies/TenantOnboardingSessionPolicyTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\WorkspaceMembership; use App\Policies\TenantOnboardingSessionPolicy; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); it('returns not found for actors outside the active workspace when viewing a draft', function (): void { - $tenant = Tenant::factory()->onboarding()->create(); + $tenant = ManagedEnvironment::factory()->onboarding()->create(); $owner = User::factory()->create(); $otherWorkspaceUser = User::factory()->create(); $otherWorkspace = \App\Models\Workspace::factory()->create(); @@ -49,7 +49,7 @@ }); it('returns not found for workspace members missing linked tenant entitlement', function (): void { - $tenant = Tenant::factory()->onboarding()->create(); + $tenant = ManagedEnvironment::factory()->onboarding()->create(); $owner = User::factory()->create(); $workspaceOnlyUser = User::factory()->create(); @@ -84,7 +84,7 @@ }); it('returns an honest forbidden message for entitled actors missing onboarding capability', function (): void { - $tenant = Tenant::factory()->onboarding()->create(); + $tenant = ManagedEnvironment::factory()->onboarding()->create(); $readonlyUser = User::factory()->create(); createUserWithTenant( diff --git a/apps/platform/tests/Unit/PolicyCaptureOrchestratorTest.php b/apps/platform/tests/Unit/PolicyCaptureOrchestratorTest.php index d8cccf6a..18b9773c 100644 --- a/apps/platform/tests/Unit/PolicyCaptureOrchestratorTest.php +++ b/apps/platform/tests/Unit/PolicyCaptureOrchestratorTest.php @@ -1,7 +1,7 @@ create([ - 'tenant_id' => 'tenant-1', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-1', 'app_client_id' => 'client-1', 'app_client_secret' => 'secret-1', 'is_current' => true, @@ -25,7 +25,7 @@ ensureDefaultProviderConnection($tenant, 'microsoft'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_type' => 'mamAppConfiguration', 'external_id' => 'A_f38e7f58-ac7c-455d-bb0e-f56bf1b3890e', 'display_name' => 'MAM Example', diff --git a/apps/platform/tests/Unit/PolicySnapshotServiceTest.php b/apps/platform/tests/Unit/PolicySnapshotServiceTest.php index 55ee1e24..f1007a54 100644 --- a/apps/platform/tests/Unit/PolicySnapshotServiceTest.php +++ b/apps/platform/tests/Unit/PolicySnapshotServiceTest.php @@ -3,7 +3,7 @@ use App\Models\Policy; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\PolicySnapshotService; @@ -11,17 +11,17 @@ uses(RefreshDatabase::class); -function tenantWithDefaultMicrosoftConnectionForPolicySnapshot(string $tenantIdentifier): Tenant +function tenantWithDefaultMicrosoftConnectionForPolicySnapshot(string $tenantIdentifier): ManagedEnvironment { - $tenant = Tenant::factory()->create([ - 'tenant_id' => $tenantIdentifier, + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => $tenantIdentifier, 'app_client_id' => null, 'app_client_secret' => null, 'is_current' => true, ]); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', @@ -323,7 +323,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant->makeCurrent(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'compliance-123', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Compliance Alpha', @@ -354,7 +354,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant->makeCurrent(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'esp-123', 'policy_type' => $policyType, 'display_name' => 'Endpoint Security Alpha', @@ -388,7 +388,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant->makeCurrent(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'enroll-notify-123', 'policy_type' => 'deviceEnrollmentNotificationConfiguration', 'display_name' => 'Enrollment Notifications', @@ -424,7 +424,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant->makeCurrent(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'app-123', 'policy_type' => 'mobileApp', 'display_name' => 'Contoso Portal', @@ -464,7 +464,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant->makeCurrent(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'wdp-123', 'policy_type' => 'windowsDriverUpdateProfile', 'display_name' => 'Driver Updates A', @@ -497,7 +497,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant = tenantWithDefaultMicrosoftConnectionForPolicySnapshot('tenant-mam-fallback'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'A_fallback-policy', 'policy_type' => 'mamAppConfiguration', 'display_name' => 'MAM Config Alpha', @@ -532,7 +532,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant = tenantWithDefaultMicrosoftConnectionForPolicySnapshot('tenant-404'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'A_missing', 'policy_type' => 'mamAppConfiguration', 'display_name' => 'Missing Policy', @@ -572,7 +572,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant = tenantWithDefaultMicrosoftConnectionForPolicySnapshot('tenant-mam-fallback-response'); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'A_resp_fallback', 'policy_type' => 'mamAppConfiguration', 'display_name' => 'MAM Config Response', @@ -648,7 +648,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant->makeCurrent(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'policy-wuring', 'policy_type' => 'windowsUpdateRing', 'display_name' => 'Ring A', @@ -717,7 +717,7 @@ public function request(string $method, string $path, array $options = []): Grap $tenant->makeCurrent(); $policy = Policy::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'external_id' => 'mam-123', 'policy_type' => 'deviceCompliancePolicy', 'display_name' => 'Compliance Config', diff --git a/apps/platform/tests/Unit/PolicyVersionEligibilityTest.php b/apps/platform/tests/Unit/PolicyVersionEligibilityTest.php index a04d791a..904580d7 100644 --- a/apps/platform/tests/Unit/PolicyVersionEligibilityTest.php +++ b/apps/platform/tests/Unit/PolicyVersionEligibilityTest.php @@ -2,30 +2,30 @@ use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('pruneEligible returns only old non-current versions', function () { - $tenant = Tenant::factory()->create(); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $tenant = ManagedEnvironment::factory()->create(); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $oldNonCurrent = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), ]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 2, 'captured_at' => now()->subDays(10), ]); $eligibleIds = PolicyVersion::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->pruneEligible(90) ->pluck('id') ->all(); @@ -34,18 +34,18 @@ }); test('pruneEligible excludes current even when old', function () { - $tenant = Tenant::factory()->create(); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $tenant = ManagedEnvironment::factory()->create(); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), ]); $eligibleCount = PolicyVersion::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->pruneEligible(90) ->count(); @@ -53,18 +53,18 @@ }); test('pruneEligible excludes archived versions', function () { - $tenant = Tenant::factory()->create(); - $policy = Policy::factory()->create(['tenant_id' => $tenant->id]); + $tenant = ManagedEnvironment::factory()->create(); + $policy = Policy::factory()->create(['managed_environment_id' => $tenant->id]); $archived = PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'captured_at' => now()->subDays(120), ]); PolicyVersion::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 2, 'captured_at' => now()->subDays(120), @@ -73,7 +73,7 @@ $archived->delete(); $eligibleIds = PolicyVersion::query() - ->where('tenant_id', $tenant->id) + ->where('managed_environment_id', $tenant->id) ->pruneEligible(90) ->pluck('id') ->all(); diff --git a/apps/platform/tests/Unit/Providers/AdminConsentUrlFactoryTest.php b/apps/platform/tests/Unit/Providers/AdminConsentUrlFactoryTest.php index 2c03d435..7baa67ba 100644 --- a/apps/platform/tests/Unit/Providers/AdminConsentUrlFactoryTest.php +++ b/apps/platform/tests/Unit/Providers/AdminConsentUrlFactoryTest.php @@ -2,7 +2,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\AdminConsentUrlFactory; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -11,15 +11,15 @@ it('builds admin consent urls for platform connections from the central platform identity', function (): void { config()->set('graph.client_id', 'platform-client-id'); config()->set('graph.client_secret', 'platform-client-secret'); - config()->set('graph.tenant_id', 'organizations'); + config()->set('graph.managed_environment_id', 'organizations'); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'target-tenant-id', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'target-tenant-id', 'app_client_id' => 'legacy-tenant-client-id', ]); $connection = ProviderConnection::factory()->platform()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'target-tenant-id', @@ -48,12 +48,12 @@ }); it('builds admin consent urls for dedicated connections from the dedicated credential identity', function (): void { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'dedicated-target-tenant-id', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'dedicated-target-tenant-id', ]); $connection = ProviderConnection::factory()->dedicated()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'dedicated-target-tenant-id', diff --git a/apps/platform/tests/Unit/Providers/CredentialManagerTest.php b/apps/platform/tests/Unit/Providers/CredentialManagerTest.php index 6cb0be6b..50e7e764 100644 --- a/apps/platform/tests/Unit/Providers/CredentialManagerTest.php +++ b/apps/platform/tests/Unit/Providers/CredentialManagerTest.php @@ -37,7 +37,7 @@ ProviderCredential::factory()->create([ 'provider_connection_id' => $connection->getKey(), 'payload' => [ - 'tenant_id' => 'tenant-b', + 'managed_environment_id' => 'tenant-b', 'client_id' => 'client-id', 'client_secret' => 'client-secret', ], diff --git a/apps/platform/tests/Unit/Providers/PlatformProviderIdentityResolverTest.php b/apps/platform/tests/Unit/Providers/PlatformProviderIdentityResolverTest.php index 730e8386..f41d0f1b 100644 --- a/apps/platform/tests/Unit/Providers/PlatformProviderIdentityResolverTest.php +++ b/apps/platform/tests/Unit/Providers/PlatformProviderIdentityResolverTest.php @@ -7,7 +7,7 @@ it('resolves the central platform identity from config', function (): void { config()->set('graph.client_id', 'platform-client-id'); config()->set('graph.client_secret', 'platform-client-secret'); - config()->set('graph.tenant_id', 'platform-home-tenant-id'); + config()->set('graph.managed_environment_id', 'platform-home-tenant-id'); $resolution = app(PlatformProviderIdentityResolver::class)->resolve('customer-tenant-id'); diff --git a/apps/platform/tests/Unit/Providers/ProviderConnectionClassifierTest.php b/apps/platform/tests/Unit/Providers/ProviderConnectionClassifierTest.php index 73d8f798..d2bc1c02 100644 --- a/apps/platform/tests/Unit/Providers/ProviderConnectionClassifierTest.php +++ b/apps/platform/tests/Unit/Providers/ProviderConnectionClassifierTest.php @@ -4,7 +4,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\ProviderConnectionClassifier; use App\Support\Providers\ProviderConnectionType; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -14,14 +14,14 @@ it('classifies a platform-like connection without legacy identity as platform', function (): void { config()->set('graph.client_id', 'platform-client-id'); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'platform-like-tenant-id', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'platform-like-tenant-id', 'app_client_id' => null, 'app_client_secret' => null, ]); $connection = ProviderConnection::factory()->platform()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'platform-like-tenant-id', @@ -43,14 +43,14 @@ }); it('classifies a credential-backed legacy connection as dedicated', function (): void { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'dedicated-like-tenant-id', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'dedicated-like-tenant-id', 'app_client_id' => null, 'app_client_secret' => null, ]); $connection = ProviderConnection::factory()->platform()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'dedicated-like-tenant-id', @@ -78,18 +78,19 @@ ]); }); -it('flags contradictory legacy identity as review required', function (): void { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'hybrid-tenant-id', - 'app_client_id' => 'legacy-tenant-client-id', - 'app_client_secret' => 'legacy-tenant-secret', +it('flags contradictory platform and dedicated identity as review required', function (): void { + config()->set('graph.client_id', 'platform-client-id'); + + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'hybrid-tenant-id', ]); $connection = ProviderConnection::factory()->platform()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'hybrid-tenant-id', + 'is_default' => true, 'consent_status' => 'granted', 'verification_status' => 'healthy', ]); @@ -116,7 +117,7 @@ ], ]) ->and($result->signals)->toMatchArray([ - 'tenant_client_id' => 'legacy-tenant-client-id', + 'tenant_client_id' => 'platform-client-id', 'credential_client_id' => 'dedicated-client-id', 'is_enabled' => true, 'consent_status' => 'granted', diff --git a/apps/platform/tests/Unit/Providers/ProviderConnectionTargetScopeDescriptorTest.php b/apps/platform/tests/Unit/Providers/ProviderConnectionTargetScopeDescriptorTest.php index 4746061b..0dc5548e 100644 --- a/apps/platform/tests/Unit/Providers/ProviderConnectionTargetScopeDescriptorTest.php +++ b/apps/platform/tests/Unit/Providers/ProviderConnectionTargetScopeDescriptorTest.php @@ -15,7 +15,7 @@ $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => '11111111-1111-1111-1111-111111111111', 'display_name' => 'Primary connection', diff --git a/apps/platform/tests/Unit/Providers/ProviderIdentityResolutionNeutralityTest.php b/apps/platform/tests/Unit/Providers/ProviderIdentityResolutionNeutralityTest.php index f96e3c92..7f781de9 100644 --- a/apps/platform/tests/Unit/Providers/ProviderIdentityResolutionNeutralityTest.php +++ b/apps/platform/tests/Unit/Providers/ProviderIdentityResolutionNeutralityTest.php @@ -4,7 +4,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\ProviderIdentityResolver; use App\Support\Providers\ProviderConnectionType; use App\Support\Providers\TargetScope\ProviderConnectionTargetScopeDescriptor; @@ -15,15 +15,15 @@ it('exposes neutral target-scope truth beside provider-owned identity metadata', function (): void { config()->set('graph.client_id', 'platform-client-id'); config()->set('graph.client_secret', 'platform-client-secret'); - config()->set('graph.tenant_id', 'platform-home-tenant-id'); + config()->set('graph.managed_environment_id', 'platform-home-tenant-id'); - $tenant = Tenant::factory()->create([ - 'tenant_id' => '22222222-2222-2222-2222-222222222222', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => '22222222-2222-2222-2222-222222222222', ]); $connection = ProviderConnection::factory()->platform()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => '22222222-2222-2222-2222-222222222222', ]); diff --git a/apps/platform/tests/Unit/Providers/ProviderIdentityResolverTest.php b/apps/platform/tests/Unit/Providers/ProviderIdentityResolverTest.php index 189e474c..ff4f2503 100644 --- a/apps/platform/tests/Unit/Providers/ProviderIdentityResolverTest.php +++ b/apps/platform/tests/Unit/Providers/ProviderIdentityResolverTest.php @@ -2,7 +2,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\ProviderIdentityResolver; use App\Support\Providers\ProviderConnectionType; use App\Support\Providers\ProviderReasonCodes; @@ -14,13 +14,13 @@ config()->set('graph.client_id', 'platform-client-id'); config()->set('graph.client_secret', 'platform-client-secret'); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'platform-target-tenant-id', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'platform-target-tenant-id', 'app_client_id' => 'legacy-tenant-client-id', ]); $connection = ProviderConnection::factory()->platform()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'platform-target-tenant-id', @@ -45,12 +45,12 @@ }); it('resolves dedicated connections from dedicated credentials only', function (): void { - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'dedicated-target-tenant-id', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'dedicated-target-tenant-id', ]); $connection = ProviderConnection::factory()->dedicated()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'dedicated-target-tenant-id', diff --git a/apps/platform/tests/Unit/Providers/ProviderNextStepsRegistryTest.php b/apps/platform/tests/Unit/Providers/ProviderNextStepsRegistryTest.php index 1c33d7c3..e22e5eda 100644 --- a/apps/platform/tests/Unit/Providers/ProviderNextStepsRegistryTest.php +++ b/apps/platform/tests/Unit/Providers/ProviderNextStepsRegistryTest.php @@ -4,7 +4,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Providers\ProviderNextStepsRegistry; use App\Support\Providers\ProviderReasonCodes; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -12,8 +12,8 @@ uses(RefreshDatabase::class); it('includes an admin consent next step when provider consent is missing', function () { - $tenant = Tenant::create([ - 'tenant_id' => 'tenant-1', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-1', 'name' => 'Contoso', ]); @@ -27,16 +27,16 @@ ->and($steps[0]['url'])->toContain('learn.microsoft.com'); }); -it('links to the real admin consent endpoint when provider credentials exist', function () { - $tenant = Tenant::factory()->create([ +it('links to the real admin consent endpoint when a dedicated provider connection exists', function () { + $tenant = ManagedEnvironment::factory()->create([ 'app_client_id' => null, ]); - $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + $connection = ProviderConnection::factory()->dedicated()->create([ + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->graphTenantId(), + 'entra_tenant_id' => 'dedicated-target-tenant-id', 'is_default' => true, ]); @@ -60,12 +60,12 @@ }); it('surfaces review-required next steps on the provider connection detail path', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'app_client_id' => null, ]); $connection = ProviderConnection::factory()->dedicated()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => (string) $tenant->graphTenantId(), diff --git a/apps/platform/tests/Unit/Providers/ProviderOperationStartGateTest.php b/apps/platform/tests/Unit/Providers/ProviderOperationStartGateTest.php index 3751c609..048fc89c 100644 --- a/apps/platform/tests/Unit/Providers/ProviderOperationStartGateTest.php +++ b/apps/platform/tests/Unit/Providers/ProviderOperationStartGateTest.php @@ -3,7 +3,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Providers\ProviderOperationStartGate; use App\Support\Auth\Capabilities; use App\Support\OperationRunOutcome; @@ -15,9 +15,9 @@ uses(RefreshDatabase::class); it('starts a provider operation and dispatches the job once', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => 'entra-tenant-id', 'consent_status' => 'granted', @@ -62,9 +62,9 @@ }); it('dedupes when the same operation is already active for the scope', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'consent_status' => 'granted', ]); ProviderCredential::factory()->create([ @@ -72,7 +72,7 @@ ]); $existing = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'running', 'context' => [ @@ -95,13 +95,13 @@ expect($dispatched)->toBe(0); expect($result->status)->toBe('deduped'); expect($result->run->getKey())->toBe($existing->getKey()); - expect(OperationRun::query()->where('tenant_id', $tenant->getKey())->count())->toBe(1); + expect(OperationRun::query()->where('managed_environment_id', $tenant->getKey())->count())->toBe(1); }); it('blocks when a different operation is already active for the scope', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'consent_status' => 'granted', ]); ProviderCredential::factory()->create([ @@ -109,7 +109,7 @@ ]); $blocking = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'inventory.sync', 'status' => 'queued', 'context' => [ @@ -132,11 +132,11 @@ expect($dispatched)->toBe(0); expect($result->status)->toBe('scope_busy'); expect($result->run->getKey())->toBe($blocking->getKey()); - expect(OperationRun::query()->where('tenant_id', $tenant->getKey())->count())->toBe(1); + expect(OperationRun::query()->where('managed_environment_id', $tenant->getKey())->count())->toBe(1); }); it('returns blocked and stores reason metadata when no default connection exists', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $dispatched = 0; $gate = app(ProviderOperationStartGate::class); @@ -162,9 +162,9 @@ }); it('starts restore execution with explicit provider connection binding and operation capability metadata', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => 'restore-entra-tenant-id', 'consent_status' => 'granted', @@ -204,9 +204,9 @@ }); it('starts directory group sync with explicit provider connection binding and sync capability metadata', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => 'directory-entra-tenant-id', 'consent_status' => 'granted', @@ -246,9 +246,9 @@ }); it('treats onboarding bootstrap provider starts as one protected scope', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'consent_status' => 'granted', ]); ProviderCredential::factory()->create([ @@ -256,7 +256,7 @@ ]); $blocking = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'inventory.sync', 'status' => 'running', 'context' => [ @@ -282,9 +282,9 @@ }); it('rejects legacy aliases before starting provider operations', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => 'directory-entra-tenant-id', 'consent_status' => 'granted', @@ -304,9 +304,9 @@ }); it('blocks provider starts when no explicit provider binding supports the connection provider', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'provider' => 'contoso', 'entra_tenant_id' => 'contoso-tenant-id', 'consent_status' => 'granted', diff --git a/apps/platform/tests/Unit/Providers/ProviderOperationStartResultPresenterTest.php b/apps/platform/tests/Unit/Providers/ProviderOperationStartResultPresenterTest.php index 5e85335f..4788f45c 100644 --- a/apps/platform/tests/Unit/Providers/ProviderOperationStartResultPresenterTest.php +++ b/apps/platform/tests/Unit/Providers/ProviderOperationStartResultPresenterTest.php @@ -1,7 +1,7 @@ create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'queued', 'context' => [ @@ -51,9 +51,9 @@ }); it('builds already-running notifications for deduped provider-backed starts', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'running', 'context' => [ @@ -74,9 +74,9 @@ }); it('builds scope-busy notifications for conflicting provider-backed starts', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'inventory_sync', 'status' => 'running', 'context' => [ @@ -97,7 +97,7 @@ }); it('builds blocked notifications from translated reason detail and first next step', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $reasonEnvelope = new ReasonResolutionEnvelope( internalCode: 'provider_consent_missing', operatorLabel: 'Admin consent required', @@ -109,7 +109,7 @@ ], ); $run = OperationRun::factory()->create([ - 'tenant_id' => $tenant->getKey(), + 'managed_environment_id' => $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'blocked', diff --git a/apps/platform/tests/Unit/RbacOnboardingServiceTest.php b/apps/platform/tests/Unit/RbacOnboardingServiceTest.php index d9d3c3be..919d9c73 100644 --- a/apps/platform/tests/Unit/RbacOnboardingServiceTest.php +++ b/apps/platform/tests/Unit/RbacOnboardingServiceTest.php @@ -2,7 +2,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Intune\RbacOnboardingService; @@ -13,22 +13,22 @@ config()->set('tenantpilot.features.conditional_access', false); }); -function fakeTenant(): Tenant +function fakeTenant(): ManagedEnvironment { - $tenant = Tenant::create([ - 'tenant_id' => '00000000-0000-0000-0000-000000000000', - 'name' => 'Tenant One', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => '00000000-0000-0000-0000-000000000000', + 'name' => 'ManagedEnvironment One', 'app_client_id' => null, 'app_client_secret' => null, 'is_current' => true, ]); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ]); ProviderCredential::factory()->create([ diff --git a/apps/platform/tests/Unit/RequiredPermissionsLinksTest.php b/apps/platform/tests/Unit/RequiredPermissionsLinksTest.php index f7ecf661..d82354bc 100644 --- a/apps/platform/tests/Unit/RequiredPermissionsLinksTest.php +++ b/apps/platform/tests/Unit/RequiredPermissionsLinksTest.php @@ -1,10 +1,10 @@ make([ + $tenant = ManagedEnvironment::factory()->make([ 'external_id' => 'tenant-123', ]); @@ -13,7 +13,7 @@ }); it('builds a tenant-scoped required permissions link with filters', function (): void { - $tenant = Tenant::factory()->make([ + $tenant = ManagedEnvironment::factory()->make([ 'external_id' => 'tenant 123', ]); diff --git a/apps/platform/tests/Unit/RestoreRunDeletableTest.php b/apps/platform/tests/Unit/RestoreRunDeletableTest.php index fe91521d..1726604c 100644 --- a/apps/platform/tests/Unit/RestoreRunDeletableTest.php +++ b/apps/platform/tests/Unit/RestoreRunDeletableTest.php @@ -2,15 +2,15 @@ use App\Models\BackupSet; use App\Models\RestoreRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); test('deletable scope includes only finished statuses', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, @@ -29,7 +29,7 @@ foreach ($statuses as $status) { RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => $status, 'is_dry_run' => true, @@ -56,17 +56,17 @@ }); test('isDeletable accepts partial even if status casing/format differs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $backupSet = BackupSet::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 0, ]); $partial = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'Partial', 'is_dry_run' => true, @@ -74,7 +74,7 @@ ]); $completedWithErrors = RestoreRun::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed-with-errors', 'is_dry_run' => true, diff --git a/apps/platform/tests/Unit/ScopeTagResolverTest.php b/apps/platform/tests/Unit/ScopeTagResolverTest.php index 55a70298..957ecbd0 100644 --- a/apps/platform/tests/Unit/ScopeTagResolverTest.php +++ b/apps/platform/tests/Unit/ScopeTagResolverTest.php @@ -2,7 +2,7 @@ use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Graph\GraphClientInterface; use App\Services\Graph\GraphResponse; use App\Services\Graph\ScopeTagResolver; @@ -18,9 +18,9 @@ }); test('resolves scope tag IDs to objects with id and displayName', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', @@ -66,9 +66,9 @@ }); test('caches scope tag objects for 1 hour', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', @@ -100,7 +100,7 @@ }); test('returns empty array for empty input', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $graph = Mockery::mock(GraphClientInterface::class); $gateway = app()->make(ProviderGateway::class, ['graph' => $graph]); @@ -112,9 +112,9 @@ }); test('handles 403 forbidden gracefully', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', @@ -141,9 +141,9 @@ }); test('filters returned scope tags to requested IDs', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'consent_status' => 'granted', diff --git a/apps/platform/tests/Unit/SettingsFoundation/SettingsResolverCacheTest.php b/apps/platform/tests/Unit/SettingsFoundation/SettingsResolverCacheTest.php index 52bc7495..751598e4 100644 --- a/apps/platform/tests/Unit/SettingsFoundation/SettingsResolverCacheTest.php +++ b/apps/platform/tests/Unit/SettingsFoundation/SettingsResolverCacheTest.php @@ -39,7 +39,7 @@ it('resolves tenant override from cache without repeated database reads', function (): void { $workspace = Workspace::factory()->create(); - $tenant = \App\Models\Tenant::factory()->create([ + $tenant = \App\Models\ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -53,7 +53,7 @@ \App\Models\TenantSetting::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'domain' => 'backup', 'key' => 'retention_keep_last_default', 'value' => 12, diff --git a/apps/platform/tests/Unit/SettingsFoundation/SettingsResolverTenantPrecedenceTest.php b/apps/platform/tests/Unit/SettingsFoundation/SettingsResolverTenantPrecedenceTest.php index 713b7c6b..e60d722d 100644 --- a/apps/platform/tests/Unit/SettingsFoundation/SettingsResolverTenantPrecedenceTest.php +++ b/apps/platform/tests/Unit/SettingsFoundation/SettingsResolverTenantPrecedenceTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantSetting; use App\Models\Workspace; use App\Models\WorkspaceSetting; @@ -13,7 +13,7 @@ it('resolves setting values in tenant -> workspace -> system default order', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -37,7 +37,7 @@ TenantSetting::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'domain' => 'backup', 'key' => 'retention_keep_last_default', 'value' => 9, diff --git a/apps/platform/tests/Unit/Support/Ai/AiApprovedSourceInputsTest.php b/apps/platform/tests/Unit/Support/Ai/AiApprovedSourceInputsTest.php index e6874180..59d1ede7 100644 --- a/apps/platform/tests/Unit/Support/Ai/AiApprovedSourceInputsTest.php +++ b/apps/platform/tests/Unit/Support/Ai/AiApprovedSourceInputsTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Ai\AiDataClassification; use App\Support\ProductKnowledge\ContextualHelpResolver; @@ -24,12 +24,12 @@ ]) ->and($source['topics'])->not->toBeEmpty() ->and($source['operational_metadata'])->toHaveKeys(['version', 'topic_count']) - ->and($source)->not->toHaveKeys(['tenant', 'tenant_id', 'workspace', 'workspace_id']); + ->and($source)->not->toHaveKeys(['tenant', 'managed_environment_id', 'workspace', 'workspace_id']); }); it('exposes only the approved redacted support summary input for ai diagnostic drafts', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); diff --git a/apps/platform/tests/Unit/Support/Ai/AiDecisionAuditMetadataTest.php b/apps/platform/tests/Unit/Support/Ai/AiDecisionAuditMetadataTest.php index 8a4401a8..9ae77cdc 100644 --- a/apps/platform/tests/Unit/Support/Ai/AiDecisionAuditMetadataTest.php +++ b/apps/platform/tests/Unit/Support/Ai/AiDecisionAuditMetadataTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\Ai\AiDataClassification; use App\Support\Ai\AiDecisionAuditMetadataFactory; @@ -17,7 +17,7 @@ it('builds bounded decision metadata without raw prompt, source, provider, or output payloads', function (): void { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->create(['workspace_id' => (int) $workspace->getKey()]); + $tenant = ManagedEnvironment::factory()->create(['workspace_id' => (int) $workspace->getKey()]); $request = new AiExecutionRequest( workspace: $workspace, @@ -55,7 +55,7 @@ 'data_classifications' => ['redacted_support_summary'], 'source_family' => 'support_diagnostics', 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'context_fingerprint' => 'support_diagnostics:summary:v1', ]) ->and($metadata)->not->toHaveKeys([ diff --git a/apps/platform/tests/Unit/Support/Ai/GovernedAiExecutionBoundaryTest.php b/apps/platform/tests/Unit/Support/Ai/GovernedAiExecutionBoundaryTest.php index e8340c6b..ecf204df 100644 --- a/apps/platform/tests/Unit/Support/Ai/GovernedAiExecutionBoundaryTest.php +++ b/apps/platform/tests/Unit/Support/Ai/GovernedAiExecutionBoundaryTest.php @@ -4,7 +4,7 @@ use App\Models\AuditLog; use App\Models\OperationalControlActivation; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -46,7 +46,7 @@ function aiPolicyWorkspace(string $policyMode = 'private_only'): array it('allows approved local-private support-diagnostics requests and writes bounded audit metadata', function (): void { [$workspace, $user] = aiPolicyWorkspace(); - $tenant = Tenant::factory()->create(['workspace_id' => (int) $workspace->getKey()]); + $tenant = ManagedEnvironment::factory()->create(['workspace_id' => (int) $workspace->getKey()]); $decision = assertNoOutboundHttp(fn () => app(GovernedAiExecutionBoundary::class)->evaluate(new AiExecutionRequest( workspace: $workspace, @@ -70,7 +70,7 @@ function aiPolicyWorkspace(string $policyMode = 'private_only'): array expect($audit)->not->toBeNull() ->and($audit?->action)->toBe(AuditActionId::AiExecutionDecisionEvaluated->value) ->and($audit?->workspace_id)->toBe((int) $workspace->getKey()) - ->and($audit?->tenant_id)->toBe((int) $tenant->getKey()) + ->and($audit?->managed_environment_id)->toBe((int) $tenant->getKey()) ->and(data_get($audit?->metadata, 'decision_outcome'))->toBe('allowed') ->and(data_get($audit?->metadata, 'decision_reason'))->toBe(AiDecisionReasonCode::Allowed->value) ->and(data_get($audit?->metadata, 'use_case_key'))->toBe('support_diagnostics.summary_draft') @@ -106,7 +106,7 @@ function aiPolicyWorkspace(string $policyMode = 'private_only'): array it('blocks disallowed data classifications before any provider resolution', function (): void { [$workspace, $user] = aiPolicyWorkspace(); - $tenant = Tenant::factory()->create(['workspace_id' => (int) $workspace->getKey()]); + $tenant = ManagedEnvironment::factory()->create(['workspace_id' => (int) $workspace->getKey()]); $decision = assertNoOutboundHttp(fn () => app(GovernedAiExecutionBoundary::class)->evaluate(new AiExecutionRequest( workspace: $workspace, diff --git a/apps/platform/tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php b/apps/platform/tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php index 399c78a8..495614b9 100644 --- a/apps/platform/tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php +++ b/apps/platform/tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php @@ -5,7 +5,7 @@ use App\Models\BackupItem; use App\Models\BackupSchedule; use App\Models\BackupSet; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\BackupHealth\BackupHealthActionTarget; use App\Support\BackupHealth\TenantBackupHealthAssessment; use App\Support\BackupHealth\TenantBackupHealthResolver; @@ -22,10 +22,10 @@ CarbonImmutable::setTestNow(); }); -function makeBackupHealthSchedule(Tenant $tenant, array $attributes = []): BackupSchedule +function makeBackupHealthSchedule(ManagedEnvironment $tenant, array $attributes = []): BackupSchedule { return BackupSchedule::query()->create(array_merge([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Backup health schedule', 'is_enabled' => true, 'timezone' => 'UTC', @@ -39,7 +39,7 @@ function makeBackupHealthSchedule(Tenant $tenant, array $attributes = []): Backu ], $attributes)); } -function resolveTenantBackupHealth(Tenant $tenant): TenantBackupHealthAssessment +function resolveTenantBackupHealth(ManagedEnvironment $tenant): TenantBackupHealthAssessment { return app(TenantBackupHealthResolver::class)->assess($tenant); } diff --git a/apps/platform/tests/Unit/Support/CanonicalNavigationContextTest.php b/apps/platform/tests/Unit/Support/CanonicalNavigationContextTest.php index 5e09b839..25501653 100644 --- a/apps/platform/tests/Unit/Support/CanonicalNavigationContextTest.php +++ b/apps/platform/tests/Unit/Support/CanonicalNavigationContextTest.php @@ -14,7 +14,7 @@ backLinkUrl: '/admin/findings/12', filterPayload: [ 'tableFilters' => [ - 'tenant_id' => ['value' => '44'], + 'managed_environment_id' => ['value' => '44'], ], ], ); @@ -22,12 +22,12 @@ expect($context->toQuery()) ->toMatchArray([ 'tableFilters' => [ - 'tenant_id' => ['value' => '44'], + 'managed_environment_id' => ['value' => '44'], ], 'nav' => [ 'source_surface' => 'finding.detail_section', 'canonical_route_name' => 'admin.operations.view', - 'tenant_id' => 44, + 'managed_environment_id' => 44, 'back_label' => 'Back to finding', 'back_url' => '/admin/findings/12', ], @@ -39,7 +39,7 @@ 'nav' => [ 'source_surface' => 'backup_set.detail_section', 'canonical_route_name' => 'admin.operations.view', - 'tenant_id' => 22, + 'managed_environment_id' => 22, 'back_label' => 'Back to backup set', 'back_url' => '/admin/backup-sets/8', ], @@ -58,7 +58,7 @@ canonicalRouteName: 'filament.admin.pages.governance.inbox', tenantId: 12, familyKey: 'finding_exceptions', - backLinkUrl: '/admin/governance/inbox?tenant_id=12&family=finding_exceptions', + backLinkUrl: '/admin/governance/inbox?managed_environment_id=12&family=finding_exceptions', ); $roundTrip = CanonicalNavigationContext::fromRequest(Request::create('/admin/finding-exceptions/queue', 'GET', $context->toQuery())); @@ -66,12 +66,12 @@ expect($context->toQuery()['nav']) ->toMatchArray([ 'source_surface' => 'governance.inbox', - 'tenant_id' => 12, + 'managed_environment_id' => 12, 'family_key' => 'finding_exceptions', 'back_label' => 'Back to governance inbox', ]) ->and($roundTrip?->sourceSurface)->toBe('governance.inbox') ->and($roundTrip?->tenantId)->toBe(12) ->and($roundTrip?->familyKey)->toBe('finding_exceptions') - ->and($roundTrip?->backLinkUrl)->toBe('/admin/governance/inbox?tenant_id=12&family=finding_exceptions'); + ->and($roundTrip?->backLinkUrl)->toBe('/admin/governance/inbox?managed_environment_id=12&family=finding_exceptions'); }); diff --git a/apps/platform/tests/Unit/Support/CreateUserWithTenantProfilesTest.php b/apps/platform/tests/Unit/Support/CreateUserWithTenantProfilesTest.php index a0da3769..48a8f1d4 100644 --- a/apps/platform/tests/Unit/Support/CreateUserWithTenantProfilesTest.php +++ b/apps/platform/tests/Unit/Support/CreateUserWithTenantProfilesTest.php @@ -34,7 +34,7 @@ ->where('user_id', (int) $user->getKey()) ->exists())->toBeTrue() ->and(session(WorkspaceContext::SESSION_KEY))->toBe((int) $tenant->workspace_id) - ->and(ProviderConnection::query()->where('tenant_id', (int) $tenant->getKey())->exists())->toBeFalse(); + ->and(ProviderConnection::query()->where('managed_environment_id', (int) $tenant->getKey())->exists())->toBeFalse(); }); it('opt-ins a standard provider context only when the canonical standard profile asks for it', function (): void { @@ -50,7 +50,7 @@ [, $tenant] = createStandardUserWithTenant(); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('is_default', true) ->first(); @@ -72,7 +72,7 @@ [, $tenant] = createCredentialEnabledUserWithTenant(); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('is_default', true) ->first(); @@ -94,7 +94,7 @@ [, $tenant] = createUiContextUserWithTenant(); - expect(ProviderConnection::query()->where('tenant_id', (int) $tenant->getKey())->exists())->toBeFalse() + expect(ProviderConnection::query()->where('managed_environment_id', (int) $tenant->getKey())->exists())->toBeFalse() ->and(Filament::getTenant()?->is($tenant))->toBeTrue(); }); @@ -111,7 +111,7 @@ [, $tenant] = createFullUserWithTenant(); $connection = ProviderConnection::query() - ->where('tenant_id', (int) $tenant->getKey()) + ->where('managed_environment_id', (int) $tenant->getKey()) ->where('is_default', true) ->first(); diff --git a/apps/platform/tests/Unit/Support/CustomerHealth/WorkspaceHealthSummaryQueryTest.php b/apps/platform/tests/Unit/Support/CustomerHealth/WorkspaceHealthSummaryQueryTest.php index b02d4f62..db91ff2b 100644 --- a/apps/platform/tests/Unit/Support/CustomerHealth/WorkspaceHealthSummaryQueryTest.php +++ b/apps/platform/tests/Unit/Support/CustomerHealth/WorkspaceHealthSummaryQueryTest.php @@ -8,7 +8,7 @@ use App\Models\ProviderConnection; use App\Models\ReviewPack; use App\Models\Finding; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantOnboardingSession; use App\Models\Workspace; use App\Support\CustomerHealth\CustomerHealthDimensionCatalog; @@ -38,9 +38,9 @@ it('derives workspace health from existing onboarding, provider, and telemetry truth', function (): void { $workspace = Workspace::factory()->create(['name' => 'Acme']); - $tenant = Tenant::factory()->for($workspace)->create([ + $tenant = ManagedEnvironment::factory()->for($workspace)->create([ 'name' => 'Acme Production', - 'status' => Tenant::STATUS_ACTIVE, + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); ProviderConnection::factory() @@ -125,9 +125,9 @@ it('uses the selected window for operations and engagement freshness', function (): void { $workspace = Workspace::factory()->create(['name' => 'Windowed Signals']); - $tenant = Tenant::factory()->for($workspace)->create([ - 'status' => Tenant::STATUS_ACTIVE, - 'name' => 'Windowed Tenant', + $tenant = ManagedEnvironment::factory()->for($workspace)->create([ + 'status' => ManagedEnvironment::STATUS_ACTIVE, + 'name' => 'Windowed ManagedEnvironment', ]); ProviderConnection::factory() @@ -165,9 +165,9 @@ it('keeps governance pressure explicit until governance truth exists', function (): void { $workspace = Workspace::factory()->create(['name' => 'Governance Signals']); - $tenant = Tenant::factory()->for($workspace)->create([ - 'status' => Tenant::STATUS_ACTIVE, - 'name' => 'Governance Tenant', + $tenant = ManagedEnvironment::factory()->for($workspace)->create([ + 'status' => ManagedEnvironment::STATUS_ACTIVE, + 'name' => 'Governance ManagedEnvironment', ]); ProviderConnection::factory() @@ -229,8 +229,8 @@ 'archived_at' => now()->subDay(), ]); - $archivedWorkspaceTenant = Tenant::factory()->for($archivedWorkspace)->create([ - 'status' => Tenant::STATUS_ACTIVE, + $archivedWorkspaceTenant = ManagedEnvironment::factory()->for($archivedWorkspace)->create([ + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); ProductUsageEvent::factory() @@ -241,14 +241,14 @@ ]); $workspace = Workspace::factory()->create(['name' => 'Mixed Workspace']); - $activeTenant = Tenant::factory()->for($workspace)->create([ - 'status' => Tenant::STATUS_ACTIVE, - 'name' => 'Active Tenant', + $activeTenant = ManagedEnvironment::factory()->for($workspace)->create([ + 'status' => ManagedEnvironment::STATUS_ACTIVE, + 'name' => 'Active ManagedEnvironment', ]); - $archivedTenant = Tenant::factory()->for($workspace)->create([ - 'status' => Tenant::STATUS_ARCHIVED, - 'name' => 'Archived Tenant', + $archivedTenant = ManagedEnvironment::factory()->for($workspace)->create([ + 'status' => ManagedEnvironment::STATUS_ARCHIVED, + 'name' => 'Archived ManagedEnvironment', 'deleted_at' => now()->subDay(), ]); @@ -291,9 +291,9 @@ $this->actingAs($platformUser, 'platform'); $criticalWorkspace = Workspace::factory()->create(['name' => 'Critical Workspace']); - $criticalTenant = Tenant::factory()->for($criticalWorkspace)->create([ - 'status' => Tenant::STATUS_ACTIVE, - 'name' => 'Critical Tenant', + $criticalTenant = ManagedEnvironment::factory()->for($criticalWorkspace)->create([ + 'status' => ManagedEnvironment::STATUS_ACTIVE, + 'name' => 'Critical ManagedEnvironment', ]); ProviderConnection::factory() @@ -315,9 +315,9 @@ ]); $warnWorkspace = Workspace::factory()->create(['name' => 'Warn Workspace']); - $warnTenant = Tenant::factory()->for($warnWorkspace)->create([ - 'status' => Tenant::STATUS_ACTIVE, - 'name' => 'Warn Tenant', + $warnTenant = ManagedEnvironment::factory()->for($warnWorkspace)->create([ + 'status' => ManagedEnvironment::STATUS_ACTIVE, + 'name' => 'Warn ManagedEnvironment', ]); ProviderConnection::factory() @@ -360,14 +360,14 @@ }); /** - * @return array{workspace: Workspace, tenant: Tenant} + * @return array{workspace: Workspace, tenant: ManagedEnvironment} */ function createWorkspaceWithActiveTenant(string $workspaceName): array { $workspace = Workspace::factory()->create(['name' => $workspaceName]); - $tenant = Tenant::factory()->for($workspace)->create([ - 'name' => $workspaceName.' Tenant', - 'status' => Tenant::STATUS_ACTIVE, + $tenant = ManagedEnvironment::factory()->for($workspace)->create([ + 'name' => $workspaceName.' ManagedEnvironment', + 'status' => ManagedEnvironment::STATUS_ACTIVE, ]); ProviderConnection::factory() diff --git a/apps/platform/tests/Unit/Support/GovernanceArtifactTruth/GovernanceArtifactLifecycleContractTest.php b/apps/platform/tests/Unit/Support/GovernanceArtifactTruth/GovernanceArtifactLifecycleContractTest.php index eaad75c2..38849d44 100644 --- a/apps/platform/tests/Unit/Support/GovernanceArtifactTruth/GovernanceArtifactLifecycleContractTest.php +++ b/apps/platform/tests/Unit/Support/GovernanceArtifactTruth/GovernanceArtifactLifecycleContractTest.php @@ -7,7 +7,7 @@ use App\Models\FindingExceptionDecision; use App\Models\ReviewPack; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\ReviewPackStatus; use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -18,7 +18,7 @@ [$user, $tenant] = createUserWithTenant(role: 'owner'); $historical = StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'fingerprint' => 'permission-posture-v1', @@ -27,7 +27,7 @@ ]); $current = StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'fingerprint' => 'permission-posture-v2', @@ -63,7 +63,7 @@ $finding = Finding::factory()->for($tenant)->create(); $exception = FindingException::query()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), @@ -80,7 +80,7 @@ ]); $requestedDecision = $exception->decisions()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'actor_user_id' => (int) $user->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_REQUESTED, @@ -90,7 +90,7 @@ ]); $approvedDecision = $exception->decisions()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'actor_user_id' => (int) $user->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_APPROVED, @@ -123,11 +123,11 @@ }); it('keeps expired direct access separate from historical lifecycle on review packs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $pack = ReviewPack::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'status' => ReviewPackStatus::Expired->value, diff --git a/apps/platform/tests/Unit/Support/GovernanceDecisions/GovernanceDecisionRegisterBuilderTest.php b/apps/platform/tests/Unit/Support/GovernanceDecisions/GovernanceDecisionRegisterBuilderTest.php index 49c83d82..5e3886a7 100644 --- a/apps/platform/tests/Unit/Support/GovernanceDecisions/GovernanceDecisionRegisterBuilderTest.php +++ b/apps/platform/tests/Unit/Support/GovernanceDecisions/GovernanceDecisionRegisterBuilderTest.php @@ -5,7 +5,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\FindingExceptionDecision; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\GovernanceDecisions\GovernanceDecisionRegisterBuilder; @@ -18,14 +18,14 @@ $owner = User::factory()->create(['name' => 'Decision Owner']); $approver = User::factory()->create(['name' => 'Decision Approver']); - $visibleTenant = Tenant::factory()->create([ + $visibleTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Visible Tenant', + 'name' => 'Visible ManagedEnvironment', 'external_id' => 'visible-tenant', ]); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Hidden Tenant', + 'name' => 'Hidden ManagedEnvironment', 'external_id' => 'hidden-tenant', ]); @@ -137,7 +137,7 @@ (int) $pendingApproval->getKey(), (int) $followUpNeeded->getKey(), ]) - ->and($openRows[(int) $pendingApproval->getKey()]['tenant_name'])->toBe('Visible Tenant') + ->and($openRows[(int) $pendingApproval->getKey()]['tenant_name'])->toBe('Visible ManagedEnvironment') ->and($openRows[(int) $pendingApproval->getKey()]['owner_name'])->toBe('Decision Owner') ->and($openRows[(int) $pendingApproval->getKey()]['next_action_label'])->toBe('Review approval') ->and($openRows[(int) $followUpNeeded->getKey()]['next_action_label'])->toBe('Review follow-up'); @@ -162,7 +162,7 @@ it('keeps missing owner visible instead of omitting follow-up-needed rows', function (): void { $workspace = Workspace::factory()->create(); $requester = User::factory()->create(); - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); @@ -205,7 +205,7 @@ * @param array $decisionAttributes */ function makeFindingExceptionWithCurrentDecision( - Tenant $tenant, + ManagedEnvironment $tenant, ?User $owner, User $actor, string $status, @@ -223,7 +223,7 @@ function makeFindingExceptionWithCurrentDecision( $exception = FindingException::query()->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => $requesterId, 'owner_user_id' => $owner?->getKey(), @@ -237,7 +237,7 @@ function makeFindingExceptionWithCurrentDecision( $decision = $exception->decisions()->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $actor->getKey(), 'decision_type' => $decisionType, 'reason' => $decisionReason, diff --git a/apps/platform/tests/Unit/Support/GovernanceInbox/GovernanceInboxSectionBuilderTest.php b/apps/platform/tests/Unit/Support/GovernanceInbox/GovernanceInboxSectionBuilderTest.php index c03db279..0be0f8cc 100644 --- a/apps/platform/tests/Unit/Support/GovernanceInbox/GovernanceInboxSectionBuilderTest.php +++ b/apps/platform/tests/Unit/Support/GovernanceInbox/GovernanceInboxSectionBuilderTest.php @@ -6,7 +6,7 @@ use App\Models\Finding; use App\Models\FindingException; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Models\User; use App\Models\Workspace; @@ -27,14 +27,14 @@ $workspace = Workspace::factory()->create(); $user = User::factory()->create(); - $alphaTenant = Tenant::factory()->create([ + $alphaTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); - $bravoTenant = Tenant::factory()->create([ + $bravoTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Bravo Tenant', + 'name' => 'Bravo ManagedEnvironment', 'external_id' => 'bravo-tenant', ]); @@ -65,7 +65,7 @@ FindingException::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $alphaTenant->getKey(), + 'managed_environment_id' => (int) $alphaTenant->getKey(), 'finding_id' => (int) $exceptionFinding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), @@ -95,7 +95,7 @@ ]); AlertDelivery::factory()->create([ - 'tenant_id' => null, + 'managed_environment_id' => null, 'workspace_id' => (int) $workspace->getKey(), 'status' => AlertDelivery::STATUS_FAILED, 'event_type' => 'alerts.failed_delivery', @@ -193,19 +193,19 @@ $workspace = Workspace::factory()->create(); $user = User::factory()->create(); - $alphaTenant = Tenant::factory()->create([ + $alphaTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Alpha Tenant', + 'name' => 'Alpha ManagedEnvironment', 'external_id' => 'alpha-tenant', ]); - $bravoTenant = Tenant::factory()->create([ + $bravoTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Bravo Tenant', + 'name' => 'Bravo ManagedEnvironment', 'external_id' => 'bravo-tenant', ]); AlertDelivery::factory()->create([ - 'tenant_id' => null, + 'managed_environment_id' => null, 'workspace_id' => (int) $workspace->getKey(), 'status' => AlertDelivery::STATUS_FAILED, ]); @@ -231,13 +231,13 @@ $workspace = Workspace::factory()->create(); $user = User::factory()->create(); - $visibleTenant = Tenant::factory()->create([ + $visibleTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Visible Tenant', + 'name' => 'Visible ManagedEnvironment', ]); - $hiddenTenant = Tenant::factory()->create([ + $hiddenTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'name' => 'Hidden Tenant', + 'name' => 'Hidden ManagedEnvironment', ]); $finding = Finding::factory() @@ -247,7 +247,7 @@ FindingException::query()->create([ 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $hiddenTenant->getKey(), + 'managed_environment_id' => (int) $hiddenTenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), diff --git a/apps/platform/tests/Unit/Support/Inventory/TenantCoverageTruthResolverTest.php b/apps/platform/tests/Unit/Support/Inventory/TenantCoverageTruthResolverTest.php index 1b2e6eb2..1d365f2a 100644 --- a/apps/platform/tests/Unit/Support/Inventory/TenantCoverageTruthResolverTest.php +++ b/apps/platform/tests/Unit/Support/Inventory/TenantCoverageTruthResolverTest.php @@ -4,7 +4,7 @@ use App\Models\InventoryItem; use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Inventory\TenantCoverageTruthResolver; use App\Support\Inventory\TenantCoverageTypeTruth; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -12,7 +12,7 @@ uses(RefreshDatabase::class); it('selects the latest completed coverage-bearing inventory sync run for tenant truth', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $olderBasis = createInventorySyncOperationRunWithCoverage($tenant, [ 'deviceConfiguration' => ['status' => 'succeeded', 'item_count' => 1], @@ -47,20 +47,20 @@ }); it('derives per-type coverage truth, observed counts, and deterministic follow-up order', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); InventoryItem::factory()->count(3)->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceCompliancePolicy', ]); InventoryItem::factory()->count(2)->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'conditionalAccessPolicy', ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', ]); @@ -129,10 +129,10 @@ }); it('returns unknown coverage rows when no basis run exists', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', ]); diff --git a/apps/platform/tests/Unit/Support/OperateHub/OperateHubShellResolutionTest.php b/apps/platform/tests/Unit/Support/OperateHub/OperateHubShellResolutionTest.php index 68d4e2b7..bf8a5035 100644 --- a/apps/platform/tests/Unit/Support/OperateHub/OperateHubShellResolutionTest.php +++ b/apps/platform/tests/Unit/Support/OperateHub/OperateHubShellResolutionTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Support\OperateHub\OperateHubShell; use App\Support\Workspaces\WorkspaceContext; @@ -13,12 +13,12 @@ uses(RefreshDatabase::class); it('prefers a valid tenant query hint over remembered tenant state on workspace-scoped admin routes', function (): void { - $rememberedTenant = Tenant::factory()->active()->create(['name' => 'Remembered Tenant']); + $rememberedTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Remembered ManagedEnvironment']); [$user, $rememberedTenant] = createUserWithTenant(tenant: $rememberedTenant, role: 'owner'); - $hintedTenant = Tenant::factory()->active()->create([ + $hintedTenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $rememberedTenant->workspace_id, - 'name' => 'Hinted Tenant', + 'name' => 'Hinted ManagedEnvironment', ]); createUserWithTenant(tenant: $hintedTenant, user: $user, role: 'owner'); @@ -49,10 +49,10 @@ }); it('falls back to a tenantless workspace state when a tenant query hint targets another workspace', function (): void { - $workspaceTenant = Tenant::factory()->active()->create(['name' => 'Current Workspace Tenant']); + $workspaceTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Current Workspace ManagedEnvironment']); [$user, $workspaceTenant] = createUserWithTenant(tenant: $workspaceTenant, role: 'owner'); - $foreignTenant = Tenant::factory()->active()->create(['name' => 'Foreign Tenant']); + $foreignTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Foreign ManagedEnvironment']); createUserWithTenant(tenant: $foreignTenant, user: User::factory()->create(), role: 'owner'); $this->actingAs($user); @@ -78,7 +78,7 @@ }); it('uses the routed tenant workspace when the tenant panel is entered without a selected workspace session', function (): void { - $tenant = Tenant::factory()->active()->create(['name' => 'Tenant Panel Scope']); + $tenant = ManagedEnvironment::factory()->active()->create(['name' => 'ManagedEnvironment Panel Scope']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $this->actingAs($user); diff --git a/apps/platform/tests/Unit/Support/OperatorExplanation/OperationRunExplanationTest.php b/apps/platform/tests/Unit/Support/OperatorExplanation/OperationRunExplanationTest.php index ce0d353b..ff740ba3 100644 --- a/apps/platform/tests/Unit/Support/OperatorExplanation/OperationRunExplanationTest.php +++ b/apps/platform/tests/Unit/Support/OperatorExplanation/OperationRunExplanationTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OpsUx\OperationUxPresenter; use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -11,14 +11,14 @@ uses(RefreshDatabase::class, BuildsGovernanceArtifactTruthFixtures::class); it('reuses governance operator explanations for run failure detail and next-step guidance', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = $this->makeArtifactTruthRun( tenant: $tenant, type: 'tenant.review.compose', context: [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'reason_code' => 'review_missing_sections', ], diff --git a/apps/platform/tests/Unit/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilderTest.php b/apps/platform/tests/Unit/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilderTest.php index bdc44ec3..b202dd1d 100644 --- a/apps/platform/tests/Unit/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilderTest.php +++ b/apps/platform/tests/Unit/Support/OpsUx/GovernanceRunDiagnosticSummaryBuilderTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\OperationRun; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OpsUx\GovernanceRunDiagnosticSummaryBuilder; use App\Support\OpsUx\SummaryCountsNormalizer; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -12,10 +12,10 @@ uses(RefreshDatabase::class, BuildsGovernanceArtifactTruthFixtures::class); it('derives a blocked baseline capture summary with prerequisite-focused next steps', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_capture', 'status' => 'completed', @@ -47,10 +47,10 @@ }); it('derives an ambiguous baseline compare summary with affected scale and scope review guidance', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', @@ -86,7 +86,7 @@ }); it('keeps execution outcome separate from artifact impact for stale evidence snapshot runs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = $this->makeArtifactTruthRun($tenant, 'tenant.evidence.snapshot.generate'); @@ -108,10 +108,10 @@ }); it('derives resume capture or generation when a compare run records a resume token', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', @@ -135,7 +135,7 @@ }); it('keeps deterministic multi-cause ordering for degraded review composition runs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = $this->makeArtifactTruthRun($tenant, 'tenant.review.compose'); @@ -174,7 +174,7 @@ }); it('derives no further action for publishable review pack runs', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $run = $this->makeArtifactTruthRun($tenant, 'tenant.review_pack.generate'); @@ -203,10 +203,10 @@ }); it('does not invent new summary count keys while deriving scale cues', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $run = OperationRun::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'baseline_compare', 'status' => 'completed', diff --git a/apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantComparePreviewBuilderTest.php b/apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantComparePreviewBuilderTest.php index e764eee0..268a504a 100644 --- a/apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantComparePreviewBuilderTest.php +++ b/apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantComparePreviewBuilderTest.php @@ -5,7 +5,7 @@ use App\Models\InventoryItem; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\PortfolioCompare\CrossTenantComparePreviewBuilder; use App\Support\PortfolioCompare\CrossTenantCompareSelection; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -77,7 +77,7 @@ $fixture = crossTenantCompareFixture(); InventoryItem::factory()->create([ - 'tenant_id' => (int) $fixture['sourceTenant']->getKey(), + 'managed_environment_id' => (int) $fixture['sourceTenant']->getKey(), 'policy_type' => 'deviceConfiguration', 'display_name' => ' ', 'external_id' => 'source-without-identifier', @@ -131,12 +131,12 @@ }); /** - * @return array{sourceTenant: Tenant, targetTenant: Tenant} + * @return array{sourceTenant: ManagedEnvironment, targetTenant: ManagedEnvironment} */ function crossTenantCompareFixture(): array { - $sourceTenant = Tenant::factory()->create(); - $targetTenant = Tenant::factory()->create([ + $sourceTenant = ManagedEnvironment::factory()->create(); + $targetTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $sourceTenant->workspace_id, ]); @@ -151,14 +151,14 @@ function crossTenantCompareFixture(): array * @return array{policy: Policy, version: PolicyVersion, inventory: InventoryItem} */ function createComparedPolicy( - Tenant $tenant, + ManagedEnvironment $tenant, string $displayName, array $snapshot, string $policyType = 'deviceConfiguration', ?string $externalId = null, ): array { $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => $policyType, 'external_id' => $externalId ?? str($displayName)->slug()->append('-')->append((string) str()->uuid())->toString(), 'display_name' => $displayName, @@ -166,7 +166,7 @@ function createComparedPolicy( ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => $policyType, 'platform' => 'windows', @@ -177,7 +177,7 @@ function createComparedPolicy( ]); $inventory = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => $policyType, 'external_id' => (string) $policy->external_id, 'display_name' => $displayName, diff --git a/apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantPromotionPreflightTest.php b/apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantPromotionPreflightTest.php index bb19d1f2..83396e00 100644 --- a/apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantPromotionPreflightTest.php +++ b/apps/platform/tests/Unit/Support/PortfolioCompare/CrossTenantPromotionPreflightTest.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\Policy; use App\Models\PolicyVersion; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\PortfolioCompare\CrossTenantComparePreviewBuilder; use App\Support\PortfolioCompare\CrossTenantCompareSelection; use App\Support\PortfolioCompare\CrossTenantPromotionPreflight; @@ -64,21 +64,21 @@ ); InventoryItem::factory()->create([ - 'tenant_id' => (int) $fixture['sourceTenant']->getKey(), + 'managed_environment_id' => (int) $fixture['sourceTenant']->getKey(), 'policy_type' => 'deviceConfiguration', 'display_name' => ' ', 'external_id' => 'missing-source-identifier', ]); Policy::factory()->create([ - 'tenant_id' => (int) $fixture['sourceTenant']->getKey(), + 'managed_environment_id' => (int) $fixture['sourceTenant']->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'meta-only-source', 'display_name' => 'Refresh Required Policy', 'platform' => 'windows', ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $fixture['sourceTenant']->getKey(), + 'managed_environment_id' => (int) $fixture['sourceTenant']->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'meta-only-source', 'display_name' => 'Refresh Required Policy', @@ -86,14 +86,14 @@ ]); Policy::factory()->create([ - 'tenant_id' => (int) $fixture['targetTenant']->getKey(), + 'managed_environment_id' => (int) $fixture['targetTenant']->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'meta-only-target', 'display_name' => 'Refresh Required Policy', 'platform' => 'windows', ]); InventoryItem::factory()->create([ - 'tenant_id' => (int) $fixture['targetTenant']->getKey(), + 'managed_environment_id' => (int) $fixture['targetTenant']->getKey(), 'policy_type' => 'deviceConfiguration', 'external_id' => 'meta-only-target', 'display_name' => 'Refresh Required Policy', @@ -166,12 +166,12 @@ }); /** - * @return array{sourceTenant: Tenant, targetTenant: Tenant} + * @return array{sourceTenant: ManagedEnvironment, targetTenant: ManagedEnvironment} */ function crossTenantPromotionFixture(): array { - $sourceTenant = Tenant::factory()->create(); - $targetTenant = Tenant::factory()->create([ + $sourceTenant = ManagedEnvironment::factory()->create(); + $targetTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $sourceTenant->workspace_id, ]); @@ -186,14 +186,14 @@ function crossTenantPromotionFixture(): array * @return array{policy: Policy, version: PolicyVersion, inventory: InventoryItem} */ function createPromotionSubject( - Tenant $tenant, + ManagedEnvironment $tenant, string $displayName, array $snapshot, string $policyType = 'deviceConfiguration', ?string $externalId = null, ): array { $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => $policyType, 'external_id' => $externalId ?? str($displayName)->slug()->append('-')->append((string) str()->uuid())->toString(), 'display_name' => $displayName, @@ -201,7 +201,7 @@ function createPromotionSubject( ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'policy_type' => $policyType, 'platform' => 'windows', @@ -212,7 +212,7 @@ function createPromotionSubject( ]); $inventory = InventoryItem::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_type' => $policyType, 'external_id' => (string) $policy->external_id, 'display_name' => $displayName, diff --git a/apps/platform/tests/Unit/Support/PortfolioTriage/PortfolioArrivalContextResolverTest.php b/apps/platform/tests/Unit/Support/PortfolioTriage/PortfolioArrivalContextResolverTest.php index 9011d849..fa69a93f 100644 --- a/apps/platform/tests/Unit/Support/PortfolioTriage/PortfolioArrivalContextResolverTest.php +++ b/apps/platform/tests/Unit/Support/PortfolioTriage/PortfolioArrivalContextResolverTest.php @@ -29,7 +29,7 @@ function portfolioArrivalRequest(array $query, int $workspaceId): Request } it('resolves a workspace-bound backup arrival context into the dashboard follow-up contract', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Absent Backup Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Absent Backup ManagedEnvironment'); $this->actingAs($user); $request = portfolioArrivalRequest([ @@ -57,7 +57,7 @@ function portfolioArrivalRequest(array $query, int $workspaceId): Request }); it('returns null when the arrival token is bound to another tenant or workspace', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Bound Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Bound ManagedEnvironment'); $this->actingAs($user); $wrongTenantRequest = portfolioArrivalRequest([ @@ -87,7 +87,7 @@ function portfolioArrivalRequest(array $query, int $workspaceId): Request }); it('sanitizes tenant-registry return targets back to allowlisted filters only', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Registry Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Registry ManagedEnvironment'); $this->actingAs($user); $request = portfolioArrivalRequest([ @@ -107,7 +107,7 @@ function portfolioArrivalRequest(array $query, int $workspaceId): Request TenantRecoveryTriagePresentation::RECOVERY_EVIDENCE_UNVALIDATED, ], 'triage_sort' => TenantRecoveryTriagePresentation::TRIAGE_SORT_WORST_FIRST, - 'leak' => ['tenant_id' => 999], + 'leak' => ['managed_environment_id' => 999], ], ]), ], (int) $tenant->workspace_id); @@ -123,7 +123,7 @@ function portfolioArrivalRequest(array $query, int $workspaceId): Request }); it('degrades the next step truthfully when the operator cannot open deeper follow-up surfaces', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Restricted Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Restricted ManagedEnvironment'); $this->actingAs($user); mock(\App\Services\Auth\CapabilityResolver::class, function ($mock) use ($tenant): void { @@ -155,7 +155,7 @@ function portfolioArrivalRequest(array $query, int $workspaceId): Request }); it('maps weakened recovery arrivals to restore-run detail and explains when current truth has changed', function (): void { - [$user, $tenant] = $this->makePortfolioTriageActor('Recovery Tenant'); + [$user, $tenant] = $this->makePortfolioTriageActor('Recovery ManagedEnvironment'); $this->actingAs($user); $backupSet = $this->seedPortfolioBackupConcern($tenant, TenantBackupHealthAssessment::POSTURE_HEALTHY); diff --git a/apps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewStateResolverTest.php b/apps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewStateResolverTest.php index 6a7706eb..64375cac 100644 --- a/apps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewStateResolverTest.php +++ b/apps/platform/tests/Unit/Support/PortfolioTriage/TenantTriageReviewStateResolverTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\TenantTriageReview; use App\Models\User; use App\Support\BackupHealth\BackupFreshnessEvaluation; @@ -47,16 +47,16 @@ function triageResolverBackupAssessment(int $tenantId, string $posture, ?string } it('resolves active review rows into current-set summaries', function (): void { - $firstTenant = Tenant::factory()->create(['status' => 'active']); + $firstTenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$reviewer, $firstTenant] = createUserWithTenant(tenant: $firstTenant, role: 'owner'); - $secondTenant = Tenant::factory()->create([ + $secondTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $firstTenant->workspace_id, ]); createUserWithTenant(tenant: $secondTenant, user: $reviewer, role: 'owner'); - $thirdTenant = Tenant::factory()->create([ + $thirdTenant = ManagedEnvironment::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $firstTenant->workspace_id, ]); @@ -118,7 +118,7 @@ function triageResolverBackupAssessment(int $tenantId, string $posture, ?string }); it('prefers changed-since-review when the current fingerprint no longer matches', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$reviewer, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); TenantTriageReview::factory() @@ -150,7 +150,7 @@ function triageResolverBackupAssessment(int $tenantId, string $posture, ?string }); it('excludes inactive concern families from the current affected set', function (): void { - $tenant = Tenant::factory()->create(['status' => 'active']); + $tenant = ManagedEnvironment::factory()->create(['status' => 'active']); [$reviewer, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); TenantTriageReview::factory() diff --git a/apps/platform/tests/Unit/Support/ProductKnowledge/ContextualHelpFallbackTest.php b/apps/platform/tests/Unit/Support/ProductKnowledge/ContextualHelpFallbackTest.php index a7a52b02..5fb9eebe 100644 --- a/apps/platform/tests/Unit/Support/ProductKnowledge/ContextualHelpFallbackTest.php +++ b/apps/platform/tests/Unit/Support/ProductKnowledge/ContextualHelpFallbackTest.php @@ -28,7 +28,7 @@ $knowledgeSource = app(ContextualHelpResolver::class)->knowledgeSource(); $encoded = json_encode($knowledgeSource, JSON_THROW_ON_ERROR); - expect($encoded)->not->toContain('tenant_id') + expect($encoded)->not->toContain('managed_environment_id') ->not->toContain('provider_connection_id') ->not->toContain('raw_response_body') ->not->toContain('credential') diff --git a/apps/platform/tests/Unit/Support/ProductKnowledge/ContextualHelpResolverTest.php b/apps/platform/tests/Unit/Support/ProductKnowledge/ContextualHelpResolverTest.php index 35b6e6d4..dd09def7 100644 --- a/apps/platform/tests/Unit/Support/ProductKnowledge/ContextualHelpResolverTest.php +++ b/apps/platform/tests/Unit/Support/ProductKnowledge/ContextualHelpResolverTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Links\RequiredPermissionsLinks; use App\Support\OperationRunOutcome; use App\Support\ProductKnowledge\ContextualHelpCatalog; @@ -13,7 +13,7 @@ uses(RefreshDatabase::class); -function contextualHelpTruthEnvelope(Tenant $tenant): ArtifactTruthEnvelope +function contextualHelpTruthEnvelope(ManagedEnvironment $tenant): ArtifactTruthEnvelope { return new ArtifactTruthEnvelope( artifactFamily: 'support_diagnostics', diff --git a/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetryRecorderTest.php b/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetryRecorderTest.php index 2ac6efcb..601f281c 100644 --- a/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetryRecorderTest.php +++ b/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetryRecorderTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\ProductTelemetry\ProductTelemetryRecorder; @@ -13,7 +13,7 @@ it('records a tenant-owned usage event with the catalog feature area', function () { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->for($workspace)->create(); + $tenant = ManagedEnvironment::factory()->for($workspace)->create(); $user = User::factory()->create(); $event = app(ProductTelemetryRecorder::class)->record( @@ -32,7 +32,7 @@ expect($event->event_name)->toBe(ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED) ->and($event->feature_area)->toBe('onboarding') ->and($event->workspace_id)->toBe((int) $workspace->getKey()) - ->and($event->tenant_id)->toBe((int) $tenant->getKey()) + ->and($event->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($event->user_id)->toBe((int) $user->getKey()) ->and($event->subject_type)->toBe('tenant_onboarding_session') ->and($event->subject_id)->toBe('42') @@ -44,7 +44,7 @@ $this->assertDatabaseHas('product_usage_events', [ 'id' => (int) $event->getKey(), 'workspace_id' => (int) $workspace->getKey(), - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'event_name' => ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED, 'feature_area' => 'onboarding', @@ -55,7 +55,7 @@ it('records a tenant-owned usage event for an archived tenant', function () { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->for($workspace)->archived()->create(); + $tenant = ManagedEnvironment::factory()->for($workspace)->archived()->create(); $user = User::factory()->create(); $event = app(ProductTelemetryRecorder::class)->record( @@ -72,13 +72,13 @@ ); expect($event->workspace_id)->toBe((int) $workspace->getKey()) - ->and($event->tenant_id)->toBe((int) $tenant->getKey()) + ->and($event->managed_environment_id)->toBe((int) $tenant->getKey()) ->and($event->feature_area)->toBe('onboarding'); }); it('rejects unknown event names before writing telemetry rows', function () { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->for($workspace)->create(); + $tenant = ManagedEnvironment::factory()->for($workspace)->create(); $user = User::factory()->create(); expect(fn () => app(ProductTelemetryRecorder::class)->record( diff --git a/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetrySafeMetadataTest.php b/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetrySafeMetadataTest.php index 18f13175..f819a636 100644 --- a/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetrySafeMetadataTest.php +++ b/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetrySafeMetadataTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\ProductTelemetry\ProductTelemetryRecorder; @@ -20,7 +20,7 @@ it('normalizes timestamp metadata into ISO strings', function () { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->for($workspace)->create(); + $tenant = ManagedEnvironment::factory()->for($workspace)->create(); $user = User::factory()->create(); $completedAt = CarbonImmutable::parse('2026-04-26T19:40:38+00:00'); @@ -47,7 +47,7 @@ it('rejects metadata keys that are not declared for the event', function () { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->for($workspace)->create(); + $tenant = ManagedEnvironment::factory()->for($workspace)->create(); $user = User::factory()->create(); expect(fn () => app(ProductTelemetryRecorder::class)->record( @@ -65,7 +65,7 @@ it('rejects unsafe metadata values', function (string $key, mixed $value) { $workspace = Workspace::factory()->create(); - $tenant = Tenant::factory()->for($workspace)->create(); + $tenant = ManagedEnvironment::factory()->for($workspace)->create(); $user = User::factory()->create(); expect(fn () => app(ProductTelemetryRecorder::class)->record( diff --git a/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetrySummaryQueryTest.php b/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetrySummaryQueryTest.php index f34f80e7..d9ecd0d3 100644 --- a/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetrySummaryQueryTest.php +++ b/apps/platform/tests/Unit/Support/ProductTelemetry/ProductTelemetrySummaryQueryTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\ProductUsageEvent; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Support\ProductTelemetry\ProductTelemetrySummaryQuery; @@ -16,10 +16,10 @@ $user = User::factory()->create(); $workspaceA = Workspace::factory()->create(); - $tenantA = Tenant::factory()->for($workspaceA)->create(); + $tenantA = ManagedEnvironment::factory()->for($workspaceA)->create(); $workspaceB = Workspace::factory()->create(); - $tenantB = Tenant::factory()->for($workspaceB)->create(); + $tenantB = ManagedEnvironment::factory()->for($workspaceB)->create(); ProductUsageEvent::factory() ->forEvent(ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED, [ @@ -28,7 +28,7 @@ ]) ->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'user_id' => (int) $user->getKey(), 'subject_type' => 'tenant_onboarding_session', 'subject_id' => '11', @@ -41,7 +41,7 @@ ]) ->create([ 'workspace_id' => (int) $workspaceB->getKey(), - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'user_id' => (int) $user->getKey(), 'subject_type' => 'operation_run', 'subject_id' => '22', @@ -54,7 +54,7 @@ ]) ->create([ 'workspace_id' => (int) $workspaceB->getKey(), - 'tenant_id' => (int) $tenantB->getKey(), + 'managed_environment_id' => (int) $tenantB->getKey(), 'user_id' => (int) $user->getKey(), 'subject_type' => 'stored_report', 'subject_id' => '33', @@ -67,7 +67,7 @@ ]) ->create([ 'workspace_id' => (int) $workspaceA->getKey(), - 'tenant_id' => (int) $tenantA->getKey(), + 'managed_environment_id' => (int) $tenantA->getKey(), 'user_id' => (int) $user->getKey(), 'subject_type' => 'tenant', 'subject_id' => '44', diff --git a/apps/platform/tests/Unit/Support/Rbac/UiEnforcementTest.php b/apps/platform/tests/Unit/Support/Rbac/UiEnforcementTest.php index 4f5f0a29..f1840457 100644 --- a/apps/platform/tests/Unit/Support/Rbac/UiEnforcementTest.php +++ b/apps/platform/tests/Unit/Support/Rbac/UiEnforcementTest.php @@ -1,6 +1,6 @@ make(), - tenant: Tenant::factory()->make(), + tenant: ManagedEnvironment::factory()->make(), isMember: false, hasCapability: false, ); @@ -24,7 +24,7 @@ it('correctly identifies member without capability as forbidden', function () { $context = new TenantAccessContext( user: User::factory()->make(), - tenant: Tenant::factory()->make(), + tenant: ManagedEnvironment::factory()->make(), isMember: true, hasCapability: false, ); @@ -37,7 +37,7 @@ it('correctly identifies authorized member', function () { $context = new TenantAccessContext( user: User::factory()->make(), - tenant: Tenant::factory()->make(), + tenant: ManagedEnvironment::factory()->make(), isMember: true, hasCapability: true, ); diff --git a/apps/platform/tests/Unit/Support/ReasonTranslation/ProviderReasonTranslationTest.php b/apps/platform/tests/Unit/Support/ReasonTranslation/ProviderReasonTranslationTest.php index 0fc06d6e..e6ad8a6e 100644 --- a/apps/platform/tests/Unit/Support/ReasonTranslation/ProviderReasonTranslationTest.php +++ b/apps/platform/tests/Unit/Support/ReasonTranslation/ProviderReasonTranslationTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Providers\ProviderReasonCodes; use App\Support\ReasonTranslation\ReasonPresenter; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -11,9 +11,9 @@ uses(RefreshDatabase::class); it('translates provider reasons into labels, explanations, and next-step links', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->dedicated()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => (string) $tenant->graphTenantId(), diff --git a/apps/platform/tests/Unit/Support/ReasonTranslation/TenantOperabilityReasonTranslationTest.php b/apps/platform/tests/Unit/Support/ReasonTranslation/TenantOperabilityReasonTranslationTest.php index a0bef223..343042e0 100644 --- a/apps/platform/tests/Unit/Support/ReasonTranslation/TenantOperabilityReasonTranslationTest.php +++ b/apps/platform/tests/Unit/Support/ReasonTranslation/TenantOperabilityReasonTranslationTest.php @@ -8,7 +8,7 @@ it('marks already archived tenant states as non-actionable while preserving diagnostics', function (): void { $envelope = TenantOperabilityReasonCode::TenantAlreadyArchived->toReasonResolutionEnvelope(); - expect($envelope->operatorLabel)->toBe('Tenant already archived') + expect($envelope->operatorLabel)->toBe('ManagedEnvironment already archived') ->and($envelope->actionability)->toBe('non_actionable') ->and($envelope->guidanceText())->toBe('No action needed.') ->and($envelope->diagnosticCode())->toBe(TenantOperabilityReasonCode::TenantAlreadyArchived->value); diff --git a/apps/platform/tests/Unit/Support/References/ReferenceLinkTargetTest.php b/apps/platform/tests/Unit/Support/References/ReferenceLinkTargetTest.php index 6fe6b533..ea0a2db7 100644 --- a/apps/platform/tests/Unit/Support/References/ReferenceLinkTargetTest.php +++ b/apps/platform/tests/Unit/Support/References/ReferenceLinkTargetTest.php @@ -9,13 +9,13 @@ targetKind: 'policy_version', url: '/admin/t/1/policy-versions/42', actionLabel: 'View policy version', - contextBadge: 'Tenant', + contextBadge: 'ManagedEnvironment', ); expect($target->toArray())->toBe([ 'targetKind' => 'policy_version', 'url' => '/admin/t/1/policy-versions/42', 'actionLabel' => 'View policy version', - 'contextBadge' => 'Tenant', + 'contextBadge' => 'ManagedEnvironment', ]); }); diff --git a/apps/platform/tests/Unit/Support/References/RelatedContextReferenceAdapterTest.php b/apps/platform/tests/Unit/Support/References/RelatedContextReferenceAdapterTest.php index 0f892be9..a12353e5 100644 --- a/apps/platform/tests/Unit/Support/References/RelatedContextReferenceAdapterTest.php +++ b/apps/platform/tests/Unit/Support/References/RelatedContextReferenceAdapterTest.php @@ -33,7 +33,7 @@ targetKind: ReferenceClass::OperationRun->value, url: '/admin/operations/44', actionLabel: 'Open operation', - contextBadge: 'Tenant context', + contextBadge: 'ManagedEnvironment context', ), technicalDetail: ReferenceTechnicalDetail::forIdentifier('44'), ), diff --git a/apps/platform/tests/Unit/Support/References/ResolvedReferenceTest.php b/apps/platform/tests/Unit/Support/References/ResolvedReferenceTest.php index 1ce19dda..d6376c24 100644 --- a/apps/platform/tests/Unit/Support/References/ResolvedReferenceTest.php +++ b/apps/platform/tests/Unit/Support/References/ResolvedReferenceTest.php @@ -20,7 +20,7 @@ targetKind: ReferenceClass::PolicyVersion->value, url: '/admin/t/1/policy-versions/42', actionLabel: 'View policy version', - contextBadge: 'Tenant', + contextBadge: 'ManagedEnvironment', ), technicalDetail: ReferenceTechnicalDetail::forIdentifier('42', 'Captured from drift evidence'), meta: ['foo' => 'bar'], @@ -37,7 +37,7 @@ 'targetKind' => 'policy_version', 'url' => '/admin/t/1/policy-versions/42', 'actionLabel' => 'View policy version', - 'contextBadge' => 'Tenant', + 'contextBadge' => 'ManagedEnvironment', ], 'technicalDetail' => [ 'displayId' => '42', diff --git a/apps/platform/tests/Unit/Support/RelatedNavigationResolverTest.php b/apps/platform/tests/Unit/Support/RelatedNavigationResolverTest.php index d839c85a..ed89e62d 100644 --- a/apps/platform/tests/Unit/Support/RelatedNavigationResolverTest.php +++ b/apps/platform/tests/Unit/Support/RelatedNavigationResolverTest.php @@ -31,12 +31,12 @@ ]); $policy = Policy::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'display_name' => 'Windows Lockdown', ]); $version = PolicyVersion::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'policy_id' => (int) $policy->getKey(), 'version_number' => 3, ]); @@ -81,7 +81,7 @@ Filament::setTenant($tenant, true); $backupSet = \App\Models\BackupSet::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'name' => 'Nightly backup', ]); diff --git a/apps/platform/tests/Unit/Support/RestoreSafety/RestoreResultAttentionTest.php b/apps/platform/tests/Unit/Support/RestoreSafety/RestoreResultAttentionTest.php index e3db0388..f08b454c 100644 --- a/apps/platform/tests/Unit/Support/RestoreSafety/RestoreResultAttentionTest.php +++ b/apps/platform/tests/Unit/Support/RestoreSafety/RestoreResultAttentionTest.php @@ -16,11 +16,11 @@ $this->actingAs($user); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'is_dry_run' => true, 'status' => 'previewed', @@ -38,11 +38,11 @@ $this->actingAs($user); $backupSet = BackupSet::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, ]); $restoreRun = RestoreRun::factory()->create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'is_dry_run' => false, 'status' => 'completed', @@ -149,7 +149,7 @@ expect($overview['overview_state'])->toBe('weakened') ->and($overview['latest_relevant_restore_run_id'])->toBe((int) $latestFailed->getKey()) ->and($overview['latest_relevant_attention_state'])->toBe(RestoreResultAttention::STATE_FAILED) - ->and($overview['claim_boundary'])->toBe('Tenant recovery is not proven.') + ->and($overview['claim_boundary'])->toBe('ManagedEnvironment recovery is not proven.') ->and($overview['reason'])->toBe(RestoreResultAttention::STATE_FAILED); }); diff --git a/apps/platform/tests/Unit/Support/RestoreSafety/RestoreSafetyAssessmentTest.php b/apps/platform/tests/Unit/Support/RestoreSafety/RestoreSafetyAssessmentTest.php index a3ed9d3b..c9e6f405 100644 --- a/apps/platform/tests/Unit/Support/RestoreSafety/RestoreSafetyAssessmentTest.php +++ b/apps/platform/tests/Unit/Support/RestoreSafety/RestoreSafetyAssessmentTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\RestoreSafety\RestoreSafetyAssessment; use App\Support\RestoreSafety\RestoreSafetyResolver; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -10,7 +10,7 @@ uses(RefreshDatabase::class); it('marks current evidence with warnings as ready with caution', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), ]); @@ -44,7 +44,7 @@ }); it('marks invalidated preview evidence as risky', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'rbac_status' => 'ok', 'rbac_last_checked_at' => now(), ]); diff --git a/apps/platform/tests/Unit/Support/SupportDiagnostics/SupportDiagnosticBundleBuilderTest.php b/apps/platform/tests/Unit/Support/SupportDiagnostics/SupportDiagnosticBundleBuilderTest.php index 91d5c0dc..14ff384f 100644 --- a/apps/platform/tests/Unit/Support/SupportDiagnostics/SupportDiagnosticBundleBuilderTest.php +++ b/apps/platform/tests/Unit/Support/SupportDiagnostics/SupportDiagnosticBundleBuilderTest.php @@ -5,7 +5,7 @@ use App\Models\Finding; use App\Models\OperationRun; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\Workspace; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; @@ -16,10 +16,10 @@ uses(RefreshDatabase::class); it('builds tenant bundles with stable section order and stable reference order', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Deterministic Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Deterministic ManagedEnvironment']); ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Deterministic connection', ]); @@ -34,14 +34,14 @@ ]); $firstFinding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'severity' => Finding::SEVERITY_LOW, 'last_seen_at' => now()->subMinutes(4), ]); $secondFinding = Finding::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'severity' => Finding::SEVERITY_CRITICAL, 'last_seen_at' => now()->subMinutes(2), @@ -77,7 +77,7 @@ $workspace = Workspace::factory()->create(); $tenantlessRun = OperationRun::factory()->create([ - 'tenant_id' => null, + 'managed_environment_id' => null, 'workspace_id' => (int) $workspace->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, @@ -92,7 +92,7 @@ $bundle = app(SupportDiagnosticBundleBuilder::class)->forOperationRun($tenantlessRun); $sections = collect($bundle['sections'])->keyBy('key'); - expect($bundle['context']['tenant_id'])->toBeNull() + expect($bundle['context']['managed_environment_id'])->toBeNull() ->and($bundle['summary']['completeness_note'])->toContain('Provider connection') ->and($bundle['summary']['completeness_note'])->toContain('Review pack') ->and($sections['operation_context']['availability'])->toBe('available') @@ -104,9 +104,9 @@ }); it('marks references without canonical destinations as inaccessible', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); $connection = ProviderConnection::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); diff --git a/apps/platform/tests/Unit/Support/SupportDiagnostics/SupportDiagnosticBundleRedactionTest.php b/apps/platform/tests/Unit/Support/SupportDiagnostics/SupportDiagnosticBundleRedactionTest.php index 225e0517..669f35af 100644 --- a/apps/platform/tests/Unit/Support/SupportDiagnostics/SupportDiagnosticBundleRedactionTest.php +++ b/apps/platform/tests/Unit/Support/SupportDiagnostics/SupportDiagnosticBundleRedactionTest.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\OperationRunType; @@ -19,12 +19,12 @@ uses(RefreshDatabase::class); it('includes translated provider reasons and explicit support diagnostic redaction markers', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Redaction Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Redaction ManagedEnvironment']); ProviderConnection::factory() ->withCredential() ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Redaction connection', 'verification_status' => ProviderVerificationStatus::Blocked->value, @@ -46,12 +46,12 @@ }); it('excludes raw provider payloads and unrestricted log excerpts from support bundles', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Secret-Free Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Secret-Free ManagedEnvironment']); $connection = ProviderConnection::factory() ->withCredential() ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'verification_status' => ProviderVerificationStatus::Blocked->value, 'last_error_reason_code' => ProviderReasonCodes::ProviderPermissionMissing, @@ -76,7 +76,7 @@ ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => [ @@ -86,7 +86,7 @@ AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'operation_run_id' => (int) $run->getKey(), 'action' => 'operation.failed', 'resource_type' => 'operation_run', diff --git a/apps/platform/tests/Unit/Support/SupportRequests/ExternalSupportDeskHandoffServiceTest.php b/apps/platform/tests/Unit/Support/SupportRequests/ExternalSupportDeskHandoffServiceTest.php index 3836287f..0a94e8e6 100644 --- a/apps/platform/tests/Unit/Support/SupportRequests/ExternalSupportDeskHandoffServiceTest.php +++ b/apps/platform/tests/Unit/Support/SupportRequests/ExternalSupportDeskHandoffServiceTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\SupportRequests\ExternalSupportDeskHandoffService; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Http\Client\Request; @@ -28,11 +28,11 @@ function configureSpec256SupportDesk(array $overrides = []): void function spec256SupportRequest(array $attributes = []): SupportRequest { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); return SupportRequest::factory()->create(array_merge([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'summary' => 'Need external support desk handoff.', 'severity' => SupportRequest::SEVERITY_HIGH, ], $attributes)); diff --git a/apps/platform/tests/Unit/Support/SupportRequests/SupportRequestContextBuilderTest.php b/apps/platform/tests/Unit/Support/SupportRequests/SupportRequestContextBuilderTest.php index 293bec79..956375b8 100644 --- a/apps/platform/tests/Unit/Support/SupportRequests/SupportRequestContextBuilderTest.php +++ b/apps/platform/tests/Unit/Support/SupportRequests/SupportRequestContextBuilderTest.php @@ -6,7 +6,7 @@ use App\Models\OperationRun; use App\Models\ProviderConnection; use App\Models\StoredReport; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\OperationRunType; @@ -18,7 +18,7 @@ uses(RefreshDatabase::class); it('builds deterministic canonical context with omission markers when diagnostics are not attached', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Omission Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Omission ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $builder = app(SupportRequestContextBuilder::class); @@ -46,13 +46,13 @@ }); it('attaches a redacted diagnostic snapshot without raw payload content', function (): void { - $tenant = Tenant::factory()->create(['name' => 'Redaction Tenant']); + $tenant = ManagedEnvironment::factory()->create(['name' => 'Redaction ManagedEnvironment']); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $connection = ProviderConnection::factory() ->withCredential() ->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => 'Redaction Connection', 'verification_status' => ProviderVerificationStatus::Blocked->value, @@ -82,7 +82,7 @@ ]); StoredReport::factory()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => [ @@ -92,7 +92,7 @@ AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'operation_run_id' => (int) $run->getKey(), 'action' => 'operation.failed', 'resource_type' => 'operation_run', diff --git a/apps/platform/tests/Unit/Support/SupportRequests/SupportRequestLatestHandoffSummaryTest.php b/apps/platform/tests/Unit/Support/SupportRequests/SupportRequestLatestHandoffSummaryTest.php index df3fed6f..9d9580a4 100644 --- a/apps/platform/tests/Unit/Support/SupportRequests/SupportRequestLatestHandoffSummaryTest.php +++ b/apps/platform/tests/Unit/Support/SupportRequests/SupportRequestLatestHandoffSummaryTest.php @@ -4,7 +4,7 @@ use App\Models\OperationRun; use App\Models\SupportRequest; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\OperationRunOutcome; use App\Support\OperationRunStatus; use App\Support\OperationRunType; @@ -14,12 +14,12 @@ uses(RefreshDatabase::class); it('returns the latest tenant-scoped handoff summary without using run-scoped requests', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); SupportRequest::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'primary_context_type' => SupportRequest::PRIMARY_CONTEXT_TENANT, 'internal_reference' => 'SR-OLDTENANT0000000000000001', 'external_handoff_mode' => SupportRequest::EXTERNAL_HANDOFF_MODE_LINK_EXISTING_TICKET, @@ -29,7 +29,7 @@ $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -47,7 +47,7 @@ SupportRequest::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'primary_context_type' => SupportRequest::PRIMARY_CONTEXT_TENANT, 'internal_reference' => 'SR-NEWTENANT0000000000000001', 'external_handoff_mode' => SupportRequest::EXTERNAL_HANDOFF_MODE_CREATE_EXTERNAL_TICKET, @@ -65,12 +65,12 @@ }); it('returns the latest run-scoped handoff summary for the current run only', function (): void { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator'); $firstRun = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, @@ -78,7 +78,7 @@ $secondRun = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, diff --git a/apps/platform/tests/Unit/Support/Tenants/TenantLifecyclePresentationTest.php b/apps/platform/tests/Unit/Support/Tenants/TenantLifecyclePresentationTest.php index 62bc4f5e..f6f545a3 100644 --- a/apps/platform/tests/Unit/Support/Tenants/TenantLifecyclePresentationTest.php +++ b/apps/platform/tests/Unit/Support/Tenants/TenantLifecyclePresentationTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Tenants\ReferencedTenantLifecyclePresentation; use App\Support\Tenants\TenantLifecycle; use App\Support\Tenants\TenantLifecyclePresentation; @@ -26,7 +26,7 @@ ]); it('builds lifecycle presentation from tenant soft-delete state', function (): void { - $tenant = Tenant::factory()->archived()->create(); + $tenant = ManagedEnvironment::factory()->archived()->create(); $presentation = TenantLifecyclePresentation::fromTenant($tenant); @@ -52,9 +52,9 @@ }); it('describes non-selectable referenced tenant lifecycle using canonical wording', function (): void { - $tenant = Tenant::factory()->create([ - 'status' => Tenant::STATUS_ONBOARDING, - 'name' => 'Onboarding Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'status' => ManagedEnvironment::STATUS_ONBOARDING, + 'name' => 'Onboarding ManagedEnvironment', ]); $presentation = ReferencedTenantLifecyclePresentation::forOperationRun($tenant); diff --git a/apps/platform/tests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php b/apps/platform/tests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php index ac1dfae2..c504ba52 100644 --- a/apps/platform/tests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php +++ b/apps/platform/tests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php @@ -18,7 +18,7 @@ $record->forceFill([ 'id' => 42, 'workspace_id' => 12, - 'tenant_id' => 8, + 'managed_environment_id' => 8, ]); $left = DerivedStateKey::fromModel( diff --git a/apps/platform/tests/Unit/Support/WorkspaceIsolation/TenantOwnedQueryScopeTest.php b/apps/platform/tests/Unit/Support/WorkspaceIsolation/TenantOwnedQueryScopeTest.php index 92989ffb..25c1fa08 100644 --- a/apps/platform/tests/Unit/Support/WorkspaceIsolation/TenantOwnedQueryScopeTest.php +++ b/apps/platform/tests/Unit/Support/WorkspaceIsolation/TenantOwnedQueryScopeTest.php @@ -4,7 +4,7 @@ use App\Filament\Concerns\InteractsWithTenantOwnedRecords; use App\Models\Policy; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\WorkspaceIsolation\TenantOwnedQueryScope; use App\Support\WorkspaceIsolation\TenantOwnedRecordResolver; use Filament\Resources\Resource; @@ -15,11 +15,11 @@ uses(RefreshDatabase::class); it('applies a tenant-owned scope to matching records only', function (): void { - $tenant = Tenant::factory()->create(); - $foreignTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $foreignTenant = ManagedEnvironment::factory()->create(); - $ownedRecord = Policy::factory()->create(['tenant_id' => $tenant->getKey()]); - Policy::factory()->create(['tenant_id' => $foreignTenant->getKey()]); + $ownedRecord = Policy::factory()->create(['managed_environment_id' => $tenant->getKey()]); + Policy::factory()->create(['managed_environment_id' => $foreignTenant->getKey()]); $records = app(TenantOwnedQueryScope::class) ->apply(Policy::query(), $tenant) @@ -30,8 +30,8 @@ }); it('fails closed when no tenant context is available', function (): void { - Tenant::factory()->count(2)->create()->each(function (Tenant $tenant): void { - Policy::factory()->create(['tenant_id' => $tenant->getKey()]); + ManagedEnvironment::factory()->count(2)->create()->each(function (ManagedEnvironment $tenant): void { + Policy::factory()->create(['managed_environment_id' => $tenant->getKey()]); }); $count = app(TenantOwnedQueryScope::class) @@ -42,11 +42,11 @@ }); it('resolves only records inside the already-scoped tenant query', function (): void { - $tenant = Tenant::factory()->create(); - $foreignTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $foreignTenant = ManagedEnvironment::factory()->create(); - $ownedRecord = Policy::factory()->create(['tenant_id' => $tenant->getKey()]); - $foreignRecord = Policy::factory()->create(['tenant_id' => $foreignTenant->getKey()]); + $ownedRecord = Policy::factory()->create(['managed_environment_id' => $tenant->getKey()]); + $foreignRecord = Policy::factory()->create(['managed_environment_id' => $foreignTenant->getKey()]); $resolver = app(TenantOwnedRecordResolver::class); $scopedQuery = app(TenantOwnedQueryScope::class)->apply(Policy::query(), $tenant); @@ -59,11 +59,11 @@ }); it('lets the shared filament trait expose the scoped query and resolver helpers', function (): void { - $tenant = Tenant::factory()->create(); - $foreignTenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); + $foreignTenant = ManagedEnvironment::factory()->create(); - $ownedRecord = Policy::factory()->create(['tenant_id' => $tenant->getKey()]); - Policy::factory()->create(['tenant_id' => $foreignTenant->getKey()]); + $ownedRecord = Policy::factory()->create(['managed_environment_id' => $tenant->getKey()]); + Policy::factory()->create(['managed_environment_id' => $foreignTenant->getKey()]); TestTenantOwnedPolicyResource::fakeTenant($tenant); @@ -82,9 +82,9 @@ class TestTenantOwnedPolicyResource extends Resource protected static ?string $tenantOwnershipRelationshipName = 'tenant'; - protected static ?Tenant $fakeTenant = null; + protected static ?ManagedEnvironment $fakeTenant = null; - public static function fakeTenant(?Tenant $tenant): void + public static function fakeTenant(?ManagedEnvironment $tenant): void { static::$fakeTenant = $tenant; } @@ -99,7 +99,7 @@ public static function resolveViaTrait(Model|int|string|null $record): ?Model return static::resolveTenantOwnedRecord($record); } - protected static function resolveTenantContextForTenantOwnedRecords(): ?Tenant + protected static function resolveTenantContextForTenantOwnedRecords(): ?ManagedEnvironment { return static::$fakeTenant; } diff --git a/apps/platform/tests/Unit/Support/Workspaces/WorkspaceContextRememberedTenantTest.php b/apps/platform/tests/Unit/Support/Workspaces/WorkspaceContextRememberedTenantTest.php index f6b3a4b6..809c4b7b 100644 --- a/apps/platform/tests/Unit/Support/Workspaces/WorkspaceContextRememberedTenantTest.php +++ b/apps/platform/tests/Unit/Support/Workspaces/WorkspaceContextRememberedTenantTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -25,7 +25,7 @@ it('clears remembered tenant context when the stored tenant belongs to another workspace', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); - $otherWorkspaceTenant = Tenant::factory()->active()->create(); + $otherWorkspaceTenant = ManagedEnvironment::factory()->active()->create(); $this->actingAs($user); @@ -41,7 +41,7 @@ it('clears remembered tenant context when the stored tenant no longer exists', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); - $missingTenant = Tenant::factory()->active()->create([ + $missingTenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); @@ -63,7 +63,7 @@ it('clears remembered tenant context when the actor is no longer entitled to the tenant', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); - $nonEntitledTenant = Tenant::factory()->active()->create([ + $nonEntitledTenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); @@ -81,7 +81,7 @@ it('clears remembered tenant context when the tenant becomes selector ineligible', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); - $onboardingTenant = Tenant::factory()->onboarding()->create([ + $onboardingTenant = ManagedEnvironment::factory()->onboarding()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); diff --git a/apps/platform/tests/Unit/System/SupportAccessGrantResolverTest.php b/apps/platform/tests/Unit/System/SupportAccessGrantResolverTest.php index e93bc769..b8642bb2 100644 --- a/apps/platform/tests/Unit/System/SupportAccessGrantResolverTest.php +++ b/apps/platform/tests/Unit/System/SupportAccessGrantResolverTest.php @@ -5,7 +5,7 @@ use App\Models\AuditLog; use App\Models\PlatformUser; use App\Models\SupportAccessGrant; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Models\User; use App\Models\Workspace; use App\Models\WorkspaceMembership; @@ -21,8 +21,8 @@ uses(RefreshDatabase::class); beforeEach(function (): void { - Tenant::factory()->create([ - 'tenant_id' => null, + ManagedEnvironment::factory()->create([ + 'managed_environment_id' => null, 'external_id' => 'platform', 'name' => 'Platform', ]); diff --git a/apps/platform/tests/Unit/TenantCurrentTest.php b/apps/platform/tests/Unit/TenantCurrentTest.php index 80f8a112..ff82de0c 100644 --- a/apps/platform/tests/Unit/TenantCurrentTest.php +++ b/apps/platform/tests/Unit/TenantCurrentTest.php @@ -1,6 +1,6 @@ 'tenant-env', - 'name' => 'Preferred Tenant', + $preferred = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-env', + 'name' => 'Preferred ManagedEnvironment', 'is_current' => false, ]); - Tenant::create([ - 'tenant_id' => 'other-tenant', - 'name' => 'Other Tenant', + ManagedEnvironment::create([ + 'managed_environment_id' => 'other-tenant', + 'name' => 'Other ManagedEnvironment', 'is_current' => true, ]); - $resolved = Tenant::current(); + $resolved = ManagedEnvironment::current(); expect($resolved->id)->toBe($preferred->id); @@ -38,9 +38,9 @@ function restoreIntuneTenantId(string|false $original): void $originalEnv = getenv('INTUNE_TENANT_ID'); putenv('INTUNE_TENANT_ID=missing-tenant'); - expect(fn () => Tenant::current())->toThrow( + expect(fn () => ManagedEnvironment::current())->toThrow( \RuntimeException::class, - 'Configured INTUNE_TENANT_ID tenant is missing or inactive.' + 'Configured INTUNE_TENANT_ID managed environment is missing or inactive.' ); restoreIntuneTenantId($originalEnv); @@ -50,19 +50,19 @@ function restoreIntuneTenantId(string|false $original): void $originalEnv = getenv('INTUNE_TENANT_ID'); putenv('INTUNE_TENANT_ID='); - $current = Tenant::create([ - 'tenant_id' => 'tenant-current', - 'name' => 'Current Tenant', + $current = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-current', + 'name' => 'Current ManagedEnvironment', 'is_current' => true, ]); - Tenant::create([ - 'tenant_id' => 'tenant-inactive', + ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-inactive', 'name' => 'Inactive Current Flag', 'status' => 'archived', ]); - $resolved = Tenant::current(); + $resolved = ManagedEnvironment::current(); expect($resolved->id)->toBe($current->id); @@ -73,13 +73,13 @@ function restoreIntuneTenantId(string|false $original): void $originalEnv = getenv('INTUNE_TENANT_ID'); putenv('INTUNE_TENANT_ID='); - Tenant::create([ - 'tenant_id' => 'tenant-one', - 'name' => 'Tenant One', + ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-one', + 'name' => 'ManagedEnvironment One', 'is_current' => false, ]); - expect(fn () => Tenant::currentOrFail())->toThrow(\RuntimeException::class, 'No current tenant selected.'); + expect(fn () => ManagedEnvironment::currentOrFail())->toThrow(\RuntimeException::class, 'No current managed environment selected.'); restoreIntuneTenantId($originalEnv); }); @@ -88,15 +88,15 @@ function restoreIntuneTenantId(string|false $original): void $originalEnv = getenv('INTUNE_TENANT_ID'); putenv('INTUNE_TENANT_ID='); - $first = Tenant::create([ - 'tenant_id' => 'tenant-first', - 'name' => 'First Tenant', + $first = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-first', + 'name' => 'First ManagedEnvironment', 'is_current' => true, ]); - $second = Tenant::create([ - 'tenant_id' => 'tenant-second', - 'name' => 'Second Tenant', + $second = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-second', + 'name' => 'Second ManagedEnvironment', ]); $second->makeCurrent(); @@ -111,15 +111,15 @@ function restoreIntuneTenantId(string|false $original): void $originalEnv = getenv('INTUNE_TENANT_ID'); putenv('INTUNE_TENANT_ID='); - $current = Tenant::create([ - 'tenant_id' => 'tenant-current', + $current = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-current', 'name' => 'Already Current', 'is_current' => true, ]); - $other = Tenant::create([ - 'tenant_id' => 'tenant-other', - 'name' => 'Other Tenant', + $other = ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-other', + 'name' => 'Other ManagedEnvironment', 'is_current' => false, ]); diff --git a/apps/platform/tests/Unit/TenantPermissionCheckClustersTest.php b/apps/platform/tests/Unit/TenantPermissionCheckClustersTest.php index 6c934c21..23b288f7 100644 --- a/apps/platform/tests/Unit/TenantPermissionCheckClustersTest.php +++ b/apps/platform/tests/Unit/TenantPermissionCheckClustersTest.php @@ -1,6 +1,6 @@ create(['external_id' => 'tenant-a']); + $tenant = ManagedEnvironment::factory()->create(['external_id' => 'tenant-a']); $checks = TenantPermissionCheckClusters::buildChecks($tenant, [ [ @@ -41,7 +41,7 @@ }); it('marks a cluster as warn and non-blocking when only delegated permissions are missing', function (): void { - $tenant = Tenant::factory()->create(['external_id' => 'tenant-b']); + $tenant = ManagedEnvironment::factory()->create(['external_id' => 'tenant-b']); $checks = TenantPermissionCheckClusters::buildChecks($tenant, [ [ @@ -62,7 +62,7 @@ }); it('marks a cluster as skipped when no mapped permissions are present', function (): void { - $tenant = Tenant::factory()->create(['external_id' => 'tenant-c']); + $tenant = ManagedEnvironment::factory()->create(['external_id' => 'tenant-c']); $checks = TenantPermissionCheckClusters::buildChecks($tenant, []); @@ -73,7 +73,7 @@ }); it('marks a cluster as passed when all mapped permissions are granted', function (): void { - $tenant = Tenant::factory()->create(['external_id' => 'tenant-d']); + $tenant = ManagedEnvironment::factory()->create(['external_id' => 'tenant-d']); $checks = TenantPermissionCheckClusters::buildChecks($tenant, [ [ @@ -102,7 +102,7 @@ }); it('degrades permission clusters to warnings when inventory is not fresh', function (): void { - $tenant = Tenant::factory()->create(['external_id' => 'tenant-e']); + $tenant = ManagedEnvironment::factory()->create(['external_id' => 'tenant-e']); $checks = TenantPermissionCheckClusters::buildChecks( tenant: $tenant, diff --git a/apps/platform/tests/Unit/TenantPermissionServiceTest.php b/apps/platform/tests/Unit/TenantPermissionServiceTest.php index c43ece2f..d5123c8e 100644 --- a/apps/platform/tests/Unit/TenantPermissionServiceTest.php +++ b/apps/platform/tests/Unit/TenantPermissionServiceTest.php @@ -1,6 +1,6 @@ create([ - 'tenant_id' => 'tenant-ok', - 'name' => 'Tenant OK', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-ok', + 'name' => 'ManagedEnvironment OK', ]); ensureDefaultProviderConnection($tenant, 'microsoft'); foreach (requiredPermissions() as $permission) { TenantPermission::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'permission_key' => $permission['key'], 'status' => 'granted', ]); @@ -49,7 +49,7 @@ function requiredPermissions(): array $result = app(TenantPermissionService::class)->compare($tenant); expect($result['overall_status'])->toBe('granted'); - expect(TenantPermission::where('tenant_id', $tenant->id)->where('status', 'granted')->count()) + expect(TenantPermission::where('managed_environment_id', $tenant->id)->where('status', 'granted')->count()) ->toBe(count(requiredPermissions())); }); @@ -64,16 +64,16 @@ function requiredPermissions(): array ])); }); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-missing', - 'name' => 'Tenant Missing', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-missing', + 'name' => 'ManagedEnvironment Missing', ]); ensureDefaultProviderConnection($tenant, 'microsoft'); $first = $permissions[0]['key']; TenantPermission::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'permission_key' => $first, 'status' => 'ok', ]); @@ -86,7 +86,7 @@ function requiredPermissions(): array if ($missingKey) { $this->assertDatabaseHas('tenant_permissions', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'permission_key' => $missingKey, 'status' => 'missing', ]); @@ -100,9 +100,9 @@ function requiredPermissions(): array ->andReturn(new GraphResponse(false, [], 500, ['Graph API error'])); }); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'tenant-error', - 'name' => 'Tenant Error', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'tenant-error', + 'name' => 'ManagedEnvironment Error', ]); ensureDefaultProviderConnection($tenant, 'microsoft'); @@ -120,7 +120,7 @@ function requiredPermissions(): array expect($result['overall_status'])->toBe('error'); $this->assertDatabaseHas('tenant_permissions', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'permission_key' => $first, 'status' => 'error', ]); @@ -140,12 +140,12 @@ function requiredPermissions(): array ]); config()->set('intune_permissions.granted_stub', ['DeviceManagementRBAC.ReadWrite.All']); - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant, 'microsoft'); TenantPermission::create([ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'permission_key' => 'DeviceManagementRBAC.ReadWrite.All', 'status' => 'granted', 'details' => ['source' => 'configured'], @@ -161,7 +161,7 @@ function requiredPermissions(): array }); it('persists permissions with workspace_id even when model events are disabled', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant, 'microsoft'); @@ -170,18 +170,18 @@ function requiredPermissions(): array }); $this->assertDatabaseHas('tenant_permissions', [ - 'tenant_id' => $tenant->id, + 'managed_environment_id' => $tenant->id, 'workspace_id' => $tenant->workspace_id, ]); }); it('persists permissions when the tenant instance does not have workspace_id loaded', function () { - $tenant = Tenant::factory()->create(); + $tenant = ManagedEnvironment::factory()->create(); ensureDefaultProviderConnection($tenant, 'microsoft'); - $tenantWithoutWorkspaceId = Tenant::query() - ->select(['id', 'tenant_id', 'external_id', 'name', 'status', 'environment']) + $tenantWithoutWorkspaceId = ManagedEnvironment::query() + ->select(['id', 'managed_environment_id', 'external_id', 'name', 'status', 'environment']) ->findOrFail((int) $tenant->getKey()); expect($tenantWithoutWorkspaceId->getAttribute('workspace_id'))->toBeNull(); @@ -189,18 +189,18 @@ function requiredPermissions(): array app(TenantPermissionService::class)->compare($tenantWithoutWorkspaceId); $this->assertDatabaseHas('tenant_permissions', [ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); }); it('does not persist when tenant workspace_id is missing', function () { - $tenant = Tenant::withoutEvents(function (): Tenant { - return Tenant::create([ - 'tenant_id' => 'tenant-no-workspace', + $tenant = ManagedEnvironment::withoutEvents(function (): ManagedEnvironment { + return ManagedEnvironment::create([ + 'managed_environment_id' => 'tenant-no-workspace', 'external_id' => 'tenant-no-workspace', - 'name' => 'Tenant No Workspace', - 'status' => Tenant::STATUS_ACTIVE, + 'name' => 'ManagedEnvironment No Workspace', + 'status' => ManagedEnvironment::STATUS_ACTIVE, 'environment' => 'other', 'workspace_id' => null, ]); @@ -208,5 +208,5 @@ function requiredPermissions(): array app(TenantPermissionService::class)->compare($tenant, persist: true); - expect(TenantPermission::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(0); + expect(TenantPermission::query()->where('managed_environment_id', (int) $tenant->getKey())->count())->toBe(0); }); diff --git a/apps/platform/tests/Unit/TenantRequiredPermissionsCopyPayloadTest.php b/apps/platform/tests/Unit/TenantRequiredPermissionsCopyPayloadTest.php index 5c58496a..68d585a0 100644 --- a/apps/platform/tests/Unit/TenantRequiredPermissionsCopyPayloadTest.php +++ b/apps/platform/tests/Unit/TenantRequiredPermissionsCopyPayloadTest.php @@ -1,6 +1,6 @@ make(['external_id' => 'tenant-copy-a', 'name' => 'Tenant']); + $tenant = ManagedEnvironment::factory()->make(['external_id' => 'tenant-copy-a', 'name' => 'ManagedEnvironment']); $vm = $builder->build($tenant, [ 'features' => ['f1'], diff --git a/apps/platform/tests/Unit/TenantResourceConsentUrlTest.php b/apps/platform/tests/Unit/TenantResourceConsentUrlTest.php index 08fdb7ca..179bc7eb 100644 --- a/apps/platform/tests/Unit/TenantResourceConsentUrlTest.php +++ b/apps/platform/tests/Unit/TenantResourceConsentUrlTest.php @@ -3,7 +3,7 @@ use App\Filament\Resources\TenantResource; use App\Models\ProviderConnection; use App\Models\ProviderCredential; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); @@ -11,17 +11,17 @@ config()->set('graph.client_id', 'platform-client-id'); config()->set('graph.client_secret', 'platform-client-secret'); - $tenant = Tenant::factory()->create([ - 'tenant_id' => 'b0091e5d-944f-4a34-bcd9-12cbfb7b75cf', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::factory()->create([ + 'managed_environment_id' => 'b0091e5d-944f-4a34-bcd9-12cbfb7b75cf', + 'name' => 'Test ManagedEnvironment', 'app_client_id' => 'legacy-tenant-client-id', ]); $connection = ProviderConnection::factory()->platform()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->graphTenantId(), + 'entra_tenant_id' => 'b0091e5d-944f-4a34-bcd9-12cbfb7b75cf', 'is_default' => true, ]); @@ -46,15 +46,15 @@ }); it('builds dedicated admin consent urls from dedicated provider connection credentials', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'app_client_id' => null, ]); $connection = ProviderConnection::factory()->dedicated()->create([ - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->graphTenantId(), + 'entra_tenant_id' => 'dedicated-target-tenant-id', 'is_default' => true, ]); diff --git a/apps/platform/tests/Unit/TenantScopeTest.php b/apps/platform/tests/Unit/TenantScopeTest.php index e2175c9e..778ddf81 100644 --- a/apps/platform/tests/Unit/TenantScopeTest.php +++ b/apps/platform/tests/Unit/TenantScopeTest.php @@ -1,16 +1,16 @@ 'b0091e5d-944f-4a34-bcd9-12cbfb7b75cf', - 'name' => 'Test Tenant', + $tenant = ManagedEnvironment::create([ + 'managed_environment_id' => 'b0091e5d-944f-4a34-bcd9-12cbfb7b75cf', + 'name' => 'Test ManagedEnvironment', ]); - $found = Tenant::query()->forTenant('b0091e5d-944f-4a34-bcd9-12cbfb7b75cf')->first(); + $found = ManagedEnvironment::query()->forTenant('b0091e5d-944f-4a34-bcd9-12cbfb7b75cf')->first(); expect($found)->not->toBeNull(); expect($found->id)->toBe($tenant->id); diff --git a/apps/platform/tests/Unit/Tenants/TenantActionPolicySurfaceTest.php b/apps/platform/tests/Unit/Tenants/TenantActionPolicySurfaceTest.php index 35e1f879..d958e3fd 100644 --- a/apps/platform/tests/Unit/Tenants/TenantActionPolicySurfaceTest.php +++ b/apps/platform/tests/Unit/Tenants/TenantActionPolicySurfaceTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use App\Filament\Resources\TenantResource; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Tenants\TenantActionPolicySurface; use App\Support\Tenants\TenantActionSurface; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -16,8 +16,8 @@ expect(app(TenantActionPolicySurface::class)->lifecycleActionForTenant($tenant)) ->toBeNull(); })->with([ - 'draft' => [fn (): Tenant => Tenant::factory()->draft()->create()], - 'onboarding' => [fn (): Tenant => Tenant::factory()->onboarding()->create()], + 'draft' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->draft()->create()], + 'onboarding' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create()], ]); it('returns archive only for active tenants and restore only for archived tenants', function ( @@ -34,8 +34,8 @@ ->and($descriptor?->label)->toBe($expectedLabel) ->and($descriptor?->requiresConfirmation)->toBeTrue(); })->with([ - 'active' => [fn (): Tenant => Tenant::factory()->active()->create(), 'archive', 'Archive'], - 'archived' => [fn (): Tenant => Tenant::factory()->archived()->create(), 'restore', 'Restore'], + 'active' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->active()->create(), 'archive', 'Archive'], + 'archived' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->archived()->create(), 'restore', 'Restore'], ]); it('returns resume onboarding as the primary action for draft and onboarding tenants with resumable drafts', function (\Closure $tenantFactory): void { @@ -48,7 +48,7 @@ 'started_by' => $user, 'updated_by' => $user, 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -59,12 +59,12 @@ ->toBe(['view', 'related_onboarding']) ->and($catalog[1]->label)->toBe('Resume onboarding'); })->with([ - 'draft' => [fn (): Tenant => Tenant::factory()->draft()->create()], - 'onboarding' => [fn (): Tenant => Tenant::factory()->onboarding()->create()], + 'draft' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->draft()->create()], + 'onboarding' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create()], ]); it('keeps completed onboarding as a view-only overflow action for active tenants', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); createOnboardingDraft([ @@ -74,7 +74,7 @@ 'updated_by' => $user, 'status' => 'completed', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -87,7 +87,7 @@ }); it('keeps tenant index catalogs within the clickable-row overflow contract', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); createOnboardingDraft([ @@ -97,7 +97,7 @@ 'updated_by' => $user, 'status' => 'completed', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); @@ -129,7 +129,7 @@ }); it('invalidates cached tenant index catalogs when the related onboarding draft lifecycle changes', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false); $draft = createOnboardingDraft([ @@ -139,7 +139,7 @@ 'updated_by' => $user, 'status' => 'in_progress', 'state' => [ - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, 'tenant_name' => (string) $tenant->name, ], ]); diff --git a/apps/platform/tests/Unit/Tenants/TenantLifecycleTest.php b/apps/platform/tests/Unit/Tenants/TenantLifecycleTest.php index d8e2e689..271a61ba 100644 --- a/apps/platform/tests/Unit/Tenants/TenantLifecycleTest.php +++ b/apps/platform/tests/Unit/Tenants/TenantLifecycleTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Tenants\TenantLifecycle; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -23,7 +23,7 @@ }); it('derives archived lifecycle from soft-deleted tenants', function (): void { - $tenant = Tenant::factory()->archived()->create(); + $tenant = ManagedEnvironment::factory()->archived()->create(); expect(TenantLifecycle::fromTenant($tenant))->toBe(TenantLifecycle::Archived); }); diff --git a/apps/platform/tests/Unit/Tenants/TenantOperabilityServiceTest.php b/apps/platform/tests/Unit/Tenants/TenantOperabilityServiceTest.php index 9e9ca21a..f53a78f7 100644 --- a/apps/platform/tests/Unit/Tenants/TenantOperabilityServiceTest.php +++ b/apps/platform/tests/Unit/Tenants/TenantOperabilityServiceTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Tenants\TenantOperabilityService; use App\Support\Tenants\TenantInteractionLane; use App\Support\Tenants\TenantLifecycle; @@ -34,7 +34,7 @@ ->and($decision->canReferenceInWorkspaceMonitoring)->toBeTrue(); })->with([ 'draft' => [ - fn (): Tenant => Tenant::factory()->draft()->create(), + fn (): ManagedEnvironment => ManagedEnvironment::factory()->draft()->create(), TenantLifecycle::Draft, false, false, @@ -43,7 +43,7 @@ true, ], 'onboarding' => [ - fn (): Tenant => Tenant::factory()->onboarding()->create(), + fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create(), TenantLifecycle::Onboarding, false, false, @@ -52,7 +52,7 @@ true, ], 'active' => [ - fn (): Tenant => Tenant::factory()->active()->create(), + fn (): ManagedEnvironment => ManagedEnvironment::factory()->active()->create(), TenantLifecycle::Active, true, true, @@ -61,7 +61,7 @@ false, ], 'archived' => [ - fn (): Tenant => Tenant::factory()->archived()->create(), + fn (): ManagedEnvironment => ManagedEnvironment::factory()->archived()->create(), TenantLifecycle::Archived, false, false, @@ -87,10 +87,10 @@ expect($outcome->allowed)->toBe($expectedAllowed) ->and($outcome->reasonCode)->toBe($expectedReason); })->with([ - 'active-selector-eligible' => [fn (): Tenant => Tenant::factory()->active()->create(), true, null], - 'draft-selector-ineligible' => [fn (): Tenant => Tenant::factory()->draft()->create(), false, TenantOperabilityReasonCode::SelectorIneligibleLifecycle], - 'onboarding-selector-ineligible' => [fn (): Tenant => Tenant::factory()->onboarding()->create(), false, TenantOperabilityReasonCode::SelectorIneligibleLifecycle], - 'archived-selector-ineligible' => [fn (): Tenant => Tenant::factory()->archived()->create(), false, TenantOperabilityReasonCode::SelectorIneligibleLifecycle], + 'active-selector-eligible' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->active()->create(), true, null], + 'draft-selector-ineligible' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->draft()->create(), false, TenantOperabilityReasonCode::SelectorIneligibleLifecycle], + 'onboarding-selector-ineligible' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create(), false, TenantOperabilityReasonCode::SelectorIneligibleLifecycle], + 'archived-selector-ineligible' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->archived()->create(), false, TenantOperabilityReasonCode::SelectorIneligibleLifecycle], ]); it('keeps tenant-bound and canonical lanes viewable across all tenant lifecycles', function ( @@ -112,15 +112,15 @@ expect($outcome->allowed)->toBeTrue() ->and($outcome->discoverable)->toBeTrue(); })->with([ - 'draft-admin' => [fn (): Tenant => Tenant::factory()->draft()->create(), TenantInteractionLane::AdministrativeManagement], - 'onboarding-admin' => [fn (): Tenant => Tenant::factory()->onboarding()->create(), TenantInteractionLane::AdministrativeManagement], - 'archived-admin' => [fn (): Tenant => Tenant::factory()->archived()->create(), TenantInteractionLane::AdministrativeManagement], - 'onboarding-canonical' => [fn (): Tenant => Tenant::factory()->onboarding()->create(), TenantInteractionLane::CanonicalWorkspaceRecord], - 'archived-canonical' => [fn (): Tenant => Tenant::factory()->archived()->create(), TenantInteractionLane::CanonicalWorkspaceRecord], + 'draft-admin' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->draft()->create(), TenantInteractionLane::AdministrativeManagement], + 'onboarding-admin' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create(), TenantInteractionLane::AdministrativeManagement], + 'archived-admin' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->archived()->create(), TenantInteractionLane::AdministrativeManagement], + 'onboarding-canonical' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create(), TenantInteractionLane::CanonicalWorkspaceRecord], + 'archived-canonical' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->archived()->create(), TenantInteractionLane::CanonicalWorkspaceRecord], ]); it('returns wrong-lane reasons for questions asked in the wrong lane', function (): void { - $tenant = Tenant::factory()->active()->create(); + $tenant = ManagedEnvironment::factory()->active()->create(); $outcome = app(TenantOperabilityService::class)->outcomeFor( tenant: $tenant, @@ -141,10 +141,10 @@ expect(app(TenantOperabilityService::class)->primaryManagementActionKey($tenant)) ->toBe($expectedActionKey); })->with([ - 'draft-primary' => [fn (): Tenant => Tenant::factory()->draft()->create(), null], - 'onboarding-primary' => [fn (): Tenant => Tenant::factory()->onboarding()->create(), null], - 'active-primary' => [fn (): Tenant => Tenant::factory()->active()->create(), 'archive'], - 'archived-primary' => [fn (): Tenant => Tenant::factory()->archived()->create(), 'restore'], + 'draft-primary' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->draft()->create(), null], + 'onboarding-primary' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create(), null], + 'active-primary' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->active()->create(), 'archive'], + 'archived-primary' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->archived()->create(), 'restore'], ]); it('can prefer onboarding as the primary management action for draft-like tenants', function ( @@ -155,6 +155,6 @@ expect(app(TenantOperabilityService::class)->primaryManagementActionKey($tenant, preferOnboarding: true)) ->toBe('resume_onboarding'); })->with([ - 'draft-prefers-onboarding' => [fn (): Tenant => Tenant::factory()->draft()->create()], - 'onboarding-prefers-onboarding' => [fn (): Tenant => Tenant::factory()->onboarding()->create()], + 'draft-prefers-onboarding' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->draft()->create()], + 'onboarding-prefers-onboarding' => [fn (): ManagedEnvironment => ManagedEnvironment::factory()->onboarding()->create()], ]); diff --git a/apps/platform/tests/Unit/VerificationAssistViewModelBuilderTest.php b/apps/platform/tests/Unit/VerificationAssistViewModelBuilderTest.php index daa4dcaf..ef7577c3 100644 --- a/apps/platform/tests/Unit/VerificationAssistViewModelBuilderTest.php +++ b/apps/platform/tests/Unit/VerificationAssistViewModelBuilderTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Services\Intune\TenantRequiredPermissionsViewModelBuilder; use App\Support\Links\RequiredPermissionsLinks; use App\Support\Providers\ProviderNextStepsRegistry; @@ -16,16 +16,16 @@ uses(RefreshDatabase::class); it('derives blocked assist visibility and action availability from the stored diagnostics', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'external_id' => 'tenant-assist-blocked-a', - 'name' => 'Blocked Tenant', + 'name' => 'Blocked ManagedEnvironment', ]); $permissionsBuilder = Mockery::mock(TenantRequiredPermissionsViewModelBuilder::class); $permissionsBuilder ->shouldReceive('build') ->twice() - ->withArgs(function (Tenant $passedTenant, array $filters) use ($tenant): bool { + ->withArgs(function (ManagedEnvironment $passedTenant, array $filters) use ($tenant): bool { return (int) $passedTenant->getKey() === (int) $tenant->getKey() && ($filters['status'] ?? null) === 'all' && ($filters['type'] ?? null) === 'all' @@ -185,7 +185,7 @@ }); it('hides the assist when the verification report is ready and permission diagnostics are healthy', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'external_id' => 'tenant-assist-ready-a', ]); @@ -245,7 +245,7 @@ }); it('builds degraded fallback messaging when permission detail is stale or incomplete', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'external_id' => 'tenant-assist-degraded-a', ]); diff --git a/apps/platform/tests/Unit/VerificationLinkBehaviorTest.php b/apps/platform/tests/Unit/VerificationLinkBehaviorTest.php index 37072edd..e4f285aa 100644 --- a/apps/platform/tests/Unit/VerificationLinkBehaviorTest.php +++ b/apps/platform/tests/Unit/VerificationLinkBehaviorTest.php @@ -4,7 +4,7 @@ use App\Filament\Resources\ProviderConnectionResource; use App\Models\ProviderConnection; -use App\Models\Tenant; +use App\Models\ManagedEnvironment; use App\Support\Links\RequiredPermissionsLinks; use App\Support\Providers\ProviderReasonCodes; use App\Support\Verification\VerificationLinkBehavior; @@ -28,7 +28,7 @@ }); it('classifies required permissions links as internal diagnostic deep dives', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'external_id' => 'tenant-required-permissions-a', ]); @@ -45,15 +45,15 @@ }); it('classifies provider connection management routes as internal diagnostic deep dives', function (): void { - $tenant = Tenant::factory()->create([ + $tenant = ManagedEnvironment::factory()->create([ 'external_id' => 'tenant-provider-connections-a', ]); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, - 'tenant_id' => (int) $tenant->getKey(), + 'managed_environment_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', - 'entra_tenant_id' => (string) $tenant->tenant_id, + 'entra_tenant_id' => (string) $tenant->managed_environment_id, ]); $behavior = app(VerificationLinkBehavior::class)->describe( diff --git a/specs/167-derived-state-memoization/contracts/request-scoped-derived-state.logical.openapi.yaml b/specs/167-derived-state-memoization/contracts/request-scoped-derived-state.logical.openapi.yaml index 19e27e2c..e4637a6f 100644 --- a/specs/167-derived-state-memoization/contracts/request-scoped-derived-state.logical.openapi.yaml +++ b/specs/167-derived-state-memoization/contracts/request-scoped-derived-state.logical.openapi.yaml @@ -309,7 +309,7 @@ x-derived-state-consumers: guardScope: - app/Filament/Widgets/Dashboard/BaselineCompareNow.php requiredMarkers: - - 'private function governanceAggregate(Tenant $tenant): TenantGovernanceAggregate' + - 'private function governanceAggregate(ManagedEnvironment $tenant): TenantGovernanceAggregate' - '$this->governanceAggregate($tenant)' - 'summaryAssessment' maxOccurrences: @@ -328,7 +328,7 @@ x-derived-state-consumers: guardScope: - app/Filament/Widgets/Tenant/BaselineCompareCoverageBanner.php requiredMarkers: - - 'private function governanceAggregate(Tenant $tenant): TenantGovernanceAggregate' + - 'private function governanceAggregate(ManagedEnvironment $tenant): TenantGovernanceAggregate' - '$this->governanceAggregate($tenant)' - 'nextActionUrl' maxOccurrences: @@ -347,7 +347,7 @@ x-derived-state-consumers: guardScope: - app/Filament/Pages/BaselineCompareLanding.php requiredMarkers: - - 'private function governanceAggregate(Tenant $tenant, BaselineCompareStats $stats): TenantGovernanceAggregate' + - 'private function governanceAggregate(ManagedEnvironment $tenant, BaselineCompareStats $stats): TenantGovernanceAggregate' - '$this->governanceAggregate($tenant, $stats)' - 'Compare now' maxOccurrences: @@ -368,7 +368,7 @@ x-derived-state-consumers: guardScope: - app/Filament/Widgets/Dashboard/NeedsAttention.php requiredMarkers: - - 'private function governanceAggregate(Tenant $tenant): TenantGovernanceAggregate' + - 'private function governanceAggregate(ManagedEnvironment $tenant): TenantGovernanceAggregate' - '$this->governanceAggregate($tenant)' - 'Baseline compare posture' maxOccurrences: diff --git a/specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md b/specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md new file mode 100644 index 00000000..674416a9 --- /dev/null +++ b/specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md @@ -0,0 +1,51 @@ +# Constitution Exception Record: SCOPE-001 Managed Environment Core Cutover + +**Status**: Approved feature-local exception for Spec `279` pre-implementation gating +**Constitution Clause**: `.specify/memory/constitution.md` SCOPE-001 database convention +**Applies To**: `specs/279-workspace-managed-environment-core/` only + +## Decision + +Spec `279` is allowed to replace active core-owned `tenant_id` truth with `managed_environment_id` inside the declared cutover inventory, even though the current constitution still states that tenant-owned tables must include `workspace_id` plus `tenant_id` as `NOT NULL`. + +## Boundaries + +- This exception applies only to the declared core-owned cutover inventory in Spec `279`. +- This exception does not expand Spec `279` into the provider-connection extraction owned by Spec `281`. +- This exception does not expand Spec `279` into the broader governance-artifact retargeting owned by Spec `282`. +- Workspace entitlement and managed-environment entitlement rules remain unchanged. + +## Reason Block + +- **Product reason**: the platform core cannot become provider-neutral while the managed-target database convention still forces active core-owned truth through `tenant_id`. +- **Smallest allowed deviation**: replace `tenant_id` with `managed_environment_id` only inside the declared core-owned cutover inventory for Spec `279`. +- **What remains standardized**: workspace entitlement, managed-environment entitlement, provider-owned seams, and follow-up ownership for Specs `280`, `281`, and `282`. +- **State owner**: the existing workspace plus current-target context stack remains the owning layer for runtime resolution; this exception only changes the active managed-target key inside the bounded core inventory. + +## Architecture Note + +- `specs/279-workspace-managed-environment-core/research.md` - Decision 1: Breaking in-place cutover with no compatibility layer. +- `specs/279-workspace-managed-environment-core/data-model.md` - Section 4: Environment-scoped Foreign-Key Contract. + +## Dedicated Proof + +- `apps/platform/tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php` +- `apps/platform/tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php` +- `apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php` + +## Separate UI Exception + +- The temporary `/admin/t/{environment}` shell bridge is a separate `Cross-panel Canonical Route Exception` recorded in the spec’s shared-pattern exception slot and proven by `ManagedEnvironmentPanelContextTest.php` plus `Spec279ManagedEnvironmentCoreCutoverSmokeTest.php`. + +## Closure + +- This exception must be superseded by a constitution update once the managed-environment cutover becomes the standing database convention. +- If that constitution update lands first, this artifact becomes historical evidence only. + +## Referenced By + +- `specs/279-workspace-managed-environment-core/spec.md` +- `specs/279-workspace-managed-environment-core/plan.md` +- `specs/279-workspace-managed-environment-core/quickstart.md` +- `specs/279-workspace-managed-environment-core/tasks.md` +- `specs/279-workspace-managed-environment-core/checklists/requirements.md` \ No newline at end of file diff --git a/specs/279-workspace-managed-environment-core/checklists/requirements.md b/specs/279-workspace-managed-environment-core/checklists/requirements.md new file mode 100644 index 00000000..56d7a1a4 --- /dev/null +++ b/specs/279-workspace-managed-environment-core/checklists/requirements.md @@ -0,0 +1,62 @@ +# Specification Quality Checklist: Workspace-first Managed Environment Core Cutover + +**Purpose**: Validate specification completeness, boundedness, and readiness before implementation +**Created**: 2026-05-06 +**Feature**: [spec.md](../spec.md) + +## Content Quality + +- [x] The package stays on the first reserved cutover slice and does not silently absorb Specs `280`-`287`. +- [x] The spec remains product- and behavior-oriented instead of reading like a raw migration diff. +- [x] The package names the real repo seams it builds on: `Tenant`, `Workspace`, `TenantPanelProvider`, current context helpers, and `TenantOwnedModelFamilies`. +- [x] The temporary `/admin/t/{environment}` exception and shell bridge are explicit and bounded. + +## Requirement Completeness + +- [x] No `[NEEDS CLARIFICATION]` markers remain. +- [x] The package clearly states that `ManagedEnvironment` becomes the new active managed-target root. +- [x] The package explicitly forbids alias models, dual columns, compatibility routes, and provider-specific fields on `ManagedEnvironment`. +- [x] The package explicitly defers the broader route/IA/provider/artifact/RBAC/copy follow-up work to Specs `280`-`287`. +- [x] Canonical proof commands match across `spec.md`, `plan.md`, `quickstart.md`, and `tasks.md`. +- [x] The legacy-core proof plan explicitly covers `tenant_id` only inside the bounded core-owned cutover inventory and keeps Spec `281`/`282` residuals explicit. + +## Repo Truth Anchoring + +- [x] The package reflects that `TenantPanelProvider` currently binds `Tenant::class` on `/admin/t`. +- [x] The package reflects that current workspace and tenant context is shared through existing helper seams. +- [x] The package reflects that `Workspace` already exists as the primary SaaS context. +- [x] The package treats `TenantOwnedModelFamilies` plus schema grep as the authoritative implementation inventory for retargeting. + +## Feature Readiness + +- [x] Filament remains on Livewire v4 and provider registration remains unchanged in `apps/platform/bootstrap/providers.php`. +- [x] The package keeps current membership semantics materially unchanged while retargeting the managed-target noun. +- [x] The package defines one bounded exception note instead of leaving route behavior ambiguous. +- [x] `ManagedEnvironment` is explicitly provider-neutral. +- [x] The package records the required SCOPE-001 constitution update or explicit approved exception before implementation begins. +- [x] If any destructive action is touched in this slice, reviewer-facing checks still require `->requiresConfirmation()` and current authorization to remain intact. + +## Test Governance + +- [x] Planned proof stays bounded to one unit family, one feature family, one browser smoke, and one grep/guard check. +- [x] No heavy-governance or broad browser rollout is introduced. +- [x] Fixture replacement cost is acknowledged instead of hidden. +- [x] The review outcome, workflow outcome, and test-governance outcome are carried into `plan.md` and `tasks.md`. + +## Notes + +- Reviewed against `.specify/memory/constitution.md`, `docs/product/spec-candidates.md`, `docs/product/roadmap.md`, `apps/platform/app/Models/Tenant.php`, `apps/platform/app/Models/Workspace.php`, `apps/platform/app/Models/ProviderConnection.php`, `apps/platform/app/Providers/Filament/TenantPanelProvider.php`, and current tenant-context helper seams on 2026-05-06. +- No application implementation was performed while preparing this package. + +## Constitution Alignment Reference + +- **Current gate evidence**: `specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md` +- **Supersession rule**: replace the gate evidence above with the actual `.specify/memory/constitution.md` amendment reference once the constitution itself is updated. + +## Review Outcome + +- **Outcome class**: `documentation-required-exception` +- **Workflow outcome**: `keep` +- **Test-governance outcome**: `keep` +- **Reason**: The package is implementation-ready, but the temporary `/admin/t/{environment}` public-path retention and ManagedEnvironment-backed shell bridge are deliberate bounded exceptions that must stay documented until Spec `280` closes them. +- **Workflow result**: Ready with the approved feature-local exception in `checklists/constitution-scope-001-exception.md` until the constitution amendment supersedes it. \ No newline at end of file diff --git a/specs/279-workspace-managed-environment-core/contracts/managed-environment-core-cutover.logical.openapi.yaml b/specs/279-workspace-managed-environment-core/contracts/managed-environment-core-cutover.logical.openapi.yaml new file mode 100644 index 00000000..5c48573f --- /dev/null +++ b/specs/279-workspace-managed-environment-core/contracts/managed-environment-core-cutover.logical.openapi.yaml @@ -0,0 +1,129 @@ +openapi: 3.0.3 +info: + title: TenantPilot Admin - Managed Environment Core Cutover (Conceptual) + version: 0.1.0 + description: | + Conceptual contract for the first workspace-first / managed-environment + cutover slice. + + NOTE: This package is intentionally narrower than the full route and IA + rewrite. The current public `/admin/t/{environment}` shell is retained as a + documented temporary exception only while the bound model changes from + `Tenant` to `ManagedEnvironment`. +paths: + /choose-environment: + servers: + - url: /admin + get: + summary: Choose the active managed environment for the current workspace + description: | + The chooser is available only after workspace context is established. + It replaces the current tenant chooser with a managed-environment + selection surface. + responses: + '200': + description: Managed-environment chooser rendered + content: + text/html: + schema: + type: string + x-logical-view-model: + $ref: '#/components/schemas/ManagedEnvironmentChooserView' + '404': + $ref: '#/components/responses/NotFound' + /t/{environment}: + servers: + - url: /admin + get: + summary: Enter the current environment-scoped panel shell + description: | + This is the temporary public shell retained by Spec 279 only. + The route parameter now resolves a `ManagedEnvironment` instead of a + `Tenant`. Spec 280 owns the later public route-family rewrite. + parameters: + - $ref: '#/components/parameters/ManagedEnvironmentSlug' + responses: + '200': + description: Environment-scoped shell rendered + content: + text/html: + schema: + type: string + x-logical-view-model: + $ref: '#/components/schemas/ManagedEnvironmentContextShell' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + x-capability-rules: + workspace_membership: required + managed_environment_membership: required +components: + parameters: + ManagedEnvironmentSlug: + name: environment + in: path + required: true + schema: + type: string + responses: + Forbidden: + description: Actor is in scope but lacks the required capability on the managed environment + NotFound: + description: Wrong workspace, wrong managed environment, or non-member access is hidden as not found + schemas: + ManagedEnvironmentChooserView: + type: object + required: + - workspace + - environments + properties: + workspace: + $ref: '#/components/schemas/WorkspaceSummary' + environments: + type: array + items: + $ref: '#/components/schemas/ManagedEnvironmentSummary' + ManagedEnvironmentContextShell: + type: object + required: + - workspace + - managed_environment + - exception_note + properties: + workspace: + $ref: '#/components/schemas/WorkspaceSummary' + managed_environment: + $ref: '#/components/schemas/ManagedEnvironmentSummary' + exception_note: + type: string + example: Temporary /admin/t shell retained by Spec 279 only; closed by Spec 280. + WorkspaceSummary: + type: object + required: [id, name, slug] + properties: + id: + type: integer + name: + type: string + slug: + type: string + ManagedEnvironmentSummary: + type: object + required: [id, workspace_id, slug, name, kind, lifecycle_status] + properties: + id: + type: integer + workspace_id: + type: integer + slug: + type: string + name: + type: string + display_name: + type: string + nullable: true + kind: + type: string + lifecycle_status: + type: string \ No newline at end of file diff --git a/specs/279-workspace-managed-environment-core/data-model.md b/specs/279-workspace-managed-environment-core/data-model.md new file mode 100644 index 00000000..3e021efb --- /dev/null +++ b/specs/279-workspace-managed-environment-core/data-model.md @@ -0,0 +1,134 @@ +# Data Model: Workspace-first Managed Environment Core Cutover + +**Date**: 2026-05-06 +**Branch**: `279-workspace-managed-environment-core` + +## Overview + +This slice introduces one new managed-target root record and replaces the current tenant-core anchor. `Workspace` remains the primary SaaS context. `ManagedEnvironment` becomes the environment-scoped root record under a workspace. Current environment-scoped records retarget from `tenant_id` to `managed_environment_id` in core-owned paths only, with no compatibility columns. + +## New Persisted Truth + +### 1. Managed Environment + +**Persistence**: new `managed_environments` table +**Ownership**: managed-target root scoped to one workspace +**Lifecycle**: current-release core entity + +| Field | Type | Nullable | Notes | +|---|---|---|---| +| `id` | bigint | no | Internal primary key | +| `workspace_id` | bigint | no | Required parent workspace | +| `slug` | string | no | Neutral route key inside the workspace | +| `name` | string | no | Internal canonical name | +| `display_name` | string | yes | Operator-facing label when it differs from `name` | +| `kind` | string | no | Bounded current-release category for the managed target | +| `lifecycle_status` | string | no | Selectability and lifecycle posture for current context | +| `metadata` | jsonb | yes | Provider-neutral environment metadata only | +| `created_at` | timestamp | yes | Standard timestamp | +| `updated_at` | timestamp | yes | Standard timestamp | + +**Rules**: + +- `ManagedEnvironment` must not store Microsoft-specific identity, Graph, or Intune fields. +- `metadata` may store only neutral presentation or lifecycle hints such as internal labels, neutral tags, or operator notes; it must not store provider tenant IDs, domains, Graph scopes, consent identifiers, or raw provider profiles. +- The route key should be neutral and operator-safe. +- Archived or inactive environments are not selectable current context by default. + +### 2. Managed Environment Membership + +**Persistence**: renamed or replaced environment-membership table +**Ownership**: environment-scoped access truth + +| Field | Type | Nullable | Notes | +|---|---|---|---| +| `id` | bigint | no | Internal primary key | +| `user_id` | bigint | no | Member actor | +| `managed_environment_id` | bigint | no | Environment scope | +| `role` | string | no | Existing role semantics preserved in this slice | +| `source` | string | yes | Existing source semantics preserved where still needed | +| `source_ref` | string | yes | Existing external source reference if still used | +| `created_by_user_id` | bigint | yes | Existing audit-facing author field if still used | +| `created_at` | timestamp | yes | Standard timestamp | +| `updated_at` | timestamp | yes | Standard timestamp | + +**Rules**: + +- This slice preserves current membership semantics; it only changes the scoped target noun and foreign key. +- Workspace membership remains the first access boundary. + +## Retargeted Existing Truth + +### 3. Workspace Relation + +`Workspace` changes from `hasMany(Tenant::class)` to `hasMany(ManagedEnvironment::class)`. + +### 4. Environment-scoped Foreign-Key Contract + +Current environment-scoped records move from `tenant_id` to `managed_environment_id` in core-owned paths only. + +This package intentionally treats the precise table list as implementation inventory driven by current repo truth through `TenantOwnedModelFamilies` plus schema grep. The retargeting set is limited to current core-owned model families that use `tenant_id` as the active managed-target key in: + +- current root-selection, membership, and current-context families +- current panel/query/helper seams that need the new managed-target key to resolve scope honestly +- current commands, fixtures, and tests that resolve active target scope directly through `tenant_id` + +**Rules**: + +- no dual columns +- no `tenant_id` plus `managed_environment_id` overlap +- no alias relationships that keep both nouns active + +## Derived Runtime Contracts + +### 5. Current Context Contract + +**Persistence**: existing context/session helpers, retargeted +**Owner**: workspace + managed-environment selection flow + +| Field | Type | Required | Notes | +|---|---|---|---| +| `current_workspace_id` | int | yes | Existing primary SaaS context | +| `current_managed_environment_id` | int | yes | Replaces current tenant-scoped active target | +| `current_managed_environment_slug` | string | yes | Route-safe current target key | + +**Rules**: + +- The app must not keep an active current-tenant contract in parallel. +- Existing chooser and panel-shell flows resolve through workspace plus managed environment together. + +### 6. Temporary Environment Shell Route Contract + +**Persistence**: none, route-model binding only +**Owner**: current environment-scoped panel shell + +| Field | Type | Required | Notes | +|---|---|---|---| +| `path_family` | string | yes | Temporarily `/admin/t/{environment}` | +| `bound_model` | string | yes | `ManagedEnvironment` | +| `exception_owner` | string | yes | Spec `279`, closed by Spec `280` | + +**Rules**: + +- this is the only allowed public-path exception in this slice +- the path family must not coexist with a second compatibility route family +- the route parameter meaning changes from tenant to managed environment immediately + +## Boundaries Explicitly Preserved + +- `Workspace` remains the primary SaaS context. +- Provider-specific identity remains outside `ManagedEnvironment`. +- Provider-connection extraction and broader governance-artifact retargeting remain follow-up work for Specs `281` and `282`. +- Broader workspace-first route-family and breadcrumb rewrite remain Spec `280`. +- Provider-profile extraction remains Spec `281`. +- Artifact retargeting polish remains Spec `282`. +- RBAC redesign remains Spec `285`. +- Copy/localization neutralization remains Spec `286`. + +## Cutover Invariants + +- No active `App\Models\Tenant` remains in core-owned paths after implementation. +- No `->tenant(Tenant::class)` Filament tenant binding remains. +- No `tenant_id` compatibility columns remain in the cutover set. +- No Microsoft-specific identity fields land on `ManagedEnvironment`. +- The only temporary exception is the public `/admin/t/{environment}` path family until Spec `280`. \ No newline at end of file diff --git a/specs/279-workspace-managed-environment-core/plan.md b/specs/279-workspace-managed-environment-core/plan.md new file mode 100644 index 00000000..8370f23c --- /dev/null +++ b/specs/279-workspace-managed-environment-core/plan.md @@ -0,0 +1,259 @@ +# Implementation Plan: Workspace-first Managed Environment Core Cutover + +**Branch**: `279-workspace-managed-environment-core` | **Date**: 2026-05-06 | **Spec**: [spec.md](./spec.md) +**Input**: Feature specification from `specs/279-workspace-managed-environment-core/spec.md` + +## Summary + +Prepare the first reserved cutover slice that replaces `Tenant` as the active managed-target core with `ManagedEnvironment`. The narrow implementation path is a breaking in-place cutover: introduce the new root entity, retarget current core foreign keys and memberships to `managed_environment_id`, replace current context seams with `ManagedEnvironment`, and keep the product bootable by temporarily rebinding the existing `/admin/t/{environment}` shell to `ManagedEnvironment` until Spec `280` owns the final Workspace-tenancy and public workspace-first route rewrite. + +This plan stays intentionally narrower than the full cutover pack. Filament remains v5 on Livewire v4, provider registration remains unchanged in `apps/platform/bootstrap/providers.php`, no compatibility layer is allowed, no new asset strategy is expected, and provider-profile extraction, artifact retargeting, RBAC redesign, copy neutralization, and cutover quality-gate automation remain explicit follow-up specs. + +## Inherited Baseline / Explicit Delta + +### Inherited baseline + +- `Workspace` already exists as the SaaS and organization context. +- `Tenant` is currently the active managed-target core across models, route binding, memberships, Filament tenancy, current-target selection, and tenant-owned query helpers. +- `TenantPanelProvider` currently binds Filament tenancy directly to `Tenant::class` on the `/admin/t` path family. +- Current helper seams such as `WorkspaceContext`, `ResolvesPanelTenantContext`, `InteractsWithTenantOwnedRecords`, `ScopesGlobalSearchToTenant`, and `TenantOwnedModelFamilies` all assume `Tenant` as the active managed target. +- Current provider and governance tables still use `tenant_id` in some follow-up lanes, but their semantic retargeting remains outside this package. + +### Explicit delta in this plan + +- Introduce `ManagedEnvironment` as the new active managed-target root inside a workspace. +- Replace active core use of `Tenant` and `tenant_id` with `ManagedEnvironment` and `managed_environment_id` in core-owned paths. +- Replace current environment-membership seams and current-target context helpers in place rather than adding adapters. +- Rebind the current `/admin/t/{environment}` shell to `ManagedEnvironment` as an explicit temporary bridge while Spec `280` retains ownership of the final `Workspace` Filament-tenancy and public route-family rewrite. +- Keep provider-specific identity off `ManagedEnvironment`; follow-up Spec `281` owns the remaining provider extraction. + +## Technical Context + +**Language/Version**: PHP 8.4, Laravel 12 +**Primary Dependencies**: Filament v5, Livewire v4, Pest v4, current workspace and authorization services, current panel providers, current tenant-owned query helpers +**Storage**: PostgreSQL with destructive pre-production cutover from `tenants`/`tenant_id` to `managed_environments`/`managed_environment_id` in core-owned paths +**Testing**: Pest unit, feature, and one browser smoke +**Validation Lanes**: fast-feedback, confidence, browser +**Target Platform**: Laravel monolith in `apps/platform` +**Project Type**: web application +**Performance Goals**: keep current environment-scoped flows functionally equivalent after the cutover; no new queue or remote-call path +**Constraints**: no compatibility shims, no dual columns, no legacy alias model, no new provider-specific fields on `ManagedEnvironment`, no second route family, and no broadened route/IA rewrite in this slice +**Scale/Scope**: one breaking core entity replacement, current context and schema retargeting, and the minimum shell/route binding needed to keep the product operable + +## Likely Affected Repo Surfaces + +- `apps/platform/app/Models/Tenant.php`, `Workspace.php`, `TenantMembership.php`, and any current core-owned model family using `tenant_id` as the managed-target key. +- `apps/platform/app/Providers/Filament/TenantPanelProvider.php` and admin routes/pages that assume `Tenant` route binding or current target semantics. +- `apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php`, `InteractsWithTenantOwnedRecords.php`, and `ScopesGlobalSearchToTenant.php`. +- Current chooser/context pages such as `ChooseTenant`, current tenant dashboard pages, and any context bar partials that name the active target. +- `apps/platform/app/Support/WorkspaceIsolation/TenantOwnedModelFamilies.php` as the authoritative inventory anchor for environment-scoped model families. +- `apps/platform/app/Support/OperationRunLinks.php` and environment-scoped route builders. +- Commands, fixtures, factories, and tests that still instantiate `Tenant` or search on `tenant_id` as active core truth. + +## Filament v5 / Panel Notes + +- **Livewire v4.0+ compliance**: The cutover keeps Filament on Livewire v4 and retargets existing native panel/provider seams only. +- **Provider registration location**: Provider registration remains unchanged in `apps/platform/bootstrap/providers.php`. +- **Global search**: Existing global-search resources touched by the cutover must keep safe environment scoping and continue to satisfy the view/edit-page rule where applicable. +- **Destructive actions**: No new destructive actions are added. Any touched existing destructive actions must preserve `->requiresConfirmation()` and current authorization. +- **Asset strategy**: No new asset registration is planned. Deployment remains unchanged. + +## Managed Environment Cutover Fit + +- Use one breaking in-place cutover rather than a staged alias or compatibility layer. +- Prefer replacing existing tenant-context helpers and route binding seams in place over adding `ManagedEnvironment` adapters around `Tenant` behavior. +- Treat the current `/admin/t/{environment}` public path family as a temporary shell-level exception only. The active bound model, route parameter meaning, and current-target naming all change to `ManagedEnvironment`, while Spec `280` owns the final workspace-first route family and the final Workspace Filament-tenancy end state. +- Keep `ManagedEnvironment` provider-neutral. Fields such as Entra tenant IDs, Graph identifiers, domains, or consent details stay in provider-owned seams. + +## RBAC / Data Ownership / Auditability Fit + +- `Workspace` remains the primary SaaS context and access boundary. +- `ManagedEnvironment` becomes the environment-scoped root entity under a workspace. +- Existing tenant-membership semantics are retargeted to managed-environment memberships without expanding role or capability scope in this slice. +- Existing audit and authorization rules remain in force; the cutover changes nouns and keys, not trust boundaries. +- Any touched audit or log surface must keep environment scope truthful after the key rename. + +## UI / Surface Guardrail Plan + +- **Guardrail scope**: changed surfaces +- **Native vs custom classification summary**: native Filament +- **Shared-family relevance**: context selection, route links, context bars, global-search scoping, current-target summaries +- **State layers in scope**: shell, page, detail, URL-query +- **Audience modes in scope**: operator-MSP, support-platform +- **Decision/diagnostic/raw hierarchy plan**: decision-first on the chooser, diagnostics-second elsewhere, no new raw/debug surface +- **Raw/support gating plan**: provider-specific metadata remains off `ManagedEnvironment` and out of default chooser/shell disclosure +- **One-primary-action / duplicate-truth control**: the chooser keeps one dominant `Enter environment` action; the shell shows current context once and avoids duplicating page-level summaries +- **Handling modes by drift class or surface**: review-mandatory with one documented route exception +- **Repository-signal treatment**: temporary `/admin/t` retention is exception-required and must be recorded in the active feature close-out +- **Special surface test profiles**: standard-native-filament, global-context-shell, exception-coded-surface +- **Required tests or manual smoke**: functional-core, state-contract, manual/browser smoke +- **Exception path and spread control**: the `/admin/t/{environment}` path retention is the only allowed route exception and must not grow a second compatibility family +- **Active feature PR close-out entry**: Guardrail + +## Shared Pattern & System Fit + +- **Cross-cutting feature marker**: yes +- **Systems touched**: panel providers, chooser pages, context helpers, query helpers, route builders, current-target summaries, and environment-bound resources +- **Shared abstractions reused**: existing `WorkspaceContext`, panel providers, capability resolver, current route builders, `TenantOwnedModelFamilies` +- **New abstraction introduced? why?**: none planned; prefer replacing or renaming tenant-specific seams in place +- **Why the existing abstraction was sufficient or insufficient**: the seams are correct cutover anchors but are currently encoded with the wrong core noun +- **Bounded deviation / spread control**: one route-path exception plus one temporary shell-binding bridge only, both owned by this feature and closed by Spec `280` + +## OperationRun UX Impact + +- **Touches OperationRun start/completion/link UX?**: yes, existing deep-link resolution only +- **Central contract reused**: `OperationRunLinks` +- **Delegated UX behaviors**: environment-aware URL resolution only +- **Surface-owned behavior kept local**: none +- **Queued DB-notification policy**: `N/A` +- **Terminal notification path**: `N/A` +- **Exception path**: same temporary `/admin/t/{environment}` shell retention described above + +## Provider Boundary & Portability Fit + +- **Shared provider/platform boundary touched?**: yes +- **Provider-owned seams**: current provider identity, Graph consent, provider metadata, Microsoft-specific identifiers +- **Platform-core seams**: managed-target root entity, workspace-to-environment relationship, route binding, current-target context, operator vocabulary +- **Neutral platform terms / contracts preserved**: `workspace`, `managed environment`, `provider connection`, `target scope` +- **Retained provider-specific semantics and why**: provider-specific identity remains where it already belongs until Spec `281` extracts it cleanly +- **Bounded extraction or follow-up path**: Specs `281`, `284`, and `286` + +## Constitution Check + +*GATE: Must pass before implementation begins and again after the design artifacts are complete.* + +- Inventory-first / snapshot truth: PASS. The cutover changes the managed-target root, not inventory or snapshot semantics. +- Read/write separation: PASS. No new operator write workflow or remote call path is introduced. +- Graph contract path: PASS. No new Graph call or contract registry change is required in this slice. +- Deterministic capabilities: PASS. Current capability semantics remain and are retargeted to managed-environment membership. +- Workspace and tenant isolation: EXCEPTION-REQUIRED. Workspace remains the primary boundary and managed-environment membership remains the scoped target boundary, but SCOPE-001 still hardcodes `tenant_id` as the required managed-target key until the constitution is amended or an explicit approved exception is recorded for this cutover inventory. +- RBAC-UX plane separation: PASS. `/admin` and `/system` remain separate. +- Destructive action discipline: PASS by non-expansion. Existing destructive actions keep current confirmation requirements. +- Global search safety: PASS if all touched resources keep environment-safe scoping. +- OperationRun / Ops-UX: PASS. Only deep-link resolution changes. +- Data minimization: PASS. Provider-specific identity stays out of `ManagedEnvironment`. +- Test governance: PASS. Planned proof is bounded to unit, feature, browser, and guard checks. +- Proportionality / no premature abstraction: PASS. The cutover replaces a wrong root concept instead of layering a framework. +- Persisted truth: PASS. New persistence is justified because the managed-target root has independent product truth. +- Behavioral state: PASS. `kind` and lifecycle posture exist only to support current target selection and filtering, not a new semantic framework. +- UI semantics / shared pattern first / Filament-native UI: PASS. Native panel/provider seams remain the first path. +- Provider boundary: PASS. Neutral core noun is introduced explicitly. + +**Gate evaluation**: PASS with approved feature-local exception in place. + +**Post-design re-check**: PASS while `research.md`, `data-model.md`, `quickstart.md`, `contracts/managed-environment-core-cutover.logical.openapi.yaml`, `checklists/requirements.md`, `checklists/constitution-scope-001-exception.md`, and `tasks.md` remain aligned and the approved exception record stays valid. + +**Implementation gate reference**: `specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md` is the current approved-exception artifact for this package. Phase 2 may not begin unless that path remains valid or is replaced by the actual constitution-amendment reference. + +## Test Governance Check + +- **Test purpose / classification by changed surface**: Unit, Feature, Browser +- **Affected validation lanes**: fast-feedback, confidence, browser +- **Why this lane mix is the narrowest sufficient proof**: the cutover changes core identity, panel binding, and shell context. Unit tests prove model/context rules, feature tests prove authorization and route binding, and one browser smoke proves the end-to-end chooser/shell path remains operable. +- **Narrowest proving command(s)**: + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php)` + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentAuthorizationTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php)` + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec279ManagedEnvironmentCoreCutoverSmokeTest.php)` + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent)` + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && rg -n --fixed-strings 'App\Models\Tenant' "$REPO_ROOT/apps/platform/app" "$REPO_ROOT/apps/platform/tests" "$REPO_ROOT/apps/platform/database"` + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && rg -n -- '->tenant\(Tenant::class' "$REPO_ROOT/apps/platform/app" "$REPO_ROOT/apps/platform/tests" "$REPO_ROOT/apps/platform/database"` +- **Fixture / helper / factory / seed / context cost risks**: moderate because current tenant fixtures must be replaced, not wrapped +- **Expensive defaults or shared helper growth introduced?**: no; keep helper replacement explicit and local +- **Heavy-family additions, promotions, or visibility changes**: none +- **Surface-class relief / special coverage rule**: one browser smoke required because the shell/context flow changes end-to-end +- **Closing validation and reviewer handoff**: rerun the exact commands above, confirm the temporary route exception is documented and bounded, confirm `LegacyTenantCoreGuardTest.php` proves `tenant_id` removal only inside the declared core-owned cutover inventory with explicit Spec `281` and `282` exclusions, confirm no provider-specific fields land on `ManagedEnvironment`, confirm any touched globally searchable resource still satisfies Filament’s edit/view eligibility rule or remains out of global search, confirm no new asset registration or deployment-step change was introduced, and confirm provider registration remains unchanged +- **Budget / baseline / trend follow-up**: contained feature-local increase only +- **Review-stop questions**: did a compatibility layer appear, did provider-specific identity leak onto `ManagedEnvironment`, did the route exception spread, did any core-owned `Tenant` references survive, did any unapproved `tenant_id` usage remain inside the declared core-owned cutover inventory, and did any touched destructive action lose `->requiresConfirmation()` or current authorization +- **Escalation path**: `document-in-feature` for the temporary route exception; `follow-up-spec` already assigned for remaining pack work +- **Active feature PR close-out entry**: Guardrail +- **Why no dedicated follow-up spec is needed**: this package already owns the first cutover slice; the remaining strategic steps are already reserved as Specs `280`-`287` + +## Review Checklist Status + +- **Review checklist artifact**: `checklists/requirements.md` +- **Review outcome class**: `documentation-required-exception` +- **Workflow outcome**: `keep` +- **Test-governance outcome**: `keep` +- **Escalation rule**: if implementation adds compatibility layers, a second route family, provider-specific fields on `ManagedEnvironment`, or absorbs Spec `280`-`287` scope, flip the workflow outcome to `split` or `reject-or-split` + +## Rollout Considerations + +- Land the schema/entity cutover and current-context replacement before broad page/UI cleanup. +- Keep the temporary `/admin/t/{environment}` path exception explicit and minimal. +- Replace fixtures, factories, and guard tests in the same cutover PR so mixed core nouns do not linger. +- Use the feature-local guard tests and grep checks to keep `Tenant` from re-entering core-owned paths while the rest of the pack is still pending. + +## Risk Controls + +- Reject any implementation that introduces an alias `Tenant` model, dual columns, or compatibility writes. +- Reject any implementation that moves provider-specific identity onto `ManagedEnvironment`. +- Reject any implementation that keeps both `/admin/t/{environment}` and a new workspace-first route family active in the same slice. +- Reject any implementation that absorbs the broader Spec `280` route/IA rewrite, Spec `281` provider extraction, or Spec `285` RBAC redesign. + +## Research & Design Outputs + +- `research.md` records the no-compatibility cutover, temporary route-path exception, provider-boundary discipline, helper-replacement strategy, and proof strategy. +- `data-model.md` captures the `ManagedEnvironment` entity, membership retargeting, current-context model, and foreign-key cutover rules. +- `quickstart.md` provides the bounded reviewer flow and exact validation commands. +- `contracts/managed-environment-core-cutover.logical.openapi.yaml` captures the logical chooser and temporary environment-shell route contract. +- `checklists/requirements.md` records the review outcome, workflow outcome, and test-governance outcome. +- `tasks.md` sequences the cutover work and keeps the remaining pack scope deferred. + +## Project Structure + +### Documentation (this feature) + +```text +specs/279-workspace-managed-environment-core/ +├── checklists/ +│ ├── constitution-scope-001-exception.md +│ └── requirements.md +├── contracts/ +│ └── managed-environment-core-cutover.logical.openapi.yaml +├── data-model.md +├── plan.md +├── quickstart.md +├── research.md +├── spec.md +└── tasks.md +``` + +### Source Code (expected implementation surfaces) + +```text +apps/platform/ +├── app/ +│ ├── Filament/ +│ │ ├── Concerns/ +│ │ │ ├── InteractsWithTenantOwnedRecords.php +│ │ │ ├── ResolvesPanelTenantContext.php +│ │ │ └── ScopesGlobalSearchToTenant.php +│ │ ├── Pages/ +│ │ │ └── ChooseTenant.php +│ │ └── Resources/ +│ │ └── TenantResource.php +│ ├── Models/ +│ │ ├── Workspace.php +│ │ ├── Tenant.php +│ │ └── ProviderConnection.php +│ ├── Providers/Filament/ +│ │ ├── AdminPanelProvider.php +│ │ └── TenantPanelProvider.php +│ ├── Support/ +│ │ ├── OperationRunLinks.php +│ │ ├── WorkspaceIsolation/ +│ │ │ └── TenantOwnedModelFamilies.php +│ │ └── Workspaces/ +│ │ └── WorkspaceContext.php +│ └── Services/Auth/ +│ └── WorkspaceCapabilityResolver.php +├── database/ +│ ├── factories/ +│ └── migrations/ +└── tests/ + ├── Browser/ + ├── Feature/ManagedEnvironment/ + └── Unit/ManagedEnvironment/ +``` + +**Structure decision**: keep the documentation package self-contained under `specs/279-workspace-managed-environment-core/`; implementation later replaces the core managed-target seams in `apps/platform/` directly instead of introducing a separate cutover package or adapter layer. \ No newline at end of file diff --git a/specs/279-workspace-managed-environment-core/quickstart.md b/specs/279-workspace-managed-environment-core/quickstart.md new file mode 100644 index 00000000..e2bede10 --- /dev/null +++ b/specs/279-workspace-managed-environment-core/quickstart.md @@ -0,0 +1,43 @@ +# Quickstart: Workspace-first Managed Environment Core Cutover + +## Reviewer Flow + +1. Read [spec.md](./spec.md), [plan.md](./plan.md), [research.md](./research.md), and [data-model.md](./data-model.md) together. +2. Confirm the bounded scope: this package owns the breaking core entity cutover only, not the full route/IA/provider/artifact/RBAC pack. +3. Confirm the one documented exception: temporary `/admin/t/{environment}` retention while the bound model changes to `ManagedEnvironment`. +4. Confirm the temporary shell bridge is explicit and that the final `Workspace` Filament-tenancy end state remains deferred to Spec `280`. +5. Confirm `ManagedEnvironment` stays provider-neutral and that provider-specific identity remains follow-up work. +6. Confirm `specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md` remains the active constitution-gate evidence, or replace it with the actual constitution-amendment reference before treating the package as implementation-startable. +7. Confirm the planned proof suite below is consistent across `spec.md`, `plan.md`, and `tasks.md`. + +## Planned Validation Commands + +```bash +export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php) + +export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentAuthorizationTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php) + +export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec279ManagedEnvironmentCoreCutoverSmokeTest.php) + +export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent) + +export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && rg -n --fixed-strings 'App\Models\Tenant' "$REPO_ROOT/apps/platform/app" "$REPO_ROOT/apps/platform/tests" "$REPO_ROOT/apps/platform/database" + +export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && rg -n -- '->tenant\(Tenant::class' "$REPO_ROOT/apps/platform/app" "$REPO_ROOT/apps/platform/tests" "$REPO_ROOT/apps/platform/database" +``` + +## Review Questions + +- Does the package avoid alias models, dual columns, and dual route families? +- Is the `/admin/t/{environment}` exception explicit, bounded, and owned by Spec `279` only? +- Is the temporary ManagedEnvironment-backed shell bridge explicit, and is the final `Workspace` Filament-tenancy end state still clearly deferred to Spec `280`? +- Does the legacy-core guard prove `tenant_id` removal inside the declared core-owned cutover inventory while leaving Spec `281` and `282` residuals explicit? +- If any destructive action is touched during implementation, does it still preserve `->requiresConfirmation()` and current authorization? +- If any globally searchable resource is touched, does it still satisfy Filament’s edit/view eligibility rule or remain out of global search, and did the slice avoid any new asset registration or deployment-step change? +- Does the package keep provider-specific identity off `ManagedEnvironment`? +- Are Specs `280`-`287` still explicitly deferred instead of being silently absorbed? + +## Notes + +- No application implementation was performed while preparing this package. +- The package is ready with the approved feature-local exception in place while `specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md` remains the active gate evidence, or once it is superseded by the constitution update itself. \ No newline at end of file diff --git a/specs/279-workspace-managed-environment-core/research.md b/specs/279-workspace-managed-environment-core/research.md new file mode 100644 index 00000000..7b56e684 --- /dev/null +++ b/specs/279-workspace-managed-environment-core/research.md @@ -0,0 +1,61 @@ +# Research: Workspace-first Managed Environment Core Cutover + +**Date**: 2026-05-06 +**Branch**: `279-workspace-managed-environment-core` + +## Decision 1: Use one breaking in-place cutover with no `Tenant` compatibility layer + +- **Decision**: Replace `Tenant` as the active managed-target core directly instead of introducing alias models, dual-read paths, or dual-write migrations. +- **Rationale**: The repo is still pre-production, the constitution explicitly rejects speculative compatibility paths, and the current coupling spans too many seams for an adapter layer to stay honest. +- **Alternatives considered**: + - `Tenant` wrapper over `ManagedEnvironment`: rejected because it would preserve the wrong core truth and spread mixed nouns. + - dual columns (`tenant_id` plus `managed_environment_id`): rejected because it would violate the pre-production lean doctrine and make later specs harder, not easier. + +## Decision 2: Keep the current `/admin/t/{environment}` path temporarily as the only bounded exception + +- **Decision**: Allow the existing public `/admin/t/{environment}` path family to remain temporarily while rebinding it to `ManagedEnvironment`. +- **Rationale**: The current cutover already replaces the core entity, memberships, query helpers, and panel binding. Folding the full workspace-first public route rewrite into the same slice would collapse Spec `280` into `279` and make the first cutover package too broad. +- **Alternatives considered**: + - immediate public route-family rewrite: rejected because it belongs to Spec `280` and would widen review scope too far. + - second compatibility route family: rejected because the cutover must not carry two public path families at once. + +## Decision 3: Replace current tenant-context helpers in place instead of layering new adapters + +- **Decision**: Retarget or rename the existing tenant-context seams (`WorkspaceContext`, Filament panel binding, resource query helpers, global-search helpers, route builders) in place. +- **Rationale**: The current helper seams are the correct ownership points. A new parallel `ManagedEnvironmentContext` layer wrapped around tenant helpers would create drift immediately. +- **Alternatives considered**: + - keep tenant helpers and add environment adapters: rejected because it creates a second context vocabulary. + - local page-by-page context replacement: rejected because the problem is cross-cutting and shared. + +## Decision 4: Keep `ManagedEnvironment` provider-neutral and defer provider extraction to Spec `281` + +- **Decision**: `ManagedEnvironment` owns neutral managed-target identity only. Provider-specific fields such as Entra tenant IDs, Graph configuration, domains, or consent details stay outside the new root entity. +- **Rationale**: The whole point of the cutover is to stop provider-specific semantics from defining the platform core. The repo already has provider-owned seams that can carry this data until Spec `281` normalizes them. +- **Alternatives considered**: + - copy current `Tenant` provider fields to `ManagedEnvironment`: rejected because it would deepen Microsoft coupling. + - extract provider profiles in the same slice: rejected because Spec `281` already owns that follow-up. + +## Decision 5: Retarget membership semantics without broad RBAC redesign + +- **Decision**: Replace current tenant-membership truth with managed-environment membership truth while preserving current workspace and capability semantics. +- **Rationale**: The cutover needs environment-scoped access control to keep current pages safe, but a broader RBAC scope redesign is already reserved for Spec `285`. +- **Alternatives considered**: + - leave memberships tenant-shaped temporarily: rejected because the active root model would still leak tenant-core assumptions. + - widen capabilities or role families now: rejected because that would collapse Spec `285` into the core cutover. + +## Decision 6: Use unit + feature + browser + guard checks as the narrowest honest proof + +- **Decision**: Plan one managed-environment unit family, one feature family, one browser smoke, and one legacy-core guard family. +- **Rationale**: The cutover changes both internal identity rules and end-to-end context selection. Feature tests alone are not enough to prove the shell/chooser still works, and browser coverage alone would hide legacy-core drift. +- **Alternatives considered**: + - feature tests only: rejected because the cutover changes end-to-end context entry. + - heavy-governance or multi-browser rollout: rejected because the slice is core infrastructure, not new multi-surface behavior. + +## Final Research Outcome + +- `279` should remain the breaking core entity cutover only. +- The only allowed public-path deviation is temporary `/admin/t/{environment}` retention while it binds `ManagedEnvironment`. +- Existing tenant-context seams should be replaced in place, not wrapped. +- `ManagedEnvironment` must stay provider-neutral. +- Membership semantics move with the core entity, but broader RBAC redesign remains deferred. +- Unit, feature, browser, and guard coverage together are the narrowest honest proof. \ No newline at end of file diff --git a/specs/279-workspace-managed-environment-core/spec.md b/specs/279-workspace-managed-environment-core/spec.md new file mode 100644 index 00000000..1b109d7f --- /dev/null +++ b/specs/279-workspace-managed-environment-core/spec.md @@ -0,0 +1,318 @@ +# Feature Specification: Workspace-first Managed Environment Core Cutover + +**Feature Branch**: `279-workspace-managed-environment-core` +**Created**: 2026-05-06 +**Status**: Ready with approved feature-local exception +**Input**: User description: "Use the next unspecced reserved cutover slot from the roadmap/spec-candidate pack and prepare the `Workspace-first Managed Environment Core Cutover` package as the next bounded implementation-ready spec." + +## Spec Candidate Check + +- **Problem**: TenantPilot still treats `Tenant` as the active managed-target core across models, route binding, Filament tenancy, memberships, query helpers, and operator context. That blocks the planned workspace-first / provider-neutral evolution because the platform core still assumes the managed target is a Microsoft-shaped tenant instead of a generic managed environment inside a workspace. +- **Today's failure**: Current repo seams such as `TenantPanelProvider`, `Tenant`, `ProviderConnection::tenant()`, tenant-owned query helpers, `Filament::getTenant()` usage, and many `tenant_id` foreign keys force every new workspace-first or provider-neutral change to either deepen `Tenant` coupling or add compatibility shims the constitution explicitly rejects. +- **User-visible improvement**: Operators and future features get one consistent managed-target identity inside a workspace. Context selection, authorization boundaries, route binding, and current environment-scoped surfaces stop depending on `Tenant` as platform-core truth. +- **Smallest enterprise-capable version**: Replace `Tenant` as the active managed-target core with `ManagedEnvironment`, retarget current core foreign-key anchors and context helpers to `managed_environment_id`, keep the existing panel bootable by temporarily rebinding the current `/admin/t/{environment}` path family to `ManagedEnvironment`, and defer the public workspace-first route/IA rewrite, provider-profile extraction, artifact retargeting refinements, and RBAC scope redesign to follow-up specs `280`-`287`. +- **Explicit non-goals**: No dual-read or dual-write compatibility layer, no legacy `Tenant` alias model, no production-data backfill strategy, no full workspace-first public route-family rewrite, no provider-profile extraction, no artifact-language rewrite, no package engine, no guided-operations layer, and no speculative multi-provider framework. +- **Permanent complexity imported**: One new managed-target root entity, one breaking schema cutover from `tenant_id` to `managed_environment_id`, one renamed environment-membership seam, existing context-helper replacement, and focused unit/feature/browser plus guard-test coverage. +- **Why now**: `279` is the first unspecced reserved slot in the roadmap-backed cutover pack, and every later cutover spec (`280`-`287`) depends on this core replacement. Waiting adds more `Tenant`- and Microsoft-specific coupling to the platform core. +- **Why not local**: The problem spans schema, Eloquent relations, route binding, Filament tenancy, current-context resolution, authorization helpers, commands, and tests. A local rename or adapter would immediately drift. +- **Approval class**: Core Enterprise +- **Red flags triggered**: New persisted truth, new state family, many touched seams, and a foundation-sounding cutover. Defense: this is current-release architecture truth, not speculative extensibility; it explicitly forbids compatibility shims and defers broader route, copy, provider, and artifact follow-through to the next reserved specs. +- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 1 | Komplexitaet: 1 | Produktnaehe: 1 | Wiederverwendung: 2 | **Gesamt: 9/12** +- **Decision**: approve + +## Spec Scope Fields + +- **Scope**: workspace +- **Primary Routes**: + - existing workspace chooser route under `/admin` + - existing tenant chooser surface, retargeted to managed-environment selection + - current environment-scoped panel routes under `/admin/t/{environment}` as a temporary bounded exception until Spec `280` replaces the public path family + - current admin resource/detail routes that bind the managed target model directly or derive environment context from it +- **Data Ownership**: + - `Workspace` remains the primary SaaS and organization context + - `ManagedEnvironment` becomes the new managed-target root record inside a workspace + - current core-owned managed-target anchors and context-owned relations retarget from `tenant_id` to `managed_environment_id`; provider-connection extraction and broader governance-artifact retargeting remain follow-up work for Specs `281` and `282` +- **RBAC**: + - workspace membership remains the first isolation boundary + - current tenant-membership semantics are retargeted to managed-environment membership semantics without widening role scope in this spec + - wrong-workspace and non-member access remain `404` + - in-scope actors missing a capability remain `403` + +Canonical-view handling for current admin surfaces: + +- **Default filter behavior when tenant-context is active**: current canonical admin views continue to prefilter to the active managed environment whenever they currently prefilter to the active tenant; broader workspace-first canonical-view semantics remain Spec `280` follow-up work +- **Explicit entitlement checks preventing cross-tenant leakage**: any route, query helper, or global-search path that currently resolves tenant scope must resolve the active managed environment plus current workspace membership before revealing environment-bound records + +## Cross-Cutting / Shared Pattern Reuse + +- **Cross-cutting feature?**: yes +- **Interaction class(es)**: context selection, route links, global-search scoping, current-target chips, resource query helpers, and environment-bound deep links +- **Systems touched**: `TenantPanelProvider`, `WorkspaceContext`, `ChooseTenant`, `ResolvesPanelTenantContext`, `InteractsWithTenantOwnedRecords`, `ScopesGlobalSearchToTenant`, `TenantOwnedModelFamilies`, `OperationRunLinks`, current tenant widgets, and tenant-scoped resources/pages +- **Existing pattern(s) to extend**: workspace-first context storage, current Filament panel-provider seams, current deny-as-not-found membership enforcement, and existing environment-bound route builders +- **Shared contract / presenter / builder / renderer to reuse**: existing `WorkspaceContext`, panel-provider registration, current resource query scoping helpers, `OperationRunLinks`, and the existing workspace capability resolver +- **Why the existing shared path is sufficient or insufficient**: those seams are sufficient as cutover points, but insufficient because they still encode `Tenant` as the platform-core managed target +- **Exception type**: `Cross-panel Canonical Route Exception` +- **Allowed deviation and why**: one bounded deviation is allowed: the current `/admin/t/{environment}` shell may remain temporarily while binding `ManagedEnvironment` instead of `Tenant`, even though the source-pack end state moves Filament tenancy to `Workspace` in Spec `280`. This temporary bridge exists only to keep the runtime operable while `Tenant` is removed from the core. No second compatibility route family is allowed. +- **Reason block**: only one canonical surface makes sense during the cutover. Keeping the existing shell avoids a second public route family, keeps shell transition explicit, preserves truthful scope signals, and leaves final canonical Workspace tenancy to Spec `280`. +- **Dedicated proof**: `apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php`, `apps/platform/tests/Browser/Spec279ManagedEnvironmentCoreCutoverSmokeTest.php`, and `specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md` +- **Consistency impact**: route keys, chooser labels, context bars, global-search scope resolution, tenant-owned query helpers, and deep-link builders must all agree on `ManagedEnvironment` as the active managed target +- **Review focus**: reviewers must verify that the cutover replaces current shared seams in place, that the temporary `/admin/t` path is the only documented exception, and that no alias model or second context stack appears + +## OperationRun UX Impact + +- **Touches OperationRun start/completion/link UX?**: yes, link semantics only +- **Shared OperationRun UX contract/layer reused**: `OperationRunLinks` and the existing OperationRun URL-resolution helpers +- **Delegated start/completion UX behaviors**: tenant/workspace-safe environment link resolution only; no new queued toasts, start events, completion notifications, or dedupe messaging are added in this slice +- **Local surface-owned behavior that remains**: none; existing surfaces continue to use the central OperationRun link helpers after their context model is retargeted +- **Queued DB-notification policy**: `N/A` +- **Terminal notification path**: `N/A` +- **Exception required?**: yes - the temporary `/admin/t/{environment}` path retention described above. This is a bounded route exception only and does not permit a second compatibility family. + +## Provider Boundary / Platform Core Check + +- **Shared provider/platform boundary touched?**: yes +- **Boundary classification**: mixed +- **Seams affected**: managed-target identity, provider-connection foreign-key anchors, current context model, operator vocabulary, route binding, and current target selection +- **Neutral platform terms preserved or introduced**: `workspace`, `managed environment`, `provider connection`, `target scope`, `operation`, `finding`, `review`, and `governance artifact` +- **Provider-specific semantics retained and why**: Microsoft-specific identifiers such as `entra_tenant_id`, Graph consent details, and portal metadata may remain in provider-owned tables or provider metadata until Spec `281` extracts and normalizes them. They must not live on `ManagedEnvironment`. +- **Why this does not deepen provider coupling accidentally**: the core cutover explicitly forbids Microsoft-specific identity, Graph, or Intune fields on `ManagedEnvironment` and replaces `Tenant` as the shared core noun +- **Follow-up path**: Spec `281` for provider-profile extraction, Spec `284` for provider-neutral artifact-source taxonomy, and Spec `286` for copy/localization cleanup + +## UI / Surface Guardrail Impact + +| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note | +|---|---|---|---|---|---|---| +| Managed-environment chooser replacing current tenant chooser | yes | Native Filament page | context selection, navigation entry point | page, URL/query | no | Keeps the existing chooser family and retargets it to managed environments | +| Current environment-scoped panel routes under `/admin/t/{environment}` | yes | Native Filament panel shell | route links, context bar, global search, resource scope | shell, page, detail, URL/query | yes | Temporary path retention only until Spec `280` owns the public route-family rewrite | +| Admin directory/resource surfaces that currently list `Tenant` records | yes | Native Filament resources/pages | detail links, current-target summaries | page, detail | no | Core noun and route binding change here; broader IA and copy polish remain deferred | + +## Decision-First Surface Role + +| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction | +|---|---|---|---|---|---|---|---| +| Managed-environment chooser | Primary Decision Surface | Operator selects the current managed target inside the active workspace | environment name, display name, lifecycle posture, and current workspace | provider-specific diagnostics stay secondary and remain follow-up work | Primary because current environment selection is the first explicit decision before any environment-scoped workflow begins | Keeps the existing current-target selection workflow intact | Removes ambiguity between workspace scope and managed-target scope | +| Current environment-scoped panel shell | Secondary Context Surface | Operator verifies they are acting in the correct managed environment while using existing pages | active workspace plus active managed-environment identity | deeper provider or governance detail remains on the current pages | Not primary because it carries context while work happens elsewhere | Aligns with existing panel-shell behavior instead of inventing a new workbench | Reduces wrong-target actions during the cutover | + +## Audience-Aware Disclosure + +| Surface | Audience Modes In Scope | Decision-First Default-Visible Content | Operator Diagnostics | Support / Raw Evidence | One Dominant Next Action | Hidden / Gated By Default | Duplicate-Truth Prevention | +|---|---|---|---|---|---|---|---| +| Managed-environment chooser | operator-MSP, support-platform | environment identity, display name, lifecycle posture, and workspace context | provider-health detail and migration notes remain secondary | raw provider metadata stays hidden | `Enter environment` | provider-specific raw metadata | chooser cards show selection truth once and defer diagnostics | +| Current environment-scoped panel shell | operator-MSP, support-platform | active workspace and active managed-environment context | deeper per-page diagnostics remain where they already live | raw payloads remain page-local and secondary | existing page action | any migration/debug hints stay lower-priority | shell surfaces should not repeat full page-level summaries | + +## UI/UX Surface Classification + +| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification | +|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +| Managed-environment chooser | Selector / Context / Entry | Context-selection page | Enter the intended managed environment | card/list selection | optional current pattern | workspace switch remains secondary | none | `/admin/choose-environment` (logical) | environment entry path | active workspace plus environment identity | Managed environment | selected target identity and lifecycle posture | none | +| Current environment-scoped panel shell | Shell / Context / Navigation | Filament panel shell | Continue into the current environment page | current shell context | forbidden | page-local links stay secondary | none | `/admin/t/{environment}` (temporary) | existing page routes under the shell | active workspace plus active managed environment | Managed environment | current environment identity | temporary route retention until Spec `280` | + +## Operator Surface Contract + +| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions | +|---|---|---|---|---|---|---|---|---|---|---| +| Managed-environment chooser | TenantPilot operator | Decide which managed environment inside the current workspace should become active | Context-selection page | Which managed environment am I about to act in? | environment identity, workspace context, lifecycle posture | provider-specific diagnostics and migration detail | lifecycle, access posture | none | Enter environment | none | +| Current environment-scoped panel shell | TenantPilot operator | Confirm that all current environment-bound pages resolve the right managed target | Panel shell | Am I in the correct workspace and managed environment? | active workspace and active managed-environment identity | page-local diagnostics only | access posture, lifecycle | none | existing page action | none | + +## Proportionality Review + +- **New source of truth?**: yes +- **New persisted entity/table/artifact?**: yes +- **New abstraction?**: no new generic abstraction; existing tenant-context seams are replaced or neutralized in place +- **New enum/state/reason family?**: yes, bounded managed-environment kind and lifecycle posture fields +- **New cross-domain UI framework/taxonomy?**: no +- **Current operator problem**: the product cannot become workspace-first or provider-neutral while the core managed target, current context, and route binding still assume `Tenant` +- **Existing structure is insufficient because**: the current `Tenant` model mixes managed-target identity, provider-specific metadata, current-context behavior, and Filament tenant binding across the app +- **Narrowest correct implementation**: a single breaking core cutover to `ManagedEnvironment` with one documented temporary route-path exception and no compatibility aliases +- **Ownership cost**: broad schema and relation retargeting, command and test updates, temporary exception tracking for `/admin/t/{environment}`, and explicit follow-up ownership for Specs `280`-`287` +- **Alternative intentionally rejected**: dual-read/dual-write aliases, a `Tenant` wrapper around `ManagedEnvironment`, or one giant combined route/IA/provider/artifact rewrite. Those options either violate the constitution or make the first cutover slice too broad to review safely. +- **Release truth**: current-release truth with explicit follow-up slices for the remaining cutover pack + +### Compatibility posture + +This feature assumes a pre-production environment. + +Backward compatibility, legacy aliases, dual-read/dual-write shims, historical fixtures, and compatibility-specific tests are out of scope unless explicitly required by this spec. + +Canonical replacement is preferred over preservation. + +## Testing / Lane / Runtime Impact + +- **Test purpose / classification**: Unit, Feature, Browser +- **Validation lane(s)**: fast-feedback, confidence, browser +- **Why this classification and these lanes are sufficient**: the cutover changes core model truth, route/model binding, and Filament context selection. Unit tests prove model and context rules, feature tests prove scope and routing semantics, and one browser smoke proves the workspace-to-environment selection flow stays operable after the cutover. +- **New or expanded test families**: one managed-environment unit family, one managed-environment feature family, and one narrow browser smoke +- **Fixture / helper cost impact**: moderate; existing tenant fixtures and helper families must be replaced with managed-environment equivalents rather than layered adapters +- **Heavy-family visibility / justification**: none +- **Special surface test profile**: standard-native-filament, global-context-shell, exception-coded-surface +- **Standard-native relief or required special coverage**: standard Filament feature coverage is sufficient for chooser and panel-context semantics; one browser smoke is required because the cutover changes end-to-end context selection and panel bootstrapping +- **Reviewer handoff**: reviewers must verify that `ManagedEnvironment` replaces `Tenant` in core-owned paths, the temporary `/admin/t` exception is the only path deviation, the legacy-core guard proves `tenant_id` removal inside the declared core-owned cutover inventory while keeping Specs `281` and `282` exclusions explicit, `ManagedEnvironment` carries no Microsoft-specific identity fields, any touched globally searchable resource still satisfies Filament’s edit/view eligibility rule or remains out of global search, no new asset registration or deployment-step change appears, and provider registration remains in `apps/platform/bootstrap/providers.php` +- **Budget / baseline / trend impact**: moderate feature-local increase only +- **Escalation needed**: `document-in-feature` for the temporary `/admin/t` path exception; `follow-up-spec` already assigned for the remaining cutover pack +- **Active feature PR close-out entry**: Guardrail +- **Planned validation commands**: + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php)` + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentAuthorizationTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php)` + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec279ManagedEnvironmentCoreCutoverSmokeTest.php)` + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent)` + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && rg -n --fixed-strings 'App\Models\Tenant' "$REPO_ROOT/apps/platform/app" "$REPO_ROOT/apps/platform/tests" "$REPO_ROOT/apps/platform/database"` + - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && rg -n -- '->tenant\(Tenant::class' "$REPO_ROOT/apps/platform/app" "$REPO_ROOT/apps/platform/tests" "$REPO_ROOT/apps/platform/database"` + +## Scope Boundaries *(required for this slice)* + +### In Scope + +- introduce `ManagedEnvironment` as the active managed-target root inside a workspace +- introduce the breaking schema/model cutover away from `Tenant` and `tenant_id` in core-owned paths +- retarget current context selection, route binding, query helpers, memberships, and the current tenant-panel shell bridge to `ManagedEnvironment` while keeping the final `Workspace` Filament-tenancy switch deferred to Spec `280` +- keep the current environment-scoped panel operable through the documented temporary `/admin/t/{environment}` exception until Spec `280` +- update factories, seeders, policies, guards, route binding, and tests so core-owned paths no longer rely on `App\Models\Tenant` +- ensure `ManagedEnvironment` carries no Microsoft-specific identity, Graph, or Intune fields + +### Non-Goals + +- final workspace-first public route family and navigation IA rewrite +- provider-profile extraction and provider-scope normalization +- governance artifact naming and route retargeting polish +- RBAC scope redesign or new capability families +- copy/localization neutralization beyond the minimum core cutover terms +- quality-gate automation beyond the feature-local guard tests needed for this slice +- package execution, guided operations, virtual consultant, or any new provider implementation + +## Assumptions + +- the repo remains pre-production, so destructive in-place replacement is acceptable and compatibility shims are not +- the temporary `/admin/t/{environment}` path retention is the only allowed path exception for this slice +- broader workspace-first IA, provider extraction, artifact retargeting, and RBAC scoping remain explicitly deferred to Specs `280`-`287` +- current workspace membership and capability semantics stay materially unchanged in this slice; only the managed-target noun and foreign-key anchors move + +## Risks + +- the implementation could accidentally combine the core cutover with the public route/IA rewrite, which would make review and rollback reasoning too broad +- lingering `Tenant` references in commands, tests, or helper traits could hide cutover drift and produce mixed context behavior +- provider-specific identity could accidentally land on `ManagedEnvironment` if current `Tenant` fields are copied forward without discipline +- the temporary `/admin/t` exception could become permanent if Spec `280` is not treated as mandatory follow-up + +## Candidate Selection Gate Summary + +- **Selected candidate**: `279 - Workspace-first Managed Environment Core Cutover` +- **Source locations**: + - `docs/product/spec-candidates.md` under the `Workspace-first / ManagedEnvironment Core Cutover candidate pack` + - `docs/product/roadmap.md` under the planned cutover pack ordering +- **Why selected now**: `279` is the first unspecced reserved slot in the cutover pack and is the prerequisite for the remaining reserved follow-ups +- **Why close alternatives were deferred**: + - `280` depends on the core entity and context replacement from `279` + - `281` depends on the new managed-target root before provider-profile extraction makes sense + - `282` depends on `managed_environment_id` becoming the core anchor first + - `283`-`287` are later normalization and guardrail layers, not the initial breaking cutover +- **Smallest viable implementation slice**: core entity replacement, foreign-key retargeting, current-context replacement, and one bounded path exception only +- **Documented deviation from raw candidate wording**: this package defers the public workspace-first route-family rewrite and final `Workspace` Filament-tenancy end state to Spec `280`. To keep the implementation bounded and the runtime operable, `279` allows the current `/admin/t/{environment}` shell to remain temporarily while rebinding it to `ManagedEnvironment`. + +## Completed-Spec Guardrail Result + +- `specs/276-support-access-governance/` already exists and remains a separate prepared package +- `specs/277-stored-reports-surface/` already exists and remains a separate prepared package +- `specs/278-cross-domain-indicator-audit/` already exists and carries completed docs-only close-out history +- `specs/247-plans-entitlements-billing-readiness/`, `specs/251-commercial-entitlements-billing-state/`, `specs/252-platform-localization-v1/`, `specs/262-lifecycle-governance-taxonomy/`, and `specs/264-cross-tenant-promotion-execution/` remain context only and are not rewritten by this package + +## Deferred Adjacent Candidates + +- `280 - Filament Workspace Tenancy & Environment Routing Cutover` +- `281 - Provider Connection, Provider Scope & Microsoft Profile Extraction` +- `282 - Governance Artifact Retargeting to ManagedEnvironment` +- `283 - Provider Capability Registry v1` +- `284 - Provider-neutral Artifact Source Taxonomy v1` +- `285 - Workspace-first RBAC & Environment Access Scoping` +- `286 - UI Copy, IA & Localization Neutralization` +- `287 - Cutover Quality Gates & No-Legacy Enforcement` + +## User Scenarios & Testing + +### User Story 1 - Resolve managed environments as the active target inside a workspace (Priority: P1) + +As a platform operator, I want the active managed target to be a `ManagedEnvironment` inside my current workspace so the platform core stops depending on `Tenant` as its primary identity model. + +**Why this priority**: every later cutover slice depends on the managed-target root being replaced first. + +**Independent Test**: Seed a workspace plus one managed environment, resolve the record through route binding and current-context helpers, and confirm the core paths no longer require `App\Models\Tenant`. + +**Acceptance Scenarios**: + +1. **Given** a workspace has a managed environment, **When** the current environment is resolved by route key, **Then** the app returns the `ManagedEnvironment` record and current workspace context instead of a `Tenant` model. +2. **Given** a wrong-workspace or non-member actor, **When** they try to resolve the same managed environment, **Then** the app responds with `404` and leaks no environment-bound data. + +--- + +### User Story 2 - Keep current environment-scoped surfaces operable through the cutover (Priority: P1) + +As an operator using the current admin panel, I want the existing environment-scoped shell to keep working while the core noun changes so the cutover is reviewable without bundling the full route/IA rewrite. + +**Why this priority**: the cutover is not implementation-ready unless the current panel still boots on the new core entity. + +**Independent Test**: Select a workspace, enter a managed environment from the retargeted chooser, and open the current environment dashboard through the temporary `/admin/t/{environment}` shell. + +**Acceptance Scenarios**: + +1. **Given** an operator selected a workspace, **When** they choose a managed environment, **Then** the current panel shell loads with that managed environment as the active bound model. +2. **Given** the same environment-scoped shell, **When** a page or deep link resolves the active target, **Then** route builders, query helpers, and current-target chips use `ManagedEnvironment` consistently. + +--- + +### User Story 3 - Remove active tenant-core drift from schema, policies, and tests (Priority: P2) + +As a maintainer, I want core-owned schema, policies, factories, and guard tests to use `ManagedEnvironment` and `managed_environment_id` so later specs do not inherit mixed core nouns. + +**Why this priority**: lingering tenant-core drift would make the follow-up cutover pack unstable and ambiguous. + +**Independent Test**: Run the managed-environment unit/feature suite and the legacy-core guard checks, then confirm no active `App\Models\Tenant` or `->tenant(Tenant::class)` binding remains in core-owned paths. + +**Acceptance Scenarios**: + +1. **Given** the cutover implementation is complete, **When** factories, policies, and tests create the managed target, **Then** they use `ManagedEnvironment` and managed-environment memberships rather than `Tenant`. +2. **Given** the final core-owned paths are searched or guard-tested, **When** forbidden legacy core patterns are checked, **Then** no active `Tenant` core model or Filament tenant binding remains. + +### Edge Cases + +- The current public `/admin/t/{environment}` path may remain temporarily, but it must bind `ManagedEnvironment` and must not coexist with a second compatibility route family. +- Microsoft-specific external terms such as `Microsoft Entra Tenant ID` may remain only in provider-owned metadata or provider profiles, not on `ManagedEnvironment`. +- Archived or inactive managed environments must not become selectable current context by default. +- Old tenant-specific factories, seeders, and fixtures must be removed or replaced in the same cutover PR rather than kept for convenience. + +## Requirements *(mandatory)* + +**Constitution alignment (required):** This feature changes core data ownership, route binding, context selection, and existing operator-facing shell behavior. It adds no Microsoft Graph calls and no new `OperationRun` family. Any security-relevant mutation that is not represented by `OperationRun` still uses existing audit behavior where applicable. + +**Constitution alignment (PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001):** The feature introduces a new persisted root entity because the current product truth needs a provider-neutral managed-target core now. A narrower alias or adapter would preserve the wrong truth and would violate the repo’s pre-production lean doctrine. + +**Constitution alignment (XCUT-001):** Current context-selection, route-building, query-scoping, and shell-context seams must be replaced in place. No second local environment-context language is allowed. + +**Constitution alignment (PROV-001):** `ManagedEnvironment` must remain provider-neutral. Provider-specific identity stays in provider-owned seams and follow-up Spec `281`. + +**Constitution alignment (SCOPE-001 exception/update prerequisite):** The current constitution still requires tenant-owned tables to use `workspace_id` plus `tenant_id` as `NOT NULL`. This package intentionally replaces active core-owned managed-target keys with `managed_environment_id`. Implementation is gated by the explicit exception record in `specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md` until the constitution itself is amended. + +### Functional Requirements + +- **FR-001**: The package MUST introduce `ManagedEnvironment` as the active managed-target root record inside a workspace. +- **FR-002**: The package MUST remove active core dependence on `App\Models\Tenant` and retarget core-owned foreign keys from `tenant_id` to `managed_environment_id`. +- **FR-003**: `ManagedEnvironment` MUST NOT contain Microsoft-specific identity, Graph, or Intune fields. +- **FR-004**: Current workspace-plus-target context resolution MUST bind `ManagedEnvironment` instead of `Tenant`. +- **FR-005**: Current environment membership and capability checks MUST continue to enforce `404` for non-members and `403` for in-scope capability denials. +- **FR-006**: The current environment-scoped panel shell may retain the `/admin/t/{environment}` path temporarily, but it MUST bind `ManagedEnvironment` and MUST remain the only documented path exception in this slice. +- **FR-007**: Current tenant-scoped query helpers, global-search scoping, route builders, and current-target UI seams MUST resolve `ManagedEnvironment` consistently. +- **FR-008**: Tests, factories, policies, and seeders in core-owned paths MUST use `ManagedEnvironment` naming and IDs after the cutover. +- **FR-009**: The package MUST not introduce dual columns, alias models, dual-write logic, or compatibility routes. +- **FR-010**: The package MUST explicitly defer the remaining workspace-first route-family rewrite, provider extraction, artifact retargeting, RBAC scope redesign, copy neutralization, and long-lived cutover quality gates to Specs `280`-`287`. + +### Authorization and Safety Requirements + +- **AR-001**: Workspace membership remains the first access boundary and must still deny non-members as `404`. +- **AR-002**: Managed-environment membership remains the second access boundary and must still deny wrong-environment access as `404`. +- **AR-003**: No new destructive action semantics are introduced. Any touched existing destructive actions must preserve `->requiresConfirmation()` and current authorization checks. + +### Non-Functional Requirements + +- **NFR-001**: Filament remains v5 on Livewire v4. +- **NFR-002**: Provider registration stays in `apps/platform/bootstrap/providers.php`; no new panel provider registration location is introduced. +- **NFR-003**: Any existing globally searchable resource touched by the cutover must continue to satisfy Filament’s edit/view-page requirement or remain out of global search. +- **NFR-004**: No new asset registration or `filament:assets` deployment change is introduced in this slice. +- **NFR-005**: The cutover must remain reviewable as one bounded implementation loop and must not silently absorb the broader Spec `280`-`287` work. diff --git a/specs/279-workspace-managed-environment-core/tasks.md b/specs/279-workspace-managed-environment-core/tasks.md new file mode 100644 index 00000000..821b1b92 --- /dev/null +++ b/specs/279-workspace-managed-environment-core/tasks.md @@ -0,0 +1,199 @@ +--- +description: "Task list for Workspace-first Managed Environment Core Cutover" +--- + +# Tasks: Workspace-first Managed Environment Core Cutover + +**Input**: Design documents from `specs/279-workspace-managed-environment-core/` +**Prerequisites**: `specs/279-workspace-managed-environment-core/spec.md`, `specs/279-workspace-managed-environment-core/plan.md`, `specs/279-workspace-managed-environment-core/checklists/requirements.md`, `specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md`, `specs/279-workspace-managed-environment-core/research.md`, `specs/279-workspace-managed-environment-core/data-model.md`, `specs/279-workspace-managed-environment-core/quickstart.md`, `specs/279-workspace-managed-environment-core/contracts/managed-environment-core-cutover.logical.openapi.yaml` + +**Tests**: REQUIRED (Pest). Keep proof bounded to one managed-environment unit family, one managed-environment feature family, one narrow browser smoke, and one legacy-core guard family. +**Operations**: No new `OperationRun` family. Existing operation links must resolve the new managed-environment context correctly. +**RBAC**: Workspace membership remains the first `404` boundary. Managed-environment membership remains the second `404` boundary. In-scope capability denials stay `403`. +**Shared Pattern Reuse**: Reuse `WorkspaceContext`, existing panel-provider seams, current query helpers, `TenantOwnedModelFamilies`, and `OperationRunLinks`. Do not create an adapter layer or second context stack. +**Filament / Panel Guardrails**: Filament remains v5 on Livewire v4. Provider registration remains unchanged in `apps/platform/bootstrap/providers.php`. No new panel, no second public route family, and no new asset strategy are allowed. +**Organization**: Tasks are grouped by user story so core entity cutover, panel/context rebinding, and legacy-core removal remain independently reviewable. +**Review Outcome**: `documentation-required-exception` +**Workflow Outcome**: `keep` +**Test-governance Outcome**: `keep` + +## Test Governance Checklist + +- [x] Lane assignment stays `fast-feedback`, `confidence`, and one narrow `browser` lane. +- [x] New or changed tests stay in `apps/platform/tests/Unit/ManagedEnvironment/`, `apps/platform/tests/Feature/ManagedEnvironment/`, and one narrow browser smoke file only. +- [x] Fixture replacement stays explicit; no tenant compatibility fixtures remain as defaults. +- [x] Planned validation commands match `spec.md`, `plan.md`, and `quickstart.md` exactly. +- [x] The `/admin/t/{environment}` path retention is tracked as an exception note, not as an uncontrolled compatibility layer. +- [x] Any attempt to absorb Spec `280`-`287` work resolves as `split` or `reject-or-split`, not hidden scope. + +## Phase 1: Setup (Shared Context) + +**Purpose**: Confirm the current tenant-core seams and the bounded cutover inventory before runtime changes begin. + +- [x] T001 Review `specs/279-workspace-managed-environment-core/spec.md`, `plan.md`, `checklists/requirements.md`, `research.md`, `data-model.md`, and `quickstart.md` together so the slice stays on the first reserved cutover only. +- [x] T001a Before any implementation-phase task starts, confirm `specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md` still governs the cutover or replace it with the actual `.specify/memory/constitution.md` amendment reference; if neither exists, stop the implementation loop. +- [x] T002 [P] Confirm the current core seam in `apps/platform/app/Models/Tenant.php`, `Workspace.php`, and the current tenant-membership model family. +- [x] T003 [P] Confirm the current panel and current-context seam in `apps/platform/app/Providers/Filament/TenantPanelProvider.php`, `ChooseTenant.php`, `WorkspaceContext.php`, and the tenant-context helper traits. +- [x] T004 [P] Use `apps/platform/app/Support/WorkspaceIsolation/TenantOwnedModelFamilies.php` plus a bounded schema grep to enumerate the cutover set that still relies on `tenant_id` as active managed-target truth. +- [x] T004a [P] Record explicit Spec `281` and `282` exclusions so provider-connection extraction and broader governance-artifact retargeting do not drift into the 279 implementation loop. + +--- + +## Phase 2: Foundational (Blocking Prerequisites) + +**Purpose**: Lock the new core entity, membership truth, and proving seams before panel and route rebinding begins. + +**Critical**: No user-story work should begin until this phase is complete. + +- [x] T005 [P] Add failing unit coverage in `apps/platform/tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php` for workspace relation, route key, selectability, and provider-neutral field rules. +- [x] T006 [P] Add failing unit coverage in `apps/platform/tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php` for current workspace plus managed-environment resolution. +- [x] T007 [P] Add failing feature coverage in `apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php` and `ManagedEnvironmentAuthorizationTest.php` for `404` versus `403` semantics. +- [x] T008 [P] Add failing feature coverage in `apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php` for chooser-to-shell context bootstrapping on the temporary `/admin/t/{environment}` path. +- [x] T009 [P] Add the narrow browser smoke in `apps/platform/tests/Browser/Spec279ManagedEnvironmentCoreCutoverSmokeTest.php` for workspace selection, managed-environment selection, and dashboard boot. +- [x] T010 Create the new `ManagedEnvironment` model, factory, migration(s), and managed-environment membership truth with no compatibility columns. +- [x] T011 Replace or rename the current environment-membership seam so current capability semantics apply to managed environments without broad RBAC redesign. + +**Checkpoint**: The new managed-target root and proving seams exist before shared runtime context changes begin. + +--- + +## Phase 3: User Story 1 - Resolve managed environments as the active target inside a workspace (Priority: P1) + +**Goal**: `ManagedEnvironment` becomes the active managed-target root and current core paths stop depending on `Tenant`. + +**Independent Test**: Create a workspace plus managed environment, resolve the route key and current context, and confirm no active `Tenant` model is needed in the core path. + +### Tests for User Story 1 + +- [x] T012 [P] [US1] Extend the managed-environment unit and feature tests to cover archived/inactive environments and wrong-workspace resolution. + +### Implementation for User Story 1 + +- [x] T013 [US1] Update `Workspace` and related root models so the primary managed-target relationship becomes `managedEnvironments()` rather than `tenants()`. +- [x] T014 [US1] Retarget the core schema and Eloquent relations from `tenant_id` to `managed_environment_id` across the cutover set identified in Phase 1, using destructive pre-production migrations only and keeping the explicit Spec `281` and `282` exclusions intact. +- [x] T015 [US1] Replace current route-model binding, current-target resolution, and membership-aware target lookup so they resolve `ManagedEnvironment` instead of `Tenant`. +- [x] T016 [US1] Remove active `App\Models\Tenant` core usage and replace tenant-specific factories, seeders, and policy anchors with managed-environment equivalents. + +**Checkpoint**: The app has one active managed-target root entity and no mixed core noun in the main data path. + +--- + +## Phase 4: User Story 2 - Keep current environment-scoped surfaces operable through the cutover (Priority: P1) + +**Goal**: The current environment-scoped shell continues to work while binding `ManagedEnvironment` instead of `Tenant`. + +**Independent Test**: Select a workspace, enter a managed environment through the retargeted chooser, and open the current environment dashboard through the temporary shell. + +### Tests for User Story 2 + +- [x] T017 [P] [US2] Extend `ManagedEnvironmentPanelContextTest.php` to cover chooser state, shell context chips, and current-target route builders. + +### Implementation for User Story 2 + +- [x] T018 [US2] Update the current tenant chooser page and related context UI so operators choose managed environments inside the active workspace. +- [x] T019 [US2] Update the current tenant-panel shell and shared tenant-context helper seams so the bound model becomes `ManagedEnvironment` while the `/admin/t/{environment}` path remains the only documented temporary exception and the final `Workspace` Filament-tenancy switch stays deferred to Spec `280`. +- [x] T020 [US2] Retarget tenant-scoped query helpers, global-search scoping, environment-bound widgets, and `OperationRunLinks` to the new managed-environment context. +- [x] T021 [US2] Keep broader workspace-first public routing, navigation, breadcrumbs, and copy cleanup explicitly out of scope and record any unavoidable temporary copy drift for Spec `280` or `286`. + +**Checkpoint**: Existing environment-scoped operator surfaces still boot and scope correctly on the new core entity. + +--- + +## Phase 5: User Story 3 - Remove active tenant-core drift from schema, policies, and tests (Priority: P2) + +**Goal**: Core-owned code, tests, and guardrails stop reintroducing `Tenant` as platform-core truth. + +**Independent Test**: Run the legacy-core guard suite and the grep validation to confirm no active `Tenant` core model or Filament tenant binding remains. + +### Tests for User Story 3 + +- [x] T022 [P] [US3] Add failing guard coverage in `apps/platform/tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php` for active `App\Models\Tenant` imports, `->tenant(Tenant::class)` panel binding, and active `tenant_id` usage inside the T004 core-owned cutover inventory only. + +### Implementation for User Story 3 + +- [x] T023 [US3] Update commands, fixtures, factories, policies, and support helpers that still instantiate or search the active managed target through `Tenant`. +- [x] T024 [US3] Add bounded search-based validation for lingering core `Tenant` references, document the only approved temporary `/admin/t/{environment}` path exception, and record the explicit Spec `281` and `282` residual allowlist for any remaining non-core `tenant_id` hits. +- [x] T025 [US3] Ensure `ManagedEnvironment` stays provider-neutral and that provider-specific identity remains in provider-owned seams only. + +**Checkpoint**: The cutover leaves no uncontrolled tenant-core drift behind. + +--- + +## Phase 6: Polish & Cross-Cutting Validation + +**Purpose**: Validate the bounded cutover and stop before the broader reserved pack is absorbed. + +- [x] T026 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php)`. +- [x] T027 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentAuthorizationTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php)`. +- [x] T028 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec279ManagedEnvironmentCoreCutoverSmokeTest.php)`. +- [x] T029 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent)`. +- [x] T030 [P] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && rg -n --fixed-strings 'App\Models\Tenant' "$REPO_ROOT/apps/platform/app" "$REPO_ROOT/apps/platform/tests" "$REPO_ROOT/apps/platform/database"` and `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && rg -n -- '->tenant\(Tenant::class' "$REPO_ROOT/apps/platform/app" "$REPO_ROOT/apps/platform/tests" "$REPO_ROOT/apps/platform/database"` and confirm only approved removed-path output remains. +- [x] T031 [P] Review touched code to confirm Filament stays on Livewire v4, provider registration remains unchanged in `apps/platform/bootstrap/providers.php`, any touched globally searchable resource still has edit/view eligibility or remains out of global search, no new asset registration or deployment-step change is introduced, no second public route family appears, no provider-specific identity lands on `ManagedEnvironment`, and any touched destructive actions still preserve `->requiresConfirmation()` plus current authorization. +- [x] T032 [P] Record the final guardrail and test-governance outcome in the active feature close-out, including the temporary `/admin/t/{environment}` exception and the mandatory follow-up ownership for Spec `280`. + +--- + +## Dependencies & Execution Order + +### Phase Dependencies + +- **Phase 1 (Setup)**: no dependencies; start immediately. +- **Phase 2 (Foundational)**: depends on Phase 1, including T001a with an actual constitution-amendment reference or approved-exception artifact path, and blocks all user-story work. +- **Phase 3 (US1)**: depends on Phase 2 and establishes the new managed-target truth. +- **Phase 4 (US2)**: depends on Phase 2 and should land after US1 so the shell binds the finished core entity. +- **Phase 5 (US3)**: depends on US1 and US2 so guard checks prove the final core path, not an intermediate state. +- **Phase 6 (Polish)**: depends on all desired user stories being complete. + +### User Story Dependencies + +- **US1 (P1)**: independently testable after Phase 2 and is the first required cutover slice. +- **US2 (P1)**: independently testable after Phase 2 but should ship with US1 so the current shell remains operable. +- **US3 (P2)**: independently testable after US1 and US2 and closes the lingering legacy-core drift. + +### Within Each User Story + +- Write the listed Pest coverage first and make it fail for the intended gap. +- Keep implementation inside current core-owned seams and do not widen into broader route/IA/provider/artifact/RBAC follow-up work. +- Re-run the narrowest relevant validation command after each story checkpoint before moving on. + +--- + +## Implementation Strategy + +### Suggested MVP Scope + +- MVP = **US1 + US2 together**. The cutover is only reviewable if the new core entity exists and the current shell still boots on it. + +### Incremental Delivery + +1. Complete Phase 1 and Phase 2. +2. Deliver US1 so the managed-target core is replaced. +3. Deliver US2 so operators can still enter the environment-scoped shell. +4. Deliver US3 to remove lingering legacy drift and lock guardrails. +5. Finish with the focused validation and exception close-out in Phase 6. + +### Team Strategy + +1. Settle schema, model, and current-context rules first. +2. Parallelize failing unit and feature test authoring before runtime edits. +3. Serialize merges around panel-provider and context-helper files so the temporary route exception does not drift. + +--- + +## Deferred Follow-Ups / Non-Goals + +- workspace-first public route-family rewrite and environment dashboard split +- provider-profile extraction and provider-scope normalization +- governance artifact naming/route retargeting polish +- RBAC scope redesign and new capability families +- copy/localization neutralization +- long-lived cutover quality gates beyond feature-local guard checks + +## Implementation Close-Out Notes + +- Completed implementation keeps Filament v5 on Livewire v4 and leaves provider registration unchanged in `apps/platform/bootstrap/providers.php`. +- The current `/admin/t/{environment}` shell remains the only temporary route exception; it now binds `ManagedEnvironment` by slug. +- `ManagedEnvironment` is provider-neutral: Microsoft/Graph identity resolves through provider-owned seams such as `provider_connections`. +- Legacy-core guard coverage confirms no exact `use App\Models\Tenant;` import, no `->tenant(Tenant::class)` binding, and no `tenant_id` column in the first-slice core tables. +- Browser smoke path covered workspace-scoped managed-environment selection through `ChooseTenant::getUrl(panel: 'admin')` into `/admin/t/spec-279-production`. +- Validation completed with the planned unit, feature, browser, Pint, syntax, and bounded regression checks; the broad planned `App\Models\Tenant` grep still returns approved longer model names such as `TenantReview`, `TenantPermission`, and `TenantOnboardingSession`.