# Intégration de l’IA externe — DOUAWÊ WIFI

## Objectif

Enrichir l’assistant métier existant avec un modèle LLM externe (OpenRouter / modèles open-source), **sans reconstruire** l’application et **sans toucher** au serveur WireGuard.

Les calculs financiers et stocks restent 100 % effectués par Laravel. L’IA explique, synthétise et recommande à partir d’un contexte déjà calculé et filtré.

---

## Fichiers ajoutés

| Fichier | Rôle |
|---------|------|
| `app/Services/Ai/ExternalAiService.php` | Client HTTP unique vers l’API compatible OpenAI (OpenRouter). Gestion 429, timeouts, erreurs. |
| `app/Services/Ai/AiContextBuilder.php` | Construit un contexte agrégé (CA, soldes, routeurs, types de tickets…) filtré par droits et `space_id`. |
| `docs/INTEGRATION_IA_EXTERNE.md` | Cette documentation. |

## Fichiers modifiés

| Fichier | Modification |
|---------|--------------|
| `app/Services/Assistant/BusinessQuestions.php` | Constructeur + fallback `externalOrUnsupported()` pour les questions non reconnues. Les intents connus (stock, solde, CA…) restent 100 % locaux. |
| `config/services.php` | Section `ai` (enabled, provider, base_url, api_key, model, timeout, max_tokens). |
| `.env.example` | Variables `AI_*` documentées, désactivées par défaut. |

**Aucun autre fichier métier, route, contrôleur de tickets ou configuration réseau n’a été modifié.**

---

## Configuration

Dans le `.env` de production (ou de test) :

```env
AI_ENABLED=true
AI_PROVIDER=openrouter
AI_BASE_URL=https://openrouter.ai/api/v1
AI_API_KEY=sk-or-v1-xxxxxxxxxxxxxxxx
AI_MODEL=qwen/qwen-2.5-72b-instruct:free
AI_TIMEOUT=25
AI_MAX_TOKENS=1200
```

Puis :

```bash
php artisan config:clear
# ou, en production après vérification :
php artisan config:cache
```

### Modèles recommandés (gratuits ou très bas coût sur OpenRouter)

- `qwen/qwen-2.5-72b-instruct:free`
- `deepseek/deepseek-chat:free`
- `mistralai/mistral-7b-instruct:free`
- `google/gemma-2-9b-it:free`

Vérifier les licences et la disponibilité sur [openrouter.ai/models](https://openrouter.ai/models) avant usage commercial.

### Désactivation

```env
AI_ENABLED=false
```

ou suppression de `AI_API_KEY`. L’assistant local continue de fonctionner exactement comme avant.

---

## Fonctionnement

1. L’utilisateur pose une question via `/assistant`.
2. Laravel authentifie et applique les permissions.
3. `BusinessQuestions` détecte l’intention :
   - **Intention connue** (stock, solde, CA, offline…) → réponse locale exacte (services métier).
   - **Question ouverte** → si IA activée et droits OK → `AiContextBuilder` prépare un contexte agrégé → `ExternalAiService` appelle le modèle → réponse affichée.
4. En cas d’erreur fournisseur (429, timeout, clé invalide…) → message clair, **pas d’erreur HTTP 500**, fonctions métier intactes.
5. Chaque échange est journalisé dans `assistant_logs` (intent `ai_external` ou statut `ai_unavailable`).

### Génération de tickets

`TicketAiService` n’a **pas** été modifié. La génération locale + validation humaine obligatoire restent inchangées.

---

## Sécurité

- La clé API ne sort jamais du serveur (jamais dans le JS client, les logs applicatifs sensibles, ni le dépôt).
- L’IA ne reçoit que le texte de la question + un résumé agrégé (pas de lignes brutes de ventes, pas de mots de passe, pas d’IP détaillées).
- Rate-limit existant sur la route `assistant.ask` (`throttle:30,1`) conservé.
- Les revendeurs n’ont pas accès aux analyses ouvertes (même règle qu’avant).

---

## Tests recommandés (avant production)

1. Sauvegarde fichiers + base.
2. Environnement de test séparé.
3. `AI_ENABLED=false` → comportement identique à l’existant.
4. `AI_ENABLED=true` + clé valide → question ouverte (« Quelles sont les recettes de ce mois et quels revendeurs performent le mieux ? »).
5. Question métier exacte (« Quel est le stock de Nina ? ») → réponse locale, pas d’appel IA.
6. Clé invalide / 401 → message clair, pas de 500.
7. Simulation timeout / 429 → message clair.
8. Génération de tickets + validation humaine → inchangée.
9. Pages existantes (dashboard, allocations, ventes…) → OK.
10. `php artisan route:list` et permissions inchangées.

---

## Retour arrière

1. Mettre `AI_ENABLED=false` (ou retirer `AI_API_KEY`).
2. Optionnel : supprimer les deux fichiers `app/Services/Ai/*`.
3. Restaurer les trois fichiers modifiés depuis la sauvegarde si besoin.
4. `php artisan config:clear`.

Aucun changement de schéma de base n’a été nécessaire.

---

## Limites et coûts

- Les forfaits gratuits OpenRouter ont des quotas journaliers / de débit variables.
- Surveiller l’usage sur le tableau de bord OpenRouter.
- Aucun abonnement n’est activé automatiquement par cette intégration.
- Pour un usage intensif, prévoir un modèle payant à bas coût ou un second fournisseur (configurable via les mêmes variables).

---

## Critères d’acceptation couverts

- [x] IA externe répond depuis l’interface existante (quand activée).
- [x] Données métier calculées par Laravel.
- [x] Génération de tickets + validation humaine conservées.
- [x] Autorisations respectées.
- [x] Erreurs fournisseur gérées sans 500 global.
- [x] Fonctionnalités existantes préservées.
- [x] Aucune modification WireGuard / réseau.
- [x] Installation et retour arrière documentés.
