create(['status' => 'active']); [$user, $tenantOverdue] = createUserWithTenant($tenantOverdue, role: 'owner', workspaceRole: 'readonly'); [$overdueProfile, $overdueSnapshot] = seedActiveBaselineForTenant($tenantOverdue); seedBaselineCompareRun($tenantOverdue, $overdueProfile, $overdueSnapshot, workspaceOverviewCompareCoverage()); Finding::factory()->count(3)->for($tenantOverdue)->create([ 'workspace_id' => (int) $tenantOverdue->workspace_id, 'status' => Finding::STATUS_TRIAGED, 'due_at' => now()->subDay(), ]); $tenantExpiring = Tenant::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantOverdue->workspace_id, 'name' => 'Expiring Tenant', ]); createUserWithTenant($tenantExpiring, $user, role: 'owner', workspaceRole: 'readonly'); [$expiringProfile, $expiringSnapshot] = seedActiveBaselineForTenant($tenantExpiring); seedBaselineCompareRun($tenantExpiring, $expiringProfile, $expiringSnapshot, workspaceOverviewCompareCoverage()); $finding = Finding::factory()->riskAccepted()->create([ 'workspace_id' => (int) $tenantExpiring->workspace_id, 'tenant_id' => (int) $tenantExpiring->getKey(), ]); FindingException::query()->create([ 'workspace_id' => (int) $tenantExpiring->workspace_id, 'tenant_id' => (int) $tenantExpiring->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), 'approved_by_user_id' => (int) $user->getKey(), 'status' => FindingException::STATUS_EXPIRING, 'current_validity_state' => FindingException::VALIDITY_EXPIRING, 'request_reason' => 'Pending governance review', 'approval_reason' => 'Short lived exception', 'requested_at' => now()->subDays(2), 'approved_at' => now()->subDay(), 'effective_from' => now()->subDay(), 'expires_at' => now()->addDay(), 'review_due_at' => now()->addDay(), 'evidence_summary' => ['reference_count' => 0], ]); $tenantStale = Tenant::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantOverdue->workspace_id, 'name' => 'Stale Tenant', ]); createUserWithTenant($tenantStale, $user, role: 'owner', workspaceRole: 'readonly'); [$staleProfile, $staleSnapshot] = seedActiveBaselineForTenant($tenantStale); seedBaselineCompareRun( $tenantStale, $staleProfile, $staleSnapshot, workspaceOverviewCompareCoverage(), completedAt: now()->subDays(10), ); $tenantFailedCompare = Tenant::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantOverdue->workspace_id, 'name' => 'Failed Compare Tenant', ]); createUserWithTenant($tenantFailedCompare, $user, role: 'owner', workspaceRole: 'readonly'); [$failedProfile, $failedSnapshot] = seedActiveBaselineForTenant($tenantFailedCompare); seedBaselineCompareRun( $tenantFailedCompare, $failedProfile, $failedSnapshot, workspaceOverviewCompareCoverage(), outcome: \App\Support\OperationRunOutcome::Failed->value, ); $workspace = $tenantOverdue->workspace()->firstOrFail(); $overview = app(WorkspaceOverviewBuilder::class)->build($workspace, $user); $metrics = collect($overview['summary_metrics'])->keyBy('key'); expect($metrics->get('governance_attention_tenants')['value'])->toBe(4) ->and($metrics->get('governance_attention_tenants')['category'])->toBe('governance_risk') ->and($metrics->get('governance_attention_tenants')['destination']['kind'])->toBe('choose_tenant'); }); it('keeps activity and alerts metrics separate from governance risk', function (): void { $tenant = Tenant::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(), '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(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => AlertDelivery::STATUS_FAILED, 'created_at' => now(), ]); $workspace = $tenant->workspace()->firstOrFail(); $overview = app(WorkspaceOverviewBuilder::class)->build($workspace, $user); $metrics = collect($overview['summary_metrics'])->keyBy('key'); expect($metrics->get('governance_attention_tenants')['value'])->toBe(0) ->and($metrics->get('active_operations')['value'])->toBe(1) ->and($metrics->get('active_operations')['category'])->toBe('activity') ->and($metrics->get('active_operations')['destination']['kind'])->toBe('operations_index') ->and($metrics->get('alert_failures')['value'])->toBe(1) ->and($metrics->get('alert_failures')['category'])->toBe('alerts'); });