# ADR-005 — Auto-migration runtime `auto` → `force_ga4` quand GA4 ID configuré
*Date : 2026-05-13 — Session 2*
*Statut : Accepté*

## Contexte
Après déploiement du module Analytics (v1.0.0), les events `nxt_cta_click` arrivaient dans `window.dataLayer` mais n'atteignaient jamais GA4.

**Cause racine :** `ensureGtag()` vérifiait `if (typeof window.gtag === 'function') return` avant d'injecter `gtag.js`. Sur les sites avec GTM, GTM définit systématiquement un stub `window.gtag = function() { dataLayer.push(arguments); }` au chargement — ce qui satisfaisait la condition et empêchait l'injection du vrai `gtag.js`. Les appels `window.gtag('event', ...)` passaient par le stub (push Arguments vers dataLayer) sans consommateur GA4.

Le mode `force_ga4` existant corrigeait le problème, mais les 60+ sites avaient `mode: 'auto'` en base de données.

## Décision

**1. Fix `ensureGtag()`** — remplacer le check `typeof window.gtag` par :
- Vérification du marker `[data-nxt-gtag]` (injection déjà faite par nous → skip)
- Vérification d'un script `[src*="gtag/js?id=GA4_ID"]` (déjà chargé pour cet ID → skip)

```js
if (document.querySelector('script[data-nxt-gtag]')) return;
if (document.querySelector('script[src*="gtag/js?id=' + GA4_ID + '"]')) return;
```

**2. Migration runtime silencieuse** dans `get_options()` :

```php
if ( $merged['mode'] === 'auto' && ! empty( trim( $merged['ga4_id'] ) ) ) {
    $merged['mode'] = 'force_ga4';
}
```

Résout tous les sites existants sans toucher à la DB ni aux 60+ tableaux de bord WP.

**3. Nouveau défaut** : `mode: 'force_ga4'` dans `DEFAULTS` pour les nouvelles installations.

## Alternatives écartées
| Alternative | Raison de l'abandon |
|-------------|---------------------|
| Mise à jour SQL en masse des `wp_options` | Données sérialisées PHP — complexe et risqué sur 60+ sites |
| Changement manuel du mode sur chaque site | 60+ sites = coût prohibitif |
| Modifier `auto` pour injecter toujours `gtag.js` | Change le contrat documenté du mode (GTM-first, n'injecte rien) de façon silencieuse |

## Conséquences
**Positives :** Tous les sites existants avec un GA4 ID configuré basculent automatiquement. Confirmé par requête réseau `region1.google-analytics.com/g/collect?tid=G-WZVGQBK40P&en=nxt_debug` en DevTools.

**Négatives :** L'UI admin affiche toujours "Auto" même si le runtime utilise "Forcer GA4" — léger décalage UI/comportement. Acceptable : l'effet est bénéfique, et la prochaine sauvegarde du formulaire persiste `force_ga4` en DB.

**Risque doublon script :** Si le thème/plugin charge déjà `gtag.js` pour le même ID, la vérification `[src*="gtag/js?id=GA4_ID"]` empêche notre injection (déduplication correcte). Si chargé pour un autre ID, on injecte le nôtre — deux instances `gtag.js` possibles, atténuées par la déduplication côté serveurs Google.

**Irréversibilité :** Faible — supprimer 3 lignes dans `get_options()` et remettre `mode: 'auto'` dans `DEFAULTS`.

## Note OVH / GTM
Sur hébergement mutualisé OVH avec GTM installé (même sans tag GA4 configuré dans GTM), GTM définit `window.gtag` comme stub. Ce pattern s'applique à tout hébergeur — la présence de `window.gtag` n'est pas un indicateur fiable de la disponibilité de `gtag.js`.
