# 🔍 Microservice de Recherche Intelligente - Symfony

**Recherche intelligente avec IA pour remplacer votre input de recherche classique**

Ce microservice Symfony utilise OpenAI pour analyser les requêtes et proposer les contenus les plus pertinents de votre base de données.

## ⚡ Installation Rapide

```bash
# 1. Installer
./install.sh

# 2. Configurer la clé OpenAI
nano .env
# Modifier: OPENAI_API_KEY=sk-your-real-key-here

# 3. Démarrer
./start.sh
```

Le service sera disponible sur `http://localhost:8003`

## 🎯 Fonctionnalités

### IA Avancée
- **Analyse OpenAI** : Extrait mots-clés, concepts et technologies
- **Résumés individuels** : Chaque contenu trouvé a son résumé IA personnalisé
- **Scoring intelligent** : Pertinence calculée automatiquement  
- **Filtrage contextuel** : Évite les résultats non pertinents (ex: HTML pour requête "API")
- **Fallback automatique** : Bascule vers recherche classique si IA indisponible

### Exemple Concret
```
Requête: "comment faire une fonction javascript"
↓
IA analyse: ["fonction", "javascript"] + concepts + technologies
↓  
Recherche dans votre contenu avec scores
↓
Résultats triés par pertinence
```

## 📡 API Endpoints

### POST /api/search/intelligent
**Recherche IA complète**

```bash
curl -X POST http://localhost:8003/api/search/intelligent \
  -H "Content-Type: application/json" \
  -d '{"query": "fonction javascript", "limit": 10}'
```

**Structure JSON reçue par le frontend :**
```json
{
  "success": true,
  "query": "comment faire une api",
  "results": [
    {
      "id": 123,
      "title": "Créer une API REST avec Symfony",
      "content": "Guide complet pour développer une API...",
      "code": "<?php\nclass ApiController extends AbstractController...",
      "summary": "Guide détaillé sur la création d'APIs REST avec Symfony, couvrant l'authentification, la sérialisation et les bonnes pratiques.",
      "relevanceScore": 85,
      "category": {
        "id": 2,
        "name": "Backend",
        "slug": "backend"
      },
      "menu": {
        "id": 15,
        "label": "APIs",
        "icon": "api"
      },
      "page": {
        "id": 45,
        "title": "Guide API Symfony",
        "slug": "api-symfony-guide"
      },
      "createdAt": "2024-01-15T10:30:00+00:00",
      "updatedAt": "2024-01-20T14:22:00+00:00"
    },
    {
      "id": 124,
      "title": "Authentification JWT pour APIs",
      "content": "Implémenter l'authentification JWT dans votre API...",
      "summary": "Explique l'implémentation de l'authentification JWT avec des exemples pratiques de middleware et gestion des tokens.",
      "relevanceScore": 72,
      "category": {
        "id": 3,
        "name": "Sécurité",
        "slug": "securite"
      }
    }
  ],
  "analysis": {
    "keywords": ["api", "faire", "comment"],
    "concepts": ["développement", "backend"],
    "technologies": ["symfony", "php"],
    "intent": "Apprendre à créer une API"
  },
  "total": 12,
  "execution_time": 2250.8,
  "timestamp": "2024-01-25T15:45:30+00:00",
  "service": "Intelligent Search (Symfony)"
}
```

**Réponse en cas d'erreur :**
```json
{
  "success": false,
  "error": "La requête est obligatoire",
  "details": "Message d'erreur détaillé (dev seulement)",
  "timestamp": "2024-01-25T15:45:30+00:00"
}
```

### GET /api/search?q=query&limit=10
**Recherche simple (fallback rapide)**

```bash
curl "http://localhost:8003/api/search?q=api&limit=5"
```

**Structure JSON (recherche simple) :**
```json
{
  "success": true,
  "query": "api",
  "results": [
    {
      "id": 123,
      "title": "API REST Symfony",
      "content": "Guide pour créer des APIs...",
      "relevanceScore": 8,
      "category": {"name": "Backend"}
    }
  ],
  "total": 3,
  "timestamp": "2024-01-25T15:45:30+00:00",
  "service": "Simple Search (Symfony)"
}
```
*Note : La recherche simple ne contient pas les champs `analysis` et `summary`*

### GET /api/search/health
**Status du service**

```json
{
  "status": "OK",
  "service": "Intelligent Search Service",
  "version": "1.0.0",
  "framework": "Symfony 7.0.x",
  "php_version": "8.2.x",
  "timestamp": "2024-01-25T15:45:30+00:00",
  "environment": "prod"
}
```

## 🏗️ Architecture

```
src/
├── Controller/SearchController.php    # API endpoints
├── Service/
│   ├── OpenAIService.php             # Intégration OpenAI
│   ├── ContentFetcherService.php     # Récupération contenu
│   └── IntelligentSearchService.php  # Logique recherche
└── Kernel.php                        # Symfony kernel

config/
├── packages/
│   ├── framework.yaml               # Config Symfony
│   └── nelmio_cors.yaml            # CORS
└── services.yaml                   # Services DI
```

## ⚙️ Configuration

### .env
```env
# Symfony
APP_ENV=prod
APP_SECRET=your_secret_key

# Service
SERVER_PORT=8003
OPENAI_API_KEY=sk-your-openai-key-here
MAIN_API_BASE_URL=http://localhost:8000/api
```

## 🎯 Système de Scoring

- **Mots-clés** : +10 points
- **Concepts** : +8 points
- **Technologies** : +15 points  
- **Titre match** : +20 points bonus
- **Catégorie tech** : +25 points bonus

## 🔄 Intégration Frontend

### Traitement des réponses JSON

```javascript
// Exemple d'intégration Vue.js/React
const handleSearchResponse = (response) => {
  // Structure de base (toujours présente)
  const {
    success,
    query,
    results = [],
    total = 0,
    timestamp,
    service
  } = response;

  if (!success) {
    console.error('Erreur recherche:', response.error);
    return;
  }

  // Champs spécifiques à la recherche intelligente
  const {
    analysis,      // Analyse OpenAI (peut être null)
    execution_time // Temps d'exécution en ms
  } = response;

  // Traiter chaque résultat
  results.forEach(result => {
    const {
      id,
      title,
      content,
      code,               // Code source (peut être vide)
      summary,            // Résumé individuel du contenu (peut être null)
      relevanceScore,     // Score de pertinence
      category: { name: categoryName },
      menu: { label: menuLabel, icon },
      page: { slug: pageSlug }
    } = result;
    
    // Afficher le résultat avec son résumé individuel
    displaySearchResult(result, summary);
  });

  // Informations de debug/monitoring
  console.log(`Recherche "${query}" : ${total} résultats en ${execution_time}ms`);
};

// Service de recherche recommandé
class SearchService {
  static async intelligentSearch(query, limit = 10) {
    const response = await fetch('/api/search/intelligent', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ query, limit })
    });
    return await response.json();
  }

  static async simpleSearch(query, limit = 10) {
    const response = await fetch(`/api/search?q=${encodeURIComponent(query)}&limit=${limit}`);
    return await response.json();
  }

  static async healthCheck() {
    const response = await fetch('/api/search/health');
    return await response.json();
  }
}
```

### Exemple d'utilisation complète

```javascript
// Dans votre composant de recherche
const performSearch = async (userQuery) => {
  try {
    // 1. Vérifier la santé du service
    const health = await SearchService.healthCheck();
    
    if (health.status !== 'OK') {
      throw new Error('Service indisponible');
    }

    // 2. Lancer la recherche intelligente
    const result = await SearchService.intelligentSearch(userQuery);
    
    if (result.success) {
      // 3. Traiter la réponse
      handleSearchResponse(result);
      
      // 4. Utiliser les résumés individuels pour l'UX
      result.results.forEach(item => {
        if (item.summary) {
          showIndividualSummary(item.id, item.summary);
        }
      });
    }
    
  } catch (error) {
    console.error('Erreur recherche:', error);
    // Fallback vers recherche simple ou API principale
    fallbackSearch(userQuery);
  }
};
```

### Types TypeScript (optionnel)

```typescript
interface SearchResult {
  id: number;
  title: string;
  content: string;
  code?: string;
  summary?: string;  // Résumé individuel généré par IA
  relevanceScore: number;
  category: {
    id: number;
    name: string;
    slug: string;
  };
  menu: {
    id: number;
    label: string;
    icon: string;
  };
  page: {
    id: number;
    title: string;
    slug: string;
  };
  createdAt: string;
  updatedAt: string;
}

interface SearchResponse {
  success: boolean;
  query: string;
  results: SearchResult[];  // Chaque résultat peut contenir son résumé individuel
  analysis?: {
    keywords: string[];
    concepts: string[];
    technologies: string[];
    intent: string;
  };
  total: number;
  execution_time?: number;
  timestamp: string;
  service: string;
}
```

## 🧪 Tests

```bash
# Santé
curl http://localhost:8003/api/search/health

# Recherche IA  
curl -X POST http://localhost:8003/api/search/intelligent \
  -H "Content-Type: application/json" \
  -d '{"query": "css flexbox", "limit": 5}'

# Recherche simple
curl "http://localhost:8003/api/search?q=php&limit=3"

# Debug (dev seulement)
curl http://localhost:8003/api/search/debug
```

## 🛡️ Sécurité & Performance

- **CORS configuré** pour vos domaines
- **Validation entrées** utilisateur
- **Timeouts** et gestion d'erreurs
- **Logging complet** pour monitoring
- **Cache intelligent** (extensible)

## 🚀 Déploiement Production

### Déploiement automatisé
```bash
# Déploiement complet en production
./deploy-prod.sh

# Monitoring du service
./monitor.sh status        # Statut actuel
./monitor.sh monitor       # Monitoring continu
./monitor.sh restart       # Redémarrage
./monitor.sh logs          # Logs temps réel
```

### Optimisations production incluses
- ✅ **Cache Redis/APCu** : Résultats de recherche, analyses OpenAI
- ✅ **Limitations OpenAI** : Max 5 résumés individuels pour réduire les coûts
- ✅ **Logs optimisés** : Niveau WARNING+, rotation automatique
- ✅ **Autoloader optimisé** : Performance maximale
- ✅ **Tests de santé** : Monitoring automatique
- ✅ **Rollback automatique** : Sécurité en cas d'échec

### Configuration production
```env
# .env optimisé
APP_ENV=prod
APP_DEBUG=0
OPENAI_MAX_SUMMARIES=5
OPENAI_TIMEOUT=10
OPENAI_MAX_TOKENS_SUMMARY=80
```

### Avec serveur web (recommandé)
```nginx
# Configuration Nginx
server {
    listen 80;
    server_name search.mondomaine.com;
    root /path/to/search-service/public;
    
    location / {
        try_files $uri /index.php$is_args$args;
    }
    
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
```

## 💰 Optimisation des Coûts OpenAI

### Stratégies mises en place
- **Cache intelligent** : Les analyses de requêtes sont mises en cache 24h
- **Limitation des résumés** : Maximum 5 résumés individuels par recherche
- **Tokens réduits** : 80 tokens max par résumé (vs 400 par défaut)
- **Timeouts courts** : 10s pour éviter les appels longs et coûteux
- **Fallback local** : Résumés basiques si OpenAI échoue

### Estimation des coûts (GPT-4o-mini)
```
Coût par recherche intelligente :
- Analyse requête : ~0.001$ (1 appel)
- 5 résumés : ~0.002$ (5 appels)
- Total : ~0.003$ par recherche

Cache hit rate 70% = réduction 70% des coûts
```

## 📊 Monitoring Production

### Logs structurés
```bash
# Logs généraux (WARNING+)
tail -f var/log/prod.log

# Logs critiques uniquement
tail -f var/log/critical.log

# Monitoring OpenAI (coûts)
tail -f var/log/openai.log

# Performances
tail -f var/log/performance.log
```

### Métriques clés à surveiller
- **Temps de réponse** : < 2s pour les recherches
- **Cache hit rate** : > 60% pour l'efficacité
- **Erreurs OpenAI** : < 5% des appels
- **Utilisation mémoire** : < 80%
- **Espace disque** : logs rotation automatique

---

## 🎉 C'est prêt !

Votre recherche intelligente remplace maintenant l'input classique avec :
- ✅ Analyse IA des requêtes
- ✅ Scoring de pertinence avancé  
- ✅ Fallback automatique
- ✅ Intégration transparente

**Exemple** : "comment faire une fonction js" → Pages JavaScript triées par pertinence IA ! 🚀