Commit Graph
100 Commits
Author SHA1 Message Date
GiteadandClaude Opus 5.5 036e26c5d8 docs: add one-time git credential setup to Quick Install
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:46:44 -04:00
GiteadandClaude Opus 5.5 d67aa75c42 docs: add Quick Install (VS Code, Claude Code extension, install-all.sh); add install-all.sh fresh-machine setup script
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:41:01 -04:00
GiteadandClaude Sonnet 5 d357edd4a6 feat: add Delta Dental Individual (DeltaIndiv) eligibility check flow; fix CCA eligibility false-positive error
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>
2026-10-02 15:37:55 -04:00
GiteadandClaude Sonnet 5 a5a15d86bc feat: CCA pre-auth — select first member in multi-record popup, retry code/tooth/billed fills, stop instead of submitting incomplete lines
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 00:56:36 -04:00
GiteadandClaude Sonnet 5 8c0fcb4267 feat: CCA claim — select first member in multi-record popup, retry grid cell fills, pick latest claim by DOB, faster submit confirmation
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 00:53:51 -04:00
GiteadandClaude Sonnet 5 ef919a2a2f perf: shorten fixed waits in MassHealth claim submit worker
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 23:52:03 -04:00
GiteadandClaude Sonnet 5 90f587ac9d feat: CCA multi-record popup — save popup as PDF and read green/red status badge
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 12:20:40 -04:00
GiteadandClaude Sonnet 5 eb731dcbd6 feat: add BCBS MA option to AI chat eligibility flow
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 15:10:44 -04:00
GiteadandClaude Sonnet 5 df5d2267cd feat: map upper/lower partial denture phrases to D5211/D5212 in CDT lookup
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 11:41:11 -04:00
GiteadandClaude Sonnet 5 c719b20dd0 feat: United Ucard claim searches by name+DOB and fills tooth number/surface when provided
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 23:40:50 -04:00
GiteadandClaude Sonnet 5 7ec82902d9 feat: United Ucard name+DOB eligibility search via chat, duplicate-record handling, Product ID as member ID
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 22:30:01 -04:00
GiteadandClaude Sonnet 5 ce25cdd2a2 fix: DDMA claim checkbox, eligibility patient name, and ID+DOB patient lookup
- 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>
2026-09-20 15:56:03 -04:00
Gitead dcf2ff536a fix: close browser window after Deltains claim completes
Session still persists via the Chrome profile/saved cookies, so
closing the window doesn't force a re-login or OTP next time.
2026-09-18 14:51:56 -04:00
GiteadandClaude Sonnet 5 7b8a7af5d7 fix: update DDMA claim worker for new provider portal
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>
2026-09-18 14:36:14 -04:00
Gitead d91e74c959 fix: Deltains claim selectors and dedicated fee schedule
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.
2026-09-17 21:00:07 -04:00
Gitead 37695130d3 feat: add Deltains claim submission flow
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.
2026-09-17 13:11:58 -04:00
GiteadandClaude Sonnet 5 8cbdba092d fix: handle no-history single-match case in United Ucard claim search
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>
2026-09-15 23:23:48 -04:00
GiteadandClaude Sonnet 5 865b754ae1 fix: complete United Ucard claim flow and remember OTP device
- 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>
2026-09-15 22:45:05 -04:00
GiteadandClaude Sonnet 5 d7015270a8 fix: auto-refresh patient table after eligibility checks
Remaining benefit amount didn't show until a manual page reload
because invalidateQueries was placed after an early return (chatbot
claim flow) for MH checks, and was missing entirely from the 7
other-provider eligibility buttons.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 13:37:56 -04:00
GiteadandClaude Sonnet 5 765368216f fix: route United Ucard claims correctly and add fee schedule
- 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>
2026-09-15 13:21:53 -04:00
GiteadandClaude Sonnet 5 af62bf151e fix: poll longer for Status & History table to load in preauth worker
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>
2026-09-14 23:38:06 -04:00
GiteadandClaude Sonnet 5 e570a0aa13 feat: add United Ucard claim worker and fix batch-column site-key routing
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>
2026-09-14 23:27:39 -04:00
GiteadandClaude Sonnet 5 f30016e674 feat: add United Ucard eligibility check with OTP + persistent session
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>
2026-09-13 22:44:43 -04:00
GiteadandClaude Sonnet 5 e8889c0ff8 fix: auto-price CDT codes and fix crown/recement code mismatches
- 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>
2026-09-12 23:29:43 -04:00
GiteadandClaude Sonnet 5 00a81b3fda fix: correctly suppress PDF popup for last claim in AI-column batch
closeClaim() was clearing chatbotAutoSubmitSiteKey synchronously right
after the selenium job kicked off, before the job's async completion
handler could check it. This was masked for all but the last claim in
the batch because closeClaim() also navigated away (unmounting the
page) whenever more claims were queued. On the last claim the page
stayed mounted, so the completion handler read a stale cleared value
and let the PDF preview popup through. Track the site key in a ref
that survives closeClaim() and is cleared only after the job's own
completion handler consumes it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 08:56:52 -04:00
GiteadandClaude Sonnet 5 fd2d1e6aba fix: default tooth # for 2PA and skip PDF popup for AI chat claims
- 2PA with no explicit tooth numbers now defaults to D0220 #8 / D0230 #24
- Claims submitted via the AI chat column no longer auto-open the PDF preview modal

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 15:52:31 -04:00
GiteadandClaude Sonnet 5 d35efe7366 fix: reliability fixes for UHC SCO and CMSP eligibility checks
- 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>
2026-09-05 13:11:58 -04:00
GiteadandClaude Sonnet 5 74d5c7c7ff feat: wire up mic/speaker and Google Translate backend for live translation
Frontend uses the Web Speech API for speech-to-text and text-to-speech
(no key needed). Adds POST /api/translate backed by Google Cloud
Translation API v2, gated on GOOGLE_TRANSLATE_API_KEY (placeholder
added to .env/.env.example, unset by default).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 21:28:57 -04:00
GiteadandClaude Sonnet 5 616ca5f259 feat: add live translation UI section above dial pad
Google Translate-style side-by-side layout with per-side language
pickers on the patient connection page. UI shell only for now, no
translation provider wired up yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 16:05:30 -04:00
GiteadandClaude Sonnet 5 8f9fd13208 fix: update hardcoded folder name from DentalManagementMH07 to DentalManagement09
Scripts still referenced the old project folder name after the rename,
which broke the desktop shortcuts and start/stop scripts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 15:51:17 -04:00
GiteadandClaude Sonnet 5 79ac6aaa31 feat: migrate SMS/voice to Telnyx (TeXML), keep browser dial pad on Twilio
Twilio now handles only the in-browser dial pad (Access Token + browser-Device
outbound TwiML); Telnyx takes over SMS, inbound voicemail, the AI voice
conversation loop, and staff-triggered outbound calls via TeXML. Adds
TelnyxSettings model, Communication.provider discriminator, new comms/routes
modules, and a real Telnyx Settings page.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 15:39:43 -04:00
Gitead b899659e13 docs: add ngrok vs Cloudflare Tunnel comparison for Twilio tunneling 2026-09-02 22:59:25 -04:00
GiteadandClaude Sonnet 5 52ddfd9f57 feat: add Remaining/Third Party columns, toggle PDF viewer, retire CMSP as separate insurance type
- 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>
2026-09-02 22:32:43 -04:00
GiteadandClaude Sonnet 5 f8235787db fix: handle DDMA site redesign in eligibility check flow
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>
2026-09-01 21:20:38 -04:00
GiteadandClaude Sonnet 5 b860fd213f fix: allow chatbot auto-scheduling when eligibility status is UNKNOWN
Only block appointment creation on explicit INACTIVE status, since
scrapes for some plan types (e.g. MassHealth Child Medicaid) can land
on UNKNOWN without actually finding an ineligible record.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 20:39:57 -04:00
Gitead 116889dd4e perf: reduce fixed sleeps in MassHealth click_plus_button
Cuts unconditional delay when adding a service line from ~7s to ~3s
as a first pass at speeding up MassHealth claim submission.
2026-08-20 00:37:14 -04:00
GiteadandClaude Sonnet 5 ad9d311a99 fix: tolerate single-letter typos in CDT code text matching
Adds Levenshtein-based fuzzy word matching to lookupCdtCodes so
misspellings like "comprehensiv exam" resolve the same as
"comprehensive exam". Both the AI chat bot and the AI claim column
share this matcher, so the fix applies to both.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 00:01:41 -04:00
GiteadandClaude Sonnet 5 374f96399e docs: add fallback keyring-disable steps for when apt purge isn't enough
D-Bus service activation can respawn gnome-keyring-daemon even after
the package is removed and PAM/autostart hooks are disabled.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 23:45:06 -04:00
GiteadandClaude Sonnet 5 e934d6bce5 chore: gitignore GCP service account key in PaymentOCRService
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 23:43:15 -04:00
GiteadandClaude Sonnet 5 304441d95a fix: nginx proxy_pass uses 127.0.0.1 instead of localhost
localhost resolves to ::1 first; backend/Vite only bind IPv4, causing
intermittent 502s when nginx tried the IPv6 loopback address.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 23:41:10 -04:00
GiteadandClaude Fable 5 5044fecb07 fix: UnitedDH selenium duplicated first attachment (multi-file input appends on send_keys)
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>
2026-08-14 00:08:30 -04:00
GiteadandClaude Fable 5 efb85d0b92 feat: auto-confirm option for AI column claims (manual toggle + implied by Auto Claim)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 00:07:30 -04:00
GiteadandClaude Fable 5 ff79cd1643 fix: earliest patient record wins when duplicates share a phone (inbound SMS/voice)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 23:11:55 -04:00
Gitead 55d798b45f docs: add Google Cloud Vision setup section to root README
Fresh-machine setup guide didn't cover the Payment OCR Service's Google
Vision credentials — add it as its own section (enable API, create
service-account key, install as google_credentials.json, verify).
2026-07-30 23:52:37 -04:00
Gitead 9efa8f6e0a docs+perf: document Google Vision key setup, consolidate OCR calls per screenshot
- README: step-by-step Google Cloud Vision API key creation and setup
  (enable API, create service-account key, place as google_credentials.json)
- ocrLocate: split into getOcrWords()/matchWordsForText() so a screenshot is
  OCR'd once and matched locally against multiple text targets, instead of a
  separate billed Vision API call per target (patient-row and Exam steps each
  cut from 2-3 calls down to 1)
2026-07-30 23:27:33 -04:00
Gitead 5cdd3452f2 fix: use Google Vision OCR instead of AI-vision estimates for Windows Type Agent clicks
Claude vision's self-reported text coordinates had a small but consistent bias,
causing the patient-row double-click to land above the name and the Exam-column
divider count to occasionally miscount and hard-fail. Swap patient-row, Exam,
and Save button targeting to exact OCR bounding boxes (Google Vision via the
existing PaymentOCRService) instead of AI-estimated ratios.
2026-07-30 23:14:02 -04:00
Gitead 76bd99f7ff fix: Tufts SCO claim file attach — send_keys directly, skip button click
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.
2026-07-29 23:57:39 -04:00
Gitead 44c6d2f833 fix: Tufts SCO claim combobox selects matching option instead of first
_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.
2026-07-29 23:19:18 -04:00
GiteadandClaude Sonnet 5 6d0838446b fix: cascade-delete stale ClaimFile rows and sync claim attachments
Deleting/replacing an appointment attachment left an orphaned ClaimFile
copy behind (auto-linked earlier by autoLinkAppointmentFiles), causing
the Selenium claim automation to upload extra files beyond what's
currently attached to the appointment. Claim PUT was also append-only
for claimFiles, so removing an attachment in the UI never persisted.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 22:57:21 -04:00
GiteadandClaude Sonnet 5 65dc795eb2 fix: locate patient row by real text position, drop unreliable AI row-verify
Row selection previously computed the target row's y arithmetically
(header.y + rowHeight * rowIndex), which drifted further off-row the
deeper the target patient was in the filtered list, and an AI
"onTarget" verification step added to catch drift instead confirmed a
click point that was visibly in blank space below the grid.

locateAllOnScreenshot now reports each text match's top/bottom edges
instead of a self-estimated center, and the patient row step locates
the target's first and last name directly, pairing whichever
occurrences land on the same row instead of trusting arithmetic or a
qualitative AI judgment call.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 21:53:12 -04:00
GiteadandClaude Sonnet 5 ad2e15ec62 feat: window-diff-based Type Agent locating for Open Dental appointment flow
Replaces fragile whole-screen text matching with a screenshot-diff step that
finds each dialog's actual pixel bounds, then restricts every subsequent AI
locate/click to that cropped region — eliminating false matches from text
elsewhere on screen (title bars, side panels). Adds column-boundary and
row-height detection so the patient row and Exam procedure click positions
are computed geometrically instead of relying on repeated fuzzy AI guesses
for visually similar neighbors. Also adds per-run screenshot/debug-crop
backups and a structured run.log for diagnosing failed runs, plus a
cmd:move primitive on the Windows agent for pre-click confirmation crops.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-27 08:50:47 -04:00
GiteadandClaude Sonnet 5 59f064583a feat: AI Type Agent - vision-based Open Dental automation via Windows agent
Adds a Windows-side agent (screenshot/click/type over HTTP) plus backend
services to locate UI elements via vision and drive an existing-patient
appointment flow in Open Dental, wired into the Copy/Type Agent page and
socket progress updates.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 17:24:27 -04:00
Gitead ae961781ac fix: CCA preauth status stays Submitted (not Approved) and screenshot mime type
- ccaPreAuthProcessor: keep claim status as PREAUTH after successful
  submission instead of jumping straight to APPROVED, matching the
  Tufts SCO/UnitedDH/MassHealth preauth flows; also tag PNG fallback
  screenshots with image/png instead of the default application/pdf
  so they render in the Documents preview modal.
- claims-recent-table: add a PREAUTH status case so it displays as
  "Submitted" instead of falling through to the raw enum value.
2026-07-25 10:15:35 -04:00
Gitead f457d6282a fix: CCA claim submission grid targeting, retry, and dashboard claim-number lookup
- 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
2026-07-25 09:49:53 -04:00
GiteadandClaude Sonnet 5 d5cecb0b54 fix: only skip appointment-attachment merge when automated claim already has files
skipAppointmentAttachmentMerge was blanket-set for any autoSubmit path
(chatbot, Claim with AI batch automation, insurance-status auto-check),
so screenshots/files attached directly on the appointment were silently
dropped from the MassHealth Selenium upload whenever a claim was
auto-submitted. Now the merge is only skipped if the automated flow
actually supplied its own files.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 00:29:26 -04:00
Gitead 870bda5950 feat: chatbot screenshot-only eligibility detect, Sun Life/DentaQuest auto-check, chatbot attachment handoff to preauth; fix TuftsSCO preauth Selenium reliability
- 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
2026-07-25 00:10:05 -04:00
GiteadandClaude Sonnet 5 6b9b3c41f2 fix: skip appointment-file merge for chatbot claims; add live screenshot capture to chatbot
- selenium-claim route no longer re-appends previously saved appointment
  attachments when the chatbot's autoSubmit flow already sent every intended
  file, preventing an unwanted extra upload (e.g. attach 2 -> Selenium sees 3).
- Add a "Take screenshot" button to the AI chatbot's attachment bar, reusing
  the same capture/crop flow as the appointment editor, so claims and
  preauths can be submitted from the chatbot with a live screenshot attached.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 22:31:34 -04:00
GiteadandClaude Sonnet 5 a42ef5f570 fix: persist and correctly forward appointment attachments to insurance claims
- Add "surg ext" alias mapping to D7210 in the AI CDT lookup.
- Add GET/DELETE endpoints for appointment attachments, and load existing
  attachments in the appointment edit modal (they were uploaded correctly
  but never re-fetched, so they appeared to vanish on reopen).
- Fix claim-form.tsx so previously-saved appointment attachments are always
  loaded (even when a claim already exists) instead of only when creating a
  brand-new claim, preventing them from being silently wiped on save.
- Merge existing appointment attachments into every insurance submit handler
  (MassHealth, CCA, DDMA, UnitedDH, TuftsSCO) so Selenium submission always
  includes files saved earlier via the Schedule editor, not just files
  uploaded in the current claim-form session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 21:03:32 -04:00
Gitead ca568de817 fix: make chatbot patient-found DOB/Member ID editable and fix eligibility→appointment ordering
- 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.
2026-07-20 20:05:13 -04:00
GiteadandClaude Sonnet 5 b30bed8903 fix: match PDF-imported patients by member ID when DOB is missing on record
MassHealth eligibility lookups via the AI chatbot only matched existing
patients on memberId+DOB, so patients imported from PDF extraction (which
have a member ID but no stored birthday) were treated as new/unknown even
though they already exist in the system.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 11:11:47 -04:00
GiteadandClaude Sonnet 5 e49dfdbee9 feat: add attachment upload to Edit Appointment form (disk, scanned, screenshot with crop)
Lets staff attach files to an appointment directly from the edit form via
local disk upload, picking a previously-saved scanned attachment, or an
inline screenshot with crop-before-save (matching the Copy Agent page's
crop UX), instead of detouring through the Copy Agent page. Also fixes a
latent data-loss bug in claim-form's save-for-appointment call, which
replaced all AppointmentFile rows instead of merging with existing ones.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 14:55:38 -04:00
Gitead f29064883c feat: fall back to saved procedures for no-notes appointments in AI claim queue, and include appointment attachments in MH selenium submission
- AI claim queue now uses previously saved AppointmentProcedure data (with a derived insurance site key) when an appointment has no notes but has saved procedures, instead of skipping with "No notes on this appointment"
- selenium-claim route now reads saved AppointmentFile attachments from disk when they weren't re-uploaded in the browser, so images/PDFs already attached via "Select Procedures" reach the MassHealth submission
2026-07-17 00:30:03 -04:00
Gitead 5979d27c57 feat: add Preauth Followup section to claims page
Adds From/To date pickers and CCA PA / United PA / Tufts PA / All recent PA
buttons above the Upload claim documents section; button logic is stubbed
for now.
2026-07-16 23:00:46 -04:00
GiteadandClaude Sonnet 5 95abbabb36 fix: patient selection in appointment form disappearing for non-recent patients
Selecting a patient from search results only stored the ID, not the
patient object. Closing the dropdown reset the search term and reverted
the list to "recent 50" patients, which often didn't include the just
selected patient, leaving nothing to render in the trigger. Also removed
a redundant prefillPatient reset that nulled the fallback display before
the list swap even happened.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 22:39:55 -04:00
GiteadandClaude Sonnet 5 6004bcb73d feat: editable insurance type selector on eligibility confirm card
Lets a user override the default MassHealth check on the chatbot's
eligibility-id-ready confirm card (e.g. switch to United SCO, CMSP,
DDMA, Delta Dental, Tufts SCO, or CCA) before running the check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 21:47:20 -04:00
GiteadandClaude Sonnet 5 c95d08c951 feat: AI-powered eligibility detection from Copy Agent screenshots
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>
2026-07-16 21:20:33 -04:00
GiteadandClaude Sonnet 5 34312b62bc feat: add "Choose from Server" attachment picker to claim/preauth forms and chatbot
Native file inputs can't be pointed at a default server folder for security
reasons, so instead the Browse buttons on the Claim/PreAuth/Select Procedures
forms and the AI chatbot's attach button now also offer picking from
previously saved Cloud Storage attachments (e.g. Copy Agent screenshots) via
a new server-side picker modal, scoped per-patient on the claim forms and
unscoped (recent across all patients) in the chatbot.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-14 00:36:43 -04:00
Gitead c4c69bfd62 docs: document Twilio-only-scoped Cloudflare Tunnel variant
Adds the actual config used for Summit Dental Care, where the tunnel
points at nginx's port-80 Twilio-only block instead of the whole app,
so only /api/twilio/* is reachable from the internet.
2026-07-12 18:08:22 -04:00
Gitead 0d2fe63b9b docs: note disabling Apache before nginx install
We hit this exact conflict during setup (Apache pre-installed and
bound to port 80), so nginx failed to start until it was disabled.
2026-07-12 17:57:15 -04:00
Gitead 44dea49fd1 docs: add LAN HTTPS setup guide (nginx + certbot + Cloudflare DNS-01)
Documents the trusted-certificate setup used for local staff access,
needed because the Screen Capture API (Copy Agent screenshots) requires
a secure context.
2026-07-12 17:34:12 -04:00
Gitead f712479882 infra: serve app over HTTPS via nginx + Let's Encrypt for LAN access
getDisplayMedia (screen capture) requires a secure context, so LAN
staff access now goes through nginx on a real trusted cert
(local-summit.mydentalofficemanagement.com, issued via certbot's
Cloudflare DNS-01 plugin) instead of plain HTTP. A separate public
hostname/nginx block is reserved for Twilio webhooks only, routed
through Cloudflare Tunnel so nothing else is exposed to the internet.

Also fixes the backend CORS allowlist for the new hostname, and stops
the Socket.IO client from bypassing nginx to hit the backend directly
on :5000 (which broke under TLS/mixed content).
2026-07-12 17:25:30 -04:00
Gitead 118315a04e feat: add screenshot capture to Copy Agent page
Staff can now capture their screen via the browser's Screen Capture
API, crop the result, name the file, and save it directly to a
selected patient's Cloud Storage attachments folder.
2026-07-12 17:25:12 -04:00
GiteadandClaude Sonnet 5 58d56c895b fix: batch-column claims dropped attachments for DDMA/TuftsSCO/UnitedDH
filesForQueue was collected from AppointmentFile/ClaimFile records but only
wired into the MH and CCA job payloads. The other three insurers' Selenium
workers read claim.claimFiles and always got an empty list, so attachments
already saved to Cloud Storage silently never got attached to the claim.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-11 23:10:02 -04:00
Gitead 3c650997f4 fix: use static rotating greeting list instead of AI-generated login greeting 2026-07-09 22:28:57 -04:00
Gitead b49877af52 docs: add Development Hosts & Ports section to README 2026-07-08 23:27:35 -04:00
GiteadandClaude Sonnet 5 f52b1b03ba fix: dual/CMSP PDF viewer panels stayed blank for cloud-backed PDFs
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>
2026-07-08 14:50:00 -04:00
GiteadandClaude Sonnet 5 0f0f3a6db9 fix: two bugs in Cloud Storage PDF viewing surfaced by live testing
- PDF viewer hung on "Loading" forever for cloud-backed PDFs: streamFileTo
  pipes with {end: false} (by design, so cloud-storage.ts's own routes can
  call res.end() themselves), but the new /pdf-files/:id cloud branch never
  did, so the HTTP response never completed.
- Documents page showed nothing for patients whose PDFs are only in Cloud
  Storage: the page lists categories from the legacy PdfGroup table, which
  new saves stopped populating. savePdfToCloudStorage now also ensures a
  blob-less PdfGroup row exists per patient/category so the category still
  appears, with actual files served from Cloud Storage via the existing
  merge in the pdf-files/group listing routes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-08 14:36:02 -04:00
GiteadandClaude Sonnet 5 3582da8510 fix: update DDMA claim submit worker for new deltadentalma.com claims-submission flow
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>
2026-07-08 00:22:35 -04:00
GiteadandClaude Sonnet 5 99cdfa702a feat: save insurance PDFs (eligibility/claims/preauth) to Cloud Storage instead of Postgres blobs
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>
2026-07-08 00:20:37 -04:00
GiteadandClaude Sonnet 5 1190bc0494 feat: split AI Input Agent into Copy/Type Agent submenu with settings
Renames the sidebar entry to "AI Copy/Type Agent" with Copy Agent, Type
Agent, and Settings sub-pages. Settings shows the server's LAN IP
address (via a new /api/ai/network-info endpoint) since it changes
depending on which office the app is running in.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-07 16:40:24 -04:00
GiteadandClaude Sonnet 5 802dbedbfb chore: add rclone sync configuration state file
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 00:24:08 -04:00
GiteadandClaude Sonnet 5 ed72d7e95f feat: seed User1 default regular user alongside admin
Adds a second seeded account (User1/123456) so a non-admin login exists by default for testing role-based UI restrictions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 00:23:03 -04:00
Gitead 877feb32fa fix: update DDMA eligibility check worker for new deltadentalma.com sign-in and search flow
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.
2026-07-04 22:57:59 -04:00
Gitead 79bae13f35 fix: dedupe claim attachments to prevent duplicate uploads to insurance
Claim attachments were being appended without checking for existing
duplicates, causing files (e.g. the same PDF) to be sent to the
insurance clearinghouse multiple times.
2026-07-04 14:17:40 -04:00
GiteadandClaude Sonnet 5 e7d610b970 fix: update project folder name to DentalManagementMH07 in shortcut scripts
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-03 23:04:29 -04:00
GiteadandClaude Sonnet 5 8eb2bceabb docs: add nginx install instructions to README step 12
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-03 22:36:34 -04:00
GiteadandClaude Sonnet 4.6 e60110226b chore: remove all .jsx files from Frontend src
Vite resolves .tsx before .jsx (per extensions order in vite.config.ts),
so .jsx files were never loaded at runtime. Switching to TSX-only source.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 21:40:59 -04:00
GiteadandClaude Sonnet 4.6 00fd213291 feat: add Dental Office Name to Lab RX form, pre-filled from office contact settings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 21:21:59 -04:00
GiteadandClaude Sonnet 4.6 191ed129d8 feat: replace DOB with Age in Lab RX form, auto-calculated from patient DOB
Age is pre-filled when opening the RX popup by calculating from patient.dateOfBirth.
The field is editable in case of override. Both preview card and print output
now show Age instead of DOB.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 21:06:44 -04:00
GiteadandClaude Sonnet 4.6 305a07874d fix: add selenium-settings-card.jsx and wire it into settings-page.jsx
selenium-settings-card.jsx didn't exist and settings-page.jsx was missing
the import and case "selenium" handler, so the Selenium settings section
was invisible on other PCs running the .jsx files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:13:49 -04:00
GiteadandClaude Sonnet 4.6 6e779fc630 fix: update lab-management-tab.jsx and add lab-rx-modal.jsx
JSX files were missing the Lab RX feature — lab-management-tab.jsx still had
the old lab order table UI, and lab-rx-modal.jsx didn't exist. The app on
other PCs runs .jsx files, so git pull wasn't showing the new Lab RX feature.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 00:12:10 -04:00
GiteadandClaude Sonnet 4.6 ce2e03e505 feat: pre-fill doctor name with default NPI provider in Lab RX popup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:55:23 -04:00
GiteadandClaude Sonnet 4.6 75ecd7cc20 feat: add Selenium Settings page to configure paymentGroupId per office
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>
2026-07-02 23:53:43 -04:00
GiteadandClaude Sonnet 4.6 abb2a0ac96 feat: add Lab RX feature with template management and auto-seed defaults
- New lab_rx_template table with sortOrder and Prisma migrations
- Backend CRUD + reorder routes at /api/lab-rx/templates
- Auto-seeds 3 Highland Dental Studio defaults on first use per user
- LabRxModal: template picker, inline rename, up/down reorder, full
  template form with sections (Template Name / Lab Info / Case Details)
- RX popup: Tooth Number, Shade, Due Date, Doctor (from NPI providers),
  Instructions pre-filled with "Please make / Thank you!", print output
- lab-rx-templates.ts config file for future git-managed additions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:20:44 -04:00
GiteadandClaude Sonnet 4.6 ac4d8c4c74 feat: add lab management layout, barcode generation, and dental education page
- Redesign lab management tab with patient search table and action buttons
- Add react-barcode integration: generates CODE128 barcode from patient name with print and download support
- Add Dental Education page and sidebar entry between Cloud Storage and AI Input Agent

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 13:03:58 -04:00
GiteadandClaude Sonnet 4.6 998ef0ac95 feat: add POE and period exam aliases → D0120 in CDT lookup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 23:58:56 -04:00
GiteadandClaude Sonnet 4.6 15a1091f35 fix: stop premature chatbot claim queue advance + skip preview popup mid-batch
handleClaimSubmit advanced the chatbot batch claim queue right after creating
the DB claim record, before the Selenium job even ran. This caused only the
last patient in a multi-patient claim batch to get its PDF saved to
Documents — earlier patients' job tracking got overwritten by the next
patient's submission before their PDF download could complete.

Also make advanceChatbotClaimQueue() report whether it navigated to another
queued patient, and skip the auto PDF preview popup in that case so it only
opens for the last/standalone claim.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 23:44:21 -04:00
GiteadandClaude Sonnet 4.6 26da3394aa fix: extract appointmentDate for multi_claim/batch_claim/preauth intents
The classifier prompt only told the AI that appointmentDate applies to
schedule_appointment/claim_only/check_and_claim, so a trailing date like
"all on 6/23/26" was dropped for multi-patient claims even though the
workflow already reads c.appointmentDate for those intents and silently
defaulted to today.

Also add Prisma config/seed scripts and shopping-vendor types/schema updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 22:52:48 -04:00
GiteadandClaude Sonnet 4.6 cdda91f2b4 feat: add multi_claim intent for different procedures per patient + fix batch claim PDF race
- 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>
2026-06-29 01:08:41 -04:00
GiteadandClaude Sonnet 4.6 cb49298b66 fix: teach AI to recognize recement and fix missing service date in column claim
Add "recement" example to LLM classifier so it spreads across multiple
teeth (recement #5, #3 → two D2920 entries). Add "today" to the AI
column claim message so the LLM sets appointmentDate instead of asking
"Which service date?"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 00:02:26 -04:00