snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s

This commit is contained in:
upstream-mirror
2026-09-17 23:28:13 +05:00
commit e7da97194a
32688 changed files with 4208681 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
---
title: Melhores Práticas
---
Este documento descreve as melhores práticas que você deve seguir ao trabalhar no backend.
## Siga uma abordagem modular
O backend segue uma abordagem modular, que é um princípio fundamental ao trabalhar com NestJS. Certifique-se de dividir seu código em módulos reutilizáveis para manter uma base de código limpa e organizada.
Cada módulo deve encapsular um recurso ou funcionalidade específico e ter um escopo bem definido. Esta abordagem modular permite uma clara separação de preocupações e remove complexidades desnecessárias.
## Expor serviços para uso em módulos
Sempre crie serviços que tenham uma responsabilidade clara e única, o que melhora a legibilidade e a manutenção do código. Nomeie os serviços de forma descritiva e consistente.
Você também deve expor serviços que deseja usar em outros módulos. Expor serviços para outros módulos é possível através do poderoso sistema de injeção de dependências do NestJS e promove o acoplamento frouxo entre os componentes.
## Evite usar o tipo `any`
Quando você declara uma variável como `any`, o verificador de tipos do TypeScript não realiza nenhuma verificação de tipo, tornando possível atribuir qualquer tipo de valores à variável. O TypeScript usa inferência de tipos para determinar o tipo da variável com base no valor. Ao declará-lo como `any`, o TypeScript não pode mais inferir o tipo. Isso torna difícil capturar erros relacionados a tipos durante o desenvolvimento, levando a erros em tempo de execução e tornando o código menos mantenível, menos confiável e mais difícil de entender para os outros.
Por isso, tudo deve ter um tipo. Assim, se você criar um novo objeto com um primeiro nome e um sobrenome, deve criar uma interface ou tipo que contenha um primeiro nome e um sobrenome que defina a forma do objeto que você está manipulando.

View File

@@ -0,0 +1,39 @@
---
title: Objetos personalizados
---
Os objetos são estruturas que permitem armazenar dados (registros, atributos e valores) específicos de uma organização. O Twenty vem com objetos padrão e personalizados.
Objetos padronizados são objetos embutidos com um conjunto de atributos disponíveis para todos os usuários. Exemplos de objetos padronizados na Twenty incluem Empresa e Pessoa. Os objetos padrão têm campos padrão que também estão disponíveis para todos os usuários do Twenty, como Company.displayName.
Objetos personalizados são objetos que você pode criar para armazenar informações exclusivas de sua organização. Eles não são embutidos; membros do seu espaço de trabalho podem criar e personalizar objetos personalizados para armazenar informações que os objetos padrão não são adequados.
## Esquema de alto nível
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/custom-object-schema.png" alt="Esquema de alto nível" />
</div>
<br />
## Como Funciona
Objetos personalizados vêm de tabelas de metadados que determinam a forma, nome e tipo dos objetos. Todas essas informações estão presentes no banco de dados do esquema de metadados, consistindo em tabelas:
* **DataSource**: Detalha onde os dados estão presentes.
* **Object**: Descreve o objeto e conecta-se a um DataSource.
* **Field**: Delimita os campos de um objeto e conecta-se ao objeto.
Para adicionar um objeto personalizado, o workspaceMember consultará a API /metadata. Isso atualiza os metadados de acordo e calcula um esquema GraphQL baseado nos metadados, armazenando-o em um cache GQL para uso posterior.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/add-custom-objects.jpeg" alt="Consultar a API /metadata para adicionar objetos personalizados" />
</div>
<br />
Para buscar dados, o processo envolve fazer consultas através do endpoint /graphql e passá-las pelo Query Resolver.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/custom-object-schema.png" alt="Consultar o endpoint /graphql para buscar dados" />
</div>

View File

@@ -0,0 +1,46 @@
---
title: Flags de recurso
---
As flags de recurso são usadas para ocultar recursos experimentais. Para a Twenty, eles são definidos no nível do espaço de trabalho e não no nível do usuário.
## Adicionando uma nova flag de recurso
Em `FeatureFlagKey.ts` adicione a flag de recurso:
```ts
type FeatureFlagKey =
| 'IS_FEATURENAME_ENABLED'
| ...;
```
Também adicione-o ao enum em `feature-flag.entity.ts`:
```ts
enum FeatureFlagKeys {
IsFeatureNameEnabled = 'IS_FEATURENAME_ENABLED',
...
}
```
Para aplicar uma flag de recurso em um recurso de **back-end**, use:
```ts
@Gate({
featureFlag: 'IS_FEATURENAME_ENABLED',
})
```
Para aplicar uma flag de recurso em um recurso de **front-end**, use:
```ts
const isFeatureNameEnabled = useIsFeatureEnabled('IS_FEATURENAME_ENABLED');
```
## Configurar flags de recurso para a implantação
Altere o registro correspondente na Tabela `core.featureFlag`:
| iD | chave | workspaceId | valor |
| --------- | ------------------------ | ----------- | ------------ |
| Aleatório | `IS_FEATURENAME_ENABLED` | WorkspaceID | `verdadeiro` |

View File

@@ -0,0 +1,125 @@
---
title: Arquitetura de Pastas
info: Um olhar detalhado sobre a arquitetura de pastas do nosso servidor
---
A estrutura do diretório do backend é a seguinte:
```
server
└───ability
└───constants
└───core
└───database
└───decorators
└───filters
└───guards
└───health
└───integrations
└───metadata
└───workspace
└───utils
```
## Habilidade
Define permissões e inclui manipuladores para cada entidade.
## Decoradores
Define decoradores personalizados no NestJS para funcionalidade adicional.
Veja [decoradores personalizados](https://docs.nestjs.com/custom-decorators) para mais detalhes.
## Filtros
Inclui filtros de exceção para lidar com exceções que podem ocorrer nos endpoints do GraphQL.
## Guards
Veja [guardas](https://docs.nestjs.com/guards) para mais detalhes.
## Integridade
Inclui uma API REST publicamente disponível (healthz) que retorna um JSON para confirmar se o banco de dados está funcionando como esperado.
## Metadados
Define objetos personalizados e disponibiliza uma API GraphQL (graphql/metadata).
## Espaço de trabalho
Gera e serve um esquema GraphQL personalizado com base nos metadados.
### Estrutura do Diretório de Trabalho
```
workspace
└───workspace-schema-builder
└───factories
└───graphql-types
└───database
└───interfaces
└───object-definitions
└───services
└───storage
└───utils
└───workspace-resolver-builder
└───factories
└───interfaces
└───workspace-query-builder
└───factories
└───interfaces
└───workspace-query-runner
└───interfaces
└───utils
└───workspace-datasource
└───workspace-manager
└───workspace-migration-runner
└───utils
└───workspace.module.ts
└───workspace.factory.spec.ts
└───workspace.factory.ts
```
A raiz do diretório workspace inclui o `workspace.factory.ts`, um arquivo que contém a função `createGraphQLSchema`. Esta função gera um esquema específico para o espaço de trabalho usando os metadados para adaptar um esquema para espaços de trabalho individuais. Ao separar a construção do esquema e do resolvedor, usamos a função `makeExecutableSchema`, que combina esses elementos discretos.
Essa estratégia não se trata apenas de organização, mas também ajuda na otimização, como no armazenamento em cache das definições de tipo geradas para melhorar o desempenho e a escalabilidade.
### Construtor de Esquema do Workspace
Gera o esquema GraphQL, e inclui:
#### Fábricas:
Construtores especializados para gerar construções relacionadas ao GraphQL.
* O type.factory traduz os metadados dos campos em tipos GraphQL usando o `TypeMapperService`.
* A type-definition.factory cria objetos de entrada ou saída do GraphQL derivados de `objectMetadata`.
#### Tipos GraphQL
Inclui enumerações, entradas, objetos e escalares, e serve como blocos de construção para a construção do esquema.
#### Interfaces e Definições de Objetos
Contém os planos para entidades GraphQL, e inclui tipos predefinidos e personalizados como `MONEY` ou `URL`.
#### Serviços
Contém o serviço responsável por associar o FieldMetadataType com seu scalar ou modificadores de consulta GraphQL apropriados.
#### Armazenamento
Inclui a classe `TypeDefinitionsStorage` que contém definições de tipos reutilizáveis, evitando a duplicação de tipos GraphQL.
### Construtor de Resolvedor de Workspace
Cria funções resolvedoras para consultar e modificar o esquema GraphQL.
Cada fábrica neste diretório é responsável por produzir um tipo distinto de resolvedor, como a `FindManyResolverFactory`, projetada para aplicação adaptável em várias tabelas.
### Executor de Consultas do Workspace
Executa as consultas geradas no banco de dados e analisa o resultado.

View File

@@ -0,0 +1,41 @@
---
title: Fila de Mensagens
---
Filas facilitam operações assíncronas a serem realizadas. Elas podem ser usadas para realizar tarefas em segundo plano, como enviar um email de boas-vindas ao se registrar.
Cada caso de uso terá sua própria classe de fila estendida de `MessageQueueServiceBase`.
Atualmente, só damos suporte ao `bull-mq`[bull-mq](https://bullmq.io/) como o driver de fila.
## Passos para criar e usar uma nova fila
1. Adicione um nome de fila para sua nova fila no enum `MESSAGE_QUEUES`.
2. Forneça a implementação da fábrica da fila com o nome da fila como o token de dependência.
3. Injete a fila que você criou no módulo/serviço necessário com o nome da fila como o token de dependência.
4. Adicione uma classe de trabalhador com injeção baseada em token, assim como o produtor.
### Exemplo de uso
```ts
class Resolver {
constructor(@Inject(MESSAGE_QUEUES.custom) private queue: MessageQueueService) {}
async onSomeAction() {
//business logic
await this.queue.add(someData);
}
}
//async worker
class CustomWorker {
constructor(@Inject(MESSAGE_QUEUES.custom) private queue: MessageQueueService) {
this.initWorker();
}
async initWorker() {
await this.queue.work(async ({ id, data }) => {
//worker logic
});
}
}
```

View File

@@ -0,0 +1,87 @@
---
title: Comandos de Backend
icon: terminal
---
## Comandos Úteis
Esses comandos devem ser executados a partir da pasta packages/twenty-server.
Em qualquer outra pasta você pode executar o `npx nx {command} twenty-server` (ou o `npx nx run twenty-server:{command}`).
### Configuração inicial
```
npx nx database:reset twenty-server # setup the database with dev seeds
```
### Iniciando o servidor
```
npx nx run twenty-server:start
```
### Lint
```
npx nx run twenty-server:lint # pass --fix to fix lint errors
```
### Teste
```
npx nx run twenty-server:test:unit # run unit tests
npx nx run twenty-server:test:integration # run integration tests
```
Nota: você pode executar `npx nx run twenty-server:test:integration:with-db-reset` caso precise redefinir o banco de dados antes de executar os testes de integração.
### Redefinindo o banco de dados
Se você deseja redefinir e semear a base de dados, pode executar o seguinte comando:
```bash
npx nx run twenty-server:database:reset
```
### Migrações
#### Para objetos nos esquemas Core/Metadata (TypeORM)
```bash
npx nx run twenty-server:database:migrate:generate
```
## Pilha de Tecnologias
O Twenty usa principalmente NestJS para o backend.
Prisma foi o primeiro ORM que usamos. Mas para permitir que os usuários criem campos e objetos personalizados, um nível mais baixo fazia mais sentido, pois precisamos ter controle detalhado. O projeto agora usa TypeORM.
Veja como a pilha de tecnologia se parece agora.
**Core**
* [NestJS](https://nestjs.com/)
* [TypeORM](https://typeorm.io/)
* [GraphQL Yoga](https://the-guild.dev/graphql/yoga-server)
**Banco de Dados**
* [Postgres](https://www.postgresql.org/)
**Integrações de terceiros**
* [Sentry](https://sentry.io/welcome/) para rastreamento de bugs
**Testes**
* [Jest](https://jestjs.io/)
**Ferramentas**
* [Yarn](https://yarnpkg.com/)
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
**Desenvolvimento**
* [AWS EKS](https://aws.amazon.com/eks/)

View File

@@ -0,0 +1,85 @@
---
title: Aplicativo Zapier
---
Sincronize o Twenty com mais de 3000 aplicativos usando [Zapier](https://zapier.com/) sem esforço. Automatize tarefas, aumente a produtividade e potencialize seus relacionamentos com clientes!
## Sobre o Zapier
O Zapier é uma ferramenta que permite automações de fluxos de trabalho conectando os aplicativos que sua equipe usa todos os dias. O conceito fundamental do Zapier são automações de fluxos de trabalho, chamadas Zaps, que incluem disparadores e ações.
Você pode aprender mais sobre como o Zapier funciona [aqui](https://zapier.com/how-it-works).
## Configuração
### Etapa 1: Instalar pacotes do Zapier
```bash
cd packages/twenty-zapier
yarn
```
### Etapa 2: Faça login com o CLI
Use suas credenciais do Zapier para fazer login usando o CLI:
```bash
zapier login
```
### Etapa 3: Defina as variáveis de ambiente
Na pasta `packages/twenty-zapier`, execute:
```bash
cp .env.example .env
```
Execute o aplicativo localmente, vá para [http://localhost:3000/settings/api-webhooks](http://localhost:3000/settings/api-webhooks) e gere uma chave API.
Substitua o valor **YOUR_API_KEY** no arquivo `.env` pela chave API que você acabou de gerar.
## Desenvolvimento
<Warning>
Certifique-se de executar `yarn build` antes de qualquer comando `zapier`.
</Warning>
### Teste
```bash
yarn test
```
### Lint
```bash
yarn format
```
### Assista e compile enquanto edita o código
```bash
yarn watch
```
### Valide seu aplicativo Zapier
```bash
yarn validate
```
### Implante seu aplicativo Zapier
```bash
yarn deploy
```
### Liste todos os comandos CLI do Zapier
```bash
zapier
```