All Docs
FeaturesSaaS FactoryUpdated February 19, 2026

Customer Health Scoring

Customer Health Scoring

The Customer Health Scoring system automatically evaluates the health of every customer account by aggregating signals from across the platform — engagement, payments, NPS, and support — into a single composite score. Scores are stored, queryable, and visualised in the CRM Health Dashboard.

How Scores Are Computed

The scoring engine (scoreAndPersistHealth() in src/lib/crm-engine.ts) combines four weighted signal categories:

SignalDescription
Engagement EventsFrequency and recency of product activity
Payment HistoryOn-time payments, failed charges, subscription continuity
NPS ResponsesCustomer-submitted Net Promoter Score surveys
Support TicketsVolume, severity, and resolution rate of open issues

The resulting composite score determines a customer's health tier:

  • Healthy — strong across most signals
  • ⚠️ At-Risk — degraded signals in one or more categories
  • 🔴 Churned / Critical — significant negative signals present

Scores are persisted to the customerHealthScores table and can be recalculated at any time via the refreshHealthScore API.


CRM Health Dashboard

The CrmHealthDashboard component (src/components/crm/crm-health-dashboard.tsx) provides a real-time view of customer health across the entire account base.

Dashboard Panels

  • Tier Breakdown — distribution of customers across health tiers
  • Component Scores — per-signal score breakdown for each customer
  • Signal Detail Dialog — drill-down view for inspecting individual score factors
  • Outreach Log — history of proactive engagement actions triggered by health changes

The dashboard reads from five tRPC queries simultaneously:

  1. listHealthScores
  2. getHealthSummary
  3. getNpsSummary
  4. listEngagementEvents
  5. listOutreachLog

API Reference

All endpoints are exposed via tRPC from src/lib/routers/crm.ts.

Health Scores

listHealthScores

Returns a paginated list of health scores for all customers.

getHealthScore

Returns the health score and component breakdown for a single customer.

refreshHealthScore

Triggers an on-demand recalculation and persistence of a customer's health score.

getHealthSummary

Returns aggregate health statistics across the entire customer base, including tier distribution and average component scores.

NPS

submitNpsResponse

Records a Net Promoter Score survey response for a customer.

// Example input
{
  customerId: "cust_abc123",
  score: 9,
  comment: "Great product, fast support."
}

listNpsResponses

Returns historical NPS responses, optionally filtered by customer or date range.

getNpsSummary

Returns aggregated NPS analytics including average score and promoter/detractor ratios.

Engagement

trackEngagement

Logs a customer engagement event (e.g. feature used, page visited, action performed).

// Example input
{
  customerId: "cust_abc123",
  eventType: "feature_used",
  metadata: { feature: "analytics_dashboard" }
}

listEngagementEvents

Returns the engagement event history for one or all customers.

Outreach

listOutreachLog

Returns the log of proactive outreach actions taken in response to health score changes.


Database Schema

Four tables are added under the CRM schema (src/db/crm-schema.ts):

TablePurpose
customerHealthScoresStores the latest computed composite score per customer
customerNpsResponsesRecords individual NPS survey submissions
customerEngagementEventsTracks product usage and activity events
proactiveOutreachLogLogs automated outreach actions triggered by health changes

Relationship to Proactive Outreach

The health scoring system feeds directly into the platform's proactive engagement loop. When a customer's score drops below a configured threshold or transitions between tiers, the system logs an outreach action in proactiveOutreachLog. This enables the AI-powered CRM to act on health changes automatically without human intervention.