Salt la conținutul principal
Stratul de date al unei aplicații Twenty reprezintă datele pe care aplicația le adaugă într-un spațiu de lucru — noile tipuri de înregistrări pe care le declară, coloanele pe care le adaugă la obiectele existente și modul în care aceste înregistrări se conectează între ele.
┌──────────────────────────────────────────────────┐
│ Object — a record type, e.g. PostCard            │
│    ├─ Field     (name, type, label)              │
│    ├─ Field                                      │
│    └─ Relation  (link to another object)         │
└──────────────────────────────────────────────────┘

            ├── lives in your app, OR


┌──────────────────────────────────────────────────┐
│ Standard / other apps' objects                   │
│    └─ Field added by your app via defineField    │
└──────────────────────────────────────────────────┘

În această secțiune

Obiecte

defineObject — declarați noi tipuri de înregistrări cu propriile lor câmpuri.

Extinderea obiectelor

defineField — adăugați câmpuri la obiecte standard sau la obiectele altor aplicații.

Relații

Conexiuni bidirecționale MANY_TO_ONE / ONE_TO_MANY între obiecte.

Entități dintr-o privire

EntitateScopDefinit cu
ObiectUn nou tip de înregistrare personalizat (de ex. PostCard, Invoice) cu propriile sale câmpuridefineObject()
CâmpO coloană pe un obiect. Câmpurile independente pot extinde obiecte pe care nu le-ați creat (de ex. adăugați loyaltyTier la Company)defineField()
RelațieO legătură bidirecțională între două obiecte — ambele părți declarate ca câmpuridefineField() cu FieldType.RELATION
IndiceUn indice de bază de date pentru a accelera o interogare recurentă asupra unuia dintre obiectele taledefineIndex()
SDK-ul detectează acestea prin analiza AST la momentul build-ului, astfel încât organizarea fișierelor ține de tine — convenția este src/objects/, src/fields/ și src/indexes/. UUID-urile stabile universalIdentifier leagă totul în toate implementările.

Indici (opțional)

Aplicațiile pot livra indici împreună cu obiectele lor pentru a menține rapide interogările recurente. Cel mai comun caz este o coloană de status sau o coloană cu cheie străină pe care o citești frecvent.
src/indexes/post-card-status.index.ts
import { defineIndex } from 'twenty-sdk/define';

import {
  POST_CARD_UNIVERSAL_IDENTIFIER,
  STATUS_FIELD_UNIVERSAL_IDENTIFIER,
} from '../objects/post-card.object';

export default defineIndex({
  universalIdentifier: 'b6e9d2a1-5a4c-46ca-9d52-42c8f02d1ff0',
  objectUniversalIdentifier: POST_CARD_UNIVERSAL_IDENTIFIER,
  fields: [
    {
      universalIdentifier: 'b6e9d2a1-5a4c-46ca-9d52-42c8f02d1ff1',
      fieldUniversalIdentifier: STATUS_FIELD_UNIVERSAL_IDENTIFIER,
    },
  ],
});

Indici unici

defineIndex acceptă isUnique: true atât pentru unicitatea pe o singură coloană, cât și pe mai multe coloane. Aceasta este primitiva recomandată — defineField({ isUnique: true }) este învechită (deprecated) și va fi eliminată într-o versiune viitoare.
defineIndex({
  universalIdentifier: '…',
  objectUniversalIdentifier: PERSON_UNIVERSAL_IDENTIFIER,
  isUnique: true,
  fields: [{ universalIdentifier: '…', fieldUniversalIdentifier: EMAIL_FIELD_UNIVERSAL_IDENTIFIER }],
});

Alte constrângeri

  • Clauzele WHERE parțiale rămân sub controlul administratorului — aplicațiile nu le pot declara.
  • Fiecare obiect este limitat la 10 indici personalizați (indicii proprii ai framework-ului nu se pun la socoteală).
Ordonează array-ul fields în modul în care Postgres ar trebui să îl folosească — coloana din stânga prima, ca într-o agendă telefonică. Indicii nu sunt gratuiți: fiecare scriere în tabel îi actualizează. Adaugă unul doar atunci când ai o interogare care are nevoie de el.
Căutați Application Config sau Roles & Permissions? Acestea descriu aplicația în sine, mai degrabă decât datele pe care le adaugă — se află la Config. Căutați Connections (Linear, GitHub, Slack OAuth)? Acestea există pentru a fi apelate din funcții de logică și se află la Logic.