feat: suggestion rules engine + caller context evaluation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-17 11:09:47 +05:30
parent a576552f8a
commit 2d18110786
2 changed files with 194 additions and 8 deletions

View File

@@ -0,0 +1,152 @@
export type SuggestionType = 'upsell' | 'crosssell' | 'retention' | 'operational';
export type SuggestionPriority = 'high' | 'medium' | 'low';
export type SuggestionTrigger = {
type: SuggestionType;
title: string;
reason: string;
priority: SuggestionPriority;
};
type CallerFacts = {
isNew: boolean;
interestedService: string | null;
leadStatus: string | null;
contactAttempts: number;
appointments: Array<{ status: string; department: string; doctorName: string; scheduledAt: string }>;
calls: Array<{ direction: string; disposition: string | null; startedAt: string }>;
utmCampaign: string | null;
leadSource: string | null;
};
const DEPARTMENT_PACKAGES: Record<string, { package: string; description: string }> = {
CARDIOLOGY: { package: 'Cardiac Wellness Package', description: 'ECG, stress test, lipid panel' },
ORTHOPEDICS: { package: 'Joint Care Package', description: 'X-ray, physiotherapy assessment, bone density' },
GENERAL_MEDICINE: { package: 'Full Body Checkup', description: 'Complete health screening with blood work' },
NEUROLOGY: { package: 'Neuro Wellness Package', description: 'EEG, nerve conduction, cognitive assessment' },
GYNECOLOGY: { package: 'Women\'s Health Package', description: 'Pap smear, mammogram, hormone panel' },
};
const CROSS_SELL_MAP: Record<string, { department: string; reason: string }> = {
ORTHOPEDICS: { department: 'Physiotherapy', reason: 'complement orthopedic treatment' },
CARDIOLOGY: { department: 'Dietician', reason: 'dietary guidance for heart health' },
GENERAL_MEDICINE: { department: 'Ophthalmology', reason: 'routine eye screening' },
};
export const evaluateSuggestionRules = (facts: CallerFacts): SuggestionTrigger[] => {
const triggers: SuggestionTrigger[] = [];
// Rule 1: Package upsell by department
for (const appt of facts.appointments) {
const dept = (appt.department ?? '').toUpperCase().replace(/\s+/g, '_');
const pkg = DEPARTMENT_PACKAGES[dept];
if (pkg && appt.status === 'SCHEDULED') {
triggers.push({
type: 'upsell',
title: pkg.package,
reason: `Patient has ${appt.department} appointment with ${appt.doctorName}, offer ${pkg.description}`,
priority: 'high',
});
break;
}
}
// Rule 2: Reschedule missed/cancelled appointments
const needsReschedule = facts.appointments.find(a =>
a.status === 'CANCELLED' || a.status === 'RESCHEDULED' || a.status === 'NO_SHOW'
);
if (needsReschedule) {
triggers.push({
type: 'retention',
title: 'Reschedule appointment',
reason: `Last ${needsReschedule.department} appointment was ${needsReschedule.status.toLowerCase()}, offer to rebook with ${needsReschedule.doctorName}`,
priority: 'medium',
});
}
// Rule 3: Cross-sell related department
for (const appt of facts.appointments) {
const dept = (appt.department ?? '').toUpperCase().replace(/\s+/g, '_');
const cross = CROSS_SELL_MAP[dept];
if (cross && appt.status === 'SCHEDULED') {
triggers.push({
type: 'crosssell',
title: `${cross.department} consultation`,
reason: `${cross.reason} — patient already seeing ${appt.department}`,
priority: 'low',
});
break;
}
}
// Rule 4: First-visit patient — health checkup
if (facts.isNew || facts.contactAttempts === 0) {
triggers.push({
type: 'upsell',
title: 'Welcome Health Checkup',
reason: 'First-time patient, offer introductory health screening package',
priority: 'medium',
});
}
// Rule 5: Returning patient with no recent appointment
if (!facts.isNew && facts.appointments.length === 0 && facts.contactAttempts > 2) {
triggers.push({
type: 'retention',
title: 'Re-engagement',
reason: `Returning patient with ${facts.contactAttempts} prior contacts but no active appointments`,
priority: 'high',
});
}
return triggers.slice(0, 4);
};
// For display in Settings > Automations (read-only cards)
export const SUGGESTION_RULE_DEFINITIONS = [
{
name: 'Package Upsell by Department',
category: 'upsell' as const,
description: 'Suggest department wellness package when patient has a scheduled appointment.',
trigger: 'On call connect',
condition: 'Scheduled appointment exists',
action: 'Suggest department package',
enabled: true,
},
{
name: 'Reschedule Missed Appointment',
category: 'retention' as const,
description: 'Offer to rebook when patient has a cancelled or rescheduled appointment.',
trigger: 'On call connect',
condition: 'Cancelled/Rescheduled/No-show appointment exists',
action: 'Suggest rebooking',
enabled: true,
},
{
name: 'Cross-sell Related Department',
category: 'crosssell' as const,
description: 'Suggest complementary department service based on current appointment.',
trigger: 'On call connect',
condition: 'Scheduled appointment in mapped department',
action: 'Suggest related service',
enabled: true,
},
{
name: 'First Visit Health Checkup',
category: 'upsell' as const,
description: 'Suggest introductory health screening for first-time patients.',
trigger: 'On call connect',
condition: 'New patient or zero contact attempts',
action: 'Suggest health checkup package',
enabled: true,
},
{
name: 'Returning Patient Re-engagement',
category: 'retention' as const,
description: 'Prompt re-engagement for returning patients with no active appointments.',
trigger: 'On call connect',
condition: 'Returning patient, no appointments, 3+ contacts',
action: 'Suggest booking',
enabled: true,
},
];