mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage-server
synced 2026-05-18 20:08:19 +00:00
Phase A+B of the alerts overhaul: - New PerformanceFactsProvider exposes agent.idleMinutes (from AgentSession), agent.busyMinutes, agent.totalCallsToday, agent.bookedCallsToday, agent.conversionPercent - Implement EscalateActionHandler (was a stub): persists a PerformanceAlert row, dedupes per agent+type+IST date so a 5-min cron can't spam, updates value if it changes - New PerformanceConsumer: setInterval every 5 min, reads on_schedule rules referencing agent.* facts, evaluates per agent, dispatches escalate actions - Two starter rules in hospital-starter.json: excessive-idle (>60min) and low-conversion (<15% with >10 calls today). NPS deferred — no source signal exists yet - New PerformanceAlertsController: GET /api/supervisor/performance-alerts (active list), POST /:id/dismiss, POST /dismiss-all - Rules engine now injects EscalateActionHandler via DI so the action has access to PlatformGraphqlService for persistence Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
135 lines
6.2 KiB
JSON
135 lines
6.2 KiB
JSON
{
|
|
"priorityConfig": {
|
|
"taskWeights": {
|
|
"missed_call": { "weight": 9, "slaMinutes": 720, "enabled": true },
|
|
"follow_up": { "weight": 8, "slaMinutes": 1440, "enabled": true },
|
|
"campaign_lead": { "weight": 7, "slaMinutes": 2880, "enabled": true },
|
|
"attempt_2": { "weight": 6, "slaMinutes": 1440, "enabled": true },
|
|
"attempt_3": { "weight": 4, "slaMinutes": 2880, "enabled": true }
|
|
},
|
|
"campaignWeights": {},
|
|
"sourceWeights": {
|
|
"WHATSAPP": 9, "PHONE": 8, "FACEBOOK_AD": 7, "GOOGLE_AD": 7,
|
|
"INSTAGRAM": 5, "WEBSITE": 7, "REFERRAL": 6, "WALK_IN": 5, "OTHER": 5
|
|
}
|
|
},
|
|
"rules": [
|
|
{
|
|
"ruleType": "priority",
|
|
"name": "Missed calls — high urgency",
|
|
"description": "Missed calls get highest priority with SLA-based urgency",
|
|
"enabled": true,
|
|
"priority": 1,
|
|
"trigger": { "type": "on_request", "request": "worklist" },
|
|
"conditions": { "all": [{ "fact": "call.taskType", "operator": "equal", "value": "missed_call" }] },
|
|
"action": { "type": "score", "params": { "weight": 9, "slaMultiplier": true } }
|
|
},
|
|
{
|
|
"ruleType": "priority",
|
|
"name": "Scheduled follow-ups",
|
|
"description": "Committed callbacks from prior calls",
|
|
"enabled": true,
|
|
"priority": 2,
|
|
"trigger": { "type": "on_request", "request": "worklist" },
|
|
"conditions": { "all": [{ "fact": "call.taskType", "operator": "equal", "value": "follow_up" }] },
|
|
"action": { "type": "score", "params": { "weight": 8, "slaMultiplier": true } }
|
|
},
|
|
{
|
|
"ruleType": "priority",
|
|
"name": "Campaign leads — weighted",
|
|
"description": "Outbound campaign calls, weighted by campaign importance",
|
|
"enabled": true,
|
|
"priority": 3,
|
|
"trigger": { "type": "on_request", "request": "worklist" },
|
|
"conditions": { "all": [{ "fact": "call.taskType", "operator": "equal", "value": "campaign_lead" }] },
|
|
"action": { "type": "score", "params": { "weight": 7, "slaMultiplier": true, "campaignMultiplier": true } }
|
|
},
|
|
{
|
|
"ruleType": "priority",
|
|
"name": "2nd attempt — medium urgency",
|
|
"description": "First call went unanswered, try again",
|
|
"enabled": true,
|
|
"priority": 4,
|
|
"trigger": { "type": "on_request", "request": "worklist" },
|
|
"conditions": { "all": [{ "fact": "call.taskType", "operator": "equal", "value": "attempt_2" }] },
|
|
"action": { "type": "score", "params": { "weight": 6, "slaMultiplier": true } }
|
|
},
|
|
{
|
|
"ruleType": "priority",
|
|
"name": "3rd attempt — lower urgency",
|
|
"description": "Two prior unanswered attempts",
|
|
"enabled": true,
|
|
"priority": 5,
|
|
"trigger": { "type": "on_request", "request": "worklist" },
|
|
"conditions": { "all": [{ "fact": "call.taskType", "operator": "equal", "value": "attempt_3" }] },
|
|
"action": { "type": "score", "params": { "weight": 4, "slaMultiplier": true } }
|
|
},
|
|
{
|
|
"ruleType": "priority",
|
|
"name": "Spam leads — deprioritize",
|
|
"description": "High spam score leads get pushed down",
|
|
"enabled": true,
|
|
"priority": 10,
|
|
"trigger": { "type": "on_request", "request": "worklist" },
|
|
"conditions": { "all": [{ "fact": "lead.spamScore", "operator": "greaterThan", "value": 60 }] },
|
|
"action": { "type": "score", "params": { "weight": -3 } }
|
|
},
|
|
{
|
|
"ruleType": "automation",
|
|
"name": "SLA breach — escalate to supervisor",
|
|
"description": "Alert supervisor when callback SLA is breached",
|
|
"enabled": true,
|
|
"priority": 1,
|
|
"status": "draft",
|
|
"trigger": { "type": "on_schedule", "interval": "5m" },
|
|
"conditions": { "all": [{ "fact": "call.slaBreached", "operator": "equal", "value": true }, { "fact": "call.callbackStatus", "operator": "equal", "value": "PENDING_CALLBACK" }] },
|
|
"action": { "type": "escalate", "params": { "channel": "notification", "recipients": "supervisor", "message": "SLA breached — no callback attempted", "severity": "critical" } }
|
|
},
|
|
{
|
|
"ruleType": "automation",
|
|
"name": "Excessive idle time",
|
|
"description": "Agent has been idle for more than the configured threshold today",
|
|
"enabled": true,
|
|
"priority": 2,
|
|
"trigger": { "type": "on_schedule", "interval": "5m" },
|
|
"conditions": { "all": [{ "fact": "agent.idleMinutes", "operator": "greaterThan", "value": 60 }] },
|
|
"action": {
|
|
"type": "escalate",
|
|
"params": {
|
|
"channel": "notification",
|
|
"recipients": "supervisor",
|
|
"message": "Excessive Idle Time",
|
|
"severity": "warning",
|
|
"alertType": "EXCESSIVE_IDLE",
|
|
"valueFact": "agent.idleMinutes"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"ruleType": "automation",
|
|
"name": "Low conversion rate",
|
|
"description": "Agent's conversion (booked/total) is below the workspace floor",
|
|
"enabled": true,
|
|
"priority": 3,
|
|
"trigger": { "type": "on_schedule", "interval": "5m" },
|
|
"conditions": {
|
|
"all": [
|
|
{ "fact": "agent.conversionPercent", "operator": "lessThan", "value": 15 },
|
|
{ "fact": "agent.totalCallsToday", "operator": "greaterThan", "value": 10 }
|
|
]
|
|
},
|
|
"action": {
|
|
"type": "escalate",
|
|
"params": {
|
|
"channel": "notification",
|
|
"recipients": "supervisor",
|
|
"message": "Low Conversion",
|
|
"severity": "warning",
|
|
"alertType": "LOW_CONVERSION",
|
|
"valueFact": "agent.conversionPercent"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|