> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oximail.ch/llms.txt
> Use this file to discover all available pages before exploring further.

# Fichiers

> La surface JMAP File Storage (draft-ietf-jmap-filenode) : les arbres FileNode, les blobs, l'historique de versions, la corbeille, les favoris par lecteur, les vignettes et les liens de partage anonymes.

Le drive est la surface du draft JMAP File Storage (des objets FileNode au-dessus de la mécanique de blobs standard) : un arbre de fichiers et de répertoires par compte, partageable par nœud, avec des liens de téléchargement anonymes comme objet distinct.

## Objets et méthodes

| Objet           | Méthodes                                                  | Notes                                                                                                            |
| --------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `FileNode`      | `get`, `set`, `query`, `queryChanges`, `changes`, `share` | Les fichiers et répertoires en un seul arbre.                                                                    |
| `FileVersion`   | `get`, `query`, `restore`                                 | L'historique de contenu immuable d'un nœud : voir [l'historique de versions](#lhistorique-de-versions) plus bas. |
| `FileShareLink` | `get`, `set`                                              | Les liens anonymes vers un nœud : expiration, plafond de téléchargements, mot de passe optionnel.                |

Le contenu passe par les points d'accès de blobs JMAP standard (`/jmap/upload`, `/jmap/download`) : une création de `FileNode` référence un `blobId` téléversé.

## L'historique de versions

Chaque mise à jour du contenu d'un nœud photographie le blob **précédent** dans son historique de versions, dans la même transaction que la mise à jour. Le contenu courant vit toujours sur le nœud lui-même ; `FileVersion` n'est que de l'histoire, et chacune de ses propriétés est immuable :

| Propriété       | Notes                                                            |
| --------------- | ---------------------------------------------------------------- |
| `id`            | L'identifiant propre de la version.                              |
| `fileNodeId`    | Le nœud auquel cette version appartient.                         |
| `versionNumber` | Monotone par nœud.                                               |
| `blobId`        | Se télécharge comme n'importe quel blob.                         |
| `size`          | Capturée au moment de la photographie.                           |
| `contentType`   | `string \| null` : la clé est toujours présente, jamais absente. |
| `createdBy`     | `string \| null`, même règle.                                    |
| `createdAt`     | Posée par le serveur (UTCDate).                                  |

La capacité `urn:ietf:params:jmap:files` annonce `maxVersionsPerNode` (10 en v0.30.0). C'est à la fois la fenêtre de conservation et la borne d'élagage, depuis une seule constante : les versions au-delà des N plus récentes sont élaguées dans la transaction même qui a créé la plus récente, et leurs blobs sont libérés par le chemin de destruction à compteur de références, jamais par une suppression directe, puisqu'un blob peut être partagé par déduplication. Un client doit conditionner son entrée de menu « historique de versions » à la présence de cette clé, plutôt que de supposer que la surface existe.

* **`FileVersion/query` exige un filtre `fileNodeId`.** Les versions n'ont pas de sens en liste à l'échelle du compte, et exiger ce point d'ancrage garde la surface bornée par le plafond de conservation. Les plus récentes d'abord par défaut. Son `queryState` est l'état de la collection **FileNode** : les versions ne changent que quand le contenu d'un nœud change, ce qui fait avancer cet état, donc un seul curseur est cohérent pour les deux. `canCalculateChanges` vaut `false` : il n'y a pas de journal de changements distinct pour les versions, donc re-interrogez sur un changement de FileNode.
* **`FileVersion/restore` ne détruit jamais l'histoire.** L'opération passe par le même point de passage de stockage qu'une mise à jour de contenu `FileNode/set { blobId }` : le contenu sur lequel vous êtes est donc photographié comme nouvelle version *avant* d'être remplacé. La version d'où vous venez reste atteignable, et l'élagage s'applique comme d'habitude. `size` et `contentType` sont restaurés depuis l'enregistrement de version, qui fait foi puisqu'il les a capturés au moment de la photographie. Restaurer la version dont le blob est déjà le courant ne change rien au contenu, mais répond quand même en succès. La méthode accepte un `ifInState` optionnel, pour le même contrôle de concurrence optimiste que `FileNode/set`, vérifié atomiquement avec l'écriture.
* **Les droits suivent le nœud.** Lire la liste des versions demande `mayRead` sur le nœud propriétaire, `restore` demande `mayWrite` (un montage partagé en lecture seule répond `forbidden`). Un nœud qui n'existe pas et un nœud qu'un appelant partagé n'a pas le droit de lire répondent avec un libellé **identique** : la surface des versions n'est pas un oracle d'existence.

## Comportements à connaître

* **`type` est respecté.** `type: "directory"` crée un répertoire ; le champ est validé, jamais deviné d'après la présence d'un blob.
* **L'arbre a une racine ; le fil utilise `null`.** Chaque compte a une racine de stockage ; `parentId: null` dans une requête signifie « premier niveau ». Les déplacements de répertoires sont vérifiés contre les cycles : un déplacement qui créerait un cycle de parenté est rejeté.
* **La corbeille voyage dans la même transaction.** Une mise à jour d'`isTrashed` est atomique avec le reste de la mise à jour (la mise à la corbeille récursive d'un répertoire est une seule transaction), et les nœuds à la corbeille se restaurent depuis la corbeille visible (ADR-035).
* **Les favoris sont par lecteur.** Mettre en favori un fichier partagé marque *votre* vue ; l'objet du propriétaire n'est pas touché.
* **Les vignettes sont dérivées côté serveur** pour les types prévisualisables ; les clients n'envoient pas les leurs.
* **Les liens de partage sont bornés et comptés.** Un `FileShareLink` donne accès à exactement son sous-arbre, applique `maxDownloads` au téléchargement près, rend le quota à la suppression, et un lecteur anonyme ne peut déchiffrer que les blobs référencés par la **projection fichiers** du compte résolu : la couche crypto adosse l'ACL ([chiffrement au repos](../operator/encryption-at-rest)).

La déduplication des blobs est par organisation et adressée par contenu : téléverser deux fois le même fichier ne le stocke qu'une fois. Les règles de rigueur sont identiques à la [surface courrier](./jmap-mail).
