# Déploiement du Hub Pilotage

Prod : **https://hub.handivia.fr** sur OVH mutualisé (alias SSH `ovh`), dossier `~/hub`, docroot `hub/public`, PHP 8.4 (`/usr/local/php8.4/bin/php`).

Le déploiement se fait par **rsync**, pas par git. Le dépôt GitHub est une sauvegarde ; pousser sur `main` ne déploie rien.

## La commande

Toujours faire un `--dry-run` d'abord (voir « Garde-fou » plus bas).

```bash
cd "/Users/SAVE BAUMBERGER Claude/hub"

# 1. Régénérer l'instantané git (la prod n'a pas les dépôts, elle affiche cet instantané)
php artisan hub:git-snapshot

# 2. Envoyer le code. JAMAIS --delete.
rsync -az \
  --exclude '.git' \
  --exclude '.env' \
  --exclude 'node_modules' \
  --exclude 'database/*.sqlite' \
  --exclude 'public/.htaccess' \
  --exclude '.htpasswd' \
  --exclude 'storage/' \
  --exclude '.phpunit.result.cache' \
  ./ ovh:hub/

# 3. Déposer l'instantané (storage/ est exclu du rsync)
scp storage/app/private/git-snapshot.json ovh:hub/storage/app/private/git-snapshot.json

# 4. Purger les caches. JAMAIS config:cache ni route:cache.
ssh ovh 'cd ~/hub && /usr/local/php8.4/bin/php artisan optimize:clear'

# 5. Si de nouvelles migrations ont été ajoutées
ssh ovh 'cd ~/hub && /usr/local/php8.4/bin/php artisan migrate --force'
```

## Pourquoi chaque exclusion compte

| Exclusion | Ce qui se passe sans elle |
|---|---|
| `database/*.sqlite` | **Destruction de données.** Le local a sa propre base au même chemin. Sans l'exclusion, la base de prod (registre des sites + historique des audits) est écrasée par la base locale. |
| `public/.htaccess` | **Le Basic Auth saute.** La version locale ne contient pas le bloc de protection. Le Hub, y compris `/prospects` (données personnelles, RGPD), devient public. |
| `.env` | Config de prod écrasée par la config locale (base, identifiants, clés). |
| `.htpasswd` | Fichier des identifiants Basic Auth, présent uniquement en prod. |
| `storage/` | Caches, sessions, rapports, archives et **la base** vivent là. On y dépose seulement `git-snapshot.json`, à la main. |

`--delete` est proscrit : il supprimerait sur la prod tout ce qui n'existe pas en local, à commencer par les fichiers ci-dessus.

## Garde-fou avant d'écrire

```bash
rsync -az --dry-run \
  --exclude '.git' --exclude '.env' --exclude 'node_modules' \
  --exclude 'database/*.sqlite' --exclude 'public/.htaccess' --exclude '.htpasswd' \
  --exclude 'storage/' --exclude '.phpunit.result.cache' \
  ./ ovh:hub/ | grep -E '\.sqlite|\.htaccess|\.htpasswd|^\.env'
```

Cette commande **ne doit rien afficher**. Si elle affiche quelque chose, ne pas déployer.

## Vérifications après déploiement

```bash
# Basic Auth intact : 401 sans identifiants
curl -sI https://hub.handivia.fr/ | head -1

# Base intacte
ssh ovh 'cd ~/hub && /usr/local/php8.4/bin/php artisan tinker --execute="
  echo Site::count().\" sites, \".SiteAudit::count().\" points d audit\n\";"'

# Aucune migration en attente
ssh ovh 'cd ~/hub && /usr/local/php8.4/bin/php artisan migrate:status'
```

Attendu : **401** sans identifiants (et une redirection vers le login avec), un nombre de sites et de points d'audit **cohérent avec avant le déploiement**, aucune migration `Pending`.

Les identifiants Basic Auth et le mot de passe du Hub sont dans le `.env` de prod. Ils ne sont volontairement pas écrits ici.

## À ne jamais faire

- **`config:cache` / `route:cache`** : les routes utilisent des closures, la mise en cache casse le boot (erreur 500). Utiliser `optimize:clear` uniquement.
- **Toucher au docroot `public` par défaut** de l'hébergement : c'est un symlink vers `javapax/public`, partagé avec www.javapax.fr.
- **Compter sur l'audit SEO lancé depuis la prod** : la sortie HTTP d'OVH mutualisé est filtrée, les sites ressortent injoignables. L'audit se lance depuis le Hub local, qui écrit dans sa propre base.

## Notes

- **L'historique des audits est en base** (tables `sites` et `site_audits`) depuis le 15/07/2026, plus dans des fichiers JSON. Les anciens JSON ont été archivés dans `storage/app/private/_archive-seo-history-20260715/`. La commande d'import initial est `php artisan hub:import-config` (elle lisait `storage/app/private/seo-history/`).
- La base plafonne à **52 points par site** : les plus anciens sortent au fil des audits.
- Le Hub n'est pas dans son propre `config/repos.php` : ses commits se font à la main.
