twenty-sdk package provides defineEntity functions to declare your app’s data model. Você deve usar export default defineEntity({...}) para que o SDK detecte suas entidades. Essas funções validam sua configuração em tempo de compilação e oferecem autocompletar na IDE e segurança de tipos.
A organização de arquivos fica a seu critério.
A detecção de entidades é baseada em AST — o SDK encontra chamadas a
export default defineEntity(...) independentemente de onde o arquivo esteja. Agrupar arquivos por tipo (por exemplo, logic-functions/, roles/) é apenas uma convenção, não um requisito.defineRole
Configurar permissões de papéis e acesso a objetos
defineRole
Configurar permissões de papéis e acesso a objetos
Papéis encapsulam permissões sobre os objetos e ações do seu espaço de trabalho.
restricted-company-role.ts
defineApplication
Configurar metadados do aplicativo (obrigatório, um por app)
defineApplication
Configurar metadados do aplicativo (obrigatório, um por app)
Todo app deve ter exatamente uma chamada a Notas:O
defineApplication que descreve:- Identidade: identificadores, nome de exibição e descrição.
- Permissões: qual papel é usado por suas funções e componentes de front-end.
- Variáveis (opcional): pares chave–valor expostos às suas funções como variáveis de ambiente.
- (Opcional) Funções de pré-instalação/pós-instalação: funções de lógica que são executadas antes ou depois da instalação.
src/application-config.ts
- Os campos
universalIdentifiersão IDs determinísticos que você controla. Gere-os uma vez e mantenha-os estáveis entre sincronizações. applicationVariablestornam-se variáveis de ambiente para suas funções e componentes de front-end (por exemplo,DEFAULT_RECIPIENT_NAMEfica disponível comoprocess.env.DEFAULT_RECIPIENT_NAME).defaultRoleUniversalIdentifierdeve fazer referência a um papel definido comdefineRole()(veja acima).- As funções de pré-instalação e pós-instalação são detectadas automaticamente durante a construção do manifesto — você não precisa referenciá-las em
defineApplication().
Metadados do Marketplace
Se você planeja publicar seu app, estes campos opcionais controlam como seu app aparece no marketplace:Papéis e permissões
O campodefaultRoleUniversalIdentifier em application-config.ts designa o papel padrão usado pelas funções de lógica e pelos componentes de front-end do seu app. Veja defineRole acima para detalhes.- O token em tempo de execução injetado como
TWENTY_APP_ACCESS_TOKENé derivado desse papel. - O cliente tipado é restrito às permissões concedidas a esse papel.
- Siga o princípio do menor privilégio: crie um papel dedicado com apenas as permissões de que suas funções precisam.
Papel de função padrão
Ao criar um novo app com o scaffold, a CLI cria um arquivo de papel padrão:src/roles/default-role.ts
universalIdentifier desse papel é referenciado em application-config.ts como defaultRoleUniversalIdentifier:- *.role.ts define o que o papel pode fazer.
- application-config.ts aponta para esse papel para que suas funções herdem suas permissões.
- Comece pelo papel gerado pelo scaffold e depois restrinja-o progressivamente seguindo o princípio do menor privilégio.
- Substitua
objectPermissionsefieldPermissionspelos objetos e campos de que suas funções realmente precisam. permissionFlagscontrolam o acesso a recursos em nível de plataforma. Mantenha-os no mínimo necessário.- Veja um exemplo funcional:
hello-world/src/roles/function-role.ts.
defineObject
Define objetos personalizados com campos
defineObject
Define objetos personalizados com campos
Objetos personalizados descrevem tanto o esquema quanto o comportamento de registros no seu espaço de trabalho. Use Pontos-chave:
defineObject() para definir objetos com validação integrada:postCard.object.ts
- Use
defineObject()para validação integrada e melhor suporte na IDE. - O
universalIdentifierdeve ser exclusivo e estável entre implantações. - Cada campo requer
name,type,labele seu própriouniversalIdentifierestável. - O array
fieldsé opcional — você pode definir objetos sem campos personalizados. - Você pode criar novos objetos usando
yarn twenty add, que orienta você sobre nomeação, campos e relacionamentos.
Os campos base são criados automaticamente. Quando você define um objeto personalizado, o Twenty adiciona automaticamente campos padrão
como
id, name, createdAt, updatedAt, createdBy, updatedBy e deletedAt.
Você não precisa definir esses no seu array fields — adicione apenas seus campos personalizados.
Você pode substituir os campos padrão definindo um campo com o mesmo nome no seu array fields,
mas isso não é recomendado.defineField — Campos padrão
Estender objetos existentes com campos adicionais
defineField — Campos padrão
Estender objetos existentes com campos adicionais
Use Pontos-chave:
defineField() para adicionar campos a objetos que não são seus — como objetos padrão do Twenty (Person, Company, etc.). ou a objetos de outros apps. Ao contrário dos campos inline em defineObject(), os campos independentes exigem um objectUniversalIdentifier para especificar qual objeto eles estendem:src/fields/company-loyalty-tier.field.ts
objectUniversalIdentifieridentifica o objeto de destino. Para objetos padrão, useSTANDARD_OBJECT_UNIVERSAL_IDENTIFIERSexportado detwenty-sdk.- Ao definir campos inline em
defineObject(), você não precisa deobjectUniversalIdentifier— ele é herdado do objeto pai. defineField()é a única forma de adicionar campos a objetos que você não criou comdefineObject().
defineField — Campos de relação
Conecte objetos com relações bidirecionais
defineField — Campos de relação
Conecte objetos com relações bidirecionais
As relações conectam objetos entre si. No Twenty, as relações são sempre bidirecionais — você define ambos os lados, e cada lado faz referência ao outro.Existem dois tipos de relação:Etapa 2: Defina o lado MANY_TO_ONE em PostCardRecipient (o lado “muitos” — contém a chave estrangeira):
Como as relações funcionam
Toda relação requer dois campos que façam referência um ao outro:- O lado MANY_TO_ONE — fica no objeto que contém a chave estrangeira
- O lado ONE_TO_MANY — fica no objeto que possui a coleção
FieldType.RELATION e fazem referência cruzada um ao outro via relationTargetFieldMetadataUniversalIdentifier.Exemplo: Um cartão postal tem muitos destinatários
Suponha que umPostCard possa ser enviado para muitos registros PostCardRecipient. Cada destinatário pertence a exatamente um cartão postal.Etapa 1: Defina o lado ONE_TO_MANY em PostCard (o lado “um”):src/fields/post-card-recipients-on-post-card.field.ts
src/fields/post-card-on-post-card-recipient.field.ts
Importações circulares: Ambos os campos de relação referenciam o
universalIdentifier um do outro. Para evitar problemas de importação circular, exporte os IDs dos seus campos como constantes nomeadas de cada arquivo e importe-os no outro arquivo. O sistema de build resolve isso em tempo de compilação.Relacionando a objetos padrão
Para criar uma relação com um objeto integrado do Twenty (Person, Company, etc.), useSTANDARD_OBJECT_UNIVERSAL_IDENTIFIERS:src/fields/person-on-self-hosting-user.field.ts
Propriedades de campos de relação
Campos de relação inline em defineObject
Você também pode definir campos de relação diretamente dentro dedefineObject(). Nesse caso, omita objectUniversalIdentifier — ele é herdado do objeto pai:Gerando entidades com yarn twenty add
Em vez de criar arquivos de entidade manualmente, você pode usar o scaffolder interativo:
universalIdentifier estável e a chamada correta de defineEntity().
Você também pode passar o tipo de entidade diretamente para pular o primeiro prompt:
Tipos de entidade disponíveis
O que o scaffolder gera
Cada tipo de entidade tem seu próprio modelo. Por exemplo,yarn twenty add object solicita:
- Nome (singular) — por exemplo,
invoice - Nome (plural) — por exemplo,
invoices - Rótulo (singular) — preenchido automaticamente a partir do nome (por exemplo,
Invoice) - Rótulo (plural) — preenchido automaticamente (por exemplo,
Invoices) - Criar uma view e um item de navegação? — se você responder sim, o scaffolder também gera uma view correspondente e um link na barra lateral para o novo objeto.
field é mais detalhado: ele solicita o nome do campo, rótulo, tipo (a partir de uma lista de todos os tipos de campo disponíveis como TEXT, NUMBER, SELECT, RELATION, etc.) e o universalIdentifier do objeto de destino.
Caminho de saída personalizado
Use a opção--path para colocar o arquivo gerado em um local personalizado: