# Coaster World v1.104.0 — 2026-08-22

## Stockage média unifié

- Un seul emplacement physique canonique pour les images : `storage/app/public/media/`.
- Suppression de la dépendance à `public/storage` et à `php artisan storage:link` pour les médias Coaster World.
- Les URL publiques `/storage/media/...` sont servies par Laravel depuis le stockage canonique.
- Les visuels de cartes sont désormais stockés dans `storage/app/public/media/coaster-cards/` et restent servis uniquement par les routes signées prévues pour le classeur.
- Les aperçus verrouillés des cartes utilisent `storage/app/public/media/coaster-card-previews/`.
- Nouvelle commande `php artisan cw:media:consolidate` pour fusionner les anciens emplacements et mettre à jour les chemins des cartes et médias en base.
- Outil Windows `tools/consolidate_media_storage_windows.bat` pour Laragon.

## Images WebP

- Toutes les nouvelles images envoyées via l'administration, la communauté et les cartes sont converties en WebP.
- Qualité par défaut : 82.
- Redimensionnement maximal par défaut : 3200 × 3200 px, sans agrandissement des petites images.
- Les métadonnées des médias conservent le MIME et le poids du fichier original quand elles sont disponibles.
- Chaque nouvel upload reçoit un nom physique propre, descriptif et unique en `.webp` ; le nom fourni par l’utilisateur n’est jamais réutilisé comme nom de stockage.
- Exemples : `park-efteling-hero-a8f31c42de.webp`, `card-42-iron-gwazi-front-91b7e43a20.webp`.
- Le serveur signale clairement si PHP GD avec support WebP n'est pas actif.

## Compatibilité / sécurité

- Les anciennes cartes restent lisibles temporairement jusqu'à l'exécution de la consolidation.
- Les chemins `coaster-cards`, `coaster-card-previews` et `private` sont bloqués sur la route publique média.
- Les fichiers en conflit lors de la consolidation sont conservés dans `media/legacy-conflicts/` au lieu d'être écrasés.
- Si une référence de base pointe vers un fichier différent d’un fichier canonique portant le même chemin, la consolidation s’arrête sans supprimer la source.
- Le contrôle de préparation production vérifie désormais `storage/app/public/media` au lieu d'exiger `public/storage`.
