twenty-sdk package provides defineEntity functions to declare your app’s data model. Sie müssen export default defineEntity({...}) verwenden, damit das SDK Ihre Entitäten erkennt. Diese Funktionen validieren Ihre Konfiguration zur Build-Zeit und bieten IDE-Autovervollständigung sowie Typsicherheit.
Die Dateiorganisation liegt bei Ihnen.
Die Entitätserkennung ist AST-basiert — das SDK findet Aufrufe von
export default defineEntity(...), unabhängig davon, wo sich die Datei befindet. Das Gruppieren von Dateien nach Typ (z. B. logic-functions/, roles/) ist lediglich eine Konvention, keine Voraussetzung.Rolle definieren
Rollenberechtigungen und Objektzugriff konfigurieren
Rolle definieren
Rollenberechtigungen und Objektzugriff konfigurieren
Rollen kapseln Berechtigungen für die Objekte und Aktionen Ihres Workspaces.
restricted-company-role.ts
Anwendung definieren
Anwendungsmetadaten konfigurieren (erforderlich, eine pro App)
Anwendung definieren
Anwendungsmetadaten konfigurieren (erforderlich, eine pro App)
Jede App muss genau einen Aufruf von Notizen:
Der
defineApplication haben, der Folgendes beschreibt:- Identität: Bezeichner, Anzeigename und Beschreibung.
- Berechtigungen: welche Rolle ihre Funktionen und Frontend-Komponenten verwenden.
- (Optional) Variablen: Schlüssel–Wert-Paare, die Ihren Funktionen als Umgebungsvariablen zur Verfügung gestellt werden.
- (Optional) Pre-/Post-Installationsfunktionen: Logikfunktionen, die vor oder nach der Installation ausgeführt werden.
src/application-config.ts
universalIdentifier-Felder sind deterministische IDs, die Ihnen gehören. Erzeugen Sie sie einmal und halten Sie sie über Synchronisierungen hinweg stabil.applicationVariableswerden zu Umgebungsvariablen für Ihre Funktionen und Frontend-Komponenten (z. B. istDEFAULT_RECIPIENT_NAMEalsprocess.env.DEFAULT_RECIPIENT_NAMEverfügbar).defaultRoleUniversalIdentifiermuss auf eine mitdefineRole()definierte Rolle verweisen (siehe oben).- Pre- und Post-Installationsfunktionen werden während des Manifest-Builds automatisch erkannt — Sie müssen sie in
defineApplication()nicht referenzieren.
Marktplatz-Metadaten
Wenn Sie planen, Ihre App zu veröffentlichen, steuern diese optionalen Felder, wie Ihre App im Marktplatz erscheint:| Feld | Beschreibung |
|---|---|
author | Name des Autors oder des Unternehmens |
category | App-Kategorie für die Filterung im Marktplatz |
logoUrl | Pfad zu Ihrem App-Logo (z. B. public/logo.png) |
screenshots | Array von Screenshot-Pfaden (z. B. public/screenshot-1.png) |
aboutDescription | Längere Markdown-Beschreibung für den Tab “Info”. Wenn weggelassen, verwendet der Marketplace die README.md des Pakets von npm |
websiteUrl | Link zu Ihrer Website |
termsUrl | Link zu den Nutzungsbedingungen |
emailSupport | Support-E-Mail-Adresse |
issueReportUrl | Link zum Issue-Tracker |
Rollen und Berechtigungen
Das FelddefaultRoleUniversalIdentifier in application-config.ts legt die Standardrolle fest, die von den Logikfunktionen und Frontend-Komponenten Ihrer App verwendet wird. Details finden Sie oben unter defineRole.- Das zur Laufzeit als
TWENTY_APP_ACCESS_TOKENinjizierte Token wird aus dieser Rolle abgeleitet. - Der typisierte Client ist auf die dieser Rolle gewährten Berechtigungen beschränkt.
- Befolgen Sie das Least-Privilege-Prinzip: Erstellen Sie eine dedizierte Rolle nur mit den Berechtigungen, die Ihre Funktionen benötigen.
Standard-Funktionsrolle
Wenn Sie eine neue App erzeugen, erstellt die CLI eine Standard-Rolldatei:src/roles/default-role.ts
universalIdentifier dieser Rolle wird in application-config.ts als defaultRoleUniversalIdentifier referenziert:- *.role.ts definiert, was die Rolle darf.
- application-config.ts verweist auf diese Rolle, sodass Ihre Funktionen deren Berechtigungen erben.
- Beginnen Sie mit der vorab erstellten Rolle und schränken Sie sie schrittweise gemäß dem Least-Privilege-Prinzip ein.
- Ersetzen Sie
objectPermissionsundfieldPermissionsdurch die Objekte und Felder, die Ihre Funktionen tatsächlich benötigen. permissionFlagssteuern den Zugriff auf Funktionen auf Plattformebene. Halten Sie sie minimal.- Ein funktionierendes Beispiel finden Sie unter:
hello-world/src/roles/function-role.ts.
Objekt definieren
Benutzerdefinierte Objekte mit Feldern definieren
Objekt definieren
Benutzerdefinierte Objekte mit Feldern definieren
Benutzerdefinierte Objekte beschreiben sowohl Schema als auch Verhalten für Datensätze in Ihrem Workspace. Verwenden Sie Hauptpunkte:
defineObject(), um Objekte mit eingebauter Validierung zu definieren:postCard.object.ts
- Verwenden Sie
defineObject()für eingebaute Validierung und bessere IDE-Unterstützung. - Der
universalIdentifiermuss eindeutig und über Deployments hinweg stabil sein. - Jedes Feld benötigt
name,type,labelund einen eigenen stabilenuniversalIdentifier. - Das Array
fieldsist optional — Sie können Objekte ohne benutzerdefinierte Felder definieren. - Sie können mit
yarn twenty addneue Objekte erzeugen; der Assistent führt Sie durch Benennung, Felder und Beziehungen.
Basisfelder werden automatisch erstellt. Wenn Sie ein benutzerdefiniertes Objekt definieren, fügt Twenty automatisch Standardfelder hinzu
wie
id, name, createdAt, updatedAt, createdBy, updatedBy und deletedAt.
Sie müssen diese nicht in Ihrem fields-Array definieren — fügen Sie nur Ihre benutzerdefinierten Felder hinzu.
Sie können Standardfelder überschreiben, indem Sie in Ihrem fields-Array ein Feld mit demselben Namen definieren,
dies wird jedoch nicht empfohlen.defineField — Standardfelder
Bestehende Objekte mit zusätzlichen Feldern erweitern
defineField — Standardfelder
Bestehende Objekte mit zusätzlichen Feldern erweitern
Verwenden Sie Hauptpunkte:
defineField(), um Objekten, die Ihnen nicht gehören — etwa Standardobjekten von Twenty (Person, Company usw.) — Felder hinzuzufügen oder Objekten aus anderen Apps. Im Gegensatz zu Inline-Feldern in defineObject() benötigen eigenständige Felder einen objectUniversalIdentifier, um anzugeben, welches Objekt sie erweitern:src/fields/company-loyalty-tier.field.ts
- Der
objectUniversalIdentifieridentifiziert das Zielobjekt. Für Standardobjekte verwenden SieSTANDARD_OBJECT_UNIVERSAL_IDENTIFIERS, die austwenty-sdkexportiert werden. - Wenn Sie Felder inline in
defineObject()definieren, benötigen SieobjectUniversalIdentifiernicht — er wird vom übergeordneten Objekt geerbt. defineField()ist die einzige Möglichkeit, Felder zu Objekten hinzuzufügen, die Sie nicht mitdefineObject()erstellt haben.
defineField — Relationsfelder
Objekte mit bidirektionalen Relationen verbinden
defineField — Relationsfelder
Objekte mit bidirektionalen Relationen verbinden
Relationen verbinden Objekte miteinander. In Twenty sind Relationen stets bidirektional — Sie definieren beide Seiten, und jede Seite referenziert die andere.Es gibt zwei Relationstypen:
Schritt 2: Definieren Sie die MANY_TO_ONE-Seite auf PostCardRecipient (die “viele” Seite — hält den Fremdschlüssel):
| Beziehungstyp | Beschreibung | Fremdschlüssel vorhanden? |
|---|---|---|
MANY_TO_ONE | Viele Datensätze dieses Objekts verweisen auf einen Datensatz des Ziels | Ja (joinColumnName) |
ONE_TO_MANY | Ein Datensatz dieses Objekts hat viele Datensätze des Ziels | Nein (inverse Seite) |
Wie Relationen funktionieren
Jede Relation erfordert zwei Felder, die sich gegenseitig referenzieren:- Die MANY_TO_ONE-Seite — befindet sich auf dem Objekt, das den Fremdschlüssel hält
- Die ONE_TO_MANY-Seite — befindet sich auf dem Objekt, dem die Sammlung gehört
FieldType.RELATION und verweisen über relationTargetFieldMetadataUniversalIdentifier gegenseitig aufeinander.Beispiel: Postkarte hat viele Empfänger
Angenommen, einePostCard kann an viele PostCardRecipient-Datensätze gesendet werden. Jeder Empfänger gehört genau zu einer Postkarte.Schritt 1: Definieren Sie die ONE_TO_MANY-Seite auf PostCard (die “eine” Seite):src/fields/post-card-recipients-on-post-card.field.ts
src/fields/post-card-on-post-card-recipient.field.ts
Zyklische Importe: Beide Relationsfelder referenzieren gegenseitig den
universalIdentifier des jeweils anderen. Um Probleme mit zyklischen Importen zu vermeiden, exportieren Sie Ihre Feld-IDs als benannte Konstanten aus jeder Datei und importieren Sie sie in der jeweils anderen Datei. Das Build-System löst dies zur Kompilierzeit auf.Relationen zu Standardobjekten
Um eine Relation mit einem integrierten Twenty-Objekt (Person, Company usw.) zu erstellen, verwenden SieSTANDARD_OBJECT_UNIVERSAL_IDENTIFIERS:src/fields/person-on-self-hosting-user.field.ts
Eigenschaften von Relationsfeldern
| Eigenschaft | Erforderlich | Beschreibung |
|---|---|---|
type | Ja | Muss FieldType.RELATION sein |
relationTargetObjectMetadataUniversalIdentifier | Ja | Der universalIdentifier des Zielobjekts |
relationTargetFieldMetadataUniversalIdentifier | Ja | Der universalIdentifier des entsprechenden Felds auf dem Zielobjekt |
universalSettings.relationType | Ja | RelationType.MANY_TO_ONE oder RelationType.ONE_TO_MANY |
universalSettings.onDelete | Nur für MANY_TO_ONE | Was passiert, wenn der referenzierte Datensatz gelöscht wird: CASCADE, SET_NULL, RESTRICT oder NO_ACTION |
universalSettings.joinColumnName | Nur für MANY_TO_ONE | Datenbankspaltenname für den Fremdschlüssel (z. B. postCardId) |
Inline-Relationsfelder in defineObject
Sie können Relationsfelder auch direkt innerhalb vondefineObject() definieren. In diesem Fall lassen Sie objectUniversalIdentifier weg — er wird vom übergeordneten Objekt geerbt:Entitäten mit yarn twenty add erstellen
Anstatt Entitätsdateien manuell zu erstellen, können Sie den interaktiven Scaffolder verwenden:
universalIdentifier und dem korrekten defineEntity()-Aufruf.
Sie können den Entitätstyp auch direkt übergeben, um die erste Eingabeaufforderung zu überspringen:
Verfügbare Entitätstypen
| Entitätstyp | Befehl | Generierte Datei |
|---|---|---|
| Objekt | yarn twenty add object | src/objects/\<name>.ts |
| Feld | yarn twenty add field | src/fields/\<name>.ts |
| Logikfunktion | yarn twenty add logicFunction | src/logic-functions/\<name>.ts |
| Frontend-Komponente | yarn twenty add frontComponent | src/front-components/\<name>.tsx |
| Rolle | yarn twenty add role | src/roles/\<name>.ts |
| Skill | yarn twenty add skill | src/skills/\<name>.ts |
| Agent | yarn twenty add agent | src/agents/\<name>.ts |
| Ansicht | yarn twenty add view | src/views/\<name>.ts |
| Navigationsmenüeintrag | yarn twenty add navigationMenuItem | src/navigation-menu-items/\<name>.ts |
| Seitenlayout | yarn twenty add pageLayout | src/page-layouts/\<name>.ts |
Was der Scaffolder generiert
Jeder Entitätstyp hat seine eigene Vorlage. Zum Beispiel fragtyarn twenty add object nach:
- Name (Singular) — z. B.
invoice - Name (Plural) — z. B.
invoices - Label (Singular) — automatisch aus dem Namen befüllt (z. B.
Invoice) - Label (Plural) — automatisch befüllt (z. B.
Invoices) - Ansicht und Navigationseintrag erstellen? — wenn Sie mit Ja antworten, erzeugt der Scaffolder außerdem eine passende Ansicht und einen Sidebar-Link für das neue Objekt.
field ist detaillierter: Er fragt nach Feldname, Label, Typ (aus einer Liste aller verfügbaren Feldtypen wie TEXT, NUMBER, SELECT, RELATION usw.) sowie dem universalIdentifier des Zielobjekts.
Benutzerdefinierter Ausgabepfad
Verwenden Sie den Schalter--path, um die generierte Datei an einem benutzerdefinierten Ort abzulegen: