record instanceof Tenant ? $this->record : null; } public function generatePack(bool $includePii = true, bool $includeOperations = true): void { $user = auth()->user(); if (! $user instanceof User) { abort(403); } $tenant = $this->resolveTenant(); if (! $tenant instanceof Tenant) { abort(404); } if (! $user->canAccessTenant($tenant)) { abort(404); } if (! $user->can(Capabilities::REVIEW_PACK_MANAGE, $tenant)) { abort(403); } /** @var ReviewPackService $service */ $service = app(ReviewPackService::class); $activeRun = $service->checkActiveRun($tenant) ? OperationRun::query() ->where('tenant_id', (int) $tenant->getKey()) ->where('type', OperationRunType::ReviewPackGenerate->value) ->active() ->orderByDesc('id') ->first() : null; if ($activeRun) { OpsUxBrowserEvents::dispatchRunEnqueued($this); OperationUxPresenter::alreadyQueuedToast((string) $activeRun->type) ->body('A review pack is already queued or running for this tenant.') ->actions([ Action::make('view_run') ->label('View run') ->url(OperationRunLinks::tenantlessView($activeRun)), ]) ->send(); return; } $reviewPack = $service->generate($tenant, $user, [ 'include_pii' => $includePii, 'include_operations' => $includeOperations, ]); $runUrl = $reviewPack->operationRun ? OperationRunLinks::tenantlessView($reviewPack->operationRun) : null; OpsUxBrowserEvents::dispatchRunEnqueued($this); $toast = OperationUxPresenter::queuedToast(OperationRunType::ReviewPackGenerate->value) ->body('The pack will be generated in the background. You will be notified when it is ready.'); if ($runUrl !== null) { $toast->actions([ Action::make('view_run') ->label('View run') ->url($runUrl), ]); } $toast->send(); } /** * @return array */ protected function getViewData(): array { $tenant = $this->resolveTenant(); if (! $tenant instanceof Tenant) { return $this->emptyState(); } $user = auth()->user(); $isTenantMember = $user instanceof User && $user->canAccessTenant($tenant); $canView = $isTenantMember && $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant); $canManage = $isTenantMember && $user->can(Capabilities::REVIEW_PACK_MANAGE, $tenant); $latestPack = ReviewPack::query() ->where('tenant_id', (int) $tenant->getKey()) ->orderByDesc('created_at') ->orderByDesc('id') ->first(); if (! $latestPack instanceof ReviewPack) { return [ 'tenant' => $tenant, 'pack' => null, 'statusEnum' => null, 'canView' => $canView, 'canManage' => $canManage, 'downloadUrl' => null, 'failedReason' => null, ]; } $statusEnum = ReviewPackStatus::tryFrom((string) $latestPack->status); $downloadUrl = null; if ($statusEnum === ReviewPackStatus::Ready && $canView) { /** @var ReviewPackService $service */ $service = app(ReviewPackService::class); $downloadUrl = $service->generateDownloadUrl($latestPack); } $failedReason = null; if ($statusEnum === ReviewPackStatus::Failed && $latestPack->operationRun) { $opContext = is_array($latestPack->operationRun->context) ? $latestPack->operationRun->context : []; $failedReason = (string) ($opContext['reason_code'] ?? 'Unknown error'); } return [ 'tenant' => $tenant, 'pack' => $latestPack, 'statusEnum' => $statusEnum, 'canView' => $canView, 'canManage' => $canManage, 'downloadUrl' => $downloadUrl, 'failedReason' => $failedReason, ]; } /** * @return array */ private function emptyState(): array { return [ 'tenant' => null, 'pack' => null, 'statusEnum' => null, 'canView' => false, 'canManage' => false, 'downloadUrl' => null, 'failedReason' => null, ]; } }