i18n - docs translations (#17434)

Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
github-actions[bot]
2026-01-26 09:06:17 +01:00
committed by GitHub
parent 2353bc62cc
commit e0d4492013
651 changed files with 37463 additions and 32557 deletions
@@ -1,22 +1,22 @@
---
title: Best Practices
title: Melhores Práticas
---
This document outlines the best practices you should follow when working on the backend.
Este documento descreve as melhores práticas que você deve seguir ao trabalhar no backend.
## Follow a modular approach
## Siga uma abordagem modular
The backend follows a modular approach, which is a fundamental principle when working with NestJS. Make sure you break down your code into reusable modules to maintain a clean and organized codebase.
Each module should encapsulate a particular feature or functionality and have a well-defined scope. This modular approach enables clear separation of concerns and removes unnecessary complexities.
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.
## Expose services to use in modules
## Expor serviços para uso em módulos
Always create services that have a clear and single responsibility, which enhances code readability and maintainability. Name the services descriptively and consistently.
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.
You should also expose services that you want to use in other modules. Exposing services to other modules is possible through NestJS's powerful dependency injection system, and promotes loose coupling between components.
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.
## Avoid using `any` type
## Evite usar o tipo `any`
When you declare a variable as `any`, TypeScript's type checker doesn't perform any type checking, making it possible to assign any type of values to the variable. TypeScript uses type inference to determine the type of variable based on the value. By declaring it as `any`, TypeScript can no longer infer the type. This makes it hard to catch type-related errors during development, leading to runtime errors and makes the code less maintainable, less reliable, and harder to understand for others.
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.
This is why everything should have a type. So if you create a new object with a first name and last name, you should create an interface or type that contains a first name and last name that defines the shape of the object you are manipulating.
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.
@@ -1,39 +1,39 @@
---
title: Custom Objects
title: Objetos personalizados
---
Objects are structures that allow you to store data (records, attributes, and values) specific to an organization. Twenty provides both standard and custom objects.
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.
Standard objects are in-built objects with a set of attributes available for all users. Examples of standard objects in Twenty include Company and Person. Standard objects have standard fields that are also available for all Twenty users, like Company.displayName.
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.
Custom objects are objects that you can create to store information that is unique to your organization. They are not built-in; members of your workspace can create and customize custom objects to hold information that standard objects aren't suitable for.
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.
## High-level schema
## Esquema de alto nível
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/custom-object-schema.png" alt="High level schema" />
<img src="/images/docs/server/custom-object-schema.png" alt="Esquema de alto nível" />
</div>
<br />
## How it works
## Como Funciona
Custom objects come from metadata tables that determine the shape, name, and type of the objects. All this information is present in the metadata schema database, consisting of tables:
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**: Details where the data is present.
* **Object**: Describes the object and links to a DataSource.
* **Field**: Outlines an Object's fields and connects to the Object.
* **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.
To add a custom object, the workspaceMember will query the /metadata API. This updates the metadata accordingly and computes a GraphQL schema based on the metadata, storing it in a GQL cache for later use.
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="Query the /metadata API to add custom objects" />
<img src="/images/docs/server/add-custom-objects.jpeg" alt="Consultar a API /metadata para adicionar objetos personalizados" />
</div>
<br />
To fetch data, the process involves making queries through the /graphql endpoint and passing them through the Query Resolver.
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="Query the /graphql endpoint to fetch data" />
<img src="/images/docs/server/custom-object-schema.png" alt="Consultar o endpoint /graphql para buscar dados" />
</div>
@@ -1,12 +1,12 @@
---
title: Feature Flags
title: Flags de recurso
---
Feature flags are used to hide experimental features. For Twenty, they are set on workspace level and not on a user level.
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.
## Adding a new feature flag
## Adicionando uma nova flag de recurso
In `FeatureFlagKey.ts` add the feature flag:
Em `FeatureFlagKey.ts` adicione a flag de recurso:
```ts
type FeatureFlagKey =
@@ -14,7 +14,7 @@ type FeatureFlagKey =
| ...;
```
Also add it to the enum in `feature-flag.entity.ts`:
Também adicione-o ao enum em `feature-flag.entity.ts`:
```ts
enum FeatureFlagKeys {
@@ -23,7 +23,7 @@ enum FeatureFlagKeys {
}
```
To apply a feature flag on a **backend** feature use:
Para aplicar uma flag de recurso em um recurso de **back-end**, use:
```ts
@Gate({
@@ -31,16 +31,16 @@ To apply a feature flag on a **backend** feature use:
})
```
To apply a feature flag on a **frontend** feature use:
Para aplicar uma flag de recurso em um recurso de **front-end**, use:
```ts
const isFeatureNameEnabled = useIsFeatureEnabled('IS_FEATURENAME_ENABLED');
```
## Configure feature flags for the deployment
## Configurar flags de recurso para a implantação
Change the corresponding record in the Table `core.featureFlag`:
Altere o registro correspondente na Tabela `core.featureFlag`:
| id | key | workspaceId | value |
| ------ | ------------------------ | ----------- | ------ |
| Random | `IS_FEATURENAME_ENABLED` | WorkspaceID | `true` |
| iD | chave | workspaceId | valor |
| --------- | ------------------------ | ----------- | ------------ |
| Aleatório | `IS_FEATURENAME_ENABLED` | WorkspaceID | `verdadeiro` |
@@ -1,12 +1,12 @@
---
title: Folder Architecture
info: A detailed look into our server folder architecture
title: Arquitetura de Pastas
info: Um olhar detalhado sobre a arquitetura de pastas do nosso servidor
---
The backend directory structure is as follows:
A estrutura do diretório do backend é a seguinte:
```
server
servidor
└───ability
└───constants
└───core
@@ -21,37 +21,37 @@ server
└───utils
```
## Ability
## Habilidade
Defines permissions and includes handlers for each entity.
Define permissões e inclui manipuladores para cada entidade.
## Decorators
## Decoradores
Defines custom decorators in NestJS for added functionality.
Define decoradores personalizados no NestJS para funcionalidade adicional.
See [custom decorators](https://docs.nestjs.com/custom-decorators) for more details.
Veja [decoradores personalizados](https://docs.nestjs.com/custom-decorators) para mais detalhes.
## Filters
## Filtros
Includes exception filters to handle exceptions that might occur in GraphQL endpoints.
Inclui filtros de exceção para lidar com exceções que podem ocorrer nos endpoints do GraphQL.
## Guards
See [guards](https://docs.nestjs.com/guards) for more details.
Veja [guardas](https://docs.nestjs.com/guards) para mais detalhes.
## Health
## Integridade
Includes a publicly available REST API (healthz) that returns a JSON to confirm whether the database is working as expected.
Inclui uma API REST publicamente disponível (healthz) que retorna um JSON para confirmar se o banco de dados está funcionando como esperado.
## Metadata
## Metadados
Defines custom objects and makes available a GraphQL API (graphql/metadata).
Define objetos personalizados e disponibiliza uma API GraphQL (graphql/metadata).
## Workspace
## Espaço de trabalho
Generates and serves custom GraphQL schema based on the metadata.
Gera e serve um esquema GraphQL personalizado com base nos metadados.
### Workspace Directory Structure
### Estrutura do Diretório de Trabalho
```
workspace
@@ -83,43 +83,43 @@ workspace
└───workspace.factory.ts
```
The root of the workspace directory includes the `workspace.factory.ts`, a file containing the `createGraphQLSchema` function. This function generates workspace-specific schema by using the metadata to tailor a schema for individual workspaces. By separating the schema and resolver construction, we use the `makeExecutableSchema` function, which combines these discrete elements.
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.
This strategy is not just about organization, but also helps with optimization, such as caching generated type definitions to enhance performance and scalability.
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.
### Workspace Schema builder
### Construtor de Esquema do Workspace
Generates the GraphQL schema, and includes:
Gera o esquema GraphQL, e inclui:
#### Factories:
#### Fábricas:
Specialised constructors to generate GraphQL-related constructs.
Construtores especializados para gerar construções relacionadas ao GraphQL.
* The type.factory translates field metadata into GraphQL types using `TypeMapperService`.
* The type-definition.factory creates GraphQL input or output objects derived from `objectMetadata`.
* 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`.
#### GraphQL Types
#### Tipos GraphQL
Includes enumerations, inputs, objects, and scalars, and serves as the building blocks for the schema construction.
Inclui enumerações, entradas, objetos e escalares, e serve como blocos de construção para a construção do esquema.
#### Interfaces and Object Definitions
#### Interfaces e Definições de Objetos
Contains the blueprints for GraphQL entities, and includes both predefined and custom types like `MONEY` or `URL`.
Contém os planos para entidades GraphQL, e inclui tipos predefinidos e personalizados como `MONEY` ou `URL`.
#### Services
#### Serviços
Contains the service responsible for associating FieldMetadataType with its appropriate GraphQL scalar or query modifiers.
Contém o serviço responsável por associar o FieldMetadataType com seu scalar ou modificadores de consulta GraphQL apropriados.
#### Storage
#### Armazenamento
Includes the `TypeDefinitionsStorage` class that contains reusable type definitions, preventing duplication of GraphQL types.
Inclui a classe `TypeDefinitionsStorage` que contém definições de tipos reutilizáveis, evitando a duplicação de tipos GraphQL.
### Workspace Resolver Builder
### Construtor de Resolvedor de Workspace
Creates resolver functions for querying and mutating the GraphQL schema.
Cria funções resolvedoras para consultar e modificar o esquema GraphQL.
Each factory in this directory is responsible for producing a distinct resolver type, such as the `FindManyResolverFactory`, designed for adaptable application across various tables.
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.
### Workspace Query Runner
### Executor de Consultas do Workspace
Runs the generated queries on the database and parses the result.
Executa as consultas geradas no banco de dados e analisa o resultado.
@@ -1,20 +1,20 @@
---
title: Message Queue
title: Fila de Mensagens
---
Queues facilitate async operations to be performed. They can be used for performing background tasks such as sending a welcome email on register.
Each use case will have its own queue class extended from `MessageQueueServiceBase`.
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`.
Currently, we only support `bull-mq`[bull-mq](https://bullmq.io/) as the queue driver.
Atualmente, só damos suporte ao `bull-mq`[bull-mq](https://bullmq.io/) como o driver de fila.
## Steps to create and use a new queue
## Passos para criar e usar uma nova fila
1. Add a queue name for your new queue under enum `MESSAGE_QUEUES`.
2. Provide the factory implementation of the queue with the queue name as the dependency token.
3. Inject the queue that you created in the required module/service with the queue name as the dependency token.
4. Add worker class with token based injection just like producer.
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.
### Example usage
### Exemplo de uso
```ts
class Resolver {
@@ -1,19 +1,19 @@
---
title: Backend Commands
title: Comandos de Backend
---
## Useful commands
## Comandos Úteis
These commands should be executed from packages/twenty-server folder.
Esses comandos devem ser executados a partir da pasta packages/twenty-server.
From any other folder you can run `npx nx {command} twenty-server` (or `npx nx run twenty-server:{command}`).
### First time setup
### Configuração inicial
```
npx nx database:reset twenty-server # setup the database with dev seeds
```
### Starting the server
### Iniciando o servidor
```
npx nx run twenty-server:start
@@ -25,16 +25,16 @@ npx nx run twenty-server:start
npx nx run twenty-server:lint # pass --fix to fix lint errors
```
### Test
### Teste
```
npx nx run twenty-server:test:unit # run unit tests
npx nx run twenty-server:test:integration # run integration tests
```
Note: you can run `npx nx run twenty-server:test:integration:with-db-reset` in case you need to reset the database before running the 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.
### Resetting the database
### Redefinindo o banco de dados
If you want to reset and seed the database, you can run the following command:
@@ -42,9 +42,9 @@ If you want to reset and seed the database, you can run the following command:
npx nx run twenty-server:database:reset
```
### Migrations
### Migrações
#### For objects in Core/Metadata schemas (TypeORM)
#### Para objetos nos esquemas Core/Metadata (TypeORM)
```bash
npx nx run twenty-server:typeorm migration:generate src/database/typeorm/core/migrations/nameOfYourMigration -d src/database/typeorm/core/core.datasource.ts
@@ -52,26 +52,25 @@ npx nx run twenty-server:typeorm migration:generate src/database/typeorm/core/mi
#### For Workspace objects
There are no migrations files, migration are generated automatically for each workspace,
stored in the database, and applied with this command
Não há arquivos de migração, as migrações são geradas automaticamente para cada espaço de trabalho, armazenadas no banco de dados e aplicadas com este comando
```bash
npx nx run twenty-server:command workspace:sync-metadata -f
```
<Warning>
This will drop the database and re-run the migrations and seed.
Isso excluirá o banco de dados e reexecutará as migrações e seeds.
Make sure to back up any data you want to keep before running this command.
Certifique-se de fazer backup de todos os dados que deseja manter antes de executar este comando.
</Warning>
## Tech Stack
## Pilha de Tecnologias
Twenty primarily uses NestJS for the backend.
O Twenty usa principalmente NestJS para o backend.
Prisma was the first ORM we used. But in order to allow users to create custom fields and custom objects, a lower-level made more sense as we need to have fine-grained control. The project now uses TypeORM.
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.
Here's what the tech stack now looks like.
Veja como a pilha de tecnologia se parece agora.
**Core**
@@ -79,23 +78,23 @@ Here's what the tech stack now looks like.
* [TypeORM](https://typeorm.io/)
* [GraphQL Yoga](https://the-guild.dev/graphql/yoga-server)
**Database**
**Banco de Dados**
* [Postgres](https://www.postgresql.org/)
**Third-party integrations**
* [Sentry](https://sentry.io/welcome/) for tracking bugs
* [Sentry](https://sentry.io/welcome/) para rastreamento de bugs
**Testing**
**Testes**
* [Jest](https://jestjs.io/)
**Tooling**
**Ferramentas**
* [Yarn](https://yarnpkg.com/)
* [ESLint](https://eslint.org/)
**Development**
**Desenvolvimento**
* [AWS EKS](https://aws.amazon.com/eks/)
@@ -1,18 +1,18 @@
---
title: Zapier App
title: Aplicativo Zapier
---
Effortlessly sync Twenty with 3000+ apps using [Zapier](https://zapier.com/). Automate tasks, boost productivity, and supercharge your customer relationships!
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!
## About Zapier
## Sobre o Zapier
Zapier is a tool that allows you to automate workflows by connecting the apps that your team uses every day. The fundamental concept of Zapier is automation workflows, called Zaps, and include triggers and actions.
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.
You can learn more about how Zapier works [here](https://zapier.com/how-it-works).
Você pode aprender mais sobre como o Zapier funciona [aqui](https://zapier.com/how-it-works).
## Setup
## Configuração
### Step 1: Install Zapier packages
### Etapa 1: Instalar pacotes do Zapier
```bash
cd packages/twenty-zapier
@@ -20,33 +20,33 @@ cd packages/twenty-zapier
yarn
```
### Step 2: Login with the CLI
### Etapa 2: Faça login com o CLI
Use your Zapier credentials to log in using the CLI:
Use suas credenciais do Zapier para fazer login usando o CLI:
```bash
zapier login
```
### Step 3: Set environment variables
### Etapa 3: Defina as variáveis de ambiente
From the `packages/twenty-zapier` folder, run:
Na pasta `packages/twenty-zapier`, execute:
```bash
cp .env.example .env
```
Run the application locally, go to [http://localhost:3000/settings/api-webhooks](http://localhost:3000/settings/api-webhooks), and generate an API key.
Execute o aplicativo localmente, vá para [http://localhost:3000/settings/api-webhooks](http://localhost:3000/settings/api-webhooks) e gere uma chave API.
Replace the **YOUR_API_KEY** value in the `.env` file with the API key you just generated.
Substitua o valor **YOUR_API_KEY** no arquivo `.env` pela chave API que você acabou de gerar.
## Development
## Desenvolvimento
<Warning>
Make sure to run `yarn build` before any `zapier` command.
Certifique-se de executar `yarn build` antes de qualquer comando `zapier`.
</Warning>
### Test
### Teste
```bash
yarn test
@@ -58,25 +58,25 @@ yarn test
yarn format
```
### Watch and compile as you edit code
### Assista e compile enquanto edita o código
```bash
yarn watch
```
### Validate your Zapier app
### Valide seu aplicativo Zapier
```bash
yarn validate
```
### Deploy your Zapier app
### Implante seu aplicativo Zapier
```bash
yarn deploy
```
### List all Zapier CLI commands
### Liste todos os comandos CLI do Zapier
```bash
zapier
@@ -1,78 +1,78 @@
---
title: Bugs, Requests & Pull Requests
info: Report issues, request features, and contribute code
title: Bugs, solicitações e Pull Requests
info: Reporte issues, solicite funcionalidades e contribua com código
---
## Reporting Bugs
## Relatar Erros
To report a bug, please [create an issue on GitHub](https://github.com/twentyhq/twenty/issues/new).
Para relatar um erro, por favor [crie um problema no GitHub](https://github.com/twentyhq/twenty/issues/new).
You can also ask for help on [Discord](https://discord.gg/cx5n4Jzs57).
Você também pode pedir ajuda no [Discord](https://discord.gg/cx5n4Jzs57).
## Feature Requests
## Solicitações de Funcionalidades
If you're not sure if it's a bug, and you feel it's closer to a feature request, then you should probably [open a discussion instead](https://github.com/twentyhq/twenty/discussions/new).
Se você não tem certeza se é um erro e sente que está mais próximo de uma solicitação de funcionalidade, então você provavelmente deve [abrir uma discussão em vez disso](https://github.com/twentyhq/twenty/discussions/new).
## Submit a Pull Request
## Envie um Pull Request
Contributing code to Twenty starts with a pull request (PR).
Contribuir com código para o Twenty começa com um pull request (PR).
### Before You Start
### Antes de Começar
1. Check [existing issues](https://github.com/twentyhq/twenty/issues) for related work
2. For new features, open an issue first to discuss
3. Review our [Code of Conduct](https://github.com/twentyhq/twenty/blob/main/CODE_OF_CONDUCT.md)
1. Confira as [issues existentes](https://github.com/twentyhq/twenty/issues) para trabalhos relacionados
2. Para novas funcionalidades, abra primeiro uma issue para discutir
3. Consulte nosso [Código de Conduta](https://github.com/twentyhq/twenty/blob/main/CODE_OF_CONDUCT.md)
### Fork and Clone
### Fork e clone
1. Fork the repository on GitHub
2. Clone your fork:
1. Crie um fork do repositório no GitHub
2. Clone seu fork:
```bash
git clone https://github.com/YOUR_USERNAME/twenty.git
cd twenty
```
3. Add upstream remote:
3. Adicione o remoto upstream:
```bash
git remote add upstream https://github.com/twentyhq/twenty.git
```
### Create a Branch
### Crie uma branch
```bash
git checkout -b feature/your-feature-name
```
Use descriptive branch names:
Use nomes de branch descritivos:
* `feature/add-export-button`
* `fix/login-redirect-issue`
* `docs/update-api-guide`
### Make Your Changes
### Faça suas alterações
1. Write clean, well-documented code
2. Follow existing code style
3. Add tests for new functionality
4. Update documentation if needed
1. Escreva código limpo e bem documentado
2. Siga o estilo de código existente
3. Adicione testes para a nova funcionalidade
4. Atualize a documentação se necessário
### Submit Your PR
### Envie seu PR
1. Push your branch:
1. Faça push da sua branch:
```bash
git push origin feature/your-feature-name
```
2. Open a PR on GitHub
3. Fill in the PR template
4. Link related issues
2. Abra um PR no GitHub
3. Preencha o modelo do PR
4. Vincule as issues relacionadas
### PR Checklist
### Checklist de PR
* [ ] Code follows project style guidelines
* [ ] Tests pass locally
* [ ] Documentation is updated
* [ ] PR description explains the changes
* [ ] O código segue as diretrizes de estilo do projeto
* [ ] Os testes passam localmente
* [ ] A documentação está atualizada
* [ ] A descrição do PR explica as alterações
@@ -1,19 +1,19 @@
---
title: Best Practices
title: Melhores Práticas
---
This document outlines the best practices you should follow when working on the frontend.
Este documento descreve as melhores práticas que você deve seguir ao trabalhar no frontend.
## State management
## Gerenciamento de Estado
React and Recoil handle state management in the codebase.
React e Recoil lidam com o gerenciamento de estado na base de código.
### Use `useRecoilState` to store state
### Use `useRecoilState` para armazenar o estado
It's good practice to create as many atoms as you need to store your state.
É uma boa prática criar tantos átomos quanto necessário para armazenar seu estado.
<Warning>
It's better to use extra atoms than trying to be too concise with props drilling.
É melhor usar átomos extras do que tentar ser muito conciso com a perfuração de props.
</Warning>
```tsx
@@ -36,29 +36,29 @@ export const MyComponent = () => {
}
```
### Do not use `useRef` to store state
### Não use `useRef` para armazenar estado
Avoid using `useRef` to store state.
Evite usar `useRef` para armazenar estado.
If you want to store state, you should use `useState` or `useRecoilState`.
See [how to manage re-renders](#managing-re-renders) if you feel like you need `useRef` to prevent some re-renders from happening.
Veja [como gerenciar re-renderizações](#managing-re-renders) se você sentir que precisa de `useRef` para evitar que algumas re-renderizações aconteçam.
## Managing re-renders
## Gerenciando re-renderizações
Re-renders can be hard to manage in React.
As re-renderizações podem ser difíceis de gerenciar no React.
Here are some rules to follow to avoid unnecessary re-renders.
Aqui estão algumas regras a seguir para evitar re-renderizações desnecessárias.
Keep in mind that you can **always** avoid re-renders by understanding their cause.
Lembre-se de que você pode **sempre** evitar re-renderizações entendendo sua causa.
### Work at the root level
### Trabalhe no nível raiz
Avoiding re-renders in new features is now made easy by eliminating them at the root level.
Evitar re-renderizações em novos recursos agora é fácil eliminando-as no nível raiz.
The `PageChangeEffect` sidecar component contains just one `useEffect` that holds all the logic to execute on a page change.
That way you know that there's just one place that can trigger a re-render.
Assim você sabe que há apenas um lugar que pode disparar uma re-renderização.
### Always think twice before adding `useEffect` in your codebase
@@ -68,13 +68,13 @@ You should think whether you need `useEffect`, or if you can move the logic in a
You'll find it generally easy to move the logic in a `handleClick` or `handleChange` function.
You can also find them in libraries like Apollo: `onCompleted`, `onError`, etc.
Você também pode encontrá-las em bibliotecas como Apollo: `onCompleted`, `onError`, etc.
### Use a sibling component to extract `useEffect` or data fetching logic
If you feel like you need to add a `useEffect` in your root component, you should consider extracting it in a sidecar component.
You can apply the same for data fetching logic, with Apollo hooks.
Você pode aplicar o mesmo para lógica de busca de dados, com hooks do Apollo.
```tsx
// ❌ Bad, will cause re-renders even if data is not changing,
@@ -129,43 +129,43 @@ export const App = () => (
);
```
### Use recoil family states and recoil family selectors
### Use estados de família Recoil e seletores de família Recoil
Recoil family states and selectors are a great way to avoid re-renders.
Estados de família Recoil e seletores são uma ótima maneira de evitar re-renderizações.
They are useful when you need to store a list of items.
Eles são úteis quando você precisa armazenar uma lista de itens.
### You shouldn't use `React.memo(MyComponent)`
### Você não deve usar `React.memo(MyComponent)`
Avoid using `React.memo()` because it does not solve the cause of the re-render, but instead breaks the re-render chain, which can lead to unexpected behavior and make the code very hard to refactor.
Evite usar `React.memo()` porque não resolve a causa da re-renderização, mas em vez disso quebra a cadeia de re-renderização, o que pode levar a um comportamento inesperado e tornar o código muito difícil de refatorar.
### Limit `useCallback` or `useMemo` usage
### Limite o uso de `useCallback` ou `useMemo`
They are often not necessary and will make the code harder to read and maintain for a gain of performance that is unnoticeable.
Eles muitas vezes não são necessários e tornarão o código mais difícil de ler e manter por um ganho de desempenho que é imperceptível.
## Console.logs
`console.log` statements are valuable during development, offering real-time insights into variable values and code flow. But, leaving them in production code can lead to several issues:
As instruções `console.log` são valiosas durante o desenvolvimento, oferecendo insights em tempo real sobre valores de variáveis e fluxo de código. Mas, deixá-los no código de produção pode levar a vários problemas:
1. **Performance**: Excessive logging can affect the runtime performance, especially on client-side applications.
1. **Desempenho**: Log excessivo pode afetar o desempenho de execução, especialmente em aplicativos do lado do cliente.
2. **Security**: Logging sensitive data can expose critical information to anyone who inspects the browser's console.
2. **Segurança**: Registrar dados sensíveis pode expor informações críticas para qualquer pessoa que inspecionar o console do navegador.
3. **Cleanliness**: Filling up the console with logs can obscure important warnings or errors that developers or tools need to see.
3. **Limpeza**: Encher o console com logs pode obscurecer avisos ou erros importantes que desenvolvedores ou ferramentas precisam ver.
4. **Professionalism**: End users or clients checking the console and seeing a myriad of log statements might question the code's quality and polish.
4. **Profissionalismo**: Usuários finais ou clientes verificando o console e vendo uma infinidade de instruções de log podem questionar a qualidade e o acabamento do código.
Make sure you remove all `console.logs` before pushing the code to production.
Certifique-se de remover todos os `console.logs` antes de enviar o código para produção.
## Naming
## Nomeação
### Variable Naming
### Nomeação de Variáveis
Variable names ought to precisely depict the purpose or function of the variable.
Os nomes das variáveis devem descrever precisamente o propósito ou função da variável.
#### The issue with generic names
#### O problema com nomes genéricos
Generic names in programming are not ideal because they lack specificity, leading to ambiguity and reduced code readability. Such names fail to convey the variable or function's purpose, making it challenging for developers to understand the code's intent without deeper investigation. This can result in increased debugging time, higher susceptibility to errors, and difficulties in maintenance and collaboration. Meanwhile, descriptive naming makes the code self-explanatory and easier to navigate, enhancing code quality and developer productivity.
Nomes genéricos na programação não são ideais porque carecem de especificidade, levando a ambiguidade e reduzindo a legibilidade do código. Tais nomes não conseguem transmitir o propósito da variável ou função, tornando desafiador para os desenvolvedores entender a intenção do código sem uma investigação mais profunda. Isso pode resultar em aumento do tempo de depuração, maior susceptibilidade a erros e dificuldades na manutenção e colaboração. Enquanto isso, nomeação descritiva torna o código auto-explicativo e mais fácil de navegar, melhorando a qualidade do código e a produtividade do desenvolvedor.
```tsx
// ❌ Bad, uses a generic name that doesn't communicate its
@@ -178,13 +178,13 @@ const [value, setValue] = useState('');
const [email, setEmail] = useState('');
```
#### Some words to avoid in variable names
#### Algumas palavras a evitar em nomes de variáveis
* dummy
### Event handlers
### Manipuladores de Eventos
Event handler names should start with `handle`, while `on` is a prefix used to name events in components props.
Os nomes dos manipuladores de eventos devem começar com `handle`, enquanto `on` é um prefixo usado para nomear eventos em props de componentes.
```tsx
// ❌ Bad
@@ -200,13 +200,13 @@ const handleEmailChange = (val: string) => {
};
```
## Optional Props
## Props Opcionais
Avoid passing the default value for an optional prop.
Evite passar o valor padrão para um prop opcional.
**EXAMPLE**
**EXEMPLO**
Take the`EmailField` component defined below:
Observe o componente `EmailField` definido abaixo:
```tsx
type EmailFieldProps = {
@@ -219,7 +219,7 @@ const EmailField = ({ value, disabled = false }: EmailFieldProps) => (
);
```
**Usage**
**Uso**
```tsx
// ❌ Bad, passing in the same value as the default value adds no value
@@ -231,11 +231,11 @@ const Form = () => <EmailField value="username@email.com" disabled={false} />;
const Form = () => <EmailField value="username@email.com" />;
```
## Component as props
## Componente como props
Try as much as possible to pass uninstantiated components as props, so children can decide on their own of what props they need to pass.
Tente tanto quanto possível passar componentes não instanciados como props, para que os filhos possam decidir por si mesmos quais props precisam passar.
The most common example for that is icon components:
O exemplo mais comum é de componentes de ícone:
```tsx
const SomeParentComponent = () => <MyComponent Icon={MyIcon} />;
@@ -252,25 +252,25 @@ const MyComponent = ({ MyIcon }: { MyIcon: IconComponent }) => {
};
```
For React to understand that the component is a component, you need to use PascalCase, to later instantiate it with `<MyIcon>`
Para que o React entenda que o componente é um componente, você precisa usar PascalCase, para depois instanciá-lo com `<MyIcon>`
## Prop Drilling: Keep It Minimal
## Perfuração de Props: Mantenha-a Mínima
Prop drilling, in the React context, refers to the practice of passing state variables and their setters through many component layers, even if intermediary components don't use them. While sometimes necessary, excessive prop drilling can lead to:
Perfuração de props, no contexto do React, refere-se à prática de passar variáveis de estado e seus setters por muitas camadas de componentes, mesmo que componentes intermediários não os usem. Embora às vezes seja necessário, perfuração excessiva de props pode levar a:
1. **Decreased Readability**: Tracing where a prop originates or where it's utilized can become convoluted in a deeply nested component structure.
1. **Legibilidade Reduzida**: Rastreamento de onde um prop se origina ou onde é utilizado pode se tornar confuso em uma estrutura de componentes profundamente aninhada.
2. **Maintenance Challenges**: Changes in one component's prop structure might require adjustments in several components, even if they don't directly use the prop.
2. **Desafios de Manutenção**: Mudanças na estrutura de props de um componente podem exigir ajustes em vários componentes, mesmo que eles não usem diretamente o prop.
3. **Reduced Component Reusability**: A component receiving a lot of props solely for passing them down becomes less general-purpose and harder to reuse in different contexts.
3. **Redução da Reutilização de Componentes**: Um componente que recebe muitos props apenas para passá-los adiante torna-se menos de propósito geral e mais difícil de reutilizar em diferentes contextos.
If you feel that you are using excessive prop drilling, see [state management best practices](#state-management).
Se você sentir que está usando perfuração excessiva de props, veja [melhores práticas de gerenciamento de estado](#state-management).
## Imports
## Importações
When importing, opt for the designated aliases rather than specifying complete or relative paths.
Ao importar, opte pelos apelidos designados em vez de especificar caminhos completos ou relativos.
**The Aliases**
**Os Pseudónimos**
```js
{
@@ -282,7 +282,7 @@ When importing, opt for the designated aliases rather than specifying complete o
}
```
**Usage**
**Uso**
```tsx
// ❌ Bad, specifies the entire relative path
@@ -300,9 +300,9 @@ import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from 'twenty-ui/testing';
```
## Schema Validation
## Validação de Esquema
[Zod](https://github.com/colinhacks/zod) is the schema validator for untyped objects:
[Zod](https://github.com/colinhacks/zod) é o validador de esquema para objetos não tipados:
```js
const validationSchema = z
@@ -320,6 +320,6 @@ const validationSchema = z
type Form = z.infer<typeof validationSchema>;
```
## Breaking Changes
## Alterações Incompatíveis
Always perform thorough manual testing before proceeding to guarantee that modifications havent caused disruptions elsewhere, given that tests have not yet been extensively integrated.
Sempre execute testes manuais completos antes de prosseguir para garantir que as modificações não tenham causado interrupções em outros lugares, dado que os testes ainda não foram extensivamente integrados.
@@ -1,11 +1,11 @@
---
title: Folder Architecture
info: A detailed look into our folder architecture
title: Arquitetura de Pastas
info: Um olhar detalhado sobre nossa arquitetura de pastas
---
In this guide, you will explore the details of the project directory structure and how it contributes to the organization and maintainability of Twenty.
Neste guia, você explorará os detalhes da estrutura de diretórios do projeto e como isso contribui para a organização e manutenção do Twenty.
By following this folder architecture convention, it's easier to find the files related to specific features and ensure that the application is scalable and maintainable.
Seguindo esta convenção de arquitetura de pastas, é mais fácil encontrar os arquivos relacionados a funcionalidades específicas e garantir que a aplicação seja escalável e manutenível.
```
front
@@ -22,14 +22,14 @@ front
└───...
```
## Pages
## Páginas
Includes the top-level components defined by the application routes. They import more low-level components from the modules folder (more details below).
Inclui os componentes de nível superior definidos pelas rotas da aplicação. Elas importam componentes de nível mais baixo da pasta `modules` (mais detalhes abaixo).
## Modules
## Módulos
Each module represents a feature or a group of feature, comprising its specific components, states, and operational logic.
They should all follow the structure below. You can nest modules within modules (referred to as submodules) and the same rules will apply.
Cada módulo representa uma funcionalidade ou um grupo de funcionalidades, compreendendo seus componentes específicos, estados e lógica operacional.
Todos devem seguir a estrutura abaixo. Você pode aninhar módulos dentro de módulos (referidos como submódulos) e as mesmas regras se aplicarão.
```
module1
@@ -50,60 +50,60 @@ module1
└───utils
```
### Contexts
### Contextos
A context is a way to pass data through the component tree without having to pass props down manually at every level.
Um contexto é uma maneira de passar dados através da árvore de componentes sem ter que passar propriedades manualmente em cada nível.
See [React Context](https://react.dev/reference/react#context-hooks) for more details.
Veja [React Context](https://react.dev/reference/react#context-hooks) para mais detalhes.
### GraphQL
Includes fragments, queries, and mutations.
Inclui fragmentos, consultas e mutações.
See [GraphQL](https://graphql.org/learn/) for more details.
Veja [GraphQL](https://graphql.org/learn/) para mais detalhes.
* Fragments
* Fragmentos
A fragment is a reusable piece of a query, which you can use in different places. By using fragments, it's easier to avoid duplicating code.
Um fragmento é uma parte reutilizável de uma consulta, que você pode usar em diferentes lugares. Usando fragmentos, é mais fácil evitar duplicar código.
See [GraphQL Fragments](https://graphql.org/learn/queries/#fragments) for more details.
Veja [GraphQL Fragments](https://graphql.org/learn/queries/#fragments) para mais detalhes.
* Queries
* Consultas
See [GraphQL Queries](https://graphql.org/learn/queries/) for more details.
Veja [GraphQL Queries](https://graphql.org/learn/queries/) para mais detalhes.
* Mutations
* Mutações
See [GraphQL Mutations](https://graphql.org/learn/queries/#mutations) for more details.
Veja [GraphQL Mutations](https://graphql.org/learn/queries/#mutations) para mais detalhes.
### Hooks
See [Hooks](https://react.dev/learn/reusing-logic-with-custom-hooks) for more details.
Veja [Hooks](https://react.dev/learn/reusing-logic-with-custom-hooks) para mais detalhes.
### States
### Estados
Contains the state management logic. [RecoilJS](https://recoiljs.org) handles this.
Contém a lógica de gerenciamento de estado. [RecoilJS](https://recoiljs.org) lida com isso.
* Selectors: See [RecoilJS Selectors](https://recoiljs.org/docs/basic-tutorial/selectors) for more details.
* Seletores: Veja [RecoilJS Selectors](https://recoiljs.org/docs/basic-tutorial/selectors) para mais detalhes.
React's built-in state management still handles state within a component.
O gerenciamento de estado embutido do React ainda lida com o estado dentro de um componente.
### Utils
### Utilitários
Should just contain reusable pure functions. Otherwise, create custom hooks in the `hooks` folder.
Deve conter apenas funções puras reutilizáveis. Caso contrário, crie hooks personalizados na pasta `hooks`.
## UI
Contains all the reusable UI components used in the application.
Contém todos os componentes reutilizáveis de UI usados na aplicação.
This folder can contain sub-folders, like `data`, `display`, `feedback`, and `input` for specific types of components. Each component should be self-contained and reusable, so that you can use it in different parts of the application.
Esta pasta pode conter subpastas, como `data`, `display`, `feedback` e `input` para tipos específicos de componentes. Cada componente deve ser autocontido e reutilizável, de modo que você possa usá-lo em diferentes partes da aplicação.
By separating the UI components from the other components in the `modules` folder, it's easier to maintain a consistent design and to make changes to the UI without affecting other parts (business logic) of the codebase.
Ao separar os componentes de UI dos outros componentes na pasta `modules`, é mais fácil manter um design consistente e fazer alterações na UI sem afetar outras partes (lógica de negócios) do código.
## Interface and dependencies
## Interface e dependências
You can import other module code from any module except for the `ui` folder. This will keep its code easy to test.
Você pode importar código de outros módulos, exceto da pasta `ui`. Isso manterá seu código fácil de testar.
### Internal
### Interno
Each part (hooks, states, ...) of a module can have an `internal` folder, which contains parts that are just used within the module.
Cada parte (hooks, estados, ...) de um módulo pode ter uma pasta `internal`, que contém partes que são usadas apenas dentro do módulo.
@@ -1,22 +1,22 @@
---
title: Frontend Commands
title: Comandos do Frontend
---
## Useful commands
## Comandos Úteis
### Starting the app
### Iniciando o aplicativo
```bash
npx nx start twenty-front
```
### Regenerate graphql schema based on API graphql schema
### Regenerar esquema GraphQL baseado no esquema de API GraphQL
```bash
npx nx run twenty-front:graphql:generate --configuration=metadata
```
OR
OU
```bash
npx nx run twenty-front:graphql:generate
@@ -28,14 +28,14 @@ npx nx run twenty-front:graphql:generate
npx nx run twenty-front:lint # pass --fix to fix lint errors
```
## Translations
## Traduções
```bash
npx nx run twenty-front:lingui:extract
npx nx run twenty-front:lingui:compile
```
### Test
### Teste
```bash
npx nx run twenty-front:test # run jest tests
@@ -44,11 +44,11 @@ npx nx run twenty-front:storybook:test # run tests # (needs yarn storybook:serve
npx nx run twenty-front:storybook:coverage # (needs yarn storybook:serve:dev to be running)
```
## Tech Stack
## Pilha de Tecnologias
The project has a clean and simple stack, with minimal boilerplate code.
O projeto possui uma pilha limpa e simples, com pouco código boilerplate.
**App**
**Aplicativo**
* [React](https://react.dev/)
* [Apollo](https://www.apollographql.com/docs/)
@@ -56,35 +56,35 @@ The project has a clean and simple stack, with minimal boilerplate code.
* [Recoil](https://recoiljs.org/docs/introduction/core-concepts)
* [TypeScript](https://www.typescriptlang.org/)
**Testing**
**Testes**
* [Jest](https://jestjs.io/)
* [Storybook](https://storybook.js.org/)
**Tooling**
**Ferramentas**
* [Yarn](https://yarnpkg.com/)
* [Craco](https://craco.js.org/docs/)
* [ESLint](https://eslint.org/)
## Architecture
## Arquitetura
### Routing
### Roteamento
[React Router](https://reactrouter.com/) handles the routing.
[React Router](https://reactrouter.com/) gerencia o roteamento.
To avoid unnecessary [re-renders](/l/pt/developers/contribute/capabilities/frontend-development/best-practices-front#managing-re-renders) all the routing logic is in a `useEffect` in `PageChangeEffect`.
### State Management
### Gerenciamento de Estado
[Recoil](https://recoiljs.org/docs/introduction/core-concepts) handles state management.
[Recoil](https://recoiljs.org/docs/introduction/core-concepts) gerencia o estado.
See [best practices](/l/pt/developers/contribute/capabilities/frontend-development/best-practices-front#state-management) for more information on state management.
Veja [melhores práticas](/l/pt/developers/contribute/capabilities/frontend-development/best-practices-front#state-management) para mais informações sobre gerenciamento de estado.
## Testing
## Testes
[Jest](https://jestjs.io/) serves as the tool for unit testing while [Storybook](https://storybook.js.org/) is for component testing.
[Jest](https://jestjs.io/) serve como ferramenta para testes unitários enquanto [Storybook](https://storybook.js.org/) para teste de componentes.
Jest is mainly for testing utility functions, and not components themselves.
Jest é principalmente para testar funções utilitárias, e não os componentes em si.
Storybook is for testing the behavior of isolated components, as well as displaying the design system.
Storybook é para testar o comportamento de componentes isolados, bem como exibir o sistema de design.
@@ -1,42 +1,42 @@
---
title: Hotkeys
title: Teclas de atalho
---
## Introduction
## Introdução
When you need to listen to a hotkey, you would normally use the `onKeyDown` event listener.
Quando você precisa ouvir uma tecla de atalho, normalmente usaria o listener de evento `onKeyDown`.
In `twenty-front` however, you might have conflicts between same hotkeys that are used in different components, mounted at the same time.
No entanto, em `twenty-front`, você pode ter conflitos entre as mesmas teclas de atalho que são usadas em diferentes componentes, montados ao mesmo tempo.
For example, if you have a page that listens for the Enter key, and a modal that listens for the Enter key, with a Select component inside that modal that listens for the Enter key, you might have a conflict when all are mounted at the same time.
Por exemplo, se você tem uma página que escuta a tecla Enter, e um modal que escuta a tecla Enter, com um componente Select dentro desse modal que escuta a tecla Enter, você pode ter um conflito quando todos são montados ao mesmo tempo.
## The `useScopedHotkeys` hook
## O hook `useScopedHotkeys`
To handle this problem, we have a custom hook that makes it possible to listen to hotkeys without any conflict.
Para lidar com esse problema, temos um hook personalizado que permite ouvir as teclas de atalho sem qualquer conflito.
You place it in a component, and it will listen to the hotkeys only when the component is mounted AND when the specified **hotkey scope** is active.
Você o coloca em um componente, e ele ouvirá as teclas de atalho somente quando o componente estiver montado E quando o **escopo da tecla de atalho** especificado estiver ativo.
## How to listen for hotkeys in practice?
## Como ouvir teclas de atalho na prática?
There are two steps involved in setting up hotkey listening :
Há dois passos envolvidos na configuração da escuta de teclas de atalho :
1. Set the [hotkey scope](#what-is-a-hotkey-scope-) that will listen to hotkeys
2. Use the `useScopedHotkeys` hook to listen to hotkeys
1. Defina o [escopo da tecla de atalho](#what-is-a-hotkey-scope-) que ouvirá as teclas de atalho
2. Use o hook `useScopedHotkeys` para ouvir as teclas de atalho
Setting up hotkey scopes is required even in simple pages, because other UI elements like left menu or command menu might also listen to hotkeys.
Configurar escopos de teclas de atalho é necessário mesmo em páginas simples, porque outros elementos de UI como o menu à esquerda ou o menu de comando também podem ouvir teclas de atalho.
## Use cases for hotkeys
## Casos de uso para teclas de atalho
In general, you'll have two use cases that require hotkeys :
Em geral, você terá dois casos de uso que requerem teclas de atalho :
1. In a page or a component mounted in a page
2. In a modal-type component that takes the focus due to a user action
1. Em uma página ou um componente montado em uma página
2. Em um componente do tipo modal que assume o foco devido a uma ação do usuário
The second use case can happen recursively : a dropdown in a modal for example.
O segundo caso de uso pode ocorrer de forma recursiva : um dropdown em um modal, por exemplo.
### Listening to hotkeys in a page
### Ouvindo teclas de atalho em uma página
Example :
Exemplo :
```tsx
const PageListeningEnter = () => {
@@ -71,11 +71,11 @@ const PageListeningEnter = () => {
};
```
### Listening to hotkeys in a modal-type component
### Ouvindo teclas de atalho em um componente do tipo modal
For this example we'll use a modal component that listens for the Escape key to tell its parent to close it.
Neste exemplo, usaremos um componente modal que ouve a tecla Escape para informar ao pai que feche.
Here the user interaction is changing the scope.
Aqui, a interação do usuário está mudando o escopo.
```tsx
const ExamplePageWithModal = () => {
@@ -108,7 +108,7 @@ const ExamplePageWithModal = () => {
};
```
Then in the modal component :
Então no componente modal :
```tsx
const MyDropdownComponent = ({ onClose }: { onClose: () => void }) => {
@@ -131,15 +131,15 @@ It's important to use this pattern when you're not sure that just using a useEff
Those conflicts can be hard to debug, and it might happen more often than not with useEffects.
## What is a hotkey scope?
## O que é um escopo de tecla de atalho?
A hotkey scope is a string that represents a context in which the hotkeys are active. It is generally encoded as an enum.
Um escopo de tecla de atalho é uma string que representa um contexto no qual as teclas de atalho estão ativas. Geralmente é codificado como um enum.
When you change the hotkey scope, the hotkeys that are listening to this scope will be enabled and the hotkeys that are listening to other scopes will be disabled.
Quando você altera o escopo da tecla de atalho, as teclas associadas a esse escopo serão ativadas e as teclas associadas a outros escopos serão desativadas.
You can set only one scope at a time.
Você pode definir apenas um escopo por vez.
As an example, the hotkey scopes for each page are defined in the `PageHotkeyScope` enum:
Como exemplo, os escopos de tecla de atalho para cada página são definidos no enum `PageHotkeyScope`:
```tsx
export enum PageHotkeyScope {
@@ -160,7 +160,7 @@ export enum PageHotkeyScope {
}
```
Internally, the currently selected scope is stored in a Recoil state that is shared across the application :
Internamente, o escopo atualmente selecionado é armazenado em um estado Recoil que é compartilhado por toda a aplicação :
```tsx
export const currentHotkeyScopeState = createState<HotkeyScope>({
@@ -169,10 +169,10 @@ export const currentHotkeyScopeState = createState<HotkeyScope>({
});
```
But this Recoil state should never be handled manually ! We'll see how to use it in the next section.
Mas esse estado Recoil nunca deve ser manipulado manualmente! Veremos como usá-lo na próxima seção.
## How is it working internally?
## Como funciona internamente?
We made a thin wrapper on top of [react-hotkeys-hook](https://react-hotkeys-hook.vercel.app/docs/intro) that makes it more performant and avoids unnecessary re-renders.
Criamos um wrapper leve em cima de [react-hotkeys-hook](https://react-hotkeys-hook.vercel.app/docs/intro) que o torna mais eficiente e evita renderizações desnecessárias.
We also create a Recoil state to handle the hotkey scope state and make it available everywhere in the application.
Também criamos um estado Recoil para gerenciar o estado do escopo da tecla de atalho e torná-lo disponível em toda a aplicação.
@@ -1,8 +1,8 @@
---
title: Storybook
description: Browse Twenty's UI component library
description: Navegue pela biblioteca de componentes UI do Twenty
---
View our complete component library and documentation in Storybook.
Veja toda a nossa biblioteca de componentes e documentação no Storybook.
[Open Storybook →](https://storybook.twenty.com)
[Abra o Storybook →](https://storybook.twenty.com)
@@ -1,24 +1,24 @@
---
title: Style Guide
title: Guia de Estilo
---
This document includes the rules to follow when writing code.
Este documento inclui as regras a seguir ao escrever código.
The goal here is to have a consistent codebase, which is easy to read and easy to maintain.
O objetivo aqui é ter uma base de código consistente, fácil de ler e fácil de manter.
For this, it's better to be a bit more verbose than to be too concise.
Para isso, é melhor ser um pouco mais detalhado do que ser muito conciso.
Always keep in mind that people read code more often than they write it, specially on an open source project, where anyone can contribute.
Sempre tenha em mente que as pessoas leem código mais frequentemente do que o escrevem, especialmente em um projeto de código aberto, onde qualquer um pode contribuir.
There are a lot of rules that are not defined here, but that are automatically checked by linters.
Há muitas regras que não estão definidas aqui, mas que são verificadas automaticamente por linters.
## React
### Use functional components
### Use componentes funcionais
Always use TSX functional components.
Use sempre componentes funcionais TSX.
Do not use default `import` with `const`, because it's harder to read and harder to import with code completion.
Não use `import` padrão com `const`, pois é mais difícil de ler e mais difícil de importar com autocomplete.
```tsx
// ❌ Bad, harder to read, harder to import with code completion
@@ -34,11 +34,11 @@ export function MyComponent() {
};
```
### Props
### Propriedades
Create the type of the props and call it `(ComponentName)Props` if there's no need to export it.
Crie o tipo das propriedades e chame-o de `(NomeDoComponente)Props` se não houver necessidade de exportá-lo.
Use props destructuring.
Use destructuring de props.
```tsx
// ❌ Bad, no type
@@ -52,7 +52,7 @@ type MyComponentProps = {
export const MyComponent = ({ name }: MyComponentProps) => <div>Hello {name}</div>;
```
#### Refrain from using `React.FC` or `React.FunctionComponent` to define prop types
#### Evite usar `React.FC` ou `React.FunctionComponent` para definir tipos de props
```tsx
/* ❌ - Bad, defines the component type annotations with `FC`
@@ -67,10 +67,10 @@ const EmailField: React.FC<{
```
```tsx
/* ✅ - Good, a separate type (OwnProps) is explicitly defined for the
* component's props
* - This method doesn't automatically include the children prop. If
* you want to include it, you have to specify it in OwnProps.
/* ✅ - Bom, um tipo separado (OwnProps) é explicitamente definido para as
* props do componente
* - Este método não inclui automaticamente a prop children. Se
* quiser incluí-la, deve especificá-la em OwnProps.
*/
type EmailFieldProps = {
value: string;
@@ -81,9 +81,9 @@ const EmailField = ({ value }: EmailFieldProps) => (
);
```
#### No Single Variable Prop Spreading in JSX Elements
#### Proibição de Prop Spreading de Variável Única em Elementos JSX
Avoid using single variable prop spreading in JSX elements, like `{...props}`. This practice often results in code that is less readable and harder to maintain because it's unclear which props the component is receiving.
Evite usar o espalhamento de props de variável única em elementos JSX, como `{...props}`. Essa prática muitas vezes resulta em código menos legível e mais difícil de manter, pois não está claro quais props o componente está recebendo.
```tsx
/* ❌ - Bad, spreads a single variable prop into the underlying component
@@ -94,23 +94,23 @@ const MyComponent = (props: OwnProps) => {
```
```tsx
/* ✅ - Good, Explicitly lists all props
* - Enhances readability and maintainability
/* ✅ - Bom, lista explicitamente todas as props
* - Aumenta a legibilidade e a manutenibilidade
*/
const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => {
return <OtherComponent {...{ prop1, prop2, prop3 }} />;
};
```
Rationale:
Justificativa:
* At a glance, it's clearer which props the code passes down, making it easier to understand and maintain.
* It helps to prevent tight coupling between components via their props.
* Linting tools make it easier to identify misspelled or unused props when you list props explicitly.
* À primeira vista, é mais claro quais props o código passa, tornando mais fácil de entender e manter.
* Ajuda a evitar o acoplamento forte entre componentes via suas props.
* Ferramentas de linting tornam mais fácil identificar props mal digitadas ou não utilizadas quando você lista props explicitamente.
## JavaScript
### Use nullish-coalescing operator `??`
### Use o operador de coalescência nula `??`
```tsx
// ❌ Bad, can return 'default' even if value is 0 or ''
@@ -120,21 +120,21 @@ const value = process.env.MY_VALUE || 'default';
const value = process.env.MY_VALUE ?? 'default';
```
### Use optional chaining `?.`
### Use encadeamento opcional `?.`
```tsx
// ❌ Bad
// ❌ Ruim
onClick && onClick();
// ✅ Good
// ✅ Bom
onClick?.();
```
## TypeScript
### Use `type` instead of `interface`
### Use `type` em vez de `interface`
Always use `type` instead of `interface`, because they almost always overlap, and `type` is more flexible.
Sempre use `type` em vez de `interface`, porque elas quase sempre se sobrepõem e `type` é mais flexível.
```tsx
// ❌ Bad
@@ -148,11 +148,11 @@ type MyType = {
};
```
### Use string literals instead of enums
### Use literais de string em vez de enums
[String literals](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) are the go-to way to handle enum-like values in TypeScript. They are easier to extend with Pick and Omit, and offer a better developer experience, specially with code completion.
[Literals de string](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) são o caminho a seguir para lidar com valores tipo enum no TypeScript. Eles são mais fáceis de estender com Pick e Omit, e oferecem uma melhor experiência de desenvolvedor, especialmente com autocomplete.
You can see why TypeScript recommends avoiding enums [here](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enums).
Você pode ver porque o TypeScript recomenda evitar enums [aqui](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enums).
```tsx
// ❌ Bad, utilizes an enum
@@ -171,13 +171,13 @@ let color = Color.Red;
let color: "red" | "green" | "blue" = "red";
```
#### GraphQL and internal libraries
#### GraphQL e bibliotecas internas
You should use enums that GraphQL codegen generates.
Você deve usar enums que o GraphQL codegen gera.
It's also better to use an enum when using an internal library, so the internal library doesn't have to expose a string literal type that is not related to the internal API.
É melhor usar um enum ao usar uma biblioteca interna, para que a biblioteca interna não precise expor um tipo literal de string que não está relacionado à API interna.
Example:
Exemplo:
```TSX
const {
@@ -190,11 +190,11 @@ setHotkeyScopeAndMemorizePreviousScope(
);
```
## Styling
## Estilização
### Use StyledComponents
Style the components with [styled-components](https://emotion.sh/docs/styled).
Estilize os componentes com [styled-components](https://emotion.sh/docs/styled).
```tsx
// ❌ Bad
@@ -208,7 +208,7 @@ const StyledTitle = styled.div`
`;
```
Prefix styled components with "Styled" to differentiate them from "real" components.
Prefixe componentes estilizados com "Styled" para diferenciá-los de componentes "reais".
```tsx
// ❌ Bad
@@ -224,17 +224,17 @@ const StyledTitle = styled.div`
`;
```
### Theming
### Tematização
Utilizing the theme for the majority of component styling is the preferred approach.
Utilizar o tema para a maioria da estilização dos componentes é a abordagem preferida.
#### Units of measurement
#### Unidades de medida
Avoid using `px` or `rem` values directly within the styled components. The necessary values are generally already defined in the theme, so its recommended to make use of the theme for these purposes.
Evite usar valores `px` ou `rem` diretamente dentro dos componentes estilizados. Os valores necessários geralmente já estão definidos no tema, por isso é recomendável fazer uso do tema para esses fins.
#### Colors
#### Cores
Refrain from introducing new colors; instead, use the existing palette from the theme. Should there be a situation where the palette does not align, please leave a comment so that the team can rectify it.
Evite introduzir novas cores; em vez disso, use a paleta existente do tema. Se houver uma situação em que a paleta não se alinhe, por favor, deixe um comentário para que a equipe possa corrigi-la.
```tsx
// ❌ Bad, directly specifies style values without utilizing the theme
@@ -258,9 +258,9 @@ const StyledButton = styled.button`
`;
```
## Enforcing No-Type Imports
## Impor Importações Sem Tipo
Avoid type imports. To enforce this standard, an ESLint rule checks for and reports any type imports. This helps maintain consistency and readability in the TypeScript code.
Evite importações de tipo. Para impor esse padrão, uma regra do ESLint verifica e relata qualquer violação de importação de tipos. Isso ajuda a manter a consistência e a legibilidade no código TypeScript.
```tsx
// ❌ Bad
@@ -273,18 +273,18 @@ import type { Meta, StoryObj } from '@storybook/react';
import { Meta, StoryObj } from '@storybook/react';
```
### Why No-Type Imports
### Por Que Não Usar Importações de Tipo
* **Consistency**: By avoiding type imports and using a single approach for both type and value imports, the codebase remains consistent in its module import style.
* **Consistência**: Ao evitar importações de tipo e usar uma única abordagem para importações de tipo e valor, a base de código permanece consistente em seu estilo de importação de módulo.
* **Readability**: No-type imports improve code readability by making it clear when you're importing values or types. This reduces ambiguity and makes it easier to understand the purpose of imported symbols.
* **Legibilidade**: Importações sem tipo melhoram a legibilidade do código, tornando claro quando você está importando valores ou tipos. Isso reduz a ambiguidade e facilita a compreensão do propósito dos símbolos importados.
* **Maintainability**: It enhances codebase maintainability because developers can identify and locate type-only imports when reviewing or modifying code.
* **Manutenção**: Melhora a manutenibilidade da base de código porque os desenvolvedores podem identificar e localizar importações somente de tipo ao revisar ou modificar o código.
### ESLint Rule
### Regra ESLint
An ESLint rule, `@typescript-eslint/consistent-type-imports`, enforces the no-type import standard. This rule will generate errors or warnings for any type import violations.
Uma regra do ESLint, `@typescript-eslint/consistent-type-imports`, aplica o padrão de importação sem tipo. Esta regra gera erros ou avisos para qualquer violação de importação de tipo.
Please note that this rule specifically addresses rare edge cases where unintentional type imports occur. TypeScript itself discourages this practice, as mentioned in the [TypeScript 3.8 release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). In most situations, you should not need to use type-only imports.
Observe que esta regra trata especificamente de casos isolados onde importações de tipos não intencionais ocorrem. O próprio TypeScript desencoraja essa prática, conforme mencionado nas [notas de lançamento do TypeScript 3.8](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). Na maioria das situações, não é necessário usar importações somente de tipo.
To ensure your code complies with this rule, make sure to run ESLint as part of your development workflow.
Para garantir que seu código esteja em conformidade com essa regra, certifique-se de executar o ESLint como parte do seu fluxo de trabalho de desenvolvimento.
@@ -1,59 +1,59 @@
---
title: Work with Figma
info: Learn how you can collaborate with Twenty's Figma
title: Trabalhar com Figma
info: Saiba como você pode colaborar com o Figma da Twenty
---
Figma is a collaborative interface design tool that aids in bridging the communication barrier between designers and developers.
This guide explains how you can collaborate with Figma.
Figma é uma ferramenta de design de interface colaborativa que ajuda a superar a barreira de comunicação entre designers e desenvolvedores.
Este guia explica como você pode colaborar com o Figma.
## Access
## Acesso
1. **Access the shared link:** You can access the project's Figma file [here](https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty).
2. **Sign in:** If you're not already signed in, Figma will prompt you to do so.
Key features are only available to logged-in users, such as the developer mode and the ability to select a dedicated frame.
1. **Acesse o link compartilhado:** Você pode acessar o arquivo do projeto no Figma [aqui](https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty).
2. **Entrar:** Se você ainda não estiver conectado, o Figma solicitará que o faça.
Recursos principais estão disponíveis apenas para usuários conectados, como o modo desenvolvedor e a capacidade de selecionar uma moldura dedicada.
<Warning>
You will not be able to collaborate effectively without an account.
Você não será capaz de colaborar efetivamente sem uma conta.
</Warning>
## Figma structure
## Estrutura do Figma
On the left sidebar, you can access the different pages of Twenty's Figma. This is how they're organized:
Na barra lateral esquerda, você pode acessar as diferentes páginas do Figma da Twenty. É assim que elas estão organizadas:
* **Components page:** This is the first page. The designer uses it to create and organize the reusable design elements used throughout the design file. For example, buttons, icons, symbols, or any other reusable components. It serves to maintain consistency across the design.
* **Main page:** The second page is the main page, which shows the complete user interface of the project. You can press ***Play*** to use the full app prototype.
* **Features pages:** The other pages are typically dedicated to features in progress. They contain the design of specific features or modules of the application or website. They are typically still in progress.
* **Página de componentes:** Esta é a primeira página. O designer a utiliza para criar e organizar os elementos de design reutilizáveis utilizados em todo o arquivo de design. Por exemplo, botões, ícones, símbolos, ou qualquer outro componente reutilizável. Serve para manter a consistência em todo o design.
* **Página principal:** A segunda página é a página principal, que mostra a interface completa do usuário do projeto. Você pode pressionar ***Play*** para usar o protótipo completo do aplicativo.
* **Páginas de recursos:** As outras páginas são tipicamente dedicadas a recursos em andamento. Elas contêm o design de recursos ou módulos específicos do aplicativo ou website. Elas geralmente ainda estão em progresso.
## Useful Tips
## Dicas Úteis
With read-only access, you can't edit the design, but you can access all features that will be useful to convert the designs into code.
Com acesso somente leitura, você não pode editar o design, mas pode acessar todos os recursos que serão úteis para converter os designs em código.
### Use the Dev mode
### Use o modo Dev
Figma's Dev Mode enhances developers' productivity by providing easy design navigation, effective asset management, efficient communication tools, toolbox integrations, quick code snippets, and key layer information, bridging the gap between design and development. You can learn more about Dev Mode [here](https://www.figma.com/dev-mode/).
O Modo Dev do Figma aumenta a produtividade dos desenvolvedores ao oferecer navegação fácil no design, gerenciamento eficaz de ativos, ferramentas de comunicação eficientes, integrações de caixa de ferramentas, trechos de código rápidos, e informações importantes de camadas, unindo design e desenvolvimento. Você pode aprender mais sobre o Modo Dev [aqui](https://www.figma.com/dev-mode/).
Switch to the "Developer" mode in the right part of the toolbar to see design specs, copy CSS, and access assets.
Mude para o modo "Desenvolvedor" na parte direita da barra de ferramentas para ver especificações de design, copiar CSS, e acessar ativos.
### Use the Prototype
### Use o Protótipo
Click on any element on the canvas and press the “Play” button at the top right edge of the interface to access the prototype view. Prototype mode allows you to interact with the design as if it were the final product. It demonstrates the flow between screens and how interface elements like buttons, links, or menus behave when interacted with.
Clique em qualquer elemento na tela e pressione o botão “Play” na borda superior direita da interface para acessar a visualização do protótipo. O modo Protótipo permite que você interaja com o design como se fosse o produto final. Demonstra o fluxo entre telas e como elementos da interface como botões, links, ou menus se comportam quando interagidos.
1. **Understanding transitions and animations:** In the Prototype mode, you can view any transitions or animations added by a designer between screens or UI elements, providing clear visual instructions to developers on the intended behavior and style.
2. **Implementation clarification:** A prototype can also help reduce ambiguities. Developers can interact with it to gain a better understanding of the functionality or appearance of particular elements.
1. **Entendendo transições e animações:** No modo Protótipo, é possível visualizar quaisquer transições ou animações adicionadas por um designer entre telas ou elementos da UI, proporcionando instruções visuais claras aos desenvolvedores sobre o comportamento e estilo pretendidos.
2. **Esclarecimento de implementação:** Um protótipo também pode ajudar a reduzir ambiguidades. Os desenvolvedores podem interagir com ele para obter uma melhor compreensão da funcionalidade ou aparência de elementos específicos.
For more comprehensive details and guidance on learning the Figma platform, you can visit the official [Figma Documentation](https://help.figma.com/hc/en-us).
Para obter informações mais abrangentes e orientações sobre como aprender a plataforma Figma, você pode visitar a [Documentação Oficial do Figma](https://help.figma.com/hc/en-us).
### Measure distances
### Medir distâncias
Select an element, hold `Option` key (Mac) or `Alt` key (Windows), then hover over another element to see the distance between them.
Selecione um elemento, mantenha a tecla `Option` (Mac) ou `Alt` (Windows) pressionada e passe o mouse sobre outro elemento para ver a distância entre eles.
### Figma extension for VSCode (Recommended)
### Extensão Figma para VSCode (Recomendado)
[Figma for VS Code](https://marketplace.visualstudio.com/items?itemName=figma.figma-vscode-extension)
lets you navigate and inspect design files, collaborate with designers, track changes, and speed up implementation - all without leaving your text editor.
It's part of our recommended extensions.
[Figma para VS Code](https://marketplace.visualstudio.com/items?itemName=figma.figma-vscode-extension)
permite que você navegue e inspecione arquivos de design, colabore com designers, acompanhe alterações e acelere a implementação - tudo sem sair do seu editor de texto.
Faz parte das extensões recomendadas por nós.
## Collaboration
## Colaboração
1. **Using Comments:** You are welcome to use the comment feature by clicking on the bubble icon in the left part of the toolbar.
2. **Cursor chat:** A nice feature of Figma is the Cursor chat. Just press `;` on Mac and `/` on Windows to send a message if you see someone else using Figma as the same time as you.
1. **Usando Comentários:** Você é bem-vindo para usar a ferramenta de comentários clicando no ícone de bolha na parte esquerda da barra de ferramentas.
2. **Chat do Cursor:** Uma característica interessante do Figma é o Chat do Cursor. Apenas pressione `;` no Mac e `/` no Windows para enviar uma mensagem se você vir outra pessoa usando Figma ao mesmo tempo que você.
@@ -1,13 +1,13 @@
---
title: Local Setup
description: The guide for contributors (or curious developers) who want to run Twenty locally.
title: Configuração Local
description: O guia para contribuidores (ou desenvolvedores curiosos) que desejam executar o Twenty localmente.
---
## Prerequisites
## Pré-requisitos
<Tabs>
<Tab title="Linux and MacOS">
Before you can install and use Twenty, make sure you install the following on your computer:
<Tab title="Linux e MacOS">
Antes de instalar e usar o Twenty, certifique-se de instalar o seguinte em seu computador:
* [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
* [Node v24.5.0](https://nodejs.org/en/download)
@@ -15,25 +15,25 @@ description: The guide for contributors (or curious developers) who want to run
* [nvm](https://github.com/nvm-sh/nvm/blob/master/README.md)
<Warning>
`npm` won't work, you should use `yarn` instead. Yarn is now shipped with Node.js, so you don't need to install it separately.
You only have to run `corepack enable` to enable Yarn if you haven't done it yet.
`npm` não funcionará, você deve usar `yarn` em vez disso. O Yarn agora vem com o Node.js, então você não precisa instalá-lo separadamente.
Você só precisa executar `corepack enable` para habilitar o Yarn, se ainda não o fez.
</Warning>
</Tab>
<Tab title="Windows (WSL)">
1. Install WSL
Open PowerShell as Administrator and run:
1. Instale o WSL
Abra o PowerShell como Administrador e execute:
```powershell
wsl --install
```
You should now see a prompt to restart your computer. If not, restart it manually.
Você deve agora ver um aviso para reiniciar o computador. Caso contrário, reinicie-o manualmente.
Upon restart, a powershell window will open and install Ubuntu. This may take up some time.
You'll see a prompt to create a username and password for your Ubuntu installation.
Ao reiniciar, uma janela do powershell será aberta e instalará o Ubuntu. Isso pode levar algum tempo.
Você verá uma solicitação para criar um nome de usuário e senha para sua instalação do Ubuntu.
2. Install and configure git
2. Instalar e configurar o git
```bash
sudo apt-get install git
@@ -43,10 +43,10 @@ description: The guide for contributors (or curious developers) who want to run
git config --global user.email "youremail@domain.com"
```
3. Install nvm, node.js and yarn
3. Instale nvm, node.js e yarn
<Warning>
Use `nvm` to install the correct `node` version. The `.nvmrc` ensures all contributors use the same version.
Use `nvm` para instalar a versão correta do `node`. O `.nvmrc` garante que todos os contribuidores usem a mesma versão.
</Warning>
```bash
@@ -55,7 +55,7 @@ description: The guide for contributors (or curious developers) who want to run
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
```
Close and reopen your terminal to use nvm. Then run the following commands.
Feche e reabra o seu terminal para usar o nvm. Em seguida, execute os seguintes comandos.
```bash
@@ -70,13 +70,13 @@ description: The guide for contributors (or curious developers) who want to run
---
## Step 1: Git Clone
## Passo 1: Clonar com Git
In your terminal, run the following command.
No seu terminal, execute o seguinte comando.
<Tabs>
<Tab title="SSH (Recommended)">
If you haven't already set up SSH keys, you can learn how to do so [here](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/about-ssh).
<Tab title="SSH (Recomendado)">
Se ainda não configurou as chaves SSH, você pode aprender como fazê-lo [aqui](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/about-ssh).
```bash
git clone git@github.com:twentyhq/twenty.git
@@ -90,36 +90,36 @@ In your terminal, run the following command.
</Tab>
</Tabs>
## Step 2: Position yourself at the root
## Passo 2: Posicione-se na raiz
```bash
cd twenty
```
You should run all commands in the following steps from the root of the project.
Você deve executar todos os comandos nas etapas seguintes a partir da raiz do projeto.
## Step 3: Set up a PostgreSQL Database
## Passo 3: Configurar um Banco de Dados PostgreSQL
<Tabs>
<Tab title="Linux">
**Option 1 (preferred):** To provision your database locally:
Use the following link to install Postgresql on your Linux machine: [Postgresql Installation](https://www.postgresql.org/download/linux/)
**Opção 1 (preferencial):** Para prover seu banco de dados localmente:
Use o seguinte link para instalar o Postgresql na sua máquina Linux: [Instalação do Postgresql](https://www.postgresql.org/download/linux/)
```bash
psql postgres -c "CREATE DATABASE \"default\";" -c "CREATE DATABASE test;"
```
Note: You might need to add `sudo -u postgres` to the command before `psql` to avoid permission errors.
Nota: Pode ser necessário adicionar `sudo -u postgres` ao comando antes de `psql` para evitar erros de permissão.
**Option 2:** If you have docker installed:
**Opção 2:** Se você tem o docker instalado:
```bash
make postgres-on-docker
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
<Tab title="Mac OS">
**Option 1 (preferred):** To provision your database locally with `brew`:
**Opção 1 (preferencial):** Para prover seu banco de dados localmente com `brew`:
```bash
brew install postgresql@16
@@ -128,16 +128,16 @@ You should run all commands in the following steps from the root of the project.
psql postgres -c "CREATE DATABASE \"default\";" -c "CREATE DATABASE test;"
```
You can verify if the PostgreSQL server is running by executing:
Você pode verificar se o servidor PostgreSQL está em execução, executando:
```bash
brew services list
```
The installer might not create the `postgres` user by default when installing
via Homebrew on MacOS. Instead, it creates a PostgreSQL role that matches your macOS
username (e.g., "john").
To check and create the `postgres` user if necessary, follow these steps:
O instalador pode não criar o usuário `postgres` por padrão ao instalar
via Homebrew no MacOS. Em vez disso, ele cria uma função PostgreSQL que corresponde ao seu nome de usuário do macOS
(por exemplo, "john").
Para verificar e criar o usuário `postgres`, se necessário, siga estas etapas:
```bash
# Connect to PostgreSQL
@@ -146,14 +146,14 @@ You should run all commands in the following steps from the root of the project.
psql -U $(whoami) -d postgres
```
Once at the psql prompt (postgres=#), run:
Uma vez no prompt do psql (postgres=#), execute:
```bash
# List existing PostgreSQL roles
\du
```
You'll see output similar to:
Você verá uma saída semelhante a:
```bash
Role name | Attributes | Member of
@@ -161,98 +161,98 @@ You should run all commands in the following steps from the root of the project.
john | Superuser | {}
```
If you do not see a `postgres` role listed, proceed to the next step.
Create the `postgres` role manually:
Se você não vir um papel `postgres` listado, prossiga para a próxima etapa.
Crie o papel `postgres` manualmente:
```bash
CREATE ROLE postgres WITH SUPERUSER LOGIN;
```
This creates a superuser role named `postgres` with login access.
Isso cria um papel de superusuário chamado `postgres` com acesso de login.
**Option 2:** If you have docker installed:
**Opção 2:** Se você tem o docker instalado:
```bash
make postgres-on-docker
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
<Tab title="Windows (WSL)">
All the following steps are to be run in the WSL terminal (within your virtual machine)
Todos os passos a seguir devem ser executados no terminal WSL (dentro da sua máquina virtual)
**Option 1:** To provision your Postgresql locally:
Use the following link to install Postgresql on your Linux virtual machine: [Postgresql Installation](https://www.postgresql.org/download/linux/)
**Opção 1:** Para provisionar seu Postgresql localmente:
Use o seguinte link para instalar o Postgresql em sua máquina virtual Linux: [Instalação do Postgresql](https://www.postgresql.org/download/linux/)
```bash
psql postgres -c "CREATE DATABASE \"default\";" -c "CREATE DATABASE test;"
```
Note: You might need to add `sudo -u postgres` to the command before `psql` to avoid permission errors.
Nota: Pode ser necessário adicionar `sudo -u postgres` ao comando antes de `psql` para evitar erros de permissão.
**Option 2:** If you have docker installed:
Running Docker on WSL adds an extra layer of complexity.
Only use this option if you are comfortable with the extra steps involved, including turning on [Docker Desktop WSL2](https://docs.docker.com/desktop/wsl).
**Opção 2:** Se você tem o docker instalado:
Executar o Docker no WSL adiciona uma camada extra de complexidade.
Use esta opção apenas se estiver confortável com as etapas adicionais envolvidas, incluindo a ativação do [Docker Desktop WSL2](https://docs.docker.com/desktop/wsl).
```bash
make postgres-on-docker
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
</Tabs>
You can now access the database at [localhost:5432](localhost:5432), with user `postgres` and password `postgres` .
Você pode agora acessar o banco de dados em [localhost:5432](localhost:5432), com o usuário `postgres` e senha `postgres`.
## Step 4: Set up a Redis Database (cache)
## Passo 4: Configurar um Banco de Dados Redis (cache)
Twenty requires a redis cache to provide the best performance
O Twenty requer um cache redis para oferecer o melhor desempenho
<Tabs>
<Tab title="Linux">
**Option 1:** To provision your Redis locally:
Use the following link to install Redis on your Linux machine: [Redis Installation](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/)
**Opção 1:** Para prover seu Redis localmente:
Use o seguinte link para instalar o Redis na sua máquina Linux: [Instalação do Redis](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/)
**Option 2:** If you have docker installed:
**Opção 2:** Se você tem o docker instalado:
```bash
make redis-on-docker
make -C packages/twenty-docker redis-on-docker
```
</Tab>
<Tab title="Mac OS">
**Option 1 (preferred):** To provision your Redis locally with `brew`:
**Opção 1 (preferencial):** Para prover seu Redis localmente com `brew`:
```bash
brew install redis
```
Start your redis server:
Inicie seu servidor redis:
`brew services start redis`
**Option 2:** If you have docker installed:
**Opção 2:** Se você tem o docker instalado:
```bash
make redis-on-docker
make -C packages/twenty-docker redis-on-docker
```
</Tab>
<Tab title="Windows (WSL)">
**Option 1:** To provision your Redis locally:
Use the following link to install Redis on your Linux virtual machine: [Redis Installation](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/)
**Opção 1:** Para prover seu Redis localmente:
Use o seguinte link para instalar o Redis na sua máquina virtual Linux: [Instalação do Redis](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/)
**Option 2:** If you have docker installed:
**Opção 2:** Se você tem o docker instalado:
```bash
make redis-on-docker
make -C packages/twenty-docker redis-on-docker
```
</Tab>
</Tabs>
If you need a Client GUI, we recommend [redis insight](https://redis.io/insight/) (free version available)
Se precisar de uma GUI de Cliente, recomendamos o [redis insight](https://redis.io/insight/) (versão gratuita disponível)
## Step 5: Setup environment variables
## Passo 5: Configurar variáveis de ambiente
Use environment variables or `.env` files to configure your project. More info [here](/l/pt/developers/self-host/capabilities/setup)
Use variáveis de ambiente ou arquivos `.env` para configurar seu projeto. Mais informações [aqui](/l/pt/developers/self-host/capabilities/setup)
Copy the `.env.example` files in `/front` and `/server`:
Copie os arquivos `.env.example` em `/front` e `/server`:
```bash
cp ./packages/twenty-front/.env.example ./packages/twenty-front/.env
@@ -260,29 +260,29 @@ cp ./packages/twenty-server/.env.example ./packages/twenty-server/.env
```
<Info>
**Multi-Workspace Mode:** By default, Twenty runs in single-workspace mode where only one workspace can be created. To enable multi-workspace support (useful for testing subdomain-based features), set `IS_MULTIWORKSPACE_ENABLED=true` in your server `.env` file. See [Multi-Workspace Mode](/l/pt/developers/self-host/capabilities/setup#multi-workspace-mode) for details.
**Modo Multiworkspace:** Por padrão, o Twenty é executado no modo de workspace único, em que apenas um workspace pode ser criado. Para ativar o suporte a multiworkspace (útil para testar recursos baseados em subdomínio), defina `IS_MULTIWORKSPACE_ENABLED=true` no arquivo `.env` do seu servidor. Veja [Modo Multiworkspace](/l/pt/developers/self-host/capabilities/setup#multi-workspace-mode) para obter detalhes.
</Info>
## Step 6: Installing dependencies
## Passo 6: Instalando dependências
To build Twenty server and seed some data into your database, run the following command:
Para compilar o servidor Twenty e popular seu banco de dados com alguns dados, execute o seguinte comando:
```bash
yarn
```
Note that `npm` or `pnpm` won't work
Note que `npm` ou `pnpm` não funcionarão
## Step 7: Running the project
## Passo 7: Executando o projeto
<Tabs>
<Tab title="Linux">
Depending on your Linux distribution, Redis server might be started automatically.
If not, check the [Redis installation guide](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/) for your distro.
Dependendo da sua distribuição Linux, o servidor Redis pode ser iniciado automaticamente.
Se não, verifique o [guia de instalação do Redis](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/) para sua distro.
</Tab>
<Tab title="Mac OS">
Redis should already be running. If not, run:
Redis já deve estar em execução. Se não, execute:
```bash
brew services start redis
@@ -290,18 +290,18 @@ Note that `npm` or `pnpm` won't work
</Tab>
<Tab title="Windows (WSL)">
Depending on your Linux distribution, Redis server might be started automatically.
If not, check the [Redis installation guide](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/) for your distro.
Dependendo da sua distribuição Linux, o servidor Redis pode ser iniciado automaticamente.
Se não, verifique o [guia de instalação do Redis](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/) para sua distro.
</Tab>
</Tabs>
Set up your database with the following command:
Configure seu banco de dados com o seguinte comando:
```bash
npx nx database:reset twenty-server
```
Start the server, the worker and the frontend services:
Inicie o servidor, o worker e os serviços de frontend:
```bash
npx nx start twenty-server
@@ -309,25 +309,25 @@ npx nx worker twenty-server
npx nx start twenty-front
```
Alternatively, you can start all services at once:
Alternativamente, você pode iniciar todos os serviços de uma vez:
```bash
npx nx start
```
## Step 8: Use Twenty
## Passo 8: Use Twenty
**Frontend**
Twenty's frontend will be running at [http://localhost:3001](http://localhost:3001).
You can log in using the default demo account: `tim@apple.dev` (password: `tim@apple.dev`)
O frontend do Twenty estará em execução em [http://localhost:3001](http://localhost:3001).
Você pode fazer login usando a conta demo padrão: `tim@apple.dev` (senha: `tim@apple.dev`)
**Backend**
* Twenty's server will be up and running at [http://localhost:3000](http://localhost:3000)
* The GraphQL API can be accessed at [http://localhost:3000/graphql](http://localhost:3000/graphql)
* The REST API can be reached at [http://localhost:3000/rest](http://localhost:3000/rest)
* O servidor do Twenty estará ativo em [http://localhost:3000](http://localhost:3000)
* A API GraphQL pode ser acessada em [http://localhost:3000/graphql](http://localhost:3000/graphql)
* A API REST pode ser acessada em [http://localhost:3000/rest](http://localhost:3000/rest)
## Troubleshooting
## Resolução de Problemas
If you encounter any problem, check [Troubleshooting](/l/pt/developers/self-host/capabilities/troubleshooting) for solutions.
Se encontrar algum problema, verifique [Resolução de Problemas](/l/pt/developers/self-host/capabilities/troubleshooting) para soluções.
@@ -1,32 +1,32 @@
---
title: Contribute
description: Contribute to Twenty's open-source development.
title: Contribuir
description: Contribua para o desenvolvimento de código aberto do Twenty.
---
<Frame>
<img src="/images/user-guide/github/github-header.png" alt="AI" />
<img src="/images/user-guide/github/github-header.png" alt="IA" />
</Frame>
## Overview
## Visão geral
Twenty is open-source and welcomes contributions from the community. Whether you're fixing bugs, adding features, or improving documentation, your contributions help make Twenty better for everyone.
O Twenty é de código aberto e recebe contribuições da comunidade. Seja corrigindo bugs, adicionando funcionalidades ou aprimorando a documentação, suas contribuições ajudam a tornar o Twenty melhor para todos.
## Ways to Contribute
## Formas de contribuir
* **Report bugs**: Help identify and document issues
* **Submit features**: Propose and implement new functionality
* **Improve documentation**: Make our docs clearer and more helpful
* **Frontend development**: Work on the React-based UI
* **Backend development**: Contribute to the NestJS server
* **Relate bugs**: Ajude a identificar e documentar problemas
* **Envie funcionalidades**: Proponha e implemente novas funcionalidades
* **Aprimore a documentação**: Torne nossa documentação mais clara e útil
* **Desenvolvimento de front-end**: Trabalhe na UI baseada em React
* **Desenvolvimento de back-end**: Contribua para o servidor NestJS
## Getting Started
## Primeiros passos
<CardGroup cols={2}>
<Card title="Bug Reports & Requests" icon="bug" href="/l/pt/developers/contribute/capabilities/bug-and-requests">
Report issues or request features
<Card title="Relatos de bugs e solicitações" icon="bug" href="/l/pt/developers/contribute/capabilities/bug-and-requests">
Relate problemas ou solicite funcionalidades
</Card>
<Card title="Frontend Development" icon="browser" href="/l/pt/developers/contribute/capabilities/frontend-development">
Contribute to the UI
<Card title="Desenvolvimento Frontend" icon="browser" href="/l/pt/developers/contribute/capabilities/frontend-development">
Contribua para a UI
</Card>
</CardGroup>
@@ -1,147 +1,147 @@
---
title: APIs
description: Query and modify your CRM data programmatically using REST or GraphQL.
description: Consulte e modifique seus dados de CRM programaticamente usando REST ou GraphQL.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
Twenty was built to be developer-friendly, offering powerful APIs that adapt to your custom data model. We provide four distinct API types to meet different integration needs.
O Twenty foi desenvolvido para ser amigável ao desenvolvedor, oferecendo APIs poderosas que se adaptam ao seu modelo de dados personalizado. Oferecemos quatro tipos distintos de API para atender diferentes necessidades de integração.
## Developer-First Approach
## Abordagem Focada no Desenvolvedor
Twenty generates APIs specifically for your data model:
Twenty gera APIs especificamente para o seu modelo de dados:
* **No long IDs required**: Use your object and field names directly in endpoints
* **Standard and custom objects treated equally**: Your custom objects get the same API treatment as built-in ones
* **Dedicated endpoints**: Each object and field gets its own API endpoint
* **Custom documentation**: Generated specifically for your workspace's data model
* **Nenhum ID longo necessário**: Use os nomes dos seus objetos e campos diretamente nas endpoints
* **Objetos padrão e personalizados tratados igualmente**: Seus objetos personalizados recebem o mesmo tratamento de API que os incorporados
* **Endpoints dedicados**: Cada objeto e campo tem seu próprio endpoint de API
* **Documentação personalizada**: Gerada especificamente para o modelo de dados do seu workspace
<Note>
Your personalized API documentation is available under **Settings → API & Webhooks** after creating an API key. Since Twenty generates APIs that match your custom data model, the documentation is unique to your workspace.
Sua documentação de API personalizada fica disponível em **Configurações → API & Webhooks** após criar uma chave de API. Como o Twenty gera APIs que correspondem ao seu modelo de dados personalizado, a documentação é exclusiva do seu workspace.
</Note>
## The Two API Types
## Os dois tipos de API
### Core API
Accessed on `/rest/` or `/graphql/`
Acessada em `/rest/` ou `/graphql/`
Work with your actual **records** (the data):
Trabalhe com seus **registros** (os dados):
* Create, read, update, delete People, Companies, Opportunities, etc.
* Query and filter data
* Manage record relationships
* Criar, ler, atualizar e excluir Pessoas, Empresas, Oportunidades, etc.
* Consultar e filtrar dados
* Gerenciar relações de registros
### Metadata API
Accessed on `/rest/metadata/` or `/metadata/`
Acessada em `/rest/metadata/` ou `/metadata/`
Manage your **workspace and data model**:
Gerencie seu **workspace e modelo de dados**:
* Create, modify, or delete objects and fields
* Configure workspace settings
* Define relationships between objects
* Criar, modificar ou excluir objetos e campos
* Configurar as configurações do workspace
* Defina relacionamentos entre objetos
## REST vs GraphQL
Both Core and Metadata APIs are available in REST and GraphQL formats:
As APIs Core e Metadata estão disponíveis nos formatos REST e GraphQL:
| Format | Available Operations |
| ----------- | ---------------------------------------------------------- |
| **REST** | CRUD, batch operations, upserts |
| **GraphQL** | Same + **batch upserts**, relationship queries in one call |
| Formato | Operações disponíveis |
| ----------- | --------------------------------------------------------------------------------- |
| **REST** | CRUD, operações em lote, upserts |
| **GraphQL** | Os mesmos + **upserts em lote**, consultas de relacionamento em uma única chamada |
Choose based on your needs — both formats access the same data.
Escolha com base nas suas necessidades — ambos os formatos acessam os mesmos dados.
## API Endpoints
## Endpoints de API
| Environment | Base URL |
| --------------- | ------------------------- |
| **Cloud** | `https://api.twenty.com/` |
| **Self-Hosted** | `https://{your-domain}/` |
| Ambiente | URL base |
| ------------------ | ------------------------- |
| **Nuvem** | `https://api.twenty.com/` |
| **Auto-hospedado** | `https://{your-domain}/` |
## Authentication
## Autenticação
Every API request requires an API key in the header:
Toda solicitação de API requer uma chave de API no cabeçalho:
```
Authorization: Bearer YOUR_API_KEY
```
### Create an API Key
### Criar uma Chave de API
1. Go to **Settings → APIs & Webhooks**
2. Click **+ Create key**
3. Configure:
* **Name**: Descriptive name for the key
* **Expiration Date**: When the key expires
4. Click **Save**
5. **Copy immediately** — the key is only shown once
1. Vá para **Configurações → APIs & Webhooks**
2. Clique em **+ Criar chave**
3. Configurar:
* **Nome**: Nome descritivo para a chave
* **Data de expiração**: Quando a chave expira
4. Clique em **Salvar**
5. **Copie imediatamente** — a chave é exibida apenas uma vez
<VimeoEmbed videoId="928786722" title="Creating API key" />
<VimeoEmbed videoId="928786722" title="Criando chave de API" />
<Warning>
Your API key grants access to sensitive data. Don't share it with untrusted services. If compromised, disable it immediately and generate a new one.
Sua chave de API concede acesso a dados confidenciais. Não a compartilhe com serviços não confiáveis. Se for comprometida, desative-a imediatamente e gere uma nova.
</Warning>
### Assign a Role to an API Key
### Atribuir uma função a uma chave de API
For better security, assign a specific role to limit access:
Para maior segurança, atribua uma função específica para limitar o acesso:
1. Go to **Settings → Roles**
2. Click on the role to assign
3. Open the **Assignment** tab
4. Under **API Keys**, click **+ Assign to API key**
5. Select the API key
1. Vá para **Configurações → Funções**
2. Clique na função que deseja atribuir
3. Abra a aba de **Atribuição**
4. Em **Chaves de API**, clique em **+ Atribuir à chave de API**
5. Selecione a chave de API
The key will inherit that role's permissions. See [Permissions](/l/pt/user-guide/permissions-access/capabilities/permissions) for details.
A chave herdará as permissões dessa função. Veja [Permissões](/l/pt/user-guide/permissions-access/capabilities/permissions) para obter detalhes.
### Manage API Keys
### Gerenciar Chaves de API
**Regenerate**: Settings → APIs & Webhooks → Click key → **Regenerate**
**Regenerar**: Configurações → APIs & Webhooks → Clique na chave → **Regenerar**
**Delete**: Settings → APIs & Webhooks → Click key → **Delete**
**Excluir**: Configurações → APIs & Webhooks → Clique na chave → **Excluir**
## API Playground
## Playground de API
Test your APIs directly in the browser with our built-in playground — available for both **REST** and **GraphQL**.
Teste suas APIs diretamente no navegador com nosso playground integrado — disponível tanto para **REST** quanto para **GraphQL**.
### Access the Playground
### Acesse o Playground
1. Go to **Settings → APIs & Webhooks**
2. Create an API key (required)
3. Click on **REST API** or **GraphQL API** to open the playground
1. Vá para **Configurações → APIs & Webhooks**
2. Crie uma chave de API (obrigatório)
3. Clique em **REST API** ou **GraphQL API** para abrir o playground
### What You Get
### O que você obtém
* **Interactive documentation**: Generated for your specific data model
* **Live testing**: Execute real API calls against your workspace
* **Schema explorer**: Browse available objects, fields, and relationships
* **Request builder**: Construct queries with autocomplete
* **Documentação interativa**: Gerada para o seu modelo de dados específico
* **Testes ao vivo**: Execute chamadas de API reais no seu workspace
* **Explorador de esquema**: Navegue pelos objetos, campos e relacionamentos disponíveis
* **Construtor de solicitações**: Construa consultas com preenchimento automático
The playground reflects your custom objects and fields, so documentation is always accurate for your workspace.
O playground reflete seus objetos e campos personalizados, portanto, a documentação está sempre precisa para o seu workspace.
## Batch Operations
## Operações em Lote
Both REST and GraphQL support batch operations:
Tanto REST quanto GraphQL suportam operações em lote:
* **Batch size**: Up to 60 records per request
* **Operations**: Create, update, delete multiple records
* **Tamanho do lote**: Até 60 registros por requisição
* **Operações**: Criar, atualizar e excluir vários registros
**GraphQL-only features:**
**Recursos exclusivos do GraphQL:**
* **Batch Upsert**: Create or update in one call
* Use plural object names (e.g., `CreateCompanies` instead of `CreateCompany`)
* **Upsert em lote**: Criar ou atualizar em uma única chamada
* Use nomes de objetos no plural (por exemplo, `CreateCompanies` em vez de `CreateCompany`)
## Rate Limits
## Limites de taxa
API requests are throttled to ensure platform stability:
As solicitações de API são limitadas para garantir a estabilidade da plataforma:
| Limit | Value |
| -------------- | -------------------- |
| **Requests** | 100 calls per minute |
| **Batch size** | 60 records per call |
| Limite | Valor |
| ------------------- | ------------------------ |
| **Solicitações** | 100 chamadas por minuto |
| **Tamanho do lote** | 60 registros por chamada |
<Tip>
Use batch operations to maximize throughput — process up to 60 records in a single API call instead of making individual requests.
Use operações em lote para maximizar a taxa de transferência — processe até 60 registros em uma única chamada de API em vez de fazer solicitações individuais.
</Tip>
@@ -1,81 +1,88 @@
---
title: Twenty Apps
description: Build and manage Twenty customizations as code.
title: Aplicativos Twenty
description: Crie e gerencie personalizações do Twenty como código.
---
<Warning>
Apps are currently in alpha testing. The feature is functional but still evolving.
Os aplicativos estão atualmente em testes alfa. O recurso é funcional, mas ainda está evoluindo.
</Warning>
## What Are Apps?
## O que são aplicativos?
Apps let you build and manage Twenty customizations **as code**. Instead of configuring everything through the UI, you define your data model and serverless functions in code — making it faster to build, maintain, and roll out to multiple workspaces.
Os aplicativos permitem criar e gerenciar personalizações do Twenty **como código**. Em vez de configurar tudo pela UI, você define seu modelo de dados e funções serverless em código — tornando mais rápido criar, manter e distribuir para vários espaços de trabalho.
**What you can do today:**
**O que você pode fazer hoje:**
* Define custom objects and fields as code (managed data model)
* Build serverless functions with custom triggers
* Deploy the same app across multiple workspaces
* Defina objetos e campos personalizados como código (modelo de dados gerenciado)
* Crie funções serverless com gatilhos personalizados
* Implemente o mesmo aplicativo em vários espaços de trabalho
**Coming soon:**
**Em breve:**
* Custom UI layouts and components
* Layouts e componentes de UI personalizados
## Prerequisites
## Pré-requisitos
* Node.js 24+ and Yarn 4
* A Twenty workspace and an API key (create one at https://app.twenty.com/settings/api-webhooks)
* Node.js 24+ e Yarn 4
* Um espaço de trabalho do Twenty e uma chave de API (crie uma em https://app.twenty.com/settings/api-webhooks)
## Getting Started
## Primeiros passos
Create a new app using the official scaffolder, then authenticate and start developing:
Crie um novo aplicativo usando o gerador oficial, depois autentique-se e comece a desenvolver:
```bash filename="Terminal"
# Scaffold a new app
# Criar a estrutura de um novo app
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
# Authenticate using your API key (you'll be prompted)
yarn auth
# Se você não usa yarn@4
corepack enable
yarn install
# Start dev mode: automatically syncs local changes to your workspace
yarn dev
# Autentique-se usando sua chave de API (você será solicitado)
yarn auth:login
# Iniciar modo de desenvolvimento: sincroniza automaticamente as alterações locais com seu workspace
yarn app:dev
```
From here you can:
A partir daqui você pode:
```bash filename="Terminal"
# Add a new entity to your application (guided)
yarn create-entity
# Adicionar uma nova entidade à sua aplicação (assistido)
yarn app:create-entity
# Generate a typed Twenty client and workspace entity types
yarn generate
# Gerar um cliente Twenty tipado e tipos de entidades do espaço de trabalho
yarn app:generate
# Run a onetime sync (instead of watch mode)
yarn sync
# Executar uma sincronização única (em vez do modo de monitoramento)
yarn app:sync
# Watch your application's functions logs
yarn logs
# Acompanhar os logs das funções da sua aplicação
yarn function:logs
# Uninstall the application from the current workspace
yarn uninstall
# Executar uma função pelo nome
yarn function:execute -n my-function -p '{"name": "test"}'
# Display commands' help
yarn help
# Desinstalar a aplicação do espaço de trabalho atual
yarn app:uninstall
# Exibir a ajuda dos comandos
yarn app:help
```
See also: the CLI reference pages for [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) and [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
Veja também: as páginas de referência da CLI para [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) e [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
## Project structure (scaffolded)
## Estrutura do projeto (com scaffold)
When you run `npx create-twenty-app@latest my-twenty-app`, the scaffolder:
Ao executar `npx create-twenty-app@latest my-twenty-app`, o gerador:
* Copies a minimal base application into `my-twenty-app/`
* Adds a local `twenty-sdk` dependency and Yarn 4 configuration
* Creates config files and scripts wired to the `twenty` CLI
* Generates a default application config and a default function role
* Copia um aplicativo base mínimo para `my-twenty-app/`
* Adiciona uma dependência local `twenty-sdk` e a configuração do Yarn 4
* Cria arquivos de configuração e scripts conectados à CLI `twenty`
* Gera uma configuração de aplicativo padrão e um papel padrão para as funções
A freshly scaffolded app looks like this:
Um aplicativo recém-criado pelo scaffold fica assim:
```text filename="my-twenty-app/"
my-twenty-app/
@@ -85,79 +92,144 @@ my-twenty-app/
.nvmrc
.yarnrc.yml
.yarn/
releases/
yarn-4.9.2.cjs
install-state.gz
eslint.config.mjs
tsconfig.json
README.md
src/
application.config.ts
role.config.ts
// your entities, actions, and other app files
app/
application.config.ts # Required - main application configuration
default-function.role.ts # Default role for serverless functions
// your entities (*.object.ts, *.function.ts, *.role.ts)
utils/ # Optional - handler implementations & utilities
```
At a high level:
### Convenção sobre configuração
* **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus scripts like `dev`, `sync`, `generate`, `create-entity`, `logs`, `uninstall`, and `auth` that delegate to the local `twenty` CLI.
* **.gitignore**: Ignores common artifacts such as `node_modules`, `.yarn`, `generated/` (typed client), `dist/`, `build/`, coverage folders, log files, and `.env*` files.
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Lock and configure the Yarn 4 toolchain used by the project.
* **.nvmrc**: Pins the Node.js version expected by the project.
* **eslint.config.mjs** and **tsconfig.json**: Provide linting and TypeScript configuration for your apps TypeScript sources.
* **README.md**: A short README in the app root with basic instructions.
* **src/**: The main place where you define your application-as-code:
* `application.config.ts`: Global configuration for your app (metadata and runtime wiring). See “Application config” below.
* `role.config.ts`: Default function role used by your serverless functions. See “Default function role” below.
* Future entities, actions/functions, and any supporting code you add.
Os aplicativos usam uma abordagem de **convenção sobre configuração** em que as entidades são detectadas pelo sufixo do arquivo. Isso permite organização flexível dentro da pasta `src/app/`:
Later commands will add more files and folders:
| Sufixo de arquivo | Tipo de entidade |
| ----------------- | ------------------------------------ |
| `*.object.ts` | Definições de objetos personalizados |
| `*.function.ts` | Definições de funções serverless |
| `*.role.ts` | Definições de papéis |
* `yarn generate` will create a `generated/` folder (typed Twenty client + workspace types).
* `yarn create-entity` will add entity definition files under `src/` for your custom objects.
### Organizações de pastas suportadas
## Authentication
Você pode organizar suas entidades em qualquer um destes padrões:
The first time you run `yarn auth`, you'll be prompted for:
**Tradicional (por tipo):**
* API URL (defaults to http://localhost:3000 or your current workspace profile)
* API key
```text
src/app/
├── application.config.ts
├── objects/
│ └── postCard.object.ts
├── functions/
│ └── createPostCard.function.ts
└── roles/
└── admin.role.ts
```
Your credentials are stored per-user in `~/.twenty/config.json`. You can maintain multiple profiles and switch using `--workspace <name>`.
**Baseada em funcionalidades:**
Examples:
```text
src/app/
├── application.config.ts
└── post-card/
├── postCard.object.ts
├── createPostCard.function.ts
└── postCardAdmin.role.ts
```
**Plana:**
```text
src/app/
├── application.config.ts
├── postCard.object.ts
├── createPostCard.function.ts
└── admin.role.ts
```
Em alto nível:
* **package.json**: Declara o nome do app, versão, engines (Node 24+, Yarn 4), e adiciona `twenty-sdk` além de scripts como `dev`, `sync`, `generate`, `create-entity`, `logs`, `uninstall` e `auth` que delegam para a CLI `twenty` local.
* **.gitignore**: Ignora artefatos comuns como `node_modules`, `.yarn`, `generated/` (cliente tipado), `dist/`, `build/`, pastas de cobertura, arquivos de log e arquivos `.env*`.
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Bloqueiam e configuram a ferramenta Yarn 4 usada pelo projeto.
* **.nvmrc**: Fixa a versão do Node.js esperada pelo projeto.
* **eslint.config.mjs** e **tsconfig.json**: Fornecem lint e configuração do TypeScript para os fontes TypeScript do seu aplicativo.
* **README.md**: Um README curto na raiz do aplicativo com instruções básicas.
* **src/app/**: O local principal onde você define seu aplicativo como código:
* `application.config.ts`: Configuração global do seu aplicativo (metadados e conexões de execução). Veja "Configuração do aplicativo" abaixo.
* `*.role.ts`: Definições de papéis usados pelas suas funções serverless. Veja "Papel de função padrão" abaixo.
* `*.object.ts`: Definições de objetos personalizados.
* `*.function.ts`: Definições de funções serverless.
* **src/utils/**: Pasta opcional para implementações de handlers e utilitários.
Comandos posteriores adicionarão mais arquivos e pastas:
* `yarn app:generate` criará uma pasta `generated/` (cliente tipado do Twenty + tipos do workspace).
* `yarn app:create-entity` adicionará arquivos de definição de entidades em `src/app/` para seus objetos, funções ou papéis personalizados.
l
## Autenticação
Na primeira vez que você executar `yarn auth:login`, será solicitado o seguinte:
* URL da API (padrão: http://localhost:3000 ou o perfil do seu espaço de trabalho atual)
* Chave de API
Suas credenciais são armazenadas por usuário em `~/.twenty/config.json`. Você pode manter vários perfis e alternar entre eles.
### Gerenciando espaços de trabalho
```bash filename="Terminal"
# Login interactively (recommended)
yarn auth
# Fazer login interativamente (recomendado)
yarn auth:login
# Use a specific workspace profile
yarn auth --workspace my-custom-workspace
# Fazer login em um perfil de espaço de trabalho específico
yarn auth:login --workspace my-custom-workspace
# Listar todos os espaços de trabalho configurados
yarn auth:list
# Alterar o espaço de trabalho padrão (interativo)
yarn auth:switch
# Alternar para um espaço de trabalho específico
yarn auth:switch production
# Verificar o status atual da autenticação
yarn auth:status
```
## Use the SDK resources (types & config)
Depois que você alternar os espaços de trabalho com `auth:switch`, todos os comandos subsequentes usarão esse espaço de trabalho por padrão. Você ainda pode substituí-lo temporariamente com `--workspace <name>`.
The twenty-sdk provides typed building blocks you use inside your app. Below are the key pieces you'll touch most often.
## Use os recursos do SDK (tipos e configuração)
### Defining objects
O twenty-sdk fornece blocos de construção tipados e funções utilitárias que você usa dentro do seu aplicativo. A seguir estão as partes principais que você usará com mais frequência.
Custom objects are regular TypeScript classes annotated with decorators from `twenty-sdk`. They live under `src/objects/` in your app and describe both schema and behavior for records in your workspace.
### Funções utilitárias
Here is an example `postCard` object from the Hello World app:
O SDK fornece quatro funções utilitárias com validação integrada para definir as entidades do seu aplicativo:
| Função | Finalidade |
| ------------------ | ------------------------------------------------- |
| `defineApp()` | Configura os metadados do aplicativo |
| `defineObject()` | Define objetos personalizados com campos |
| `defineFunction()` | Define funções serverless com handlers |
| `defineRole()` | Configura permissões de papéis e acesso a objetos |
Essas funções validam sua configuração em tempo de execução e oferecem melhor autocompletar na IDE e segurança de tipos.
### Definindo objetos
Objetos personalizados descrevem tanto o esquema quanto o comportamento de registros no seu espaço de trabalho. Use `defineObject()` para definir objetos com validação integrada:
```typescript
import { type Note } from '../../generated';
import {
type AddressField,
Field,
FieldType,
type FullNameField,
Object,
OnDeleteAction,
Relation,
RelationType,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
} from 'twenty-sdk';
// src/app/postCard.object.ts
import { defineObject, FieldType } from 'twenty-sdk';
enum PostCardStatus {
DRAFT = 'DRAFT',
@@ -166,176 +238,186 @@ enum PostCardStatus {
RETURNED = 'RETURNED',
}
@Object({
export default defineObject({
universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
nameSingular: 'postCard',
namePlural: 'postCards',
labelSingular: 'Post card',
labelPlural: 'Post cards',
description: ' A post card object',
labelSingular: 'Post Card',
labelPlural: 'Post Cards',
description: 'A post card object',
icon: 'IconMail',
})
export class PostCard {
@Field({
universalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b',
type: FieldType.TEXT,
label: 'Content',
description: "Postcard's content",
icon: 'IconAbc',
})
content: string;
@Field({
universalIdentifier: 'c6aa31f3-da76-4ac6-889f-475e226009ac',
type: FieldType.FULL_NAME,
label: 'Recipient name',
icon: 'IconUser',
})
recipientName: FullNameField;
@Field({
universalIdentifier: '95045777-a0ad-49ec-98f9-22f9fc0c8266',
type: FieldType.ADDRESS,
label: 'Recipient address',
icon: 'IconHome',
})
recipientAddress: AddressField;
@Field({
universalIdentifier: '87b675b8-dd8c-4448-b4ca-20e5a2234a1e',
type: FieldType.SELECT,
label: 'Status',
icon: 'IconSend',
defaultValue: `'${PostCardStatus.DRAFT}'`,
options: [
{ value: PostCardStatus.DRAFT, label: 'Draft', position: 0, color: 'gray' },
{ value: PostCardStatus.SENT, label: 'Sent', position: 1, color: 'orange' },
{ value: PostCardStatus.DELIVERED, label: 'Delivered', position: 2, color: 'green' },
{ value: PostCardStatus.RETURNED, label: 'Returned', position: 3, color: 'orange' },
],
})
status: PostCardStatus;
@Relation({
universalIdentifier: 'c9e2b4f4-b9ad-4427-9b42-9971b785edfe',
type: RelationType.ONE_TO_MANY,
label: 'Notes',
icon: 'IconComment',
inverseSideTargetUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.note,
onDelete: OnDeleteAction.CASCADE,
})
notes: Note[];
@Field({
universalIdentifier: 'e06abe72-5b44-4e7f-93be-afc185a3c433',
type: FieldType.DATE_TIME,
label: 'Delivered at',
icon: 'IconCheck',
isNullable: true,
defaultValue: null,
})
deliveredAt?: Date;
}
fields: [
{
universalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b',
name: 'content',
type: FieldType.TEXT,
label: 'Content',
description: "Postcard's content",
icon: 'IconAbc',
},
{
universalIdentifier: 'c6aa31f3-da76-4ac6-889f-475e226009ac',
name: 'recipientName',
type: FieldType.FULL_NAME,
label: 'Recipient name',
icon: 'IconUser',
},
{
universalIdentifier: '95045777-a0ad-49ec-98f9-22f9fc0c8266',
name: 'recipientAddress',
type: FieldType.ADDRESS,
label: 'Recipient address',
icon: 'IconHome',
},
{
universalIdentifier: '87b675b8-dd8c-4448-b4ca-20e5a2234a1e',
name: 'status',
type: FieldType.SELECT,
label: 'Status',
icon: 'IconSend',
defaultValue: `'${PostCardStatus.DRAFT}'`,
options: [
{ value: PostCardStatus.DRAFT, label: 'Draft', position: 0, color: 'gray' },
{ value: PostCardStatus.SENT, label: 'Sent', position: 1, color: 'orange' },
{ value: PostCardStatus.DELIVERED, label: 'Delivered', position: 2, color: 'green' },
{ value: PostCardStatus.RETURNED, label: 'Returned', position: 3, color: 'orange' },
],
},
{
universalIdentifier: 'e06abe72-5b44-4e7f-93be-afc185a3c433',
name: 'deliveredAt',
type: FieldType.DATE_TIME,
label: 'Delivered at',
icon: 'IconCheck',
isNullable: true,
defaultValue: null,
},
],
});
```
Key points:
Pontos-chave:
* The `@Object` decorator defines the object identity and labels used across the workspace; its `universalIdentifier` must be unique and stable across deployments.
* Each `@Field` decorator defines a field on the object with a type, label, and its own stable `universalIdentifier`.
* `@Relation` wires this object to other objects (standard or custom) and controls cascade behavior with `onDelete`.
* You can scaffold new objects using `yarn create-entity`, which guides you through naming, fields, and relationships, then generates object files similar to the `postCard` example.
* Use `defineObject()` para validação integrada e melhor suporte na IDE.
* O `universalIdentifier` deve ser exclusivo e estável entre implantações.
* Cada campo requer `name`, `type`, `label` e seu próprio `universalIdentifier` estável.
* O array `fields` é opcional — você pode definir objetos sem campos personalizados.
* Você pode criar novos objetos usando `yarn app:create-entity`, que orienta você sobre nomeação, campos e relacionamentos.
### Application config (application.config.ts)
<Note>
**Os campos base são criados automaticamente.** Quando você define um objeto personalizado, o Twenty adiciona automaticamente campos padrão como `name`, `createdAt`, `updatedAt`, `createdBy`, `position` e `deletedAt`. Você não precisa definir esses no seu array `fields` — adicione apenas seus campos personalizados.
</Note>
Every app has a single `application.config.ts` file that describes:
<Accordion title="Alternativa: Sintaxe baseada em decoradores">
Você também pode definir objetos usando decoradores do TypeScript. Essa abordagem usa sintaxe baseada em classe com os decoradores `@Object`, `@Field` e `@Relation`:
* **Who the app is**: identifiers, display name, and description.
* **How its functions run**: which role they use for permissions.
* **(Optional) variables**: keyvalue pairs exposed to your functions as environment variables.
```typescript
import {
type AddressField,
Field,
FieldType,
type FullNameField,
Object,
OnDeleteAction,
Relation,
RelationType,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
} from 'twenty-sdk';
import { type Note } from '../../generated';
When you scaffold a new app, you start with a minimal config:
@Object({
universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
nameSingular: 'postCard',
namePlural: 'postCards',
labelSingular: 'Post card',
labelPlural: 'Post cards',
description: 'A post card object',
icon: 'IconMail',
})
export class PostCard {
@Field({
universalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b',
type: FieldType.TEXT,
label: 'Content',
description: "Postcard's content",
icon: 'IconAbc',
})
content: string;
@Relation({
universalIdentifier: 'c9e2b4f4-b9ad-4427-9b42-9971b785edfe',
type: RelationType.ONE_TO_MANY,
label: 'Notes',
icon: 'IconComment',
inverseSideTargetUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.note,
onDelete: OnDeleteAction.CASCADE,
})
notes: Note[];
}
```
Observação: A abordagem com decoradores requer `experimentalDecorators` na sua configuração do TypeScript.
</Accordion>
### Configuração do aplicativo (application.config.ts)
Todo aplicativo tem um único arquivo `application.config.ts` que descreve:
* **O que é o aplicativo**: identificadores, nome de exibição e descrição.
* **Como suas funções são executadas**: qual papel usam para permissões.
* **Variáveis (opcional)**: pares chavevalor expostos às suas funções como variáveis de ambiente.
Use `defineApp()` para definir a configuração do seu aplicativo:
```typescript
import { type ApplicationConfig } from 'twenty-sdk';
// src/app/application.config.ts
import { defineApp } from 'twenty-sdk';
import { DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER } from './default-function.role';
const config: ApplicationConfig = {
universalIdentifier: '<generated-app-uuid>',
export default defineApp({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
displayName: 'My Twenty App',
description: 'My first Twenty app',
functionRoleUniversalIdentifier: '<generated-role-uuid>',
};
export default config;
```
You can gradually extend this file as your app grows. For example, you can add an icon and application-scoped variables:
```typescript
import { type ApplicationConfig } from 'twenty-sdk';
const config: ApplicationConfig = {
universalIdentifier: '<your-app-uuid>',
displayName: 'My App',
description: 'What your app does',
icon: 'IconWorld', // Choose an icon by name
icon: 'IconWorld',
applicationVariables: {
DEFAULT_RECIPIENT_NAME: {
universalIdentifier: '<uuid>',
description: 'Default recipient used by functions',
universalIdentifier: '19e94e59-d4fe-4251-8981-b96d0a9f74de',
description: 'Default recipient name for postcards',
value: 'Jane Doe',
isSecret: false,
},
},
functionRoleUniversalIdentifier: '<your-role-uuid>',
};
export default config;
functionRoleUniversalIdentifier: DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER,
});
```
Notes:
Notas:
* `universalIdentifier` fields are deterministic IDs you own; generate them once and keep them stable across syncs.
* `applicationVariables` become environment variables for your functions (for example, `DEFAULT_RECIPIENT_NAME` is available as `process.env.DEFAULT_RECIPIENT_NAME`).
* `functionRoleUniversalIdentifier` must match the role you define in `role.config.ts` (see below).
* `universalIdentifier` são IDs determinísticos que você controla; gere-os uma vez e mantenha-os estáveis entre sincronizações.
* `applicationVariables` tornam-se variáveis de ambiente para suas funções (por exemplo, `DEFAULT_RECIPIENT_NAME` fica disponível como `process.env.DEFAULT_RECIPIENT_NAME`).
* `functionRoleUniversalIdentifier` deve corresponder ao papel que você define no seu arquivo `*.role.ts` (veja abaixo).
#### Roles and permissions
#### Papéis e permissões
Applications can define roles that encapsulate permissions on your workspaces objects and actions. The field `functionRoleUniversalIdentifier` in `application.config.ts` designates the default role used by your apps serverless functions.
Os aplicativos podem definir papéis que encapsulam permissões sobre os objetos e ações do seu espaço de trabalho. O campo `functionRoleUniversalIdentifier` em `application.config.ts` designa o papel padrão usado pelas funções serverless do seu aplicativo.
* The runtime API key injected as `TWENTY_API_KEY` is derived from this default function role.
* The typed client will be restricted to the permissions granted to that role.
* Follow leastprivilege: create a dedicated role with only the permissions your functions need, then reference its universal identifier.
* A chave de API em tempo de execução, injetada como `TWENTY_API_KEY`, é derivada desse papel padrão de função.
* O cliente tipado ficará 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 e, em seguida, faça referência ao seu identificador universal.
##### Default function role (role.config.ts)
##### Papel de função padrão (\*.role.ts)
When you scaffold a new app, the CLI also creates `src/role.config.ts`. This file exports the default role your serverless functions will use at runtime:
Ao criar um novo aplicativo com o scaffold, a CLI também cria um arquivo de papel padrão. Use `defineRole()` para definir papéis com validação integrada:
```typescript
import { PermissionFlag, type RoleConfig } from 'twenty-sdk';
// src/app/default-function.role.ts
import { defineRole, PermissionFlag } from 'twenty-sdk';
export const functionRole: RoleConfig = {
universalIdentifier: '<generated-role-uuid>',
label: 'My Twenty App default function role',
description: 'My Twenty App default function role',
canReadAllObjectRecords: true,
canUpdateAllObjectRecords: true,
canSoftDeleteAllObjectRecords: true,
canDestroyAllObjectRecords: false,
};
```
export const DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER =
'b648f87b-1d26-4961-b974-0908fd991061';
The `universalIdentifier` of this role is automatically wired into `application.config.ts` as `functionRoleUniversalIdentifier`. In other words:
* **role.config.ts** defines what the default function role can do.
* **application.config.ts** points to that role so your functions inherit its permissions.
As you move beyond the initial scaffold, you should tighten this role and make it explicit about what it can access. A more production-ready role might look closer to:
```typescript
import { PermissionFlag, type RoleConfig } from 'twenty-sdk';
export const functionRole: RoleConfig = {
universalIdentifier: '<your-role-uuid>',
export default defineRole({
universalIdentifier: DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER,
label: 'Default function role',
description: 'Default role for function Twenty client',
canReadAllObjectRecords: false,
@@ -363,41 +445,41 @@ export const functionRole: RoleConfig = {
canUpdateFieldValue: false,
},
],
permissionFlags: ['APPLICATIONS'],
};
permissionFlags: [PermissionFlag.APPLICATIONS],
});
```
Notes:
O `universalIdentifier` desse papel é então referenciado em `application.config.ts` como `functionRoleUniversalIdentifier`. Em outras palavras:
* Start from the scaffolded role, then progressively restrict it following leastprivilege.
* Replace the `objectPermissions` and `fieldPermissions` with the objects/fields your functions need.
* `permissionFlags` control access to platform-level capabilities. Keep them minimal; add only what you need.
* See a working example in the Hello World app: [`packages/twenty-apps/hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
* **\*.role.ts** define o que o papel de função padrão pode fazer.
* **application.config.ts** aponta para esse papel para que suas funções herdem suas permissões.
### Serverless function config and entrypoint
Notas:
Each function exports a main handler and a config describing its triggers. You can mix multiple trigger types.
* Comece pelo papel gerado pelo scaffold e depois restrinja-o progressivamente seguindo o princípio do menor privilégio.
* Substitua `objectPermissions` e `fieldPermissions` pelos objetos/campos de que suas funções precisam.
* `permissionFlags` controlam o acesso a recursos em nível de plataforma. Mantenha-os mínimos; adicione apenas o que for necessário.
* Veja um exemplo funcional no app Hello World: [`packages/twenty-apps/hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
### Configuração de função serverless e ponto de entrada
Cada arquivo de função usa `defineFunction()` para exportar uma configuração com um handler e gatilhos opcionais. Use o sufixo de arquivo `*.function.ts` para detecção automática.
```typescript
// src/actions/create-new-post-card.ts
import type {
FunctionConfig,
DatabaseEventPayload,
ObjectRecordCreateEvent,
CronPayload,
} from 'twenty-sdk';
import Twenty, { type Person } from '../generated';
// src/app/createPostCard.function.ts
import { defineFunction } from 'twenty-sdk';
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk';
import Twenty, { type Person } from '../../generated';
// main handler can accept parameters from route, cron, or database events
export const main = async (
const handler = async (
params:
| { name?: string }
| RoutePayload
| DatabaseEventPayload<ObjectRecordCreateEvent<Person>>
| CronPayload,
) => {
const client = new Twenty(); // generated typed client
const name = 'name' in params
? params.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world'
const name = 'name' in params.queryStringParameters
? params.queryStringParameters.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world'
: 'Hello world';
const result = await client.mutation({
@@ -410,14 +492,15 @@ export const main = async (
return result;
};
export const config: FunctionConfig = {
universalIdentifier: '<function-uuid>',
export default defineFunction({
universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
name: 'create-new-post-card',
timeoutSeconds: 2,
handler,
triggers: [
// Public HTTP route trigger '/s/post-card/create'
{
universalIdentifier: '<route-trigger-uuid>',
universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
type: 'route',
path: '/post-card/create',
httpMethod: 'GET',
@@ -425,39 +508,137 @@ export const config: FunctionConfig = {
},
// Cron trigger (CRON pattern)
{
universalIdentifier: '<cron-trigger-uuid>',
universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2',
type: 'cron',
pattern: '0 0 1 1 *',
},
// Database event trigger
{
universalIdentifier: '<db-trigger-uuid>',
universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156',
type: 'databaseEvent',
eventName: 'person.created',
eventName: 'person.updated',
updatedFields: ['name'],
},
],
});
```
Tipos de gatilho comuns:
* **route**: Expõe sua função em um caminho e método HTTP **no endpoint `/s/`**:
> por exemplo, `path: '/post-card/create',` -> chamar em `<APP_URL>/s/post-card/create`
* **cron**: Executa sua função em um agendamento usando uma expressão CRON.
* **databaseEvent**: Executa em eventos do ciclo de vida de objetos do espaço de trabalho. Quando a operação do evento é `updated`, campos específicos a serem observados podem ser especificados no array `updatedFields`. Se deixar indefinido ou vazio, qualquer atualização acionará a função.
> por exemplo, `person.updated`
Notas:
* O array `triggers` é opcional. Funções sem gatilhos podem ser usadas como funções utilitárias chamadas por outras funções.
* Você pode misturar vários tipos de gatilho em uma única função.
### Payload de gatilho de rota
<Warning>
**Alteração incompatível (v1.16, janeiro de 2026):** O formato do payload de gatilho de rota mudou. Antes da v1.16, os parâmetros de consulta, parâmetros de caminho e corpo eram enviados diretamente como o payload. A partir da v1.16, eles ficam aninhados dentro de um objeto estruturado `RoutePayload`.
**Antes da v1.16:**
```typescript
const handler = async (params) => {
const { param1, param2 } = params; // Direct access
};
```
**Depois da v1.16:**
```typescript
const handler = async (event: RoutePayload) => {
const { param1, param2 } = event.body; // Access via .body
const { queryParam } = event.queryStringParameters;
const { id } = event.pathParameters;
};
```
**Para migrar funções existentes:** Atualize seu handler para desestruturar de `event.body`, `event.queryStringParameters` ou `event.pathParameters` em vez de diretamente do objeto de parâmetros.
</Warning>
Quando um gatilho de rota invoca sua função, ela recebe um objeto `RoutePayload` que segue o formato do AWS HTTP API v2. Importe o tipo de `twenty-sdk`:
```typescript
import { defineFunction, type RoutePayload } from 'twenty-sdk';
const handler = async (event: RoutePayload) => {
// Access request data
const { headers, queryStringParameters, pathParameters, body } = event;
// HTTP method and path are available in requestContext
const { method, path } = event.requestContext.http;
return { message: 'Success' };
};
```
Common trigger types:
O tipo `RoutePayload` tem a seguinte estrutura:
* route: Exposes your function on an HTTP path and method **under the `/s/` endpoint**:
| Propriedade | Tipo | Descrição |
| ---------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `headers` | `Record<string, string \| undefined>` | Cabeçalhos HTTP (apenas aqueles listados em `forwardedRequestHeaders`) |
| `queryStringParameters` | `Record<string, string \| undefined>` | Parâmetros de query string (valores múltiplos unidos por vírgulas) |
| `pathParameters` | `Record<string, string \| undefined>` | Parâmetros de caminho extraídos do padrão de rota (por exemplo, `/users/:id` → `{ id: '123' }`) |
| `corpo` | `object \| null` | Corpo da requisição analisado (JSON) |
| `isBase64Encoded` | `booleano` | Se o corpo está codificado em base64 |
| `requestContext.http.method` | `string` | Método HTTP (GET, POST, PUT, PATCH, DELETE) |
| `requestContext.http.path` | `string` | Caminho bruto da requisição |
> e.g. `path: '/post-card/create',` -> call on `<APP_URL>/s/post-card/create`
### Encaminhamento de cabeçalhos HTTP
* cron: Runs your function on a schedule using a CRON expression.
* databaseEvent: Runs on workspace object lifecycle events
Por padrão, os cabeçalhos HTTP das requisições recebidas **não** são repassados para sua função serverless por motivos de segurança. Para acessar cabeçalhos específicos, liste-os explicitamente no array `forwardedRequestHeaders`:
> e.g. `person.created`
```typescript
export default defineFunction({
universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
name: 'webhook-handler',
handler,
triggers: [
{
universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
type: 'route',
path: '/webhook',
httpMethod: 'POST',
isAuthRequired: false,
forwardedRequestHeaders: ['x-webhook-signature', 'content-type'],
},
],
});
```
You can create new functions in two ways:
No seu handler, você pode então acessar esses cabeçalhos:
* **Scaffolded**: Run `yarn create-entity --path <custom-path>` and choose the option to add a new function. This generates a starter file under `<custom-path>` with a `main` handler and a `config` block similar to the example above.
* **Manual**: Create a new file and export `main` and `config` yourself, following the same pattern.
```typescript
const handler = async (event: RoutePayload) => {
const signature = event.headers['x-webhook-signature'];
const contentType = event.headers['content-type'];
### Generated typed client
// Validate webhook signature...
return { received: true };
};
```
Run yarn generate to create a local typed client in generated/ based on your workspace schema. Use it in your functions:
<Note>
Os nomes dos cabeçalhos são normalizados para minúsculas. Acesse-os usando chaves em minúsculas (por exemplo, `event.headers['content-type']`).
</Note>
Você pode criar novas funções de duas formas:
* **Gerado automaticamente**: Execute `yarn app:create-entity` e escolha a opção para adicionar uma nova função. Isso gera um arquivo inicial com um handler e configuração.
* **Manual**: Crie um novo arquivo `*.function.ts` e use `defineFunction()`, seguindo o mesmo padrão.
### Cliente tipado gerado
Execute yarn app:generate para criar um cliente tipado local em generated/ com base no esquema do seu workspace. Use-o em suas funções:
```typescript
import Twenty from './generated';
@@ -466,34 +647,34 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
The client is re-generated by `yarn generate`. Re-run after changing your objects and `yarn sync` or when onboarding to a new workspace.
O cliente é regenerado pelo `yarn app:generate`. Execute novamente após alterar seus objetos e executar `yarn app:sync`, ou ao ingressar em um novo workspace.
#### Runtime credentials in serverless functions
#### Credenciais em tempo de execução em funções serverless
When your function runs on Twenty, the platform injects credentials as environment variables before your code executes:
Quando sua função é executada no Twenty, a plataforma injeta credenciais como variáveis de ambiente antes da execução do seu código:
* `TWENTY_API_URL`: Base URL of the Twenty API your app targets.
* `TWENTY_API_KEY`: Shortlived key scoped to your applications default function role.
* `TWENTY_API_URL`: URL base da API do Twenty que seu aplicativo usa como alvo.
* `TWENTY_API_KEY`: Chave de curta duração com escopo para o papel de função padrão do seu aplicativo.
Notes:
Notas:
* You do not need to pass URL or API key to the generated client. It reads `TWENTY_API_URL` and `TWENTY_API_KEY` from process.env at runtime.
* The API keys permissions are determined by the role referenced in your `application.config.ts` via `functionRoleUniversalIdentifier`. This is the default role used by serverless functions of your application.
* Applications can define roles to follow leastprivilege. Grant only the permissions your functions need, then point `functionRoleUniversalIdentifier` to that roles universal identifier.
* Você não precisa passar a URL ou a chave de API para o cliente gerado. Ele lê `TWENTY_API_URL` e `TWENTY_API_KEY` de process.env em tempo de execução.
* As permissões da chave de API são determinadas pelo papel referenciado no seu `application.config.ts` via `functionRoleUniversalIdentifier`. Este é o papel padrão usado pelas funções serverless do seu aplicativo.
* Os aplicativos podem definir papéis para seguir o princípio do menor privilégio. Conceda apenas as permissões de que suas funções precisam e, em seguida, aponte `functionRoleUniversalIdentifier` para o identificador universal desse papel.
### Hello World example
### Exemplo Hello World
Explore a minimal, end-to-end example that demonstrates objects, functions, and multiple triggers [here](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
Explore um exemplo mínimo de ponta a ponta que demonstra objetos, funções e vários gatilhos [aqui](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
## Manual setup (without the scaffolder)
## Configuração manual (sem o gerador)
While we recommend using `create-twenty-app` for the best getting-started experience, you can also set up a project manually. Do not install the CLI globally. Instead, add `twenty-sdk` as a local dependency and wire scripts in your package.json:
Embora recomendemos usar `create-twenty-app` para a melhor experiência inicial, você também pode configurar um projeto manualmente. Não instale a CLI globalmente. Em vez disso, adicione `twenty-sdk` como uma dependência local e conecte scripts no seu package.json:
```bash filename="Terminal"
yarn add -D twenty-sdk
```
Then add scripts like these:
Em seguida, adicione scripts como estes:
```json filename="package.json"
{
@@ -510,13 +691,13 @@ Then add scripts like these:
}
```
Now you can run the same commands via Yarn, e.g. `yarn dev`, `yarn sync`, etc.
Agora você pode executar os mesmos comandos via Yarn, por exemplo, `yarn app:dev`, `yarn app:sync`, etc.
## Troubleshooting
## Resolução de Problemas
* Authentication errors: run `yarn auth` and ensure your API key has the required permissions.
* Cannot connect to server: verify the API URL and that the Twenty server is reachable.
* Types or client missing/outdated: run `yarn generate` and then `yarn dev`.
* Dev mode not syncing: ensure `yarn dev` is running and that changes are not ignored by your environment.
* Erros de autenticação: execute `yarn auth:login` e certifique-se de que sua chave de API tenha as permissões necessárias.
* Não é possível conectar ao servidor: verifique a URL da API e se o servidor do Twenty está acessível.
* Tipos ou cliente ausentes/desatualizados: execute `yarn app:generate` e depois `yarn app:dev`.
* Modo de desenvolvimento não sincronizando: certifique-se de que `yarn app:dev` esteja em execução e de que as alterações não estejam sendo ignoradas pelo seu ambiente.
Discord Help Channel: https://discord.com/channels/1130383047699738754/1130386664812982322
Canal de ajuda no Discord: https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -1,44 +1,44 @@
---
title: Webhooks
description: Receive real-time notifications when events occur in your CRM.
description: Receba notificações em tempo real quando eventos ocorrerem no seu CRM.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
Webhooks push data to your systems in real-time when events occur in Twenty — no polling required. Use them to keep external systems in sync, trigger automations, or send alerts.
Os webhooks enviam dados para seus sistemas em tempo real quando eventos ocorrem no Twenty — sem necessidade de polling. Use-os para manter sistemas externos em sincronia, acionar automações ou enviar alertas.
## Create a Webhook
## Criar Webhook
1. Go to **Settings → APIs & Webhooks → Webhooks**
2. Click **+ Create webhook**
3. Enter your webhook URL (must be publicly accessible)
4. Click **Save**
1. Vá para **Configurações → APIs & Webhooks → Webhooks**
2. Clique em **+ Criar webhook**
3. Insira a URL do seu webhook (deve ser publicamente acessível)
4. Clique em **Salvar**
The webhook activates immediately and starts sending notifications.
O webhook é ativado imediatamente e começa a enviar notificações.
<VimeoEmbed videoId="928786708" title="Creating a webhook" />
<VimeoEmbed videoId="928786708" title="Criando um webhook" />
### Manage Webhooks
### Gerenciar Webhooks
**Edit**: Click the webhook → Update URL → **Save**
**Editar**: Clique no webhook → Atualizar URL → **Salvar**
**Delete**: Click the webhook → **Delete** → Confirm
**Excluir**: Clique no webhook → **Excluir** → Confirmar
## Events
## Eventos
Twenty sends webhooks for these event types:
O Twenty envia webhooks para estes tipos de eventos:
| Event | Example |
| ------------------ | ---------------------------------------------------------- |
| **Record Created** | `person.created`, `company.created`, `note.created` |
| **Record Updated** | `person.updated`, `company.updated`, `opportunity.updated` |
| **Record Deleted** | `person.deleted`, `company.deleted` |
| Evento | Exemplo |
| ----------------------- | ---------------------------------------------------------- |
| **Registro criado** | `person.created`, `company.created`, `note.created` |
| **Registro atualizado** | `person.updated`, `company.updated`, `opportunity.updated` |
| **Registro excluído** | `person.deleted`, `company.deleted` |
All event types are sent to your webhook URL. Event filtering may be added in future releases.
Todos os tipos de evento são enviados para a URL do seu webhook. A filtragem de eventos pode ser adicionada em versões futuras.
## Payload Format
## Formato do payload
Each webhook sends an HTTP POST with a JSON body:
Cada webhook envia um HTTP POST com um corpo JSON:
```json
{
@@ -55,35 +55,35 @@ Each webhook sends an HTTP POST with a JSON body:
}
```
| Field | Description |
| ----------- | ------------------------------------------------ |
| `event` | What happened (e.g., `person.created`) |
| `data` | The full record that was created/updated/deleted |
| `timestamp` | When the event occurred (UTC) |
| Campo | Descrição |
| ------------------- | ------------------------------------------------------ |
| `evento` | O que aconteceu (por exemplo, `person.created`) |
| `data` | O registro completo que foi criado/atualizado/excluído |
| `registro de Tempo` | Quando o evento ocorreu (UTC) |
<Note>
Respond with a **2xx HTTP status** (200-299) to acknowledge receipt. Non-2xx responses are logged as delivery failures.
Responda com um **status HTTP 2xx** (200-299) para confirmar o recebimento. Respostas não 2xx são registradas como falhas de entrega.
</Note>
## Webhook Validation
## Validação de Webhook
Twenty signs each webhook request for security. Validate signatures to ensure requests are authentic.
O Twenty assina cada solicitação de webhook por segurança. Valide as assinaturas para garantir que as solicitações sejam autênticas.
### Headers
| Header | Description |
| ---------------------------- | --------------------- |
| `X-Twenty-Webhook-Signature` | HMAC SHA256 signature |
| `X-Twenty-Webhook-Timestamp` | Request timestamp |
| Cabeçalho | Descrição |
| ---------------------------- | ------------------------ |
| `X-Twenty-Webhook-Signature` | Assinatura HMAC SHA256 |
| `X-Twenty-Webhook-Timestamp` | Timestamp da solicitação |
### Validation Steps
### Etapas de validação
1. Get the timestamp from `X-Twenty-Webhook-Timestamp`
2. Create the string: `{timestamp}:{JSON payload}`
3. Compute HMAC SHA256 using your webhook secret
4. Compare with `X-Twenty-Webhook-Signature`
1. Obtenha o timestamp de `X-Twenty-Webhook-Timestamp`
2. Crie a string: `{timestamp}:{JSON payload}`
3. Calcule o HMAC SHA256 usando o segredo do seu webhook
4. Compare com `X-Twenty-Webhook-Signature`
### Example (Node.js)
### Exemplo (Node.js)
```javascript
const crypto = require("crypto");
@@ -101,12 +101,12 @@ const expectedSignature = crypto
const isValid = expectedSignature === req.headers["x-twenty-webhook-signature"];
```
## Webhooks vs Workflows
## Webhooks vs Fluxos de trabalho
| Method | Direction | Use Case |
| ---------------------------- | --------- | ---------------------------------------------------------- |
| **Webhooks** | OUT | Automatically notify external systems of any record change |
| **Workflow + HTTP Request** | OUT | Send data out with custom logic (filters, transformations) |
| **Workflow Webhook Trigger** | IN | Receive data into Twenty from external systems |
| Método | Direção | Caso de uso |
| ------------------------------------------- | ------- | -------------------------------------------------------------------------------- |
| **Webhooks** | SAÍDA | Notificar automaticamente sistemas externos sobre qualquer alteração de registro |
| **Fluxo de trabalho + Solicitação HTTP** | SAÍDA | Enviar dados para fora com lógica personalizada (filtros, transformações) |
| **Gatilho de webhook de fluxo de trabalho** | ENTRADA | Receber dados no Twenty a partir de sistemas externos |
For receiving external data, see [Set Up a Webhook Trigger](/l/pt/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger).
Para receber dados externos, consulte [Configurar um gatilho de Webhook](/l/pt/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger).
@@ -1,34 +1,34 @@
---
title: Extend
description: Extend Twenty's functionality with APIs, webhooks, and custom apps.
title: Estender
description: Amplie a funcionalidade do Twenty com APIs, webhooks e aplicativos personalizados.
---
<Frame>
<img src="/images/user-guide/integrations/plug.png" alt="AI" />
<img src="/images/user-guide/integrations/plug.png" alt="IA" />
</Frame>
## Overview
## Visão geral
Twenty is designed to be extensible. Use our APIs, webhooks, and app framework to integrate with your existing tools and build custom functionality.
O Twenty foi projetado para ser extensível. Use nossas APIs, webhooks e o framework de aplicativos para integrar-se às suas ferramentas existentes e criar funcionalidades personalizadas.
## What You Can Do
## O que você pode fazer
* **APIs**: Query and modify your CRM data programmatically using REST or GraphQL
* **Webhooks**: Receive real-time notifications when events occur in Twenty
* **Apps**: Build custom applications that extend Twenty's capabilities - Coming soon!
* **APIs**: Consulte e modifique seus dados de CRM programaticamente usando REST ou GraphQL
* **Webhooks**: Receba notificações em tempo real quando eventos ocorrerem no Twenty
* **Apps**: Crie aplicativos personalizados que expandem as capacidades do Twenty - Em breve!
## Getting Started
## Primeiros passos
<CardGroup cols={2}>
<Card title="APIs" icon="code" href="/l/pt/developers/extend/capabilities/apis">
Connect to Twenty programmatically
<Card title="APIs" icon="código" href="/l/pt/developers/extend/capabilities/apis">
Conecte-se ao Twenty programaticamente
</Card>
<Card title="Webhooks" icon="bell" href="/l/pt/developers/extend/capabilities/webhooks">
Get notified of events in real-time
Receba notificações de eventos em tempo real
</Card>
<Card title="Apps" icon="puzzle-piece" href="/l/pt/developers/extend/capabilities/apps">
Build customizations as code (Alpha)
<Card title="Aplicativos" icon="puzzle-piece" href="/l/pt/developers/extend/capabilities/apps">
Crie personalizações como código (Alpha)
</Card>
</CardGroup>
@@ -1,23 +1,23 @@
---
title: Getting Started
description: Welcome to Twenty Developer Documentation, your resources for extending, self-hosting, and contributing to Twenty.
title: Primeiros passos
description: Bem-vindo à Documentação para Desenvolvedores da Twenty, seus recursos para estender, auto-hospedar e contribuir para o Twenty.
---
import { CardTitle } from "/snippets/card-title.mdx"
<CardGroup cols={3}>
<Card href="/l/pt/developers/extend/extend" img="/images/user-guide/integrations/plug.png">
<CardTitle>Extend</CardTitle>
Build integrations with APIs, webhooks, and custom apps.
<CardTitle>Estender</CardTitle>
Crie integrações com APIs, webhooks e aplicativos personalizados.
</Card>
<Card href="/l/pt/developers/self-host/self-host" img="/images/user-guide/what-is-twenty/20.png">
<CardTitle>Self-Host</CardTitle>
Deploy and manage Twenty on your own infrastructure.
<CardTitle>Auto-hospedar</CardTitle>
Implante e gerencie o Twenty na sua própria infraestrutura.
</Card>
<Card href="/l/pt/developers/contribute/contribute" img="/images/user-guide/github/github-header.png">
<CardTitle>Contribute</CardTitle>
Join our open-source community and contribute to Twenty.
<CardTitle>Contribuir</CardTitle>
Junte-se à nossa comunidade de código aberto e contribua para o Twenty.
</Card>
</CardGroup>
@@ -1,45 +1,45 @@
---
title: Other methods
title: Outros métodos
---
<Warning>
This document is maintained by the community. It might contain issues.
Este documento é mantido pela comunidade. Pode conter problemas.
</Warning>
## Kubernetes via Terraform and Manifests
## Kubernetes via Terraform e Manifests
Community-led documentation for Kubernetes deployment is available [here](https://github.com/twentyhq/twenty/tree/main/packages/twenty-docker/k8s)
A documentação liderada pela comunidade para a implantação do Kubernetes está disponível [aqui](https://github.com/twentyhq/twenty/tree/main/packages/twenty-docker/k8s)
### Coolify
Deploy Twenty on servers using Coolify. (official image on Coolify will be available soon)
Implante o Twenty em servidores usando o Coolify. (imagem oficial no Coolify estará disponível em breve)
[Coolify documentation](https://coolify.io/docs/get-started/introduction)
[Documentação Coolify](https://coolify.io/docs/get-started/introduction)
### EasyPanel
Deploy Twenty on EasyPanel with the community maintained template below.
Implante o Twenty no EasyPanel com o modelo mantido pela comunidade abaixo.
[Deploy on EasyPanel](https://easypanel.io/docs/templates/twenty)
[Implante no EasyPanel](https://easypanel.io/docs/templates/twenty)
### Elest.io
Deploy Twenty on servers with Elest.io using link below.
Implante o Twenty em servidores com Elest.io usando o link abaixo.
[Deploy on Elest.io](https://elest.io/open-source/twenty)
[Implante no Elest.io](https://elest.io/open-source/twenty)
### Twenty on Railway
### Twenty no Railway
Deploy Twenty on Railway with the community maintained template below.
Implante o Twenty no Railway com o modelo mantido pela comunidade abaixo.
[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
[![Implante no Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Twenty on Sealos
### Twenty no Sealos
Deploy Twenty on Sealos with the community maintained template below.
Implante o Twenty no Sealos com o modelo mantido pela comunidade abaixo.
[![Deploy on Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
[![Implante no Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## Others
## Outros
Please feel free to Open a PR to add more Cloud Provider options.
Sinta-se à vontade para abrir um PR para adicionar mais opções de Provedor de Nuvem.
@@ -1,253 +1,253 @@
---
title: 1-Click w/ Docker Compose
title: 1-Clique c/ Docker Compose
---
<Warning>
Docker containers are for production hosting or self-hosting, for the contribution please check the [Local Setup](/l/pt/developers/contribute/capabilities/local-setup).
Contêineres Docker são para hospedagem de produção ou auto-hospedagem, para contribuições, por favor, verifique o [Setup Local](/l/pt/developers/contribute/capabilities/local-setup).
</Warning>
## Overview
## Visão geral
This guide provides step-by-step instructions to install and configure the Twenty application using Docker Compose. The aim is to make the process straightforward and prevent common pitfalls that could break your setup.
Este guia fornece instruções passo a passo para instalar e configurar o aplicativo Twenty usando Docker Compose. O objetivo é tornar o processo simples e evitar armadilhas comuns que possam quebrar sua configuração.
**Important:** Only modify settings explicitly mentioned in this guide. Altering other configurations may lead to issues.
**Importante:** Modifique apenas as configurações explicitamente mencionadas neste guia. Alterar outras configurações pode levar a problemas.
See docs [Setup Environment Variables](/l/pt/developers/self-host/capabilities/setup) for advanced configuration. All environment variables must be declared in the docker-compose.yml file at the server and / or worker level depending on the variable.
Veja a documentação [Configurar Variáveis de Ambiente](/l/pt/developers/self-host/capabilities/setup) para configuração avançada. Todas as variáveis de ambiente devem ser declaradas no arquivo docker-compose.yml no nível do servidor e/ou trabalhador, dependendo da variável.
## System Requirements
## Requisitos do Sistema
* RAM: Ensure your environment has at least 2GB of RAM. Insufficient memory can cause processes to crash.
* Docker & Docker Compose: Make sure both are installed and up-to-date.
* RAM: Certifique-se de que seu ambiente tenha pelo menos 2GB de RAM. Memória insuficiente pode causar falhas nos processos.
* Docker & Docker Compose: Certifique-se de que ambos estão instalados e atualizados.
## Option 1: One-line script
## Opção 1: Script de uma linha
Install the latest stable version of Twenty with a single command:
Instale a versão estável mais recente do Twenty com um único comando:
```bash
bash <(curl -sL https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/scripts/install.sh)
```
To install a specific version or branch:
Para instalar uma versão ou branch específica:
```bash
VERSION=vx.y.z BRANCH=branch-name bash <(curl -sL https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/scripts/install.sh)
```
* Replace x.y.z with the desired version number.
* Replace branch-name with the name of the branch you want to install.
* Substitua x.y.z pelo número da versão desejada.
* Substitua branch-name pelo nome da branch que você deseja instalar.
## Option 2: Manual steps
## Opção 2: Etapas manuais
Follow these steps for a manual setup.
Siga estas etapas para uma configuração manual.
### Step 1: Set Up the Environment File
### Etapa 1: Configure o arquivo de ambiente
1. **Create the .env File**
1. **Crie o arquivo .env**
Copy the example environment file to a new .env file in your working directory:
Copie o exemplo de arquivo de ambiente para um novo arquivo .env no seu diretório de trabalho:
```bash
curl -o .env https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-docker/.env.example
```
2. **Generate Secret Tokens**
2. **Gere Tokens Secretos**
Run the following command to generate a unique random string:
Execute o seguinte comando para gerar uma string aleatória única:
```bash
openssl rand -base64 32
```
**Important:** Keep this value secret / do not share it.
**Importante:** Mantenha este valor em segredo / não o compartilhe.
3. **Update the `.env`**
3. **Atualize o `.env`**
Replace the placeholder value in your .env file with the generated token:
Substitua o valor do espaço reservado no seu arquivo .env pelo token gerado:
```ini
APP_SECRET=first_random_string
```
4. **Set the Postgres Password**
4. **Defina a Senha do Postgres**
Update the `PG_DATABASE_PASSWORD` value in the .env file with a strong password without special characters.
Atualize o valor `PG_DATABASE_PASSWORD` no arquivo .env com uma senha forte sem caracteres especiais.
```ini
PG_DATABASE_PASSWORD=my_strong_password
```
### Step 2: Obtain the Docker Compose File
### Etapa 2: Obtenha o arquivo Docker Compose
Download the `docker-compose.yml` file to your working directory:
Baixe o arquivo `docker-compose.yml` para o seu diretório de trabalho:
```bash
curl -o docker-compose.yml https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-docker/docker-compose.yml
```
### Step 3: Launch the Application
### Etapa 3: Inicie o Aplicativo
Start the Docker containers:
Inicie os contêineres Docker:
```bash
docker compose up -d
```
### Step 4: Access the Application
### Etapa 4: Acesse o Aplicativo
If you host twentyCRM on your own computer, open your browser and navigate to [http://localhost:3000](http://localhost:3000).
Se você hospedar o twentyCRM no seu próprio computador, abra o navegador e acesse [http://localhost:3000](http://localhost:3000).
If you host it on a server, check that the server is running and that everything is ok with
Se você hospedar em um servidor, verifique se o servidor está em execução e se está tudo ok com
```bash
curl http://localhost:3000
```
## Configuration
## Configuração
### Expose Twenty to External Access
### Expor o Twenty para Acesso Externo
By default, Twenty runs on `localhost` at port `3000`. To access it via an external domain or IP address, you need to configure the `SERVER_URL` in your `.env` file.
Por padrão, o Twenty é executado em `localhost` na porta `3000`. Para acessá-lo via um domínio externo ou endereço IP, você precisa configurar o `SERVER_URL` no seu arquivo `.env`.
#### Understanding `SERVER_URL`
#### Compreendendo `SERVER_URL`
* **Protocol:** Use `http` or `https` depending on your setup.
* Use `http` if you haven't set up SSL.
* Use `https` if you have SSL configured.
* **Domain/IP:** This is the domain name or IP address where your application is accessible.
* **Port:** Include the port number if you're not using the default ports (`80` for `http`, `443` for `https`).
* **Protocolo:** Use `http` ou `https` dependendo da sua configuração.
* Use `http` se você não configurou SSL.
* Use `https` se você tiver SSL configurado.
* **Domínio/IP:** Este é o nome de domínio ou endereço IP onde seu aplicativo está acessível.
* **Porta:** Inclua o número da porta se você não estiver usando as portas padrão (`80` para `http`, `443` para `https`).
### SSL Requirements
### Requisitos de SSL
SSL (HTTPS) is required for certain browser features to work properly. While these features might work during local development (as browsers treat localhost differently), a proper SSL setup is needed when hosting Twenty on a regular domain.
SSL (HTTPS) é necessário para que certos recursos do navegador funcionem corretamente. Embora esses recursos possam funcionar durante o desenvolvimento local (já que os navegadores tratam o localhost de modo diferente), é necessária uma configuração adequada de SSL ao hospedar o Twenty em um domínio normal.
For example, the clipboard API might require a secure context - some features like copy buttons throughout the application might not work without HTTPS enabled.
Por exemplo, a API da área de transferência pode exigir um contexto seguro - alguns recursos, como botões de cópia através do aplicativo, podem não funcionar sem HTTPS ativado.
We strongly recommend setting up Twenty behind a reverse proxy with SSL termination for optimal security and functionality.
Recomendamos fortemente configurar o Twenty atrás de um proxy reverso com terminação SSL para segurança e funcionalidade ótimas.
#### Configuring `SERVER_URL`
#### Configurando `SERVER_URL`
1. **Determine Your Access URL**
* **Without Reverse Proxy (Direct Access):**
1. **Determine sua URL de Acesso**
* **Sem Proxy Reverso (Acesso Direto):**
If you're accessing the application directly without a reverse proxy:
Se você estiver acessando o aplicativo diretamente sem um proxy reverso:
```ini
SERVER_URL=http://your-domain-or-ip:3000
```
* **With Reverse Proxy (Standard Ports):**
* **Com Proxy Reverso (Portas Padrão):**
If you're using a reverse proxy like Nginx or Traefik and have SSL configured:
Se você estiver usando um proxy reverso como Nginx ou Traefik e tiver SSL configurado:
```ini
SERVER_URL=https://your-domain-or-ip
```
* **With Reverse Proxy (Custom Ports):**
* **Com Proxy Reverso (Portas Customizadas):**
If you're using non-standard ports:
Se você estiver usando portas não-padrão:
```ini
SERVER_URL=https://your-domain-or-ip:custom-port
```
2. **Update the `.env` File**
2. **Atualize o arquivo `.env`**
Open your `.env` file and update the `SERVER_URL`:
Abra seu arquivo `.env` e atualize o `SERVER_URL`:
```ini
SERVER_URL=http(s)://your-domain-or-ip:your-port
```
**Examples:**
**Exemplos:**
* Direct access without SSL:
* Acesso direto sem SSL:
```ini
SERVER_URL=http://123.45.67.89:3000
```
* Access via domain with SSL:
* Acesso via domínio com SSL:
```ini
SERVER_URL=https://mytwentyapp.com
```
3. **Restart the Application**
3. **Reinicie o Aplicativo**
For changes to take effect, restart the Docker containers:
Para que as alterações entrem em vigor, reinicie os contêineres Docker:
```bash
docker compose down
docker compose up -d
```
#### Considerations
#### Considerações
* **Reverse Proxy Configuration:**
* **Configuração de Proxy Reverso:**
Ensure your reverse proxy forwards requests to the correct internal port (`3000` by default). Configure SSL termination and any necessary headers.
Certifique-se de que seu proxy reverso encaminha as solicitações para a porta interna correta (`3000` por padrão). Configure a terminação SSL e quaisquer cabeçalhos necessários.
* **Firewall Settings:**
* **Configurações de Firewall:**
Open necessary ports in your firewall to allow external access.
Abra as portas necessárias no seu firewall para permitir acesso externo.
* **Consistency:**
* **Consistência:**
The `SERVER_URL` must match how users access your application in their browsers.
A `SERVER_URL` deve corresponder à forma como os usuários acessam seu aplicativo nos navegadores.
#### Persistence
#### Persistência
* **Data Volumes:**
* **Volumes de Dados:**
The Docker Compose configuration uses volumes to persist data for the database and server storage.
A configuração do Docker Compose usa volumes para persistir dados para o banco de dados e armazenamento do servidor.
* **Stateless Environments:**
* **Ambientes Sem Estado:**
If deploying to a stateless environment (e.g., certain cloud services), configure external storage to persist data.
Se estiver implantando em um ambiente sem estado (por exemplo, certos serviços de nuvem), configure armazenamento externo para persistir dados.
## Backup and Restore
## Backup e restauração
Regular backups protect your CRM data from loss.
Backups regulares protegem os dados do seu CRM contra perda.
### Create a Database Backup
### Crie um backup do banco de dados
```bash
docker exec twenty-postgres pg_dump -U postgres twenty > backup_$(date +%Y%m%d).sql
```
### Automate Daily Backups
### Automatize backups diários
Add to your crontab (`crontab -e`):
Adicione ao seu crontab (`crontab -e`):
```bash
0 2 * * * docker exec twenty-postgres pg_dump -U postgres twenty > /backups/twenty_$(date +\%Y\%m\%d).sql
```
### Restore from Backup
### Restaurar a partir de um backup
1. Stop the application:
1. Pare o aplicativo:
```bash
docker compose stop twenty-server twenty-front
```
2. Restore the database:
2. Restaure o banco de dados:
```bash
docker exec -i twenty-postgres psql -U postgres twenty < backup_20240115.sql
```
3. Restart services:
3. Reinicie os serviços:
```bash
docker compose up -d
```
### Backup Best Practices
### Melhores práticas de backup
* **Test restores regularly** — verify backups actually work
* **Store backups off-site** — use cloud storage (S3, GCS, etc.)
* **Encrypt sensitive data** — protect backups with encryption
* **Retain multiple copies** — keep daily, weekly, and monthly backups
* **Teste as restaurações regularmente** — verifique se os backups realmente funcionam
* **Armazene os backups fora das instalações** — use armazenamento em nuvem (S3, GCS, etc.)
* **Criptografe dados confidenciais** — proteja os backups com criptografia
* **Mantenha várias cópias** — guarde backups diários, semanais e mensais
## Troubleshooting
## Resolução de Problemas
If you encounter any problem, check [Troubleshooting](/l/pt/developers/self-host/capabilities/troubleshooting) for solutions.
Se encontrar algum problema, verifique [Resolução de Problemas](/l/pt/developers/self-host/capabilities/troubleshooting) para soluções.
@@ -1,146 +1,146 @@
---
title: Setup
title: Configuração
---
# Configuration Management
# Gestão de Configuração
<Warning>
**First time installing?** Follow the [Docker Compose installation guide](/l/pt/developers/self-host/capabilities/docker-compose) to get Twenty running, then return here for configuration.
**Primeira vez instalando?** Siga o [guia de instalação do Docker Compose](/l/pt/developers/self-host/capabilities/docker-compose) para iniciar o Twenty, depois retorne aqui para configurar.
</Warning>
Twenty offers **two configuration modes** to suit different deployment needs:
Twenty oferece **dois modos de configuração** para atender diferentes necessidades de implantação:
**Admin panel access:** Only users with admin privileges (`canAccessFullAdminPanel: true`) can access the configuration interface.
**Acesso ao painel de administração:** Apenas usuários com privilégios de administrador (`canAccessFullAdminPanel: true`) podem acessar a interface de configuração.
## 1. Admin Panel Configuration (Default)
## 1. Configuração do Painel Administrativo (Padrão)
```bash
IS_CONFIG_VARIABLES_IN_DB_ENABLED=true # default
```
**Most configuration happens through the UI** after installation:
**A maior parte da configuração acontece através da interface do usuário** após a instalação:
1. Access your Twenty instance (usually `http://localhost:3000`)
2. Go to **Settings / Admin Panel / Configuration Variables**
3. Configure integrations, email, storage, and more
4. Changes take effect immediately (within 15 seconds for multi-container deployments)
1. Acesse sua instância do Twenty (geralmente `http://localhost:3000`)
2. Vá para **Configurações / Painel de Administração / Variáveis de Configuração**
3. Configure integrações, email, armazenamento e mais
4. As alterações entram em vigor imediatamente (em até 15 segundos para implantações em múltiplos containers)
<Warning>
**Multi-Container Deployments:** When using database configuration (`IS_CONFIG_VARIABLES_IN_DB_ENABLED=true`), both server and worker containers read from the same database. Admin panel changes affect both automatically, eliminating the need to duplicate environment variables between containers (except for infrastructure variables).
**Implantações em Múltiplos Containers:** Ao usar a configuração do banco de dados (`IS_CONFIG_VARIABLES_IN_DB_ENABLED=true`), tanto servidores quanto containers de trabalho leem do mesmo banco de dados. Alterações no painel de administração afetam ambos automaticamente, eliminando a necessidade de duplicar variáveis de ambiente entre os containers (exceto para variáveis de infraestrutura).
</Warning>
**What you can configure through the admin panel:**
**O que você pode configurar através do painel de administração:**
* **Authentication** - Google/Microsoft OAuth, password settings
* **Email** - SMTP settings, templates, verification
* **Storage** - S3 configuration, local storage paths
* **Integrations** - Gmail, Google Calendar, Microsoft services
* **Workflow & Rate Limiting** - Execution limits, API throttling
* **And much more...**
* **Autenticação** - OAuth do Google/Microsoft, configurações de senha
* **Email** - configurações SMTP, modelos, verificação
* **Armazenamento** - configuração S3, caminhos de armazenamento local
* **Integrações** - Gmail, Google Calendar, serviços Microsoft
* **Fluxo de trabalho e limitação de taxa** - limites de execução, limitação de taxa da API
* **E muito mais...**
![Admin Panel Configuration Variables](/images/user-guide/setup/admin-panel-config-variables.png)
![Variáveis de configuração do painel de administração](/images/user-guide/setup/admin-panel-config-variables.png)
<Warning>
Each variable is documented with descriptions in your admin panel at **Settings → Admin Panel → Configuration Variables**.
Some infrastructure settings like database connections (`PG_DATABASE_URL`), server URLs (`SERVER_URL`), and app secrets (`APP_SECRET`) can only be configured via `.env` file.
Cada variável é documentada com descrições no seu painel de administração em **Configurações → Painel de Administração → Variáveis de Configuração**.
Algumas configurações de infraestrutura como conexões de banco de dados (`PG_DATABASE_URL`), URLs de servidor (`SERVER_URL`) e segredos do app (`APP_SECRET`) só podem ser configuradas via arquivo `.env`.
[Complete technical reference →](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/twenty-config/config-variables.ts)
[Referência técnica completa →](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/twenty-config/config-variables.ts)
</Warning>
## 2. Environment-Only Configuration
## 2. Configuração Somente por Ambiente
```bash
IS_CONFIG_VARIABLES_IN_DB_ENABLED=false
```
**All configuration managed through `.env` files:**
**Toda a configuração gerenciada através de arquivos `.env`:**
1. Set `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false` in your `.env` file
2. Add all configuration variables to your `.env` file
3. Restart containers for changes to take effect
4. Admin panel will show current values but cannot modify them
1. Defina `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false` no seu arquivo `.env`
2. Adicione todas as variáveis de configuração ao seu arquivo `.env`
3. Reinicie os containers para que as alterações entrem em vigor
4. O painel de administração mostrará valores atuais, mas não poderá modificá-los
## Multi-Workspace Mode
## Modo de vários espaços de trabalho
By default, Twenty runs in **single-workspace mode** — ideal for most self-hosted deployments where you need one CRM instance for your organization.
Por padrão, o Twenty é executado no **modo de espaço de trabalho único** — ideal para a maioria das implantações auto-hospedadas em que você precisa de uma instância de CRM para sua organização.
### Single-Workspace Mode (Default)
### Modo de espaço de trabalho único (padrão)
```bash
IS_MULTIWORKSPACE_ENABLED=false # default
```
* One workspace per Twenty instance
* First user automatically becomes admin with full privileges (`canImpersonate` and `canAccessFullAdminPanel`)
* New signups are disabled after the first workspace is created
* Simple URL structure: `https://your-domain.com`
* Um espaço de trabalho por instância do Twenty
* O primeiro usuário torna-se automaticamente administrador com privilégios completos (`canImpersonate` e `canAccessFullAdminPanel`)
* Novos cadastros são desativados após a criação do primeiro espaço de trabalho
* Estrutura de URL simples: `https://your-domain.com`
### Enabling Multi-Workspace Mode
### Ativando o modo de vários espaços de trabalho
```bash
IS_MULTIWORKSPACE_ENABLED=true
DEFAULT_SUBDOMAIN=app # default value
```
Enable multi-workspace mode for SaaS-like deployments where multiple independent teams need their own workspaces on the same Twenty instance.
Ative o modo de vários espaços de trabalho para implantações ao estilo SaaS em que várias equipes independentes precisam de seus próprios espaços de trabalho na mesma instância do Twenty.
**Key differences from single-workspace mode:**
**Principais diferenças em relação ao modo de espaço de trabalho único:**
* Multiple workspaces can be created on the same instance
* Each workspace gets its own subdomain (e.g., `sales.your-domain.com`, `marketing.your-domain.com`)
* Users sign up and log in at `{DEFAULT_SUBDOMAIN}.your-domain.com` (e.g., `app.your-domain.com`)
* No automatic admin privileges — first user in each workspace is a regular user
* Workspace-specific settings like subdomain and custom domain become available in workspace settings
* Vários espaços de trabalho podem ser criados na mesma instância
* Cada espaço de trabalho recebe seu próprio subdomínio (por exemplo, `sales.your-domain.com`, `marketing.your-domain.com`)
* Os usuários se cadastram e fazem login em `{DEFAULT_SUBDOMAIN}.your-domain.com` (por exemplo, `app.your-domain.com`)
* Sem privilégios administrativos automáticos — o primeiro usuário de cada espaço de trabalho é um usuário comum
* Configurações específicas do espaço de trabalho, como subdomínio e domínio personalizado, ficam disponíveis nas configurações do espaço de trabalho
<Warning>
**Environment-only setting:** `IS_MULTIWORKSPACE_ENABLED` can only be configured via `.env` file and requires a restart. It cannot be changed through the admin panel.
**Configuração apenas por ambiente:** `IS_MULTIWORKSPACE_ENABLED` só pode ser configurado via arquivo `.env` e requer reinicialização. Isso não pode ser alterado pelo painel de administração.
</Warning>
### DNS Configuration for Multi-Workspace
### Configuração de DNS para vários espaços de trabalho
When using multi-workspace mode, configure your DNS with a wildcard record to allow dynamic subdomain creation:
Ao usar o modo de vários espaços de trabalho, configure seu DNS com um registro curinga para permitir a criação dinâmica de subdomínios:
```
*.your-domain.com -> your-server-ip
```
This enables automatic subdomain routing for new workspaces without manual DNS configuration.
Isso permite o roteamento automático de subdomínios para novos espaços de trabalho sem configuração manual de DNS.
### Restricting Workspace Creation
### Restringindo a criação de espaços de trabalho
In multi-workspace mode, you may want to limit who can create new workspaces:
No modo de vários espaços de trabalho, você pode querer limitar quem pode criar novos espaços de trabalho:
```bash
IS_WORKSPACE_CREATION_LIMITED_TO_SERVER_ADMINS=true
```
When enabled, only users with `canAccessFullAdminPanel` can create additional workspaces. Users can still create their first workspace during initial signup.
Quando ativado, apenas usuários com `canAccessFullAdminPanel` podem criar espaços de trabalho adicionais. Os usuários ainda podem criar seu primeiro espaço de trabalho durante o cadastro inicial.
## Gmail & Google Calendar Integration
## Integração com Gmail e Google Calendar
### Create Google Cloud Project
### Criar Projeto no Google Cloud
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
2. Create a new project or select existing one
3. Enable these APIs:
1. Vá para [Google Cloud Console](https://console.cloud.google.com/)
2. Crie um novo projeto ou selecione um já existente
3. Ative essas APIs:
* [Gmail API](https://console.cloud.google.com/apis/library/gmail.googleapis.com)
* [Google Calendar API](https://console.cloud.google.com/apis/library/calendar-json.googleapis.com)
* [People API](https://console.cloud.google.com/apis/library/people.googleapis.com)
* [API do Gmail](https://console.cloud.google.com/apis/library/gmail.googleapis.com)
* [API do Google Calendar](https://console.cloud.google.com/apis/library/calendar-json.googleapis.com)
* [API de Pessoas](https://console.cloud.google.com/apis/library/people.googleapis.com)
### Configure OAuth
1. Go to [Credentials](https://console.cloud.google.com/apis/credentials)
2. Create OAuth 2.0 Client ID
3. Add these redirect URIs:
* `https://{your-domain}/auth/google/redirect` (for SSO)
* `https://{your-domain}/auth/google-apis/get-access-token` (for integrations)
1. Vá para [Credenciais](https://console.cloud.google.com/apis/credentials)
2. Crie um ID do Cliente OAuth 2.0
3. Adicione estes URIs de redirecionamento:
* `https://{your-domain}/auth/google/redirect` (para SSO)
* `https://{your-domain}/auth/google-apis/get-access-token` (para integrações)
### Configure in Twenty
### Configurar no Twenty
1. Go to **Settings → Admin Panel → Configuration Variables**
2. Find the **Google Auth** section
3. Set these variables:
1. Vá para **Configurações → Painel de Administração → Variáveis de Configuração**
2. Encontre a seção **Google Auth**
3. Defina estas variáveis:
* `MESSAGING_PROVIDER_GMAIL_ENABLED=true`
* `CALENDAR_PROVIDER_GOOGLE_ENABLED=true`
* `AUTH_GOOGLE_CLIENT_ID={client-id}`
@@ -149,35 +149,35 @@ When enabled, only users with `canAccessFullAdminPanel` can create additional wo
* `AUTH_GOOGLE_APIS_CALLBACK_URL=https://{your-domain}/auth/google-apis/get-access-token`
<Warning>
**Environment-only mode:** If you set `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`, add these variables to your `.env` file instead.
**Modo somente ambiente:** Se você definir `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`, adicione estas variáveis ao seu arquivo `.env`.
</Warning>
**Required scopes** (automatically configured):
[See relevant source code](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/auth/utils/get-google-apis-oauth-scopes.ts#L4-L10)
**Escopos necessários** (configurados automaticamente):
[Veja o código relevante](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/auth/utils/get-google-apis-oauth-scopes.ts#L4-L10)
* `https://www.googleapis.com/auth/calendar.events`
* `https://www.googleapis.com/auth/gmail.readonly`
* `https://www.googleapis.com/auth/profile.emails.read`
### If your app is in test mode
### Se seu aplicativo estiver em modo de teste
If your app is in test mode, you will need to add test users to your project.
Se seu aplicativo estiver em modo de teste, será necessário adicionar usuários de teste ao seu projeto.
Under [OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent), add your test users to the "Test users" section.
Na [tela de consentimento OAuth](https://console.cloud.google.com/apis/credentials/consent), adicione seus usuários de teste à seção "Usuários de teste".
## Microsoft 365 Integration
## Integração com Microsoft 365
<Warning>
Users must have a [Microsoft 365 Licence](https://admin.microsoft.com/Adminportal/Home) to be able to use the Calendar and Messaging API. They will not be able to sync their account on Twenty without one.
Os usuários devem ter uma [Licença do Microsoft 365](https://admin.microsoft.com/Adminportal/Home) para poder usar as APIs de Calendário e Mensagem. Eles não poderão sincronizar sua conta no Twenty sem uma.
</Warning>
### Create a project in Microsoft Azure
### Criar um projeto no Microsoft Azure
You will need to create a project in [Microsoft Azure](https://portal.azure.com/#view/Microsoft_AAD_IAM/AppGalleryBladeV2) and get the credentials.
Você precisará criar um projeto no [Microsoft Azure](https://portal.azure.com/#view/Microsoft_AAD_IAM/AppGalleryBladeV2) e obter as credenciais.
### Enable APIs
### Habilitar APIs
On Microsoft Azure Console enable the following APIs in "Permissions":
No Console do Microsoft Azure habilite as seguintes APIs em "Permissões":
* Microsoft Graph: Mail.ReadWrite
* Microsoft Graph: Mail.Send
@@ -188,20 +188,20 @@ On Microsoft Azure Console enable the following APIs in "Permissions":
* Microsoft Graph: profile
* Microsoft Graph: offline_access
Note: "Mail.ReadWrite" and "Mail.Send" are only mandatory if you want to send emails using our workflow actions. You can use "Mail.Read" instead if you only want to receive emails.
Nota: "Mail.ReadWrite" e "Mail.Send" são apenas obrigatórios se você quiser enviar emails usando nossas ações de fluxo de trabalho. Você pode usar "Mail.Read" em vez disso se quiser apenas receber emails.
### Authorized redirect URIs
### URIs de redirecionamento autorizados
You need to add the following redirect URIs to your project:
Você precisa adicionar os seguintes URIs de redirecionamento ao seu projeto:
* `https://{your-domain}/auth/microsoft/redirect` if you want to use Microsoft SSO
* `https://{your-domain}/auth/microsoft/redirect` se você quiser usar SSO da Microsoft
* `https://{your-domain}/auth/microsoft-apis/get-access-token`
### Configure in Twenty
### Configurar no Twenty
1. Go to **Settings → Admin Panel → Configuration Variables**
2. Find the **Microsoft Auth** section
3. Set these variables:
1. Vá para **Configurações → Painel de Administração → Variáveis de Configuração**
2. Encontre a seção **Microsoft Auth**
3. Defina estas variáveis:
* `MESSAGING_PROVIDER_MICROSOFT_ENABLED=true`
* `CALENDAR_PROVIDER_MICROSOFT_ENABLED=true`
* `AUTH_MICROSOFT_ENABLED=true`
@@ -211,32 +211,32 @@ You need to add the following redirect URIs to your project:
* `AUTH_MICROSOFT_APIS_CALLBACK_URL=https://{your-domain}/auth/microsoft-apis/get-access-token`
<Warning>
**Environment-only mode:** If you set `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`, add these variables to your `.env` file instead.
**Modo somente ambiente:** Se você definir `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`, adicione estas variáveis ao seu arquivo `.env`.
</Warning>
### Configure scopes
### Configurar escopos
[See relevant source code](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/auth/utils/get-microsoft-apis-oauth-scopes.ts#L2-L9)
[Veja o código relevante](https://github.com/twentyhq/twenty/blob/main/packages/twenty-server/src/engine/core-modules/auth/utils/get-microsoft-apis-oauth-scopes.ts#L2-L9)
* 'openid'
* 'email'
* 'profile'
* 'perfil'
* 'offline_access'
* 'Mail.ReadWrite'
* 'Mail.Send'
* 'Calendars.Read'
### If your app is in test mode
### Se seu aplicativo estiver em modo de teste
If your app is in test mode, you will need to add test users to your project.
Se seu aplicativo estiver em modo de teste, será necessário adicionar usuários de teste ao seu projeto.
Add your test users to the "Users and groups" section.
Adicione seus usuários de teste à seção "Usuários e grupos".
## Background Jobs for Calendar & Messaging
## Trabalhos em Segundo Plano para Calendário e Mensagens
After configuring Gmail, Google Calendar, or Microsoft 365 integrations, you need to start the background jobs that sync data.
Após configurar integrações com Gmail, Google Calendar ou Microsoft 365, é necessário iniciar os trabalhos em segundo plano que sincronizam dados.
Register the following recurring jobs in your worker container:
Registre os seguintes trabalhos recorrentes em seu container de trabalho:
```bash
# from your worker container
@@ -249,15 +249,15 @@ yarn command:prod cron:calendar:ongoing-stale
yarn command:prod cron:workflow:automated-cron-trigger
```
## Email Configuration
## Configuração de Email
1. Go to **Settings → Admin Panel → Configuration Variables**
2. Find the **Email** section
3. Configure your SMTP settings:
1. Vá para **Configurações → Painel de Administração → Variáveis de Configuração**
2. Encontre a seção **Email**
3. Configure suas configurações SMTP:
<ArticleTabs label1="Gmail" label2="Office365" label3="Smtp4dev">
<ArticleTab>
You will need to provision an [App Password](https://support.google.com/accounts/answer/185833).
Você precisará provisionar uma [Senha de App](https://support.google.com/accounts/answer/185833).
* EMAIL_DRIVER=smtp
* EMAIL_SMTP_HOST=smtp.gmail.com
@@ -267,7 +267,7 @@ yarn command:prod cron:workflow:automated-cron-trigger
</ArticleTab>
<ArticleTab>
Keep in mind that if you have 2FA enabled, you will need to provision an [App Password](https://support.microsoft.com/en-us/account-billing/manage-app-passwords-for-two-step-verification-d6dc8c6d-4bf7-4851-ad95-6d07799387e9).
Lembre-se de que, se você tiver 2FA ativado, precisará providenciar uma [Senha de App](https://support.microsoft.com/en-us/account-billing/manage-app-passwords-for-two-step-verification-d6dc8c6d-4bf7-4851-ad95-6d07799387e9).
* EMAIL_DRIVER=smtp
* EMAIL_SMTP_HOST=smtp.office365.com
@@ -277,11 +277,11 @@ yarn command:prod cron:workflow:automated-cron-trigger
</ArticleTab>
<ArticleTab>
**smtp4dev** is a fake SMTP email server for development and testing.
**smtp4dev** é um servidor SMTP falso para desenvolvimento e teste.
* Run the smtp4dev image: `docker run --rm -it -p 8090:80 -p 2525:25 rnwood/smtp4dev`
* Access the smtp4dev ui here: [http://localhost:8090](http://localhost:8090)
* Set the following variables:
* Execute a imagem smtp4dev: `docker run --rm -it -p 8090:80 -p 2525:25 rnwood/smtp4dev`
* Acesse a interface smtp4dev aqui: [http://localhost:8090](http://localhost:8090)
* Defina as seguintes variáveis:
* EMAIL_DRIVER=smtp
* EMAIL_SMTP_HOST=localhost
* EMAIL_SMTP_PORT=2525
@@ -289,5 +289,49 @@ yarn command:prod cron:workflow:automated-cron-trigger
</ArticleTabs>
<Warning>
**Environment-only mode:** If you set `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`, add these variables to your `.env` file instead.
**Modo somente ambiente:** Se você definir `IS_CONFIG_VARIABLES_IN_DB_ENABLED=false`, adicione estas variáveis ao seu arquivo `.env`.
</Warning>
## Funções serverless
O Twenty oferece suporte a funções serverless para fluxos de trabalho e lógica personalizada. O ambiente de execução é configurado por meio da variável de ambiente `SERVERLESS_TYPE`.
<Warning>
**Aviso de segurança:** O driver serverless local (`SERVERLESS_TYPE=LOCAL`) executa código diretamente no host em um processo Node.js sem sandbox. Deve ser usado apenas para código confiável em desenvolvimento. Para implantações de produção que lidam com código não confiável, recomendamos fortemente usar `SERVERLESS_TYPE=LAMBDA` ou `SERVERLESS_TYPE=DISABLED`.
</Warning>
### Drivers disponíveis
| Driver | Variável de ambiente | Caso de uso | Nível de segurança |
| ---------- | -------------------------- | --------------------------------------------- | -------------------------------------- |
| Desativado | `SERVERLESS_TYPE=DISABLED` | Desativar completamente as funções serverless | N/A |
| Local | `SERVERLESS_TYPE=LOCAL` | Desenvolvimento e ambientes confiáveis | Baixo (sem sandbox) |
| Lambda | `SERVERLESS_TYPE=LAMBDA` | Produção com código não confiável | Alto (isolamento em nível de hardware) |
### Configuração recomendada
**Para desenvolvimento:**
```bash
SERVERLESS_TYPE=LOCAL # default
```
**Para produção (AWS):**
```bash
SERVERLESS_TYPE=LAMBDA
SERVERLESS_LAMBDA_REGION=us-east-1
SERVERLESS_LAMBDA_ROLE=arn:aws:iam::123456789:role/your-lambda-role
SERVERLESS_LAMBDA_ACCESS_KEY_ID=your-access-key
SERVERLESS_LAMBDA_SECRET_ACCESS_KEY=your-secret-key
```
**Para desativar as funções serverless:**
```bash
SERVERLESS_TYPE=DISABLED
```
<Note>
Ao usar `SERVERLESS_TYPE=DISABLED`, qualquer tentativa de executar uma função serverless retornará um erro. Isso é útil se você quiser executar o Twenty sem recursos de funções serverless.
</Note>
@@ -1,26 +1,25 @@
---
title: Troubleshooting
title: Resolução de Problemas
---
## Troubleshooting
## Resolução de Problemas
If you encounter any problem while setting up environment for development, upgrading your instance or self-hosting,
here are some solutions for common problems.
Se encontrar algum problema ao configurar o ambiente para desenvolvimento, atualizar sua instância ou auto-hospedagem, aqui estão algumas soluções para problemas comuns.
### Self-hosting
### Auto-hospedagem
#### First install results in `password authentication failed for user "postgres"`
#### Primeira instalação resulta em `falha na autenticação de senha para o usuário "postgres"`
🚨 **IMPORTANT: This solution is ONLY for fresh installations** 🚨
If you have an existing Twenty instance with production data, **DO NOT** follow these steps as they will permanently delete your database!
🚨 **IMPORTANTE: Esta solução é APENAS para instalações novas** 🚨
Se você tiver uma instância existente do Twenty com dados em produção, **NÃO** siga estes passos, pois eles excluirão permanentemente seu banco de dados!
While installing Twenty for the first time, you might want to change the default database password.
The password you set during the first installation becomes permanently stored in the database volume. If you later try to change this password in your configuration without removing the old volume, you'll get authentication errors because the database is still using the original password.
Ao instalar o Twenty pela primeira vez, você pode querer alterar a senha padrão do banco de dados.
A senha definida durante a primeira instalação é armazenada permanentemente no volume do banco de dados. Se posteriormente tentar alterar esta senha na sua configuração sem remover o volume antigo, receberá erros de autenticação porque o banco de dados ainda está usando a senha original.
⚠️ WARNING: Following steps will PERMANENTLY DELETE all database data! ⚠️
Only proceed if this is a fresh installation with no important data.
⚠️ AVISO: Seguir os próximos passos irá EXCLUIR PERMANENTEMENTE todos os dados do banco de dados! ⚠️
Prossiga apenas se esta for uma instalação nova, sem dados importantes.
In order to update the `PG_DATABASE_PASSWORD` you need to:
Para atualizar o `PG_DATABASE_PASSWORD` você precisa:
```sh
# Update the PG_DATABASE_PASSWORD in .env
@@ -28,33 +27,33 @@ docker compose down --volumes
docker compose up -d
```
#### CR line breaks found [Windows]
#### Quebras de linha CR encontradas [Windows]
This is due to the line break characters of Windows and the git configuration. Try running:
Isso se deve aos caracteres de quebra de linha do Windows e à configuração do git. Tente executar:
```
git config --global core.autocrlf false
```
Then delete the repository and clone it again.
Depois exclua o repositório e clone novamente.
#### Missing metadata schema
#### Esquema de metadados ausente
During Twenty installation, you need to provision your postgres database with the right schemas, extensions, and users.
If you're successful in running this provisioning, you should have `default` and `metadata` schemas in your database.
If you don't, make sure you don't have more than one postgres instance running on your computer.
Durante a instalação do Twenty, é necessário configurar seu banco de dados postgres com os esquemas, extensões e usuários corretos.
Se conseguir executar esta configuração, você deve ter os esquemas `default` e `metadata` no seu banco de dados.
Se não, certifique-se de que não possui mais de uma instância do postgres em execução no seu computador.
#### Cannot find module 'twenty-emails' or its corresponding type declarations.
#### Não é possível encontrar o módulo 'twenty-emails' ou suas declarações de tipo correspondentes.
You have to build the package `twenty-emails` before running the initialization of the database with `npx nx run twenty-emails:build`
É preciso compilar o pacote `twenty-emails` antes de iniciar a inicialização do banco de dados com `npx nx run twenty-emails:build`
#### Missing twenty-x package
#### Pacote twenty-x ausente
Make sure to run yarn in the root directory and then run `npx nx server:dev twenty-server`. If this still doesn't work try building the missing package manually.
Certifique-se de executar o yarn no diretório raiz e depois executar `npx nx server:dev twenty-server`. Se isso ainda não funcionar, tente compilar manualmente o pacote ausente.
#### Lint on Save not working
#### Lint no Save não funcionando
This should work out of the box with the eslint extension installed. If this doesn't work try adding this to your vscode setting (on the dev container scope):
Isso deve funcionar automaticamente com a extensão eslint instalada. Se isso não funcionar, tente adicionar este trecho às suas configurações do vscode (no escopo do contêiner de desenvolvimento):
```
"editor.codeActionsOnSave": {
@@ -64,85 +63,85 @@ This should work out of the box with the eslint extension installed. If this doe
}
```
#### While running `npx nx start` or `npx nx start twenty-front`, Out of memory error is thrown
#### Ao executar `npx nx start` ou `npx nx start twenty-front`, é lançada uma mensagem de erro de falta de memória
In `packages/twenty-front/.env` uncomment `VITE_DISABLE_TYPESCRIPT_CHECKER=true` to disable background checks thus reducing amount of needed RAM.
No `packages/twenty-front/.env` descomente `VITE_DISABLE_TYPESCRIPT_CHECKER=true` para desativar verificações em segundo plano, reduzindo assim a quantidade de RAM necessária.
**If it does not work:**
Run only the services you need, instead of `npx nx start`. For instance, if you work on the server, run only `npx nx worker twenty-server`
**Se não funcionar:**
Execute apenas os serviços que precisar, em vez de `npx nx start`. Por exemplo, se estiver trabalhando no servidor, execute apenas `npx nx worker twenty-server`
**If it does not work:**
If you tried to run only `npx nx run twenty-server:start` on WSL and it's failing with the below memory error:
**Se não funcionar:**
Se você tentou executar apenas `npx nx run twenty-server:start` no WSL e está falhando com o erro de memória abaixo:
`FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory`
`ERRO FATAL: Marcação ineficaz perto do limite de heap Alocação falhou - heap do JavaScript sem memória`
Workaround is to execute below command in terminal or add it in .bashrc profile to get setup automatically:
A solução alternativa é executar o comando abaixo no terminal ou adicioná-lo no perfil .bashrc para ser configurado automaticamente:
`export NODE_OPTIONS="--max-old-space-size=8192"`
The --max-old-space-size=8192 flag sets an upper limit of 8GB for the Node.js heap; usage scales with application demand.
Reference: https://stackoverflow.com/questions/56982005/where-do-i-set-node-options-max-old-space-size-2048
O parâmetro --max-old-space-size=8192 define um limite superior de 8GB para o heap do Node.js; o uso escala conforme as demandas da aplicação.
Referência: https://stackoverflow.com/questions/56982005/where-do-i-set-node-options-max-old-space-size-2048
**If it does not work:**
Investigate which processes are taking you most of your machine RAM. At Twenty, we noticed that some VScode extensions were taking a lot of RAM so we temporarily disable them.
**Se não funcionar:**
Investigue quais processos estão consumindo a maior parte da RAM do seu computador. No Twenty, percebemos que algumas extensões do VScode estavam consumindo muita RAM, então as desativamos temporariamente.
**If it does not work:**
Restart your machine helps to clean up ghost processes.
**Se não funcionar:**
Reiniciar sua máquina ajuda a limpar processos fantasmas.
#### While running `npx nx start` there are weird [0] and [1] in logs
#### Ao executar `npx nx start`, há logs estranhos [0] e [1]
That's expected as command `npx nx start` is running more commands under the hood
Isso é esperado, pois o comando `npx nx start` está executando mais comandos por trás dos bastidores
#### No emails are sent
#### Nenhum email é enviado
Most of the time, it's because the `worker` is not running in the background. Try to run
Na maioria das vezes, isso ocorre porque o `worker` não está sendo executado em segundo plano. Tente executar
```
npx nx worker twenty-server
```
#### Cannot connect my Microsoft 365 account
#### Não consigo conectar minha conta Microsoft 365
Most of the time, it's because your admin has not enabled the Microsoft 365 Licence for your account. Check [https://admin.microsoft.com/](https://admin.microsoft.com/Adminportal/Home).
Na maioria das vezes, é porque seu administrador não ativou a Licença Microsoft 365 para sua conta. Verifique [https://admin.microsoft.com/](https://admin.microsoft.com/Adminportal/Home).
If you have an error code `AADSTS50020`, it probably means that you are using a personal Microsoft account. This is not supported yet. More info [here](https://learn.microsoft.com/fr-fr/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50020-user-account-identity-provider-does-not-exist)
Se você tem um código de erro `AADSTS50020`, provavelmente significa que você está usando uma conta pessoal da Microsoft. Isso ainda não é suportado. Mais informações [aqui](https://learn.microsoft.com/fr-fr/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50020-user-account-identity-provider-does-not-exist)
#### While running `yarn` warnings appear in console
#### Ao executar `yarn` avisos aparecem no console
Warnings are informing about pulling additional dependencies which aren't explicitly stated in `package.json`, so as long as no breaking error appears, everything should work as expected.
Os avisos informam sobre a obtenção de dependências adicionais que não estão explicitamente declaradas em `package.json`, portanto, desde que não apareça nenhum erro crítico, tudo deve funcionar como esperado.
#### When user accesses login page, error about unauthorized user trying to access workspace appears in logs
#### Quando o usuário acessa a página de login, aparece nos logs um erro sobre o usuário não autorizado tentando acessar o espaço de trabalho
That's expected as user is unauthorized when logged out since its identity is not verified.
Isso é esperado, pois o usuário fica sem autorização quando está desconectado, já que sua identidade não está verificada.
#### How to check if your worker is running?
#### Como verificar se seu worker está em execução?
* Go to [webhook-test.com](https://webhook-test.com/) and copy **Your Unique Webhook URL**.
* Vá para [webhook-test.com](https://webhook-test.com/) e copie **Sua URL de Webhook exclusiva**.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/self-hosting/webhook-test.jpg" alt="Webhook test" />
<img src="/images/docs/developers/self-hosting/webhook-test.jpg" alt="Teste de webhook" />
</div>
* Open your Twenty app, navigate to `/settings`, and enable the **Advanced** toggle at the bottom left of the screen.
* Create a new webhook.
* Paste **Your Unique Webhook URL** in the **Endpoint Url** field in Twenty. Set the **Filters** to `Companies` and `Created`.
* Abra seu aplicativo Twenty, navegue até `/settings`, e ative a alternância **Avançado** na parte inferior esquerda da tela.
* Crie um novo webhook.
* Cole **Sua URL Webhook Única** no campo **Endpoint Url** no Twenty. Defina os **Filtros** para `Companies` e `Created`.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/self-hosting/webhook-settings.jpg" alt="Webhook settings" />
<img src="/images/docs/developers/self-hosting/webhook-settings.jpg" alt="Configurações de webhook" />
</div>
* Go to `/objects/companies` and create a new company record.
* Return to [webhook-test.com](https://webhook-test.com/) and check if a new **POST request** has been received.
* Vá para `/objects/companies` e crie um novo registro de empresa.
* Retorne para [webhook-test.com](https://webhook-test.com/) e verifique se uma nova **solicitação POST** foi recebida.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/self-hosting/webhook-test-result.jpg" alt="Webhook test result" />
<img src="/images/docs/developers/self-hosting/webhook-test-result.jpg" alt="Resultado do teste de webhook" />
</div>
* If a **POST request** is received, your worker is running successfully. Otherwise, you need to troubleshoot your worker.
* Se uma **solicitação POST** for recebida, seu worker está funcionando com sucesso. Caso contrário, você precisa solucionar problemas no seu worker.
#### Front-end fails to start and returns error TS5042: Option 'project' cannot be mixed with source files on a command line
#### Front-end não inicia e retorna erro TS5042: A opção 'project' não pode ser misturada com arquivos de origem na linha de comando
Comment out checker plugin in `packages/twenty-ui/vite-config.ts` like in example below
Comente o plugin checker em `packages/twenty-ui/vite-config.ts` como no exemplo abaixo
```
plugins: [
@@ -166,62 +165,62 @@ plugins: [
],
```
#### Admin panel not accessible
#### Painel administrativo não acessível
Run `UPDATE core."user" SET "canAccessFullAdminPanel" = TRUE WHERE email = 'you@yourdomain.com';` in database container to get access to admin panel.
Execute `UPDATE core."user" SET "canAccessFullAdminPanel" = TRUE WHERE email = 'você@seudominio.com';` no contêiner de banco de dados para obter acesso ao painel administrativo.
### 1-click Docker compose
### Docker compose com um clique
#### Unable to Log In
#### Impossível efetuar login
If you can't log in after setup:
Se você não consegue efetuar login após a configuração:
1. Run the following commands:
1. Execute os seguintes comandos:
```bash
docker exec -it twenty-server-1 yarn
docker exec -it twenty-server-1 npx nx database:reset --configuration=no-seed
```
2. Restart the Docker containers:
2. Reinicie os contêineres Docker:
```bash
docker compose down
docker compose up -d
```
Note the database:reset command will completely erase your database and recreate it from scratch.
Observe que o comando database:reset irá apagar completamente seu banco de dados e recriá-lo do zero.
#### Connection Issues Behind a Reverse Proxy
#### Problemas de conexão por trás de um proxy reverso
If you're running Twenty behind a reverse proxy and experiencing connection issues:
Se você está executando o Twenty por trás de um proxy reverso e está enfrentando problemas de conexão:
1. **Verify SERVER_URL:**
1. **Verifique o SERVER_URL:**
Ensure `SERVER_URL` in your `.env` file matches your external access URL, including `https` if SSL is enabled.
Certifique-se de que o `SERVER_URL` no seu arquivo `.env` corresponda à sua URL de acesso externo, incluindo `https` se o SSL estiver habilitado.
2. **Check Reverse Proxy Settings:**
2. **Verifique as configurações do Proxy Reverso:**
* Confirm that your reverse proxy is correctly forwarding requests to the Twenty server.
* Ensure headers like `X-Forwarded-For` and `X-Forwarded-Proto` are properly set.
* Confirme que seu proxy reverso está encaminhando corretamente as solicitações para o servidor Twenty.
* Certifique-se de que cabeçalhos como `X-Forwarded-For` e `X-Forwarded-Proto` estão configurados corretamente.
3. **Restart Services:**
3. **Reinicie os Serviços:**
After making changes, restart both the reverse proxy and Twenty containers.
Após fazer as alterações, reinicie tanto o proxy reverso quanto os contêineres do Twenty.
#### Error when uploading an image - permission denied
#### Erro ao carregar uma imagem - permissão negada
Switching the data folder ownership on the host from root to another user and group resolves this problem.
Alterar a propriedade do diretório de dados no host de root para outro usuário e grupo resolve esse problema.
## Getting Help
## Obtendo Ajuda
If you encounter issues not covered in this guide:
Se encontrar problemas não abordados neste guia:
* Check Logs:
* Verifique os Logs:
View container logs for error messages:
Veja os logs dos contêineres para mensagens de erro:
```bash
docker compose logs
```
* Community Support:
* Suporte Comunitário:
Reach out to the [Twenty community](https://github.com/twentyhq/twenty/issues) or [support channels](https://discord.gg/cx5n4Jzs57) for assistance.
Entre em contato com a [comunidade Twenty](https://github.com/twentyhq/twenty/issues) ou [canais de suporte](https://discord.gg/cx5n4Jzs57) para obter assistência.
@@ -1,40 +1,40 @@
---
title: Upgrade guide
title: Guia de atualização
---
## General guidelines
## Diretrizes gerais
**Always make sure to back up your database before starting the upgrade process** by running `docker exec -it {db_container_name_or_id} pg_dumpall -U {postgres_user} > databases_backup.sql`.
**Certifique-se sempre de fazer backup do banco de dados antes de iniciar o processo de atualização** executando `docker exec -it {db_container_name_or_id} pg_dumpall -U {postgres_user} > databases_backup.sql`.
To restore backup, run `cat databases_backup.sql | docker exec -i {db_container_name_or_id} psql -U {postgres_user}`.
Para restaurar o backup, execute `cat databases_backup.sql | docker exec -i {db_container_name_or_id} psql -U {postgres_user}`.
If you used Docker Compose, follow these steps:
Se você usou o Docker Compose, siga estas etapas:
1. In a terminal, on the host where Twenty is running, turn off Twenty: `docker compose down`
1. No terminal, no host onde o Twenty está em execução, desligue o Twenty: `docker compose down`
2. Upgrade the version by changing the `TAG` value in the .env file near your docker-compose. ( We recommend consuming `major.minor` version such as `v0.53` )
2. Atualize a versão alterando o valor `TAG` no arquivo .env próximo ao seu docker-compose. (Recomendamos consumir a versão `major.minor` como `v0.53`)
3. Bring Twenty back online with `docker compose up -d`
3. Traga o Twenty de volta ao ar com `docker compose up -d`
If you want to upgrade your instance by few versions, e.g. from v0.33.0 to v0.35.0, you have to upgrade your instance sequentially, in this example from v0.33.0 to v0.34.0, then from v0.34.0 to v0.35.0.
Se você quiser atualizar sua instância em algumas versões, por exemplo, de v0.33.0 para v0.35.0, você deve atualizar sua instância sequencialmente, neste exemplo de v0.33.0 para v0.34.0, depois de v0.34.0 para v0.35.0.
**Make sure that after each upgraded version you have non-corrupted backup.**
**Certifique-se de que após cada versão atualizada você tenha um backup não corrompido.**
## Version-specific upgrade steps
## Etapas de atualização específicas da versão
## v1.0
Hello Twenty v1.0! 🎉
Olá Twenty v1.0! 🎉
## v0.60
### Performance Enhancements
### Melhorias de Performance
All interactions with the metadata API have been optimized for better performance, particularly for object metadata manipulation and workspace creation operations.
Todas as interações com a API de metadados foram otimizadas para um melhor desempenho, particularmente para manipulação de metadados de objetos e operações de criação de espaço de trabalho.
We've refactored our caching strategy to prioritize cache hits over database queries when possible, significantly improving the performance of metadata API operations.
Reformulamos nossa estratégia de cache para priorizar acertos de cache em detrimento de consultas ao banco de dados sempre que possível, melhorando significativamente o desempenho das operações da API de metadados.
If you encounter any runtime issues after upgrading, you may need to flush your cache to ensure it's synchronized with the latest changes. Run this command in your twenty-server container:
Se você encontrar problemas de execução após a atualização, pode ser necessário limpar seu cache para garantir que esteja sincronizado com as alterações mais recentes. Execute este comando em seu contêiner do twenty-server:
```bash
yarn command:prod cache:flush
@@ -42,113 +42,113 @@ yarn command:prod cache:flush
### v0.55
Upgrade your Twenty instance to use v0.55 image
Atualize sua instância do Twenty para usar a imagem v0.55
You don't need to run any command anymore, the new image will automatically care about running all required migrations.
Você não precisa mais executar nenhum comando, a nova imagem cuidará automaticamente de executar todas as migrações necessárias.
### `User does not have permission` error
### Erro `User does not have permission`
If you encounter authorization errors on most requests after upgrading, you may need to flush your cache to recompute the latest permissions.
Se você encontrar erros de autorização na maioria das solicitações após a atualização, pode ser necessário limpar seu cache para recálculo das permissões mais recentes.
In your `twenty-server` container, run:
Em seu contêiner `twenty-server`, execute:
```bash
yarn command:prod cache:flush
```
This issue is specific to this Twenty version and should not be required for future upgrades.
Este problema é específico para esta versão do Twenty e não deverá ser necessário em futuras atualizações.
### v0.54
Since version `0.53`, no manual actions needed.
Desde a versão `0.53`, nenhuma ação manual é necessária.
#### Metadata schema deprecation
#### Desativação do esquema de metadados
We've merged the `metadata` schema into the `core` one to simplify data retrieval from `TypeORM`.
We have merged the `migrate` command step within the `upgrade` command. We do not recommend running `migrate` manually within any of your server/worker containers.
Mesclamos o esquema `metadata` no `core` para simplificar a recuperação de dados do `TypeORM`.
Mesclamos o passo do comando `migrate` dentro do comando `upgrade`. Não recomendamos a execução manual do `migrate` em nenhum de seus servidores/conteineres de trabalho.
### Since v0.53
### Desde v0.53
Starting from `0.53`, upgrade is programmatically done within the `DockerFile`, this means from now on, you shouldn't have to run any command manually anymore.
A partir de `0.53`, a atualização é feita programaticamente dentro do `DockerFile`, o que significa que, a partir de agora, você não precisará mais executar nenhum comando manualmente.
Make sure to keep upgrading your instance sequentially, without skipping any major version (e.g. `0.43.3` to `0.44.0` is allowed, but `0.43.1` to `0.45.0` isn't), else could lead to workspace version desynchronization that could result in runtime error and missing functionality.
Certifique-se de manter atualizando sua instância sequencialmente, sem pular qualquer versão principal (por exemplo, `0.43.3` para `0.44.0` é permitido, mas `0.43.1` para `0.45.0` não é), caso contrário, pode levar a uma desincronização na versão do espaço de trabalho que pode resultar em erro de tempo de execução e funcionalidade ausente.
To check if a workspace has been correctly migrated you can review its version in database in `core.workspace` table.
Para verificar se um espaço de trabalho foi migrado corretamente, você pode revisar sua versão no banco de dados na tabela `core.workspace`.
It should always be in the range of your current Twenty's instance `major.minor` version, you can view your instance version in the admin panel (at `/settings/admin-panel`, accessible if your user has `canAccessFullAdminPanel` property set to true in the database) or by running `echo $APP_VERSION` in your `twenty-server` container.
Deve estar sempre na faixa da versão `major.minor` atual da instância do Twenty, você pode ver a versão de sua instância no painel de administração (em `/settings/admin-panel`, acessível se seu usuário tiver a propriedade `canAccessFullAdminPanel` definida como verdadeira no banco de dados) ou executando `echo $APP_VERSION` em seu contêiner `twenty-server`.
To fix a desynchronized workspace version, you will have to upgrade from the corresponding twenty's version following related upgrade guide sequentially and so on until it reaches desired version.
Para corrigir uma versão de workspace dessincronizada, você terá que atualizar da versão correspondente do twenty seguindo o guia de atualização relacionado sequencialmente e assim por diante até alcançar a versão desejada.
#### `auditLog` removal
#### Remoção do `auditLog`
We've removed the auditLog standard object, which means your backup size might be significantly reduced after this migration.
Removemos o objeto padrão auditLog, o que significa que o tamanho do backup pode ser significativamente reduzido após esta migração.
### v0.51 to v0.52
### v0.51 para v0.52
Upgrade your Twenty instance to use v0.52 image
Atualize sua instância do Twenty para usar a imagem v0.52
```
yarn database:migrate:prod
yarn command:prod upgrade
```
#### I have a workspace blocked in version between `0.52.0` and `0.52.6`
#### Tenho um espaço de trabalho bloqueado na versão entre `0.52.0` e `0.52.6`
Unfortunately `0.52.0` and `0.52.6` have been completely removed from dockerHub.
You will have to manually update your workspace version to `0.51.0` in database and upgrade using twenty version `0.52.11` following its just above upgrade guide.
Infelizmente, `0.52.0` e `0.52.6` foram completamente removidos do dockerHub.
Você terá que atualizar manualmente a versão do espaço de trabalho para `0.51.0` no banco de dados e atualizar usando a versão twenty `0.52.11` seguindo o guia de atualização logo acima.
### v0.50 to v0.51
### v0.50 para v0.51
Upgrade your Twenty instance to use v0.51 image
Atualize sua instância do Twenty para usar a imagem v0.51
```
yarn database:migrate:prod
yarn command:prod upgrade
```
### v0.44.0 to v0.50.0
### v0.44.0 para v0.50.0
Upgrade your Twenty instance to use v0.50.0 image
Atualize sua instância do Twenty para usar a imagem v0.50.0
```
yarn database:migrate:prod
yarn command:prod upgrade
```
#### Docker-compose.yml mutation
#### Mutação docker-compose.yml
This version includes a `docker-compose.yml` mutation to give `worker` service access to the `server-local-data` volume.
Please update your local `docker-compose.yml` with [v0.50.0 docker-compose.yml](https://github.com/twentyhq/twenty/blob/v0.50.0/packages/twenty-docker/docker-compose.yml)
Esta versão inclui uma mutação `docker-compose.yml` para dar ao serviço `worker` acesso ao volume `server-local-data`.
Por favor, atualize seu `docker-compose.yml` local com [v0.50.0 docker-compose.yml](https://github.com/twentyhq/twenty/blob/v0.50.0/packages/twenty-docker/docker-compose.yml)
### v0.43.0 to v0.44.0
### v0.43.0 para v0.44.0
Upgrade your Twenty instance to use v0.44.0 image
Atualize sua instância do Twenty para usar a imagem v0.44.0
```
yarn database:migrate:prod
yarn command:prod upgrade
```
### v0.42.0 to v0.43.0
### v0.42.0 para v0.43.0
Upgrade your Twenty instance to use v0.43.0 image
Atualize sua instância do Twenty para usar a imagem v0.43.0
```
yarn database:migrate:prod
yarn command:prod upgrade
```
In this version, we have also switched to postgres:16 image in docker-compose.yml.
Nesta versão, também trocamos para a imagem postgres:16 no docker-compose.yml.
#### (Option 1) Database migration
#### (Opção 1) Migração do banco de dados
Keeping the existing postgres-spilo image is fine, but you will have to freeze the version in your docker-compose.yml to be 0.43.0.
Manter a imagem postgres-spilo existente está ok, mas você terá que congelar a versão no seu docker-compose.yml para ser 0.43.0.
#### (Option 2) Database migration
#### (Opção 2) Migração do banco de dados
If you want to migrate your database to the new postgres:16 image, please follow these steps:
Se você quiser migrar seu banco de dados para a nova imagem postgres:16, siga estas etapas:
1. Dump your database from the old postgres-spilo container
1. Faça dump do seu banco de dados do contêiner antigo postgres-spilo
```
docker exec -it twenty-db-1 sh
@@ -157,11 +157,11 @@ exit
docker cp twenty-db-1:/home/postgres/databases_backup.sql .
```
Make sure your dump file is not empty.
Certifique-se de que seu arquivo de dump não está vazio.
2. Upgrade your docker-compose.yml to use postgres:16 image as in the [docker-compose.yml](https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/docker-compose.yml) file.
2. Atualize seu docker-compose.yml para usar a imagem postgres:16 como no arquivo [docker-compose.yml](https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/docker-compose.yml).
3. Restore the database to the new postgres:16 container
3. Restaure o banco de dados para o novo contêiner postgres:16
```
docker cp databases_backup.sql twenty-db-1:/databases_backup.sql
@@ -170,86 +170,86 @@ psql -U {YOUR_POSTGRES_USER} -d {YOUR_POSTGRES_DB} -f databases_backup.sql
exit
```
### v0.41.0 to v0.42.0
### v0.41.0 para v0.42.0
Upgrade your Twenty instance to use v0.42.0 image
Atualize sua instância do Twenty para usar a imagem v0.42.0
```
yarn database:migrate:prod
yarn command:prod upgrade-0.42
```
**Environment Variables**
**Variáveis de Ambiente**
* Removed: `FRONT_PORT`, `FRONT_PROTOCOL`, `FRONT_DOMAIN`, `PORT`
* Added: `FRONTEND_URL`, `NODE_PORT`, `MAX_NUMBER_OF_WORKSPACES_DELETED_PER_EXECUTION`, `MESSAGING_PROVIDER_MICROSOFT_ENABLED`, `CALENDAR_PROVIDER_MICROSOFT_ENABLED`, `IS_MICROSOFT_SYNC_ENABLED`
* Removido: `FRONT_PORT`, `FRONT_PROTOCOL`, `FRONT_DOMAIN`, `PORT`
* Adicionado: `FRONTEND_URL`, `NODE_PORT`, `MAX_NUMBER_OF_WORKSPACES_DELETED_PER_EXECUTION`, `MESSAGING_PROVIDER_MICROSOFT_ENABLED`, `CALENDAR_PROVIDER_MICROSOFT_ENABLED`, `IS_MICROSOFT_SYNC_ENABLED`
### v0.40.0 to v0.41.0
### v0.40.0 para v0.41.0
Upgrade your Twenty instance to use v0.41.0 image
Atualize sua instância do Twenty para usar a imagem v0.41.0
```
yarn database:migrate:prod
yarn command:prod upgrade-0.41
```
**Environment Variables**
**Variáveis de Ambiente**
* Removed: `AUTH_MICROSOFT_TENANT_ID`
* Removido: `AUTH_MICROSOFT_TENANT_ID`
### v0.35.0 to v0.40.0
### v0.35.0 para v0.40.0
Upgrade your Twenty instance to use v0.40.0 image
Atualize sua instância do Twenty para usar a imagem v0.40.0
```
yarn database:migrate:prod
yarn command:prod upgrade-0.40
```
**Environment Variables**
**Variáveis de Ambiente**
* Added: `IS_EMAIL_VERIFICATION_REQUIRED`, `EMAIL_VERIFICATION_TOKEN_EXPIRES_IN`, `WORKFLOW_EXEC_THROTTLE_LIMIT`, `WORKFLOW_EXEC_THROTTLE_TTL`
* Adicionado: `IS_EMAIL_VERIFICATION_REQUIRED`, `EMAIL_VERIFICATION_TOKEN_EXPIRES_IN`, `WORKFLOW_EXEC_THROTTLE_LIMIT`, `WORKFLOW_EXEC_THROTTLE_TTL`
### v0.34.0 to v0.35.0
### v0.34.0 para v0.35.0
Upgrade your Twenty instance to use v0.35.0 image
Atualize sua instância do Twenty para usar a imagem v0.35.0
```
yarn database:migrate:prod
yarn command:prod upgrade-0.35
```
The `yarn database:migrate:prod` command will apply the migrations to the database structure (core and metadata schemas)
The `yarn command:prod upgrade-0.35` takes care of the data migration of all workspaces.
O comando `yarn database:migrate:prod` aplicará as migrações à estrutura do banco de dados (esquemas core e metadata)
O `yarn command:prod upgrade-0.35` cuida da migração de dados de todos os espaços de trabalho.
**Environment Variables**
**Variáveis de Ambiente**
* We replaced `ENABLE_DB_MIGRATIONS` with `DISABLE_DB_MIGRATIONS` (default value is now `false`, you probably don't have to set anything)
* Substituímos `ENABLE_DB_MIGRATIONS` por `DISABLE_DB_MIGRATIONS` (o valor padrão agora é `false`, você provavelmente não precisará definir nada)
### v0.33.0 to v0.34.0
### v0.33.0 para v0.34.0
Upgrade your Twenty instance to use v0.34.0 image
Atualize sua instância do Twenty para usar a imagem v0.34.0
```
yarn database:migrate:prod
yarn command:prod upgrade-0.34
```
The `yarn database:migrate:prod` command will apply the migrations to the database structure (core and metadata schemas)
The `yarn command:prod upgrade-0.34` takes care of the data migration of all workspaces.
O comando `yarn database:migrate:prod` aplicará as migrações à estrutura do banco de dados (esquemas core e metadata)
O `yarn command:prod upgrade-0.34` cuida da migração de dados de todos os espaços de trabalho.
**Environment Variables**
**Variáveis de Ambiente**
* Removed: `FRONT_BASE_URL`
* Added: `FRONT_DOMAIN`, `FRONT_PROTOCOL`, `FRONT_PORT`
* Removido: `FRONT_BASE_URL`
* Adicionado: `FRONT_DOMAIN`, `FRONT_PROTOCOL`, `FRONT_PORT`
We have updated the way we handle the frontend URL.
You can now set the frontend URL using the `FRONT_DOMAIN`, `FRONT_PROTOCOL` and `FRONT_PORT` variables.
If FRONT_DOMAIN is not set, the frontend URL will fall back to `SERVER_URL`.
Atualizamos a forma como lidamos com a URL do frontend.
Agora você pode definir a URL do frontend usando as variáveis `FRONT_DOMAIN`, `FRONT_PROTOCOL` e `FRONT_PORT`.
Se FRONT_DOMAIN não estiver definido, a URL do frontend voltará para `SERVER_URL`.
### v0.32.0 to v0.33.0
### v0.32.0 para v0.33.0
Upgrade your Twenty instance to use v0.33.0 image
Atualize sua instância do Twenty para usar a imagem v0.33.0
```
yarn command:prod cache:flush
@@ -257,68 +257,68 @@ yarn database:migrate:prod
yarn command:prod upgrade-0.33
```
The `yarn command:prod cache:flush` command will flush the Redis cache.
The `yarn database:migrate:prod` command will apply the migrations to the database structure (core and metadata schemas)
The `yarn command:prod upgrade-0.33` takes care of the data migration of all workspaces.
O comando `yarn command:prod cache:flush` limpará o cache do Redis.
O comando `yarn database:migrate:prod` aplicará as migrações à estrutura do banco de dados (esquemas core e metadata)
O `yarn command:prod upgrade-0.33` cuida da migração de dados de todos os espaços de trabalho.
Starting from this version, twenty-postgres image for DB became deprecated and twenty-postgres-spilo is used instead.
If you want to keep using twenty-postgres image, simply replace `twentycrm/twenty-postgres:${TAG}` with `twentycrm/twenty-postgres` in docker-compose.yml.
A partir desta versão, a imagem twenty-postgres para DB tornou-se obsoleta e o twenty-postgres-spilo é usado em vez disso.
Se você quiser continuar usando a imagem twenty-postgres, basta substituir `twentycrm/twenty-postgres:${TAG}` por `twentycrm/twenty-postgres` em docker-compose.yml.
### v0.31.0 to v0.32.0
### v0.31.0 para v0.32.0
Upgrade your Twenty instance to use v0.32.0 image
Atualize sua instância do Twenty para usar a imagem v0.32.0
**Schema and data migration**
**Migração de esquema e dados**
```
yarn database:migrate:prod
yarn command:prod upgrade-0.32
```
The `yarn database:migrate:prod` command will apply the migrations to the database structure (core and metadata schemas)
The `yarn command:prod upgrade-0.32` takes care of the data migration of all workspaces.
O comando `yarn database:migrate:prod` aplicará as migrações à estrutura do banco de dados (esquemas core e metadata)
O `yarn command:prod upgrade-0.32` cuida da migração de dados de todos os espaços de trabalho.
**Environment Variables**
**Variáveis de Ambiente**
We have updated the way we handle the Redis connection.
Atualizamos a forma como lidamos com a conexão Redis.
* Removed: `REDIS_HOST`, `REDIS_PORT`, `REDIS_USERNAME`, `REDIS_PASSWORD`
* Added: `REDIS_URL`
* Removido: `REDIS_HOST`, `REDIS_PORT`, `REDIS_USERNAME`, `REDIS_PASSWORD`
* Adicionado: `REDIS_URL`
Update your `.env` file to use the new `REDIS_URL` variable instead of the individual Redis connection parameters.
Atualize seu arquivo `.env` para usar a nova variável `REDIS_URL` em vez dos parâmetros de conexão Redis individuais.
We have also simplified the way we handle the JWT tokens.
Também simplificamos a forma como lidamos com os tokens JWT.
* Removed: `ACCESS_TOKEN_SECRET`, `LOGIN_TOKEN_SECRET`, `REFRESH_TOKEN_SECRET`, `FILE_TOKEN_SECRET`
* Added: `APP_SECRET`
* Removido: `ACCESS_TOKEN_SECRET`, `LOGIN_TOKEN_SECRET`, `REFRESH_TOKEN_SECRET`, `FILE_TOKEN_SECRET`
* Adicionado: `APP_SECRET`
Update your `.env` file to use the new `APP_SECRET` variable instead of the individual tokens secrets (you can use the same secret as before or generate a new random string)
Atualize seu arquivo `.env` para usar a nova variável `APP_SECRET` em vez dos segredos dos tokens individuais (você pode usar o mesmo segredo de antes ou gerar uma nova string aleatória)
**Connected Account**
**Conta Ligada**
If you are using connected account to synchronize your Google emails and calendars, you will need to activate the [People API](https://developers.google.com/people) on your Google Admin console.
Se você estiver usando uma conta conectada para sincronizar seus e-mails e calendários do Google, precisará ativar a [API People](https://developers.google.com/people) no console de administração do Google.
### v0.30.0 to v0.31.0
### v0.30.0 para v0.31.0
Upgrade your Twenty instance to use v0.31.0 image
Atualize sua instância do Twenty para usar a imagem v0.31.0
**Schema and data migration**:
**Migração de esquema e dados**:
```
yarn database:migrate:prod
yarn command:prod upgrade-0.31
```
The `yarn database:migrate:prod` command will apply the migrations to the database structure (core and metadata schemas)
The `yarn command:prod upgrade-0.31` takes care of the data migration of all workspaces.
O comando `yarn database:migrate:prod` aplicará as migrações à estrutura do banco de dados (esquemas core e metadata)
O `yarn command:prod upgrade-0.31` cuida da migração de dados de todos os espaços de trabalho.
### v0.24.0 to v0.30.0
### v0.24.0 para v0.30.0
Upgrade your Twenty instance to use v0.30.0 image
Atualize sua instância do Twenty para usar a imagem v0.30.0
**Breaking change**:
To enhance performances, Twenty now requires redis cache to be configured. We have updated our [docker-compose.yml](https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/docker-compose.yml) to reflect this.
Make sure to update your configuration and to update your environment variables accordingly:
**Mudança radical**:
Para melhorar o desempenho, o Twenty agora requer que o cache redis seja configurado. Atualizamos nosso [docker-compose.yml](https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-docker/docker-compose.yml) para refletir isso.
Certifique-se de atualizar sua configuração e suas variáveis de ambiente adequadamente:
```
REDIS_HOST={your-redis-host}
@@ -326,49 +326,49 @@ REDIS_PORT={your-redis-port}
CACHE_STORAGE_TYPE=redis
```
**Schema and data migration**:
**Migração de esquema e dados**:
```
yarn database:migrate:prod
yarn command:prod upgrade-0.30
```
The `yarn database:migrate:prod` command will apply the migrations to the database structure (core and metadata schemas)
The `yarn command:prod upgrade-0.30` takes care of the data migration of all workspaces.
O comando `yarn database:migrate:prod` aplicará as migrações à estrutura do banco de dados (esquemas core e metadata)
O `yarn command:prod upgrade-0.30` cuida da migração de dados de todos os espaços de trabalho.
### v0.23.0 to v0.24.0
### v0.23.0 para v0.24.0
Upgrade your Twenty instance to use v0.24.0 image
Atualize sua instância do Twenty para usar a imagem v0.24.0
Run the following commands:
Execute os seguintes comandos:
```
yarn database:migrate:prod
yarn command:prod upgrade-0.24
```
The `yarn database:migrate:prod` command will apply the migrations to the database structure (core and metadata schemas)
The `yarn command:prod upgrade-0.24` takes care of the data migration of all workspaces.
O comando `yarn database:migrate:prod` aplicará as migrações à estrutura do banco de dados (esquemas core e metadata)
O `yarn command:prod upgrade-0.24` cuida da migração de dados de todos os espaços de trabalho.
### v0.22.0 to v0.23.0
### v0.22.0 para v0.23.0
Upgrade your Twenty instance to use v0.23.0 image
Atualize sua instância do Twenty para usar a imagem v0.23.0
Run the following commands:
Execute os seguintes comandos:
```
yarn database:migrate:prod
yarn command:prod upgrade-0.23
```
The `yarn database:migrate:prod` command will apply the migrations to the Database.
The `yarn command:prod upgrade-0.23` takes care of the data migration, including transferring activities to tasks/notes.
O comando `yarn database:migrate:prod` aplicará as migrações ao Banco de Dados.
O `yarn command:prod upgrade-0.23` cuida da migração de dados, incluindo a transferência de atividades para tarefas/notas.
### v0.21.0 to v0.22.0
### v0.21.0 para v0.22.0
Upgrade your Twenty instance to use v0.22.0 image
Atualize sua instância do Twenty para usar a imagem v0.22.0
Run the following commands:
Execute os seguintes comandos:
```
yarn database:migrate:prod
@@ -376,6 +376,6 @@ yarn command:prod workspace:sync-metadata -f
yarn command:prod upgrade-0.22
```
The `yarn database:migrate:prod` command will apply the migrations to the Database.
The `yarn command:prod workspace:sync-metadata -f` command will sync the definition of standard objects to the metadata tables and apply to required migrations to existing workspaces.
The `yarn command:prod upgrade-0.22` command will apply specific data transformations to adapt to the new object defaultRequestInstrumentationOptions.
O comando `yarn database:migrate:prod` aplicará as migrações ao Banco de Dados.
O comando `yarn command:prod workspace:sync-metadata -f` sincronizará a definição de objetos padrão com as tabelas de metadados e aplicará as migrações necessárias aos espaços de trabalho existentes.
O comando `yarn command:prod upgrade-0.22` aplicará transformações de dados específicas para se adaptar às novas opções padrão de requestInstrumentationOptions do objeto.
@@ -1,30 +1,30 @@
---
title: Self-Host
description: Deploy and manage Twenty on your own infrastructure.
title: Auto-hospedagem
description: Implante e gerencie o Twenty na sua própria infraestrutura.
---
<Frame>
<img src="/images/user-guide/what-is-twenty/20.png" alt="AI" />
<img src="/images/user-guide/what-is-twenty/20.png" alt="IA" />
</Frame>
## Overview
## Visão geral
Twenty can be self-hosted on your own infrastructure, giving you full control over your data and deployment.
O Twenty pode ser auto-hospedado na sua própria infraestrutura, oferecendo controle total sobre seus dados e a implantação.
## Why Self-Host?
## Por que auto-hospedar?
* **Data ownership**: Keep all CRM data on your own servers
* **Compliance**: Meet regulatory requirements for data residency
* **Customization**: Full access to modify and extend the platform
* **Propriedade dos dados**: Mantenha todos os dados de CRM nos seus próprios servidores
* **Conformidade**: Atenda aos requisitos regulatórios de residência de dados
* **Personalização**: Acesso total para modificar e estender a plataforma
## Getting Started
## Primeiros passos
<CardGroup cols={2}>
<Card title="Docker Compose" icon="docker" href="/l/pt/developers/self-host/capabilities/docker-compose">
Quick setup with Docker
Configuração rápida com Docker
</Card>
<Card title="Cloud Providers" icon="cloud" href="/l/pt/developers/self-host/capabilities/cloud-providers">
Deploy on AWS, GCP, or Azure
<Card title="Provedores de nuvem" icon="cloud" href="/l/pt/developers/self-host/capabilities/cloud-providers">
Implante na AWS, GCP ou Azure
</Card>
</CardGroup>