d
Dental Map
Brief  ·  v0.1
MVP Brief Greater Cairo · Pilot Cohort

A search engine
for dentists,
wired to the
clinics that treat.

Egypt already has Vezeeta for doctors. What it doesn't have is a dentistry-first booking layer that's actually live-synced with the clinic's real calendar — the operating system dentists already use, Dentolize. Dental Map closes that loop: patients book a slot, and the slot becomes an appointment in the clinic's own schedule. No receptionist reconciliation. No phone tag.

Reference
Vezeeta · but for teeth
Integration bus
Google Calendar · until partnership
Ship target
5–6 weeks to pilot
✺   ✺   ✺
01
i.
Section

The gap, precisely.

The incumbent
Vezeeta

17,000+ doctors in Egypt · 110k bookings/month. Dominant for GPs and specialists. Dentistry coverage is shallow; bookings flow to leads, not to clinic software.

The clinic OS
Dentolize

~5,000 dentists across 29 countries. Patient charts, scheduling, WhatsApp bot, billing, inventory. No public API. The integration surface we'll negotiate our way into.

The play
Dental Map

Arabic-first patient marketplace. Live slot availability computed from the dentist's own Google Calendar. Booking writes straight back. The loop closes itself.

02
ii.
Section

Eight decisions, locked.

MVP Core
01
Patient directory + live booking

The ambitious path. Patients see a dentist's actual open slots — not a lead form.

Dentolize link
02
Google Calendar as sync bus

Clinics connect a Google Calendar per dentist. Where Dentolize mirrors to Google, the loop is automatic. Where it doesn't, the receptionist copies once per booking during the pilot.

Launch surface
03
Greater Cairo · 20–50 clinics

One city, all dentistry subspecialties. Prove the loop before going nationwide.

Language
04
Arabic-first RTL · English toggle

Matches Egyptian market reality. English available via header toggle.

Patient auth
05
Email + password

Phone is still required at booking — the clinic needs to reach the patient. OTP login can come in v1.1 if signup dropoff is high.

Platforms
06
PWA · responsive web

One codebase. Installable from the browser. No app-store friction.

Revenue
07
Free for pilot

Zero friction for clinics. Monetize post-pilot via commission or subscription once liquidity exists.

Stack
08
Next.js 15 + Supabase · Vercel

SSR for SEO on dentist profiles. Supabase collapses Postgres + Auth + Storage + Realtime into one managed surface.

03
iii.
Section

Architecture, one screen.

┌──────────────────────────────────────────────────────────────────┐ │ Next.js 15 (App Router) · Vercel │ │ │ │ /[locale]/(patient)/... │ /[locale]/(dentist)/... │ │ home · search · profile │ dashboard · calendar · │ │ booking flow · account │ clinic profile · bookings │ │ │ │ RSC + Server Actions + Route Handlers │ └───────────┬───────────────┬────────────────────────┬─────────────┘ │ │ │ ▼ ▼ ▼ ┌────────────┐ ┌──────────────┐ ┌─────────────────┐ │ Supabase │ │ Google Cal. │ │ Resend │ │ Postgres · │ │ API · OAuth │ │ Transactional │ │ Auth · │ │ per dentist │ │ email │ │ Storage · │ │ │ │ (WhatsApp v2) │ │ Realtime · │ │ busy/free │ └─────────────────┘ │ RLS │ │ + write │ └────────────┘ └──────────────┘
Why Next.js

RSC + SSR so every dentist profile is Google-indexable. "Dentist in Nasr City" long-tails are Vezeeta's #1 acquisition channel — we need the same.

Why Supabase

Postgres (relational queries: "dentists taking Insurance X, area Y, slot Z"), auth, storage, row-level security, realtime — one service, a weekend of wiring, not a month.

Why Google Calendar

The only integration surface we can reach without a Dentolize partnership. The dentist already owns the OAuth consent. We read free/busy, write events back.

04
iv.
Section

Data model, sketched.

profilesextends auth.users; role: patient · dentist_admin · ops.
clinicsname, slug, address, lat/lng, Cairo district, phone, photos.
dentistsname_ar, name_en, slug, title (professor / consultant / specialist / resident), bio, years of experience.
clinic_dentistsmany-to-many; fee (EGP) and working hours per clinic.
specialtiesadult, pediatric, orthodontics, cosmetic, endodontics, implants, surgery.
insuranceAXA, MetLife, Bupa, GlobeMed … with per-clinic acceptance map.
dentist_calendarsencrypted Google refresh token, watched calendar ID, last sync cursor.
availability_slotsderived: working_hours − Google busy. Refreshed on demand + webhook push.
appointmentspatient, slot, fee_at_booking, status (pending · confirmed · completed · cancelled · no_show), gcal_event_id.
reviewsone per appointment. RLS enforces: only the patient who completed that appointment can insert. Verified only.
The crux

The Dentolize problem, answered honestly.

Phase 1 · MVP

Google Calendar is the canonical sync surface. Clinics that already mirror Dentolize ↔ Google get a seamless loop. Clinics that don't: their receptionist copies the booking into Dentolize once — ≤30 seconds per booking — aided by a one-click copy patient details button. Tolerable at pilot volume.

Phase 2 · Post-pilot

Pitch Dentolize for a real partnership with demonstrated patient-side liquidity. If they won't deal: a tiny opt-in desktop helper that pushes bookings into Dentolize via the clinic's own session. No credential-harvesting. No ToS-breaking.

05
v.
Section

Six weeks, ordered.

Week 1 Foundation

Next.js 15 scaffold with next-intl (Arabic RTL + English). Supabase: Postgres schema, email/password auth, storage buckets, RLS policies. Tailwind + shadcn/ui with custom palette. Patient shell, dentist shell, auth pages.

Week 2 Dentist side

Clinic/dentist profile editor. Google Calendar OAuth start + callback. Encrypted token storage. Working-hours editor. The availability engine (lib/availability/) that computes open slots from working hours minus Google busy.

Week 3 Patient side

Search (specialty + area + date + insurance + fee range). Dentist profile page, SSR'd. Slot grid. Booking flow with inline email signup. Booking server action: database + Google Calendar event + patient + clinic emails, atomic.

Week 4 Polish · reviews · ops

Post-appointment auto-transitions (Vercel cron). Review flow behind RLS. Ops console: invite clinics, view bookings, dispute tools. Arabic translation QA pass.

Weeks 5–6 Pilot prep

SEO: sitemaps, schema.org MedicalBusiness + Physician markup, localized URLs. Seed 20–50 Cairo clinics. Soft launch to a small patient list (WhatsApp groups, FB). Sentry, Supabase logs, daily funnel dashboard.

06
vi.
Section

The shape of the repo.

app/ [locale]/ (patient)/ page.tsx # home search/page.tsx # results dentist/[slug]/page.tsx # profile · SSR for SEO book/[slotId]/page.tsx # booking flow account/page.tsx # past bookings (dentist)/ dashboard/page.tsx calendar/page.tsx # hours + Google Calendar status clinic/page.tsx # profile editor bookings/page.tsx (ops)/ admin/... # internal console (auth)/ signin/page.tsx signup/page.tsx api/ gcal/oauth/start/route.ts gcal/oauth/callback/route.ts bookings/route.ts cron/finalize-appointments/route.ts middleware.ts # locale + auth gating lib/ supabase/{server,client,admin}.ts gcal/{client,availability,events}.ts availability/{compute,types}.ts i18n/{request,config}.ts email/{resend,templates}/ db/ schema.sql seed.sql # specialties, insurance, Cairo areas i18n/ ar.json en.json
07
vii.
Section

What could bite us.

Risk Mitigation
Dentolize ↔ Google sync is absent or clunky for some clinics. Phase-1 fallback: receptionist manual mirror, ≤30 s per booking. One-click copy button. Acceptable at pilot volume.
Email/password auth is weak for Egyptian patients who rarely use email. Phone is mandatory at booking time regardless of login method. Add phone OTP login as v1.1 if signup dropoff is material.
SMS / WhatsApp reminders matter for no-show reduction. Email-only for MVP. WhatsApp Cloud API if week-5 time permits; otherwise phase 2.
Patient liquidity — classic chicken/egg. Sign 5–10 clinics before any patient acquisition. Paid FB + Google for first 500 Cairo patients.
Google Calendar quotas or webhook breakage. Push notifications (watch endpoints) + refresh tokens. Quota is generous at 50-clinic scale.
Arabic RTL bugs in Tailwind / shadcn components. next-intl + dir="rtl" wrapper. Component-by-component audit. Half-week QA budget in week 5.
08
viii.
Section

How we know it works.

Before the pilot opens to more than two clinics, the following must all pass. Any red, we don't ship.

01

Dentist onboarding. Connect Google Calendar on two test dentists. Set working hours. Availability grid matches expectations (working hours minus Google busy).

02

Patient booking. In incognito, search "dentist in Nasr City," pick a dentist, pick a slot, sign up with email, book.

03

Write-through loop. Booking appears in (a) our appointments table, (b) the dentist's Google Calendar, (c) patient's email, (d) clinic admin's email.

04

Dentolize loop. For a clinic with Dentolize↔Google sync on, event appears in Dentolize within its SLA. For a clinic without: receptionist confirms ≤30 s copy time.

05

Review gate. Posting a review from a non-booking patient is rejected by RLS. Posting from the booking patient after completion succeeds.

06

i18n. Locale toggle flips direction and copy cleanly. RTL mirror layout has no leaking LTR components.

07

SEO. View-source on a dentist profile shows localized title, description, and schema.org JSON-LD. Sitemap submitted to Search Console.

ix.
Section

Not this version.

Explicit YAGNI. Everything below is tempting. None of it is on the MVP path.

Native mobile apps Telehealth video Online payment collection Insurance claim processing Pharmacy delivery Multi-city Direct Dentolize API Loyalty / referral Dentist-to-dentist referrals
✺   ✺   ✺

Ready when you
are.

review  ·  respond  ·  we break ground