- Member ID and DOB in the AI chat "patient found" confirmation card are now
editable inputs, and edits are persisted back to the patient record before
proceeding so corrections don't revert to stale values.
- Fix auto-lookup-by-member-ID effect on the insurance status page clobbering
a hand-edited DOB with the stale DB value during chatbot prefill.
- CMSP (under-14) eligibility flow was missing the appointment-creation hook
that the adult MassHealth flow already had, so under-14 patients never got
scheduled after a chatbot-initiated "eligibility & appointment" request.
- For already-known patients, the chatbot was creating the appointment before
running the eligibility check instead of after; now eligibility is always
checked first and the appointment created only afterward, and only when the
resulting patient status is ACTIVE.
Adds an "AI Detect & Check Eligibility" action to the Copy Agent page that
sends captured screenshots to Claude to extract Member ID/DOB, then opens
the chatbot's eligibility confirm step pre-filled with the result.
- POST /api/ai/detect-eligibility-info: Claude vision extraction of
Member ID/DOB from uploaded screenshots.
- POST /api/patients/create-temp: auto-creates a placeholder "PID-<id>"
patient (matched by insuranceId+dob) when no patient is selected, so
screenshots can be saved immediately; the real eligibility check later
rewrites the patient's name and Cloud Storage folder automatically via
the existing createOrUpdatePatientByInsuranceId matching logic.
- Chatbot: Member ID/DOB on the confirm card are now editable (MM/DD/YYYY),
with edits synced back to the patient record before the check runs.
- Fixed a useEffect ordering bug on the insurance-status page that could
silently clear a chatbot-prefilled Member ID/DOB before the auto-trigger
effect ran, preventing the eligibility check from ever starting.
- Added a local-disk-only screenshot backup (apps/Backend/uploads/
screenshot-backups/) for debugging, not exposed anywhere in the UI.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Missed these five Number(...) coercions when widening PDF ids to support the
"cloud:<id>" format — member details/history/accumulator panels in the MH and
CMSP multi-PDF viewers were fed NaN, which usePdfBlob treats as falsy and
never fetches. Only the first panel (eligibility) used the already-fixed
pdfFileId field, so it worked while the rest silently stayed blank.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New saves go into the patient's Cloud Storage folder under category subfolders
(Eligibility/Claims/PreAuth/Claim Status/Attachments) via a new
storage.savePdfToCloudStorage helper, instead of the legacy PdfGroup/PdfFile
Postgres blob tables. Old records and their read paths are left untouched for
backward compatibility; PDF list/content/delete endpoints and viewers now
transparently handle both legacy numeric ids and new "cloud:<id>" ids.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Add batch_eligibility_by_name intent so "check Mary and Sinthia" resolves multiple names
- Add "Check All & Appointment Today" button to batch eligibility UI — creates appointment for each patient after their eligibility check completes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
The chatbot-extracted DOB was stored in chatbot_claim_codes but never
forwarded to chatbot_claim_prefill, leaving the claim form DOB empty
when the patient DB record lacked it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- claims-page: after auto-submit closes the form, automatically navigate
back to /appointments when an AI claim queue is pending resume, eliminating
the manual navigation delay between appointments
- internal-chat-workflow: warn and block claim when D1120 (child prophy) is
requested for a patient aged 14+ — recommend D1110 (adult prophy) instead,
and advise manual claim if user insists on D1120
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- parseSrpCode: recognize "D4341 UL" / "4341 LR" etc., store quadrant in quad field
- matchOne: auto-prefix D for 4-digit inputs like "0120" → D0120
- LLM prompt: keep SRP code and quadrant together as one procedureName entry
- CdtMatch / CdtResult: add quad field, thread through matchedCodes action data
- claim-form.tsx: include quad in chatbot_claim_prefill type and spread to service line
- selenium_claimSubmitWorker.py: pass quad to fill_service_line, select quadrant
dropdown by index (UR=1, UL=2, LL=3, LR=4) matching MassHealth form structure
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Claim file uploads (chatbot or manual) now save to both the Cloud
Storage patient folder and the Documents page via new
POST /api/claims/upload-to-cloud endpoint
- MH submit flow now calls uploadAttachmentsToLocalFolder (same as
DDMA/United/Tufts) so chatbot-attached X-rays are persisted
- Removed old /upload-attachments disk route and attachmentDiskStorage
multer config; deleted uploads/patients/ folder
- uploadAttachmentsToLocalFolder now points to /upload-to-cloud and
sends patientId so the backend can create the patient folder
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add "Eligibility & Appointment" button to chatbot eligibility-id-ready card
- For known patients: creates today's appointment immediately, then opens eligibility page
- For unknown patients: navigates to eligibility page; after Selenium creates the patient,
auto-creates appointment via tryAppointmentFromChatbot on the insurance-status page
- Update MH Eligibility & Appointment button to create a today's schedule slot instead of
navigating to the appointments page; shows PDF preview on completion
- createAppointmentToday falls back from Column A to Column B when Column A is full;
returns column label in response so UI can display it
- Set AI-scheduled appointment duration to 15 minutes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Chatbot: add paperclip button to attach X-ray/PDF files to claim submissions;
files flow through chatbotFileStore into claim-form uploadedFiles for Selenium
- CDT lookup: auto-select D3310/D3320/D3330 by tooth number for RCT; strip #NN
from procedure names before alias lookup so "1 pa, #3" → D0220 tooth 3;
add "1 pa" alias for D0220; expand multi-PA notation via AI prompt rule
- AI classifier: add navigate_eligibility intent ("check mh" → /insurance-status);
fix duplicate intent entry; add RCT and multi-PA prompt rules
- Check+claim flow: pass serviceDate through check_and_claim_ready actionData;
tryClaimFromChatbot skips PDF preview and navigates straight to claims with
memberId fallback lookup; wired into all provider onPdfReady callbacks
- Claims table: add Service Date column between Patient Name and Submission Date
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Internal AI chat: schedule_appointment intent books earliest available
slot in Column A using office hours; claim_only intent looks up latest
past appointment for service date, asks user when two appointments are
within 7 days, auto-triggers correct Selenium worker with mapped prices
- Gemini model updated to gemini-flash-latest; conversation history (15
messages) passed for pronoun/reference resolution; history trimmed to
start with user turn so Gemini doesn't reject the context
- Insurance alias file (insuranceAliases.json) replaces hardcoded siteKey
matching; "tufs" now resolves to TUFTS_SCO
- DOB format normalized (MM/DD/YYYY → YYYY-MM-DD) before parseLocalDate;
autoCheck now fires for all insurance types, not just MH/CMSP
- Claim form auto-submit: all handlers (MH, CCA, DDMA, UnitedDH, Tufts)
accept formToUse and receive fee-schedule-priced form; prefillDone set
after chatbot code prefill so autoSubmit gate opens correctly
- Chatbot: chat history persisted in sessionStorage, cleared on logout
and auto-logout; Clear button writes fresh state synchronously; message
history window increased to 15
- DentaQuest/TuftsSCO Selenium: "Remember me" checkbox clicked before
sign-in to persist OTP trust cookie across sessions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New Selenium worker (fresh Chrome per run, no persistent session)
login → OTP modal → eTools → ConnectCenter → Verification →
New Eligibility Request → fill form (NPI, member ID, DOB) →
Expand All → CDP PDF back to app
- Backend route fetches BCBS_MA credentials + provider NPI from settings
- Frontend OTP modal with 6-digit code entry
- BCBS MA added to insurance credentials dropdown in settings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove "Claim Status" from appointment context menu
- Rename "Eligibility Status" → "Check Eligibility"
- Check Eligibility now navigates to insurance-status page and auto-starts
the correct selenium flow based on the patient's stored insurance provider:
MassHealth 21+ → MH Eligibility & History
MassHealth <21 → CMSP Eligibility & History & Remaining
Delta Dental MA → DDMA selenium
Delta Dental Ins → Delta Ins selenium (OTP modal if needed)
United Healthcare SCO → United SCO selenium
DentaQuest/Tufts → Tufts SCO selenium
Commonwealth Care Alliance → CCA selenium
Unknown → scroll to Other provider checks section
- Add autoTrigger/onAutoTriggered props to all five button components
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Socket.IO reconnects through Cloudflare proxy get a new socket.id, causing
the backend to emit job:update to a stale socket that no longer exists. The
PDF viewer modal never opened even though PDFs were saved successfully.
Adds a GET /api/insurance-status/job-status/:jobId endpoint backed by
InProcessQueue.getJob(), and a waitForSeleniumJob() helper on the frontend
that races socket events against HTTP polling every 3s. Whichever resolves
first wins, so local (socket) and external (Cloudflare) both work reliably.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add ChatbotButton component to top-app-bar (bot icon, upper right)
- Slide-in chat panel with 4 options: Check Eligibility, Schedule, Claims, Chat
- Single paste area accepts member ID + DOB in either order
- Age-based routing: ≥21 → MH Eligibility & History, <21 → CMSP auto-triggered
- Insurance-status page prefills fields and auto-fires the correct button via sessionStorage + custom event
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After clicking the member ID link, print the member details page via CDP
before navigating to service history. Adds member details as a panel in
the side-by-side PDF viewer: MH History shows 3 panels (eligibility,
member details, service history); CMSP shows 4 panels (eligibility,
member details, service history, accumulator).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add MH Eligibility & History button: runs full MH eligibility flow then
clicks member ID → service history, prints both PDFs via CDP, opens
dual side-by-side PDF modal (eligibility auto-downloads, history does not)
- Add CMSP Eligibility & History & Remaining button: same flow plus
navigates back to member details, clicks View Accumulator, prints
accumulator PDF via CDP; opens 3-panel side-by-side PDF modal
- Generalize DualPdfPreviewModal to accept panels[] array (works for 2 or 3 PDFs)
- Auto-download eligibility PDF via direct API URL to avoid Chrome Safe
Browsing pause on blob: URL downloads
- New backend processors, job types, and routes for both flows
- New Python Selenium workers with stable CSS selectors (ng-bind, href*)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>