# Checklist mise en production — Vulcan'Affûtage

> **2026-08-29 — la mise en service est préparée et vérifiée.**
> Le mode opératoire de la bascule du 1er septembre 11 h vit désormais dans
> [`docs/mise-en-service-2026-09-01.md`](docs/mise-en-service-2026-09-01.md) :
> c'est le document à suivre. Il recense aussi les trois actions restantes,
> toutes dans le panneau OVH (sous-domaine `old.`, réaffectation du domaine
> principal, tâche planifiée `app:cron`).
>
> L'inventaire des e-mails transactionnels est dans
> [`docs/emails-transactionnels.md`](docs/emails-transactionnels.md).
>
> La page ci-dessous garde sa valeur d'historique ; les sections « Bloquants »
> et « Recommandé » ont été traitées depuis, sauf mention contraire dans le
> mode opératoire.

État au 2026-07-23. Corrections code déjà appliquées listées en bas. Cette page = ce qui **reste à faire côté serveur / déploiement** (actions non réalisables depuis le code du poste dev).

## 🔴 Bloquants — à faire AVANT toute mise en ligne

### 1. Roter tous les secrets exposés (ils ont été en clair dans le dépôt)
- **Mot de passe SMTP OVH** (`.env:42`, `Thanozorus...`) : changer le mot de passe du compte `no-reply@vulcanaffutage.com` chez OVH, puis mettre le nouveau **hors dépôt** (`.env.local` ou variable d'env serveur).
- **APP_SECRET** : en générer un neuf (`php bin/console secrets:generate-keys` ou `openssl rand -hex 16`) et le fournir via env serveur / `.env.local`. L'ancien était versionné dans `.env.dev` → considéré compromis (invalide tokens CSRF/URI signées).
- **Base de données** : ne PAS utiliser `root` sans mot de passe. Créer un utilisateur MySQL dédié à privilèges limités (SELECT/INSERT/UPDATE/DELETE sur la base `vulcan_affutage` uniquement) avec mot de passe fort. Mettre `DATABASE_URL` à jour hors dépôt.
- **PayPal** : vérifier que `PAYPAL_CLIENT_ID`/`PAYPAL_CLIENT_SECRET` sont en env serveur, `PAYPAL_MODE=live` en prod.

### 2. Environnement de prod
- `APP_ENV=prod` et `APP_DEBUG=0` (actuellement `APP_ENV=dev` → profiler `/​_profiler`, stack traces et dump de config exposés publiquement).
- `composer dump-env prod` puis `composer install --no-dev --optimize-autoloader`.
- Vider/réchauffer le cache prod : `php bin/console cache:clear --env=prod`.
- **Docroot serveur = `public/` strictement** (jamais la racine projet) — sinon `.env`, `var/`, `src/` deviennent accessibles.

### 3. Dépendances (CVE) — ✅ RÉSOLU (2026-07-22)
- Contraintes `symfony/*` montées de `7.2.*` vers `7.4.*` (Symfony 7.4.14), `composer update -W` exécuté : `composer audit` = **0 advisory** (contre 36 / 13 paquets avant).
- Régression validée : suite complète **177/177 tests OK** (614 assertions) sur 7.4, dépréciations 7.3 corrigées (`eraseCredentials` `#[\Deprecated]`, `collect_serializer_data`).
- ⚠️ Reste à valider manuellement en pré-prod ce que les tests ne couvrent pas : paiement PayPal réel et rendu factures PDF.

## 🟠 Recommandé avant prod

- **Rate limiting login** (client + admin) : installer `symfony/rate-limiter` et brancher un `login_throttling` (protection brute-force ; aujourd'hui bcrypt seul).
- **CSRF sur endpoints mutateurs** encore sans token : `ApiCliController` (addToCart, delProductCart, send-mail), `ApiAdminController` (update-status, update-tracking, update-home-products), et passer `delete-product`/`toggle-product` de GET → POST. Protection actuelle = SameSite=lax seulement.
- **`client_ob` en session** (`ClientLoginController`) : l'entité `Client` complète (avec hash mot de passe) est stockée en session. Refactor pour ne garder que l'`id` et recharger l'entité à la demande. Impacte `PaymentController` (`getPrenom()/getEmail()`) et `CompteController` (`findBy['client' => client_ob]`) — à tester après refonte.
- **CSP complète** : le `SecurityHeadersSubscriber` pose aujourd'hui une CSP minimale (`object-src 'none'; base-uri 'self'; frame-ancestors 'self'`) qui ne casse pas l'inline. Une CSP stricte sur `script-src`/`style-src` nécessite une refonte avec nonces (beaucoup de JS/CSS inline + GTM + jsDelivr).
- **Cookies session** : ✅ fait 2026-07-23 — `cookie_httponly: true` explicite, commentaires de durées corrigés (48 h / 72 h). `cookie_secure: auto` conservé (flag Secure posé automatiquement en HTTPS) ; passer à `true` si l'on veut interdire toute session hors HTTPS.
- **Limites upload PHP** (php.ini prod) : l'admin promet 5 Mo/image mais la valeur PHP par défaut est `upload_max_filesize=2M` — les photos smartphone étaient refusées avec une erreur peu claire (constaté en dev 2026-07-16). Régler `upload_max_filesize=6M` et `post_max_size=48M` (12 images max/requête).

## 🟡 Données / contenu

- **Photos produits manquantes** : seul `3-1.jpg` existe sur disque. Les produits 7–12 n'ont aucune image (404 sur home/listing). Uploader les vraies photos via l'admin.
- **Libellés « forgé »** en base (ex. « Couteau forgé Signature ») : la DA 2.0 a retiré ce vocabulaire des templates mais il reste dans les données produit — corriger via l'admin si voulu.
- **Photos atelier affûtage** (avant/après, timeline) : placeholders actuellement.

---

## ✅ Audit fichiers du dépôt (2026-07-23)

Vérification complète « tout ce qui touche les fichiers » avant mise en prod :

- **Aucun secret tracké** : `.env`, `.env.local`, `.env.dev` hors dépôt (gitignorés) ; `.env.test` versionné mais sans secret réel (`MAILER_DSN=null://null`, `LAPOSTE_API_KEY` vide, `APP_SECRET` factice de test). ⚠️ La rotation des secrets historiquement exposés (section 🔴 n°1) reste nécessaire — l'historique git les contient toujours.
- **`composer audit` : 0 advisory** (Symfony 7.4.14). Outils dev (profiler, debug, maker, fixtures, phpunit) en `require-dev` et confinés `dev`/`test` dans `bundles.php` + `when@dev` — `composer install --no-dev` ne les embarquera pas.
- **Aucun artefact debug** : pas de `dump()`/`dd()` dans `src/` ni `templates/`, pas de fichier `.sql`/dump/backup/phpinfo/adminer tracké.
- **`public/.htaccess` créé** (recette apache-pack) : front controller + blocage des `.md`/`.yaml`/`.lock` servis depuis `public/` (les `AGENTS.md` de `public/` ne sont plus téléchargeables). Indispensable si le serveur est Apache (OVH mutualisé).
- **`robots.txt` durci** : Disallow des pages transactionnelles et compte (panier, commande, facture, mdp, activation…).
- **`sitemap.xml` régénéré** sur les routes DA 2.0 actuelles — l'ancien datait de 2025-03 et listait les URLs v1 disparues (`/produits/couteau/roquefort`, etc.).
- **`.gitattributes`** : `export-ignore` sur `tests/`, `AGENTS.md`, `PROD-CHECKLIST.md`, `.env.test`, etc. → un déploiement par `git archive` n'embarque pas l'outillage interne.
- **Dossiers d'upload** (`public/assets/product`, carrousel — gitignorés) : auto-créés par `ProductImageManager`/`HeaderCarouselManager` au premier upload, rien à préparer au déploiement.
- **Migrations** : toutes versionnées (dernière `Version20260723150000`), suite complète verte.
- Docs internes `AGENTS.md` (`src/Controller`, `src/Service`) mises à jour : les notes « bug localhost PayPal / routes de test » dataient d'avant les correctifs du 2026-07-03.

## ✅ Déjà corrigé côté code (2026-07-03)

**Auth / DA 2.0** : suite auth migrée DA 2.0 (split immersif), pages d'erreur old-gen remplacées par messages inline / pages statut DA 2.0 / redirections, notifications toast bicolores, logo e-mail en CID (plus d'URL cassée), validation serveur inscription + reset.

**Bascule pages** : URLs canoniques servent la DA 2.0, `/newXXX` → 301, anciens templates conservés hors route.

**Sécurité** :
- Supprimé : `/phpInfo` (AccueilController), `/info` (FactureController), `phpinfo.php` (racine), `/test-mail` (MailerController supprimé), `/test-paypal`, `/test-access-token`, `/capture-payment`, `/check-order`, méthodes debug `testAccessToken`/`testCreateOrder` (echo/dump/exit) dans PayPalService.
- **RCE upload** : validation stricte images (MIME réel via finfo, whitelist jpg/png/webp, refus php/svg, taille max 5 Mo) sur create + edit produit.
- **XSS** : retiré `|raw` de `payment/error.html.twig` (param URL user-contrôlé).
- **Fuite d'infos** : `PaymentController` ne renvoie plus `getMessage()`/`getTraceAsString()` au client (log serveur).
- **DomPDF** : `isPhpEnabled`/`isRemoteEnabled`/`isJavascriptEnabled` → `false` ; chroot corrigé.
- **Bug prod PayPal** : `return_url`/`cancel_url` `https://127.0.0.1:8000` en dur → URLs absolues générées via `UrlGeneratorInterface`.
- **Guards auth** : `/compte`, `/commande`, `/information-client` redirigent vers login si non connecté ; `get-product` (API admin) exige `admin_id`.
- **Fixation de session** : `$session->migrate(true)` à la connexion client + admin.
- **Open redirect** : `redirectRoute` validé (chemin interne only) au login.
- **En-têtes sécurité** : `SecurityHeadersSubscriber` (nosniff, X-Frame-Options SAMEORIGIN, Referrer-Policy, Permissions-Policy, CSP minimale, HSTS en HTTPS).
- **Route dupliquée** `/admin` (`app_admin_compte`) supprimée.
- `.gitignore` : `.env.dev` exclu (contenait un secret réel).
