feat: auto-populate patient fields from member ID on eligibility page

When a member ID is typed on the insurance eligibility page, debounced
lookup fills in date of birth, first name, and last name if the patient
already exists in the database.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gitead
2026-05-08 14:30:29 -04:00
parent 9908e5b5fd
commit e9296c68f9
7 changed files with 81 additions and 8 deletions

View File

@@ -72,6 +72,12 @@ export function startNewPatientConversation(userId: number, patientId: number):
stageStore.set(convKey(userId, patientId), "new_patient_greeted");
}
// Called when office sends a reschedule greeting — patient's next reply enters
// the reschedule flow.
export function startRescheduleConversation(userId: number, patientId: number): void {
stageStore.set(convKey(userId, patientId), "asked_reschedule_confirm");
}
// ── Pending reschedule data ───────────────────────────────────────────────────
// Holds the confirmed new date while AI waits for a time-slot answer.

View File

@@ -53,8 +53,8 @@ router.put("/chat-templates", async (req: Request, res: Response): Promise<any>
try {
const userId = req.user?.id;
if (!userId) return res.status(401).json({ message: "Unauthorized" });
const { reminderGreeting, newPatientGreeting, generalFallback } = req.body;
await storage.saveAiChatTemplates(userId, { reminderGreeting, newPatientGreeting, generalFallback });
const { reminderGreeting, newPatientGreeting, generalFallback, rescheduleGreeting } = req.body;
await storage.saveAiChatTemplates(userId, { reminderGreeting, newPatientGreeting, generalFallback, rescheduleGreeting });
const updated = await storage.getAiChatTemplates(userId);
return res.status(200).json(updated);
} catch (err) {

View File

@@ -1,7 +1,7 @@
import express, { Request, Response } from "express";
import twilio from "twilio";
import { storage } from "../storage";
import { getHandoff, setHandoff, resetConversation, startNewPatientConversation, getAfterHoursHandoff, setAfterHoursHandoff } from "../ai/aiHandoffStore";
import { getHandoff, setHandoff, resetConversation, startNewPatientConversation, startRescheduleConversation, getAfterHoursHandoff, setAfterHoursHandoff } from "../ai/aiHandoffStore";
const router = express.Router();
@@ -95,6 +95,8 @@ router.post("/send-sms", async (req: Request, res: Response): Promise<any> => {
// Set conversation stage based on which flow was started
if (startFlow === "new_patient") {
startNewPatientConversation(userId, pid);
} else if (startFlow === "reschedule") {
startRescheduleConversation(userId, pid);
} else {
resetConversation(userId, pid);
}

View File

@@ -66,16 +66,18 @@ export const twilioStorage = {
reminderGreeting: all["_ai_chat_reminder_greeting"] ?? "",
newPatientGreeting: all["_ai_chat_new_patient_greeting"] ?? "",
generalFallback: all["_ai_chat_general_fallback"] ?? "",
rescheduleGreeting: all["_ai_chat_reschedule_greeting"] ?? "",
};
},
async saveAiChatTemplates(userId: number, templates: { reminderGreeting?: string; newPatientGreeting?: string; generalFallback?: string }) {
async saveAiChatTemplates(userId: number, templates: { reminderGreeting?: string; newPatientGreeting?: string; generalFallback?: string; rescheduleGreeting?: 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;
if (templates.rescheduleGreeting !== undefined) updated["_ai_chat_reschedule_greeting"] = templates.rescheduleGreeting;
return db.twilioSettings.upsert({
where: { userId },
update: { templates: updated },