Commit Graph

172 Commits

Author SHA1 Message Date
ff
fd4feb3e76 feat: AI claim queue auto-return + D1120 age warning
- 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>
2026-06-12 22:18:59 -04:00
Gitead
831f67b093 feat: chatbot CDT lookup — SRP quad, 4-digit auto-prefix, quad field to Selenium
- 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>
2026-06-11 22:14:50 -04:00
Gitead
6cfca0d015 feat: select DDMA provider by NPI settings instead of always first
Pass the user's primary NPI provider name through the eligibility and
claim routes so the Selenium workers click the matching option in the
DDMA member-search provider dropdown (data-testid=member-search_provider_select-btn)
rather than always falling back to the first entry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 15:32:01 -04:00
Gitead
75c49ab1df feat: chatbot rendering provider override and NPI provider ordering
- AI chat extracts 'with provider <name>' and routes claim to that provider
- Claim form reads provider from sessionStorage before any async effects run,
  preventing saved claim/procedure data from overriding the chatbot selection
- NPI provider settings table shows Provider #1 / #2 labels with up/down
  reorder buttons; Provider #1 is always the default for claims
- Default provider now uses sortOrder instead of hardcoded 'Mary Scannell'
- Added sortOrder column to NpiProvider schema with migration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 13:17:05 -04:00
ff
d4b9c1b889 feat: save claim attachments to cloud storage and documents page
- 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>
2026-06-11 00:30:32 -04:00
ff
46daeb1c1f feat: implement Claim for Column with AI queue logic
Sequential AI-assisted claim flow:
- Filters unclaimed appointments in selected columns
- Calls /api/ai/internal-chat to interpret appointment notes into CDT codes
- Shows per-appointment confirmation modal (patient name, notes, matched codes)
- Confirm → stores chatbot_claim_prefill + navigates to claims page for Selenium
- Skip → moves to next appointment
- Queue persisted in sessionStorage; auto-resumes on return to schedule page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 22:00:46 -04:00
ff
b986350edd feat: add Claim for Column with AI button to schedule page
UI-only stub — logic to be defined. Mirrors the existing Claim for
Column section with its own column checkboxes and loading state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 21:27:05 -04:00
Gitead
949e64c129 fix: add migration for missing ai_settings columns
The original migration only created the table with id/userId/apiKey.
All provider keys, models, toggles, and feature flags were in the
schema but never added to the database, causing every AI settings
save to fail with a Prisma column-not-found error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:46:52 -04:00
ff
facf9e79e2 fix: show only user-typed notes on appointment card
Remove auto-appending of "Appointment with [staff name]" to notes on
save, and preserve existing notes when dragging an appointment to a
new slot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 21:48:17 -04:00
ff
541d65da6d feat: AI chat Eligibility & Appointment button with 15-min slots and Column B fallback
- 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>
2026-06-09 16:14:08 -04:00
ff
a8ec1a21c0 feat: include uploads folder in network sync (all three subfolders)
Daily sync and Sync Now both pull database + uploads in one operation.
PC1 streams uploads/ as a zip via GET /network-backup-files (archiver).
PC2 clears cloud-storage, patients, and patient-documents then extracts
the fresh copy before resolving. Timeout extended to 5 min for large files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 10:10:46 -04:00
ff
f5f3768108 feat: add Network Backup section to Database Management
PC2 can now automatically pull and restore a fresh copy of PC1's database
on a daily schedule. Config and API key are stored in local JSON files so
they survive database restores.

- New networkSyncConfigService: file-based config (network-backup-key.json,
  network-sync-config.json) that persists through DB restores
- New networkSyncService: streams live pg_dump from source PC over HTTP and
  pipes into psql, then reconnects Prisma and applies missing migrations
- 6 new endpoints: get/regenerate API key, serve backup stream (key-auth
  only), get/save sync config, trigger immediate sync
- Hourly cron job that fires only when current hour matches configured syncHour
- NetworkBackupManager component: shows this machine's key (show/copy/regen)
  and receiver config (enable toggle, hour picker 0-23, source URL + key,
  Save + Sync Now, last sync status)
- README setup guide for both PCs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 00:15:42 -04:00
ff
27d95ed752 fix: add United Healthcare SCO aliases so AI chat routes to UnitedDH worker
"United Healthcare SCO" does not contain the substring "united sco" so
deriveSiteKey was falling through to the MH default. Add exact and prefix
aliases so any United Healthcare variant maps to UNITED_SCO.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 23:25:02 -04:00
ff
09cd0328cb fix: recognize CDT codes with primary tooth letter notation (# H)
extractToothSurface now handles A-T primary tooth letters in addition to
numeric #1-32. strippedCleaned strips both formats so "D7111 # H" reduces
to "D7111" for the CDT pass-through. Pass-through no longer returns null
for codes not in the fee schedule JSON.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 00:28:56 -04:00
ff
967a53fc6c feat: AI chat file uploads, RCT/PA tooth mapping, check+claim flow, service date column
- 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>
2026-06-07 23:47:48 -04:00
ff
19bb5c1145 feat: route MH eligibility to CMSP button for patients under 21 in AI chat
siteKeyToAutoCheck now accepts an optional dob parameter. When siteKey is MH
and the patient is under 21 years old, returns "cmsp" so the AI chat triggers
the CMSP eligibility & history & remaining button instead of the adult MH one.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 00:44:09 -04:00
ff
cb1c6cef3b fix: click tooth dropdown chevron button to open 1-32 listbox, then select by number
Instead of typing into the combobox, find the toggle button ("^" icon) in the
same container as the tooth input and click it via JS to open the dropdown.
Tries progressively wider ancestor scopes (1-5 levels up) to locate the button,
falls back to JS focus if none found. Then selects the exact tooth number from
the listbox options.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 00:33:15 -04:00
ff
730c41f9b0 fix: DDMA Create claim stale element, tooth dropdown select, longer page waits
step2: wait for patient list //tbody//tr then 3s stabilize; wait for patient
name link to be element_to_be_clickable before reading href; wait for Create
claim button to be element_to_be_clickable (visible+enabled) then 3s for React
to finish re-rendering.

step3: re-find Create claim button fresh each attempt (avoids stale element
from React re-render); try selenium click → js events → js.click() in sequence;
verify URL changed before declaring success.

step4: open tooth dropdown via JS focus (avoids element-not-interactable on
click); select the matching tooth number option directly from 1-32 listbox
instead of typing characters.

step7: find Submit claim button with individual XPaths to avoid NoneType crash.

claims-page: use wouter setLocation for URL param cleanup so internal search
state stays in sync.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 00:28:01 -04:00
ff
d02e8c8dcb fix: extract tooth number and surface from #NN notation for all DDMA procedures
Added extractToothSurface() helper that parses "#NN [SURFACES]" from any
procedure input (tooth 1-32, surface letters O/M/D/B/L/F/I/V). Applied to
all lookup paths so any procedure with #14 or #29 OB carries toothNumber and
toothSurface through to the DDMA Selenium worker.

Also propagate toothNumber/toothSurface in matchedCodes and chatbot_claim_prefill
so the claim-form prefill sets these fields on the service lines before auto-submit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 23:31:22 -04:00
ff
905e236166 fix: claim confirm card was storing autoSubmit=false, blocking Selenium auto-start
The green claim confirmation card in the chatbot was saving autoSubmit:false
to sessionStorage, so claims-page.tsx never set chatbotAutoSubmitSiteKey and
ClaimForm received autoSubmit=false, leaving Selenium unstarted after form fill.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 23:14:46 -04:00
ff
86cf55aa4d feat: AI chat claim confirmation, CDT alias learning, and eligibility auto-trigger fixes
- Claim flow: show green confirm card (patient, CDT codes, service date) before Selenium starts
- CDT lookup: add DIRECT_CODE_MAP + ALIAS_MAP with 60+ dental abbreviations from office fee schedule
  (2BW→D0272, 4BW→D0274, PA→D0220, FL→D1208, RCT codes, composite tooth#/surface parser, etc.)
- Composite filling parser: auto-map "#29 OB" → D2392 based on tooth# (front/back) and surface count
- Ask-and-learn: unknown CDT terms block claim and ask user; answer saved to DB alias map for future use
- Cancel on confirm card returns to chat (not full reset) so user can correct and retry
- Eligibility auto-trigger fix: reset autoTriggeredRef when autoTrigger resets to false so second
  chatbot eligibility check on same page visit fires correctly (all 5 provider buttons fixed)
- check_eligibility by name now returns eligibility_id_ready with correct siteKey for non-MH patients
- DDMA/CCA/United/Tufts fee schedules updated with office prices (single Price field, no age split)
- getCodeMap case-insensitive matching fix (ddma/cca/etc. now correctly selected)
- Family plan member disambiguation: insuranceId+DOB composite lookup prevents overwriting siblings
- AI chat date fix: send clientDate from browser to avoid UTC midnight rollover (EST→wrong day)
- AI prompt: appointmentDate extracted for claim_only intent when user says "today" or a date

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 21:11:58 -04:00
ff
4899ab8368 feat: multi-provider AI support with per-provider model selection
- Add llm-factory.ts: unified LLM provider abstraction (Google/Claude/OpenAI)
- Install @langchain/anthropic and @langchain/openai packages
- resolveAiProvider picks active provider from DB settings (Claude > OpenAI > Google)
- All AI graphs (reminder, new-patient, reschedule, internal-chat) now accept provider+model params
- Add claudeAiModel, openAiModel, googleAiModel columns to ai_settings table
- New PUT /api/ai/provider-model route to save selected model per provider
- UI model dropdowns for Claude (Haiku/Sonnet/Opus), OpenAI (GPT-5.x series), Google (Gemini 2.5/3.x)
- Google AI section also gets model selector alongside existing API key field

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 09:34:11 -04:00
ff
d5bc96ff39 feat: add per-patient Local folder in Documents page backed by Cloud Storage
- Documents page shows a "Local Folder" card for each selected patient
  with an "Open in Cloud Storage" button that deep-links to their folder
- Cloud Storage page reads ?folderId URL param on mount and auto-opens
  the folder panel for seamless navigation from Documents
- Backend: GET /api/cloud-storage/patient-folder/:patientId endpoint
  that idempotently gets or creates a top-level CloudFolder per patient
- CloudFolder schema gains optional patientId field linked to Patient
- Disk directories for cloud storage folders now use the folder's name
  (e.g. "Xiaohui Wang/") instead of the opaque "folder-{id}/" path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 23:01:56 -04:00
ff
2457e12b5c feat: AI API Setting page with 4 provider sections and toggles
Add OpenAI, Claude AI, and DentalManagement AI sections to the AI API
Setting page, each with a masked API key input and an on/off toggle
(defaulting to off). Rename sidebar label from "Google AI Settings" to
"AI API Setting". Add provider-key and provider-enabled backend endpoints
and extend the AiSettings schema with 6 new fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 16:36:01 -04:00
ff
1bbca38344 feat: AI chat scheduling, claim automation, and session improvements
- 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>
2026-06-05 16:19:56 -04:00
Gitead
ba2882957a feat: Users AI Chat multi-step workflows with CDT lookup and alias management
- Add eligibility_by_id and check_and_claim intents to internal chat
- New cdt-lookup.ts: keyword search against fee schedule JSON (no LLM)
- New internal-chat-workflow.ts: deterministic orchestration — patient
  resolution, insurance siteKey derivation, CDT code mapping
- Custom CDT aliases stored per-user in DB (TwilioSettings JSON blob)
  with GET/PUT /api/ai/cdt-aliases endpoints
- Chatbot UI: new steps for eligibility-id-ready, check-and-claim-ready,
  and need-insurance-clarification with insurance picker
- Settings UI: CDT Aliases CRUD table with built-in alias reference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 17:44:19 -04:00
Gitead
4274cd61dc fix: ensure appointment is created before saving claim from claims page
- mutationFn now throws on non-ok responses so failed appointment
  creation (409 no slots, 400 validation) properly rejects instead of
  silently calling onSuccess with no id
- handleAppointmentSubmit rejects if server returns success but no id
- invalidate QK_APPOINTMENTS_BASE cache after successful appointment
  creation so the appointments page refreshes automatically

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 00:15:44 -04:00
ff
bcf4111cdf feat: auto-logout after 1 hour of inactivity
Tracks user activity events (mouse, keyboard, scroll, touch) and resets
a 60-minute idle timer on each event. Shows a warning toast at 55 minutes,
then calls logoutMutation at 60 minutes to clear the session.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 23:56:21 -04:00
ff
57c18b404f fix: BCBS MA — wait for ccProgressBar spinner cycle before clicking buttons
Use appear-then-disappear pattern: briefly wait for spinner to show up
(so we don't pass through before it starts), then wait for it to clear.
Prevents element click interception on Find Provider button in step2.
Also restores element_to_be_clickable for New Eligibility Request (step1).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 23:53:46 -04:00
Gitead
4a1fd27870 fix: broaden XPath and add fallback for BCBS MA New Eligibility Request click
The exact ng-click='newEligibility();' XPath was failing to match the link.
Replaced with three alternative patterns (partial ng-click, full text, partial
text), added a JS-click fallback for intercepted clicks, and auto-re-opens the
Verification dropdown if it closes before the link is found.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 22:26:07 -04:00
ff
ddcc49b72c feat: add in-browser dial pad with Twilio Voice SDK
- New DialPad component on Patient Connection page: clickable keypad,
  call/hangup/mute buttons, duration timer, keyboard input support
- Backend: POST /api/twilio/voice-token issues Access Token for browser
  Device; POST /api/twilio/webhook/voice-browser is the TwiML webhook
  Twilio calls to bridge the browser to the patient's phone
- TwiML App SID field added to Twilio Settings (stored in templates JSON)
- README: one-time Twilio Console setup instructions for the dial pad

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 22:24:53 -04:00
ff
be90966f6e feat: add internal AI chat assistant and AI Input Agent page
- Add Gemini-powered internal staff chatbot (free-text input in the
  upper-right bot panel): type "check MARIA GONZALES" to search patient
  and pre-fill eligibility, or "open claims" to navigate directly
- Add /api/ai/internal-chat endpoint with LangGraph + Google Gemini
  classifier (intent: check_eligibility, find_patient, navigate_*)
- Add Users AI Chat settings section in Settings > Advanced > AI Chat
  to configure a custom system prompt for the internal assistant
- Store internal chat system prompt in existing twilioSettings JSON
  blob (no DB migration needed)
- Add AI Input Agent sidebar entry and placeholder page describing
  planned keyboard-automation typing into Open Dental / Eaglesoft

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 00:44:05 -04:00
ff
3ac185b0ec fix: BCBS MA — identify patient by member ID + DOB, prevent overwriting subscriber
- Added getPatientByInsuranceIdAndDob to storage
- Processor uses insuranceId + DOB as unique key instead of insuranceId alone
- Dependent with same subscriber ID but different DOB gets a new patient record
  (bypasses createOrUpdatePatientByInsuranceId which would overwrite subscriber)
- Name extraction anchored to "Relationship:" to scope Patient Info column only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 23:51:11 -04:00
ff
87d7ce9ed9 fix: BCBS MA eligibility — name extraction, tab switching, DOB input, button color
- Extract patient first/last name from Patient Information DOM section
  (scoped to avoid duplicate Subscriber Information column values)
- Switch to latest tab at start of step2 (Eligibility Identifier opens in new tab)
- DOB: double-click + ActionChains.send_keys (no pyperclip, avoids Chrome crash)
- BCBS MA button changed to variant="default" to match nearby buttons
- Backend processor uses extracted names from selenium result

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 01:18:20 -04:00
ff
e644d21cee feat: add BCBS MA eligibility check with OTP flow
- 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>
2026-06-01 00:36:11 -04:00
ff
535619c286 feat: make claim number editable in Edit Claim Status modal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 23:44:55 -04:00
ff
acd0e74cab fix: increase claim search page wait times in UnitedDH claim worker step9
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 23:07:30 -04:00
ff
4bf8cb1a94 feat: schedule page UX improvements + CDT combo price skip
- Move Select Procedures above Check Eligibility in appointment right-click menu
- Show 3 blank service lines by default when opening Select Procedures with no saved procedures
- Fix serviceLines not being preserved when API returns empty procedures list
- CDT combo buttons no longer auto-fill price (only fill codes); user maps price via Map Price button
- Overlap detection in schedule: shorten earlier appointment display span when a later one starts within its range
- Procedures dialog: replace single manual-add row with 3 pre-filled blank rows grid + Add Line / Save Lines buttons

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 19:37:12 -04:00
ff
70f36fc13c feat: United SCO claim worker rewrite + eligibility/patient-table fixes
- Rewrote UnitedDH claim worker to navigate via eligibility page → Selected Patient → Submit Claim button flow
- Updated helpers_uniteddh_claim.py step names to match new 9-step workflow
- Changed payer selection in both eligibility and claim workers to type + Enter
- Updated patient table column header from 'DOB / Gender' to 'DOB'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 14:46:51 -04:00
ff
cda00f5f8a fix: restore Continue button as page indicator in claim step3 to prevent browser close
Using paymentGroupId label as the page-load wait caused TimeoutException when
the claim flow's page structure differed, returning ERROR and triggering
_minimize_browser (about:blank + minimize). Now waits for the btn-primary
Continue button (original safe indicator) and wraps both dropdown selections
in try/except so the step never fails due to a missed dropdown.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 22:26:21 -04:00
ff
72b204f33f fix: apply Treatment Location + Billing Entity selection to United SCO claim worker
Mirrors the same Provider & Location page pattern from the eligibility worker:
- wait for paymentGroupId label visibility before interacting
- Treatment Location: ng-arrow-wrapper click + ARROW_DOWN/ENTER
- Billing Entity: ng-arrow-wrapper click + ARROW_DOWN/ENTER
- re-find Continue button after selections to avoid stale element

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 18:10:45 -04:00
ff
c952f79853 fix: United SCO provider/location page selection + DOB display format
- United SCO eligibility: add Treatment Location step before Billing Entity
  on Provider & Location page; both use ng-arrow-wrapper ActionChains click
  + ARROW_DOWN/ENTER keyboard selection to handle upward-opening panels
- Use visibility_of_element_located for Billing Entity label wait so code
  waits for page to fully render after Select Insurance modal closes
- DOB (and all dates) now display as MM/DD/YYYY instead of Mon DD, YYYY

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 18:04:16 -04:00
ff
0b7b12eb4c fix: preserve DentaQuest cookies on startup so OTP trust survives restart
DentaQuest stores its MFA trust as a persistent cookie, not in
LocalStorage like DDMA/Azure B2C. Deleting the Cookies file on startup
wiped that trust token, forcing OTP on every app restart. Now only the
credentials tracking file is reset on startup; if credentials change,
_force_logout() still calls delete_all_cookies() for a full reset.

Covers both eligibility and claim flows (both share the same
DentaQuestBrowserManager singleton).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 14:38:55 -04:00
ff
9d0cfe5dba feat: appointment type inference, procedure codes on cards, claim attachment fixes
- Add appointment type categories matching insurance claim form (recall, filling, pedo, dentures, implant, endo, crown, perio, extraction, ortho, consultation, emergency, other)
- Auto-infer appointment type from CDT codes with priority rules (endo > implant > crown > ...)
- typeLocked flag prevents auto-overwrite when user manually sets type
- Show appointment type label and procedure codes on schedule cards
- Background sync on /day route retroactively fixes stale appointment types
- Fix PUT /api/claims/:id to save claimFiles (previously silently dropped)
- Auto-link AppointmentFile records to ClaimFile when claim is created or updated
- Fix D5750 (denture reline) CDT range to map correctly to dentures category
- Fix typeLocked Zod rejection in appointment update route

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 14:18:10 -04:00
ff
b20dc8e976 fix: D0140 claim sync, schedule column prefill, multi-appt, DentaQuest OTP session
- Fix Express route ordering in appointments-procedures so /prefill-from-appointment
  is matched before /:id (D0140 and other codes now always reach the claim)
- claim-form: always fetch AppointmentProcedure records when an existing claim loads
  so post-save procedure edits (e.g. adding D0140) are reflected immediately
- appointments-page: replace sessionStorage with React state (newApptPrefill) for
  slot-click prefill so columns B-F correctly carry their staffId into the form
- add-appointment-modal / appointment-form: thread prefillData prop; add
  NewAppointmentPrefill interface; useEffect applies values via setValue
- appointments upsert: remove per-patient dedup so the same patient can have
  multiple appointments on the same day in the same column
- DentaQuest / TuftsSCO: navigate to about:blank and minimize instead of
  quit_driver after each run — session cookie stays in memory so OTP is only
  required once per app startup, not on every eligibility or claim check

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 15:39:36 -04:00
Gitead
0b3cc241bf fix: broaden XPath for United SCO Select Insurance OK button
Use normalize-space(.) instead of text() to capture button text inside
child elements, add modal-scoped fallback selectors, and prefer JS click
to avoid overlay interception.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 23:30:00 -04:00
ff
3e61bdec36 feat: route batch-column claims by insurance type, fix eligibility UX
- claims.ts: batch-column now routes each patient to the correct portal
  (MH/CCA/DDMA/TuftsSCO/UnitedSCO) based on patient.insuranceProvider
- appointments-page.tsx: eligibility badge falls back to patientStatus
  for all insurance types, not just MassHealth
- unitedDHClaimProcessor/ddmaClaimProcessor/tuftsSCOClaimProcessor:
  auto-save claim PDF when no socketId (batch-column path)
- unitedSCOEligibilityProcessor: unknown eligibility no longer stored as INACTIVE
- queues.ts: add tuftssco-claim-submit and uniteddh-claim-submit to SeleniumJobType
- selenium_UnitedSCO_eligibilityCheckWorker.py:
  - step1: add Select Insurance OK click with staleness wait; Provider &
    Location page just clicks Continue; skip first/last name input
  - step2: extract name from eligibility details tab (ALL CAPS → title case);
    skip "not available" guard; fix name regex to match only all-caps words
- .gitignore: ignore all chrome_profile_* directories

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 23:07:42 -04:00
ff
080b0c65b8 fix: correct license key part count validation (5 not 6)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 21:50:30 -04:00
ff
070752380d feat: add license activation system with feature gates
- License key generator tool at ~/Desktop/LicenseGenerator
- Backend validator route (GET /api/license/status, POST /api/license/activate)
- Activation page in sidebar with status, key input, and free/premium feature list
- useLicense hook for frontend license state
- Feature gates: premium eligibility buttons (DDMA, DeltaIns, Tufts, United, CCA) disabled without license
- Feature gates: premium claim buttons (CCA, Delta MA, United, Tufts) and all PreAuth buttons disabled without license
- Free features always active: MassHealth eligibility/claim, Documents, Payments, Backups, Reports
- README: license key generator usage instructions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 21:22:34 -04:00
ff
816d9e0ee7 feat: make Cloudflare host configurable per office via env
Each office sets VITE_CLOUDFLARE_HOST and CLOUDFLARE_HOST in their
local .env files instead of hardcoding the subdomain in source code.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 11:55:28 -04:00