Passer au contenu principal
Les objets personnalisés sont de nouveaux types d’enregistrements que votre application ajoute à un espace de travail — carte postale, facture, abonnement, tout ce qui est spécifique à votre domaine. Chaque objet déclare son schéma (champs, relations, valeurs par défaut) et un identifiant universel stable qui survit aux synchronisations et aux déploiements.
src/objects/post-card.object.ts
import { defineObject, FieldType } from 'twenty-sdk/define';

enum PostCardStatus {
  DRAFT = 'DRAFT',
  SENT = 'SENT',
  DELIVERED = 'DELIVERED',
  RETURNED = 'RETURNED',
}

export default defineObject({
  universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
  nameSingular: 'postCard',
  namePlural: 'postCards',
  labelSingular: 'Post Card',
  labelPlural: 'Post Cards',
  description: 'A post card object',
  icon: 'IconMail',
  fields: [
    {
      universalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b',
      name: 'content',
      type: FieldType.TEXT,
      label: 'Content',
      description: "Postcard's content",
      icon: 'IconAbc',
    },
    {
      universalIdentifier: 'c6aa31f3-da76-4ac6-889f-475e226009ac',
      name: 'recipientName',
      type: FieldType.FULL_NAME,
      label: 'Recipient name',
      icon: 'IconUser',
    },
    {
      universalIdentifier: '95045777-a0ad-49ec-98f9-22f9fc0c8266',
      name: 'recipientAddress',
      type: FieldType.ADDRESS,
      label: 'Recipient address',
      icon: 'IconHome',
    },
    {
      universalIdentifier: '87b675b8-dd8c-4448-b4ca-20e5a2234a1e',
      name: 'status',
      type: FieldType.SELECT,
      label: 'Status',
      icon: 'IconSend',
      defaultValue: `'${PostCardStatus.DRAFT}'`,
      options: [
        { value: PostCardStatus.DRAFT, label: 'Draft', position: 0, color: 'gray' },
        { value: PostCardStatus.SENT, label: 'Sent', position: 1, color: 'orange' },
        { value: PostCardStatus.DELIVERED, label: 'Delivered', position: 2, color: 'green' },
        { value: PostCardStatus.RETURNED, label: 'Returned', position: 3, color: 'orange' },
      ],
    },
    {
      universalIdentifier: 'e06abe72-5b44-4e7f-93be-afc185a3c433',
      name: 'deliveredAt',
      type: FieldType.DATE_TIME,
      label: 'Delivered at',
      icon: 'IconCheck',
      isNullable: true,
      defaultValue: null,
    },
  ],
});

Points clés

  • Le universalIdentifier doit être unique et stable entre les déploiements.
  • Chaque champ nécessite un name, un type, un label et son propre universalIdentifier stable.
  • Le tableau fields est facultatif — vous pouvez définir des objets sans champs personnalisés.
  • Les champs en ligne définis ici n’ont pas besoin d’un objectUniversalIdentifier — il est hérité de l’objet parent. Utilisez defineField() pour ajouter des champs aux objets que vous ne possédez pas.
  • Vous pouvez générer de nouveaux objets avec yarn twenty dev:add object, qui vous guide à travers le nommage, les champs et les relations. Voir Architecture → Scaffolding entities.
Les champs de base sont ajoutés automatiquement. Lorsque vous définissez un objet personnalisé, Twenty crée pour vous des champs standard comme id, name, createdAt, updatedAt, createdBy, updatedBy et deletedAt. Vous n’avez pas besoin de les déclarer dans votre tableau fields — uniquement vos champs personnalisés. Vous pouvez remplacer un champ par défaut en en déclarant un avec le même nom, mais c’est rarement une bonne idée.

Valeurs par défaut

Les valeurs par défaut de type chaîne littérale doivent être entourées de guillemets simples à l’intérieur de la chaîne — defaultValue: "'Draft'", et non defaultValue: "Draft". C’est pourquoi le champ status ci-dessus utilise `'${PostCardStatus.DRAFT}'`. Les chaînes sans guillemets sont réservées aux valeurs par défaut calculées, évaluées lors de la création d’un enregistrement :
  • 'uuid' — génère un UUID (pour les champs UUID)
  • 'now' — l’horodatage actuel (pour les champs DATE_TIME)
La même convention s’applique aux sous-champs de type chaîne des valeurs par défaut composites (par exemple { source: "'MANUAL'" } sur un champ ACTOR) ainsi qu’aux valeurs SELECT/MULTI_SELECT. Une valeur par défaut littérale de type chaîne laissée sans guillemets génère un avertissement lors de la compilation de votre application.

Et après

  • Connectez cet objet aux autres — voir Relations pour le modèle de relation bidirectionnelle.
  • Ajoutez des champs aux objets d’autres applications — voir Extending Objects pour defineField().
  • Affichez cet objet dans l’interface utilisateur — voir Views et Navigation Menu Items pour l’ajouter à la barre latérale.