Le besoin
Les créateurs uploadent des photos pour leurs drops. On a besoin d'un stockage fiable, rapide et pas cher.
Pourquoi R2
- Egress gratuit : pas de frais de bande passante (contrairement à S3)
- Compatible S3 : même API, même SDK
- CDN intégré : les fichiers sont servis depuis le edge Cloudflare
- Coût prévisible : $0.015/GB/mois de stockage, rien d'autre
Le flow d'upload
1. Le client demande une URL d'upload
L'app web appelle POST /api/v1/uploads/presign avec :
- Le type de fichier (image/jpeg, image/png)
- Le préfixe (drop-images, avatars, etc.)
- Le nom du fichier
2. L'API génère une presigned URL
L'API vérifie les permissions, génère un UUID unique pour la clé, et retourne une URL pré-signée valide 10 minutes.
3. Le client upload directement vers R2
Le navigateur fait un PUT directement vers R2 — le fichier ne passe jamais par notre API. C'est plus rapide et ça ne charge pas le serveur.
4. L'URL publique est stockée
Une fois l'upload terminé, le client envoie l'URL publique du fichier à l'API qui l'associe au drop.
Sécurité
- Validation du type MIME : seuls les formats image autorisés
- Validation du nom de fichier : regex stricte, pas de path traversal
- Ownership check : seul le créateur du drop peut uploader des images pour ce drop
- Presigned URL : expiration courte (10 min), usage unique
Organisation des buckets
avatars/— photos de profildrop-images/— visuels des dropsdrop-assets/— fichiers digitaux (post-achat)post-purchase/— contenu post-achat
En résumé
Client → API (presign) → R2 (upload direct) → URL publique. Rapide, sécurisé, pas cher.