# Documentation Backend - ParcApp API ## Conventions de stockage des médias ### Structure des dossiers Les médias (images, audio, vidéo) sont stockés via Laravel Storage sur le disk `public` : ``` storage/app/public/ ├── vehicles/ # Photos de véhicules ├── trailers/ # Photos de remorques ├── audios/ # Fichiers audio (futur) └── videos/ # Fichiers vidéo (futur) ``` ### Convention de nommage - **Véhicules** : `vehicle_{timestamp}_{uniqid}.{ext}` - **Remorques** : `trailer_{timestamp}_{uniqid}.{ext}` - **Audio** : `audio_{timestamp}_{uniqid}.{ext}` (futur) - **Vidéo** : `video_{timestamp}_{uniqid}.{ext}` (futur) ### Stockage en base de données Les chemins/URLs de médias sont stockés dans la base de données sous forme de : - **URLs absolues externes** : `https://example.com/image.jpg` (Cloudinary, CDN, etc.) - **Chemins relatifs locaux** : `/storage/vehicles/photo.jpg` ou `vehicles/photo.jpg` **Important** : La base de données peut contenir des chemins relatifs ou des URLs absolues. La transformation en URL absolue se fait au moment de la sérialisation (API Resource). ## Convention d'API : URLs absolues obligatoires ### Règle fondamentale **Toutes les URLs de médias renvoyées par l'API doivent être absolues** (commençant par `https://apiparcapp.jrbxsolutions.com/...`). Cette règle garantit le bon fonctionnement en environnement multi-domaines : - Frontend : `https://parcapp.jrbxsolutions.com` - Backend API : `https://apiparcapp.jrbxsolutions.com` ### Utilisation du helper `media_url()` Le helper `App\Support\MediaUrl::url()` (ou fonction globale `media_url()`) doit être utilisé partout où des URLs de médias sont renvoyées : ```php use App\Support\MediaUrl; // Dans un API Resource 'photoUrl' => MediaUrl::url($this->photo_url), // Dans un Controller (upload) $url = MediaUrl::url($path, 'public'); ``` ### Comportement du helper 1. **URL absolue existante** : Retournée telle quelle ```php media_url('https://example.com/image.jpg') // → 'https://example.com/image.jpg' ``` 2. **Chemin relatif avec `/storage/`** : Transformé en URL absolue ```php media_url('/storage/vehicles/photo.jpg') // → 'https://apiparcapp.jrbxsolutions.com/storage/vehicles/photo.jpg' ``` 3. **Chemin relatif de disk** : Utilise `Storage::disk()->url()` puis rend absolu ```php media_url('vehicles/photo.jpg', 'public') // → 'https://apiparcapp.jrbxsolutions.com/storage/vehicles/photo.jpg' ``` ## Configuration ### Variables d'environnement **Production** (`.env`) : ```env APP_URL=https://apiparcapp.jrbxsolutions.com APP_ENV=production ``` **Développement local** (`.env`) : ```env APP_URL=http://apiparcapp.test APP_ENV=local ``` ### Forçage HTTPS en production Le `AppServiceProvider` force automatiquement HTTPS en production : ```php if ($this->app->environment('production')) { \URL::forceScheme('https'); } ``` Cela garantit que toutes les URLs générées par Laravel (Storage, routes, etc.) utilisent HTTPS. ## Endpoints concernés ### Upload de médias - `POST /api/upload/vehicle-photo` → Retourne `{ url: "https://...", publicId: null }` - `POST /api/upload/trailer-photo` → Retourne `{ url: "https://...", publicId: null }` ### Endpoints GET - `GET /api/vehicles` → Tous les `photoUrl` et `plaquePhotoUrl` sont absolus - `GET /api/vehicles/{id}` → `photoUrl` et `plaquePhotoUrl` sont absolus - `GET /api/trailers` → Tous les `photoUrl` sont absolus - `GET /api/trailers/{id}` → `photoUrl` est absolu ## Extension future (audio/vidéo) ### Structure prévue ```php // Dans un futur Model (ex: Breakdown) 'audio_url' => MediaUrl::url($this->audio_path, 'public'), 'video_url' => MediaUrl::url($this->video_path, 'public'), ``` ### Dossiers à créer ```bash storage/app/public/audios/ storage/app/public/videos/ ``` ### Endpoints à créer - `POST /api/upload/breakdown-audio` - `POST /api/upload/breakdown-video` ## Tests ### Vérification manuelle 1. Uploader une photo de véhicule via `POST /api/upload/vehicle-photo` 2. Vérifier que la réponse contient une URL absolue : ```json { "url": "https://apiparcapp.jrbxsolutions.com/storage/vehicles/vehicle_1234567890_abc123.jpg", "publicId": null } ``` 3. Récupérer un véhicule via `GET /api/vehicles/{id}` 4. Vérifier que `photoUrl` est une URL absolue commençant par `https://apiparcapp.jrbxsolutions.com/` ### Test automatisé (à implémenter) ```php public function test_vehicle_photo_url_is_absolute() { $vehicle = Vehicle::factory()->create([ 'photo_url' => '/storage/vehicles/test.jpg' ]); $response = $this->getJson("/api/vehicles/{$vehicle->id}"); $response->assertJson([ 'photoUrl' => function ($url) { return str_starts_with($url, 'https://apiparcapp.jrbxsolutions.com/'); } ]); } ``` ## Migration des données existantes Si la base de données contient des chemins relatifs (`/storage/...`), ils seront automatiquement transformés en URLs absolues lors de la sérialisation via les API Resources. **Aucune migration de données n'est nécessaire** : la transformation se fait à la volée. ## Notes importantes 1. **Ne jamais renvoyer de chemins relatifs** dans les réponses API 2. **Toujours utiliser `MediaUrl::url()`** dans les API Resources 3. **Vérifier `APP_URL`** en production pour garantir le bon domaine 4. **Le helper gère automatiquement** les URLs externes (Cloudinary, CDN, etc.)