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
3.7 KiB
Spec 379 Storage, OperationRun, and UI Decisions
Date: 2026-06-14
Owner Surface
V1 generation is owned by ReviewPackResource detail (ViewReviewPack).
Rationale:
- The Review Pack detail already owns the current customer-safe ZIP artifact, rendered-report action, readiness checks, and download capability.
- The management PDF is derived from the current ready Review Pack, not from an independent report center.
- Server-side generation authorization uses
REVIEW_PACK_MANAGE; download usesREVIEW_PACK_VIEW.
Storage Substrate
The PDF uses StoredReport as the persisted artifact substrate.
Rationale:
- Avoids a new report-center table or broad artifact lifecycle framework.
- Keeps workspace and managed-environment scope on the existing report model.
- Adds only narrow nullable fields required for source linkage, operation linkage, private file metadata, profile, format, status, SHA-256, and generated timestamp.
- Keeps
StoredReportResource::$isGloballySearchable = false; no global-search behavior changed.
Private files are stored on the existing exports disk under management-reports/... with generated safe filenames. Ready artifacts are exposed only through a signed route that re-checks tenant scope, current source Review Pack, artifact status, file existence, and REVIEW_PACK_VIEW.
OperationRun
A distinct canonical operation type was added:
report.management.generate- Enum:
OperationRunType::ManagementReportGenerate - Catalog label:
Management report PDF generation
Rationale:
- Reusing
environment.review_pack.generatewould mislabel PDF generation as ZIP generation in monitoring, audit, and notifications. - The operation does not introduce a new artifact-family taxonomy in
OperationCatalog; it remains a stored-report-backed workflow.
Generation queues GenerateManagementReportPdfJob through OperationRunService::dispatchOrFail() and writes terminal state through OperationRunService::updateRun().
Audit
Distinct audit action IDs were added because ZIP generation/download and management-PDF generation/download have different artifact semantics:
management_report_pdf.generation_requestedmanagement_report_pdf.generation_blockedmanagement_report_pdf.generatedmanagement_report_pdf.generation_failedmanagement_report_pdf.downloaded
Audit metadata records workspace, managed environment, source review, source Review Pack, stored report id, operation run id, profile, SHA-256 where available, and redacted request context. Signed URLs, secrets, raw provider payloads, stack traces, and SQL errors are not included.
Runtime Gate
Generation is gated by ManagementReportPdfRuntimeGate.
Blocked states include:
- renderer disabled
- unsupported renderer driver
- staging/runtime validation missing
- source Review Pack not ready, expired, missing artifact, or not current
- disclosure/profile blockers
- active generation already running
The default environment remains blocked until TENANTPILOT_PDF_RENDERER_RUNTIME_VALIDATED=true.
UI Coverage
Generate management PDFappears in the Review Pack detail header only when no ready PDF exists.- The action uses
Action::make(...)->action(...),->requiresConfirmation(), and server-sideREVIEW_PACK_MANAGE. - When generation is active, the header shows
Open PDF operation. - When a ready PDF exists, the header shows
Download management PDF. - Browser evidence:
specs/379-management-report-pdf-runtime/artifacts/screenshots/generate-state.pngspecs/379-management-report-pdf-runtime/artifacts/screenshots/download-state.png
No navigation redesign, customer workspace redesign, scheduled delivery, public links, AI-generated copy, or secondary renderer was added.