Autologin skips password entry, so the login keyring never unlocks and
apps keep popping "Authentication required". Document removing it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>
- 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
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.
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>
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>
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>
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>
Some routers (confirmed on Verizon Fios/G3100) block the local-<office>
hostname from resolving because it's a public domain pointing at a
private LAN IP, which matches the DNS rebinding attack pattern. Document
the router-level fix (DNS Rebind Protection exception) and the per-machine
hosts-file workaround for both the Debian server and Windows staff PCs,
including the antivirus hosts-file-lock gotcha on Windows.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.
Documents the trusted-certificate setup used for local staff access,
needed because the Screen Capture API (Copy Agent screenshots) requires
a secure context.
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).
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.
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>
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>
- 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>
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>
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>
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>
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>
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.
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.
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>
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>
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>
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>
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>
- 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>
- 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>
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>
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>
- Add multi_claim intent so AI correctly handles "claim X for patient A and Y for patient B"
instead of applying all procedures to all patients (batch_claim)
- Each patient carries their own matchedCodes in the queue
- Fix batch claim PDF race condition: chatbot queue no longer advances in closeClaim(),
instead advances after selenium PDF is downloaded (matching column claim behavior)
- Align United SCO eligibility worker with claim worker: only fill subscriber ID + DOB,
use treatmentLocation by ID instead of arrow-wrapper click
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add "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>
- Add `import re` to all Selenium workers that use re.search() for claim number extraction
- Pass uploadedFiles to onHandleForMHSeleniumClaim so attachments reach the MH website
- Save chatbot pending files in check-and-claim and batch-check-and-claim flows
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
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>
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>