# Solution : SMS Callback Multi-Tenant Sans Paramètres d'URL

## 🎯 Problème résolu

Vous aviez raison ! On ne peut pas mettre un lien fixe avec `?tenantId=6` dans Twilio Dashboard car il doit fonctionner pour **tous les tenants**.

## ✅ Solution implémentée

**Identification automatique du tenant via le numéro Twilio** (même logique que les appels entrants)

### Comment ça fonctionne

```
📱 Callback Twilio arrive
    ↓
🔍 Extraction du numéro Twilio (From)
    ↓
🏢 Lookup dans TwilioPhoneNumber (table admin)
    ↓
🎯 Récupération du tenantId
    ↓
📊 Lookup dans Tenant pour obtenir schemaName
    ↓
🔄 Switch vers le schéma tenant
    ↓
💾 Mise à jour du statut SMS
```

### Code implémenté

**TwilioSmsCallbackController.java** (lignes 57-102) :

```java
// STEP 1: Identifier le tenant via le numéro Twilio
TenantContext.setTenantId("admin"); // Admin context pour lookup
Optional<TwilioPhoneNumber> twilioPhone = twilioPhoneNumberRepository.findByPhoneNumber(from);
String tenantId = twilioPhone.get().getTenantId();

// STEP 2: Récupérer le schéma du tenant
Optional<Tenant> tenant = tenantRepository.findByTenantId(tenantId);
String schemaName = tenant.get().getSchemaName();

// STEP 3: Switch vers le schéma tenant
TenantContext.setTenantId(schemaName);

// STEP 4: Mettre à jour le statut SMS
inboundCallService.updateSmsStatus(messageSid, messageStatus);

// STEP 5: Nettoyer le contexte
TenantContext.clear();
```

## 🎨 Architecture

### Flux complet SMS avec callback

```
1️⃣ Patient confirme RDV
   → OpenAI détecte appointmentConfirmed=true
   
2️⃣ Envoi SMS
   → TwilioSmsService.sendAppointmentConfirmationSms()
   → statusCallbackUrl = SERVER_BASE_URL + "/api/voip/sms/status-callback"
   → SMS envoyé avec callback URL
   → smsSent=true, smsSid="SM123...", smsStatus="queued"
   
3️⃣ Callback Twilio #1 (queued → sent)
   → From = +1234567890 (numéro Twilio)
   → MessageSid = SM123...
   → MessageStatus = "sent"
   → Lookup tenant via From
   → Update smsStatus="sent"
   
4️⃣ Callback Twilio #2 (sent → delivered)
   → MessageStatus = "delivered"
   → Lookup tenant via From
   → Update smsStatus="delivered" ✅
```

## 📝 Fichiers modifiés

### Nouveaux fichiers
- ✅ `TwilioSmsCallbackController.java` - Endpoint webhook avec identification automatique du tenant

### Fichiers modifiés
- ✅ `InboundCallRequest.java` - Ajout du champ `smsStatus`
- ✅ `InboundCallService.java` - Méthode `updateSmsStatus(smsSid, smsStatus)`
- ✅ `InboundCallRequestRepository.java` - Méthode `findBySmsSid(String smsSid)`

### Documentation
- ✅ `docs/SMS_TRACKING.md` - Guide complet
- ✅ `docs/SMS_CALLBACK_SOLUTION.md` - Ce fichier
- ✅ `replit.md` - Mise à jour architecture

## 🔧 Configuration requise

### .env
```bash
SERVER_BASE_URL=https://your-ngrok-url.ngrok.io
```

### Twilio (optionnel - déjà dans le code)
Le callback est automatiquement ajouté lors de l'envoi du SMS. Pas besoin de configuration dans Twilio Dashboard !

## ✨ Avantages de cette solution

✅ **Une seule URL** pour tous les tenants
✅ **Aucun paramètre** dans l'URL de callback
✅ **Identification automatique** via le numéro Twilio
✅ **Sécurisé** - Le tenant est déterminé côté serveur
✅ **Compatible** avec l'architecture existante (même pattern que les appels entrants)
✅ **Maintenable** - Pas de URLs différentes à gérer

## 🧪 Test

```bash
# 1. Démarrer ngrok
ngrok http 8000

# 2. Mettre à jour .env
SERVER_BASE_URL=https://abc123.ngrok.io

# 3. Relancer l'app
mvn spring-boot:run

# 4. Faire un appel test
# 5. Confirmer un RDV

# 6. Vérifier les logs :
# 📬 Callback SMS reçu - SID: SM123... | Statut: sent | From (Twilio): +1234567890
# 🏢 Tenant identifié via numéro Twilio +1234567890 → Tenant ID: acme_corp | Schema: tenant_acme_corp
# ✅ Statut SMS mis à jour dans tenant_acme_corp : SM123... → delivered
```

## 📊 Base de données

### Vérifier le statut SMS

```sql
-- Dans le schéma tenant (ex: tenant_acme_corp)
SELECT 
    call_sid,
    nom,
    telephone,
    sms_sent,
    sms_sid,
    sms_status,
    appointment_confirmed,
    created_at
FROM inbound_call_requests 
WHERE sms_sent = true 
ORDER BY created_at DESC;
```

### Statuts possibles
- `queued` - En attente d'envoi
- `sent` - Envoyé par Twilio
- `delivered` - Délivré au téléphone du patient ✅
- `failed` - Échec de livraison ❌
- `undelivered` - Non délivré ❌

## 🚀 Prêt pour la production !

Le système est maintenant complètement fonctionnel et multi-tenant ready 🎉
