Dentolize CRM Module — Overview
Status: unreleased / beta-gated. Every surface described here ships behindFEATURE_CRM_*feature flags and is intended for controlled beta clinics. Nothing in this module is generally available yet. This walkthrough documents what the code actually does in the PR (feat/crm-module, PR #159), verified against/work/repo— not marketing copy.
What this is
The CRM module turns Dentolize from a clinic-operations system into a full patient-acquisition pipeline. It connects a clinic's paid-social and ad accounts, captures the leads those ads generate, routes conversations from every social channel into one inbox, automates the busywork of following up, measures real return on ad spend against clinic revenue, and asks happy patients for public reviews.
It is built as five cooperating capabilities, each independently flag-gated:
| Capability | One-line purpose | Flag |
|---|---|---|
| Social & Ad Integrations | Connect Meta / TikTok / Snapchat / Google; discover pages, IG accounts, lead forms, ad accounts | FEATURE_CRM_INTEGRATIONS_{META,TIKTOK,SNAPCHAT,GOOGLE} |
| Lead Capture & Attribution | Turn ad clicks, form fills, and DMs into deduplicated leads with a full source trail | (part of integrations) |
| Unified Inbox | One inbox for WhatsApp, Messenger, Instagram DMs, and FB/IG comments, with SLA timers | FEATURE_CRM_INBOX_UNIFIED |
| Marketing Hub & ROI | Sync campaigns and spend; compute CPL, CPA, ROAS, and revenue-based ROI | FEATURE_CRM_MARKETING_HUB |
| Automation Engine | Trigger → condition → action rules for assigning, tagging, moving, and messaging leads | FEATURE_CRM_AUTOMATION |
| Reviews & Reputation | WhatsApp review requests with tracked links, cooldowns, and click tracking | FEATURE_CRM_REVIEWS |
Why it was built
The module is the follow-up to a lead-management gap analysis. Before it, a clinic's ad budget lived on Meta's dashboard, leads arrived by phone or walk-in with no source attribution, social messages were scattered across apps, and there was no way to prove whether a campaign actually produced paying patients. The CRM closes that loop: ad spend → lead → conversation → patient → revenue → ROI, all inside Dentolize.
How the pieces fit together
Ad platforms (Meta / Google / …)
│ signed webhooks + OAuth-synced data
▼
Webhook inbox ──► Lead capture ──► Lead pipeline (stages)
(verify→persist (dedupe by phone, │
→enqueue→200) round-robin, ├─► Unified Inbox (SLA timers)
attribution spine) ├─► Automation rules (assign/tag/move/message)
└─► Reviews (WhatsApp → tracked /r/ link)
│
▼
Marketing Hub ──► CPL · CPA · ROAS · revenue-based ROI
│ daily ad spend
▼
Accounting general ledger (optional "Post ad spend to GL")
Two architectural ideas run through the whole module:
- Everything ingested is idempotent and replayable. Inbound webhooks are
signature-verified, persisted to a durable WebhookEvent inbox, and only then processed. Redeliveries collapse on database unique keys, so a platform can retry a webhook a hundred times and produce exactly one lead. See Lead Capture & Attribution.
- Two-layer gating. GraphQL Shield permissions decide who may call a mutation;
feature flags decide whether the capability exists for that clinic at all. A user with the right permission but no flag still cannot reach the write path. See Security, Flags & Data Retention.
Where it runs
- Web app (
clinic-web) — the primary surface. OAuth "Connect" flows are
web-only by design; the Marketing Hub, unified inbox, automation builder, and review tools all live here.
- Mobile app (
clinic-mobile) — a near-complete companion: inbox, automations,
reviews, marketing dashboards, and integration management (view / refresh / disconnect / map assets). It cannot initiate an OAuth connection.
- Gateway service (
whatsapp-official) — hosts the public webhook endpoints, the
BullMQ queue workers, and the automation executor.
- API server (
server) — GraphQL API, permissions, and the scheduled cron jobs
that reconcile counters, sync insights, and redact old data.
Read next
- New to the feature? Start with the Feature Tour — real
screenshots from the beta sandbox.
- Presenting it to a team? Jump to your By team page.
- Building or testing against it? The In depth pages carry
file:line
references into the code.
- Wondering what's not done, or why the PR contains more than CRM? Read
Scope, Gaps & Honest Notes first.