Dentolize · Update-Button & Conversation Tags Fix Walkthrough
On this pageCalendar break Update buttonWhatsApp conversation tag syncExplicitly out of scope for this PR (don't file as regressions)

For Quality

Calendar break Update button

Where: Settings → Users → (any user) → User Calendar Settings.

ScenarioExpected
Open the tab, change nothingUpdate disabled
Add a break to any day, touch nothing elseUpdate enabled
Edit an existing break's time range, touch nothing elseUpdate enabled
Remove all break entries for a day, touch nothing else, ending state matches what was originally loadedUpdate disabled again (breaks now equal the saved value)
Change opening/closing time, closed days, or rooms, touch nothing elseUpdate enabled (unaffected by this fix, but worth a regression check)
Add a break and change another fieldUpdate enabled
Save after adding a breakBreak persists on reload; no error
User without editUser permissionUpdate stays disabled regardless of edits (permission check is unchanged, first clause of the disabled expression)

Edge case worth checking: a user whose calendarSettings.breaks is null in the database (never configured) versus one where it's [] (explicitly empty). String(null) and String([]) are not equal ("null" vs ""), so the breaks-unchanged comparison can behave unexpectedly on record load for such users, independent of any actual edit. Worth confirming this doesn't leave Update enabled on a completely untouched form for legacy users with breaks: null — this is a pre-existing quirk unrelated to the direction of the fix, but it's the kind of thing that can produce a confusing follow-up bug report ("Update was already active when I opened the page").

Code: packages/clinic-web/src/components/dashboard/settings/Users/UserCalendarSettingsTab.js:436-440.

WhatsApp conversation tag sync

Setup needed: a company with the official WhatsApp integration enabled, at least one lead or patient linked to an OnlineConversation, and existing PatientTags configured. (Not available in the standard sandbox used for this walkthrough — whatsapp was disabled in this branch's sandbox config and no conversations were seeded; use a sandbox with whatsapp: true and seeded WhatsApp data, or a company that already has WhatsApp connected.)

ScenarioExpected
Edit a lead's tags where the lead has its own onlineConversationConversation's patientTags updates to match
Edit a lead's tags where the patient behind the lead has a different onlineConversation than the leadBoth conversations update
Edit a lead's tags where lead and patient point at the same conversationOnly one update call is made (deduped via Set) — verify no duplicate-write error, not just correctness
Edit a lead but leave tags unchangedNo onlineConversation.update call at all (the tagsChanged short-circuit) — worth confirming via query logging, since a false-negative here (skipping when it shouldn't) would silently reintroduce a variant of the original bug
Edit a lead's tags to an empty list (remove all tags)Conversation's tags also clear to empty, not left stale
Create a new patient from a WhatsApp conversation, choosing tags on the new-patient formConversation's patientTags is seeded to match what was chosen, not left empty
Create a new patient from a WhatsApp conversation, choosing no tagsConversation's patientTags set to empty (explicit clear, not skipped)
Open "Add new patient" from a conversation that already has tags (web)New-patient form pre-fills those tags (NewPatientButton.js:36PatientForm.js:328-330)
Open "Add new patient" from a conversation that already has tags (mobile)Same pre-fill via ConversationMessagesScreen.js:74
Multi-tenant checkVerify onlineConversation updates never cross company boundaries — the existing authorization block later in editLead.js (:276-288) checks companyId on several relations but does not explicitly re-check the conversation(s) touched by the new tag-sync block; worth confirming a conversation can't belong to a different company than the lead in practice (relational integrity) rather than assuming the authorization block covers it

Code: packages/server/src/resolvers/mutations/actions/leads/editLead.js:254-274, packages/server/src/resolvers/mutations/actions/patient/addNewPatient.js:239-244.

Explicitly out of scope for this PR (don't file as regressions)

  • No retroactive fix / backfill for conversations whose tags were already

stale before this shipped.

  • No new UI for viewing or editing a conversation's tags directly — they

only ever follow the patient/lead.

  • Editing a patient's tags directly (not via a lead) was already

correct before this PR — packages/server/src/resolvers/mutations/actions/patient/editPatient.js:438-449 has the same sync logic, working, with onlineConversation properly selected. That's useful context for testing: it's the reference implementation the editLead.js fix now matches. Still worth a quick regression pass on editPatient.js's path (edit a patient's tags directly, not through a lead) to confirm this PR didn't touch or break it.