TenantAtlas/specs/378-management-report-pdf-v1/tasks.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

222 lines
22 KiB
Markdown

# Tasks: Spec 378 - Management Report PDF v1
**Input**: `specs/378-management-report-pdf-v1/spec.md`, `specs/378-management-report-pdf-v1/plan.md`
**Prerequisites**: Spec and plan are complete. Renderer governance is approved with controls for Gotenberg 8 Chromium. Renderer runtime/gateway work must complete and be staging-validated before report generation work.
**Tests**: Required. Use Pest 4 Unit, Feature/Filament action, and Browser/content smoke. PostgreSQL lane is required if migrations/indexes are introduced.
**Implementation note**: Renderer governance and the first runtime/gateway boundary are implemented. Downstream report generation tasks remain pending for later `/spec-kit-implementation-loop` passes.
## Phase 1: Repo Verification And Hard Gates
**Purpose**: Confirm current repo truth before runtime edits.
- Gate stop note (2026-06-14): branch `378-management-report-pdf-v1`, HEAD `f1eadadf docs: add spec 377 post-productization browser reaudit closeout gate (#448)`, dirty baseline was the untracked active spec directory `specs/378-management-report-pdf-v1/`. Runtime implementation stopped before code edits because T008 initially found no approved production-safe PDF renderer in `apps/platform/composer.json`, Playwright is dev/browser tooling only in `apps/platform/package.json`, and `docs/package-governance.md` did not yet approve a production PDF renderer.
- Renderer governance update (2026-06-14): T008 has been reviewed and updated through package/runtime governance. Gotenberg 8 Chromium is approved with controls as an internal Docker service, documented in `artifacts/spec378-pdf-renderer-decision-matrix.md`, `artifacts/spec378-gotenberg-security-controls.md`, `artifacts/spec378-constitution-renderer-gate-review.md`, `spec.md`, `plan.md`, and `docs/package-governance.md`. No runtime service, app code, report generation, or tests were implemented by this governance update.
- Runtime/gateway update (2026-06-14): Sail/local runtime target is root `docker-compose.yml`; no Dokploy config file is present in the repo, so `docs/deployment-checklist.md` records staging/production controls. `apps/platform/.env.example`, `apps/platform/config/tenantpilot.php`, and `apps/platform/app/Services/Pdf/*` now define the Gotenberg app config and gateway/client boundary. Report payload, storage, OperationRun, UI action, download route, PDF template, and browser smoke remain pending.
- [x] T001 Re-read `specs/378-management-report-pdf-v1/spec.md`, `plan.md`, `tasks.md`, and `checklists/requirements.md`.
- [x] T002 Record branch, HEAD, dirty state, and touched-file baseline in the active implementation close-out notes before runtime edits.
- [x] T003 Verify the existing rendered report source paths: `ReviewPackRenderedReportController`, `rendered-report.blade.php`, `ReportProfileRegistry`, `ReportDisclosurePolicy`, `ReportThemeResolver`, and `ReviewPackService`.
- [x] T004 Verify current Review Pack source readiness/current-pack rules in `ReviewPackService`, `ReviewPackDownloadController`, `EnvironmentReviewResource`, `ReviewPackResource`, and related tests.
- [x] T005 Verify current `StoredReport` schema/model/resource capability map and decide whether a narrow extension can represent a management PDF artifact.
- [x] T006 Verify current `OperationRunType`, `OperationCatalog`, `OperationRunService`, and Operations UI/actionability rules before adding or mapping `report.management.generate`.
- [x] T007 Verify current audit action IDs and audit logger usage for review exports/downloads; identify whether distinct management PDF generation/download action IDs are required.
- [x] T008 Hard gate: verify an approved production-safe PDF renderer path. If no approved path exists, stop before runtime edits, run package-governance review, and update `spec.md`/`plan.md`.
- [x] T009 Confirm no live Graph/provider call is required for payload, render, generation, or download.
- [ ] T010 Decide the first owner surface for v1 generation: Environment Review detail, Review Pack detail, or Customer Review Workspace. Prefer Environment Review or Review Pack detail unless repo verification proves otherwise.
## Phase 1A: Renderer Governance Decision Completed
**Purpose**: Document the renderer/package/runtime decision without implementing report generation.
- [x] G001 Review the renderer/package gate after the manual `gate stop valid` decision.
- [x] G002 Evaluate renderer candidates: Gotenberg 8 Chromium, Spatie Browsershot / Spatie Laravel PDF, dompdf / laravel-dompdf, wkhtmltopdf / Snappy, and PrinceXML.
- [x] G003 Create `specs/378-management-report-pdf-v1/artifacts/spec378-pdf-renderer-decision-matrix.md`.
- [x] G004 Document required Gotenberg security controls in `specs/378-management-report-pdf-v1/artifacts/spec378-gotenberg-security-controls.md`.
- [x] G005 Document invoice/billing/e-invoice boundary in `spec.md`, `plan.md`, and `specs/378-management-report-pdf-v1/artifacts/spec378-constitution-renderer-gate-review.md`.
- [x] G006 Update `docs/package-governance.md` with Gotenberg 8 Chromium approved-with-controls runtime service entry.
- [x] G007 Update `spec.md` and `plan.md` with the selected renderer and pending runtime-config boundary.
- [x] G008 Identify exact runtime config targets before editing: root `docker-compose.yml` for Sail/local service wiring, Dokploy/deployment config or documentation location if present, and explicit `not present` notes for missing deployment config files.
- [x] G009 Add the Gotenberg runtime service to the identified Sail/Dokploy config target(s) with a pinned image, no public port, health check, timeouts, request/output limits, and outbound/file-access controls.
- [x] G010 Add renderer app config for base URL, timeout, body/output limits, unavailable behavior, and correlation id handling.
- [x] G011 Add failing renderer gateway/client tests for health check, renderer unavailable, timeout, invalid response, size-limit rejection, and safe error mapping before completing the gateway/client.
- [x] G012 Implement the Laravel `PdfRenderingGateway` / `PdfRendererClient` as the only production renderer integration boundary.
- [ ] G013 Confirm Gotenberg runtime controls in staging before enabling report PDF generation.
- Remaining validation note: `docker compose config --quiet` passes locally, but a direct pull/probe of `gotenberg/gotenberg:8.34.0-chromium` was cancelled after staying silent and returning a Docker credential interruption. Staging/Dokploy must verify the configured `/health` healthcheck command runs inside the pinned image.
## Phase 2: Test Design First
**Purpose**: Add failing or pending proof for the core behavior before implementation.
- [ ] T011 Add Unit coverage for management report payload sections: cover, executive summary, governance posture, key decisions, top findings, accepted risks, evidence readiness, limitations, next actions, provenance, and method summary.
- [ ] T012 Add Unit coverage proving `customer_executive` profile and disclosure policy hide technical appendix, raw provider payloads, internal MSP fields, signed URLs, and raw operation context.
- [ ] T013 Add Unit coverage for readiness decisions: missing review, non-current pack, expired pack, not-ready pack, invalid/unimplemented profile, disclosure blocker, missing evidence limitation, and unauthorized actor.
- [x] T014 Add Unit or Feature coverage for Gotenberg gateway renderer failure mapping to safe failed/blocked result without stack trace leakage.
- [ ] T015 Add Feature coverage for authorized generation from a ready current Review Pack or Environment Review source.
- [ ] T016 Add Feature coverage for artifact storage or canonical artifact reference with workspace, tenant scope, managed environment, source review, source pack, profile, format, generated-by, generated-at, and operation-run provenance.
- [ ] T017 Add Feature coverage for generation audit metadata and failed generation audit/OperationRun evidence.
- [ ] T018 Add Feature coverage for successful download audit metadata.
- [ ] T019 Add authorization coverage for no workspace membership, wrong tenant, and wrong managed environment returning 404.
- [ ] T020 Add authorization coverage for scoped member without generation/download capability returning 403 after scope is established.
- [ ] T021 Add Feature coverage proving denied generation creates no artifact and exposes no download.
- [ ] T022 Add Feature coverage proving download route re-resolves artifact/source scope and rejects stale, expired, cross-workspace, cross-tenant, or cross-environment access.
- [ ] T023 Add Filament/Livewire action coverage for visibility, disabled reason, notification, and operation/download link behavior on the chosen owner surface.
- [ ] T024 Add Browser/content smoke coverage for generate or download flow when local fixtures support it.
- [ ] T025 Add Browser/content smoke assertions that PDF text includes required management chapters and excludes forbidden strings: `SQLSTATE`, `access token`, `client secret`, `raw Graph payload`, `internal_msp_review`, serialized job markers, and signed URLs.
## Phase 3: Payload, Readiness, And Disclosure
**Purpose**: Build deterministic report content from existing source truth only.
- [ ] T026 Implement a bounded management report payload builder or equivalent under the existing report/review-pack support namespace.
- [ ] T027 Build payload only from existing `ReviewPack`, `EnvironmentReview`, `EvidenceSnapshot`, findings summary, accepted risk/exception, decision summary, and rendered-report support truth.
- [ ] T028 Ensure the payload builder does not query from Blade/PDF templates and does not call Graph/provider services.
- [ ] T029 Resolve the effective profile through `ReportProfileRegistry` and default to `customer_executive`.
- [ ] T030 Apply `ReportDisclosurePolicy` before rendering and fail closed for unknown/unimplemented profile input.
- [ ] T031 Implement readiness/blocked reason mapping for source missing, not current, not ready, expired, evidence limitation, disclosure blocker, Gotenberg renderer unavailable, storage unavailable, and authorization failure.
- [ ] T032 Ensure missing evidence either blocks generation or appears as a management-visible limitation according to existing review/report policy; document the chosen behavior in code/tests.
- [ ] T033 Keep next actions derived from existing report/review/finding/evidence data; do not invent AI or unsupported recommendations.
## Phase 4: Artifact Storage And Idempotency
**Purpose**: Store or reference the generated PDF without inventing a report center.
- [ ] T034 If current fields are insufficient, add a narrow reversible migration for the existing report/artifact substrate rather than a new table.
- [ ] T035 If extending `StoredReport`, add only fields required for PDF artifact identity, tenant scope, source environment, source review/pack, profile, format, status, file disk/path, generated by, generated at, and operation run provenance; newly persisted tenant-owned artifact truth must include NOT NULL `tenant_id` unless a constitution-compliant exception is added before implementation.
- [ ] T036 Add or update `StoredReport` constants/casts/relationships for management PDF only if `StoredReport` is the chosen substrate.
- [ ] T037 Update `StoredReportResource` capability/report type handling only if management PDFs are listed/viewed there; keep global search disabled.
- [ ] T038 Store PDF artifacts on a private disk/path and avoid public filenames or secret-bearing paths.
- [ ] T039 Implement source/profile/fingerprint idempotency or document why repeated generation intentionally creates separate artifacts.
- [ ] T040 Ensure no ready/downloadable artifact is exposed when generation fails before storage commit.
- [ ] T041 If any schema/index behavior is PostgreSQL-specific, add PostgreSQL lane proof.
## Phase 5: OperationRun And Audit
**Purpose**: Make generation observable and accountable.
- [ ] T042 Add or map canonical operation type `report.management.generate` only if no existing type fits; update `OperationRunType`, `OperationCatalog`, labels, guards, and tests consistently.
- [ ] T043 Start/queue generation through `OperationRunService` unless a spec/plan update explicitly approves a synchronous no-run path.
- [ ] T044 Route queued toast/link/artifact-link/start-failure behavior through existing OperationRun UX patterns.
- [ ] T045 Mark successful generation completed/succeeded with safe results metadata.
- [ ] T046 Mark renderer/storage/source blocked cases completed/failed or completed/blocked with safe reason codes according to existing OperationRun outcome semantics.
- [ ] T047 Do not write `context.reconciliation` unless an actual reconciliation adapter runs.
- [ ] T048 Record generation audit with actor, workspace, tenant scope, managed environment, source review, source pack, stored artifact/report id, operation run id, profile, format, generated at, and safe metadata.
- [ ] T049 Record download audit with actor, workspace, tenant scope, managed environment, artifact/report id, source review/pack, profile, format, downloaded at, and safe request metadata if available.
- [ ] T050 Confirm audit metadata excludes secrets, signed URLs, raw provider payloads, raw operation context, stack traces, and SQL errors.
## Phase 6: UI Action And Download Route
**Purpose**: Expose one clear, safe generation/download flow.
- [ ] T051 Add the `Generate management PDF` action to the selected owner surface using `Action::make(...)->action(...)`.
- [ ] T052 Gate the action with server-side authorization, readiness, and scope checks; UI state is not security.
- [ ] T053 Implement explicit Filament confirmation for high-impact artifact creation using `->requiresConfirmation()` or the repo-approved equivalent before generation starts.
- [ ] T054 Show disabled/blocked reason when source review/pack is not ready, expired, not current, profile-blocked, disclosure-blocked, unauthorized, or renderer unavailable.
- [ ] T055 If a matching ready PDF artifact already exists, prefer a `Download management PDF` or `Open management PDF` affordance over duplicate generation.
- [ ] T056 If generation is queued/running, show a single canonical `View operation` or equivalent operation link through existing link helpers.
- [ ] T057 Implement a signed and/or server-authorized PDF download route if existing routes cannot safely represent management PDF format/profile/artifact identity.
- [ ] T058 In the download route/controller, re-resolve workspace, tenant scope, managed environment, source review/pack, artifact status, and actor capability before returning file bytes.
- [ ] T059 Set safe PDF download filename and headers without exposing internal IDs as the primary label.
- [ ] T060 Keep Review Pack ZIP download behavior unchanged.
## Phase 7: PDF Rendering
**Purpose**: Render the management PDF from prepared payload only.
- [ ] T061 Implement the PDF renderer through the approved Gotenberg 8 Chromium path via `PdfRenderingGateway` / `PdfRendererClient`.
- [ ] T062 Render cover, executive summary, governance posture, key decisions, top risks/findings, accepted risks, evidence readiness, scope/limitations, next actions, provenance, and method summary.
- [ ] T063 Include generated timestamp, source review/pack metadata, profile, and classification/confidentiality marker.
- [ ] T064 Include header/footer and page numbering when supported by the approved renderer.
- [ ] T065 Avoid remote fonts, external assets, public images, or network-dependent resources.
- [ ] T066 Avoid huge raw tables; limit top findings to a management-safe count and route full details to deferred technical/auditor reports.
- [ ] T067 Ensure PDF output does not include hidden technical appendix content for `customer_executive`.
- [ ] T068 Ensure Gotenberg renderer errors produce safe exceptions/results that can be mapped to OperationRun failed/blocked.
## Phase 8: Localization
**Purpose**: Make the report labels and actions DE/EN-ready through existing seams.
- [ ] T069 Add EN localization keys for action labels, notifications, blocked reasons, PDF chapter titles, profile labels, limitation labels, and provenance labels.
- [ ] T070 Add DE localization keys for the same user-facing labels.
- [ ] T071 Ensure date/time/number formatting uses existing locale-aware conventions where available.
- [ ] T072 Add tests for central labels or rendered content in EN and DE where feasible.
## Phase 9: UI Coverage And Documentation-In-Feature
**Purpose**: Satisfy UI-COV without broad docs churn.
- [ ] T073 Apply the UI coverage rule: update route inventory for any new signed/authorized PDF route, `ui-099-rendered-review-report.md` for rendered-report/PDF source or customer-facing report presentation changes, `ui-042-review-pack-detail.md` for Review Pack detail action/download changes, `ui-048-stored-report-detail.md` for StoredReport registry/detail exposure, and the design coverage matrix for material action hierarchy, artifact state, or surface classification changes.
- [ ] T074 If materially changed, update the relevant UI coverage artifact(s) with screenshot/reference/status.
- [ ] T075 If not materially changed, record the checked no-update rationale in the implementation close-out.
- [ ] T076 Store browser screenshots/content evidence under `specs/378-management-report-pdf-v1/artifacts/` if captured.
- [x] T077 Record renderer/package decision in the governance artifacts.
- [ ] T092 Record the storage substrate decision in implementation close-out after `StoredReport` versus alternate canonical artifact representation is resolved.
- [ ] T093 Record the OperationRun type decision in implementation close-out after confirming whether `report.management.generate` or an existing canonical type is used.
- [ ] T094 Record the UI coverage decision in implementation close-out after owner surface, download route, and StoredReport exposure are known.
## Phase 10: Validation
**Purpose**: Prove the feature and prevent adjacent report regressions.
- [x] T078 Run `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec378`.
- [ ] T079 Run `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec357`.
- [ ] T080 Run `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec366`.
- [ ] T081 Run focused Review Pack regressions selected from current touched surfaces, including rendered-report/profile/download/resource tests as applicable.
- [ ] T082 Run focused Customer Review Workspace regression if the implementation touches customer workspace action/state copy.
- [ ] T083 Run focused OperationRun regression if a new operation type or OperationCatalog mapping is added.
- [ ] T084 Run `cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec378ManagementReportPdfSmokeTest.php --compact` if browser/content smoke was added.
- [ ] T085 Run PostgreSQL lane if migrations, JSONB indexes, or artifact storage constraints require it.
- [x] T086 Run `cd apps/platform && ./vendor/bin/sail pint --dirty`.
- [x] T087 Run `git diff --check`.
- [x] T088 Static scan changed runtime files for Livewire v3 API names (`emit`, `emitTo`, `dispatchBrowserEvent`) and confirm none were introduced.
- [x] T089 Review changed runtime files for Graph/provider calls during render/generation/download and confirm none were introduced.
- [x] T090 Review final implementation diff for new packages, env vars, migrations, queues, scheduler, storage, panel providers, global search, Filament assets, native PDF runtime, customer portal, scheduled delivery, AI, and auditor/technical report scope.
- [ ] T091 Complete final close-out with Livewire v4 compliance, provider registration location, global search status, destructive/high-impact action status, asset strategy, tests, and deployment impact.
## Non-Goals
- [ ] NT001 Do not build a Technical Evidence Report PDF.
- [ ] NT002 Do not build an Auditor Evidence Report PDF.
- [ ] NT003 Do not build a Report Delivery Center.
- [ ] NT004 Do not add scheduled/email/Teams delivery.
- [ ] NT005 Do not add public links or a customer portal.
- [ ] NT006 Do not add Word/DOCX, PowerPoint, Excel, or raw JSON customer appendix export.
- [ ] NT007 Do not add AI-generated summaries or AI review workflow.
- [ ] NT008 Do not create a second report taxonomy or generic report engine.
- [ ] NT009 Do not change Review Pack ZIP download contract.
- [ ] NT010 Do not add a new artifact lifecycle/retention framework.
- [ ] NT011 Do not call Microsoft Graph/provider APIs during render, generation, or download.
- [ ] NT012 Do not rewrite completed historical specs or remove close-out/validation evidence from related specs.
## Dependencies And Ordering
- Phase 1 gates must complete before runtime edits.
- Phase 1A governance is complete, but G008-G013 must complete before management report payload/storage/OperationRun/UI/PDF generation implementation.
- T010 must complete before T023 and T051-T060, but it is not a prerequisite for G008-G013 runtime/gateway work.
- Tests in Phase 2 should be added before or alongside implementation.
- Payload/readiness/disclosure must complete before PDF rendering.
- Artifact storage and OperationRun/audit must complete before exposing download.
- Browser/content smoke runs after the owner surface and download route are usable.
- Validation and close-out run last.
## Parallel Opportunities
- T003-T007 can run in parallel during verification.
- T011-T014 can be developed in parallel with T015-T023 after fixtures are agreed.
- T069-T072 can run after visible labels are known.
- T078-T083 can run in parallel once implementation is stable.
## Implementation Strategy
1. Resolve the renderer/package gate first. Completed decision: Gotenberg 8 Chromium internal service approved with controls.
2. Add the Gotenberg runtime service/config and Laravel gateway before report generation work.
3. Keep content/payload derived from existing rendered-report truth.
4. Prefer narrow StoredReport/canonical artifact extension over new persistence.
5. Use OperationRun/audit as generation truth.
6. Add the smallest owner-surface action and signed/authorized download path.
7. Prove customer-safe content and leakage boundaries with tests and browser/content smoke.
## Expected Task Count
- Implementation tasks: 94 plus 13 renderer-governance/runtime-boundary tasks
- Non-goal guardrails: 12
- MVP path: T001-T068 plus validation subset T078, T081, T083 if operation type changed, T084, T086-T091