feat: AI chat system with LangGraph, multi-step patient flows, and appointment rescheduling
- Add floating chat window Hand-off to AI toggle (per-patient) and after-hours AI toggle (global) - Add LangGraph-powered appointment reminder flow: AI introduces itself, classifies YES/NO, handles confirmation with appointment date/time - Add multi-step rescheduling flow: ASAP vs next week, tomorrow offer, Mon/Tue/Wed picker, morning/afternoon time slot — automatically updates appointment in DB - Add new patient / after-hours flow: new vs existing patient, dental insurance check, MassHealth Selenium eligibility check (auto-uses saved member ID + DOB for existing patients), self-pay fallback - Add AI Chat Settings page (Settings → Advanced) with editable greeting templates and LangGraph flow diagrams for both reminder and new-patient flows - Add Schedule a New Patient template option in chat window, starts new-patient conversation flow - Add GET/PUT endpoints for AI handoff, after-hours handoff, and AI chat templates - Add multilingual support (7 languages) across all AI reply nodes with LLM generation and hardcoded fallbacks - Add pending reschedule in-memory store and conversation stage tracking across all flows Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -59,6 +59,30 @@ export const twilioStorage = {
|
||||
});
|
||||
},
|
||||
|
||||
async getAiChatTemplates(userId: number): Promise<Record<string, string>> {
|
||||
const settings = await db.twilioSettings.findUnique({ where: { userId } });
|
||||
const all = (settings?.templates as Record<string, string>) || {};
|
||||
return {
|
||||
reminderGreeting: all["_ai_chat_reminder_greeting"] ?? "",
|
||||
newPatientGreeting: all["_ai_chat_new_patient_greeting"] ?? "",
|
||||
generalFallback: all["_ai_chat_general_fallback"] ?? "",
|
||||
};
|
||||
},
|
||||
|
||||
async saveAiChatTemplates(userId: number, templates: { reminderGreeting?: string; newPatientGreeting?: string; generalFallback?: string }) {
|
||||
const settings = await db.twilioSettings.findUnique({ where: { userId } });
|
||||
const existing = (settings?.templates as Record<string, string>) || {};
|
||||
const updated: Record<string, string> = { ...existing };
|
||||
if (templates.reminderGreeting !== undefined) updated["_ai_chat_reminder_greeting"] = templates.reminderGreeting;
|
||||
if (templates.newPatientGreeting !== undefined) updated["_ai_chat_new_patient_greeting"] = templates.newPatientGreeting;
|
||||
if (templates.generalFallback !== undefined) updated["_ai_chat_general_fallback"] = templates.generalFallback;
|
||||
return db.twilioSettings.upsert({
|
||||
where: { userId },
|
||||
update: { templates: updated },
|
||||
create: { userId, accountSid: "", authToken: "", phoneNumber: "", templates: updated },
|
||||
});
|
||||
},
|
||||
|
||||
async getRecentCommunicationsByUser(userId: number, limit = 20) {
|
||||
return db.communication.findMany({
|
||||
where: { patient: { userId } },
|
||||
|
||||
Reference in New Issue
Block a user