Implemented management report layout branded report themes as requested. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #437
27 KiB
Implementation Plan: Spec 366 - Management Report Layout & Branded Report Themes v1
Branch: 366-management-report-layout-branded-report-themes-v1 | Date: 2026-06-08 | Spec: spec.md
Input: Feature specification from /specs/366-management-report-layout-branded-report-themes-v1/spec.md
Note: This plan is a preparation artifact only. It defines the implementation path and validation gate; it does not implement application code.
Summary
Spec 366 productizes the existing authenticated Review Pack rendered-report route into a management-ready, profile-aware, print-friendly report with bounded text co-branding. It builds on the repo-real Spec 356 HTML report renderer and Spec 357 static profile/disclosure policy. The implementation should improve the existing rendered-report family, not create a new report engine, PDF stack, delivery workflow, customer portal, or theme persistence layer.
The narrow technical approach is:
- Verify current report truth and capture a small current-layout audit.
- Add tests first for derived theme/layout behavior, rendered output, disclosure preservation, print toolbar behavior, and browser screenshots.
- Add a bounded derived report theme/layout contract only where it reduces controller/view duplication and improves testability.
- Refactor the existing rendered-report Blade into profile-aware sections/partials only if that makes the report safer to review.
- Keep all report truth derived from existing Review Pack, Environment Review, Evidence Snapshot, profile, and disclosure policy data.
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, Laravel Sail 1.x, Tailwind CSS 4.2.2 through the existing platform build
Storage: PostgreSQL via existing models only. No new table, migration, persisted report theme, or upload storage is planned.
Testing: Pest 4 Unit, Feature, and one bounded Browser smoke. Browser tests use Pest 4 browser testing and should assert no JavaScript errors/console logs.
Validation Lanes: fast-feedback, confidence, browser.
Target Platform: Laravel web application under apps/platform.
Project Type: Laravel + Filament app with a custom authenticated Blade report view under the existing Review Pack route family.
Performance Goals: Rendered report remains stored-data-only. No Graph/provider calls during report render.
Constraints: Disclosure policy is authoritative; branding cannot hide readiness/limitations; no raw JSON/secrets/default diagnostics; no new asset registration unless implementation proves it necessary.
Scale/Scope: One existing rendered-report route/view family and existing owner-surface links. No new IA, panel, or navigation.
Repo Truth Captured During Prep
- Current branch after Spec Kit scaffold:
366-management-report-layout-branded-report-themes-v1 - Baseline HEAD before prep edits:
6ac0913f feat: implement operations UI operator actions regression gate (#436) - Starting worktree: clean on
platform-dev; after scaffold only the new Spec 366 artifacts are intended to change. - No existing
specs/366-management-report-layout-branded-report-themes-v1/directory or branch existed before preparation. - Spec 356 and Spec 357 packages contain completed-task and validation signals and are treated as historical context only.
- Current package baseline from Laravel Boost:
- PHP 8.4.15
- Laravel 12.52.0
- Filament 5.2.1
- Livewire 4.1.4
- Pest 4.3.1
- PostgreSQL
Relevant implementation files discovered:
apps/platform/app/Http/Controllers/ReviewPackRenderedReportController.php
apps/platform/app/Services/ReviewPackService.php
apps/platform/app/Support/ReviewPacks/ReportProfileRegistry.php
apps/platform/app/Support/ReviewPacks/ReportDisclosurePolicy.php
apps/platform/app/Support/ReviewPacks/ReviewPackOutputReadiness.php
apps/platform/app/Support/ReviewPacks/ReviewPackOutputResolutionGuidance.php
apps/platform/app/Filament/Resources/EnvironmentReviewResource.php
apps/platform/app/Filament/Resources/EnvironmentReviewResource/Pages/ViewEnvironmentReview.php
apps/platform/app/Filament/Resources/ReviewPackResource.php
apps/platform/app/Filament/Resources/ReviewPackResource/Pages/ViewReviewPack.php
apps/platform/resources/views/review-packs/rendered-report.blade.php
apps/platform/lang/en/localization.php
apps/platform/lang/de/localization.php
apps/platform/tests/Feature/ReviewPack/ReviewPackDownloadTest.php
apps/platform/tests/Feature/ReviewPack/Spec357RenderedReportProfileTest.php
apps/platform/tests/Browser/Spec357ReportProfilesSmokeTest.php
apps/platform/tests/Unit/Support/ReviewPacks/Spec357ReportProfileRegistryTest.php
apps/platform/tests/Unit/Support/ReviewPacks/Spec357ReportDisclosurePolicyTest.php
Repo-specific baseline decisions:
ReviewPackRenderedReportControlleralready builds the rendered-report payload and currently owns base branding, hero, management summary, source metadata, and profile/disclosure integration.ReportProfileRegistryalready definescustomer_executive,customer_technical,internal_msp_review,auditor_appendix, and placeholderframework_readiness.ReportDisclosurePolicyalready emits mandatory disclosures, warnings, blocking reasons, proof states, and appendix/technical-detail visibility decisions.rendered-report.blade.phpalready has a report toolbar outsidemain.report-canvas, print CSS that hides toolbar/screen-only controls, a cover/hero section, management summary, profile, limitations, evidence basis, appendix, and disclosure areas.- Existing tests already prove some Spec 366-adjacent behavior, so implementation must avoid duplicating broad Spec 356/357 proof and instead add the missing layout/theme/productization checks.
Candidate Selection Gate
- Selected candidate: Management Report Layout & Branded Report Themes v1.
- Source: Direct user-provided Spec 366 draft.
- Why selected: It is a bounded follow-through after the report renderer and profile/disclosure policy are repo-real.
- Deferred alternatives: scheduled delivery, compliance framework profiles, customer portal report consumption, native PDF, and AI/HITL report review are deferred because they depend on a stable management-ready report layout.
- Completed-spec guardrail: Specs 356 and 357 are completed/validated context only; they are not rewritten. No completed Spec 366 package existed.
- Result: PASS.
UI / Surface Guardrail Plan
- Guardrail scope: changed customer-facing report surface.
- Affected routes/pages/actions/states/navigation/panel/provider surfaces:
- existing rendered Review Pack report URL generated by
ReviewPackService::generateRenderedReportUrl() ReviewPackRenderedReportControllerresources/views/review-packs/rendered-report.blade.php- existing report launch links on Environment Review and Review Pack detail surfaces
- existing rendered Review Pack report URL generated by
- No-impact class, if applicable: N/A.
- Native vs custom classification summary: existing custom Blade report view inside an authenticated Laravel/Filament app. Keep owner surfaces Filament-native; report canvas may stay custom because it is a print artifact.
- Custom surface exception:
UI-EX-001: Legitimate Custom Surface Exceptionapplies to the rendered-report canvas and toolbar/print treatment. The product reason is that the customer-facing governance report requires cover identity, readiness, KPI/decision strip, profile-aware appendix hierarchy, disclosure, and print behavior that ordinary CRUD/detail/table primitives do not express cleanly. - Smallest custom behavior: one local Blade report canvas with bounded toolbar/print CSS, profile-aware section ordering, and text-only co-branding. No second renderer, general design system, native PDF stack, customer portal, theme editor, upload UI, or report-layout framework.
- Standardized behavior retained: authorization, workspace/environment entitlement, Review Pack launch links, owner surfaces, profile registry, disclosure policy, localization, and read-only action semantics remain on existing Laravel/Filament/Review Pack paths.
- Custom surface proof: Feature/Browser tasks must prove report hierarchy, disclosure visibility, toolbar-hidden print behavior, screenshots, accessibility/focus basics, no text overlap, no JavaScript/console errors, and UI coverage update or no-update rationale.
- Shared-family relevance: evidence/report viewer, status/readiness messaging, report toolbar, customer-safe disclosure, source metadata.
- State layers in scope: report payload, report view, print CSS, profile-specific section ordering, derived theme/co-branding slots.
- Audience modes in scope: customer executive, customer technical, internal MSP review, controlled auditor appendix.
- Decision/diagnostic/raw hierarchy plan: management decision content first; evidence/technical appendix second; raw/support data absent by default.
- Raw/support gating plan: no raw JSON or support payload in default report output. If existing technical details are rendered for internal/auditor profiles, keep them structured and non-secret.
- One-primary-action / duplicate-truth control: report toolbar remains outside canvas; report content itself stands alone with a single readable management story.
- Handling modes by drift class or surface: review-mandatory for any customer-facing disclosure, print CSS, appendix hierarchy, or branding change.
- Repository-signal treatment: update
ui-099-rendered-review-report.mdand/or coverage matrix if the implemented visual hierarchy materially changes the page contract; otherwise record a no-update rationale. - Special surface test profiles: report-viewer / customer-facing artifact surface.
- Required tests or manual smoke: Feature route/output tests plus one bounded Browser smoke with screenshots.
- Exception path and spread control: custom report CSS remains local to the rendered report unless implementation proves a shared asset is required. No new Filament asset registration is planned.
- Active feature PR close-out entry: Guardrail + Smoke Coverage.
- UI/Productization coverage decision: material existing-page/report-surface change; coverage docs must be updated or explicitly closed out.
- Coverage artifacts to update: likely
docs/ui-ux-enterprise-audit/page-reports/ui-099-rendered-review-report.md; maybe design coverage matrix if the surface classification changes. - No-impact rationale: N/A.
- Navigation / Filament provider-panel handling: no panel provider or navigation change planned. Laravel 12 Filament providers remain in
apps/platform/bootstrap/providers.php. - Screenshot or page-report need: yes, screenshots under
specs/366-management-report-layout-branded-report-themes-v1/artifacts/screenshots/.
Shared Pattern & System Fit
- Cross-cutting feature marker: yes.
- Systems touched: existing Review Pack rendered report, profile registry, disclosure policy, Review Pack service URL generation, Environment Review/Review Pack owner-surface report links, localization.
- Shared abstractions reused:
ReportProfileRegistry,ReportDisclosurePolicy,ReviewPackOutputReadiness,ReviewPackOutputResolutionGuidance,ReviewPackService. - New abstraction introduced? why?: One bounded derived report theme/layout contract is planned because Spec 366 needs a testable contract for text co-branding, layout mode, KPI strip, and print/report section metadata. The concrete implementation may be a
ReportThemeResolveror a controller-local view-model if that is narrower. - Why the existing abstraction was sufficient or insufficient: Existing profile/disclosure abstractions are sufficient for audience and safety. They do not define theme/co-branding slots, profile-specific section ordering, or KPI strip composition.
- Bounded deviation / spread control: The new shape must live inside
App\Support\ReviewPacksor the existing controller payload; it must not become a cross-domain theme engine.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: no.
- Central contract reused: N/A.
- Delegated UX behaviors: N/A.
- Surface-owned behavior kept local: N/A.
- Queued DB-notification policy: N/A.
- Terminal notification path: N/A.
- Exception path: none. Existing Review Pack generation OperationRun behavior is out of scope.
Provider Boundary & Portability Fit
- Shared provider/platform boundary touched?: no.
- Provider-owned seams: none.
- Platform-core seams: report profile/audience, rendered report source metadata, evidence/readiness truth.
- Neutral platform terms / contracts preserved: workspace, managed environment, report, profile, audience, readiness, evidence basis, review pack.
- Retained provider-specific semantics and why: Existing stored report/pack sections may contain provider-specific evidence summaries where already allowed by profile/disclosure policy; no new provider coupling is added.
- Bounded extraction or follow-up path: none.
Constitution Check
GATE: Must pass before implementation. Re-check after design and before code merge.
- Inventory-first: PASS. Report rendering consumes existing last-observed/released review and Review Pack truth.
- Read/write separation: PASS. Report route remains read-only. No restore/remediation/provider write action is introduced.
- Graph contract path: PASS. No Graph/provider calls during report render.
- Deterministic capabilities: PASS. Existing
REVIEW_PACK_VIEWcapability and policies remain authoritative. - RBAC-UX: PASS. Existing cross-workspace/environment not-found semantics and missing-capability 403 stay in place.
- Workspace isolation: PASS. Existing Review Pack/Environment Review workspace/environment scope must remain.
- Destructive-like actions: PASS. No destructive or high-impact action is introduced.
- Global search: PASS. No resource global-search behavior changes.
- Run observability: PASS. No new OperationRun type or queue path.
- OperationRun start UX: PASS / N/A. No OperationRun start/link UX touched.
- Ops-UX lifecycle and summary counts: PASS / N/A.
- Data minimization: PASS. No secrets/raw provider payloads/default raw JSON in report output.
- Test governance: PASS. Unit, Feature, and Browser lanes are explicit and bounded.
- Proportionality: PASS. Bounded report theme/layout resolver is justified only for current report productization and remains derived/non-persisted.
- No premature abstraction: PASS with constraint. Do not create theme persistence, editor, or generalized rendering framework.
- Persisted truth: PASS. No new persisted truth.
- Behavioral state: PASS. No new status/state family.
- UI semantics: PASS. Directly map report profile/readiness/disclosure truth into layout.
- Shared pattern first: PASS. Use existing report profile/disclosure services first.
- Provider boundary: PASS. No provider-specific theme or platform-core leakage.
- V1 explicitness / few layers: PASS. Keep local and derived.
- Spec discipline / bloat check: PASS. Proportionality review is complete.
- Badge semantics: PASS. If status-like badges are changed, use existing safe report/status presentation rather than ad-hoc truth.
- Filament-native UI: PASS. Owner surfaces remain Filament-native; custom report canvas is covered by
UI-EX-001: Legitimate Custom Surface Exceptionand remains bounded to the existing print/report artifact. - UI/UX surface taxonomy: PASS. Rendered report surface classified.
- Decision-first operating model: PASS. Report first screen supports management decision.
- Audience-aware disclosure: PASS. Customer/internal/auditor profile hierarchy is explicit.
- Filament UI Action Surface Contract: PASS. No new Filament mutating actions; report toolbar actions are navigation/download/print only.
- UI/Productization coverage: PASS. Coverage update/no-update rationale required.
Test Governance Check
- Test purpose / classification by changed surface:
- Unit: derived theme/layout/profile mapping.
- Feature: rendered-report route authorization, content, disclosure, ZIP invariance, print CSS, no provider calls.
- Browser: visual/smoke proof for profile variants, print view, and screenshot artifacts.
- Affected validation lanes: fast-feedback, confidence, browser.
- Why this lane mix is the narrowest sufficient proof: Most safety is server-rendered HTML/content and deterministic derived data. Browser proof is required only for real report hierarchy, print toolbar behavior, JS/console smoke, and screenshots.
- Narrowest proving command(s):
cd apps/platform && ./vendor/bin/sail artisan test tests/Unit/Support/ReviewPacks/Spec366ReportThemeContractTest.php --compactcd apps/platform && ./vendor/bin/sail artisan test tests/Feature/ReviewPack/Spec366RenderedReportLayoutTest.php --compactcd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec366ManagementReportLayoutSmokeTest.php --compact
- Fixture / helper / factory / seed / context cost risks: Reuse Spec357 rendered-report fixtures and helpers where possible. New helpers must be local to Spec366 files.
- Expensive defaults or shared helper growth introduced?: no.
- Heavy-family additions, promotions, or visibility changes: one explicit Browser smoke file only.
- Surface-class relief / special coverage rule: customer-facing report surface requires browser screenshots and no raw leakage checks.
- Closing validation and reviewer handoff: Re-run Spec356/Spec357/ReviewPack/EnvironmentReview regressions and verify no ZIP/download/authorization behavior changed.
- Budget / baseline / trend follow-up: none expected beyond one browser file.
- Review-stop questions:
- Does branding hide or weaken disclosure/readiness truth?
- Does any metric lack a repo-backed source?
- Does customer executive layout still show appendix too prominently?
- Does print hide toolbar and keep disclosure visible?
- Did implementation add persistence/upload/theme editor/native PDF/delivery scope?
- Escalation path: document-in-feature for deferred optional logo/accent; follow-up-spec for scheduled delivery, theme CRUD, PDF, portal, AI, or compliance reports.
- Active feature PR close-out entry: Guardrail + Smoke Coverage.
- Why no dedicated follow-up spec is needed: This is the dedicated layout/theme productization slice. Larger delivery/compliance/portal/AI items stay separate follow-ups.
Project Structure
Documentation (this feature)
specs/366-management-report-layout-branded-report-themes-v1/
├── spec.md
├── plan.md
├── tasks.md
├── checklists/
│ └── requirements.md
└── artifacts/
└── screenshots/ # created during implementation/browser smoke
Implementation tasks will create a repo-truth map and may create a current-layout audit:
specs/366-management-report-layout-branded-report-themes-v1/repo-truth-map.md
specs/366-management-report-layout-branded-report-themes-v1/current-report-layout-audit.md
repo-truth-map.md is required by the implementation task list to lock the current report fields, repo-backed metrics, baseline commit, and any narrower controller-local theme decision. current-report-layout-audit.md is optional and should only be created when screenshots or manual review reveal concrete layout problems that guide implementation. Neither artifact is runtime code.
Source Code (repository root)
Expected implementation paths:
apps/platform/app/
├── Http/Controllers/ReviewPackRenderedReportController.php
├── Services/ReviewPackService.php
├── Support/ReviewPacks/
│ ├── ReportProfileRegistry.php
│ ├── ReportDisclosurePolicy.php
│ ├── ReviewPackOutputReadiness.php
│ ├── ReviewPackOutputResolutionGuidance.php
│ └── ReportThemeResolver.php # only if justified during implementation
└── Filament/Resources/
├── EnvironmentReviewResource.php
└── ReviewPackResource.php
apps/platform/resources/views/review-packs/
├── rendered-report.blade.php
└── partials/ # only if splitting reduces review risk
├── report-toolbar.blade.php
├── report-cover.blade.php
├── report-state-hero.blade.php
├── report-kpi-strip.blade.php
├── report-executive-summary.blade.php
├── report-appendix.blade.php
└── report-disclosure-footer.blade.php
apps/platform/lang/
├── en/localization.php
└── de/localization.php
apps/platform/tests/
├── Unit/Support/ReviewPacks/Spec366ReportThemeContractTest.php
├── Feature/ReviewPack/Spec366RenderedReportLayoutTest.php
└── Browser/Spec366ManagementReportLayoutSmokeTest.php
Structure Decision: Stay inside the existing Review Pack rendered-report family. Add no new app module, no new base folder outside existing conventions, and no new package.
Data / Domain Model Implications
- No new persisted entity, table, enum, lifecycle state, queue family, or independent report artifact.
- Derived theme/layout data may include:
prepared_byprepared_forgenerated_bygenerated_ataccentlogolayout_modekpi_stripsection_order
logoandaccentmust stay null/default unless existing safe repo-backed fields are verified.- KPI strip values must be derived only from existing report/review/evidence payloads.
Implementation Phases
Phase 0 - Repo Verification and Current Layout Audit
- Confirm Specs 356 and 357 are stable in the current branch.
- Re-read current controller/view/tests.
- Create
repo-truth-map.mdto record current fields, gaps, repo-backed metrics, optional branding fields, baseline commit, and any narrower controller-local theme decision. - Create
current-report-layout-audit.mdonly if browser screenshots or manual review reveal concrete layout problems that guide implementation. - Stop if Spec 357 profile/disclosure behavior is absent or failing.
Phase 1 - Tests First
- Add Unit tests for derived theme/layout contract or verify current controller payload if no new class is justified.
- Add Feature tests for route output, profile layout, co-branding, print CSS, disclosure preservation, no ZIP change, no provider call, no raw/localization leakage.
- Add Browser smoke for profile variants, print class/print behavior, screenshots, and no JS/console errors.
Phase 2 - Theme/Layout Contract
- Add
ReportThemeResolveror equivalent controller-local view-model shape only if justified by tests and current code. - Use workspace and managed-environment names for text co-branding.
- Keep optional logo/accent null/default unless repo-backed fields already exist.
- Add layout-mode and section-order data derived from
ReportProfileRegistry.
Phase 3 - Rendered Report Layout Productization
- Update
ReviewPackRenderedReportControllerto provide stable theme/layout/KPI data. - Update or split
rendered-report.blade.phpinto partials only where reviewability improves. - Render management-ready first screen: cover, state hero, KPI strip, executive summary, key risks/decisions, evidence basis, accepted risks, next action, disclosure.
- Ensure appendix is secondary for
customer_executiveand more prominent forauditor_appendix. - Keep toolbar outside report canvas and hidden in print.
Phase 4 - Localization and Report Copy
- Add EN/DE keys for new dominant report copy only.
- Avoid raw localization keys in output.
- Keep action labels and source metadata consistent with existing Review Pack/report vocabulary.
Phase 5 - UI Coverage, Browser Smoke, and Close-Out
- Run focused validation commands.
- Save screenshots under the Spec 366 artifact directory.
- Update UI audit coverage or record no-update rationale.
- Record no migrations/packages/env/queues/scheduler/storage/asset changes.
Rollout and Deployment Considerations
- Staging: Validate rendered report profile variants, print behavior, and review-pack download unchanged.
- Production: No schema change expected. Deploy as ordinary app/view/test change.
- Migrations: none planned.
- Environment variables: none planned.
- Queues / scheduler: none planned.
- Storage: no new storage path except test/browser screenshot artifacts in the repo during implementation.
- Filament assets: no new registered Filament assets expected. If implementation registers assets unexpectedly, deployment must include
cd apps/platform && php artisan filament:assets; otherwise existing deployment asset handling is unchanged. - Reverse proxy / SSL: no impact.
- Rollback/forward: revert code/view/localization changes; no data migration rollback.
Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| Bounded derived report theme/layout resolver or equivalent view-model | Current-release report productization needs deterministic co-branding, layout, KPI, and profile ordering proof | Scattered controller/view variables would be harder to test and could let profile/disclosure/branding drift |
Proportionality Review
- Current operator problem: MSPs need a professional, customer-safe, print-ready report artifact over existing Review Pack truth.
- Existing structure is insufficient because: It proves a report can render, but not yet that the report has a stable management layout/theme contract across profiles and print states.
- Narrowest correct implementation: Local derived theme/layout contract inside the Review Pack report family, rendered by the existing route/view.
- Ownership cost created: One small Unit test family, one Feature test file, one Browser smoke, localization keys, and optional partial files.
- Alternative intentionally rejected: persisted themes, logo upload, a generic report engine, native PDF, scheduled delivery, AI, or compliance report framework.
- Release truth: Current-release report productization.
Filament v5 / Livewire v4 Output Contract
- Livewire v4.0+ compliance: The application uses Livewire 4.1.4; this spec does not introduce Livewire v3 APIs.
- Provider registration location: No panel provider change planned. Laravel 12 Filament providers remain registered in
apps/platform/bootstrap/providers.php. - Global search: No globally searchable resource is changed or enabled. If implementation unexpectedly touches
ReviewPackResourceorEnvironmentReviewResourceglobal search, it must verify safe View/Edit pages or keep global search disabled. - Destructive/high-impact actions: None introduced. Existing Review Pack download/render/print actions remain read-only. Any unexpected mutating action must stop implementation and update spec/plan first.
- Asset strategy: No new registered Filament assets planned; no new
filament:assetsdeployment requirement unless implementation proves otherwise. - Testing plan: Pest Unit/Feature/Browser tests as listed above, plus Spec356/Spec357/ReviewPack/EnvironmentReview regressions.
Stop Conditions
Stop and update spec/plan before code implementation continues if:
- Spec 357 profile/disclosure policy is not present or not stable.
- A native PDF package, new dependency, persisted theme table, upload UI, or theme editor appears necessary.
- Report metrics require new data collection or a new source of truth.
- A customer portal, public link, scheduled delivery, approval workflow, or AI narrative becomes necessary.
- Branding cannot be implemented from existing workspace/managed-environment truth without new persisted fields.
- Any write/mutation action is proposed inside the report surface.