twenty-sdk package provides defineEntity functions to declare your app’s data model. Devi usare export default defineEntity({...}) affinché l’SDK rilevi le tue entità. Queste funzioni convalidano la configurazione in fase di build e offrono il completamento automatico nell’IDE e la sicurezza dei tipi.
L’organizzazione dei file dipende da te.
Il rilevamento delle entità è basato sull’AST — l’SDK trova le chiamate a
export default defineEntity(...) indipendentemente da dove si trova il file. Raggruppare i file per tipo (ad es., logic-functions/, roles/) è solo una convenzione, non un requisito.defineRole
Configura i permessi dei ruoli e l'accesso agli oggetti
defineRole
Configura i permessi dei ruoli e l'accesso agli oggetti
I ruoli incapsulano i permessi sugli oggetti e sulle azioni del tuo spazio di lavoro.
restricted-company-role.ts
defineApplication
Configura i metadati dell'applicazione (obbligatorio, uno per app)
defineApplication
Configura i metadati dell'applicazione (obbligatorio, uno per app)
Ogni app deve avere esattamente una chiamata a Note:
L’
defineApplication che descrive:- Identità: identificatori, nome visualizzato e descrizione.
- Autorizzazioni: quale ruolo usano le sue funzioni e i componenti front-end.
- Variabili (opzionali): coppie chiave–valore esposte alle funzioni come variabili d’ambiente.
- (Opzionali) Funzioni di pre-installazione/post-installazione: funzioni logiche che vengono eseguite prima o dopo l’installazione.
src/application-config.ts
- I campi
universalIdentifiersono ID deterministici che possiedi. Generali una volta e mantienili stabili tra una sincronizzazione e l’altra. applicationVariablesdiventano variabili d’ambiente per le tue funzioni e i componenti front-end (ad esempio,DEFAULT_RECIPIENT_NAMEè disponibile comeprocess.env.DEFAULT_RECIPIENT_NAME).defaultRoleUniversalIdentifierdeve fare riferimento a un ruolo definito condefineRole()(vedi sopra).- Le funzioni di pre-installazione e post-installazione vengono rilevate automaticamente durante il build del manifesto — non è necessario farvi riferimento in
defineApplication().
Metadati del marketplace
Se prevedi di pubblicare la tua app, questi campi opzionali controllano come appare nel marketplace:| Campo | Descrizione |
|---|---|
author | Nome dell’autore o dell’azienda |
category | Categoria dell’app per il filtraggio nel marketplace |
logoUrl | Percorso al logo della tua app (ad es., public/logo.png) |
screenshots | Array di percorsi degli screenshot (ad es., public/screenshot-1.png) |
aboutDescription | Descrizione markdown più lunga per la scheda “Informazioni”. Se omesso, il marketplace utilizza il README.md del pacchetto da npm |
websiteUrl | Link al tuo sito web |
termsUrl | Link ai Termini di servizio |
emailSupport | Indirizzo email di supporto |
issueReportUrl | Link al sistema di tracciamento dei problemi |
Ruoli e permessi
IldefaultRoleUniversalIdentifier in application-config.ts indica il ruolo predefinito utilizzato dalle funzioni logiche e dai componenti front-end della tua app. Vedi defineRole sopra per i dettagli.- Il token di runtime iniettato come
TWENTY_APP_ACCESS_TOKENè derivato da questo ruolo. - Il client tipizzato è limitato ai permessi concessi a quel ruolo.
- Segui il principio del privilegio minimo: crea un ruolo dedicato con solo i permessi necessari alle tue funzioni.
Ruolo funzione predefinito
Quando esegui lo scaffolding di una nuova app, la CLI crea un file di ruolo predefinito:src/roles/default-role.ts
universalIdentifier di questo ruolo viene referenziato in application-config.ts come defaultRoleUniversalIdentifier:- *.role.ts definisce ciò che il ruolo può fare.
- application-config.ts punta a quel ruolo in modo che le tue funzioni ne ereditino i permessi.
- Parti dal ruolo generato dallo scaffolder, quindi restringilo progressivamente seguendo il principio del privilegio minimo.
- Sostituisci
objectPermissionsefieldPermissionscon gli oggetti e i campi di cui le tue funzioni hanno realmente bisogno. permissionFlagscontrollano l’accesso alle funzionalità a livello di piattaforma. Mantienili al minimo.- Vedi un esempio funzionante:
hello-world/src/roles/function-role.ts.
defineObject
Definisci oggetti personalizzati con campi
defineObject
Definisci oggetti personalizzati con campi
Gli oggetti personalizzati descrivono sia lo schema sia il comportamento per i record nel tuo spazio di lavoro. Usa Punti chiave:
defineObject() per definire oggetti con convalida integrata:postCard.object.ts
- Usa
defineObject()per una convalida integrata e un migliore supporto IDE. - Il
universalIdentifierdeve essere univoco e stabile tra i deployment. - Ogni campo richiede un
name,type,labele il propriouniversalIdentifierstabile. - L’array
fieldsè facoltativo: puoi definire oggetti senza campi personalizzati. - Puoi generare nuovi oggetti con
yarn twenty add, che ti guida nella denominazione, nei campi e nelle relazioni.
I campi base vengono creati automaticamente. Quando definisci un oggetto personalizzato, Twenty aggiunge automaticamente i campi standard
come
id, name, createdAt, updatedAt, createdBy, updatedBy e deletedAt.
Non è necessario definirli nel tuo array fields — aggiungi solo i tuoi campi personalizzati.
Puoi sovrascrivere i campi predefiniti definendo un campo con lo stesso nome nel tuo array fields,
ma non è consigliato.defineField — Campi standard
Estendi gli oggetti esistenti con campi aggiuntivi
defineField — Campi standard
Estendi gli oggetti esistenti con campi aggiuntivi
Usa Punti chiave:
defineField() per aggiungere campi a oggetti che non possiedi — come gli oggetti standard di Twenty (Person, Company, ecc.) o oggetti di altre app. A differenza dei campi inline in defineObject(), i campi autonomi richiedono un objectUniversalIdentifier per specificare quale oggetto estendono:src/fields/company-loyalty-tier.field.ts
objectUniversalIdentifieridentifica l’oggetto di destinazione. Per gli oggetti standard, usaSTANDARD_OBJECT_UNIVERSAL_IDENTIFIERSesportati datwenty-sdk.- Quando definisci campi inline in
defineObject(), non hai bisogno diobjectUniversalIdentifier— viene ereditato dall’oggetto padre. defineField()è l’unico modo per aggiungere campi a oggetti che non hai creato condefineObject().
defineField — Campi di relazione
Collega gli oggetti tra loro con relazioni bidirezionali
defineField — Campi di relazione
Collega gli oggetti tra loro con relazioni bidirezionali
Le relazioni collegano gli oggetti tra loro. In Twenty, le relazioni sono sempre bidirezionali — definisci entrambi i lati e ciascun lato fa riferimento all’altro.Esistono due tipi di relazione:
Passaggio 2: definisci il lato MANY_TO_ONE su PostCardRecipient (il lato “molti” — contiene la chiave esterna):
| Tipo di relazione | Descrizione | Ha una chiave esterna? |
|---|---|---|
MANY_TO_ONE | Molti record di questo oggetto puntano a un record della destinazione | Sì (joinColumnName) |
ONE_TO_MANY | Un record di questo oggetto ha molti record della destinazione | No (lato inverso) |
Come funzionano le relazioni
Ogni relazione richiede due campi che fanno riferimento l’uno all’altro:- Il lato MANY_TO_ONE — risiede sull’oggetto che detiene la chiave esterna
- Il lato ONE_TO_MANY — risiede sull’oggetto che possiede la collezione
FieldType.RELATION e si riferiscono reciprocamente tramite relationTargetFieldMetadataUniversalIdentifier.Esempio: Post Card ha molti destinatari
Supponiamo che unPostCard possa essere inviato a molti record PostCardRecipient. Ogni destinatario appartiene esattamente a una sola cartolina.Passaggio 1: definisci il lato ONE_TO_MANY su PostCard (il lato “uno”):src/fields/post-card-recipients-on-post-card.field.ts
src/fields/post-card-on-post-card-recipient.field.ts
Importazioni circolari: Entrambi i campi di relazione fanno riferimento all’
universalIdentifier dell’altro. Per evitare problemi di importazioni circolari, esporta gli ID dei campi come costanti denominate da ciascun file e importale nell’altro file. Il sistema di build le risolve in fase di compilazione.Relazioni con gli oggetti standard
Per creare una relazione con un oggetto Twenty integrato (Person, Company, ecc.), usaSTANDARD_OBJECT_UNIVERSAL_IDENTIFIERS:src/fields/person-on-self-hosting-user.field.ts
Proprietà dei campi di relazione
| Proprietà | Obbligatorio | Descrizione |
|---|---|---|
tipo | Sì | Deve essere FieldType.RELATION |
relationTargetObjectMetadataUniversalIdentifier | Sì | L’universalIdentifier dell’oggetto di destinazione |
relationTargetFieldMetadataUniversalIdentifier | Sì | L’universalIdentifier del campo corrispondente sull’oggetto di destinazione |
universalSettings.relationType | Sì | RelationType.MANY_TO_ONE o RelationType.ONE_TO_MANY |
universalSettings.onDelete | Solo MANY_TO_ONE | Cosa accade quando il record referenziato viene eliminato: CASCADE, SET_NULL, RESTRICT o NO_ACTION |
universalSettings.joinColumnName | Solo MANY_TO_ONE | Nome della colonna del database per la chiave esterna (ad es., postCardId) |
Campi di relazione inline in defineObject
Puoi anche definire i campi di relazione direttamente all’interno didefineObject(). In tal caso, ometti objectUniversalIdentifier — viene ereditato dall’oggetto padre:Creazione di entità con lo scaffolding tramite yarn twenty add
Invece di creare manualmente i file delle entità, puoi usare lo scaffolder interattivo:
universalIdentifier stabile e la corretta chiamata a defineEntity().
Puoi anche passare direttamente il tipo di entità per saltare il primo prompt:
Tipi di entità disponibili
| Tipo di entità | Comando | File generato |
|---|---|---|
| Oggetto | yarn twenty add object | src/objects/\<name>.ts |
| Campo | yarn twenty add field | src/fields/\<name>.ts |
| Funzione logica | yarn twenty add logicFunction | src/logic-functions/\<name>.ts |
| Componente front-end | yarn twenty add frontComponent | src/front-components/\<name>.tsx |
| Ruolo | yarn twenty add role | src/roles/\<name>.ts |
| Abilità | yarn twenty add skill | src/skills/\<name>.ts |
| Agente | yarn twenty add agent | src/agents/\<name>.ts |
| Vista | yarn twenty add view | src/views/\<name>.ts |
| Voce del menu di navigazione | yarn twenty add navigationMenuItem | src/navigation-menu-items/\<name>.ts |
| Layout di pagina | yarn twenty add pageLayout | src/page-layouts/\<name>.ts |
Cosa genera lo scaffolder
Ogni tipo di entità ha il proprio template. Ad esempio,yarn twenty add object richiede:
- Nome (singolare) — ad es.,
invoice - Nome (plurale) — ad es.,
invoices - Etichetta (singolare) — compilata automaticamente dal nome (ad es.,
Invoice) - Etichetta (plurale) — compilata automaticamente (ad es.,
Invoices) - Creare una vista e una voce di navigazione? — se rispondi sì, lo scaffolder genera anche una vista corrispondente e un link nella barra laterale per il nuovo oggetto.
field è più dettagliato: chiede il nome del campo, l’etichetta, il tipo (da un elenco di tutti i tipi di campo disponibili come TEXT, NUMBER, SELECT, RELATION, ecc.) e l’universalIdentifier dell’oggetto di destinazione.
Percorso di output personalizzato
Usa il flag--path per posizionare il file generato in una posizione personalizzata: