--- 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