# Page de livraison

> Déployer templates/drop sur Vercel avec votre bucket : Root Directory, variables, CORS et cycle de vie sur R2.

Canonical: https://colis-docs.vercel.app/docs/page-de-livraison · Markdown: https://colis-docs.vercel.app/docs/page-de-livraison.md

La page de livraison est une app Next.js du dépôt, `templates/drop`. C’est elle que votre client
ouvre : elle reçoit les fichiers, affiche la page de retrait avec l’aperçu, tient l’accusé de
réception et envoie les webhooks. Elle tourne sur votre compte Vercel, avec votre bucket ; une démo
est en ligne sur [colis-tau.vercel.app](https://colis-tau.vercel.app).

## Ce qu’elle sert

| Route                         | Rôle                                                                                                                      |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `/`                           | La zone de dépôt, le fichier en attente avec ses options, et « Vous avez déjà un code ? ».                                |
| `/K7QP2M4X`                   | La page de retrait : l’aperçu, ce que l’on sait du colis, le téléchargement, un QR code, la réponse du client.            |
| `/api/transfers/*`            | Les quatre routes du [protocole](https://colis-docs.vercel.app/docs/protocole), donc la CLI fonctionne aussi.                                          |
| `/api/transfers/:code/status` | L’accusé de réception, et ses deux `POST` : `opened` et `verdict`. Voir [Suivi et validation](https://colis-docs.vercel.app/docs/suivi-et-validation). |
| `/api/transfers/uploads/*`    | Les [gros fichiers](https://colis-docs.vercel.app/docs/gros-fichiers) : URL présignées pour les morceaux, puis l’assemblage.                           |
| `/api/preview/:code`          | Les mêmes octets, servis pour être regardés plutôt qu’enregistrés.                                                        |
| `/connexion`, `/api/auth/*`   | Les [comptes](https://colis-docs.vercel.app/docs/compte), facultatifs : connexion par lien e-mail, et `colis connexion` pour un terminal.              |
| `/api/unlock/:code`           | Là où l’on tape le mot de passe d’un colis protégé.                                                                       |

## Le bucket

1. **Créez un bucket** et une paire de clés qui ne peut que lire et écrire dans ce bucket. Sur
   Cloudflare R2 : **R2 → Create bucket**, puis un jeton d’API avec **Object Read & Write** limité à
   ce bucket. Sur AWS : un utilisateur IAM ou un rôle limité au bucket. Voir [Stockages](https://colis-docs.vercel.app/docs/stockages).
2. **Ajoutez une règle de cycle de vie** sur le préfixe (`drop/` par défaut). L’expiration empêche
   un colis d’être remis ; seule la règle supprime l’objet. Réglez-la au moins un jour au-delà de la
   plus longue durée autorisée, `DROP_MAX_EXPIRES_IN` (sept jours par défaut, donc huit jours) —
   ou `DROP_PRO_MAX_EXPIRES_IN` (trente jours, donc 31) si le déploiement vend la
   [formule Pro](https://colis-docs.vercel.app/docs/abonnement) —, sinon le bucket supprime des colis encore valides. Ajoutez-y `AbortIncompleteMultipartUpload` après un
   jour, pour les envois de gros fichiers abandonnés.
3. **Ajoutez une règle CORS** si vous gardez les [gros fichiers](https://colis-docs.vercel.app/docs/gros-fichiers) : le navigateur
   envoie leurs morceaux directement au bucket.

Sur R2, les deux réglages sont dans **R2 → votre bucket → Settings** : _Object lifecycle rules_ et
_CORS Policy_. La règle CORS, avec l’adresse de votre déploiement :

```json
[
  {
    "AllowedOrigins": ["https://votre-livraison.vercel.app"],
    "AllowedMethods": ["PUT"],
    "AllowedHeaders": ["*"],
    "ExposeHeaders": ["ETag"],
    "MaxAgeSeconds": 3600
  }
]
```

Ajoutez `http://localhost:3400` aux origines pour tester en développement.

## Sur Vercel

Tant que les paquets `@colis/*` ne sont pas sur npm, la page se construit depuis le monorepo : on
importe **tout le dépôt**, pas seulement le dossier du template.

1. **Add New → Project**, et choisissez votre fork du dépôt `colis`.
2. **Root Directory** : `templates/drop`. Laissez _Include files outside the root directory_ activé :
   le `vercel.json` de ce dossier installe à la racine avec Bun
   (`bun install --frozen-lockfile`) et construit avec Turborepo
   (`bunx turbo run build --filter=colis-drop`), paquets compris.
3. **Environment Variables** : les cinq variables du bucket, et `DROP_PASSWORD` pour que des
   inconnus ne puissent pas remplir votre bucket.

| Variable                | Valeur                                                                               |
| ----------------------- | ------------------------------------------------------------------------------------ |
| `COLIS_BUCKET`          | Le nom du bucket.                                                                    |
| `COLIS_ENDPOINT`        | Pour R2 : `https://<account-id>.r2.cloudflarestorage.com`. Vide pour AWS S3.         |
| `COLIS_REGION`          | `auto` pour R2 (c’est la valeur par défaut) ; une vraie région pour AWS et Scaleway. |
| `AWS_ACCESS_KEY_ID`     | La clé d’accès.                                                                      |
| `AWS_SECRET_ACCESS_KEY` | La clé secrète.                                                                      |
| `DROP_PASSWORD`         | Demandé avant chaque envoi. Le retrait ne le demande jamais.                         |

Toutes les autres variables (durées, tailles, aperçu, webhooks) sont dans
[Configuration](https://colis-docs.vercel.app/docs/configuration#la-page-de-livraison).

4. **Vérifiez** que le déploiement fait un vrai aller-retour :

```sh
colis verifier --remote https://votre-livraison.vercel.app/api/transfers --token "$DROP_PASSWORD"
```

Pour garder l’adresse et le mot de passe hors de votre historique, mettez-les dans un
`colis.config.json` (`colis init --provider remote`), voir [CLI](https://colis-docs.vercel.app/docs/cli#le-fichier-de-configuration).

## Avant l’envoi

Choisir un fichier ne l’envoie pas : la page le montre (l’image, la vidéo, les premières lignes du
texte) et propose ce que l’expéditeur peut décider. Rien ne part avant le bouton.

| Option                                       | Effet                                                                                 |
| -------------------------------------------- | ------------------------------------------------------------------------------------- |
| **Durée de conservation**                    | De dix minutes à `DROP_MAX_EXPIRES_IN`. Passé ce délai, le bucket ne remet plus rien. |
| **Mot de passe pour ce colis**               | Demandé avant de voir quoi que ce soit. Haché avec scrypt, jamais récupérable.        |
| **Détruire après le premier téléchargement** | Le code cesse de fonctionner quand les octets partent. L’aperçu reste gratuit.        |
| **Renommer le fichier**                      | Le nom sous lequel le client le télécharge.                                           |
| **Envoyé depuis**                            | Une étiquette pour la machine, devinée depuis le navigateur : « Chrome sur macOS ».   |
| **Un message**                               | Jusqu’à 280 caractères, affichés au-dessus du fichier sur la page de retrait.         |

Ces options voyagent dans des en-têtes `x-drop-*` à côté du protocole, que la CLI ne connaît pas :
un colis envoyé par `colis envoyer` prend les valeurs par défaut du déploiement. Depuis un terminal,
les mêmes options s’envoient à la main :

```sh
curl -X POST https://votre-livraison.vercel.app/api/transfers \
  -H "authorization: Bearer $DROP_PASSWORD" \
  -H 'content-type: application/pdf' \
  -H "x-colis-filename: $(printf %s contrat.pdf | jq -sRr @uri)" \
  -H 'x-drop-expires-in: 3600' -H 'x-drop-once: 1' \
  -H 'x-drop-passphrase: open%20sesame' \
  --data-binary @contrat.pdf
```

`x-drop-note` et `x-drop-device` portent le message et l’étiquette, encodés de la même façon.

## Le retrait

Trois façons d’arriver sur la page de retrait :

- **Taper le code** sur la page d’accueil. `k7qp-2m4x` retrouve `K7QP2M4X` : séparateurs retirés,
  casse unifiée, `O` lu comme zéro.
- **Scanner le QR code** affiché après l’envoi et sur la page de retrait.
- **Depuis un terminal** : `colis recevoir k7qp-2m4x --remote https://votre-livraison.vercel.app/api/transfers`.

La page montre ce qu’il y a avant tout téléchargement : image, vidéo, audio, PDF, premières lignes
d’un texte, et pour le reste l’extension et la taille. Dessous, le nom, la taille, le type, la date
d’envoi, le temps restant, la machine d’envoi et, le cas échéant, la destruction au téléchargement.
Puis la réponse du client : voir [Suivi et validation](https://colis-docs.vercel.app/docs/suivi-et-validation).

**Un colis protégé** ne dit que cela tant que le mot de passe n’est pas tapé. Il part vers
`/api/unlock/<code>`, qui donne au navigateur un cookie valable pour ce seul code, jusqu’à la
fermeture du navigateur. Dix mauvais mots de passe depuis un même client, ou cinquante sur un même
code, verrouillent ce code quinze minutes (`429`). Depuis un terminal, le mot de passe du colis
passe en `--token`.

**Un colis à usage unique** l’annonce avant le clic. Le premier téléchargement le réserve par une
écriture conditionnelle ; un second lancé au même moment est refusé.

## Les deux mots de passe

`DROP_PASSWORD` appartient au déploiement : sans lui, quiconque trouve la page peut déposer un
fichier dans votre bucket. Avec lui, la page le demande une fois avant l’envoi et l’envoie en jeton
Bearer ; la CLI le passe avec `--token`, le nœud n8n dans ses identifiants.

Le mot de passe d’un colis appartient à l’expéditeur, un par colis. Seule son empreinte scrypt est
stockée : personne, pas même vous, ne peut le relire ni le réinitialiser.

## Personnaliser

Tailwind 4, deux pages, aucune bibliothèque de composants. Les couleurs, les polices et les rayons
sont des variables en tête de `app/globals.css`, avec un jeu sombre sous `prefers-color-scheme`.
`DROP_NAME` change le nom affiché dans l’en-tête et le titre. Le
[README du template](https://github.com/mamadouwhile/colis/blob/main/templates/drop/README.md)
liste chaque fichier et son rôle.
