EduLab / documentation /TRACKING_INTEGRATION.md
rinogeek's picture
Initial deploy to Hugging Face
062d102

📊 Intégration du Tracking - Résumé

✅ Pages Intégrées

Le système de tracking des recherches a été intégré dans les pages suivantes :

1. Questions (/questions)

Catégorie : QUESTIONS

Ce qui est tracké :

  • Terme de recherche saisi
  • Filtre appliqué : all, solved, unsolved
  • Numéro de page
  • Nombre de résultats retournés

Implémentation :

const { trackSearch } = useSearchTracking('QUESTIONS');

// Fetch questions with debounce (300ms for quick UX)
useEffect(() => {
  const timer = setTimeout(() => {
    fetchQuestions();
  }, 300);
  return () => clearTimeout(timer);
}, [filter, searchTerm, currentPage]);

// Track search separately with longer debounce (800ms - user has stopped typing)
useEffect(() => {
  if (searchTerm.trim().length >= 2) {
    const trackTimer = setTimeout(() => {
      trackSearch(
        searchTerm,
        { 
          filter: filter !== 'all' ? filter : undefined,
          page: currentPage 
        },
        totalCount
      );
    }, 800);
    return () => clearTimeout(trackTimer);
  }
}, [searchTerm, filter, currentPage, totalCount]);

Stratégie de Debounce :

  • Fetch : 300ms (UX rapide, résultats s'affichent vite)
  • Tracking : 800ms (l'utilisateur a vraiment fini de taper)
  • Minimum : 2 caractères pour éviter le bruit

Pourquoi 2 niveaux ?

  • L'utilisateur voit les résultats rapidement (300ms)
  • Mais on ne track que la recherche finale (800ms)
  • Évite de polluer les analytics avec "p", "py", "pyt", etc.

2. Mentors (/mentors)

Catégorie : MENTORS

Ce qui est tracké :

  • Terme de recherche (nom ou bio)
  • Pays sélectionné
  • Spécialité sélectionnée
  • Tri appliqué (rating, reviews)
  • Nombre de résultats filtrés

Implémentation :

const { trackSearch } = useSearchTracking('MENTORS');

// Track search with debounce (only when user stops typing)
useEffect(() => {
  if (searchTerm.trim().length >= 2) {
    const timer = setTimeout(() => {
      trackSearch(
        searchTerm,
        {
          country: selectedCountry !== 'All' ? selectedCountry : undefined,
          specialty: selectedSpecialty !== 'All' ? selectedSpecialty : undefined,
          sortBy
        },
        filteredMentors.length
      );
    }, 800);
    return () => clearTimeout(timer);
  }
}, [searchTerm, selectedCountry, selectedSpecialty, sortBy, filteredMentors.length]);

Debounce : 800ms (filtrage local, pas de fetch API)


3. Opportunities (/opportunities)

Catégorie : OPPORTUNITIES

Ce qui est tracké :

  • Type d'opportunité sélectionné (filtre)
  • Nombre de résultats correspondants

Implémentation :

const { trackSearch } = useSearchTracking('OPPORTUNITIES');

// Track filter changes
useEffect(() => {
  if (filter !== 'All') {
    trackSearch(
      filter,
      { type: filter },
      filteredOpportunities.length
    );
  }
}, [filter, filteredOpportunities.length]);

Note : Pas de debounce car c'est un clic sur un bouton, pas une saisie


📈 Données Collectées

Pour chaque recherche, le système enregistre :

Champ Description Exemple
user Utilisateur connecté (ou null) user_id: 123
category Type de recherche QUESTIONS
search_query Terme recherché "python django"
filters_applied Filtres JSON {"filter": "unsolved", "page": 2}
results_count Nombre de résultats 15
session_id ID de session Auto
ip_address IP de l'utilisateur Auto
user_agent Navigateur Auto
page_url URL de la page Auto
created_at Timestamp Auto

🎯 Prochaines Étapes Suggérées

Pages à Intégrer Ensuite

  1. Tools (/tools)

    • Catégorie : TOOLS
    • Recherche d'outils pédagogiques
  2. Recherche Globale (si existe)

    • Catégorie : GENERAL
    • Barre de recherche dans le header
  3. Users (si page de recherche d'utilisateurs existe)

    • Catégorie : USERS

Fonctionnalités Avancées

  1. Tracking des Clics

    • Utiliser trackClick() quand un utilisateur clique sur un résultat
    • Exemple dans Questions :
    const { trackClick } = useSearchTracking('QUESTIONS');
    
    <QuestionCard 
      onClick={() => trackClick(null, question.id, index)}
    />
    
  2. Suggestions Autocomplete

    • Utiliser analyticsService.getPopularSearches() pour suggérer des recherches populaires
    • Afficher en dessous de la barre de recherche
  3. Dashboard Analytics

    • Créer une page admin pour visualiser :
      • Top 10 des recherches
      • Tendances de la semaine
      • Recherches sans résultats
      • Taux de clic par catégorie

🔍 Exemples de Requêtes Utiles

Recherches les plus populaires cette semaine

SELECT search_query, COUNT(*) as count
FROM search_logs
WHERE category = 'QUESTIONS'
  AND created_at >= NOW() - INTERVAL '7 days'
GROUP BY search_query
ORDER BY count DESC
LIMIT 10;

Recherches sans résultats (lacunes de contenu)

SELECT search_query, COUNT(*) as count
FROM search_logs
WHERE results_count = 0
  AND created_at >= NOW() - INTERVAL '30 days'
GROUP BY search_query
ORDER BY count DESC
LIMIT 20;

Filtres les plus utilisés

SELECT 
  category,
  jsonb_object_keys(filters_applied) as filter_key,
  COUNT(*) as usage_count
FROM search_logs
WHERE filters_applied != '{}'::jsonb
GROUP BY category, filter_key
ORDER BY usage_count DESC;

✨ Bonnes Pratiques Appliquées

  1. Debounce : Évite de tracker chaque frappe (300-500ms)
  2. Minimum 2 caractères : Ne track que si searchTerm.trim() existe
  3. Non-bloquant : Tracking async, n'affecte pas l'UX
  4. Gestion d'erreurs : Le tracking échoue silencieusement si l'API est down
  5. Respect de la vie privée : IP et User Agent pour analytics, pas de données sensibles
  6. Flexible : Filtres en JSON permettent d'ajouter de nouveaux critères sans migration

📊 Métriques Disponibles

Avec ce système, vous pouvez maintenant répondre à :

  • Quels sujets intéressent le plus les étudiants ?
  • 🔍 Quelles recherches ne donnent aucun résultat ? (opportunités de contenu)
  • 🌍 Quels pays recherchent quels mentors ?
  • 📈 Quelles sont les tendances émergentes ?
  • 🎯 Les filtres sont-ils utilisés ? Lesquels ?
  • À quelles heures les utilisateurs recherchent-ils le plus ?

Système opérationnel et prêt à collecter des insights précieux ! 🚀

Développé avec ❤️ par Marino ATOHOUN pour Hypee