# Multi-domain tenancy

## Objectif

La plateforme charge désormais la bonne boutique à partir du host HTTP, sans duplication de code.

Formes de domaines prévues :

- boutiques génériques : `boutique.ateliercomduroumois.fr` et `boutique.ateliercomdesfranchises.fr`
- sous-domaines internes plateforme : `burgerfactory.ateliercomdesfranchises.fr`
- domaines personnalisés client : `boutique.client.fr`
- alias historiques ou offres découverte : `ateliercomduroumois.fr/client` et `ateliercomdesfranchises.fr/client`
- domaines locaux compatibles WAMP : `burgerfactory.localhost`

## Variables d'environnement

Configurer au minimum :

- `PLATFORM_DOMAIN`
- `PLATFORM_CNAME_TARGET`
- `PLATFORM_WILDCARD_ENABLED`
- `CUSTOM_DOMAINS_ENABLED`
- `GENERIC_SHOP_CODE`
- `FALLBACK_SHOP_DOMAIN`
- `ALLOW_UNKNOWN_HOSTS`
- `AUTO_SSL_ENABLED`
- `SSL_PROVIDER`

Exemple local :

```env
PLATFORM_DOMAIN=localhost
PLATFORM_CNAME_TARGET=cname.localhost
GENERIC_SHOP_CODE=generic
FALLBACK_SHOP_DOMAIN=generic.localhost
PLATFORM_WILDCARD_ENABLED=true
CUSTOM_DOMAINS_ENABLED=true
ALLOW_UNKNOWN_HOSTS=false
AUTO_SSL_ENABLED=false
SSL_PROVIDER=manual
```

## Résolution du tenant

Flux appliqué :

1. lecture et normalisation de `HTTP_HOST`
2. suppression éventuelle du port local
3. recherche dans `shop_domains.normalized_domain`
4. chargement de la boutique associée
5. si domaine secondaire et `redirect_to_primary=1`, redirection vers le domaine principal uniquement si la cible est atteignable sans risque SSL
6. si aucun domaine ne correspond, recherche d'un alias `host + chemin` dans `shop_path_aliases`
7. si un alias correspond, redirection permanente vers le domaine principal de la boutique en conservant le suffixe du chemin et la query string
8. si host inconnu, redirection vers `FALLBACK_SHOP_DOMAIN` ou vers le domaine principal de la boutique générique

Le paramètre `?__shop_preview=` n'est plus utilisé.

## Données

La table `shop_domains` porte désormais :

- le domaine brut et normalisé
- le type `platform_subdomain` ou `custom_domain`
- le domaine principal
- la politique `redirect_to_primary`
- l'état de vérification DNS
- l'état SSL

Les migrations applicatives sont :

- `database/migrations/025_shop_domains_multidomain.sql`
- `database/migrations/029_shop_path_aliases.sql`

Les alias de chemin servent de pont vers un domaine canonique. Ils ne dupliquent pas le storefront. Pour qu'un alias comme `ateliercomduroumois.fr/client` fonctionne, le proxy ou le vhost frontal doit transmettre ce préfixe à la plateforme avant le site vitrine.

## Back-office

La gestion des domaines se fait depuis la fiche boutique :

- lister les domaines
- ajouter un domaine
- définir le principal
- activer ou désactiver la redirection vers le principal
- vérifier le DNS
- supprimer un domaine secondaire

Les actions sont soumises aux droits back-office existants et journalisées via l'audit.

## DNS

Pour un domaine personnalisé, la recommandation standard est :

- type : `CNAME`
- nom : `boutique`
- cible : valeur de `PLATFORM_CNAME_TARGET`

La vérification applicative contrôle :

- le `CNAME` attendu si `CUSTOM_DOMAIN_DNS_MODE=cname`
- ou l'IP serveur si `PLATFORM_SERVER_IP` est configurée

## SSL

L'application prépare l'état SSL mais ne promet pas un provisionnement automatique si l'infrastructure ne le permet pas.

Services préparés :

- `CertificateProvisioningService::requestCertificateForDomain()`
- `CertificateProvisioningService::renewCertificate()`
- `CertificateProvisioningService::checkCertificateStatus()`

Exemples d'infra :

- [Apache](</C:/wamp64/www/atelier-com-site/racine/atelier-com-platform/examples/server/apache-vhost-multidomain.conf.example>)
- [Nginx](</C:/wamp64/www/atelier-com-site/racine/atelier-com-platform/examples/server/nginx-multidomain.conf.example>)
- [Pseudo-script Certbot](</C:/wamp64/www/atelier-com-site/racine/atelier-com-platform/scripts/certbot_provision_domain.example.sh>)

## Actions serveur manuelles

- créer le wildcard DNS interne `*.PLATFORM_DOMAIN`
- pointer `PLATFORM_CNAME_TARGET` vers le serveur applicatif
- configurer le vhost catch-all Apache ou Nginx vers `public/`
- ouvrir le port 80 pour les validations HTTP-01
- provisionner les certificats custom quand le DNS est validé
- activer la redirection HTTPS seulement après certificat actif

## Checklist de mise en production

- migration `025_shop_domains_multidomain.sql` exécutée
- migration `029_shop_path_aliases.sql` exécutée si les URL `/client` sont utilisées
- boutique générique identifiée et domaine de repli configuré
- wildcard interne opérationnel
- `PLATFORM_CNAME_TARGET` résout vers l'application
- `ADMIN_HOSTS` séparé du front
- `ALLOW_UNKNOWN_HOSTS=false`
- un domaine principal défini par boutique
- vérification DNS fonctionnelle côté PHP
- stratégie SSL validée côté serveur
- tests manuels de la matrice multi-domaines exécutés
