Saltar al contenido principal
Los objetos personalizados son nuevos tipos de registro que tu aplicación añade a un espacio de trabajo — Tarjeta postal, Factura, Suscripción, cualquier cosa específica de tu dominio. Cada objeto declara su esquema (campos, relaciones, valores predeterminados) y un identificador universal estable que se mantiene a través de sincronizaciones e implementaciones.
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,
    },
  ],
});

Puntos clave

  • El universalIdentifier debe ser único y estable entre implementaciones.
  • Cada campo requiere name, type, label y su propio universalIdentifier estable.
  • La matriz fields es opcional: puedes definir objetos sin campos personalizados.
  • Los campos en línea definidos aquí no necesitan un objectUniversalIdentifier, ya que se hereda del objeto padre. Usa defineField() para añadir campos a objetos que no te pertenecen.
  • Puedes generar nuevos objetos con yarn twenty dev:add object, que te guía en la asignación de nombres, los campos y las relaciones. Consulta Arquitectura → Generación de entidades.
Los campos base se añaden automáticamente. Cuando defines un objeto personalizado, Twenty crea campos estándar como id, name, createdAt, updatedAt, createdBy, updatedBy y deletedAt por ti. No necesitas declararlos en tu matriz fields, solo tus campos personalizados. Puedes sobrescribir un campo predeterminado declarando uno con el mismo nombre, pero esto rara vez es una buena idea.

Valores predeterminados

Los valores predeterminados de cadenas literales deben ir entre comillas simples dentro de la cadena — defaultValue: "'Draft'", no defaultValue: "Draft". Por eso el campo status anterior utiliza `'${PostCardStatus.DRAFT}'`. Las cadenas sin comillas se reservan para valores predeterminados calculados, evaluados cuando se crea un registro:
  • 'uuid' — genera un UUID (para campos UUID)
  • 'now' — la marca de tiempo actual (para campos DATE_TIME)
La misma convención se aplica a los subcampos de tipo cadena de los valores predeterminados compuestos (por ejemplo, { source: "'MANUAL'" } en un campo ACTOR) y a los valores de SELECT/MULTI_SELECT. Un valor predeterminado de tipo cadena literal dejado sin comillas genera una advertencia cuando se compila tu aplicación.

¿Qué sigue?