comment(Inspiring::quote()); })->purpose('Display an inspiring quote'); Schedule::command('tenantpilot:schedules:dispatch')->everyMinute(); Schedule::command('tenantpilot:directory-groups:dispatch')->everyMinute(); Schedule::command('tenantpilot:alerts:dispatch') ->everyMinute() ->name('tenantpilot:alerts:dispatch') ->withoutOverlapping(); Schedule::job(new PruneOldOperationRunsJob) ->daily() ->name(PruneOldOperationRunsJob::class) ->withoutOverlapping(); Schedule::job(new ReconcileAdapterRunsJob) ->everyThirtyMinutes() ->name(ReconcileAdapterRunsJob::class) ->withoutOverlapping(); Schedule::command('stored-reports:prune') ->daily() ->name('stored-reports:prune') ->withoutOverlapping(); Schedule::command('tenantpilot:review-pack:prune') ->daily() ->name('tenantpilot:review-pack:prune') ->withoutOverlapping(); Schedule::call(function (): void { $tenants = Tenant::query() ->whereHas('providerConnections', function ($q): void { $q->where('status', 'connected'); }) ->whereNotNull('workspace_id') ->get(); foreach ($tenants as $tenant) { ScanEntraAdminRolesJob::dispatch( tenantId: (int) $tenant->getKey(), workspaceId: (int) $tenant->workspace_id, ); } }) ->daily() ->name('entra-admin-roles:scan') ->withoutOverlapping(); // TODO: Add tenantpilot:posture:dispatch schedule entry once the command // infrastructure exists (FR-015 deferred — see specs/109 research.md §7).