# Installation d'un nouveau site client

## Prerequis

- Docker + Docker Compose
- Git
- Un compte Google (pour reCAPTCHA)
- Un compte Brevo (pour les emails transactionnels)

## Process rapide

```bash
# 1. Creer la branche client depuis main
cd ~/projects/blog_web
git checkout main
git checkout -b bw_nom-du-client

# 2. Configurer l'environnement
cp .env.local.example .env.local
# Editer : APP_SECRET, DATABASE_URL, MAILER_DSN

# 3. Lancer + creer la BDD + builder les assets
make up && make db-client && make assets

# 4. Setup complet (site + admin + pages legales + menus)
docker compose exec php php bin/console app:client:setup

# 5. Activer les modules
docker compose exec php php bin/console app:module:enable blog

# 6. Configurer reCAPTCHA
docker compose exec php php bin/console app:recaptcha:setup

# 7. Personnaliser (templates, CSS, contenu)
# Templates : templates/client/home.html.twig (override de la home)
# CSS : templates/client/theme.css (surcharge du theme, charge en dernier)

# 8. Vider le cache
docker compose exec php php bin/console cache:clear
```

Le site est pret sur http://localhost:8080/admin

---

## Detail des etapes

### 1. Creer la branche client

Chaque client a sa propre branche git, creee depuis `main`. Cela permet de personnaliser librement les templates, le CSS et la structure tout en recevant les mises a jour du CMS via `git rebase main`.

```bash
cd ~/projects/blog_web
git checkout main
git pull origin main
git checkout -b bw_nom-du-client
```

Convention de nommage : `bw_nom-du-client` (ex: `bw_boulangerie-martin`, `bw_garage-dupont`).

> **Pour le deploiement en production**, cloner le repo et checkout la branche client :
> ```bash
> git clone git@github.com:laigneletdavid/blog_web.git /var/www/clients/client-x
> cd /var/www/clients/client-x
> git checkout bw_nom-du-client
> ```

### 2. Configurer l'environnement

```bash
cp .env.local.example .env.local
```

Editer `.env.local` :
- `APP_SECRET` : generer une cle unique (`openssl rand -hex 32`)
- `DATABASE_URL` : adapter le nom de la BDD pour ce client (`blog_client_x`)
- `MAILER_DSN` : `brevo+api://CLE_API@default` (un seul compte Brevo centralise pour tous les sites, cle API commune)

> **Note pour Claude Code / agent :** les 3 valeurs ci-dessus doivent etre fournies par l'utilisateur ou generees. `APP_SECRET` peut etre genere avec `openssl rand -hex 32`. `DATABASE_URL` doit avoir un nom de BDD unique par client. `MAILER_DSN` utilise le compte Brevo centralise ComWeb Solutions (meme cle API pour tous les sites). L'expediteur est `noreply@comwebsolutions.fr` avec reply-to dynamique vers l'email du site client.

### 3. Lancer Docker + BDD + Assets

```bash
make up          # Lance les containers (PHP, Nginx, MariaDB, Mailpit)
make db-client   # Create BDD client (via root) + Migrate (lit le nom dans .env.local)
make assets      # Build Webpack (CSS + JS)
```

Verifier que tout tourne : `docker compose ps`

### 4. Setup client

```bash
docker compose exec php php bin/console app:client:setup
```

Cette commande unique fait tout :
1. **Cree le site** — nom, email de contact, telephone
2. **Cree le super admin** — email, mot de passe (min 12 car.), nom, prenom
3. **Cree les pages legales** — mentions legales, politique de confidentialite
4. **Synchronise les menus** — header, footer navigation, footer legal
5. **Nettoie les fichiers dev** — supprime CLAUDE*.md, PLAN.md, DESIGN_THEME.md, audit, .claude/docs/

La commande est **idempotente** : si le site ou l'admin existent deja, ces etapes sont ignorees.

> **Regle de redaction :** tous les textes, contenus, libelles, menus, pages, commentaires et autres elements crees pour le site doivent etre **en francais avec les accents** (é, è, ê, à, ç, ô, î, û, etc.). Ne jamais livrer des contenus client en francais sans accents ou en anglais — c'est du contenu qui sera lu par les visiteurs finaux.

Mode non-interactif (pour scripts ou agents) :
```bash
docker compose exec php php bin/console app:client:setup \
  --site-name="Mon Site" \
  --site-email=contact@client.fr \
  --admin-email=admin@client.fr \
  --admin-password=MonMotDePasse123
```

#### 4b. Compte client en ROLE_ADMIN (au lieu de SUPER_ADMIN)

Par defaut `app:client:setup` cree le compte client en `ROLE_SUPER_ADMIN` (acces total : modules, infrastructure, themes...). Pour les livraisons standards, le client ne doit avoir que `ROLE_ADMIN` (gestion complete du contenu mais pas du systeme).

**Downgrader le compte juste apres le setup :**
```bash
docker compose exec -T db mariadb -uapp -papp <db_name> -e \
  "UPDATE user SET roles='[\"ROLE_ADMIN\"]', is_verified=1 WHERE email='client@example.fr';"
```

> **Note :** la commande set aussi `is_verified=1` car la creation CLI ne le fait pas (sinon le client est bloque au login en attendant la verification email).

**Creer son propre compte SUPER_ADMIN dev (optionnel) :**
```bash
docker compose exec php php bin/console app:create-super-admin \
  --email=david@comwebsolutions.fr --password=MonMotDePasse123 \
  --first-name=David --last-name=Laignelet
# Puis verifier l'email manuellement (la commande ne le fait pas) :
docker compose exec -T db mariadb -uapp -papp <db_name> -e \
  "UPDATE user SET is_verified=1 WHERE email='david@comwebsolutions.fr';"
```

### 5. Activer les modules

```bash
# Blog (articles, categories, tags) — active par defaut pour la plupart des clients
docker compose exec php php bin/console app:module:enable blog

# Optionnel — selon les besoins du client :
docker compose exec php php bin/console app:module:enable services
docker compose exec php php bin/console app:module:enable catalogue
docker compose exec php php bin/console app:module:enable ecommerce    # cree aussi les CGV
docker compose exec php php bin/console app:module:enable events
docker compose exec php php bin/console app:module:enable directory
docker compose exec php php bin/console app:module:enable faq
docker compose exec php php bin/console app:module:enable portfolio
```

Chaque module active ses routes, cree ses pages legales associees et met a jour les menus.

#### 5b. Remplir les placeholders des pages legales

Les pages legales generees (mentions legales, politique de confidentialite, CGV, CGU) contiennent des placeholders type `{{RAISON_SOCIALE}}`, `{{ADRESSE}}`, `{{SIRET}}`, etc. **Aucune commande automatique ne les remplit** — c'est manuel via SQL ou via le CRUD admin (Pages > Edition).

**Approche SQL recommandee (rapide, batch) :**
```bash
docker compose exec -T db mariadb -uapp -papp <db_name> <<'SQL'
UPDATE page SET content = REPLACE(content, '{{DATE}}', '16 avril 2026') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{RAISON_SOCIALE}}', 'APA d''Bearn') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{FORME_JURIDIQUE}}', 'Entreprise individuelle') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{ADRESSE}}', '413 chemin Labarrere, 64570 Arette') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{SIRET}}', '999 572 647 00017') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{TVA}}', 'Non assujetti (art. 293 B du CGI)') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{CAPITAL}}', 'Non applicable') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{NOM_DIRECTEUR}}', 'Prenom Nom') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{EMAIL_CONTACT}}', 'contact@client.fr') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{TELEPHONE}}', '06 25 63 63 76') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{NOM_HEBERGEUR}}', 'OVH SAS') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{ADRESSE_HEBERGEUR}}', '2 rue Kellermann, 59100 Roubaix, France') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{URL_HEBERGEUR}}', 'https://www.ovhcloud.com/fr/') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{EMAIL_DPO}}', 'contact@client.fr') WHERE is_system = 1;
UPDATE page SET content = REPLACE(content, '{{MEDIATEUR}}', 'Non applicable') WHERE is_system = 1;
SQL
```

**Verifier qu'il ne reste aucun placeholder :**
```bash
docker compose exec -T db mariadb -uapp -papp <db_name> -e \
  "SELECT id, title, content REGEXP '\\\\{\\\\{[A-Z_]+\\\\}\\\\}' AS has_placeholder FROM page WHERE is_system = 1;"
```
Tous les `has_placeholder` doivent etre a `0`. Sinon adapter la liste de REPLACE ci-dessus avec le placeholder manquant (ex : `{{SERVICES_SUPPLEMENTAIRES}}` pour les CGU si module ecommerce non actif).

> **Alternative :** ouvrir chaque page dans Admin > Pages et modifier via l'editeur Tiptap. Plus long mais plus visuel.

### 6. Configurer reCAPTCHA (anti-spam)

Le reCAPTCHA v3 protege le formulaire de contact contre les bots. Il est **invisible** pour les visiteurs (pas de case a cocher).

#### Etape 1 — Creer les cles Google (manuelle)

1. Aller sur https://www.google.com/recaptcha/admin
2. Se connecter avec un compte Google
3. Cliquer sur **+** (creer un nouveau site)
4. Remplir :
   - **Label** : nom du client (ex: "Mon Site - client-x")
   - **Type** : reCAPTCHA v3
   - **Domaines** : ajouter le domaine du client (ex: `client-x.fr`) + `localhost` pour le dev
5. Accepter les conditions et valider
6. Copier la **cle du site** (site key) et la **cle secrete** (secret key)

#### Etape 2 — Configurer dans le projet (automatisable)

```bash
docker compose exec php php bin/console app:recaptcha:setup
```

La commande demande les 2 cles et les ecrit dans `.env.local`.

Mode non-interactif (pour agents) :
```bash
docker compose exec php php bin/console app:recaptcha:setup \
  --site-key=6LcXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
  --secret-key=6LcXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

Puis vider le cache :
```bash
docker compose exec php php bin/console cache:clear
```

> **Sans reCAPTCHA** : le formulaire de contact reste protege par 3 couches (CSRF + honeypot + rate limiting 3/min). Le reCAPTCHA est recommande en production mais pas obligatoire.

### 7. Injecter les images d'identite

> **Utilisateur** : fournir les fichiers. **Agent** : les injecter dans le projet et la BDD.

Les images du site se repartissent en deux categories :

#### Images injectees par l'agent (identite du site)

Ces images sont **techniques** — elles doivent etre en place avant la personnalisation. L'utilisateur les fournit, l'agent les injecte directement en BDD et dans le filesystem.

| Image | Format attendu | Destination | Champ Site |
|-------|---------------|-------------|------------|
| **Logo** | PNG transparent ou JPG, horizontal ou carre, ~150px de haut | `public/documents/medias/` + Media en BDD | `logo` |
| **Favicon** | PNG carre, 32x32 ou 64x64 px | `public/documents/medias/` + Media en BDD | `favicon` |
| **Image Open Graph** | JPG ou PNG, 1200x630 px (apercu reseaux sociaux) | `public/documents/medias/` + Media en BDD | `ogImage` |
| Apple-touch-icon (optionnel) | PNG carre, 180x180 px | `public/images/apple-touch-icon.png` | — |

**Ce que l'agent fait :**

1. Copie les fichiers dans `public/documents/medias/`
2. Cree les entrees `Media` en BDD pour chaque fichier
3. Associe au `Site` les champs `logo`, `favicon` et `ogImage`
4. Remplace les fallbacks statiques dans `public/images/` si fournis (favicon-16x16, favicon-32x32, apple-touch-icon)

> **Verif rapide :** recharger http://localhost:8080 — le logo doit apparaitre dans le header et le favicon dans l'onglet du navigateur.

#### Images importees via l'admin (contenu visuel)

Ces images sont **editoriales** — elles relevent de la personnalisation du site et se gerent dans Admin > Medias puis se selectionnent dans les formulaires.

| Image | Ou la selectionner | Role |
|-------|-------------------|------|
| **Image hero** | Reglages > Apparence > Images du theme | Grande image d'accueil (bandeau principal). Fallback OG si pas d'image OG dediee. |
| **Image a propos** | Reglages > Apparence > Images du theme | Illustration section "A propos" sur la home |
| **Galerie** | Reglages > Apparence > Images du theme | Slot `gallery` — carousel ou grille sur la home |
| **Logos clients** | Reglages > Apparence > Images du theme | Slot `logo` — bandeau de logos partenaires/clients |
| **Temoignages** | Reglages > Apparence > Images du theme | Slot `testimonial` — photos temoignages |
| **Images articles/pages** | Contenu > Articles / Pages | Image a la une (utilisee aussi comme OG de l'article) |

> **Fallback OG :** si l'image Open Graph n'est pas definie, le systeme utilise automatiquement : `ogImage > heroImage > logo`.

### 8. Personnaliser les templates et le CSS

Les fichiers de personnalisation client vivent dans `templates/client/` :

| Fichier | Role | Charge quand |
|---------|------|--------------|
| `templates/client/home.html.twig` | Override complet de la home | Prioritaire sur le theme et le generique |
| `templates/client/theme.css` | Surcharge CSS du theme | Charge en dernier dans `<head>`, apres le theme.css |

**`client/theme.css`** est le bon endroit pour ajuster les couleurs, le hero, le CTA, la taille du logo, etc. sans modifier les fichiers du CMS. Exemple :
```css
/* Forcer le CTA en couleur secondaire */
.theme-artisan .home-cta { background: var(--secondary); }
/* Agrandir le logo header */
.theme-artisan .header-logo img { height: auto !important; max-height: 140px; }
```

> **Regle :** ne jamais modifier directement les fichiers `themes/*/theme.css` ou `themes/*/_header.html.twig` sur une branche client. Utiliser les overrides `templates/client/`.

### 9. Personnaliser dans l'admin

> **Utilisateur** : valide le rendu. **Agent** : execute les modifications dans l'admin.

Se connecter a http://localhost:8080/admin puis :

1. **Identite du site** (Reglages > Identite) — coordonnees completes, description, SEO par defaut
2. **Theme et couleurs** (Reglages > Apparence) — choix du theme, couleurs, polices
3. **Images du theme** (Reglages > Apparence) — hero, a propos, galerie, logos, temoignages (via admin Medias)
4. **Navigation** (Reglages > Navigation) — organiser les menus par drag & drop
5. **Contenu** — creer articles, pages, ajouter des medias
6. **SEO** — remplir les champs SEO des pages principales
7. **Guide** — consulter Aide > Guide pour les details

### 9. Resync menus (apres changement de theme)

```bash
docker compose exec php php bin/console app:menu:sync
```

---

## Acces dev

| Service | URL |
|---------|-----|
| Site | http://localhost:8080 |
| Admin | http://localhost:8080/admin |
| Mailpit | http://localhost:8025 |
| MariaDB | localhost:3307 (app/app) |

---

## Toutes les commandes disponibles

| Commande | Role | Description |
|----------|------|-------------|
| `app:client:setup` | Setup initial | Cree site + admin + pages legales + menus (idempotent) |
| `app:module:enable <module>` | Modules | Active un module (blog, services, catalogue, ecommerce, events, directory, faq, portfolio) |
| `app:module:disable <module>` | Modules | Desactive un module |
| `app:recaptcha:setup` | Securite | Configure les cles reCAPTCHA v3 dans .env.local |
| `app:menu:sync` | Navigation | Resynchronise les menus systeme depuis le theme |
| `app:legal-pages:update` | Contenu | Regenere les pages legales (mentions, confidentialite, CGV) |
| `app:media:regenerate-sizes` | Medias | Regenere les 3 tailles WebP (480, 800, 1200px) des medias existants |
| `app:create-super-admin` | Standalone | Cree un super admin (inclus dans `app:client:setup`) |
| `app:init-site` | Standalone | Initialise le site (inclus dans `app:client:setup`) |

---

## Preparer le commit de la branche client

Avant de pousser la branche `bw_*` ou de generer un dump pour le deploiement, s'assurer que tous les fichiers specifiques au client sont bien committes. Sans ca, ils seront **perdus au prochain deploy fresh** sur OVH.

### Fichiers a commit sur la branche client (force-track si gitignore)

| Fichier / dossier | Quand le commit ? | Genere par |
|-------------------|-------------------|------------|
| `templates/client/home.html.twig` | Apres customisation home | Manuel |
| `templates/client/_header.html.twig`, `_footer.html.twig`, `blog.html.twig`, `contact.html.twig` | Apres customisation override | Manuel |
| `templates/client/theme.css` | Apres customisation CSS | Manuel |
| `public/documents/medias/*` | Apres upload images via admin (logo, photos hero, about, content...) | Admin > Medias |
| `public/documents/files/*` | Apres upload de PDF/DOCX/ZIP via admin ou editeur TipTap | Admin > Documents |
| `public/favicon-*.png`, `apple-touch-icon.png`, `android-chrome-*.png`, `mstile-150x150.png` | Apres upload du logo via admin (regeneration auto) | `SiteLogoListener` |
| `public/site.webmanifest`, `public/browserconfig.xml` | Apres upload du logo (regeneration auto) | `SiteLogoListener` |
| `scripts/bw_<client>_dump.sql` | Avant chaque deploy OVH | `make db-dump` |

### Commandes types

```bash
# 1. Apres customisation templates/CSS et upload des medias via l'admin :
git add templates/client/ public/documents/medias/ \
        public/favicon-*.png public/apple-touch-icon.png \
        public/android-chrome-*.png public/mstile-150x150.png \
        public/site.webmanifest public/browserconfig.xml
git commit -m "feat(bw_<client>): customisations + medias client"

# 2. Avant deploy : generer + commit le dump BDD
make db-dump                     # Genere scripts/bw_<client>_dump.sql
git add scripts/bw_<client>_dump.sql
git commit -m "chore(bw_<client>): dump BDD pour deploiement OVH"

# 3. Push
git push origin bw_<client>
```

> **Le dump SQL est temporaire** : le supprimer du repo (`git rm scripts/bw_<client>_dump.sql && git commit && git push`) apres le 1er deploy OVH reussi pour ne pas alourdir le repo. Garder uniquement entre dev et prod, le temps de l'import.

### Fichiers a NE PAS commit

- `.env.local` (gitignore : config locale, contient APP_SECRET, DSN BDD, mailer)
- `.claude/settings.local.json` (local Claude Code)
- `config/reference.php` si modifie sans intention (regenere automatiquement par cache:clear, c'est du parasite Symfony)

---

## Deploiement en production

Voir **`DEPLOY_REFERENCE.md`** pour le guide complet de deploiement OVH mutualise.

En resume :

```bash
# Premier deploy OVH
git clone -b bw_nom_client https://github.com/laigneletdavid/blog_web.git .
chmod +x scripts/deploy-ovh.sh
./scripts/deploy-ovh.sh --init    # Genere .env.local + deploy + import dump

# Mises a jour
./scripts/deploy-ovh.sh           # Pull + build + cache + migrations
```

---

## Architecture git — branches client

### Principe

Chaque client a sa propre branche git creee depuis `main`. Le CMS commun vit sur `main`, les personnalisations client vont dans `templates/client/` et les fichiers specifiques (images, CI/CD). Quand une nouvelle feature arrive sur `main`, on **merge main dans la branche client** (jamais rebase, jamais l'inverse).

```
main                          ← CMS stable, reference pour tous les clients
  │
  ├── bw_front                  ← Site vitrine BlogWeb
  ├── bw_boulangerie-martin     ← Branche client (home custom, CSS, contenu)
  ├── bw_garage-dupont          ← Branche client
  └── bw_cabinet-avocat         ← Branche client
```

| Element | Ou ca vit | Conflit au merge ? |
|---------|-----------|-------------------|
| Code CMS (controllers, entities, services) | main | **Non** — pas touche sur bw_* |
| Templates themes (headers, footers) | main | **Non** — pas touche sur bw_* |
| Templates client (overrides) | `templates/client/` sur bw_* | **Non** — fichiers differents |
| Images client | `public/documents/medias/` sur bw_* | **Non** — fichiers differents |
| Contenu (articles, pages) | BDD | **Non** |
| Config client (.env.local) | Fichier local (gitignore) | **Non** |
| Theme, couleurs, polices | BDD (entite Site) | **Non** |

### Workflow : ajouter une feature au CMS

```bash
# 1. Developper sur main
git checkout main
# ... ajouter la feature ...
git add ... && git commit -m "feat: description" && git push

# 2. Merger main dans chaque branche client
git checkout bw_front
git merge main          # Zero conflit
git push origin bw_front
```

### Workflow : corriger un bug

```bash
# 1. Corriger sur main
git checkout main
# ... fix ...
git add ... && git commit -m "fix: description" && git push

# 2. Merger main dans chaque branche client
for branch in $(git branch --list 'bw_*'); do
    echo "=== Mise a jour: $branch ==="
    git checkout "$branch" && git merge main && git push origin "$branch"
done
```

### Mise a jour en production (OVH)

```bash
ssh user@host
./scripts/deploy-ovh.sh    # Pull + build + cache + migrations
```

### Regles importantes

- **Features CMS** : toujours sur `main`, jamais directement sur une branche client
- **Personnalisations client** : dans `templates/client/` + images dans `public/documents/medias/`
- **Ne jamais modifier les templates themes** sur une branche client → utiliser le systeme d'override
- **Merge main dans bw_xxx** pour les mises a jour, **jamais rebase, jamais l'inverse**
- **Ne jamais merger bw_* dans main** — main ne recoit jamais de code client

### Cas particuliers

**Ajout d'un nouveau module :** apres `git merge main`, activer le module si besoin :
```bash
docker compose exec php php bin/console app:module:enable <module>
```

**Changement de theme :** apres `git merge main`, resync les menus si le theme a change :
```bash
docker compose exec php php bin/console app:menu:sync
```

---

## Fichiers de developpement

Le repo contient des fichiers de documentation technique (specs, audit, roadmap) dans `.claude/docs/`. Ces fichiers sont **utiles pour le developpement** mais ne doivent **jamais** se retrouver chez un client.

**Nettoyage automatique :** `app:client:setup` (etape 5) supprime automatiquement :
- `CLAUDE.md`, `CLAUDE2.md`, `CLAUDE3.md`, `CLAUDE_FULL.md` (conventions et specs techniques)
- `PLAN.md`, `DESIGN_THEME.md` (plans de dev)
- `audit_cms_claude_code.md` (audit securite)
- `.claude/docs/` (documentation detaillee)

**Securite supplementaire :** `scripts/deploy.sh` nettoie aussi ces fichiers a chaque deploiement.

> **Migration initiale (une seule fois sur le repo de dev) :** pour deplacer les docs vers `.claude/docs/`, lancer `./scripts/migrate-docs.sh` puis remplacer CLAUDE.md par CLAUDE.md.new.

---

## Hook pre-commit (marqueurs de conflit)

Le repo inclut un hook `.githooks/pre-commit` qui bloque les commits contenant des marqueurs de conflit Git (`<<<<<<<`, `=======`, `>>>>>>>`). A activer une fois par clone :

```bash
git config core.hooksPath .githooks
```

---

## Notes

- **Pages legales** : editez le contenu dans Admin > Pages (les pages systeme sont pre-remplies avec des sections `[A COMPLETER]`).
- **Menus** : les elements systeme sont editables (renommer, reordonner, masquer) mais pas supprimables. Ajoutez vos propres liens dans Reglages > Navigation.
- **BDD vierge** : `make db` repart de zero (drop + create + migrate). Aucune donnee de test ne se retrouve chez le client.
- **Commandes standalone** : `app:create-super-admin` et `app:init-site` fonctionnent separement si besoin, mais `app:client:setup` les englobe.
- **Verification email** : les utilisateurs inscrits via le formulaire doivent confirmer leur email avant de pouvoir se connecter. Les comptes admin crees via CLI sont exempts.
- **Securite contact** : 4 couches de protection (CSRF + honeypot + rate limiting + reCAPTCHA v3 optionnel).

---

## Guide pour Claude Code / agents

Ce projet est prevu pour etre installe et personnalise via Claude Code. Voici le workflow type :

| Etape | Qui | Action |
|-------|-----|--------|
| 1 | **Utilisateur** | Fournit la fiche de reference client (`client_reference_template.md`) |
| 2 | **Agent** | Cree la branche `bw_nom-du-client` depuis `main` |
| 3 | **Agent** | Execute le setup : `.env.local`, `make up`, `make db`, `make assets`, `app:client:setup` |
| 4 | **Agent** | Active les modules selon la fiche |
| 5 | **Utilisateur** | Fournit les cles reCAPTCHA (creees sur Google) |
| 6 | **Agent** | Configure le reCAPTCHA via `app:recaptcha:setup --site-key=... --secret-key=...` |
| 7 | **Utilisateur** | Fournit les images d'identite : logo (PNG/JPG), favicon (PNG 32x32/64x64), image OG (JPG/PNG 1200x630) |
| 8 | **Agent** | Injecte logo + favicon + OG dans `public/documents/medias/`, cree les Media en BDD, associe au Site (`logo`, `favicon`, `ogImage`) |
| 9 | **Agent** | Personnalise le site dans l'admin (theme, couleurs, SEO par defaut) |
| 10 | **Utilisateur** | Fournit les images de contenu : hero, a propos, galerie, logos clients, temoignages |
| 11 | **Agent** | Importe les images de contenu via Admin > Medias, les associe dans Apparence > Images du theme |
| 12 | **Agent** | Customise les templates et le CSS sur la branche client |
| 13 | **Agent** | Commit les personnalisations sur la branche `bw_nom-du-client` |
| 14 | **Utilisateur** | Valide le rendu et le contenu |
| 15 | **Ensemble** | Push en prod quand c'est valide |

Les seules etapes manuelles (utilisateur) sont :
- Fournir la fiche client
- Creer les cles reCAPTCHA sur Google (necessite un compte Google)
- Fournir les images d'identite (logo, favicon, OG) — injectees par l'agent
- Fournir les images de contenu (hero, a propos, galerie...) — importees via l'admin par l'agent
- Creer le compte Brevo et recuperer les identifiants SMTP
- Valider le contenu final

> **Distinction importante :**
> - **Images d'identite** (logo, favicon, OG) → l'agent les injecte directement dans le filesystem + BDD (etape 8)
> - **Images de contenu** (hero, a propos, galerie, temoignages, logos clients) → l'agent les importe via Admin > Medias puis les selectionne dans les formulaires (etape 11)

> **Regle importante pour l'agent :** ne jamais modifier le core CMS (controllers, entities, services) sur une branche client. Les personnalisations client se limitent aux templates, CSS, images et contenu.

---

## Troubleshooting / FAQ

### BDD : "Access denied" a la creation
L'utilisateur `app` n'a pas les droits `CREATE DATABASE`. Utiliser `make db-client` au lieu de `make db` — cette commande cree la BDD via root et accorde les privileges automatiquement.

### Super admin : mode non-interactif
La commande supporte les options CLI :
```bash
docker compose exec php php bin/console app:create-super-admin \
  --email=admin@client.fr --password=MonMotDePasse123 \
  --first-name=Prenom --last-name=Nom
```

### OVH : `^M` / "mauvais interpreteur" sur les scripts
Les scripts .sh ont des fins de ligne Windows (CRLF). Le `.gitattributes` corrige ca pour les futurs clones. Pour un clone existant :
```bash
sed -i 's/\r$//' scripts/deploy-ovh.sh
```

### OVH : PHP 5.4 par defaut sur un nouveau multisite
Creer un `.ovhconfig` a la racine du dossier :
```
app.engine=php
app.engine.version=8.4
http.firewall=none
environment=production
container.image=stable64
```
Se deconnecter et reconnecter en SSH pour appliquer.

### OVH : Erreur sync-rpc lors du build assets
Le build Encore echoue avec "listen EACCES". Appliquer le patch avant le build :
```bash
ESLINT_FILE="node_modules/@symfony/webpack-encore/lib/plugins/eslint.js"
sed -i "s|^const forceSync|//const forceSync|" "$ESLINT_FILE"
sed -i "s|^const hasEslintConfiguration = forceSync|//const hasEslintConfiguration = forceSync|" "$ESLINT_FILE"
NODE_ENV=production npx encore production
```
Note : `deploy-ovh.sh` applique ce patch automatiquement.

### OVH : Dossier non vide au `git clone .`
OVH cree un dossier `public/` par defaut. Supprimer avant de cloner :
```bash
rmdir public
git clone -b bw_nom_client https://github.com/laigneletdavid/blog_web.git .
```

### Assets : pas besoin de rebuild pour les templates/CSS themes
Le `theme.css` est charge en inline via Twig. Les templates sont interpretes par Symfony. Apres un `git pull` sur le serveur, un simple `cache:clear` suffit :
```bash
php bin/console cache:clear --env=prod
```
Le rebuild assets (npm/encore) n'est necessaire que si les fichiers dans `assets/` (SCSS, JS) ont change.
