TenantAtlas/apps/platform/app/Http/Controllers/ManagementReportPdfDownloadController.php
ahmido dbff2a0a90 feat(report): implement management report pdf runtime (#450)
Added jobs, controllers, and PDF generation logic for management report runtime as defined in Spec 379. Includes artifact migrations, payload builders, and testing coverage.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #450
2026-06-15 11:36:29 +00:00

104 lines
3.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\ManagedEnvironment;
use App\Models\ReviewPack;
use App\Models\StoredReport;
use App\Models\User;
use App\Services\Audit\WorkspaceAuditLogger;
use App\Support\Audit\AuditActionId;
use App\Support\Auth\Capabilities;
use App\Support\ReviewPackStatus;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class ManagementReportPdfDownloadController extends Controller
{
public function __invoke(Request $request, StoredReport $storedReport): StreamedResponse
{
$storedReport->loadMissing(['tenant.workspace', 'sourceReviewPack.environmentReview']);
$user = $request->user();
$tenant = $storedReport->tenant;
$reviewPack = $storedReport->sourceReviewPack;
if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment || ! $reviewPack instanceof ReviewPack) {
throw new NotFoundHttpException;
}
if (! $storedReport->isReadyManagementPdf()) {
throw new NotFoundHttpException;
}
if ((int) $storedReport->managed_environment_id !== (int) $tenant->getKey()
|| (int) $reviewPack->managed_environment_id !== (int) $tenant->getKey()
) {
throw new NotFoundHttpException;
}
if ($reviewPack->status !== ReviewPackStatus::Ready->value || ($reviewPack->expires_at !== null && $reviewPack->expires_at->isPast())) {
throw new NotFoundHttpException;
}
$review = $reviewPack->environmentReview;
if (! $review || (int) ($review->current_export_review_pack_id ?? 0) !== (int) $reviewPack->getKey()) {
throw new NotFoundHttpException;
}
if (! $user->canAccessTenant($tenant)) {
throw new NotFoundHttpException;
}
if (! $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant)) {
abort(403);
}
$disk = Storage::disk((string) $storedReport->file_disk);
if (! $disk->exists((string) $storedReport->file_path)) {
throw new NotFoundHttpException;
}
app(WorkspaceAuditLogger::class)->log(
workspace: $tenant->workspace,
action: AuditActionId::ManagementReportPdfDownloaded,
context: [
'metadata' => [
'stored_report_id' => (int) $storedReport->getKey(),
'review_pack_id' => (int) $reviewPack->getKey(),
'environment_review_id' => $storedReport->source_environment_review_id !== null
? (int) $storedReport->source_environment_review_id
: null,
'source_surface' => (string) $request->query('source_surface', 'review_pack'),
'profile' => (string) $storedReport->profile,
],
],
actor: $user,
resourceType: 'stored_report',
resourceId: (string) $storedReport->getKey(),
targetLabel: sprintf('Management report PDF #%d', (int) $storedReport->getKey()),
tenant: $tenant,
operationRunId: $storedReport->operation_run_id,
);
return $disk->download((string) $storedReport->file_path, $this->filename($storedReport, $tenant), [
'Content-Type' => 'application/pdf',
'X-Management-Report-PDF-SHA256' => $storedReport->sha256 ?? '',
]);
}
private function filename(StoredReport $storedReport, ManagedEnvironment $tenant): string
{
$tenantSlug = preg_replace('/[^A-Za-z0-9._-]+/', '-', (string) ($tenant->external_id ?: $tenant->name)) ?: 'environment';
$date = $storedReport->generated_at?->format('Y-m-d') ?? now()->format('Y-m-d');
return sprintf('management-report-%s-%s.pdf', trim($tenantSlug, '-') ?: 'environment', $date);
}
}