feat(rental): Sprint F — photos & vidéos items rental #80

Merged
tarzzan merged 1 commit from feat/rental-sprint-f into main 2026-06-02 09:38:38 +00:00
Owner

Sprint F — Photos & vidéos items rental

Comble le gap mentionné dans la doc Sprint A : les items rental n'avaient qu'un imageUrl simple, là où les carbets ont un modèle Media riche avec ordering, cover, suppression, variantes responsives.

Schéma

  • Nouveau modèle RentalItemMedia (parallèle de Media) : s3Key, s3Url, sortOrder, type (PHOTO|VIDEO), cascade sur RentalItem
  • Migration 20260603100000_rental_item_mediaappliquée à la DB prod via container éphémère

Endpoints upload (dédiés, pas d'overload du flow carbet)

  • POST /api/uploads/rental-presign — auth canManageRentalProvider (admin OR provider manager), s3Key préfixé rental-items/<itemId>/
  • POST /api/uploads/rental-finalize — crée la RentalItemMedia, hydrate RentalItem.imageUrl avec la première PHOTO (rétro-compat listings), génère les variantes responsives en best-effort
  • DELETE /api/rental-media/[id] + POST /api/rental-media/reorder — reorder met à jour imageUrl pour suivre le cover (sortOrder 0)

MediaUploader générique

Refactor avec prop scope: {kind, id} :

  • {kind: "carbet", carbetId} — comportement inchangé (rétro-compat carbetId prop deprecated)
  • {kind: "rental-item", itemId} — utilise les nouveaux endpoints

Aucune régression côté carbet : les call-sites existants restent intacts.

UI branchée

  • /admin/rental-items/[id] — section « Photos & vidéos » au-dessus du form
  • /espace-prestataire/items/[itemId] — idem côté prestataire
  • /materiel/[itemId] — nouveau <ItemGallery /> (thumbs cliquables + support vidéo), fallback sur ancien imageUrl si pas de média dédié (compat seed)

Test plan

  • Activer gear-rental sur /admin/plugins
  • /admin/rental-items/[id] : upload 2 photos via drag&drop, réordonner, supprimer
  • Vérifier que RentalItem.imageUrl est mis à jour vers le cover (DB)
  • /materiel/[itemId] affiche la galerie avec thumbs
  • Login prestataire (role RENTAL_PROVIDER), même flow depuis /espace-prestataire/items/[itemId]
  • Variantes responsives générées dans MinIO : rental-items/X/Y.jpg-320.jpg, -800.jpg, -1600.jpg

🤖 Generated with Claude Code

## Sprint F — Photos & vidéos items rental Comble le gap mentionné dans la doc Sprint A : les items rental n'avaient qu'un `imageUrl` simple, là où les carbets ont un modèle `Media` riche avec ordering, cover, suppression, variantes responsives. ### Schéma - Nouveau modèle `RentalItemMedia` (parallèle de `Media`) : s3Key, s3Url, sortOrder, type (PHOTO|VIDEO), cascade sur RentalItem - Migration `20260603100000_rental_item_media` — **appliquée à la DB prod** via container éphémère ### Endpoints upload (dédiés, pas d'overload du flow carbet) - `POST /api/uploads/rental-presign` — auth `canManageRentalProvider` (admin OR provider manager), s3Key préfixé `rental-items/<itemId>/` - `POST /api/uploads/rental-finalize` — crée la `RentalItemMedia`, hydrate `RentalItem.imageUrl` avec la première PHOTO (rétro-compat listings), génère les variantes responsives en best-effort - `DELETE /api/rental-media/[id]` + `POST /api/rental-media/reorder` — reorder met à jour `imageUrl` pour suivre le cover (sortOrder 0) ### MediaUploader générique Refactor avec prop `scope: {kind, id}` : - `{kind: "carbet", carbetId}` — comportement inchangé (rétro-compat `carbetId` prop deprecated) - `{kind: "rental-item", itemId}` — utilise les nouveaux endpoints Aucune régression côté carbet : les call-sites existants restent intacts. ### UI branchée - `/admin/rental-items/[id]` — section « Photos & vidéos » au-dessus du form - `/espace-prestataire/items/[itemId]` — idem côté prestataire - `/materiel/[itemId]` — nouveau `<ItemGallery />` (thumbs cliquables + support vidéo), fallback sur ancien `imageUrl` si pas de média dédié (compat seed) ### Test plan - [ ] Activer `gear-rental` sur `/admin/plugins` - [ ] `/admin/rental-items/[id]` : upload 2 photos via drag&drop, réordonner, supprimer - [ ] Vérifier que `RentalItem.imageUrl` est mis à jour vers le cover (DB) - [ ] `/materiel/[itemId]` affiche la galerie avec thumbs - [ ] Login prestataire (role RENTAL_PROVIDER), même flow depuis `/espace-prestataire/items/[itemId]` - [ ] Variantes responsives générées dans MinIO : `rental-items/X/Y.jpg-320.jpg`, `-800.jpg`, `-1600.jpg` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
tarzzan added 1 commit 2026-06-02 09:34:32 +00:00
feat(rental): Sprint F — photos & vidéos items rental
All checks were successful
CI / test (pull_request) Successful in 2m18s
9da58288dc
Nouveau modèle `RentalItemMedia` parallèle de `Media` (carbet) :
- s3Key / s3Url / sortOrder / type (PHOTO|VIDEO), cascade sur RentalItem
- Migration `20260603100000_rental_item_media` appliquée

Endpoints upload dédiés (mêmes conventions que carbet) :
- POST /api/uploads/rental-presign + POST /api/uploads/rental-finalize
  → auth par canManageRentalProvider (admin OR provider manager)
  → s3Key préfixé `rental-items/<itemId>/`
  → finalize hydrate `RentalItem.imageUrl` avec la première PHOTO
  → générateur de variantes (320/800/1600 via sharp) en best-effort
- DELETE /api/rental-media/[id] + POST /api/rental-media/reorder
  → reorder rafraîchit imageUrl (cover = sortOrder 0)

`MediaUploader` rendu générique :
- Nouveau prop `scope: {kind: "carbet" | "rental-item", id}` ; conserve
  rétro-compat `carbetId` (deprecated)
- Endpoints + payload key (`carbetId` ↔ `itemId`) calculés via
  `endpointsFor()`. Aucun changement de comportement côté carbet.

UI branchée :
- /admin/rental-items/[id] : section « Photos & vidéos » au-dessus du
  form, alimentée par `item.media` chargé par `getRentalItemForAdmin`
- /espace-prestataire/items/[itemId] : idem, charge via `getHostItem`
- /materiel/[itemId] : nouveau `<ItemGallery />` (thumbs cliquables +
  support vidéo). Fallback : ancien `item.imageUrl` si pas de média
  dédié (compat seed).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tarzzan merged commit d24e3b4af7 into main 2026-06-02 09:38:38 +00:00
tarzzan deleted branch feat/rental-sprint-f 2026-06-02 09:38:38 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: tarzzan/karbe#80
No description provided.