feat: migrate SMS/voice to Telnyx (TeXML), keep browser dial pad on Twilio

Twilio now handles only the in-browser dial pad (Access Token + browser-Device
outbound TwiML); Telnyx takes over SMS, inbound voicemail, the AI voice
conversation loop, and staff-triggered outbound calls via TeXML. Adds
TelnyxSettings model, Communication.provider discriminator, new comms/routes
modules, and a real Telnyx Settings page.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-03 15:39:43 -04:00
co-authored by Claude Sonnet 5
parent b899659e13
commit 79ac6aaa31
463 changed files with 7823 additions and 3397 deletions
@@ -269,9 +269,9 @@ export function MessageThread({ patient, onBack, appointmentInfo }: MessageThrea
const [pendingStartFlow, setPendingStartFlow] = useState<"new_patient" | "reschedule" | null>(null);
useQuery<{ enabled: boolean }>({
queryKey: ["/api/twilio/ai-handoff", patient.id],
queryKey: ["/api/telnyx/ai-handoff", patient.id],
queryFn: async () => {
const res = await apiRequest("GET", `/api/twilio/ai-handoff/${patient.id}`);
const res = await apiRequest("GET", `/api/telnyx/ai-handoff/${patient.id}`);
return res.json();
},
onSuccess: (data: { enabled: boolean }) => setHandOffToAI(data.enabled),
@@ -289,7 +289,7 @@ export function MessageThread({ patient, onBack, appointmentInfo }: MessageThrea
const handoffMutation = useMutation({
mutationFn: async (enabled: boolean) =>
apiRequest("PUT", `/api/twilio/ai-handoff/${patient.id}`, { enabled }),
apiRequest("PUT", `/api/telnyx/ai-handoff/${patient.id}`, { enabled }),
});
const handleHandoffToggle = (enabled: boolean) => {
@@ -318,7 +318,7 @@ export function MessageThread({ patient, onBack, appointmentInfo }: MessageThrea
const sendMessageMutation = useMutation({
mutationFn: async (message: string) =>
apiRequest("POST", "/api/twilio/send-sms", {
apiRequest("POST", "/api/telnyx/send-sms", {
to: patient.phone,
message,
patientId: patient.id,