# Research — Tenant Dashboard Productization v1 **Date**: 2026-05-02 **Spec**: [spec.md](spec.md) This document resolves the planning decisions for the smallest safe productization follow-up on the tenant dashboard. ## Decision 1 — Keep the existing tenant dashboard route as the canonical tenant landing surface **Decision**: Productize the existing [../../apps/platform/app/Filament/Pages/TenantDashboard.php](../../apps/platform/app/Filament/Pages/TenantDashboard.php) page at `/admin/t/{tenant}` instead of creating a second tenant landing page, new panel, or portal shell. **Rationale**: - The repo already routes tenant selection, onboarding completion, support diagnostics bundles, and portfolio arrival continuity back to this page. - The product gap is the current composition and decision hierarchy, not missing routing or missing tenant context. - Reusing the existing page preserves current workspace and tenant isolation behavior and keeps the slice bounded. **Alternatives considered**: - Add a second tenant-home page. - Rejected: duplicates the existing tenant route and widens shell-level information architecture scope. - Convert the page into a new Resource. - Rejected: the dashboard is still a derived landing surface, not a new persisted model family. ## Decision 2 — Collapse the current widget stack behind one bounded dashboard summary composition **Decision**: Replace the current seven-widget first-screen stack with one bounded dashboard summary and composite overview surface while keeping current widgets as truth seams or migration sources. **Rationale**: - The current stack splits posture, recovery, baseline compare, findings, and operations into separate blocks that operators must manually reconcile. - A single dashboard-local summary layer is the narrowest way to apply the new caps on KPI count, header actions, and recommended actions while keeping fallback behavior coherent. - The constitution allows a narrow abstraction here because the existing local shape is insufficient for the required operator workflow. **Alternatives considered**: - Keep the widget stack and only adjust copy or spacing. - Rejected: leaves priority fragmented and does not satisfy the decision-first first-screen contract. - Introduce a generic dashboard framework. - Rejected: imports unnecessary structure beyond current release truth. ## Decision 3 — Preserve arrival-context continuity as a thin contextual strip, not as a first-screen dominant block **Decision**: Keep [../../apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php](../../apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php) as a conditional contextual strip when arrival metadata exists, but do not let it displace the new decision-first hierarchy. **Rationale**: - Arrival continuity is already a real workflow seam for portfolio triage and should not be discarded. - It is contextual support information, not the primary tenant posture surface. - Keeping it conditional preserves continuity without repeating the tenant's main problem summary. **Alternatives considered**: - Remove the arrival surface entirely. - Rejected: breaks an existing workflow continuity seam. - Leave the current arrival block as a top-of-page dominant widget. - Rejected: it competes with the new posture and next-action summary. ## Decision 4 — Use the existing Governance Inbox as the primary canonical governance queue when the operator can open it **Decision**: Treat [../../apps/platform/app/Filament/Pages/Governance/GovernanceInbox.php](../../apps/platform/app/Filament/Pages/Governance/GovernanceInbox.php) as a repo-real primary follow-up destination because it already supports workspace membership checks, tenant prefiltering, family filters, and calm empty-state behavior. **Rationale**: - The page already accepts `tenant_id` query input, resolves a selected tenant from current authorized tenants, and keeps workspace-safe visibility rules. - This allows the dashboard to use `Open governance inbox` or a narrower `Review findings` style CTA without inventing a new governance queue. - The inbox already behaves as a decision-oriented canonical surface rather than a raw storage list. **Alternatives considered**: - Always link directly to findings. - Rejected: loses the chance to route operators into the existing canonical governance queue when it is the better working surface. - Invent a dashboard-only governance queue. - Rejected: fake route and clear scope expansion. ## Decision 5 — Keep risk and exception follow-up on the existing FindingException resource **Decision**: Use [../../apps/platform/app/Filament/Resources/FindingExceptionResource.php](../../apps/platform/app/Filament/Resources/FindingExceptionResource.php) and its current list or view pages as the repo-real risk-exception surface for dashboard follow-up. **Rationale**: - The resource already exposes tenant-scoped stats, status badges, and view routes for exception records. - The repo already treats exceptions and accepted-risk governance as tenant-owned truth. - The dashboard needs summary and drill-through, not a new accepted-risk page. **Alternatives considered**: - Introduce a new `Accepted Risks` dashboard route. - Rejected: unnecessary duplication of exception truth. - Keep risk information as non-actionable summary only. - Rejected: the spec requires next actions and real follow-up paths. ## Decision 6 — Treat required permissions as the provider-health follow-up seam **Decision**: Use [../../apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php](../../apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php) and [../../apps/platform/app/Support/Links/RequiredPermissionsLinks.php](../../apps/platform/app/Support/Links/RequiredPermissionsLinks.php) as the repo-real provider blockage and follow-up seam. **Rationale**: - Repo discovery did not surface a dedicated tenant provider-health page equivalent to the mockup card. - Required-permissions truth already gives overall status, missing counts, feature impacts, freshness, and deep-link generation. - This is the narrowest current-release implementation that keeps provider detail on provider-owned surfaces. **Alternatives considered**: - Add a new tenant provider-health page. - Rejected: scope expansion and unnecessary new surface. - Use vague provider health text without an actual destination. - Rejected: breaks the repo-real follow-up requirement. ## Decision 7 — Reuse existing review, evidence, and review-pack routes for customer-safe output readiness **Decision**: Reuse the current customer-review and artifact surfaces instead of inventing a customer-view route. **Rationale**: - [../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php](../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php) already supports tenant-prefiltered customer-safe review consumption. - [../../apps/platform/app/Filament/Resources/TenantReviewResource.php](../../apps/platform/app/Filament/Resources/TenantReviewResource.php), [../../apps/platform/app/Filament/Resources/ReviewPackResource.php](../../apps/platform/app/Filament/Resources/ReviewPackResource.php), and [../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php](../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php) already own detailed truth and capability checks. - [../../apps/platform/app/Filament/Widgets/Tenant/TenantReviewPackCard.php](../../apps/platform/app/Filament/Widgets/Tenant/TenantReviewPackCard.php) already exposes latest-pack and generation-decision seams if a retained action needs them. **Alternatives considered**: - Add a new `Open customer view` route. - Rejected: fake maturity and explicit spec violation. - Keep output readiness as static copy only. - Rejected: loses the real downstream handoff surfaces that already exist. ## Decision 8 — Reuse canonical operations continuity for recent runs and follow-up **Decision**: Keep [../../apps/platform/app/Filament/Pages/Monitoring/Operations.php](../../apps/platform/app/Filament/Pages/Monitoring/Operations.php) and [../../apps/platform/app/Support/OperationRunLinks.php](../../apps/platform/app/Support/OperationRunLinks.php) as the only canonical operations follow-up path. **Rationale**: - The canonical operations page already applies dashboard prefilter state and preserves tenant continuity. - `OperationRunLinks` already centralizes labels and URLs. - The dashboard needs calmer recent-run summary, not a second operations viewer. **Alternatives considered**: - Keep a full operations table as the first-screen primary surface. - Rejected: breaks the decision-first contract. - Add a dashboard-local operations detail layer. - Rejected: duplicates the canonical monitoring surface. ## Decision 9 — Demote support request and diagnostics utilities out of the primary header plane **Decision**: Do not keep support request and diagnostics as the default dominant header actions when the dashboard is productized. If retained, they move to a clearly secondary utility position. **Rationale**: - The spec caps visible header actions at two and requires the header to stay decision-first. - The current page header is utility-heavy rather than governance-first. - Support request and diagnostics remain real features, but they are not the primary tenant-governance action on first load. **Alternatives considered**: - Leave support utilities in the main header and squeeze governance actions elsewhere. - Rejected: preserves the current action hierarchy problem. - Remove support utilities entirely. - Rejected: unnecessary functionality loss. ## Decision 10 — Use existing dashboard truth and customer-health phrasing patterns instead of inventing a new dashboard score vocabulary **Decision**: Reuse existing badge semantics and calm reason/impact phrasing patterns from current dashboard and customer-health surfaces rather than introducing a new dashboard-specific scoring language. **Rationale**: - Existing badge semantics are already centralized. - [../../apps/platform/app/Filament/System/Pages/Directory/Concerns/BuildsCustomerHealthDecisionData.php](../../apps/platform/app/Filament/System/Pages/Directory/Concerns/BuildsCustomerHealthDecisionData.php) already demonstrates reason/impact/recommended-action phrasing that is calm and enterprise-safe. - The spec forbids creating a new local status taxonomy. **Alternatives considered**: - Add a new composite dashboard score or taxonomy. - Rejected: violates proportionality and risks duplicate truth. - Leave current widget-local wording unchanged. - Rejected: misses the productization goal. ## Decision 11 — Keep browser proof bounded to one new tenant-dashboard smoke **Decision**: Expand existing dashboard feature tests and add exactly one browser smoke covering the productized tenant landing flow. **Rationale**: - The repo already contains dashboard DB-only, truth-alignment, scope, arrival-context, and RBAC tests that are the right base to expand. - The main user-visible risk is first-screen information hierarchy and action density, which merits one real-browser pass. - A broader browser family would increase test-governance cost without materially better proof. **Alternatives considered**: - Add multiple browser tests for every card and every follow-up route. - Rejected: too broad for a bounded productization slice. - Rely on feature tests only. - Rejected: does not prove the primary first-screen operator flow under real rendering.