TenantAtlas/specs/277-stored-reports-surface/tasks.md
ahmido c44f683aa6 277-stored-reports-surface → platform-dev (#333)
Auto-created PR: committing all local changes and pushing branch `277-stored-reports-surface` to remote.

Please review and adjust the title/description as needed.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #333
2026-05-06 00:04:53 +00:00

14 KiB

description
Task list for Stored Reports Surface v1

Tasks: Stored Reports Surface v1

Input: Design documents from specs/277-stored-reports-surface/
Prerequisites: specs/277-stored-reports-surface/spec.md, specs/277-stored-reports-surface/plan.md, specs/277-stored-reports-surface/checklists/requirements.md, specs/277-stored-reports-surface/research.md, specs/277-stored-reports-surface/data-model.md, specs/277-stored-reports-surface/quickstart.md, specs/277-stored-reports-surface/contracts/tenant-stored-reports-surface.logical.openapi.yaml

Tests: REQUIRED (Pest). Keep proof bounded to focused Feature coverage in apps/platform/tests/Feature/StoredReports/, a narrow update to apps/platform/tests/Feature/EntraAdminRoles/AdminRolesSummaryWidgetTest.php, and the required UI smoke coverage in apps/platform/tests/Browser/Spec277StoredReportsSurfaceSmokeTest.php. Operations: No new OperationRun family. Existing scan and generation actions remain on their current surfaces. RBAC: Wrong-tenant or non-member access remains 404; in-scope actors missing the relevant report-family capability remain 403; collection visibility requires at least one supported report-family capability. Shared Pattern Reuse: Reuse StoredReport, ArtifactTruthPresenter, centralized badge semantics, and the current admin-roles widget launch seam. Do not create a report registry, analytics console, or second lifecycle system. Filament / Panel Guardrails: Filament remains v5 on Livewire v4. Provider registration remains unchanged in apps/platform/bootstrap/providers.php. The new stored-report resource is not globally searchable and adds no new asset strategy. Organization: Tasks are grouped by user story so browse, detail, and canonical drilldown behavior stay independently implementable and testable. This package productizes existing stored-report truth and stops before generic reporting scope. Review Outcome: acceptable-special-case Workflow Outcome: keep Test-governance Outcome: keep

Test Governance Checklist

  • Lane assignment stays fast-feedback and confidence and remains the narrowest sufficient proof.
  • New or changed tests stay in apps/platform/tests/Feature/StoredReports/, apps/platform/tests/Feature/EntraAdminRoles/, and the required narrow browser smoke file only.
  • Shared helpers stay cheap by default; stored-report setup should reuse the current factory and tenant fixtures.
  • Planned validation commands cover register behavior, entitlement behavior, detail presentation, widget drilldown, and the required narrow browser smoke without widening into heavy-governance lanes.
  • The declared surface test profile remains standard-native-filament and shared-detail-family only.
  • Any drift toward a report engine, cross-tenant hub, or generic registry resolves as reject-or-split, not hidden scope.

Phase 1: Setup (Shared Context)

Purpose: Confirm the current stored-report, artifact-truth, and launch seams before runtime changes begin.

  • T001 Review specs/277-stored-reports-surface/spec.md, specs/277-stored-reports-surface/plan.md, specs/277-stored-reports-surface/checklists/requirements.md, specs/277-stored-reports-surface/research.md, specs/277-stored-reports-surface/data-model.md, and specs/277-stored-reports-surface/quickstart.md together so the slice stays on existing stored-report truth.
  • T002 [P] Confirm the current stored-report truth and lifecycle anchors in apps/platform/app/Models/StoredReport.php, apps/platform/database/factories/StoredReportFactory.php, and apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php.
  • T003 [P] Confirm the current repo-real launch seam in apps/platform/app/Filament/Widgets/Tenant/AdminRolesSummaryWidget.php and apps/platform/resources/views/filament/widgets/tenant/admin-roles-summary.blade.php.
  • T004 [P] Confirm the current tenant-panel read-only resource patterns in apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php, apps/platform/app/Filament/Resources/ReviewPackResource.php, and their related feature tests.

Phase 2: Foundational (Blocking Prerequisites)

Purpose: Lock authorization, test coverage, and setup before the new surface is built.

Critical: No user-story work should begin until this phase is complete.

  • T005 [P] Add failing feature coverage in apps/platform/tests/Feature/StoredReports/StoredReportEntitlementEnforcementTest.php for collection visibility, direct-detail access, family-filtered rows, and 404 versus 403 semantics.
  • T006 [P] Add failing feature coverage in apps/platform/tests/Feature/StoredReports/StoredReportResourceTest.php for tenant-scoped list behavior, current versus historical visibility, search, filter options, and honest empty-state behavior.
  • T007 [P] Add failing feature coverage in apps/platform/tests/Feature/StoredReports/StoredReportDetailPresentationTest.php for allowed current permission-posture detail, allowed historical Entra admin-roles detail, collapsed raw payload disclosure, and integrity-anchor rendering when present.
  • T008 [P] Prepare the minimal widget test fixtures or helpers in apps/platform/tests/Feature/EntraAdminRoles/AdminRolesSummaryWidgetTest.php for a report-present state and a capability-blocked state so US3 can add one bounded assertion set.
  • T009 Add Capabilities::PERMISSION_POSTURE_VIEW in apps/platform/app/Support/Auth/Capabilities.php and map it in apps/platform/app/Services/Auth/RoleCapabilityMap.php with bounded read-only role coverage.
  • T010 Keep stored-report test setup cheap by extending apps/platform/database/factories/StoredReportFactory.php only as needed for current and historical supported-family fixtures.

Checkpoint: Authorization and proving seams are ready for the stored-report resource implementation.


Phase 3: User Story 1 - Browse current stored reports for one tenant (Priority: P1)

Goal: Entitled actors can browse current and historical stored reports for the active tenant in one first-class register.

Independent Test: Open /admin/t/{tenant}/stored-reports, confirm current and historical behavior, and verify family-aware visibility and filters.

Tests for User Story 1

  • T011 [P] [US1] Extend apps/platform/tests/Feature/StoredReports/StoredReportResourceTest.php to cover clickable-row inspection, history toggle behavior, and family-aware filter visibility on the tenant panel.

Implementation for User Story 1

  • T012 [US1] Create apps/platform/app/Filament/Resources/StoredReportResource.php with tenant ownership, isGloballySearchable = false, family-aware canViewAny() behavior, and a read-only action-surface declaration.
  • T013 [US1] Create apps/platform/app/Filament/Resources/StoredReportResource/Pages/ListStoredReports.php with a tenant-scoped query, report-family filters, history visibility, search, clickable rows, and no row or bulk mutation actions.
  • T014 [US1] Add bounded family-summary extraction on the stored-report resource or list page using current payload shapes and existing artifact-truth badges rather than a shared registry.
  • T015 [US1] Wire the list empty state to an honest next step such as the tenant overview, without implying the stored-report surface can generate reports itself.

Checkpoint: The tenant panel has one calm stored-report register that stays tenant-scoped, read-only, and family-aware.


Phase 4: User Story 2 - Inspect a retained report without false calmness (Priority: P1)

Goal: Entitled actors can inspect one stored report and immediately understand what it says, whether it is current or historical, and when it was measured.

Independent Test: Open one current permission-posture report and one historical Entra admin-roles report and verify lifecycle truth, measured time, bounded summary, and progressive disclosure.

Tests for User Story 2

  • T016 [P] [US2] Extend apps/platform/tests/Feature/StoredReports/StoredReportDetailPresentationTest.php to cover the one-primary-action rule, current-report jump on historical rows, and the absence of speculative unsupported-family rendering in v1.

Implementation for User Story 2

  • T017 [US2] Create apps/platform/app/Filament/Resources/StoredReportResource/Pages/ViewStoredReport.php as a read-only view page using infolist sections for artifact truth, family summary, lineage, and collapsed raw payload.
  • T018 [US2] Reuse ArtifactTruthPresenter::forStoredReport() in the detail surface and keep any “current report” lookup local to StoredReportResource and ViewStoredReport instead of broadening the artifact envelope.
  • T019 [US2] Keep the detail page to one dominant next action, Open current report, only when the viewed row is historical, and keep all mutation actions out of scope.

Checkpoint: Stored-report detail behaves like a true inspection surface rather than a pseudo-editor or diagnostics dump.


Phase 5: User Story 3 - Follow stored-report truth from the tenant admin-roles widget (Priority: P2)

Goal: The current admin-roles widget launch seam points to the canonical stored-report detail route instead of leaving operators in a fragmented local view.

Independent Test: Launch the current Entra admin-roles report from AdminRolesSummaryWidget and confirm the canonical tenant stored-report detail route opens.

Tests for User Story 3

  • T020 [P] [US3] Extend apps/platform/tests/Feature/EntraAdminRoles/AdminRolesSummaryWidgetTest.php to prove canonical stored-report drilldown and capability-gated absence without widening the proving suite.

Implementation for User Story 3

  • T021 [US3] Update apps/platform/app/Filament/Widgets/Tenant/AdminRolesSummaryWidget.php and apps/platform/resources/views/filament/widgets/tenant/admin-roles-summary.blade.php so viewReportUrl resolves to the canonical tenant stored-report detail route when the actor can view Entra admin roles.
  • T022 [US3] Keep convergence bounded to AdminRolesSummaryWidget; do not add new stored-report links to EvidenceSnapshotResource, ReviewPackResource, or TenantReviewResource in v1.
  • T023 [US3] Ensure generated detail URLs preserve tenant-panel routing semantics and that direct detail access keeps family-aware authorization behavior.

Checkpoint: The admin-roles widget definitely launches the canonical detail route, and any additional convergence remains bounded to repo-real affordances.


Phase 6: Polish & Cross-Cutting Validation

Purpose: Validate the bounded slice and stop before reporting-platform scope creeps in.

  • T024 [P] Run export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/StoredReports/StoredReportResourceTest.php tests/Feature/StoredReports/StoredReportEntitlementEnforcementTest.php.
  • T025 [P] Run export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/StoredReports/StoredReportDetailPresentationTest.php tests/Feature/EntraAdminRoles/AdminRolesSummaryWidgetTest.php.
  • T026 [P] Run cd apps/platform && ./vendor/bin/sail pint on the touched application and test files; ./vendor/bin/sail pint --dirty reported no tracked dirty files because several feature files were new.
  • T027 [P] Review touched code to confirm Filament stays on Livewire v4, provider registration remains unchanged in apps/platform/bootstrap/providers.php, the new resource stays out of global search, no new asset strategy appears, and no report engine or analytics scope slipped in.
  • T028 [P] Record the final guardrail and test-governance outcome in the active feature close-out without widening into cross-tenant browse, raw export, or generic report-framework work.

Dependencies & Execution Order

Phase Dependencies

  • Phase 1 (Setup): no dependencies; start immediately.
  • Phase 2 (Foundational): depends on Phase 1 and blocks all user stories.
  • Phase 3 (US1): depends on Phase 2 and establishes the primary browse surface.
  • Phase 4 (US2): depends on Phase 2 and should ship with US1 so the register opens into a finished detail surface.
  • Phase 5 (US3): depends on Phase 2 and should follow once the canonical detail route exists.
  • Phase 6 (Polish): depends on all desired user stories being complete.

User Story Dependencies

  • US1 (P1): independently testable after Phase 2 and delivers the primary operator value.
  • US2 (P1): independently testable after Phase 2 and should ship with US1 so the browse surface is meaningful.
  • US3 (P2): independently testable after Phase 2 and can follow once the canonical detail route is in place.

Within Each User Story

  • Write the listed Pest coverage first and make it fail for the intended gap.
  • Keep implementation inside the resource, widget, capability, and existing report-truth seams named above.
  • Re-run the narrowest relevant validation command after each story checkpoint before moving on.

Implementation Strategy

Suggested MVP Scope

  • MVP = US1 + US2 together. The feature only closes the operator gap when the register and detail surface both exist.

Incremental Delivery

  1. Complete Phase 1 and Phase 2.
  2. Deliver US1 so operators can browse current and historical stored reports.
  3. Deliver US2 so the browse surface opens into a trustworthy detail surface.
  4. Deliver US3 by wiring the canonical detail route into the current admin-roles widget seam.
  5. Finish with the focused validation and guardrail review in Phase 6.

Team Strategy

  1. Settle capability and test shape first.
  2. Parallelize failing test authoring within the stored-report feature family before runtime edits.
  3. Serialize merges around StoredReportResource, ViewStoredReport, and AdminRolesSummaryWidget so route and vocabulary drift does not spread.

Deferred Follow-Ups / Non-Goals

  • report generation, scheduling, or rerun actions from the stored-report surface
  • raw payload download or export
  • cross-tenant or workspace-wide stored-report browsing
  • customer-facing stored-report consumption
  • generic report registry, renderer framework, or analytics console