TenantAtlas/specs/378-management-report-pdf-v1/plan.md
ahmido d43ebcb4ee feat(report): implement management report pdf v1 (#449)
Added PDF generation service for management reports as per Spec 378, including Gotenberg integration in docker-compose and configuration updates.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #449
2026-06-14 18:36:07 +00:00

34 KiB

Implementation Plan: Spec 378 - Management Report PDF v1

Branch: 378-management-report-pdf-v1 | Date: 2026-06-14 | Spec: specs/378-management-report-pdf-v1/spec.md Input: Feature specification from specs/378-management-report-pdf-v1/spec.md

Summary

Implement the first durable customer-executive management PDF artifact over the existing Review Pack rendered-report family. The PDF must reuse the current ReviewPackRenderedReportController content/profile/disclosure truth where possible, produce a stored or canonically referenced private artifact, expose an authorized download path, and record OperationRun plus audit evidence for generation and download.

This is not a new report engine. It is the smallest PDF artifact productization slice after Specs 356, 357, and 366.

Technical Context

Language/Version: PHP 8.4.15, Laravel 12.52.0 Primary Dependencies: Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1, PostgreSQL, approved Gotenberg 8 Chromium internal PDF rendering service (Sail/local service and Laravel gateway configured; staging/Dokploy controls pending), existing Playwright dev/browser tooling only Storage: PostgreSQL plus private Laravel storage disk for generated PDF artifacts if stored file output is implemented Testing: Pest Unit, Feature/Filament action, and Browser/content smoke Validation Lanes: fast-feedback, confidence, browser; PostgreSQL lane if migrations/indexes are introduced Target Platform: Laravel Sail locally, Dokploy container deployment for staging/production Project Type: Laravel monolith under apps/platform Performance Goals: PDF generation is queue-safe and idempotent; report render/download stays DB/storage-only with no live provider calls Constraints: no Graph calls during render/generation/download; Gotenberg 8 Chromium only through a Laravel gateway/client; no direct browser runtime in Laravel app/queue containers; no new runtime package without package governance; workspace/managed-environment isolation; profile/disclosure fail-closed; private artifact storage; no raw technical leakage Scale/Scope: one customer-executive PDF profile, one current ready Review Pack source, one artifact output path, focused report/audit/OperationRun tests

Repo Truth Map

Current runtime/report foundations:

  • apps/platform/app/Http/Controllers/ReviewPackRenderedReportController.php builds the existing rendered report state.
  • apps/platform/resources/views/review-packs/rendered-report.blade.php renders the management-style HTML/print report.
  • apps/platform/app/Support/ReviewPacks/ReportProfileRegistry.php defines customer_executive, technical, internal, auditor, and framework profiles.
  • apps/platform/app/Support/ReviewPacks/ReportDisclosurePolicy.php evaluates mandatory disclosures and appendix/technical visibility.
  • apps/platform/app/Support/ReviewPacks/ReportThemeResolver.php exists from Spec 366 for management layout/theme derivation.
  • apps/platform/app/Services/ReviewPackService.php generates Review Packs, signed ZIP/download URLs, and signed rendered-report URLs.
  • apps/platform/app/Http/Controllers/ReviewPackDownloadController.php owns current signed ZIP download access/audit.
  • apps/platform/app/Models/StoredReport.php and StoredReportResource provide a narrow report substrate for permission posture and Entra admin roles.
  • apps/platform/app/Services/OperationRunService.php, OperationRunType, OperationCatalog, and Operations UI/actionability specs provide run truth.
  • docs/ui-ux-enterprise-audit/page-reports/ui-099-rendered-review-report.md, ui-042-review-pack-detail.md, and ui-048-stored-report-detail.md are the relevant UI coverage references.

Repo-truth constraints:

  • No native PDF runtime dependency is present in apps/platform/composer.json.
  • apps/platform/package.json includes Playwright for dev/browser tooling, not an approved production PDF runtime.
  • Gotenberg 8 Chromium is approved with controls as an internal Docker PDF rendering service. Root docker-compose.yml, Laravel app config, and PdfRenderingGateway / PdfRendererClient now exist for Sail/local; no Dokploy config file exists in the repo, so docs/deployment-checklist.md records the required staging/production controls.
  • Existing StoredReport has no file path, format, generated-by, status, source review, source review pack, or operation-run columns today.
  • Existing Review Pack ZIP contract must remain unchanged.

Renderer Governance Gate Result

  • Gate result: approved with controls.
  • Selected renderer: Gotenberg 8 Chromium internal service.
  • Decision matrix: specs/378-management-report-pdf-v1/artifacts/spec378-pdf-renderer-decision-matrix.md.
  • Security controls: specs/378-management-report-pdf-v1/artifacts/spec378-gotenberg-security-controls.md.
  • Constitution review: specs/378-management-report-pdf-v1/artifacts/spec378-constitution-renderer-gate-review.md.
  • Package governance: docs/package-governance.md records the approved runtime service scope and controls.
  • Runtime status: Sail/local renderer service, Laravel config, health check, timeout/size controls, and gateway/client safe result mapping are implemented. Staging/Dokploy runtime validation remains pending before management report PDF generation is enabled.
  • Approved service boundary: Laravel must call Gotenberg through PdfRenderingGateway / PdfRendererClient; production PDF rendering must not install or execute Chromium, Chrome, Puppeteer, Playwright, Node, or browser binaries in Laravel app/queue containers.
  • Invoice / billing boundary: this approval is not approval for legal invoice generation, German B2B e-invoicing, XRechnung, ZUGFeRD/Factur-X, GoBD archival, tax calculation, invoice numbering, or billing compliance.

PDF Rendering Layer Responsibilities

  • PdfRendererClient: low-level HTTP transport to the internal Gotenberg service. It owns multipart request assembly, timeout handling, HTTP status mapping, response byte validation, configured body/output size limits, and correlation id headers.
  • PdfRenderingGateway: shared application boundary for server-generated HTML-to-PDF rendering. It accepts sanitized HTML/assets/render options and returns typed success/failure results suitable for OperationRun and audit mapping. It does not know management-report domain rules.
  • ManagementReportPdfRenderer: Spec 378 domain adapter. It converts a prepared management report payload into sanitized HTML/assets, calls PdfRenderingGateway, and maps returned renderer outcomes into management-report generation flow. It does not own HTTP transport, storage persistence, OperationRun lifecycle, or billing/invoice semantics.

SaaS Invoice / Billing Boundary

The shared renderer is infrastructure only. Domain truth remains separate:

  • PDF Rendering Infrastructure: shared.
  • Report Domain: separate.
  • Billing / Invoice Domain: separate.
  • E-Invoice XML Compliance: separate.

Target separation:

Shared PDF Rendering Infrastructure
  -> Gotenberg / Chromium Renderer
  -> PdfRenderingGateway
  -> Storage
  -> Audit
  -> OperationRun

Domain-specific generators
  -> ManagementReportGenerator
  -> EvidenceReportGenerator
  -> InvoiceDocumentGenerator
  -> CreditNoteDocumentGenerator

Identity boundaries:

  • StoredReport is not BillingDocument.
  • Report ID is not Invoice Number.
  • OperationRun ID is not Invoice Number.
  • StoredReport ID is not Invoice Number.

Future billing specs must separately define BillingDocument, InvoiceNumberAllocator, InvoiceTaxCalculator, EInvoiceXmlBuilder, ZugferdFacturXBuilder, XRechnungBuilder, InvoicePdfRenderer via PdfRenderingGateway, BillingDocumentArchive, and BillingAuditTrail.

Candidate Selection Gate

  • Selected candidate: Spec 378 - Management Report PDF v1.
  • Source: Direct user-provided Spec 378 draft.
  • Why selected: It is the natural bounded follow-up after Specs 356/357/366 made the rendered report, profile/disclosure policy, and management layout repo-real.
  • Deferred alternatives: Technical/Auditor Evidence Report, Delivery Center, scheduled delivery, Customer Review Workspace polish, compliance-framework reports, AI summaries.
  • Completed-spec guardrail: Specs 356, 357, 365, 366, 367, 372, and 377 are context only. They contain completed task markers, validation, close-out, or browser evidence and must not be rewritten.
  • Result: PASS.

UI / Surface Guardrail Plan

  • Guardrail scope: changed existing report/review artifact surfaces plus one possible new signed/authorized PDF download route.
  • Affected routes/pages/actions/states/navigation/panel/provider surfaces:
    • ReviewPackRenderedReportController
    • rendered-report Blade template only if PDF payload generation requires shared partial/content extraction
    • EnvironmentReviewResource and/or ReviewPackResource detail/header actions
    • StoredReportResource only if generated management PDF artifacts appear there
    • optional new management PDF download route
  • No-impact class, if applicable: N/A.
  • Native vs custom classification summary: owner surfaces remain native Filament actions; report canvas inherits Spec 366's legitimate custom report/print surface; stored report remains native Filament read-only registry.
  • Shared-family relevance: report viewer, artifact download, status/readiness messaging, OperationRun start/link UX, audit.
  • State layers in scope: detail header action state, source report payload, PDF artifact state, signed/download URL, OperationRun status/outcome, stored report/artifact lifecycle.
  • Audience modes in scope: customer/read-only for PDF content; operator-MSP for generation/download/action state; support-platform only through existing OperationRun/log diagnostics.
  • Decision/diagnostic/raw hierarchy plan: decision-first PDF; diagnostics only in OperationRun/logs; raw/support payload absent from PDF.
  • Raw/support gating plan: no raw JSON/provider payload/support context in customer-executive PDF. Any failure detail remains safe summary in UI and deeper diagnostics in logs/OperationRun.
  • One-primary-action / duplicate-truth control: source detail surfaces expose at most one dominant next step: generate if no current PDF and ready, download/open if generated, view operation if running/failed. The generate action must require explicit Filament confirmation before artifact creation starts.
  • Handling modes by drift class or surface: hard-stop-candidate for raw leakage, unauthorized artifact access, unapproved PDF runtime package, second report engine, or historical/expired pack impersonation.
  • Repository-signal treatment: update UI-099/UI-042/UI-048 only if action hierarchy or artifact presentation materially changes; otherwise record a no-update rationale in close-out.
  • Special surface test profiles: report-viewer, high-impact artifact generation action, customer-facing artifact.
  • Required tests or manual smoke: Unit payload/disclosure/readiness; Feature authorization/artifact/audit/run/download; Browser/content smoke for generate/download/PDF text.
  • Exception path and spread control: custom PDF/report layout remains bounded to the existing rendered-report family. No generic report framework.
  • Active feature PR close-out entry: Guardrail + Smoke Coverage.
  • UI/Productization coverage decision: reachable report/action surfaces change; implementation must update or explicitly close out coverage docs.
  • Coverage artifacts to update: update route inventory when a new signed/authorized PDF route is added; update ui-099-rendered-review-report.md when rendered-report/PDF source content or customer-facing report presentation materially changes; update ui-042-review-pack-detail.md when Review Pack detail owns the action/download state; update ui-048-stored-report-detail.md when StoredReport registry/detail exposes the artifact; update design coverage matrix when action hierarchy, artifact state, or customer-facing surface classification materially changes.
  • No-impact rationale: N/A.
  • Navigation / Filament provider-panel handling: no navigation or panel provider change planned. Laravel 12 Filament provider registration remains in apps/platform/bootstrap/providers.php.
  • Screenshot or page-report need: yes, one bounded browser/content smoke with artifact evidence where local tooling permits it.

Shared Pattern & System Fit

  • Cross-cutting feature marker: yes.
  • Systems touched: Review Pack rendered report, report profiles, disclosure policy, Review Pack service, stored report/artifact storage, OperationRun, audit, localization, Filament owner-surface actions.
  • Shared abstractions reused:
    • ReportProfileRegistry
    • ReportDisclosurePolicy
    • ReportThemeResolver
    • ReviewPackOutputReadiness
    • ReviewPackOutputResolutionGuidance
    • ReviewPackService
    • current signed route/download patterns
    • OperationRunService
    • current audit logger/action ID pattern
  • New abstraction introduced? why?: likely one bounded generation service and one renderer adapter. This is justified because PDF generation must not live in Blade/controller code and must isolate rendering/storage failures.
  • Why the existing abstraction was sufficient or insufficient: Existing abstractions are sufficient for HTML report content, profile/disclosure, source current-pack validation, and signed URL generation. They are insufficient for private PDF artifact storage, generation idempotency, OperationRun result metadata, and download audit.
  • Bounded deviation / spread control: new code must live under existing report/review-pack/support namespaces and target only management PDF v1. No profile CRUD, delivery system, report engine, or artifact lifecycle framework.

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: yes.
  • Central contract reused: OperationRunService, OperationRunLinks, OperationUxPresenter, OperationCatalog, OperationRunType if a new type is needed.
  • Delegated UX behaviors: queued toast/run link/artifact link/run-enqueued browser event/dedupe-or-blocked/start-failure messaging should use the shared OperationRun start UX path.
  • Surface-owned behavior kept local: generation readiness explanation and source review/pack selection only.
  • Queued DB-notification policy: no queued/running DB notification unless explicitly approved through the existing shared start UX contract.
  • Terminal notification path: central lifecycle mechanism.
  • Exception path: none expected. If implementation proposes synchronous no-run PDF generation, update spec/plan first and prove why OperationRun is unnecessary.

Provider Boundary & Portability Fit

  • Shared provider/platform boundary touched?: yes, indirectly through report/evidence content.
  • Provider-owned seams: existing review/evidence summaries that may include Microsoft-specific evidence labels.
  • Platform-core seams: report artifact identity, profile, disclosure, provenance, OperationRun type, StoredReport/source descriptor.
  • Neutral platform terms / contracts preserved: management report, profile, evidence readiness, limitation, managed environment, workspace, generated artifact, source review, source pack, operation.
  • Retained provider-specific semantics and why: only existing profile-safe evidence/finding summaries from stored review/pack truth. No new provider lookup or provider-specific renderer branch.
  • Bounded extraction or follow-up path: Technical/Auditor Evidence Report follow-up if provider-specific detailed appendix becomes necessary.

Constitution Check

GATE: Must pass before implementation. Re-check after design and before code merge.

  • Inventory-first: PASS. Report consumes existing released review/Review Pack/evidence truth, not live provider state.
  • Read/write separation: PASS. PDF generation mutates TenantPilot artifact storage only and requires explicit operator action, audit, and tests.
  • Graph contract path: PASS. No Graph calls are allowed during render, generation, or download.
  • Deterministic capabilities: PASS with task. Reuse existing capability registry paths or add a tested capability only after repo verification.
  • RBAC-UX: REQUIRED. Non-member/wrong scope 404; member missing capability 403; server-side authorization required.
  • Workspace isolation: REQUIRED. Artifact, source review, source pack, operation, and download all resolve workspace/environment scope.
  • Destructive-like/high-impact action: REQUIRED. Generate PDF is high-impact artifact creation; it needs readiness gate, authorization, audit, and safe feedback. It is not destructive.
  • Global search: PASS. No global-search enablement planned; StoredReportResource remains non-globally-searchable unless spec/plan are updated.
  • Run observability: REQUIRED. Preferred path creates/reuses an OperationRun for generation.
  • OperationRun start UX: REQUIRED if queued generation is used; central UX path only.
  • Ops-UX lifecycle: REQUIRED. Status/outcome transitions through OperationRunService; summary counts flat numeric-only if used.
  • Data minimization: REQUIRED. No secrets/raw provider payloads/signed URLs in PDF/audit metadata.
  • Test governance: REQUIRED. Unit/Feature/Browser lanes and fixture costs explicit.
  • Proportionality: PASS with constraint. Generated PDF artifact truth and renderer/generation service solve current customer artifact gap.
  • No premature abstraction: PASS with constraint. Generation/renderer/payload components are bounded to one report family and must not become a generic framework.
  • Persisted truth: PASS. Generated PDF is durable artifact truth with provenance.
  • Behavioral state: PASS if new status/reason keys change artifact visibility, OperationRun outcome, or download behavior.
  • UI semantics: PASS. Directly map existing profile/readiness/disclosure into the PDF; no new taxonomy.
  • Shared pattern first: PASS. Reuse report/profile/disclosure/OperationRun/audit paths first.
  • Provider boundary: PASS. Stored summaries only; no provider runtime calls.
  • V1 explicitness / few layers: PASS. One profile, one artifact, one source family.
  • BLOAT-001: REQUIRED and covered in spec.md.
  • Badge/Filament-native UI: PASS. Owner surfaces stay native Filament. Custom report canvas remains bounded to report/print artifact.
  • UI-COV-001: REQUIRED. Coverage update/no-update rationale required.

Test Governance Check

  • Test purpose / classification by changed surface:
    • Unit: payload/readiness/disclosure/profile filtering and renderer adapter failure mapping.
    • Feature: generation action, authorization, artifact storage, OperationRun outcomes, audit metadata, signed download, cross-scope denial.
    • Filament/Livewire: owner-surface action visibility/disabled state where generation action lands.
    • Browser/content smoke: generate/download path and PDF/text content proof.
  • Affected validation lanes: fast-feedback, confidence, browser; pgsql if schema/index changes.
  • Why this lane mix is the narrowest sufficient proof: Unit tests prove deterministic content and safety decisions; Feature tests prove server-side trust; Browser/content smoke proves the customer-facing artifact is usable and leakage-free.
  • Narrowest proving command(s):
    • cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec378
    • cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec378ManagementReportPdfSmokeTest.php --compact
    • cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec357
    • cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec366
    • cd apps/platform && ./vendor/bin/sail pint --dirty
    • git diff --check
  • Fixture / helper / factory / seed / context cost risks: Reuse Spec357/Spec366 report fixtures and review-output seed command. Any new PDF fixture helpers must remain local to Spec378 unless reused by at least three current specs.
  • Expensive defaults or shared helper growth introduced?: no by default.
  • Heavy-family additions, promotions, or visibility changes: one explicit browser/content smoke only.
  • Surface-class relief / special coverage rule: customer-facing document artifact requires special content/leakage smoke.
  • Closing validation and reviewer handoff: reviewers verify package governance gate, no raw leakage, artifact/operation/audit agreement, scope-safe download, and no report-center/auditor scope.
  • Budget / baseline / trend follow-up: record follow-up if PDF rendering adds material runtime to browser/confidence lanes or production queue requirements.
  • Review-stop questions: renderer approved? artifact storage private? no raw leakage? no second report engine? OperationRun/audit consistent? correct 404/403?
  • Escalation path: document-in-feature for approved renderer choice; follow-up-spec for delivery center, technical/auditor PDF, scheduled delivery, artifact lifecycle.
  • Active feature PR close-out entry: Guardrail + Smoke Coverage.
  • Why no dedicated follow-up spec is needed: The renderer/artifact choice belongs inside Spec 378 if it stays bounded; any broader delivery/auditor lifecycle work is explicitly deferred.

Implementation Approach

Phase 0 - Pre-Implementation Verification

  1. Re-read current report/runtime files listed in the Repo Truth Map.
  2. Renderer/package governance decision is complete: use Gotenberg 8 Chromium as an internal service with the controls in artifacts/spec378-gotenberg-security-controls.md.
  3. Confirm the runtime config task has added the pinned Gotenberg service and app config before any report generation implementation starts.
  4. Verify whether StoredReport can be extended narrowly to reference PDF artifacts.
  5. Verify whether generation should land on Environment Review, Review Pack, or Customer Review Workspace first. Preferred v1 placement: Environment Review or Review Pack detail, because both already know source review/pack readiness.

Phase 0.5 - PDF Rendering Infrastructure Runtime Config

This phase is the first allowed implementation phase after the governance gate. It must be completed before management report payload, storage, OperationRun, UI action, PDF templates, or report-generation work.

Required future implementation work:

  • Identify exact runtime config targets before editing: root docker-compose.yml for Sail/local service wiring, the repo's Dokploy/deployment config or documentation location if present, and an explicit not present note if no Dokploy config file exists in the repo.
  • Add a pinned Gotenberg 8 Chromium internal service to Sail/Dokploy runtime config.
  • Keep the renderer internal-network only with no public port.
  • Add renderer configuration for base URL, timeout, request body limit, asset size limit, PDF output size limit, queue/concurrency expectations, and disabled/unavailable behavior.
  • Add health check verification using Gotenberg /health.
  • Add failing gateway/client tests for health check, renderer unavailable, timeout, invalid response, size-limit rejection, and safe error mapping before completing PdfRendererClient / PdfRenderingGateway.
  • Add PdfRenderingGateway / PdfRendererClient as the only Laravel integration boundary after the gateway/client tests are in place.
  • Add request correlation using the OperationRun id or generation correlation id.
  • Render server-generated HTML payloads only; do not use user-provided URL rendering.
  • Apply the Gotenberg security controls before enabling report generation.
  • Map renderer unavailable, timeout, invalid request, and output-size failures into safe internal result types for later OperationRun handling.
  • Do not add Composer/npm PDF/browser packages unless this spec/plan and docs/package-governance.md are updated again.

Phase 1 - Payload and Readiness

Create a deterministic management-report payload from existing report truth:

  • Source: current ready non-expired Review Pack and linked Environment Review.
  • Profile: customer_executive.
  • Disclosure: ReportDisclosurePolicy::evaluate(...).
  • Sections: cover, executive summary, governance posture, decisions, top risks/findings, accepted risks, evidence readiness, limitations, next actions, provenance, method summary.
  • Readiness: block or disable generation when source is missing/not ready/expired/not current/profile-blocked/disclosure-blocked/unauthorized.
  • No direct database queries in Blade/PDF template.

Likely implementation surfaces:

apps/platform/app/Support/ReviewPacks/ManagementReportPayloadBuilder.php
apps/platform/app/Support/ReviewPacks/ManagementReportReadiness.php
apps/platform/app/Support/ReviewPacks/ManagementReportPdfRenderer.php

Names may differ if existing repo conventions suggest a better home.

Phase 2 - Artifact Storage

Preferred path:

  • Use StoredReport if it can represent the generated PDF artifact with a narrow migration/addition.
  • Add a management report type constant only if resource capability/report type maps are updated safely.
  • Store private PDF file path/disk or artifact reference in the canonical substrate.
  • Keep PDF payload/provenance in JSONB metadata without raw provider payloads.
  • Do not create a new artifact table unless the spec/plan are updated and proportionality is re-approved.

Migration impact if needed:

  • Safe incremental migration under apps/platform/database/migrations.
  • Reversible where feasible.
  • PostgreSQL lane if constraints/indexes/JSONB behavior are relevant.
  • Staging validation required before production.

Phase 3 - OperationRun and Audit

Preferred path:

  • Add or map canonical operation type report.management.generate only if no existing type fits.
  • Register the operation type in OperationCatalog/related guards as required.
  • Use OperationRunService for queued/running/completed/failed/blocked transitions.
  • Use safe context.results summary with artifact id, source review/pack ids, profile, format, and file metadata.
  • Do not write adapter reconciliation metadata unless a reconciliation adapter actually runs.
  • Record audit for generation and download with safe metadata.

Phase 4 - UI Actions and Download

Owner surface behavior:

  • Show or enable Generate management PDF only when source is ready and actor is authorized.
  • If a current generated PDF exists for the same source/profile/fingerprint, prefer Download management PDF or Open management PDF rather than duplicate generation.
  • When generation is running, show one clear operation link.
  • When blocked/failed, show safe reason and operation link.
  • Keep one primary action per focused area.

Download behavior:

  • Use a signed route or server-authorized route with short-lived URL if signing is used.
  • Re-resolve artifact/source scope server-side.
  • Audit every successful download.
  • Do not embed signed URLs in the PDF body.

Phase 5 - PDF Rendering

Renderer requirements:

  • Use the approved Gotenberg 8 Chromium renderer path through PdfRenderingGateway only.
  • Render from prepared payload, not live controller/global request state.
  • No remote fonts/assets.
  • Header/footer, page metadata, generated timestamp, and page numbers when supported.
  • Clean table/section breaks; no huge raw tables.
  • No technical appendix in customer_executive PDF.
  • EN/DE labels through localization.

Phase 6 - Validation and Close-Out

  • Run targeted Spec378 tests.
  • Run Spec357/Spec366 regressions.
  • Run Review Pack and Customer Review Workspace focused regressions as needed.
  • Run browser/content smoke.
  • Run Pint and git diff --check.
  • Record Livewire v4 compliance, provider registration, global-search posture, destructive/high-impact action safety, asset strategy, tests, and deployment impact.

Data Model / Persistence Impact

Expected possibilities:

  1. No schema change: if current artifact storage can reference a PDF through existing fields. Unlikely based on current StoredReport.
  2. Narrow StoredReport extension: likely path if adding report_type=management_report_pdf, artifact file metadata, tenant scope, source environment, source review/pack, operation run, generated by, generated at, status, and profile. This must stay tenant-owned with workspace_id, NOT NULL tenant_id where the table represents tenant-owned artifact truth, and source managed_environment_id.
  3. New artifact entity: not approved by this plan. Stop and update spec/plan before implementation if this becomes necessary.
  4. Tenant-scope stop condition: if the selected substrate cannot represent constitution-compliant tenant scope, stop before persistence changes and update spec/plan; do not rely on managed_environment_id alone for newly persisted tenant-owned artifact truth.

Retention/lifecycle:

  • V1 may use existing stored report retention defaults or record "retained" semantics consistent with current StoredReportResource.
  • Do not implement artifact lifecycle/hold/delete framework in this spec.

RBAC / Policy Implications

  • Generation requires workspace membership, tenant entitlement, managed-environment entitlement, and an existing review/export/manage capability unless a new capability is proven necessary.
  • Download requires view/download permission for the generated artifact and same workspace/tenant/environment scope.
  • Server handlers must call Gate/Policy/capability checks; UI disabled/hidden state is not security.
  • Non-member/wrong workspace/wrong tenant/wrong environment gets 404.
  • Member without capability gets 403 after scope is established.
  • StoredReportResource capability map must include any new management report type or explicitly keep it out of the registry if a separate download route owns access.

UI / Filament / Livewire Implications

  • Filament v5 on Livewire 4.1.4 remains compliant; no Livewire v3 APIs.
  • Panel providers remain registered in apps/platform/bootstrap/providers.php; no panel changes planned.
  • StoredReportResource remains globally non-searchable unless spec/plan are updated. It has a View page today.
  • Generate action is high-impact artifact creation and must use Action::make(...)->action(...), ->requiresConfirmation(), server-side authorization, readiness gate, explicit notification, and audit before artifact creation starts.
  • No destructive action is added.
  • No new Filament assets planned.

Audit / Observability / Evidence Implications

  • Generation audit must include actor, workspace, managed environment, source review id, source review pack id, stored report/artifact id, operation run id, profile, format, status, generated at, and safe metadata.
  • Download audit must include actor, workspace, managed environment, artifact id, source review/pack ids, profile, format, downloaded at, and safe request metadata if existing audit captures it.
  • OperationRun results should include artifact id/path hash/size/fingerprint only if safe; no signed URLs or secrets.
  • Failed generation must be observable and safe.

Deployment / Ops Impact

  • Env vars: renderer base URL, timeout, body/output size limits, disabled/unavailable behavior, and matching Gotenberg timeout/body/concurrency controls are added to apps/platform/.env.example; no direct browser binary path is approved.
  • Migrations: possible narrow stored_reports extension; staging migration validation required.
  • Queues: likely uses queue worker for report generation. Dokploy worker command already includes reports queue in deployment guidance; implementation must confirm actual queue selection.
  • Scheduler/cron: none.
  • Storage: private PDF artifact storage required; production persistence/backup must include the disk/path.
  • Filament assets: none planned; deployment already runs php artisan filament:assets when assets are registered.
  • Package/runtime: Gotenberg 8 Chromium is approved with controls as an internal runtime service; no Composer/npm PDF/browser runtime package is approved. Any different renderer/runtime dependency requires package governance before code changes.

Filament v5 Output Contract For Implementation Close-Out

Implementation response must explicitly state:

  1. Livewire v4.0+ compliance.
  2. Provider registration remains in apps/platform/bootstrap/providers.php.
  3. Global search status: StoredReportResource is globally non-searchable today; any changed resource must keep View/Edit safety explicit.
  4. Destructive/high-impact actions: no destructive action; generation is high-impact artifact creation with authorization, readiness, audit, and explicit confirmation implemented.
  5. Asset strategy: no new Filament assets unless implementation changes plan; deploy filament:assets only if assets are registered.
  6. Testing plan/results for payload, generation, access, audit, OperationRun, download, and browser/content smoke.

Risks and Mitigations

  • Renderer config gap: Sail/local renderer service/config and gateway/client boundary exist, but staging/Dokploy controls are not yet validated. Mitigate by confirming internal-only staging runtime, health check, queue behavior, and persistence before enabling report generation.
  • Storage mismatch: StoredReport may need schema changes. Mitigate with narrow extension or stop/split.
  • Raw leakage: PDF may include hidden/internal content. Mitigate with prebuilt payload and negative content tests.
  • Scope leakage: signed URL could bypass context. Mitigate by server-side re-resolution and 404/403 tests.
  • Duplicate artifact churn: repeated generation could create clutter. Mitigate with source/profile/fingerprint idempotency where practical.
  • Queue failures: renderer/storage can fail. Mitigate OperationRun failed/blocked outcomes and no ready artifact exposure.

Open Questions

Renderer governance decision is complete. Gotenberg 8 Chromium is approved with controls as the internal production PDF rendering service for report-style documents. Runtime/gateway implementation has started: Sail/local service, Laravel config, health check, timeout/size controls, and PdfRenderingGateway / PdfRendererClient now exist. Management report payload/storage/OperationRun/UI/PDF generation work must wait until staging/Dokploy controls are confirmed and the next implementation phase begins.

Implementation Phases

  1. Repo verification and renderer/package gate.
  2. Runtime config target discovery and Gotenberg service/config.
  3. Failing gateway/client tests, then PdfRenderingGateway / PdfRendererClient.
  4. Failing tests for payload, readiness, disclosure, authorization, audit, storage, OperationRun, download, renderer failure mapping, and content leakage.
  5. Payload/readiness/disclosure implementation.
  6. Artifact storage and idempotency.
  7. OperationRun and audit integration.
  8. UI action and download route integration.
  9. PDF rendering through the approved Gotenberg gateway.
  10. Localization.
  11. Browser/content smoke and UI coverage close-out.
  12. Final validation and close-out.