171 lines
11 KiB
Markdown
171 lines
11 KiB
Markdown
# 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. |