# WhatsApp Shared Account Model - Implementation Guide

## Overview

This guide documents the **Shared WhatsApp Business Account** implementation for the bakery-ia pilot program. This model simplifies WhatsApp setup by using a single master WhatsApp Business Account with phone numbers assigned to each bakery tenant.

---

## Architecture

### Shared Account Model

```
┌─────────────────────────────────────────────┐
│   Master WhatsApp Business Account (WABA)   │
│   - Centrally managed by platform admin     │
│   - Single set of credentials               │
│   - Multiple phone numbers (up to 120)      │
└─────────────────────────────────────────────┘
                      │
        ┌─────────────┼─────────────┐
        │             │             │
   Phone #1       Phone #2      Phone #3
   Bakery A       Bakery B      Bakery C
```

### Key Benefits

✅ **Zero configuration for bakery users** - No Meta navigation required
✅ **5-minute setup** - Admin assigns phone number via UI
✅ **Lower support burden** - Centralized management
✅ **Predictable costs** - One WABA subscription
✅ **Perfect for pilot** - Quick deployment for 10 bakeries

---

## User Experience

### For Bakery Owners (Non-Technical Users)

**Before (Manual Setup):**
- Navigate Meta Business Suite ❌
- Create WhatsApp Business Account ❌
- Create message templates ❌
- Get credentials (3 different IDs) ❌
- Copy/paste into settings ❌
- **Time:** 1-2 hours, high error rate

**After (Shared Account):**
- Toggle WhatsApp ON ✓
- See assigned phone number ✓
- **Time:** 30 seconds, zero configuration

### For Platform Admin

**Admin Workflow:**
1. Access WhatsApp Admin page (`/app/admin/whatsapp`)
2. View list of tenants
3. Select tenant
4. Assign phone number from dropdown
5. Done!

---

## Technical Implementation

### Backend Changes

#### 1. Tenant Settings Model

**File:** `services/tenant/app/models/tenant_settings.py`

**Changed:**
```python
# OLD (Per-Tenant Credentials)
notification_settings = {
    "whatsapp_enabled": False,
    "whatsapp_phone_number_id": "",
    "whatsapp_access_token": "",           # REMOVED
    "whatsapp_business_account_id": "",    # REMOVED
    "whatsapp_api_version": "v18.0",       # REMOVED
    "whatsapp_default_language": "es"
}

# NEW (Shared Account)
notification_settings = {
    "whatsapp_enabled": False,
    "whatsapp_phone_number_id": "",        # Phone # from shared account
    "whatsapp_display_phone_number": "",   # Display format "+34 612 345 678"
    "whatsapp_default_language": "es"
}
```

#### 2. WhatsApp Business Service

**File:** `services/notification/app/services/whatsapp_business_service.py`

**Changed `_get_whatsapp_credentials()` method:**

```python
async def _get_whatsapp_credentials(self, tenant_id: str) -> Dict[str, str]:
    """
    Uses global master account credentials with tenant-specific phone number
    """
    # Always use global master account
    access_token = self.global_access_token
    business_account_id = self.global_business_account_id
    phone_number_id = self.global_phone_number_id  # Default

    # Fetch tenant's assigned phone number
    if self.tenant_client:
        notification_settings = await self.tenant_client.get_notification_settings(tenant_id)
        if notification_settings and notification_settings.get('whatsapp_enabled'):
            tenant_phone_id = notification_settings.get('whatsapp_phone_number_id', '')
            if tenant_phone_id:
                phone_number_id = tenant_phone_id  # Use tenant's phone

    return {
        'access_token': access_token,
        'phone_number_id': phone_number_id,
        'business_account_id': business_account_id
    }
```

**Key Change:** Always uses global credentials, but selects the phone number based on tenant assignment.

#### 3. Phone Number Management API

**New File:** `services/tenant/app/api/whatsapp_admin.py`

**Endpoints:**

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/v1/admin/whatsapp/phone-numbers` | List available phone numbers from master WABA |
| GET | `/api/v1/admin/whatsapp/tenants` | List all tenants with WhatsApp status |
| POST | `/api/v1/admin/whatsapp/tenants/{id}/assign-phone` | Assign phone to tenant |
| DELETE | `/api/v1/admin/whatsapp/tenants/{id}/unassign-phone` | Remove phone assignment |

**Example: Assign Phone Number**

```bash
curl -X POST http://localhost:8001/api/v1/admin/whatsapp/tenants/{tenant_id}/assign-phone \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number_id": "123456789012345",
    "display_phone_number": "+34 612 345 678"
  }'
```

**Response:**
```json
{
  "success": true,
  "message": "Phone number +34 612 345 678 assigned to tenant 'Panadería San Juan'",
  "tenant_id": "uuid-here",
  "phone_number_id": "123456789012345",
  "display_phone_number": "+34 612 345 678"
}
```

### Frontend Changes

#### 1. Simplified Notification Settings Card

**File:** `frontend/src/pages/app/database/ajustes/cards/NotificationSettingsCard.tsx`

**Removed:**
- Access Token input field
- Business Account ID input field
- Phone Number ID input field
- API Version selector
- Setup wizard instructions

**Added:**
- Display-only phone number (green badge if configured)
- "Contact support" message if not configured
- Language selector only

**UI Before/After:**

```
BEFORE:
┌────────────────────────────────────────┐
│ WhatsApp Business API Configuration    │
│                                         │
│ Phone Number ID: [____________]         │
│ Access Token:    [____________]         │
│ Business Acct:   [____________]         │
│ API Version:     [v18.0 ▼]             │
│ Language:        [Español ▼]           │
│                                         │
│ ℹ️ Setup Instructions:                 │
│   1. Create WhatsApp Business...       │
│   2. Create templates...               │
│   3. Get credentials...                │
└────────────────────────────────────────┘

AFTER:
┌────────────────────────────────────────┐
│ WhatsApp Configuration                  │
│                                         │
│ ✅ WhatsApp Configured                 │
│    Phone: +34 612 345 678              │
│                                         │
│ Language: [Español ▼]                  │
│                                         │
│ ℹ️ WhatsApp Notifications Included     │
│    WhatsApp messaging is included      │
│    in your subscription.               │
└────────────────────────────────────────┘
```

#### 2. Admin Interface

**New File:** `frontend/src/pages/app/admin/WhatsAppAdminPage.tsx`

**Features:**
- Lists all available phone numbers from master WABA
- Shows phone number quality rating (GREEN/YELLOW/RED)
- Lists all tenants with WhatsApp status
- Dropdown to assign phone numbers
- One-click unassign button
- Real-time status updates

**Screenshot Mockup:**

```
┌──────────────────────────────────────────────────────────────┐
│ WhatsApp Admin Management                                    │
│ Assign WhatsApp phone numbers to bakery tenants              │
├──────────────────────────────────────────────────────────────┤
│ 📞 Available Phone Numbers (3)                               │
├──────────────────────────────────────────────────────────────┤
│ +34 612 345 678    Bakery Platform    [GREEN]                │
│ +34 612 345 679    Bakery Support     [GREEN]                │
│ +34 612 345 680    Bakery Notifications [YELLOW]             │
└──────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────┐
│ 👥 Bakery Tenants (10)                                       │
├──────────────────────────────────────────────────────────────┤
│ Panadería San Juan  ✅ Active                                │
│ Phone: +34 612 345 678           [Unassign]                  │
├──────────────────────────────────────────────────────────────┤
│ Panadería Goiko    ⚠️ Not Configured                         │
│ No phone number assigned  [Assign phone number... ▼]         │
└──────────────────────────────────────────────────────────────┘
```

---

## Setup Instructions

### Step 1: Create Master WhatsApp Business Account (One-Time)

**Prerequisites:**
- Meta/Facebook Business account
- Verified business
- Phone number(s) to register

**Instructions:**

1. **Create WhatsApp Business Account**
   - Go to [Meta Business Suite](https://business.facebook.com)
   - Add WhatsApp product
   - Complete business verification (1-3 days)

2. **Add Phone Numbers**
   - Add at least 10 phone numbers (one per pilot bakery)
   - Verify each phone number
   - Note: You can request up to 120 phone numbers per WABA

3. **Create Message Templates**
   - Create `po_notification` template:
     ```
     Category: UTILITY
     Language: Spanish (es)
     Message: "Hola {{1}}, has recibido una nueva orden de compra {{2}} por un total de {{3}}."
     ```
   - Submit for approval (15 min - 24 hours)

4. **Get Master Credentials**
   - Business Account ID: From WhatsApp Manager settings
   - Access Token: Create System User or use temporary token
   - Phone Number ID: Listed in phone numbers section

### Step 2: Configure Environment Variables

**File:** `services/notification/.env`

```bash
# Master WhatsApp Business Account Credentials
WHATSAPP_BUSINESS_ACCOUNT_ID=987654321098765
WHATSAPP_ACCESS_TOKEN=EAAxxxxxxxxxxxxxxxxxxxxxxxxxx
WHATSAPP_PHONE_NUMBER_ID=123456789012345  # Default/fallback phone
WHATSAPP_API_VERSION=v18.0
ENABLE_WHATSAPP_NOTIFICATIONS=true
WHATSAPP_WEBHOOK_VERIFY_TOKEN=random-secret-token-here
```

**Security Notes:**
- Store `WHATSAPP_ACCESS_TOKEN` securely (use secrets manager in production)
- Rotate token every 60 days
- Use System User token (not temporary token) for production

### Step 3: Assign Phone Numbers to Tenants

**Via Admin UI:**

1. Access admin page: `http://localhost:5173/app/admin/whatsapp`
2. See list of tenants
3. For each tenant:
   - Select phone number from dropdown
   - Click assign
   - Verify green checkmark appears

**Via API:**

```bash
# Assign phone to tenant
curl -X POST http://localhost:8001/api/v1/admin/whatsapp/tenants/{tenant_id}/assign-phone \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number_id": "123456789012345",
    "display_phone_number": "+34 612 345 678"
  }'
```

### Step 4: Test Notifications

**Enable WhatsApp for a Tenant:**

1. Login as bakery owner
2. Go to Settings → Notifications
3. Toggle WhatsApp ON
4. Verify phone number is displayed
5. Save settings

**Trigger Test Notification:**

```bash
# Create a purchase order (will trigger WhatsApp notification)
curl -X POST http://localhost:8003/api/v1/orders/purchase-orders \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: {tenant_id}" \
  -d '{
    "supplier_id": "uuid",
    "items": [...]
  }'
```

**Verify:**
- Check notification service logs: `docker logs -f notification-service`
- Supplier should receive WhatsApp message from assigned phone number
- Message status tracked in `whatsapp_messages` table

---

## Monitoring & Operations

### Check Phone Number Usage

```bash
# List all tenants with assigned phone numbers
curl http://localhost:8001/api/v1/admin/whatsapp/tenants | jq
```

### View WhatsApp Message Logs

```sql
-- In notification database
SELECT
    tenant_id,
    recipient_phone,
    template_name,
    status,
    created_at,
    error_message
FROM whatsapp_messages
WHERE created_at > NOW() - INTERVAL '24 hours'
ORDER BY created_at DESC;
```

### Monitor Meta Rate Limits

WhatsApp Cloud API has the following limits:

| Metric | Limit |
|--------|-------|
| Messages per second | 80 |
| Messages per day (verified) | 100,000 |
| Messages per day (unverified) | 1,000 |
| Conversations per 24h | Unlimited (pay per conversation) |

**Check Quality Rating:**

```bash
curl -X GET "https://graph.facebook.com/v18.0/{PHONE_NUMBER_ID}" \
  -H "Authorization: Bearer {ACCESS_TOKEN}" \
  | jq '.quality_rating'
```

**Quality Ratings:**
- **GREEN** - No issues, full limits
- **YELLOW** - Warning, limits may be reduced
- **RED** - Quality issues, severely restricted

---

## Migration from Per-Tenant to Shared Account

If you have existing tenants with their own credentials:

### Automatic Migration Script

```python
# services/tenant/scripts/migrate_to_shared_account.py
"""
Migrate existing tenant WhatsApp credentials to shared account model
"""

import asyncio
from sqlalchemy import select
from app.core.database import database_manager
from app.models.tenant_settings import TenantSettings

async def migrate():
    async with database_manager.get_session() as session:
        # Get all tenant settings
        result = await session.execute(select(TenantSettings))
        all_settings = result.scalars().all()

        for settings in all_settings:
            notification_settings = settings.notification_settings

            # If tenant has old credentials, preserve phone number ID
            if notification_settings.get('whatsapp_access_token'):
                phone_id = notification_settings.get('whatsapp_phone_number_id', '')

                # Update to new schema
                notification_settings['whatsapp_phone_number_id'] = phone_id
                notification_settings['whatsapp_display_phone_number'] = ''  # Admin will set

                # Remove old fields
                notification_settings.pop('whatsapp_access_token', None)
                notification_settings.pop('whatsapp_business_account_id', None)
                notification_settings.pop('whatsapp_api_version', None)

                settings.notification_settings = notification_settings

                print(f"Migrated tenant: {settings.tenant_id}")

        await session.commit()
        print("Migration complete!")

if __name__ == "__main__":
    asyncio.run(migrate())
```

---

## Troubleshooting

### Issue: Tenant doesn't receive WhatsApp messages

**Checklist:**
1. ✅ WhatsApp enabled in tenant settings?
2. ✅ Phone number assigned to tenant?
3. ✅ Master credentials configured in environment?
4. ✅ Template approved by Meta?
5. ✅ Recipient phone number in E.164 format (+34612345678)?

**Check Logs:**

```bash
# Notification service logs
docker logs -f notification-service | grep whatsapp

# Look for:
# - "Using tenant-assigned WhatsApp phone number"
# - "WhatsApp template message sent successfully"
# - Any error messages
```

### Issue: Phone number assignment fails

**Error:** "Phone number already assigned to another tenant"

**Solution:**
```bash
# Find which tenant has the phone number
curl http://localhost:8001/api/v1/admin/whatsapp/tenants | \
  jq '.[] | select(.phone_number_id == "123456789012345")'

# Unassign from old tenant first
curl -X DELETE http://localhost:8001/api/v1/admin/whatsapp/tenants/{old_tenant_id}/unassign-phone
```

### Issue: "WhatsApp master account not configured"

**Solution:**

Ensure environment variables are set:

```bash
# Check if variables exist
docker exec notification-service env | grep WHATSAPP

# Should show:
# WHATSAPP_BUSINESS_ACCOUNT_ID=...
# WHATSAPP_ACCESS_TOKEN=...
# WHATSAPP_PHONE_NUMBER_ID=...
```

### Issue: Template not found

**Error:** "Template po_notification not found"

**Solution:**

1. Create template in Meta Business Manager
2. Wait for approval (check status):
   ```bash
   curl -X GET "https://graph.facebook.com/v18.0/{WABA_ID}/message_templates" \
     -H "Authorization: Bearer {TOKEN}" \
     | jq '.data[] | select(.name == "po_notification")'
   ```
3. Ensure template language matches tenant's `whatsapp_default_language`

---

## Cost Analysis

### WhatsApp Business API Pricing (as of 2024)

**Meta Pricing:**
- **Business-initiated conversations:** €0.0319 - €0.0699 per conversation (Spain)
- **User-initiated conversations:** Free (24-hour window)
- **Conversation window:** 24 hours

**Monthly Cost Estimate (10 Bakeries):**
- Assume 5 PO notifications per bakery per day
- 5 × 10 bakeries × 30 days = 1,500 messages/month
- Cost: 1,500 × €0.05 = **€75/month**

**Shared Account vs. Individual Accounts:**

| Model | Setup Time | Monthly Cost | Support Burden |
|-------|------------|--------------|----------------|
| Individual Accounts | 1-2 hrs/bakery | €75 total | High |
| Shared Account | 5 min/bakery | €75 total | Low |

**Savings:** Time savings = 10 hrs × €50/hr = **€500 in setup cost**

---

## Future Enhancements

### Option 1: Template Management API

Automate template creation for new tenants:

```python
async def create_po_template(waba_id: str, access_token: str):
    """Programmatically create PO notification template"""
    url = f"https://graph.facebook.com/v18.0/{waba_id}/message_templates"
    payload = {
        "name": "po_notification",
        "language": "es",
        "category": "UTILITY",
        "components": [{
            "type": "BODY",
            "text": "Hola {{1}}, has recibido una nueva orden de compra {{2}} por un total de {{3}}."
        }]
    }
    response = await httpx.post(url, headers={"Authorization": f"Bearer {access_token}"}, json=payload)
    return response.json()
```

### Option 2: WhatsApp Embedded Signup

For scaling beyond pilot:

- Apply for Meta Business Solution Provider program
- Implement OAuth-style signup flow
- Users click "Connect WhatsApp" → auto-configured
- Estimated implementation: 2-4 weeks

### Option 3: Tiered Pricing

```
Basic Tier (Free):
- Email notifications only

Standard Tier (€29/month):
- Shared WhatsApp account
- Pre-approved templates
- Up to 500 messages/month

Enterprise Tier (€99/month):
- Own WhatsApp Business Account
- Custom templates
- Unlimited messages
- White-label phone number
```

---

## Security & Compliance

### Data Privacy

**GDPR Compliance:**
- WhatsApp messages contain supplier contact info (phone numbers)
- Ensure GDPR consent for sending notifications
- Provide opt-out mechanism
- Data retention: Messages stored for 90 days (configurable)

**Encryption:**
- WhatsApp messages: End-to-end encrypted by Meta
- Access tokens: Stored in environment variables (use secrets manager in production)
- Database: Encrypt `notification_settings` JSON column

### Access Control

**Admin Access:**
- Only platform admins can assign/unassign phone numbers
- Implement role-based access control (RBAC)
- Audit log for phone number assignments

```python
# Example: Add admin check
@router.post("/admin/whatsapp/tenants/{tenant_id}/assign-phone")
async def assign_phone(tenant_id: UUID, current_user = Depends(require_admin_role)):
    # Only admins can access
    pass
```

---

## Support & Contacts

**Meta Support:**
- WhatsApp Business API Support: https://business.whatsapp.com/support
- Developer Docs: https://developers.facebook.com/docs/whatsapp

**Platform Admin:**
- Email: admin@bakery-platform.com
- Phone number assignment requests
- Template approval assistance

**Bakery Owner Help:**
- Settings → Notifications → Toggle WhatsApp ON
- If phone number not showing: Contact support
- Language preferences can be changed anytime

---

## Appendix

### A. Database Schema Changes

**Migration Script:**

```sql
-- Add new field, remove old fields
-- services/tenant/migrations/versions/00002_shared_whatsapp_account.py

ALTER TABLE tenant_settings
  -- The notification_settings JSONB column now has:
  -- + whatsapp_display_phone_number (new)
  -- - whatsapp_access_token (removed)
  -- - whatsapp_business_account_id (removed)
  -- - whatsapp_api_version (removed)
;

-- No ALTER TABLE needed (JSONB is schema-less)
-- Migration handled by application code
```

### B. API Reference

**Phone Number Info Schema:**

```typescript
interface WhatsAppPhoneNumberInfo {
  id: string;                    // Meta Phone Number ID
  display_phone_number: string;  // E.164 format: +34612345678
  verified_name: string;          // Business name verified by Meta
  quality_rating: string;         // GREEN, YELLOW, RED
}
```

**Tenant WhatsApp Status Schema:**

```typescript
interface TenantWhatsAppStatus {
  tenant_id: string;
  tenant_name: string;
  whatsapp_enabled: boolean;
  phone_number_id: string | null;
  display_phone_number: string | null;
}
```

### C. Environment Variables Reference

```bash
# Notification Service (services/notification/.env)
WHATSAPP_BUSINESS_ACCOUNT_ID=    # Meta WABA ID
WHATSAPP_ACCESS_TOKEN=           # Meta System User Token
WHATSAPP_PHONE_NUMBER_ID=        # Default phone (fallback)
WHATSAPP_API_VERSION=v18.0       # Meta API version
ENABLE_WHATSAPP_NOTIFICATIONS=true
WHATSAPP_WEBHOOK_VERIFY_TOKEN=   # Random secret for webhook verification
```

### D. Useful Commands

```bash
# View all available phone numbers
curl http://localhost:8001/api/v1/admin/whatsapp/phone-numbers | jq

# View tenant WhatsApp status
curl http://localhost:8001/api/v1/admin/whatsapp/tenants | jq

# Assign phone to tenant
curl -X POST http://localhost:8001/api/v1/admin/whatsapp/tenants/{id}/assign-phone \
  -H "Content-Type: application/json" \
  -d '{"phone_number_id": "XXX", "display_phone_number": "+34 612 345 678"}'

# Unassign phone from tenant
curl -X DELETE http://localhost:8001/api/v1/admin/whatsapp/tenants/{id}/unassign-phone

# Test WhatsApp connectivity
curl -X GET "https://graph.facebook.com/v18.0/{PHONE_ID}" \
  -H "Authorization: Bearer {TOKEN}"

# Check message template status
curl "https://graph.facebook.com/v18.0/{WABA_ID}/message_templates?fields=name,status,language" \
  -H "Authorization: Bearer {TOKEN}" | jq
```

---

**Document Version:** 1.0
**Last Updated:** 2025-01-17
**Author:** Platform Engineering Team
**Status:** Production Ready for Pilot
