Aller au contenu

Propriétés

Les propriétés définissent les colonnes de votre table de base de données ainsi que la manière dont elles sont affichées dans l’interface d’administration. Chaque propriété possède un type qui détermine :

  • Le type de colonne de la base de données (via la génération de schéma Drizzle)
  • Le composant de champ de formulaire
  • Le moteur de rendu de cellule de tableau
  • Les règles de validation
Type Description Colonne PostgreSQL
string Texte, select, markdown, téléversement de fichier, URL, e-mail text par défaut ; varchar, char ou uuid avec columnType
number Entier, décimal, devise integer, numeric, bigint, serial
boolean Bascule vrai/faux boolean
date Date, date et heure, horodatage timestamp, date
array Liste ordonnée de valeurs Un tableau natif (text[], integer[], numeric[], boolean[]) lorsque of est une unique propriété chaîne, nombre ou booléen ; jsonb sinon
map Objet clé-valeur jsonb
geopoint Paire latitude/longitude jsonb
reference Référence intégrée vers une autre entité Le type de la clé primaire de la cible (stocke son ID)
relation Relation de clé étrangère SQL Utilise le tableau relations
vector Embedding, pour la recherche des plus proches voisins VECTOR(n) (pgvector)
binary Octets bruts, lus et écrits en base64 bytea

Tous les types de propriétés partagent ces options :

Propriété Type Description
type string Requis. Type de données (voir ci-dessus)
name string Libellé d’affichage. Par défaut, la clé de la propriété mise en forme — publishDate → “Publish Date”. Définissez-le lorsque cette dérivation est incorrecte : "URL" plutôt que “Url”.
description string Texte d’aide affiché sous le champ
defaultValue any Valeur par défaut pour les nouvelles entités. Une valeur littérale — une chaîne, un nombre, un booléen, une date, un identifiant d’enum, ou un document map/array — devient également le DEFAULT de la colonne, de sorte qu’une ligne insérée par tout ce qui n’est pas le panneau d’administration (l’API REST, un seed, psql) la reçoit également
databaseDefault boolean | SqlExpression Depuis 0.25 La base de données remplit la colonne lorsqu’une création la laisse vide : une colonne NOT NULL DEFAULT <expression> comme gen_random_uuid() ou nextval(…). Un champ required qui l’a peut être omis d’une création, par le formulaire d’administration comme par l’API, et un null envoyé à la création est laissé à la base de données ; il reste obligatoire à la modification, et le type Insert généré le rend optionnel. Donnez l’expression sous la forme de gabarit qu’accepte isId, databaseDefault: "sql`gen_random_uuid()`", et le planificateur de schéma l’écrit comme DEFAULT de la colonne, de sorte que rebase db push la conserve. true déclare un DEFAULT écrit ailleurs et n’en écrit aucun, si bien qu’un push prévoit de le supprimer. « Import from table » et rebase schema introspect définissent l’expression qu’ils lisent
validation object Règles de validation
propertyConfig string Clé de configuration de propriété enregistrée
columnName string Nom explicite de la colonne en base de données (contourne la conversion en snake_case)
callbacks PropertyCallbacks Hooks pour les transformations afterRead et beforeSave
excludeFromApi boolean Ne jamais mentionner cette colonne sur l’API, dans aucune direction — utile pour un hash de mot de passe ou un jeton de vérification. La valeur est toujours écrite et interrogeable côté serveur ; elle est retirée de chaque ligne servie par l’API, pour chaque appelant y compris les administrateurs et les clés de service, et elle est absente des types générés Row, Insert et Update ainsi que du schéma OpenAPI. Équivalent syntaxique de access: { read: [], write: [] } — les deux reposent sur le même mécanisme, et définir les deux sur une même propriété est refusé au démarrage
access { read?: string[]; write?: string[] } Qui peut lire et qui peut écrire ce champ spécifique, par rôle. Une liste omise délègue aux règles de sécurité de la ligne ; [] signifie personne via l’API ; une liste de rôles correspond à ces rôles plus admin. Un champ non lisible est absent des réponses plutôt que null, et une écriture ciblant un champ non modifiable renvoie une 400. Voir Accès aux champs
metadata Record<string, unknown> Tout ce dont votre propre code a besoin d’associer à une propriété. Rebase ne le lit pas ; il survit à la sérialisation sans modification
dynamicProps function Générateur de propriété dynamique (voir Champs conditionnels). Formulaire d’administration uniquement — non appliqué par l’API ou la base de données.
conditions PropertyConditions Conditions déclaratives JSON Logic. Formulaire d’administration uniquement — non appliqué par l’API ou la base de données.

Configuration de l’interface utilisateur (admin)

Section intitulée « Configuration de l’interface utilisateur (admin) »

Les options liées à l’interface utilisateur sont imbriquées sous le sous-objet admin :

price: {
type: "number",
name: "Price",
admin: {
readOnly: true,
columnWidth: 120,
hideFromCollection: false
}
}
Propriété Type Description
admin.readOnly boolean Empêche la modification
admin.disabled boolean | PropertyDisabledConfig Désactive avec infobulle optionnelle
admin.filledByServer boolean Le serveur remplit le champ lorsqu’un nouvel enregistrement le laisse vide (un hook beforeSave). Le formulaire laisse passer une création sans lui ; il reste requis à l’édition, et les propres vérifications du serveur continuent de s’appliquer
admin.hideFromCollection boolean Masque de la vue en tableau. Affichage uniquement : les lignes liées d’une propriété de relation masquée sont tout de même embarquées dans la lecture de liste (voir Relations)
admin.columnWidth number Largeur de colonne en pixels (vue en tableau)
admin.span 1 | 2 | 3 | 4 Largeur du champ sur la grille de formulaire à quatre colonnes
admin.Field React.ComponentType Composant de champ personnalisé
admin.Preview React.ComponentType Composant de cellule de tableau personnalisé
admin.Filter React.ComponentType Champ de filtre personnalisé pour cette propriété. Prioritaire sur la surcharge Collection.FilterField au niveau de la collection et sur le champ intégré par type
admin.filterOperators WhereFilterOp[] Restreint les opérateurs proposés lors du filtrage sur cette propriété. L’ensemble proposé est l’intersection des capacités du moteur, des valeurs par défaut du type et de cette liste — vous pouvez uniquement restreindre, jamais ajouter un opérateur que le moteur ne peut pas exécuter. [] désactive le filtrage sur la propriété
admin.customProps unknown Tout ce dont votre propre Field ou Preview a besoin. Rebase le transmet tel quel

La forme objet de admin.disabled. Le contrôle reste visible et grisé, ce qui constitue la différence avec admin.readOnly — un utilisateur peut voir la forme de ce qu’il n’est pas autorisé à remplir.

Propriété Type Description
disabledMessage string Raison pour laquelle cette propriété est désactivée, affichée à l’utilisateur. Sans cela, un contrôle grisé n’explique rien
clearOnDisabled boolean Définit la valeur sur null lorsque la propriété devient désactivée, afin qu’une valeur obsolète ne soit pas enregistrée avec l’entité
hidden boolean Masque entièrement le champ lorsqu’il est désactivé, plutôt que de le griser

Le type string est le plus polyvalent — selon les options que vous définissez, il s’affiche sous forme de différents widgets.

Un champ de saisie de texte simple sur une seule ligne.

name: {
type: "string",
name: "Name",
validation: { required: true, min: 2, max: 200 }
}

Définissez admin.multiline pour effectuer le rendu sous forme de zone de texte (textarea). Cela modifie la façon dont le champ est dessiné, pas ce que contient la colonne ; cela réside donc dans le bloc admin avec le reste des options de présentation.

description: {
type: "string",
name: "Description",
admin: { multiline: true }
}

Définissez admin.markdown pour afficher un éditeur markdown complet avec barre d’outils.

body: {
type: "string",
name: "Blog text",
admin: { markdown: true }
}

Définissez email: true pour ajouter la validation du format d’e-mail et l’afficher avec une icône d’e-mail.

email: {
type: "string",
name: "User email",
email: true,
validation: { required: true }
}

Définissez url: true pour ajouter la validation du format d’URL et l’afficher avec une icône de lien.

website: {
type: "string",
name: "Amazon link",
url: true
}

Définissez storage pour afficher une zone de dépôt pour le téléversement de fichiers. La colonne reste une chaîne de caractères — ce qui y est écrit est la clé de l’objet dans le bucket :

avatar: {
type: "string",
name: "Main image",
storage: { storagePath: "avatars", acceptedFiles: ["image/*"] }
}

Toutes les options disponibles dans storage, ainsi que la variante multi-fichiers de ce même champ, sont détaillées sur Téléversements de fichiers.

Définissez enum pour afficher une liste déroulante select. Voir Valeurs d’énumération pour plus de détails.

category: {
type: "string",
name: "Category",
enum: [
{ id: "electronics", label: "Electronics", color: "blueDark" },
{ id: "clothing", label: "Clothing", color: "pink" },
]
}

Plusieurs valeurs issues d’un ensemble fixe correspondent à un tableau de chaînes enum, et non à un indicateur sur une chaîne unique : la colonne contient plusieurs valeurs, la propriété qui la décrit est donc le tableau. C’est une colonne Postgres unique, un text[], plutôt qu’une jointure : un tableau dont of est une unique propriété chaîne reçoit par défaut un tableau natif, et le columnType ci-dessous ne fait que le dire explicitement.

locales: {
type: "array",
name: "Available locales",
columnType: "text[]",
of: {
type: "string",
name: "Locale",
enum: [
{ id: "es", label: "Spanish", color: "pink" },
{ id: "en", label: "English", color: "blueLight" },
{ id: "fr", label: "French", color: "purpleLight" },
]
}
}
Propriété Type Description
admin.multiline boolean Rendu sous forme de zone de texte (textarea)
admin.markdown boolean Rendu sous forme d’éditeur markdown
email boolean Validation du format d’e-mail
url boolean Validation du format d’URL
storage StorageConfig Active le téléversement de fichiers — voir Téléversements de fichiers
enum EnumValues Rendu sous forme de liste déroulante de sélection
columnType "varchar" | "text" | "char" | "uuid" La colonne de base de données. Par défaut text, ou uuid lorsque isId l’indique. text pour les chaînes sans limite de taille, char pour une longueur fixe
isId boolean | string Marque la propriété comme clé primaire et indique qui la renseigne : "manual" (vous-même), "uuid" (gen_random_uuid()), ou toute autre chaîne, utilisée textuellement comme expression SQL par défaut de la colonne — brute (nanoid()) ou sous forme de template ("sql`nanoid()`"). La fonction doit exister ; rien ici ne la crée. "increment" est une stratégie pour les nombres et ne fait rien ici, et "cuid" est refusé au chargement de la configuration
autoValue "user_on_create" | "user_on_update" Marque la colonne avec l’uid de l’utilisateur actif — à la création uniquement, ou à chaque écriture. Voir Colonnes d’audit
userSelect boolean Rendu sous forme de sélecteur d’utilisateur. La valeur est une simple colonne de chaîne contenant l’identifiant de l’utilisateur — rien ne la résout ni ne la vérifie à l’entrée. Formulaire d’administration uniquement — non appliqué par l’API ou la base de données. Le sélecteur liste les noms, e-mails et avatars des utilisateurs à quiconque peut écrire dans la collection, via GET /api/admin/users/pick, sans la portée users:read. Une collection dont les règles d’écriture sont en SQL brut ne compte pas, car elles ne peuvent pas être jugées à l’avance : là, seuls les détenteurs de users:read peuvent choisir.
admin.previewAsTag boolean Affiche cette chaîne sous forme de tag dans les aperçus
admin.clearable boolean Ajoute une icône pour effacer la valeur (définir sur null)
admin.urlPreview PreviewType Comment afficher une chaîne contenant une URL : un lien, ou un aperçu d’image, d’audio ou de vidéo intégré. Présentation uniquement — le fait que la valeur soit une URL dépend de l’indicateur url sur la propriété, à partir duquel le contrat OpenAPI est généré

autoValue sur une chaîne de caractères est l’équivalent created_by / updated_by de la même option sur une date :

createdBy: {
type: "string",
name: "Created by",
autoValue: "user_on_create",
admin: { readOnly: true }
},
updatedBy: {
type: "string",
name: "Updated by",
autoValue: "user_on_update"
}

La valeur provient du contexte de l’appel, jamais du corps de la requête — le pilote écrase tout ce qui a été envoyé, de sorte qu’un appelant ne peut pas prétendre être quelqu’un d’autre en fournissant le champ. Une colonne dont la valeur est fournie par l’appelant n’est pas une colonne d’audit.

En l’absence d’utilisateur actif — une requête anonyme, un jeton de service, un script de seed — la colonne est définie sur null. Associez-la à validation: { required: true } et cela devient une erreur 400 à la place : une collection qui exige de savoir qui a écrit une ligne est une collection qui ne peut pas accepter une écriture anonyme.

Il n’y a pas de clé étrangère. L’uid est une chaîne de caractères, le magasin d’utilisateurs peut être une base de données totalement différente, et un utilisateur supprimé ne doit pas emporter la piste d’audit avec lui — déclarez une relation si vous souhaitez une jointure.

price: {
type: "number",
name: "Price",
validation: { required: true, min: 0 }
}
quantity: {
type: "number",
name: "Quantity",
columnType: "integer" // Store as integer
}

Les champs numériques s’affichent sous forme de champ de saisie de texte standard avec validation numérique.

Propriété Type Description
enum EnumValues Rendu sous forme de select avec des valeurs numériques. Contrairement à un enum de chaînes, cela ne crée aucun type enum Postgres — la colonne reste NUMERIC ou INTEGER, de sorte que le panneau propose les valeurs mais la base de données ne les impose pas
columnType string "integer", "real", "double precision", "numeric", "bigint", "serial", "bigserial". Vaut par défaut integer lorsque validation.integer ou isId indique que la valeur est entière, numeric sinon
precision / scale number Nombre total de chiffres significatifs et de chiffres après la virgule sur une colonne numeric — NUMERIC(10, 2). L’argent manipulé sans cela est un NUMERIC sans limite qui conserve tout ce que l’appelant a envoyé, et ne peut pas être restreint ultérieurement sans réécrire la colonne
isId boolean | string Marque la propriété comme clé primaire : "manual", "increment", ou toute autre chaîne utilisée textuellement comme expression SQL par défaut de la colonne. "increment" est toujours INTEGER GENERATED BY DEFAULT AS IDENTITY — la propriété columnType définie à ses côtés est ignorée avec un avertissement, car toute clé étrangère pointant vers une clé numérique est de type INTEGER et une clé plus large serait référencée par des colonnes plus étroites
admin.clearable boolean Ajoute une icône pour effacer la valeur (définir sur null)
admin.format NumberFormatOptions Formate le nombre sous forme de devise, de pourcentage ou avec des décimales fixes. Si omis, la valeur brute est affichée — un nombre dans la base de données est affiché tel quel

Présentation uniquement. La valeur stockée ne change jamais — un affichage arrondi reste le nombre complet dans la colonne et dans l’API.

Propriété Type Description
style "decimal" | "currency" | "percent" Vaut "decimal" par défaut. "currency" requiert currency
currency string Code ISO 4217 — "EUR", "USD". Le définir implique style: "currency", le cas courant se résume donc à une seule clé
locale string Tag BCP 47. Par défaut, la locale du panneau, ce qui permet au même montant de s’afficher sous la forme 1,234.50 pour un lecteur et 1.234,50 pour un autre
minimumFractionDigits number Complète avec au moins ce nombre de décimales — 2 affiche 5 sous la forme 5.00
maximumFractionDigits number Arrondit à au plus ce nombre de décimales. Ne modifie pas la valeur stockée
notation "standard" | "compact" "compact" affiche 12000 sous la forme 12K. Pratique dans une colonne de tableau étroite
active: {
type: "boolean",
name: "Selectable",
defaultValue: true
}

Les booléens s’affichent sous forme d’interrupteur à bascule (switch).

Définissez mode: "date" pour afficher un sélecteur de date sans l’heure.

event_date: {
type: "date",
name: "Expiry date",
mode: "date"
}

Le mode par défaut "date_time" inclut à la fois la date et l’heure.

arrival_time: {
type: "date",
name: "Arrival time",
mode: "date_time"
}

Utilisez autoValue pour définir automatiquement des horodatages lors de la création ou de la mise à jour.

createdAt: {
type: "date",
name: "Created At",
autoValue: "on_create",
admin: { readOnly: true }
}
updatedAt: {
type: "date",
name: "Updated At",
autoValue: "on_update"
}

on_update est un déclencheur (trigger) de base de données, pas seulement une empreinte au niveau de la couche applicative. Rebase écrit la colonne à chaque sauvegarde qu’il effectue — ainsi un hook beforeSave voit la nouvelle valeur — et installe un déclencheur BEFORE UPDATE qui l’écrit pour toutes les autres opérations. Sans ce déclencheur, un script de seed, un rétro-remplissage de migration ou une ligne modifiée dans psql laisserait la colonne prétendre que la ligne n’a pas changé, et tout processus la lisant pour décider quoi réindexer ou renvoyer ignorerait cette ligne.

Le déclencheur est généré dans .rebase/sql/triggers.sql, appliqué par rebase db push et au démarrage par la vérification du schéma — Atlas ne peut pas le gérer, pour la même raison qu’il ne peut pas gérer les utilitaires de recherche textuelle intégrale (full-text search).

Propriété Type Description
mode "date" | "date_time" Date uniquement ou date + heure (par défaut : "date_time"). Choisit le widget ; la colonne reste identique dans les deux cas. Formulaire d’administration uniquement — non appliqué par l’API ou la base de données.
autoValue "on_create" | "on_update" Définit automatiquement les horodatages. on_create est un DEFAULT now() ; on_update est un déclencheur BEFORE UPDATE **ainsi qu’**une empreinte au niveau applicatif, de sorte qu’un UPDATE direct issu d’un seed ou d’une migration met également à jour la colonne
columnType "timestamp" | "date" | "time" La colonne de base de données. Vaut par défaut timestamp avec fuseau horaire. Une colonne date est choisie et affichée comme un jour, quel que soit mode ; une colonne time comme une heure de la journée seule, en UTC, sans jour (elle circule sous la forme de cette heure au 1970-01-01)
timezone string Fuseau horaire dans lequel le sélecteur lit et écrit la valeur. Formulaire d’administration uniquement — non appliqué par l’API ou la base de données.
admin.clearable boolean Ajoute une icône pour effacer la valeur (définir sur null)

Propriétés de tableau et d’objet (Array et Map)

Section intitulée « Propriétés de tableau et d’objet (Array et Map) »

Les deux types composites — une liste répétable et un objet structuré, tous deux stockés sous forme de JSONB sauf si un tableau natif Postgres convient. Les éléments répétés, éditeurs de blocs, groupes, éditeurs clé-valeur et toutes les options associées sont décrits dans Tableaux et objets.

Une paire latitude/longitude, stockée en jsonb — { latitude, longitude }, ce que décrivent le type TypeScript généré, le schéma OpenAPI et le champ de formulaire.

location: {
type: "geopoint",
name: "Location"
}

Les écritures acceptent le même format, ou un GeoPoint de @rebasepro/types : new GeoPoint(41.4036, 2.1744).

Il n’y a pas d’autres options que celles partagées par toutes les propriétés. La colonne n’est pas indexée spatialement et il n’y a pas d’opérateur de distance pour filtrer : un geopoint est une valeur que vous stockez et affichez, pas une valeur selon laquelle vous effectuez des recherches. Pour cela, modélisez les deux nombres dans leurs propres colonnes.

Les références créent des liens vers des entités d’une autre collection. Elles s’affichent sous forme de carte d’aperçu montrant les détails de l’entité référencée.

client: {
type: "reference",
name: "Related client",
path: "clients",
admin: {
previewProperties: ["first_name", "last_name", "email"]
}
}

Sur Postgres, une reference est une clé étrangère comme une autre, elle suit donc la même règle ON DELETE qu’une relation belongsTo : optionnelle équivaut à SET NULL, requise équivaut à RESTRICT. Voir Relations.

Ces options s’appliquent à la fois aux propriétés reference et relation.

Propriété Type Description
admin.fixedFilter FilterValues Filtre les entités proposées dans le widget de sélection
admin.widget "select" | "dialog" Quel widget permet de sélectionner l’entité liée (relations uniquement)
admin.includeId boolean Affiche l’identifiant de l’entité liée dans les aperçus (par défaut : true)
admin.includeEntityLink boolean Affiche un lien ouvrant l’entité liée (par défaut : true)
admin.previewProperties string[] Quelles propriétés de la cible apparaissent dans l’aperçu (max 3)
admin.renderInForm boolean Affiche une relation de type many sous la forme d’un sélecteur dans le formulaire en plus de l’onglet qu’elle possède déjà. Vaut false par défaut : la vue de l’entité répertorie déjà les lignes liées dans un onglet, les deux surfaces sont donc redondantes par définition. Sans effet sur une relation to-one, qui ne dispose pas d’onglet

Une colonne d’embedding, pour la recherche des plus proches voisins. Postgres uniquement.

embedding: {
type: "vector",
name: "Embedding",
dimensions: 1536
}
Propriété Type Description
dimensions number Requis. Longueur du vecteur. Se compile en VECTOR(n).
index VectorIndexConfig | false Comment l’index ANN est construit. Si omis, un index HNSW pour la distance cosinus. false n’en crée aucun.

Un index ANN est créé avec la colonne, de sorte que vectorSearch est approximatif et rapide plutôt qu’un scan exact. Il est configuré pour la distance cosinus, qui est la mesure par défaut de vectorSearch à moins que vous ne transmettiez distance — un index ne prend en charge qu’un seul opérateur, donc une requête l2 sur un index cosinus bascule silencieusement sur un scan séquentiel. method (hnsw ou ivfflat), distance (un ou plusieurs), m, efConstruction et lists sont tous configurables sur index. Au-delà de 2000 dimensions, pgvector ne peut construire aucun des deux types d’index, la colonne est donc laissée sans index et le démarrage l’indique.

Interrogez-le avec .vectorSearch(), qui couvre également les prérequis d’installation de pgvector et la façon d’optimiser l’index. Pour les index btree, GIN et BRIN standards sur n’importe quelle collection, consultez Index.

Octets bruts, stockés sous forme de bytea. Les valeurs transitent par l’API sous forme de chaînes base64 — y compris defaultValue.

signature: {
type: "binary",
name: "Signature"
}

Les fichiers volumineux ont leur place dans le stockage, pas dans une colonne : un bytea est lu et écrit intégralement avec la ligne.

Les valeurs d’énumération, les règles de validation et les champs conditionnels disposent de leur propre page : Validation et conditions.