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:
| Signal | Description |
|---|---|
| Engagement Events | Frequency and recency of product activity |
| Payment History | On-time payments, failed charges, subscription continuity |
| NPS Responses | Customer-submitted Net Promoter Score surveys |
| Support Tickets | Volume, 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:
listHealthScoresgetHealthSummarygetNpsSummarylistEngagementEventslistOutreachLog
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):
| Table | Purpose |
|---|---|
customerHealthScores | Stores the latest computed composite score per customer |
customerNpsResponses | Records individual NPS survey submissions |
customerEngagementEvents | Tracks product usage and activity events |
proactiveOutreachLog | Logs 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.