- Tufts SCO claim/preauth: robust location dropdown selection (multiple
option selectors, retries, keyboard fallback, HTML dump on failure)
- CDT lookup: map ext/extraction/simple ext to D7140; ignore dangling
"on/of/for/at" left after stripping tooth number
- Custom CDT aliases: keep only the Dxxxx code ("D7140 #25" → "D7140") and
drop tooth numbers from phrases, on save and at lookup — fixes $0 fee
from code "D7140#25"
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Open the toothSurfaces MUI listbox (retrying if it doesn't appear), check
each surface letter by option text via JS and verify it ends up selected,
then close the popover with Escape or a backdrop click so its overlay no
longer blocks the fee field. Waits for the tooth-number listbox to close
first so its options aren't misread.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Eligibility: rebuilt the Delta Indiv worker for my.deltadentalcoversme.com —
Dentist tab -> Universal Delta Sign In -> username/Next -> password -> SIGN IN,
confirmation-code (MFA) page detected by URL so the app's OTP popup shows,
then Search for Patient -> Last Name + DOB -> Submit. On the "Benefits for"
details page it reads the patient name, Subscriber # and Eligible through
(active while that date is today or later) and saves the PDF downloaded by
the Print link. Session persists: login is skipped while Search for Patient
is reachable, and Delta Indiv cookies are no longer wiped on agent startup.
The button needs Last Name + DOB (member ID optional; backend falls back to
the scraped Subscriber #). Chatbot gains a Delta Indiv option and aliases.
Claims: Delta Indiv uses the same 2024 ADA form as BCBS with the payer
address Delta Dental, P.O. Box 103, Stevens Point, WI 54481-0103. Adds Delta
Indiv Claim/PreAuth (ADA Form) buttons, Claim All and AI queue routing, Print
ADA Form in the claim viewer, a Delta Indiv fee schedule (copied from BCBS),
and Delta Indiv as its own insurance type so it is no longer treated as
Deltains.
Also renames eligibility buttons: Delta Indiv (Last name, DOB or ID),
Metlife Dental (ID or SSN), Altus (ID, First name, DOB).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reuses the MetLife eligibility login (persistent profile, email MFA, OTP
from app or browser), then Submit Claims -> ClaimConnect -> DentalXChange
Single Claim: billing/rendering provider, member ID, last name, payer
Metlife 65978, patient picked by DOB/name, signature on file Yes, one
claim item per CDT code (date, code, tooth, surfaces, fee; Add Claim Item
past 3), Finish, Submit Claim, then Back to Claim to read the Claim ID and
save the page as PDF. Waits out Wicket ajax/veil before each click.
MetLife now has its own fee schedule (seeded from DDMA) instead of falling
back to MassHealth prices.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Eligibility (no OTP, fresh browser per run like MH): logs in, opens Benefits &
Claims Information, searches by Subscriber ID (or Subscriber Last Name via
"Click Here"), First Name and DOB, picks the matching row from the patient list,
sets ACTIVE/INACTIVE from the Coverage range, reads Group Number into the
patient's Group Number, opens View Details for the last name and plan name,
and saves the details page PDF to the patient's Eligibility folder. A patient
switching plans is matched by name + DOB so Altus overwrites the old insurance
instead of creating a duplicate.
Claims: Altus uses the same 2024 ADA form as BCBS with the Altus payer address
(P.O. Box 1557, Providence, RI 02901-1557). Adds Altus Claim/PreAuth (ADA Form)
buttons, Claim All and AI queue routing, Print ADA Form in the claim viewer, and
an Altus fee schedule (copied from BCBS).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mirrors the DDMA flow: persistent Chrome profile + credential-change logout,
PingOne login with email MFA selection and OTP from app or browser,
Eligibility & Plan Details search (masked Subscriber ID/SSN), family member
picked by DOB and re-verified on the plan details page, PDF saved to the
patient's Eligibility folder and status set ACTIVE/INACTIVE.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Claim form: AI claim/preauth prefill adds rows beyond the initial 10
instead of dropping codes 11+
- CDT lookup: "D6010 #5, 9, 11, 12" expands to one line per tooth, and
the chat graph rebuilds such lists from the message if the LLM drops items
- Eligibility: match an existing patient by name+DOB when the insurance ID
changed (e.g. MassHealth → CCA) instead of creating a duplicate patient
- CCA PreAuth: services grid scrolls to reach rows 11+
- CCA and Tufts SCO PreAuth: tentative service date = today + 3 days
- CCA (eligibility/claim/preauth) and DentalHub (claim/preauth): keep Chrome
open, blank and minimized, after a job so the next job reuses it
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Use ServicesSURFACE{n} editor ids (matching header mapping names);
keep ServicesSURF{n} as a one-try fallback
- Derive missing surface columns from TOOTH+n when headers lack names
- Treat a failed surface fill as an error so the claim is not submitted
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CCA step1 was treating the harmless "password set to expire" banner as a
fatal error, closing the browser before the eligibility popup/report
could be captured. Now it short-circuits to success once the patient
popup renders and ignores password-expiration notices.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Claim step2: robust member checkbox selection with page-wide fallback
- Eligibility: take patient name from 'Benefits for' heading, not subscriber name
- Processor: update the patient just created/matched by ID+DOB, not first ID match
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
DDMA redesigned their claims-submission flow, so the worker now navigates
via the dashboard's "Submit Claims" quick link, the "Member Search" and
"Claim Detail" sidebar sections, checkbox-based member selection, indexed
treatment-row fields, a multi-file upload input, and the new confirmation
page layout.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fixes the transaction-type radio button (was matching nothing; now
targets the real data-testid), and adds a Deltains fee schedule
(seeded from DDMA's prices) so Deltains claims stop falling back to
MassHealth pricing.
Adds a full "Deltains Claim" button next to Delta MA Claim, mirroring
the DDMA claim flow across frontend, backend queue/routes, and a new
Selenium worker. Reuses the existing Deltains eligibility login/OTP
code and was iteratively wired against the live portal (patient roster
search, per-service-line fields, tooth number/surface selects, review
and submit). Also fixes chatbot/insurance-alias carrier recognition so
"deltains" resolves correctly instead of falling back to MassHealth.
Only two paths now: click the radio in the last history row when a
table is shown, or click the Member Details link directly when no
history/radio appears at all (single unambiguous match, as seen for
patient Nassim). Removes the first-row retry fallback.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Click the first visible 'Next' button on the Patient Information step
instead of a stale hidden one, so the wizard advances after member select
- Read procedure fee from totalBilled/billedAmount (matching every other
claim worker) instead of a fee key the frontend never sends
- Implement claim confirmation PDF capture + claim number extraction
- Check "Remember this device" on the OTP page so future logins skip OTP
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- AI-column auto-submit and manual "Claim All" dispatchers in claim-form.tsx
had no United Ucard branch, so United Ucard claims silently fell through
to the MassHealth (MH) submit handler instead of opening the United Ucard
site.
- Added a United Ucard fee schedule (copied from United SCO as a starting
point) and wired it into the frontend price-mapping/mismatch-check code
and the backend fee-schedule update route, which previously had no
schedule for United Ucard and fell back to MassHealth's prices.
- Selenium claim worker: when the member search returns multiple coverage
records, it now tries the last row first (existing default) and falls
back to the first row only if the "Member Details" link never appears
(i.e. the last row was an inactive record), instead of only ever trying
one or the other.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Status & History page loads results asynchronously; a single 20s wait
was giving up before the row appeared, so the pre-auth number was
never captured. Now polls up to 75s for a populated row.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a "United Ucard Claim" button (claims/preauth insurance form) that
submits through a full Selenium pipeline mirroring the Tufts SCO claim
worker: frontend handler -> backend route/queue processor -> Python
agent, reusing the persistent login/OTP session from the existing
United Ucard eligibility check. Implements the UHC Dental claim wizard
end-to-end (Provider Information, Patient Information search/select,
Claim Information procedures + questions, Upload Documents, Review and
Sign, Submit); the final confirmation-page PDF/claim-number capture is
still a TODO stub pending that page's DOM.
Also wires United Ucard into the AI chatbot's eligibility flow
(insuranceAliases.json, siteKeyToAutoCheck, clarification options), and
fixes a bug where the AI-column batch claim feature silently defaulted
United Ucard patients to MassHealth because batchColumnDeriveSiteKey
had no matching branch and no job-dispatch case for UNITED_UCARD.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a full login/OTP/search/capture flow for United Ucard (OneHealthcareID
-> UHC Dental provider portal), mirroring the United SCO/DDMA pattern:
persistent Chrome profile, OTP polling, member eligibility search, and PDF
capture saved to the patient's Eligibility folder.
Also fixes a validation bug in the browser-safe patient schema where
email/address/city/zipCode/gender/phone were optional but not nullable,
rejecting patient records with null values on those fields during edits
(e.g. "Expected string, received null").
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Auto-fill service line price when a recognized CDT code is typed
(e.g. D2740), instead of requiring a separate "Map Price" click
- Fix chatbot preauth prefill using an empty DOB for price lookup,
causing age-tiered codes (D2740) to price as $0
- Re-apply fee-schedule pricing with the loaded patient DOB before
MassHealth preauth auto-submit
- Add a "Recement Crown" (D2920) combo button distinct from "Crown"
(D2740) to avoid picking the wrong code/price
- Fix AI note parsing to prioritize "recement" over "crown" regardless
of word order or tooth-number format (e.g. "#7 crown recement")
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- unitedSCOEligibilityProcessor: overwrite patient's stored insuranceId when
the eligibility page reports a different (updated) Member ID than the one
searched with.
- CMSP worker: add AngularJS late-binding retry to results-table extraction
(ported from the MH worker's a0417653 fix), since every patient now routes
through this worker for the accumulator check.
- cmspEligibilityHistoryRemainingProcessor: stop forcing patient status to
UNKNOWN when extraction fails; a failed run landing after a successful one
was clobbering a correct ACTIVE/INACTIVE status.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Add remainingBenefit and thirdPartyInsurance columns to Patient; extract both
from the MassHealth accumulator/member-detail pages during the eligibility
check and surface them in the eligibility table
- Add an updated-date display and a toggle to suppress the post-check PDF
viewer popup (default off) on the insurance eligibility page
- Rename CMSP-prefixed PDF filenames and UI copy to MH, since CMSP and MH now
share the same worker
- Fold CMSP into MassHealth/MH across patient/claim insurance-type dropdowns
and the chatbot's eligibility routing, since they're the same insurance
- Remove auto-download of saved eligibility PDFs; downloading is now manual
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
DDMA now often skips the family-members results table and navigates
straight to the single-patient detail page, and labels the patient's
name "Subscriber name:" instead of "Name:". Update step1/step2 to
detect the detail-page URL correctly (it's nested under the search
path, so a plain substring check couldn't tell them apart), extract
the name from the new label, and fall back to parsing "Coverage is:"
for eligibility status when there's no results row to read it from.
Also fix a status-text substring bug ("active" matching inside
"inactive") and stop the backend from collapsing an unknown
eligibility result into INACTIVE. Skip name extraction entirely when
the caller already knows the patient (existing-patient recheck).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
DentalHub's upload input is a multi-file input; chromedriver send_keys
appends to the existing selection instead of replacing it, so the second
iteration re-uploaded the first file (2 attachments became 3). Clear the
input value before each send_keys and skip duplicate filePaths.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The three Python services (PatientDataExtractorService, PaymentOCRService,
SeleniumService) provisioned their venvs via postinstall, chained into
root's own postinstall. A failure in any one of them aborted the whole
npm install, which could leave unrelated Node deps (e.g. Backend's sharp)
uninstalled — silently breaking the app with no indication why.
Renamed each service's postinstall to an explicit "setup" script, added a
root "npm run setup:python" to run all three, and documented it as its
own step in the README instead of an automatic install-time side effect.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Clicking "Add a file" triggers input.click() which opens the OS-native
file picker that WebDriver can't control, causing send_keys on the
underlying input to fail with a message-less exception. The input is
already present in the DOM (display:none) so send_keys can target it
directly without the click.
_fill_combobox typed the value then used a single unioned XPath
(match-by-text | option[1]) to pick the dropdown option. Selenium's
find_element on a multi-match XPath returns the first node in
document order, not the first union alternative, so option[1] (e.g.
tooth "1") was always clicked regardless of what was typed (e.g. "22").
Split into a value-match wait with a separate fallback wait for
option[1] only when no match is found.
- Fix NameError (col_idx vs col_expr) that silently corrupted grid-fill logs
- Poll for new grid rows to render before clicking, instead of failing immediately
- Abort submission with a clear error if code/tooth/billed amount fail to fill,
instead of silently submitting an incomplete claim
- Compute grid column positions live from header metadata instead of stale
hardcoded indices; billed amount was landing on a hidden helper column
(TAB_FROM_CODE_CELL) via td[last()] instead of the real Billed Amt column
- Read claim/encounter number from the top (newest) dashboard row instead
of the bottom row
- Chatbot: submitting with only a screenshot attached (no text) now triggers the same
"AI Detect & Check Eligibility" flow as the Copy Agent page
- detect-eligibility-info now also extracts the visible insurance payer name and picks
Tufts SCO auto-check when both Sun Life and DentaQuest are detected, else MassHealth
- Chatbot-attached files are now handed off to both claim and preauth forms unconditionally,
not just claims
- TuftsSCO preauth Selenium worker: verify-and-retry the Tooth field (typing was silently
getting reset by duplicate-procedure-code warning banners), add a final re-verification
pass across all rows, fix acknowledgement-checkbox targeting/verification, and verify
the "Next step" click actually advances the wizard instead of trusting a blind click
Site now uses a dedicated claims-submission page with a Subscriber ID +
Birthdate search form instead of the member-ID search box, and login
detection now checks for the check-patient-benefits-search link rather
than the old member-search input placeholder.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Delta Dental MA moved their provider login from providers.deltadentalma.com/onboarding
to www.deltadentalma.com/sign-in with new form field selectors, and moved eligibility
search behind a "Group/Health Connector" search page keyed by subscriber ID + birthdate
instead of the old member-search form. Updates login, OTP/MFA handling, and member
search/selection across the eligibility and claim DDMA workers and their session helpers.
Adds a new Settings → Advanced → Selenium Settings page where the office
name (paymentGroupId) used in United/DentalHub portal dropdowns can be
configured without touching code. Previously hardcoded as "Summit Dental
Care"; now injected from DB into the three United workers at job dispatch.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add multi_claim intent so AI correctly handles "claim X for patient A and Y for patient B"
instead of applying all procedures to all patients (batch_claim)
- Each patient carries their own matchedCodes in the queue
- Fix batch claim PDF race condition: chatbot queue no longer advances in closeClaim(),
instead advances after selenium PDF is downloaded (matching column claim behavior)
- Align United SCO eligibility worker with claim worker: only fill subscriber ID + DOB,
use treatmentLocation by ID instead of arrow-wrapper click
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add `import re` to all Selenium workers that use re.search() for claim number extraction
- Pass uploadedFiles to onHandleForMHSeleniumClaim so attachments reach the MH website
- Save chatbot pending files in check-and-claim and batch-check-and-claim flows
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a toggle behind the Go button on the Payments page to automatically run the MH batch payment check on a user-selected day of week and hour. Default is off.
- Schema: added autoMhCheckEnabled, autoMhCheckDayOfWeek, autoMhCheckHour to User model
- Backend: new mhBatchPaymentService (shared logic), GET/PUT /auto-mh-check-setting routes, hourly cron job that fires on matching day+hour
- Frontend: toggle + day select (Mon–Sun) + time select (hourly) that persist immediately to DB
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PDF import now marks payments as PAID when MassHealth patient's
mhPaidAmount >= totalBilled (no patient balance)
- Newly created patients from MH vouchers get insuranceProvider = 'MassHealth'
- Existing patients with blank insuranceProvider get it filled on import
- Fix: update patient name from PDF if existing record has empty name
- Various frontend/selenium/route updates
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces arrow-wrapper click (which hit the "Type to search" placeholder) with
find_element(By.ID, "treatmentLocation") + click, mirroring the paymentGroupId
approach. Looks for "Summit Dental Care" first, falls back to first available option.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extract patient name from search results row instead of failing on detail page
- Return dateOfBirth from input data (no need to scrape from webpage)
- Wait for search page to fully load before provider dropdown selection
- Add 3s wait after search results appear for row content to render
- Backend: fallback to update existing patient DOB instead of creating duplicate
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add preauth intent to AI chatbot (classifier, workflow, frontend UI card)
- Auto-prefill preauth form with CDT codes, service date, and mapped prices
- Auto-trigger preauth Selenium handler by insurance siteKey (MH/Tufts/CCA/UnitedDH)
- Default tentative service date to today+3 for preauth (user didn't pick a date)
- Fix #number always means tooth number, distributes to all procedures in comma list
- Fix bare "post"/"pos" → D2954 (was matching D2955 via keyword scorer)
- UnitedDH pre-auth: fill procedure date with Ctrl+A to overwrite prefilled value
- UnitedDH pre-auth: select Location "Summit Dental Care" in step1 (same as billing entity)
- UnitedDH pre-auth: remove page refresh in step9 to preserve pre-auth number
- UnitedDH pre-auth: wait for table rows before extracting pre-auth number
- UnitedDH pre-auth/claim: explicit wait for Submit button after file upload (no sleep)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>