feat: add AI recall calling — books existing patients for routine cleanings

Adds a new recall conversation flow (recall-graph.ts) triggered from the
Patient Connection "AI Call" button: offers an existing patient a routine
exam & cleaning, classifies their yes/no reply, then books directly onto
the schedule (Column A, 30-minute slots, real conflict checking against
office hours and existing appointments) instead of only capturing a
preference for staff to follow up on.

Also adds a "Voice call" label in the message thread to distinguish call
transcripts from SMS, and updates the Call Templates settings UI with an
editable recall greeting.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
ff
2026-08-02 23:13:09 -04:00
co-authored by Claude Sonnet 5
parent 06dc63c53e
commit cef928be97
10 changed files with 588 additions and 39 deletions
+9
View File
@@ -3,6 +3,9 @@ import { prisma as db } from "@repo/db/client";
export type ConversationStage =
| "initial"
| "reminder_initial"
| "recall_initial"
| "recall_asked_datetime"
| "recall_asked_time_for_date"
| "greeted"
| "done"
| "new_patient_greeted"
@@ -81,6 +84,12 @@ export async function startRescheduleConversation(userId: number, patientId: num
await setStage(userId, patientId, "asked_reschedule_confirm");
}
// Recall: office proactively calls/texts an existing patient to offer a
// routine exam & cleaning (typically covered at no cost by insurance).
export async function startRecallConversation(userId: number, patientId: number): Promise<void> {
await setStage(userId, patientId, "recall_initial");
}
// ── Pending reschedule (in-memory — seconds-lived within a single exchange) ───
interface PendingReschedule {