Dentolize · Hidden-Number WhatsApp Contacts Walkthrough
On this page1. Conversations tab (clinic-web)2. Requests tab (clinic-web) — conversation feedback table3. Patients list — where the phone numbers this feature matches against liveWhat you won't see here

Walkthrough

This is a backend/data-model fix with a small, deliberately quiet UI surface: when it works, staff should barely notice anything changed except that a conversation which used to error out now just... shows up. The screenshots below are real captures from the branch sandbox, taken by logging in as the owner seed user and going to the actual screens this PR touches.

A note on the sandbox data: this environment's WhatsApp integration is not seeded with any conversations (whatsapp=false in the sandbox settings summary), so there is no live hidden-number contact to show mid-conversation. What follows are the real, current screens — showing their empty state — with the exact UI logic this PR added explained underneath each one. The logic itself is verified against the code in /work/repo, referenced in the Feature breakdown pages.

1. Conversations tab (clinic-web)

WhatsApp Conversations tab, currently empty in this sandbox
WhatsApp Conversations tab, currently empty in this sandbox

This is /whatsapp/chats, rendered by packages/clinic-web/src/components/dashboard/officialWhatsapp/conversations/ConversationBox.js. Each row in this list is one OnlineConversation. Before this PR, the row unconditionally rendered +{item.phone} — which would have printed +undefined (or crashed the WhatsApp icon link) for a hidden-number contact. Now:

  • If item.phone is set, the row still shows the clickable WhatsApp icon linking to wa.me/<phone>.
  • If not, the icon renders without a link, and the address text falls back to @username (if Meta told Dentolize the contact's username) or the raw BSUID (ConversationBox.js:172-187, using the shared getConversationHandle helper — see Patient Linking & What Staff See).

2. Requests tab (clinic-web) — conversation feedback table

WhatsApp Requests tab, currently empty in this sandbox
WhatsApp Requests tab, currently empty in this sandbox

This is the Phone Number column of the Requests table (ConversationFeedbacks.js:62-66), one row per ConversationFeedback — a flagged/assigned conversation needing staff attention (e.g. a call-back request). The column header still says "Phone Number" because most rows have one; a hidden-number contact's row now renders the same @username/BSUID fallback instead of a broken phone link. The equivalent mobile screen is ConversationsFeedback.js:74-81.

3. Patients list — where the phone numbers this feature matches against live

Patients list showing phone numbers used for WhatsApp/patient matching
Patients list showing phone numbers used for WhatsApp/patient matching

This isn't a new screen from this PR, but it's the other half of the story: Patient.fullNumber is how Dentolize links a WhatsApp conversation to an existing patient or creates a lead (Patient Linking & What Staff See). Patient records only ever carry a phone number — there's no BSUID column on Patient — which is why the linking logic in this PR had to be taught to read the conversation's stored phone specifically, rather than whatever address the latest inbound message arrived on.

What you won't see here

The parts of this PR with the most engineering weight — the webhook parsing that tells a phone-number message from a BSUID-only one, the address-matching that keeps a contact on one conversation across both, and the to-vs-recipient choice on every outbound reply — have no UI at all. They run inside packages/whatsapp-official, the standalone service that talks to Meta's Graph API. See Receiving & Replying to Messages for the full trace.