# WhatsApp Sector Testing Guide

Physical end-to-end testing walkthrough for all 4 sectors you want to validate, using **one** test organization and the **sector-switcher script** to flip between them.

## Prerequisites (do this once)

1. **Follow the setup guide first**: [`whatsapp-twilio-ngrok-setup.md`](./whatsapp-twilio-ngrok-setup.md)
   - ngrok tunnel running
   - `NGROK_URL` set in `.env.local`
   - Dev server running on port 9001
   - Twilio Sandbox joined from your phone
   - Twilio webhook pointed at `https://<ngrok>.ngrok-free.app/api/webhooks/twilio-whatsapp`

2. **One-time test org provisioning**. Create a test org in Convex with Twilio credentials wired up. Run from `mawidi-site/`:

   ```bash
   npx tsx -e "
   import { config } from 'dotenv';
   config({ path: '.env.local' });
   import { ConvexHttpClient } from 'convex/browser';
   import { encrypt } from './lib/encryption';

   const client = new ConvexHttpClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
   const ORG_ID = 'YOUR_ORG_ID_HERE';  // fill from Convex dashboard

   (async () => {
     await client.mutation('organizations/mutations:updateOrganizationNoAuth' as any, {
       organizationId: ORG_ID,
       twilioAccountSid: 'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
       twilioAuthTokenEncrypted: encrypt('YOUR_TWILIO_AUTH_TOKEN'),
       twilioWhatsappNumber: '+14155238886',
       twilioWhatsappConfigured: true,
       twilioWhatsappConfiguredAt: Date.now(),
       twilioWhatsappConfiguredBy: 'manual-setup',
     });
     console.log('✅ Twilio wired');
   })();
   "
   ```

3. **Note your org ID and test phone number** — you'll pass these to the switcher script for every sector change.

---

## The Test Loop

For each sector, the flow is:

```
1. Run the switcher to flip the org + wipe conversation state
2. Send a WhatsApp message from your phone to +14155238886
3. Verify you get the bilingual greeting
4. Reply "2" (English)
5. Send a sector-specific trigger message
6. Walk through the collected fields
7. Verify booking/confirmation
```

The switcher clears the conversation history, so every sector test starts fresh.

---

## Test 1: Retail (Product Consultation)

### Switch

```bash
npx tsx scripts/switch-sector.ts <ORG_ID> retail-services --reset-conversation=+YOUR_PHONE
```

### What you should see in the terminal

```
✅ Set industry="retail-services", sector="retail_services"
✅ Deleted N old workflow(s)
✅ Seeded 2 workflow(s), 0 error(s)
   Workflows now active:
     • Product Consultation
     • Order Status Inquiry
```

### What to send from WhatsApp

| You send | Bot responds |
|----------|-------------|
| `hi` | Bilingual greeting → "1 for Arabic, 2 for English" |
| `2` | "Great! We'll communicate in English..." |
| `I want a consultation about a sofa` | Matches **Product Consultation** workflow (trigger: "consultation"). Bot asks: product interest, store preference, preferred date/time |
| `Modern 3-seater, Doha City Center, Friday 4pm` | Collects fields and confirms |

### What the AI knows about retail (from sector context)

- Transaction noun: **"consultation"** / "استشارة"
- Uses retail vocabulary: consultant, meeting, case, review, advice, assessment
- Does NOT push deposits aggressively (30% default deposit — only prompts if Stripe is configured)

---

## Test 2: Café / Restaurant (Table Reservation)

### Switch

```bash
npx tsx scripts/switch-sector.ts <ORG_ID> restaurants-cafes --reset-conversation=+YOUR_PHONE
```

### What you should see in the terminal

```
✅ Set industry="restaurants-cafes", sector="food_hospitality"
✅ Seeded 2 workflow(s), 0 error(s)
   Workflows now active:
     • Table Reservation
     • Catering / Group Inquiry
```

### What to send from WhatsApp

| You send | Bot responds |
|----------|-------------|
| `hi` | Bilingual greeting (first message after wipe) |
| `2` | English confirmed |
| `I'd like to book a table for Friday evening` | Matches **Table Reservation** (triggers: "table", "reservation", "reserve", "book a table", "dinner") |
| Bot asks party size → `4 people` | |
| Bot asks date → `Friday` | |
| Bot asks time → `8pm` | |
| Bot asks dietary requirements → `one vegetarian` | |
| Confirmation → "Your reservation for 4 on Friday at 8pm is received. We'll confirm shortly." | |

### What the AI knows about food_hospitality

- Transaction noun: **"reservation"** / "حجز"
- Vocabulary: table, party, menu, dietary, chef's special, guests, course, allergies
- **No deposit required** (set in sector registry — pay at venue)
- Custom fields: party_size, dietary_requirements, special_occasion

---

## Test 3: Real Estate (Viewing Request)

> ⚠️ **Important**: Real estate uses a **different webhook endpoint**. In your Twilio Sandbox settings, temporarily change the webhook URL to:
>
> ```
> https://<ngrok>.ngrok-free.app/api/webhooks/twilio-whatsapp-re
> ```
>
> This routes messages through the dedicated `realEstateAIEngine` which has property search + broker assignment logic. The unified Twilio webhook (`/api/webhooks/twilio-whatsapp`) also supports `property_facilities` sector workflows, but the RE-specific engine is more feature-complete.

### Switch

```bash
npx tsx scripts/switch-sector.ts <ORG_ID> property-facilities --reset-conversation=+YOUR_PHONE
```

### What you should see in the terminal

```
✅ Set industry="property-facilities", sector="property_facilities"
✅ Seeded 2 workflow(s), 0 error(s)
   Workflows now active:
     • Viewing Request
     • Maintenance Request
```

### What to send from WhatsApp

| You send | Bot responds |
|----------|-------------|
| `hi` | Bilingual greeting |
| `2` | English confirmed |
| `I want to see the apartment in The Pearl` | Matches **Viewing Request** (triggers: "apartment", "viewing", "see the property", "villa", "tour") |
| Bot asks budget range → `9000-12000 QAR` | |
| Bot asks bedroom count → `2 bedrooms` | |
| Bot asks preferred date → `Saturday 3pm` | |
| Confirmation → "Your viewing request has been received. A broker will reach out shortly." | |

### What the AI knows about property_facilities

- Transaction noun: **"viewing"** / "معاينة"
- Vocabulary: property, villa, apartment, viewing, bedrooms, location, rent, sale
- **No deposit required** (handled separately in RE flow)
- Custom fields: property_address, property_type, bedrooms
- If you use the `-re` webhook: also gets property search, broker assignment

---

## Test 4: Healthcare / Appointments

### Switch

```bash
npx tsx scripts/switch-sector.ts <ORG_ID> healthcare --reset-conversation=+YOUR_PHONE
```

> If you tested real estate with `-re` webhook above, **don't forget to switch Twilio back** to the unified webhook:
>
> ```
> https://<ngrok>.ngrok-free.app/api/webhooks/twilio-whatsapp
> ```

### What you should see in the terminal

```
✅ Set industry="healthcare", sector="health_care"
✅ Seeded 2 workflow(s), 0 error(s)
   Workflows now active:
     • Appointment Booking
     • Appointment Status Check
```

### What to send from WhatsApp

| You send | Bot responds |
|----------|-------------|
| `hi` | Bilingual greeting |
| `2` | English confirmed |
| `I want to book a doctor appointment` | Matches **Appointment Booking** (triggers: "book", "appointment", "schedule", "doctor", "clinic") |
| Bot asks doctor/specialist → `Dr. Smith, cardiologist` | |
| Bot asks reason → `chest pain follow-up` | |
| Bot asks new vs follow-up → `follow-up` | |
| Bot asks date → `Monday` | |
| Bot asks time → `10am` | |
| Confirmation → "Your appointment request has been received. We will confirm shortly." | |

### What the AI knows about health_care

- Transaction noun: **"appointment"** / "موعد"
- Vocabulary: doctor, specialist, consultation, clinic, prescription, patient, referral, checkup
- **25% deposit** default (only prompted if Stripe is configured on the org)
- Custom fields: doctor_specialist, department

---

## Verifying the Learning Loop

After each test, check the dashboard:

1. Open `/en/dashboard` → Knowledge Base tab
2. You should see:
   - **SuggestedFAQs** section with unanswered questions tracked from your conversations
   - **WhatsAppGreetingForm** where you can customize the welcome message
   - Pending FAQ suggestions if the AI hit KB misses

Or check Convex directly:
```bash
npx convex run whatsapp/queries:getUnansweredQuestions '{ "organizationId": "<ORG_ID>" }'
```

---

## Troubleshooting

### "I sent a retail trigger but got the default sector response"

- The switcher prints which workflows are active. If none match your trigger keyword, the AI falls back to the generic sector vocabulary.
- Try sending a message that contains one of the trigger keywords literally (e.g. `"consultation"`, `"reservation"`, `"viewing"`, `"appointment"`).
- Or check `/var/log` equivalent (dev server terminal) for `[WorkflowMatch]` or `matchedWorkflow` log lines.

### "The bot doesn't greet me — it just goes straight to idle"

- Your custom greeting is set to empty, or `autoGreetingEnabled === false`. Reset via the dashboard **WhatsApp Greeting** section, or run:
  ```bash
  npx tsx -e "
  import { config } from 'dotenv'; config({ path: '.env.local' });
  import { ConvexHttpClient } from 'convex/browser';
  const c = new ConvexHttpClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
  await c.mutation('organizations/mutations:updateOrganizationNoAuth' as any, {
    organizationId: 'YOUR_ORG_ID',
    autoGreetingEnabled: true,
    greetingMessageEn: null,
    greetingMessageAr: null,
  });
  console.log('Greeting reset to default');
  "
  ```

### "I see 'unknown To number' in dev server logs"

- Your Twilio sandbox number in Convex doesn't match the From address Twilio is sending. Confirm `twilioWhatsappNumber` in the Convex dashboard is exactly `+14155238886` (no `whatsapp:` prefix).

### "Signature validation failed"

- `NGROK_URL` is stale (you restarted ngrok and got a new URL). Update `.env.local` + restart `npx next dev`.

### "I keep getting the same greeting twice"

- The script only wipes conversation state when you pass `--reset-conversation=+PHONE`. If you don't pass it, the old `conversation.conversationState` persists and the greeting won't re-fire.

---

## Summary of Sector → Test Flow

| Sector | Industry key | Webhook | Trigger word example | Noun |
|--------|-------------|---------|----------------------|------|
| Retail | `retail-services` | `/twilio-whatsapp` | "consultation" | consultation |
| Restaurant | `restaurants-cafes` | `/twilio-whatsapp` | "table" or "reservation" | reservation |
| Real estate | `property-facilities` | `/twilio-whatsapp-re` | "viewing" or "apartment" | viewing |
| Healthcare | `healthcare` | `/twilio-whatsapp` | "appointment" or "doctor" | appointment |
| Beauty | `beauty-wellness` | `/twilio-whatsapp` | "haircut" or "appointment" | appointment |
| Auto | `vehicle-rental` | `/twilio-whatsapp` | "rental" or "car" | rental |
| Education | `education` | `/twilio-whatsapp` | "course" or "enrollment" | enrolment |
| Events | `events-venues` | `/twilio-whatsapp` | "venue" or "event" | event booking |
| Pet | `pet-services` | `/twilio-whatsapp` | "grooming" or "vet" | appointment |
| Home services | `home-services-trades` | `/twilio-whatsapp` | "repair" or "plumbing" | job |

You only need to test 4 sectors per your request — the others are all covered by the same plumbing.

---

## What's Happening Behind the Scenes

For every message:
1. **Twilio** POSTs form-encoded body + signature → ngrok → your dev server
2. **Rate limiter** (100/min per IP via Upstash)
3. **Signature verification** against `${NGROK_URL}/api/webhooks/twilio-whatsapp` + org's decrypted Twilio auth token
4. **Multi-tenant router** resolves `To` number → org (Redis-cached 1hr)
5. **Sector config** loaded from `lib/config/sector-registry.ts` via org's `industry` field
6. **Conversation + language** upserted in Convex
7. **Custom greeting** built via `buildGreetingForOrg` (custom if set, default if not)
8. **AI engine** loads KB + appointment types + **active workflows in parallel**, matches a workflow by trigger, injects its system prompt addition + field checklist
9. **Response** translated to Qatari Arabic if language=ar, sent back via Twilio
10. **Learning service** fires non-blocking to track KB misses for `unanswered_questions`

All of this is wired, tested, and committed on `feature/whatsapp`.
