/opt/mawid
NameSizeModeActions
.git/-0755rm
apps/-0755rm
backups/-0755rm
packages/-0755rm
scripts/-0755rm
.env.droplet7840644editdlrm
.gitignore990644editdlrm
.nvmrc80644editdlrm
.prettierignore520644editdlrm
.prettierrc730644editdlrm
Caddyfile2420644editdlrm
DEMO.md53980644editdlrm
deploy.sh7890755editdlrm
docker-compose.droplet.yml10570644editdlrm
docker-compose.prod.yml10330644editdlrm
docker-compose.yml21870644editdlrm
eslint.config.mjs6470644editdlrm
GOLIVE.md83250644editdlrm
package.json6190644editdlrm
pnpm-lock.yaml2477460644editdlrm
pnpm-workspace.yaml1850644editdlrm
PROGRESS.md225590644editdlrm
PROJECT_PLAN.md129970644editdlrm
README.md9820644editdlrm
RUNBOOK.md51250644editdlrm
tsconfig.base.json3160644editdlrm
Edit: /opt/mawid/DEMO.md (5398B)
# Demo Setup — real WhatsApp from your laptop (no company, no server) Goal: pitch Mawid to a clinic with a live demo — the clinic owner messages a real WhatsApp number from their own phone, the AI books them an appointment, and you show it landing on the dashboard calendar in real time. Uses Meta's **free test number** (individual developer account, no business verification, no payment method). Everything runs on your laptop; a tunnel exposes the webhook. ## One-time setup (~45 min) ### 1. Meta developer app (no company needed) 1. developers.facebook.com → **My Apps → Create App** → type **Business** (creating the app and a Business Portfolio needs no documents — the portfolio can be named after yourself). 2. **Add product → WhatsApp → Set up** → Meta creates a test WhatsApp Business Account + **free test phone number**. 3. From *WhatsApp → API Setup*, note: - **Phone number ID** and **WABA ID** - App Settings → Basic → **App secret** 4. Still in API Setup → **To** field → **Manage phone number list** → add up to **5 recipient numbers** (your phone + the clinic owner's). Each gets an SMS code. Only these numbers can chat with the test number — plenty for demos. 5. Token: the API-Setup token expires in 24h — fine for a first try, but for demos create the permanent one now (GOLIVE.md §3.2, System User) so it never dies mid-pitch. ### 2. Tunnel (public HTTPS → localhost) ngrok's free plan includes one **static domain** — better than a random URL because the Meta webhook config survives restarts: ```bash brew install ngrok ngrok config add-authtoken # claim your free static domain in the ngrok dashboard, then: ngrok http --domain=.ngrok-free.app 3001 ``` Leave this running during demos. (Alternative: `cloudflared tunnel --url http://localhost:3001` — zero signup, but the URL changes every run and you must re-save the Meta webhook each time.) ### 3. Local env + restart Create `.env` in the repo root (compose picks it up automatically): ``` WA_PHONE_NUMBER_ID= WA_BUSINESS_ACCOUNT_ID= WA_ACCESS_TOKEN= WA_APP_SECRET= WA_WEBHOOK_VERIFY_TOKEN= OPENAI_API_KEY= ``` ```bash docker compose up -d api # restart with the new env ``` ### 4. Point Meta at your tunnel App dashboard → WhatsApp → **Configuration**: - Callback URL: `https://.ngrok-free.app/webhooks/whatsapp` - Verify token: your `WA_WEBHOOK_VERIFY_TOKEN` → **Verify and save** - Webhook fields → subscribe to **messages** ### 5. Wire the demo clinic to the test number ```bash docker compose exec -T postgres psql -U mawid -d mawid -c \ "UPDATE \"Clinic\" SET \"waPhoneNumberId\"='' WHERE name='Demo Dental Clinic';" ``` ### 6. Templates (only needed for the reminder/waitlist part of the demo) WhatsApp Manager → Message templates → create `appointment_reminder` and `waitlist_offer` per GOLIVE.md §3.4 (test WABAs can create custom templates; Utility templates usually approve in minutes). The AI chat itself needs no templates — replies ride the 24h window the patient just opened. ### 7. Smoke test WhatsApp the test number from your registered phone: *"Merhaba, yarın için muayene randevusu almak istiyorum"* → the agent should reply with real slots. Watch `docker compose logs -f api` and the dashboard **Conversations** page. ## Demo script (10 min pitch) 1. **Hook** — hand the owner your phone (or use theirs if registered): they message the clinic in Turkish or Arabic, the AI answers in the same language, offers real free slots, books one. No app, no forms. 2. **Dashboard** — flip to `localhost:3000`: the appointment is on the calendar, the transcript is under Conversations, "take over" pauses the AI. 3. **The money slide** — reminders: show Settings → reminder offsets, explain the T-24h/T-2h buttons + the unconfirmed-risk flag. If templates are approved, pre-stage an appointment with short offsets so a real reminder with ✅/❌/🔁 buttons arrives during the pitch. 4. **Waitlist** — cancel the booked slot from the phone (❌ button or chat): the waitlisted patient (your second registered number) gets the offer with a 20-minute hold; accept → slot refilled, owner notified. 5. Close with the weekly summary (dashboard card): "this is the report you get on WhatsApp every Monday." ## Reset between demos ```bash ./scripts/demo-reset.sh +90XXXXXXXXXX # wipe one demo patient (GDPR delete) ``` Removes that phone's patient row, appointments, conversations and waitlist entries via the API, so the next pitch starts from a blank chat. (WhatsApp chat history on the phone: just delete the chat.) ## Gotchas - Test numbers only talk to the 5 registered recipients — register the clinic owner's phone *before* the meeting, the SMS verification takes a minute. - The tunnel and `docker compose` stack must both be running; check `https:///health` before walking in. - If replies stop after ~24h token life, you used the temporary token — switch to the System-User permanent token. - Demo on hotel/clinic Wi-Fi: ngrok occasionally gets blocked on guest networks; tether to your phone's hotspot as a fallback.