Documentation

Référence

Données : collections, fichiers, réglages

Mis à jour le 4 septembre 2026Plateforme v1 Markdown brut

Le principe

Une app Capibara ne possède pas de base de données : ses données vivent dans
l’organisation qui l’a installée
, cloisonnées par app. Trois familles, toutes
servies par ctx (code hébergé) :

Famille ctx Capability Pour quoi
Collections ctx.data.<nom> data.collections des enregistrements typés, déclarés au manifeste (scores, favoris, tickets…)
Clé/valeur ctx.kv storage.tenant.ro / .rw curseurs, caches, petits réglages (32 Ko / 200 clés)
Fichiers privés ctx.files files.private pièces jointes, exports, images générées (≤ 5 Mo)

Et une quatrième, saisie par un administrateur de l’organisation, jamais par
votre code : les réglages (settings du manifeste → ctx.install.config),
avec des champs secret chiffrés au repos.

Conséquences, toutes voulues : la donnée est supprimée avec l’organisation,
incluse dans son export RGPD, conservée 30 jours après une
désinstallation (réinstaller la retrouve) puis purgée par la plateforme —
l’admin peut aussi purger tout de suite depuis la fiche de l’app. Vous ne
gérez ni migration, ni sauvegarde, ni DDL : le manifeste est le contrat.

Déclarer des collections

{
  "capabilities": ["data.collections"],
  "collections": {
    "favorites": { "fields": { "city": "string", "addedAt": "date" } },
    "scores":    { "fields": { "partyId": "string", "value": "number", "label": "string", "meta": "json" }, "indexes": ["partyId"] }
  }
}
  • Types de champ : string (≤ 20 000 caractères), number, boolean,
    date (ISO 8601, normalisée à l’écriture), json (valeur libre ≤ 16 Ko).
  • Au plus 10 collections et 30 champs par collection ; noms =
    identifiants simples (a-z puis lettres/chiffres/_). Le nom $files
    est réservé.
  • indexes est documentaire : les égalités sont déjà indexées (GIN).
  • Requiert main : seules les apps hébergées y accèdent — un backend
    externe
    n’a ni collections, ni KV, ni fichiers
    (le manifeste les refuse sans main).

Toute écriture est validée contre la déclaration : un champ non déclaré,
un type faux ou un enregistrement > 64 Ko sont refusés avec un message qui
nomme le champ. Un null est accepté partout (champ vide).

Lire et écrire — ctx.data

// Créer ou remplacer (clé fournie) — la clé est générée (« rec_… ») si absente.
const fav = await ctx.data.favorites.set({ city: 'Lyon', addedAt: new Date().toISOString() }, 'lyon');

// Lire une ligne par sa clé.
const row = await ctx.data.favorites.get('lyon');   // { id, key, data, createdAt, updatedAt } | null

// Interroger : where + orderBy + curseur, ≤ 100 lignes par page.
const page = await ctx.data.scores.query({
  where: { partyId: 'p_123', value: { gte: 10 } },
  orderBy: { field: 'createdAt', dir: 'desc' },
  limit: 20,
});
const next = page.nextCursor ? await ctx.data.scores.query({ where: { partyId: 'p_123' }, cursor: page.nextCursor }) : null;

// Compter, supprimer.
const { count } = await ctx.data.scores.count({ partyId: 'p_123' });
await ctx.data.favorites.delete('lyon');

Opérateurs de where par type (au plus 5 conditions, in ≤ 20 valeurs) :

Type Opérateurs
string eq, ne, in, contains
number eq, ne, in, gt, gte, lt, lte
date eq, ne, gt, gte, lt, lte
boolean eq, ne
json aucun (stockage seulement)

{ champ: valeur } vaut { champ: { eq: valeur } }. Le tri porte sur
updatedAt (défaut, décroissant), createdAt ou key — le tri par champ
de données viendra plus tard ; en attendant, triez la page côté code ou
utilisez la clé.

Quota de lignes par app installée (toutes collections) : 5 000 (Gratuit),
100 000 (Pro), 1 000 000 (Business). Au-delà, set d’une NOUVELLE clé
échoue avec un message clair — remplacer une ligne existante passe toujours.

Fichiers privés — ctx.files

{ "capabilities": ["files.private"] }
const f = await ctx.files.put('rapport.pdf', pdfBytes);     // Uint8Array, ArrayBuffer ou base64
// f = { id, name, contentType, size, url, createdAt }
return ui.link({ label: 'Télécharger le rapport', href: f.url });   // ou ui.image({ src: f.url, alt: '…' })

const { dataBase64 } = await ctx.files.get(f.id);
const { files } = await ctx.files.list();
await ctx.files.delete(f.id);
  • Types acceptés : png, jpg, webp, gif (vérifiés par leurs octets de
    signature), pdf, csv, txt, md, json — ≤ 5 Mo par fichier,
    500 fichiers par installation ; l’espace compte dans le quota de
    stockage de la formule
    de l’organisation (comme sa médiathèque).
  • url est un chemin relatif vers une route gardée : seule une personne
    connectée à l’organisation ET autorisée à « utiliser l’app » peut l’ouvrir.
    Jamais d’URL publique, jamais de lien devinable.

Réglages — settings

{
  "settings": {
    "fields": [
      { "key": "defaultCity", "label": "Ville par défaut", "type": "text", "placeholder": "Paris" },
      { "key": "mode", "label": "Mode", "type": "select", "options": [{ "value": "simple", "label": "Simple" }, { "value": "expert", "label": "Expert" }] },
      { "key": "apiKey", "label": "Clé API du service tiers", "type": "secret", "required": true, "help": "Trouvez-la dans votre compte du service." }
    ]
  }
}
  • Types : text, textarea, number, boolean, select (avec
    options), secret. Au plus 20 champs.
  • Un administrateur remplit ces réglages sur la fiche de l’app
    (« Réglages de l’app ») ; votre code les lit dans ctx.install.config
    (ctx.install.config.defaultCity).
  • Un champ secret est chiffré au repos (contexte imposé par la
    plateforme) et jamais renvoyé à l’écran : l’admin voit « défini » et
    peut le remplacer ; seul votre code hébergé reçoit la valeur en clair.
    Ne le journalisez pas (ctx.log est visible de l’admin).
  • Les champs config des widgets continuent d’arriver dans le même
    ctx.install.config ; en cas de clé identique, le réglage déclaré prime.

Cycle de vie, export, test

  • Désinstallation : tout est conservé 30 jours (l’organisation voit
    « Données conservées » sur la fiche, avec « Effacer maintenant ») ; passé ce
    délai, la plateforme purge lignes, fichiers, KV et réglages.
  • Export : l’admin exporte les données de votre app en JSON depuis la
    fiche ; elles font aussi partie de l’export RGPD de l’organisation
    (collections + métadonnées des fichiers + KV).
  • Pendant le développement : la section Données de votre app
    (portail) montre les collections, le KV et les fichiers de vos
    installations de test, avec suppression ligne à ligne — jamais ceux
    d’une installation réelle. Retirer une install de test efface ses données.
Données : collections, fichiers, réglages · Capibara for Developers