TenantAtlas/specs/245-customer-health-score/tasks.md
ahmido 86505483bf
Some checks failed
Main Confidence / confidence (push) Failing after 52s
feat(customer-health): add decision card to tenant/workspace detail (spec 245) (#283)
Add Customer Health decision card to tenant & workspace detail pages (spec 245).

What I changed:
- Render a decision-first Customer Health card on tenant and workspace detail pages.
- Reuse `WorkspaceHealthSummaryQuery` and preserve `window` query param.
- Update attention widget link text to "Review health details" and include `?window=`.
- Add/adjust tests to cover new behavior and explainability.
- Run Pint formatting.

Compare URL: https://git.cloudarix.de/ahmido/TenantAtlas/compare/dev...245-customer-health-score

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #283
2026-04-27 08:30:01 +00:00

151 lines
13 KiB
Markdown

---
description: "Task list for Customer Health Score"
---
# Tasks: Customer Health Score
**Input**: Design documents from `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/245-customer-health-score/`
**Prerequisites**: `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/245-customer-health-score/plan.md` (required), `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/245-customer-health-score/spec.md` (required), `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/245-customer-health-score/checklists/requirements.md` (required)
**Tests (TEST-GOV-001)**: REQUIRED (Pest) for all runtime behavior changes in this slice. Keep proof in Unit + Feature lanes only.
**Operations**: This slice must not change `OperationRun` start, completion, notification, or link UX.
**RBAC**: Existing `/system` dashboard access remains authoritative. No tenant/admin-plane or customer-facing health viewer is introduced.
**Organization**: Tasks are grouped by user story so aggregate health counts, the attention-needed workspace list, and edge-case hardening remain independently deliverable. Core unknown-handling lives in the foundational query path.
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Prepare the bounded support namespace and narrow test surfaces for the first slice.
- [x] T001 Create the feature-local support namespace and test directories under `apps/platform/app/Support/CustomerHealth/`, `apps/platform/tests/Unit/Support/CustomerHealth/`, and `apps/platform/tests/Feature/System/CustomerHealth/`
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Add the single shared dimension catalog and derived summary query before any dashboard UI adoption.
**Checkpoint**: One bounded, derived-only customer-health path exists before the dashboard starts rendering it, including the base unknown-handling and review-pack-readiness rules.
- [x] T002 Create the fixed first-slice dimension catalog in `apps/platform/app/Support/CustomerHealth/CustomerHealthDimensionCatalog.php`, reusing existing `SystemHealth` level semantics and locking the first slice to onboarding readiness, provider connection health, operational stability, governance pressure, review-pack readiness, and engagement freshness
- [x] T003 Create the derived workspace summary query in `apps/platform/app/Support/CustomerHealth/WorkspaceHealthSummaryQuery.php` that reads existing onboarding, provider connection, telemetry, `OperationRun`, findings, and review-pack truth without introducing a persisted score model, and bakes in the base unknown-handling plus selected-window review-pack-readiness rules
- [x] T004 [P] Add unit coverage for dimension labels, level precedence, unknown handling, the selected-window review-pack-readiness rule table, and windowed versus point-in-time signal rules in `apps/platform/tests/Unit/Support/CustomerHealth/CustomerHealthDimensionCatalogTest.php` and `apps/platform/tests/Unit/Support/CustomerHealth/WorkspaceHealthSummaryQueryTest.php`
- [x] T005 Run the foundational unit suite with `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/CustomerHealth/CustomerHealthDimensionCatalogTest.php tests/Unit/Support/CustomerHealth/WorkspaceHealthSummaryQueryTest.php`
---
## Phase 3: User Story 1 - See Portfolio Health At A Glance (Priority: P1) 🎯 MVP
**Goal**: Show aggregate workspace-health counts on the existing `/system` dashboard.
**Independent Test**: Seed mixed workspace truth and verify the dashboard renders aggregate `ok`, `warn`, `critical`, and `unknown` counts with explicit unknown handling.
### Tests for User Story 1
- [x] T006 [P] [US1] Add dashboard feature coverage for aggregate health counts, unknown handling, selected-window behavior, and a visible time-basis cue in `apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthDashboardWidgetsTest.php`
### Implementation for User Story 1
- [x] T007 [US1] Create the summary stats widget in `apps/platform/app/Filament/System/Widgets/CustomerHealthKpis.php` using the shared `StatsOverviewWidget` pattern and `WorkspaceHealthSummaryQuery`, including visible copy that distinguishes selected-window dimensions from point-in-time dimensions
- [x] T008 [US1] Register the new summary widget on `apps/platform/app/Filament/System/Pages/Dashboard.php` without changing the existing system dashboard access gate or header actions
- [x] T009 [US1] Run the first-slice dashboard summary proof with `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/System/CustomerHealth/CustomerHealthDashboardWidgetsTest.php`
---
## Phase 4: User Story 2 - Review Attention-Needed Workspaces With Explainable Reasons (Priority: P1)
**Goal**: List the worst workspaces first with dominant health dimensions and one platform-safe next link.
**Independent Test**: Seed several unhealthy workspaces and verify the dashboard shows them in priority order with dominant reasons and platform-safe links only.
### Tests for User Story 2
- [x] T010 [P] [US2] Add feature coverage for deterministic workspace ordering, dominant-dimension rendering, operator-first default disclosure, absence of raw/support detail on the default dashboard surface, absence of duplicate visible decision summaries across the two widgets, and exactly one platform-safe next link per row with the tenant-detail fallback path in `apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthExplainabilityTest.php`
### Implementation for User Story 2
- [x] T011 [US2] Create the compact attention widget in `apps/platform/app/Filament/System/Widgets/CustomerHealthTopWorkspaces.php`
- [x] T012 [US2] Add the companion Blade view in `apps/platform/resources/views/filament/system/widgets/customer-health-top-workspaces.blade.php`, keeping the surface read-only and triage-first
- [x] T013 [US2] Use existing platform-plane link helpers inside `apps/platform/app/Filament/System/Widgets/CustomerHealthTopWorkspaces.php` so each row exposes exactly one next link on system directory or system operations surfaces, with fallback to system tenant detail when no more specific platform-plane route is appropriate
- [x] T014 [US2] Register the attention-needed widget on `apps/platform/app/Filament/System/Pages/Dashboard.php` without turning `/system` into a second workbench page
- [x] T015 [US2] Run the explainability and link proof with `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/System/CustomerHealth/CustomerHealthExplainabilityTest.php`
---
## Phase 5: User Story 3 - Keep Health Honest And Narrow (Priority: P2)
**Goal**: Harden archived-workspace and archived-tenant handling, authorization, and dominant-reason edge cases after the foundational unknown-handling rules are already in place.
**Independent Test**: Verify that archived workspaces stay out of active attention counts, archived tenants do not drive active workspace health, review-pack edge cases continue to follow the selected-window rule, and unauthorized users cannot read the widgets.
### Tests for User Story 3
- [x] T016 [P] [US3] Add feature coverage for `/system` authorization boundaries in `apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthAuthorizationTest.php`
- [x] T017 [P] [US3] Extend `apps/platform/tests/Unit/Support/CustomerHealth/WorkspaceHealthSummaryQueryTest.php` with archived-workspace, archived-tenant, dominant-reason ordering, and recent-review-pack-request edge cases that harden the existing foundational rules
### Implementation for User Story 3
- [x] T018 [US3] Harden `apps/platform/app/Support/CustomerHealth/WorkspaceHealthSummaryQuery.php` for archived-workspace and archived-tenant exclusions, dominant-reason ordering, and review-pack edge cases without moving the core unknown-handling rules out of the foundation
- [x] T019 [US3] Keep overall level rendering on existing `BadgeDomain::SystemHealth` semantics inside `apps/platform/app/Filament/System/Widgets/CustomerHealthKpis.php` and `apps/platform/app/Filament/System/Widgets/CustomerHealthTopWorkspaces.php` rather than introducing a new score language
- [x] T020 [US3] Run the narrow safety and authorization proof with `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/CustomerHealth/WorkspaceHealthSummaryQueryTest.php tests/Feature/System/CustomerHealth/CustomerHealthAuthorizationTest.php`
---
## Phase 6: Polish & Cross-Cutting Concerns
**Purpose**: Lock down vocabulary, formatting, and the minimal validation suite before implementation close-out.
- [x] T021 [P] Confirm that dashboard labels, dominant reason copy, health levels, the visible time-basis cue, and the no-duplicate-visible-summary rule stay aligned across `apps/platform/app/Support/CustomerHealth/CustomerHealthDimensionCatalog.php`, the dashboard widgets, and any linked platform-safe surfaces
- [x] T022 Run formatting on touched platform files with `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- [x] T023 Run the full narrow validation suite with `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/CustomerHealth tests/Feature/System/CustomerHealth/CustomerHealthDashboardWidgetsTest.php tests/Feature/System/CustomerHealth/CustomerHealthExplainabilityTest.php tests/Feature/System/CustomerHealth/CustomerHealthAuthorizationTest.php`
- [x] T024 Review `apps/platform/app/Filament/System/Widgets/CustomerHealthTopWorkspaces.php` and `apps/platform/resources/views/filament/system/widgets/customer-health-top-workspaces.blade.php` against `/Users/ahmeddarrazi/Documents/projects/wt-plattform/docs/product/standards/list-surface-review-checklist.md`, recording the accepted compact-widget exceptions before sign-off
Accepted compact-widget exceptions for sign-off: no persistence trio, no bulk actions, no row click, and no empty-state CTA because this is a read-only dashboard triage widget rather than a standalone Filament table surface.
---
## Phase 7: Detail Follow-Up Decision Context
**Purpose**: Keep the dashboard-to-detail drilldown explainable by repeating the health decision above existing residual diagnostics.
- [x] T025 [US2] Preserve the selected dashboard time window on system health-detail drilldown links in `apps/platform/app/Support/CustomerHealth/WorkspaceHealthSummaryQuery.php` so the linked residual detail pages can explain the same dominant drivers as the dashboard
- [x] T026 [US2] Rename the tenant/workspace drilldown affordance in `apps/platform/app/Support/CustomerHealth/WorkspaceHealthSummaryQuery.php` from an opening verb to the decision-first `Review health details` copy while keeping `Open runs` unchanged for operational follow-up
- [x] T027 [US2] Add a read-only customer-health decision card above existing diagnostics on `apps/platform/app/Filament/System/Pages/Directory/ViewTenant.php`, `apps/platform/app/Filament/System/Pages/Directory/ViewWorkspace.php`, and their directory Blade views by reusing `WorkspaceHealthSummaryQuery`
- [x] T028 [P] [US2] Add focused feature coverage for the new residual detail follow-up card in `apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthDetailDecisionTest.php`
- [x] T029 [US2] Run the focused drilldown validation proof with `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/CustomerHealth/WorkspaceHealthSummaryQueryTest.php tests/Feature/System/CustomerHealth/CustomerHealthExplainabilityTest.php tests/Feature/System/CustomerHealth/CustomerHealthDetailDecisionTest.php`
---
## Dependencies & Execution Order
### Recommended Execution Order
```text
Phase 1 (Setup)
Phase 2 (Dimension catalog + derived summary query)
↙ ↘
US1 (aggregate health counts) US2 (attention-needed workspace list)
US3 (honest unknown handling + authorization hardening)
```
### Parallel Opportunities
- The foundational unit tests can be authored in parallel once the fixed first-slice dimension inventory is agreed.
- The aggregate summary widget and attention-needed widget feature tests can be written in parallel after the derived summary shape is stable.
- Authorization coverage can proceed in parallel with final unknown-handling hardening because it exercises existing `/system` gates.
---
## Test Governance Checklist
- [x] Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
- [x] New or changed tests stay in the smallest honest family, and no heavy-governance or browser family is introduced accidentally.
- [x] Shared helpers and fixture setup remain cheap by default.
- [x] Planned validation commands cover the change without pulling in unrelated lane cost.
- [x] The adopted surfaces explicitly use `standard-native-filament` relief.
- [x] No material budget or baseline escalation is introduced.
**Test-governance outcome (TEST-GOV-001)**: keep