Commit Graph
174 Commits
Author SHA1 Message Date
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
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 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
ff 41bed21302 feat: send appointment confirmation SMS after AI-booked appointments
Voice-call bookings previously only spoke the confirmation during the
live call, leaving nothing for the patient afterward. Now every
successful booking (recall, reschedule, and new-patient) also sends a
standalone confirmation text, regardless of which channel the
conversation happened on.
2026-08-07 00:28:56 -04:00
ff 67e71a02e4 fix: AI recall follow-up message repeats "Great" and buries office hours
When the AI rejects a requested time in the recall booking flow, it reused
the same "Great, what time..." template used for a fresh ask, producing an
awkward double-greeting right after a rejection, and appended office hours
as a bare fragment instead of framing them as a sentence.
2026-08-07 00:07:10 -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
ffandClaude Sonnet 5 0cd095330a fix: AI recall-call flow, speech-to-text time parsing, and stale conversation state
- Reset conversation stage to a fresh start on every new voice call
  (recall and reminder alike), and on every hangup/timeout/goodbye,
  so an abandoned or completed call never leaves a patient stuck
  mid-flow for their next call or text.
- Add a staleness check to the SMS flow: after a long idle gap,
  check whether the patient's reply still reads as a continuation
  before resuming the stored stage, falling back to a friendly
  "it's been a while" re-greeting when unsure.
- Fix parseTime() to handle Twilio's speech-to-text output, which
  renders "pm"/"am" with periods and often drops the colon in a
  spoken time (e.g. "100 p.m." -> 1:00 PM) — this was silently
  failing and causing the AI to loop asking for a time it had
  already been given.
- Extend the voice Gather timeout so the AI doesn't hang up on a
  patient who just needs a few seconds to respond.
- Reword the recall-call opening line and rework the post-"yes"
  prompt to ask for day and time together.
- Fix rclone WebDAV server to serve only the backups folder instead
  of the entire backend app directory (was exposing .env and source).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 09:35:48 -04:00
ff 55ce52f276 fix: patient language field silently dropped by stale browser-side validation schema
packages/db/usedSchemas/browser.ts (the browser-resolved copy of the Patient
zod schema, kept separate from the Node copy since it can't import
Prisma-generated code) was missing several fields added to the real schema
over time — preferredLanguage, gender, insuranceProvider, insuranceId,
groupNumber, policyHolder, and the PLAN_NOT_ACCEPTED status. Since the schema
isn't strict, those fields were silently stripped from every patient
create/update in the browser with no validation error, so edits to them
never reached the server.

Also fixes the AI call greeting always playing in English regardless of the
patient's preferred language — the greeting text was a single hardcoded
string, unlike every later turn in the conversation which already branched
by language.
2026-08-05 21:40:53 -04:00
ffandClaude Sonnet 5 cef928be97 feat: add AI recall calling — books existing patients for routine cleanings
Adds a new recall conversation flow (recall-graph.ts) triggered from the
Patient Connection "AI Call" button: offers an existing patient a routine
exam & cleaning, classifies their yes/no reply, then books directly onto
the schedule (Column A, 30-minute slots, real conflict checking against
office hours and existing appointments) instead of only capturing a
preference for staff to follow up on.

Also adds a "Voice call" label in the message thread to distinguish call
transcripts from SMS, and updates the Call Templates settings UI with an
editable recall greeting.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-02 23:13:09 -04:00
ffandClaude Sonnet 5 06dc63c53e feat: unify AI voice calls with SMS conversation rules, add Call Templates
AI phone calls now route through the same routePatientTurn() rule engine
as SMS (office-hours checks, slot-conflict checks, MassHealth eligibility,
staff escalation) instead of a freeform LLM chat, and speak in the
patient's preferred language (English/Spanish). Adds a separate "Call
Templates" settings section so spoken wording can be customized
independently from SMS wording.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 23:39:31 -04:00
ffandClaude Sonnet 5 089e94ba88 feat: add AI-driven phone calls to patient connection
Adds an "AI Call" option alongside Call/SMS/Chat that places an outbound
call where Lisa converses live with the patient via Twilio speech
gather + TTS, using the same conversational AI as chat. Includes a
separate, user-editable Call Template (Settings > AI Chat/Call Settings)
so the call greeting can be customized independently of SMS templates.

Also fixes the outbound-call webhook URL to always use the fixed public
Twilio hostname (CLOUDFLARE_HOST) instead of deriving it from the
triggering request, since staff-browser requests arrive over the
LAN-only hostname, which Twilio can never reach.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 20:14:09 -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
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 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
ffandClaude Sonnet 5 b1932fa3d6 feat: add Provider field to appointment form, drive AI claim automation
Adds an optional Provider (NPI) select to the Edit Appointment form,
sourced from Settings > NPI Providers. The AI "Claim for Column" batch
flow now prefers the appointment's own provider when resolving which
provider Selenium should select on the insurance site (e.g. MassHealth
rendering provider dropdown), falling back to the existing per-procedure
selection, active claim, or first configured provider.

Also resyncs packages/db's committed compiled schema/client artifacts
with their .ts sources — they had drifted out of sync (some untouched
since July), which was silently stripping the new npiProviderId field
via stale .strict() zod schemas.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 23:07:10 -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
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 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
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
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 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
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 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 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 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
GiteadandClaude Sonnet 4.6 e1fe4862d5 fix: allow claims without appointment + support post/core multi-tooth input
- Make appointmentId nullable/optional in Prisma Zod schema via @zod rich
  comment so claims can be submitted without an existing appointment
- Convert undefined appointmentId to null in all claim form handlers and
  the backend claim creation endpoint
- Add AI classifier rule for expanding one procedure across multiple
  comma-separated tooth numbers (e.g. "post/core on #23, 24, 25, 26")
- Add "post/core" (slash) alias to CDT lookup maps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 22:57:24 -04:00
GiteadandClaude Sonnet 4.6 c9d08028a9 feat: teach AI classifier to recognize "comp" and tooth surface notation
Add "comp" as alias for composite in CDT lookup. Update classifier
prompt with explicit examples for "claim comp #8 ml for lisa today"
and dental surface letter definitions (M/D/L/F/B/O/V/I) so the LLM
correctly treats #tooth+surfaces as composite fillings, not insurance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 20:55:41 -04:00
GiteadandClaude Sonnet 4.6 fc3e8c0e25 feat: add Auto Check MH Payment toggle with weekly schedule
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>
2026-06-26 22:58:36 -04:00
Summit Dental CareandClaude Sonnet 4.6 27d9132820 fix: use in-memory startedAt for cron job log to survive DB restore
The auto-import wipes the database, destroying the cronJobLog record
created at the start of the job. Now duration is calculated from a
local variable instead of querying the DB, and if the record is gone
a fresh log entry is created in the restored database.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 22:55:07 -04:00
GiteadandClaude Sonnet 4.6 1edf73fdc8 feat: add new frontend components, MH batch worker, and gitignore rules
- Add all new Frontend source files (pages, components, hooks, utils)
- Add selenium_MHBatchPaymentCheckWorker.py and MHSinglePaymentCheckWorker.py
- Add install-steps-5-13.sh setup script
- Update .gitignore to exclude runtime/sensitive data (backups, uploads,
  chat-history, keys, downloads, generated .d.ts files) while keeping folders
- Add .gitkeep to preserve empty runtime folders in git

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 00:23:43 -04:00
GiteadandClaude Sonnet 4.6 b7e06adf2f feat: MassHealth PDF import auto-pays full balance + patient name fix
- 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>
2026-06-26 00:16:31 -04:00
Summit Dental CareandClaude Sonnet 4.6 7deba90db3 fix: use prisma db push after backup import to sync schema reliably
applyMissingMigrations ran the entire migration SQL as one transaction,
which rolled back all changes when any statement failed (e.g. adding a
NOT NULL column to a non-empty table). Replaced with prisma db push
which compares the schema and applies only what's needed. Also added
support for importing .sql files (not just .zip) in auto-import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 16:05:18 -04:00
ffandClaude Sonnet 4.6 99a54cee9a feat: rclone syncs all 3 folders (backups, chat-history, uploads)
WebDAV server now serves the Backend root directory. Receiver pulls
backups/, chat-history/, and uploads/ individually so all data is
synced between PCs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 23:50:40 -04:00