# language: fr
Fonctionnalité: Ciblage horaire publicités et gestion fuseaux horaires
  En tant que publicitaire
  Je veux cibler mes publicités sur des plages horaires en heure locale utilisateur
  Afin d'optimiser mes campagnes selon les moments de la journée (rush matin/soir)

  Contexte:
    Étant donné qu'un publicitaire crée une campagne publicitaire

  # Règle 1 : Ciblage horaire = Heure locale utilisateur

  Scénario: Campagne "7h-9h" diffuse selon heure locale de chaque utilisateur
    Étant donné qu'une campagne est configurée avec plage horaire "7h-9h"
    Et que nous sommes le 7 février 2026 à 8h00 UTC
    Quand le système vérifie la diffusion pour différents utilisateurs:
      | utilisateur     | localisation | fuseau horaire   | heure locale | diffusion ? |
      | User Marseille  | Marseille    | Europe/Paris     | 9h00         | ✅ Oui      |
      | User Guadeloupe | Pointe-à-Pitre | America/Guadeloupe | 4h00    | ❌ Non      |
      | User Réunion    | Saint-Denis  | Indian/Reunion   | 12h00        | ❌ Non      |
      | User Lyon       | Lyon         | Europe/Paris     | 9h00         | ✅ Oui      |
    Alors la pub est diffusée uniquement aux utilisateurs dans la plage 7h-9h leur heure locale

  Scénario: Campagne "17h-19h" (rush soir) - Heure locale de chaque utilisateur
    Étant donné qu'une campagne est configurée avec plage horaire "17h-19h"
    Et que nous sommes le 7 février 2026 à 17h30 UTC
    Quand le système vérifie la diffusion pour:
      | utilisateur     | fuseau horaire      | heure locale | diffusion ? |
      | User Paris      | Europe/Paris        | 18h30        | ✅ Oui      |
      | User Martinique | America/Martinique  | 13h30        | ❌ Non      |
      | User Réunion    | Indian/Reunion      | 21h30        | ❌ Non      |
    Alors la pub est diffusée uniquement à User Paris (18h30 dans 17h-19h)

  Scénario: Campagne 24/7 (toute la journée) - Pas de restriction horaire
    Étant donné qu'une campagne n'a AUCUNE restriction horaire
    Quand le système vérifie la diffusion
    Alors la pub est diffusée à tout moment (0h-23h)
    Et tous les utilisateurs sont éligibles quelle que soit l'heure locale

  # Détection fuseau horaire utilisateur

  Scénario: Détection fuseau via GPS (méthode primaire)
    Étant donné qu'un utilisateur a le GPS activé
    Et que sa position GPS est (latitude: 48.8566, longitude: 2.3522)
    Quand le système détecte le fuseau horaire
    Alors le fuseau horaire déterminé est "Europe/Paris"
    Et l'heure locale est calculée avec ce fuseau

  Scénario: Détection fuseau via paramètres device (si GPS désactivé)
    Étant donné qu'un utilisateur a le GPS désactivé
    Mais que les paramètres OS indiquent fuseau "America/Guadeloupe"
    Quand le système détecte le fuseau horaire
    Alors le fuseau horaire utilisé est "America/Guadeloupe"
    Et l'heure locale est calculée avec ce fuseau

  Scénario: Fallback IP geolocation (si GPS désactivé ET paramètres indisponibles)
    Étant donné qu'un utilisateur a le GPS désactivé
    Et que les paramètres device ne sont pas accessibles
    Mais que l'IP est géolocalisée à La Réunion
    Quand le système détecte le fuseau horaire
    Alors le fuseau horaire approximatif est "Indian/Reunion"
    Et l'heure locale est calculée avec ce fuseau

  # Règle 2 : Ciblage "France" = Métropole + DOM

  Scénario: Ciblage "France entière" inclut Métropole + DOM
    Étant donné qu'une campagne cible "France (nationale)"
    Quand le système vérifie les utilisateurs éligibles
    Alors les utilisateurs inclus sont:
      | zone                          | départements / territoires                     |
      | France métropolitaine         | 96 départements (01 à 95, 2A, 2B, etc.)       |
      | Guadeloupe                    | 971                                            |
      | Martinique                    | 972                                            |
      | Guyane                        | 973                                            |
      | Réunion                       | 974                                            |
      | Mayotte                       | 976                                            |

  Scénario: Publicitaire affine ciblage "Région Provence-Alpes-Côte d'Azur"
    Étant donné qu'une campagne cible "Région Provence-Alpes-Côte d'Azur"
    Quand le système vérifie les utilisateurs éligibles
    Alors seuls les utilisateurs en Métropole dans cette région sont ciblés
    Et les utilisateurs DOM (Guadeloupe, Réunion, etc.) ne sont PAS ciblés

  Scénario: Publicitaire affine ciblage "Département 971 (Guadeloupe)"
    Étant donné qu'une campagne cible "Département 971"
    Quand le système vérifie les utilisateurs éligibles
    Alors seuls les utilisateurs en Guadeloupe sont ciblés
    Et les utilisateurs Métropole ne sont PAS ciblés

  Scénario: Publicitaire affine ciblage "Ville Pointe-à-Pitre"
    Étant donné qu'une campagne cible "Ville Pointe-à-Pitre"
    Quand le système vérifie les utilisateurs éligibles
    Alors seuls les utilisateurs à Pointe-à-Pitre (Guadeloupe) sont ciblés

  # Interface publicitaire

  Scénario: Interface création campagne - Note explicite sur inclusion DOM
    Étant donné qu'un publicitaire accède au formulaire de création campagne
    Quand il sélectionne "National (France entière)"
    Alors une note informative s'affiche:
      """
      ℹ️ Note : "National (France entière)" inclut les DOM
      (Guadeloupe, Martinique, Réunion, Guyane, Mayotte)
      """

  Scénario: Interface - Liste déroulante ciblage géographique
    Étant donné qu'un publicitaire configure le ciblage géographique
    Quand il consulte la liste déroulante
    Alors les options disponibles sont:
      | option                        | description                                |
      | National (France entière)     | Métropole + DOM                            |
      | Région                        | Ex: Provence-Alpes-Côte d'Azur (Métropole)|
      | Département                   | Ex: 13 (Métropole) ou 971 (Guadeloupe)    |
      | Ville                         | Ex: Marseille, Pointe-à-Pitre              |
      | Point GPS + rayon             | Latitude/Longitude + rayon en km           |

  # Cas d'usage publicitaire

  Scénario: Restaurant local Guadeloupe - Ciblage département 971 + horaires 12h-14h
    Étant donné qu'un restaurant à Pointe-à-Pitre crée une campagne
    Et que le ciblage est "Département 971 (Guadeloupe)"
    Et que les horaires sont "12h-14h" (rush déjeuner)
    Quand le système diffuse les pubs à 12h30
    Alors les utilisateurs Guadeloupe à 12h30 heure locale reçoivent la pub
    Et les utilisateurs Métropole ne reçoivent PAS la pub (hors zone géo)
    Et les utilisateurs Martinique ne reçoivent PAS la pub (hors zone géo)

  Scénario: Assureur national - Ciblage France + horaires 7h-9h + 17h-19h
    Étant donné qu'un assureur national crée une campagne
    Et que le ciblage est "France (nationale)"
    Et que les horaires sont "7h-9h" et "17h-19h" (rush matin/soir)
    Quand le système diffuse les pubs
    Alors à 8h locale Marseille, User Marseille reçoit la pub
    Et à 8h locale Réunion, User Réunion reçoit la pub
    Et User Réunion reçoit la pub à 8h locale (= 5h métropole, mais c'est son rush matin)

  Scénario: Utilisateur en vacances change de fuseau horaire
    Étant donné qu'un utilisateur habite Paris (Europe/Paris)
    Et qu'il part en vacances à La Réunion
    Et qu'il télécharge 50 contenus + pubs avant de partir
    Quand l'utilisateur écoute à 8h locale Réunion (device détecte fuseau)
    Alors le filtrage des pubs utilise l'heure locale Réunion (8h)
    Et les pubs ciblées "7h-9h" sont diffusées normalement

  # Implémentation technique

  Scénario: Calcul heure locale via PostgreSQL AT TIME ZONE
    Étant donné qu'une campagne a une plage horaire "7h-9h"
    Et qu'un utilisateur a le fuseau "Indian/Reunion" (UTC+4)
    Quand le backend vérifie l'éligibilité à 08h00 UTC
    Alors la requête SQL utilise:
      """sql
      SELECT
        EXTRACT(HOUR FROM NOW() AT TIME ZONE 'Indian/Reunion') AS local_hour
      -- Résultat: 12 (8h UTC + 4h = 12h locale)
      """
    Et local_hour = 12 n'est PAS dans [7, 8, 9], donc pas de diffusion

  Scénario: Base IANA Time Zone pour conversion GPS → fuseau
    Étant donné qu'un utilisateur a GPS (48.8566, 2.3522)
    Quand le système convertit GPS → fuseau horaire
    Alors la base IANA Time Zone est utilisée
    Et le fuseau déterminé est "Europe/Paris"
    Et la base est mise à jour régulièrement (changements DST, fuseaux)

  # Justification

  Scénario: Comparaison avec standard industrie - Google Ads, Facebook Ads
    Étant donné qu'on compare avec Google Ads et Facebook Ads
    Quand on évalue le comportement du ciblage horaire
    Alors RoadWave suit le standard:
      | plateforme   | ciblage horaire         | référence temporelle | norme       |
      | Google Ads   | 7h-9h                   | Heure locale user    | ✅ Standard |
      | Facebook Ads | 7h-9h                   | Heure locale user    | ✅ Standard |
      | RoadWave     | 7h-9h                   | Heure locale user    | ✅ Standard |

  Scénario: Avantages UX intuitive pour publicitaires
    Étant donné qu'un publicitaire configure "7h-9h"
    Quand il pense "rush matin"
    Alors il n'a pas besoin de comprendre UTC
    Et "7h-9h" signifie "matin partout en France"
    Et l'UX est intuitive:
      | avantage                      | description                                  |
      | UX intuitive publicitaires    | "7h-9h" = matin partout, pas UTC compliqué   |
      | Équité géographique           | Pas de discrimination DOM-TOM                |
      | Simplicité technique          | Détection automatique fuseau (GPS/device)    |
      | Standard industrie            | Même comportement Google/Facebook            |

  # Cas limites

  Scénario: Utilisateur change de fuseau pendant campagne active
    Étant donné qu'un utilisateur écoute des pubs en métropole (Europe/Paris)
    Et qu'une campagne cible "7h-9h"
    Quand l'utilisateur part en vacances Réunion (Indian/Reunion)
    Alors le système détecte le nouveau fuseau horaire automatiquement
    Et les pubs "7h-9h" sont filtrées selon l'heure locale Réunion
    Et l'utilisateur reçoit les pubs à 7h-9h heure locale Réunion

  Scénario: Changement heure d'été/hiver (DST) - Gestion automatique
    Étant donné qu'une campagne cible "7h-9h" en Europe/Paris
    Et que le changement heure d'été arrive (dernier dimanche mars)
    Quand l'heure passe de 2h à 3h (UTC+1 → UTC+2)
    Alors le système utilise automatiquement le nouveau décalage UTC
    Et les pubs "7h-9h" continuent de se diffuser à 7h-9h heure locale
    Et PostgreSQL AT TIME ZONE gère automatiquement le DST

  # Métriques dashboard publicitaire

  Scénario: Dashboard publicitaire - Répartition géographique diffusions
    Étant donné qu'une campagne "France (nationale)" + "7h-9h" est active
    Quand le publicitaire consulte le dashboard
    Alors la répartition géographique affiche:
      | zone                | impressions | % total |
      | Île-de-France       | 45,000      | 60%     |
      | Provence-Alpes      | 15,000      | 20%     |
      | Guadeloupe          | 3,000       | 4%      |
      | Réunion             | 4,500       | 6%      |
      | Autres              | 7,500       | 10%     |

  Scénario: Dashboard publicitaire - Répartition horaire diffusions
    Étant donné qu'une campagne "7h-9h" est active
    Quand le publicitaire consulte le dashboard
    Alors un graphique horaire affiche:
      | heure locale | impressions |
      | 7h           | 12,000      |
      | 8h           | 18,000      |
      | 9h           | 5,000       |
    Et les impressions hors plage (autres heures) = 0

  Scénario: Validation création campagne - Cohérence géo + horaires
    Étant donné qu'un publicitaire crée une campagne
    Et qu'il sélectionne "Département 971 (Guadeloupe)"
    Et qu'il configure horaires "7h-9h"
    Quand il valide la campagne
    Alors le système confirme:
      """
      Votre campagne sera diffusée à 7h-9h heure locale Guadeloupe (UTC-4).
      Estimation: 2,500 impressions/jour.
      """
