feat: batch eligibility, batch claim, and batch check+claim from AI chat

- Add batch_eligibility, batch_claim, and batch_check_and_claim intents
  to AI classifier so multiple patients can be processed one by one
- Add queue processing on insurance-status and claims pages to auto-start
  the next patient after each check/claim completes
- Make patient schema firstName, lastName, phone optional so patients can
  be created with just member ID + DOB from eligibility checks
- Cancel buttons now preserve chat history instead of clearing it
- Patient-found card shows Check Eligibility, Eligibility & Appointment
  Today, and Cancel buttons
- Claim service date asks user to pick between latest appointment and
  today when they differ
- Login page subtitle styled with animated gradient

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ff
2026-06-18 23:41:56 -04:00
co-authored by Claude Sonnet 4.6
parent a2e5c157ad
commit a52ff2d723
9 changed files with 710 additions and 66 deletions
@@ -385,6 +385,7 @@ export default function InsuranceStatusPage() {
setPreviewFallbackFilename(jobResult.pdfFilename ?? `eligibility_${memberId}.pdf`);
setPreviewOpen(true);
}
processNextInQueue();
} catch (error: any) {
dispatch(setTaskStatus({ key: "eligibilityCheck", status: "error", message: error.message || "Selenium submission failed" }));
toast({ title: "Selenium service error", description: error.message || "An error occurred.", variant: "destructive" });
@@ -574,6 +575,7 @@ export default function InsuranceStatusPage() {
if (claimed) return;
setSelectedPatient(null);
await queryClient.invalidateQueries({ queryKey: QK_PATIENTS_BASE });
processNextInQueue();
// Open all PDFs side by side in the modal
if (jobResult.pdfFileId || jobResult.memberDetailsPdfFileId || jobResult.historyPdfFileId) {
@@ -643,6 +645,7 @@ export default function InsuranceStatusPage() {
setSelectedPatient(null);
await queryClient.invalidateQueries({ queryKey: QK_PATIENTS_BASE });
processNextInQueue();
// Open 4-panel modal
if (jobResult.pdfFileId || jobResult.memberDetailsPdfFileId || jobResult.historyPdfFileId || jobResult.accumulatorPdfFileId) {
@@ -773,6 +776,29 @@ export default function InsuranceStatusPage() {
} catch {}
};
const processNextInQueue = () => {
try {
const raw = sessionStorage.getItem("chatbot_eligibility_queue");
if (!raw) return;
const queue = JSON.parse(raw) as { memberId: string; dob: string; autoCheck: string }[];
if (!queue.length) {
sessionStorage.removeItem("chatbot_eligibility_queue");
return;
}
const [next, ...rest] = queue;
if (rest.length > 0) {
sessionStorage.setItem("chatbot_eligibility_queue", JSON.stringify(rest));
} else {
sessionStorage.removeItem("chatbot_eligibility_queue");
}
toast({ title: `${rest.length + 1} patient${rest.length > 0 ? "s" : ""} remaining`, description: `Starting next: ${next!.memberId}` });
setTimeout(() => {
sessionStorage.setItem("chatbot_eligibility", JSON.stringify({ memberId: next!.memberId, dob: next!.dob, autoCheck: next!.autoCheck }));
window.dispatchEvent(new CustomEvent("chatbot:eligibility-prefill"));
}, 1500);
} catch {}
};
// Redirect from schedule page "Check Eligibility": prefill patient + optionally auto-trigger or scroll
useEffect(() => {
const params = new URLSearchParams(window.location.search);
@@ -1018,6 +1044,7 @@ export default function InsuranceStatusPage() {
setPreviewFallbackFilename(fallbackFilename ?? `eligibility_ddma_${memberId}.pdf`);
setPreviewOpen(true);
}
processNextInQueue();
}}
/>
</div>
@@ -1039,6 +1066,7 @@ export default function InsuranceStatusPage() {
setPreviewFallbackFilename(fallbackFilename ?? `eligibility_deltains_${memberId}.pdf`);
setPreviewOpen(true);
}
processNextInQueue();
}}
/>
</div>
@@ -1057,6 +1085,7 @@ export default function InsuranceStatusPage() {
fallbackFilename ?? `eligibility_bcbs_ma_${memberId}.pdf`,
);
setPreviewOpen(true);
processNextInQueue();
}}
/>
</div>
@@ -1081,6 +1110,7 @@ export default function InsuranceStatusPage() {
setPreviewFallbackFilename(fallbackFilename ?? `eligibility_tuftssco_${memberId}.pdf`);
setPreviewOpen(true);
}
processNextInQueue();
}}
/>
</div>
@@ -1102,6 +1132,7 @@ export default function InsuranceStatusPage() {
setPreviewFallbackFilename(fallbackFilename ?? `eligibility_unitedsco_${memberId}.pdf`);
setPreviewOpen(true);
}
processNextInQueue();
}}
/>
</div>
@@ -1123,6 +1154,7 @@ export default function InsuranceStatusPage() {
setPreviewFallbackFilename(fallbackFilename ?? `eligibility_cca_${memberId}.pdf`);
setPreviewOpen(true);
}
processNextInQueue();
}}
/>
</div>