feat: Tufts SCO claim automation, Claim All button, fee schedule updates

- Add full Tufts SCO claim Selenium worker (steps 1-8): login with OTP
  support, member search, Create Claim, fill form, attach files, submit,
  extract claim number and save confirmation PDF
- Fix DentaQuest browser manager to preserve device trust token on startup
  (only clear cookies, not LocalStorage/IndexedDB) so OTP is only needed
  once for both eligibility and Tufts claim
- Fix Tufts SCO claim route credential lookup key (TUFTS_SCO not TuftsSCO)
- Add Tufts SCO and United/DentalHub entries to fee schedule update route
- Add "Claim All" button that auto-routes to the correct claim handler
  based on the Insurance Type dropdown value
- Add fee schedule JSON files for DDMA, Tufts SCO, and United/DentalHub

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gitead
2026-05-25 20:22:26 -04:00
parent 1e581c193c
commit 3534ecb3c9
11 changed files with 5188 additions and 88 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1202,16 +1202,26 @@ export function ClaimForm({
? npiProviders.find((p) => p.npiNumber === npiProvider.npiNumber)?.id ?? null
: null;
const createdClaim = await onSubmit({
...formToCreateClaim,
serviceLines: filteredServiceLines,
staffId: appointmentStaffId ?? Number(staff?.id),
patientId,
insuranceProvider: "Tufts SCO",
appointmentId: appointmentIdToUse!,
claimFiles: claimFilesMeta,
...(selectedNpiProviderId ? { npiProviderId: selectedNpiProviderId } : {}),
});
let createdClaim: any;
try {
createdClaim = await onSubmit({
...formToCreateClaim,
serviceLines: filteredServiceLines,
staffId: appointmentStaffId ?? Number(staff?.id),
patientId,
insuranceProvider: "Tufts SCO",
appointmentId: appointmentIdToUse!,
claimFiles: claimFilesMeta,
...(selectedNpiProviderId ? { npiProviderId: selectedNpiProviderId } : {}),
});
} catch (err: any) {
toast({
title: "Failed to save claim",
description: err?.message || "An error occurred saving the claim.",
variant: "destructive",
});
return;
}
onHandleForTuftsSCOSeleniumClaim({
...form,
@@ -1228,6 +1238,27 @@ export function ClaimForm({
onClose();
};
const handleClaimAll = () => {
const siteKey = (form.insuranceSiteKey || deriveInsuranceSiteKey(form.insuranceProvider || "")).toUpperCase();
if (siteKey === "MH" || siteKey === "MASSHEALTH") {
runWithPriceCheck(() => handleMHSubmit());
} else if (siteKey === "CCA") {
runWithPriceCheck(handleCCAClaim);
} else if (siteKey === "DDMA") {
runWithPriceCheck(handleDDMAClaim);
} else if (siteKey === "TUFTSSCO" || siteKey === "TUFTS_SCO") {
runWithPriceCheck(handleTuftsSCOClaim);
} else if (siteKey === "UNITEDSCO" || siteKey === "UNITEDDH" || siteKey === "UNITED_SCO") {
runWithPriceCheck(handleUnitedDHClaim);
} else {
toast({
title: "No automated claim for this insurance",
description: `Insurance type "${form.insuranceSiteKey || "unknown"}" does not have an automated claim. Please use one of the buttons below.`,
variant: "destructive",
});
}
};
const handleCCAPreAuth = async () => {
const missingFields: string[] = [];
if (!form.memberId?.trim()) missingFields.push("Member ID");
@@ -2146,6 +2177,15 @@ export function ClaimForm({
</Button>
</div>
) : (
<>
<div className="flex justify-center mb-3">
<Button
className="w-36 bg-slate-800 hover:bg-slate-900 text-white font-semibold"
onClick={handleClaimAll}
>
Claim All
</Button>
</div>
<div className="flex flex-wrap gap-2 justify-center">
<Button
className="w-32 bg-blue-600 hover:bg-blue-700 text-white"
@@ -2184,6 +2224,7 @@ export function ClaimForm({
Claim Saved
</Button>
</div>
</>
)}
</div>
</div>