
# Champs de pièce jointe et stockage

Un [champ de pièce jointe](/fr/docs/attachment-fields) ne stocke pas un fichier. Il stocke une _référence_ vers un fichier, dont les octets vivent dans un [bucket](/fr/docs/buckets-overview) comme n'importe quel téléversement. Comprendre cette indirection explique l'essentiel des comportements de cette page.

```yaml
tables:
  - id: 1
    name: contracts
    fields:
      - id: 1
        name: document
        type: single-attachment
        bucket: documents
        allowedFileTypes: [application/pdf]
        maxFileSize: 10485760
```

## Quel bucket

`bucket` nomme une entrée de votre tableau `buckets[]`. Omettez-le et le champ écrit dans le bucket `default` implicite, dont la visibilité dépend de la présence de `app.auth` — voir [Présentation des buckets](/fr/docs/buckets-overview).

Deux couches de limites s'appliquent alors au même téléversement, et les deux doivent passer :

| Limite              | Sur le champ       | Sur le bucket                               |
| ------------------- | ------------------ | ------------------------------------------- |
| Types MIME acceptés | `allowedFileTypes` | `allowedMimeTypes`                          |
| Plafond de taille   | `maxFileSize`      | `maxFileSize`, puis `STORAGE_MAX_FILE_SIZE` |

Déclarer la plus stricte des deux sur le champ garde l'intention à côté de la colonne qu'elle contraint ; la limite du bucket reste le filet de sécurité pour tous les champs qui pointent vers lui.

## Ce que contient la colonne

Le fichier atteint le stockage par le [point de terminaison de téléversement](/fr/docs/file-operations) habituel, qui renvoie une clé de la forme `<uuid>-<nom-de-fichier>`. C'est cette clé — pas le nom de fichier, pas une URL — que contient la colonne.

Avec `storeMetadata: true`, la colonne contient à la place un objet portant la clé et les métadonnées capturées au téléversement (dimensions, durée). Les deux formes se résolvent vers le même objet stocké ; la seule différence tient à ce que vous pouvez afficher sans seconde requête.

## Ce que renvoie l'API des enregistrements

Lisez un enregistrement et ses valeurs de pièce jointe reviennent décorées d'un moyen d'aller réellement chercher le fichier. La décoration obtenue dépend de `STORAGE_DEFAULT_ACCESS` :

```json
{
  "id": 1,
  "fields": {
    "document": {
      "key": "9f3c1e2a-7b44-4d10-9e21-8a6f0c1d2e3b-contract.pdf",
      "signedUrl": "https://app.example.com/api/buckets/default/signed?path=…&op=download&expires=…&token=…",
      "signedUrlExpiresAt": "2026-04-05T11:00:00Z"
    }
  }
}
```

| Mode d'accès au stockage        | Ajouté à la valeur                 | Durée de vie |
| ------------------------------- | ---------------------------------- | ------------ |
| `private` (le défaut)           | `signedUrl` + `signedUrlExpiresAt` | 1 heure      |
| `STORAGE_DEFAULT_ACCESS=public` | `url` — sans jeton ni expiration   | Illimitée    |

Les deux s'excluent par conception : en mode public, `signedUrl` est délibérément absent, de sorte qu'un client peut compter sur le fait que `url` ne contient jamais de jeton et que `signedUrl` signifie toujours « ceci expire ».

Parce que l'URL est émise à chaque lecture, un enregistrement récupéré il y a une heure porte un lien désormais mort. Relisez l'enregistrement plutôt que de mettre l'URL en cache — la clé est la prise durable, l'URL ne l'est pas.

:::callout
**Les URL signées automatiques pointent vers le bucket `default`.** L'URL attachée par l'API des enregistrements est construite sur `/api/buckets/default/signed`, quel que soit le bucket déclaré par le champ. Un champ avec `bucket: documents` renvoie donc un lien qui ne se résoudra pas. En attendant la correction, émettez l'URL vous-même sur le bon bucket avec [`POST /api/buckets/{bucket}/sign`](/fr/docs/signed-urls-download) — ou gardez les champs de pièce jointe sur le bucket `default`, où le lien renvoyé est correct.
:::

## Les images en pièce jointe

L'URL signée d'une image en pièce jointe accepte des [paramètres de transformation](/fr/docs/image-transforms) ajoutés à sa suite : un seul original stocké sert ainsi toutes les tailles dont une page a besoin.

```text
<signedUrl>&width=150&height=150&fit=cover
```

Le jeton couvre le chemin et l'expiration, pas la requête de transformation : ajouter des paramètres ne l'invalide donc jamais.

## Suppression

La suppression d'un enregistrement pilote celle du fichier — voir [Cycle de vie et quotas](/fr/docs/file-lifecycle) pour le tableau complet. En résumé : une suppression douce conserve les octets, `?purge=true` les retire, `?permanent=true` ne les retire pas, et remplacer ou vider une valeur `single-attachment` supprime le fichier qu'elle déplace.

## Pages associées

- [Champs de pièce jointe](/fr/docs/attachment-fields) — les propriétés du champ lui-même.
- [Présentation des buckets](/fr/docs/buckets-overview) — le bucket où écrit une pièce jointe.
- [Opérations sur les fichiers](/fr/docs/file-operations) — le point de terminaison qui produit la clé.
- [URL de téléchargement](/fr/docs/signed-urls-download) — émettre un lien soi-même.
- [Cycle de vie et quotas](/fr/docs/file-lifecycle) — quand les octets disparaissent.
- [Téléversement de fichiers par formulaire](/fr/docs/form-file-uploads) — remplir une pièce jointe depuis un formulaire.
