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: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):
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
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
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: