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

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

View File

@@ -0,0 +1,22 @@
---
title: Лучшие практики
---
Этот документ описывает лучшие практики, которым следует следовать при работе с бэкендом.
## Следуйте модульному подходу
Бэкенд следует модульному подходу, который является основным принципом при работе с NestJS. Убедитесь, что вы разбиваете код на повторно используемые модули, чтобы поддерживать чистую и хорошо организованную кодовую базу.
Каждый модуль должен инкапсулировать конкретную функциональность и иметь чётко определённую область ответственности. Этот модульный подход обеспечивает четкое разделение областей ответственности и устраняет лишние сложности.
## Предоставляйте сервисы для использования в модулях
Всегда создавайте сервисы с одной чёткой областью ответственности, что повышает читаемость и облегчает сопровождение кода. Называйте сервисы понятно и единообразно.
Также следует экспортировать сервисы, которые вы хотите использовать в других модулях. Экспорт сервисов в другие модули возможен благодаря мощной системе внедрения зависимостей NestJS и способствует слабой связности между компонентами.
## Избегайте использования типа `any`
Когда вы объявляете переменную с типом `any`, система проверки типов TypeScript перестаёт выполнять проверку, что позволяет присваивать переменной значения любого типа. TypeScript использует вывод типов для определения типа переменной на основе значения. Если объявить переменную с типом `any`, TypeScript больше не сможет вывести её тип. Это затрудняет выявление ошибок, связанных с типами, во время разработки, приводит к ошибкам времени выполнения и делает код менее поддерживаемым, менее надёжным и труднее понятным для других разработчиков.
Поэтому всё должно иметь тип. Поэтому, если вы создаёте новый объект с именем и фамилией, следует создать интерфейс или тип с полями имя и фамилия, определяющий структуру объекта, с которым вы работаете.

View File

@@ -0,0 +1,39 @@
---
title: Пользовательские объекты
---
Объекты - это структуры, которые позволяют хранить данные (записи, атрибуты и значения), специфичные для организации. В Twenty предусмотрены как стандартные, так и пользовательские объекты.
Стандартные объекты - это встроенные объекты с набором атрибутов, доступных для всех пользователей. В Twenty к стандартным объектам относятся Company и Person. Стандартные объекты имеют стандартные поля, которые также доступны всем пользователям Twenty, например, Company.displayName.
Пользовательские объекты - это объекты, которые вы можете создать для хранения уникальной информации для вашей организации. Они не являются встроенными; участники вашего рабочего пространства могут создавать и настраивать пользовательские объекты для хранения информации, для которой стандартные объекты не подходят.
## Схема высокого уровня
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/custom-object-schema.png" alt="Схема высокого уровня" />
</div>
<br />
## Как это работает
Пользовательские объекты происходят из таблиц метаданных, определяющих форму, имя и тип объектов. Вся эта информация присутствует в базе данных схемы метаданных, состоящей из таблиц:
* **DataSource**: Указывает, где находятся данные.
* **Объект**: Описывает объект и связывается с DataSource.
* **Поле**: Описывает поля объекта и соединяет с объектом.
Чтобы добавить пользовательский объект, участник рабочего пространства сделает запрос к /metadata API. Это обновляет метаданные соответствующим образом и создает схему GraphQL на основе метаданных, храня их в кэше GQL для дальнейшего использования.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/add-custom-objects.jpeg" alt="Запросите API /metadata для добавления пользовательских объектов" />
</div>
<br />
Для извлечения данных процесс включает выполнение запросов через конечную точку /graphql и их передачу через Query Resolver.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/custom-object-schema.png" alt="Запросите конечную точку /graphql для получения данных" />
</div>

View File

@@ -0,0 +1,46 @@
---
title: Флаги функций
---
Флаги функций используются для скрытия экспериментальных функций. Для Twenty они устанавливаются на уровне рабочей области, а не на уровне пользователя.
## Добавление нового флага функции
В `FeatureFlagKey.ts` добавьте флаг функции:
```ts
type FeatureFlagKey =
| 'IS_FEATURENAME_ENABLED'
| ...;
```
Также добавьте его в перечисление в `feature-flag.entity.ts`:
```ts
enum FeatureFlagKeys {
IsFeatureNameEnabled = 'IS_FEATURENAME_ENABLED',
...
}
```
Чтобы применить флаг функции к **бэкенд**-функции, используйте:
```ts
@Gate({
featureFlag: 'IS_FEATURENAME_ENABLED',
})
```
Чтобы применить флаг функции к **фронтенд**-функции, используйте:
```ts
const isFeatureNameEnabled = useIsFeatureEnabled('IS_FEATURENAME_ENABLED');
```
## Настройте флаги функций для развертывания
Измените соответствующую запись в таблице `core.featureFlag`:
| идентификатор | ключ | workspaceId | значение |
| ------------- | ------------------------ | ----------- | -------- |
| Случайный | `IS_FEATURENAME_ENABLED` | WorkspaceID | `истина` |

View File

@@ -0,0 +1,125 @@
---
title: Архитектура папок
info: Подробное рассмотрение нашей архитектуры папок сервера
---
Структура серверной директории следующая:
```
server
└───ability
└───constants
└───core
└───database
└───decorators
└───filters
└───guards
└───health
└───integrations
└───metadata
└───workspace
└───utils
```
## Правила доступа
Определяет разрешения и включает обработчики для каждого объекта.
## Декораторы
Определяет пользовательские декораторы в NestJS для расширенной функциональности.
Смотрите [пользовательские декораторы](https://docs.nestjs.com/custom-decorators) для более подробной информации.
## Фильтры
Включает фильтры исключений для обработки исключений, которые могут возникать в конечных точках GraphQL.
## Гарды
Смотрите [защиты](https://docs.nestjs.com/guards) для более подробной информации.
## Работоспособность
Включает общедоступный REST API (healthz), который возвращает JSON, чтобы подтвердить, что база данных работает должным образом.
## Метаданные
Определяет пользовательские объекты и предоставляет GraphQL API (graphql/metadata).
## Рабочее пространство
Генерирует и обслуживает пользовательскую GraphQL схему на основе метаданных.
### Структура каталога рабочей области
```
workspace
└───workspace-schema-builder
└───factories
└───graphql-types
└───database
└───interfaces
└───object-definitions
└───services
└───storage
└───utils
└───workspace-resolver-builder
└───factories
└───interfaces
└───workspace-query-builder
└───factories
└───interfaces
└───workspace-query-runner
└───interfaces
└───utils
└───workspace-datasource
└───workspace-manager
└───workspace-migration-runner
└───utils
└───workspace.module.ts
└───workspace.factory.spec.ts
└───workspace.factory.ts
```
Корень каталога рабочей области включает `workspace.factory.ts`, файл, содержащий функцию `createGraphQLSchema`. Эта функция генерирует схему, специфичную для рабочей области, используя метаданные для адаптации схемы для индивидуальных рабочих областей. Разделением построения схемы и резолвера, мы используем функцию `makeExecutableSchema`, которая объединяет эти отдельные элементы.
Эта стратегия касается не только организации, но и помогает в оптимизации, например в кэшировании сгенерированных определений типов для повышения производительности и масштабируемости.
### Конструктор схем рабочей области
Генерирует GraphQL схему и включает:
#### Фабрики:
Специализированные конструкторы для генерации связанных с GraphQL конструкций.
* Фабрика типов переводит метаданные поля в типы GraphQL, используя `TypeMapperService`.
* Фабрика определения типов создает объекты ввода или вывода GraphQL на основе `objectMetadata`.
#### Типы GraphQL
Включает перечисления, входы, объекты и скаляры и служит строительными блоками для построения схемы.
#### Интерфейсы и определение объектов
Содержит чертежи для GraphQL сущностей и включает как предопределенные, так и пользовательские типы, такие как `MONEY` или `URL`.
#### Сервисы
Содержит сервис, ответственный за ассоциацию FieldMetadataType с соответствующим скаляром GraphQL или модификаторами запроса.
#### Хранилище
Включает класс `TypeDefinitionsStorage`, содержащий переиспользуемые определения типов, предотвращая дублирование GraphQL типов.
### Конструктор резолверов рабочей области
Создает функции резолверов для запроса и изменения схемы GraphQL.
Каждая фабрика в этом каталоге отвечает за создание отдельного типа резолвера, как, например, `FindManyResolverFactory`, предназначенной для адаптируемого применения в различных таблицах.
### Выполнители запросов рабочей области
Выполняет сгенерированные запросы в базе данных и анализирует результат.

View File

@@ -0,0 +1,41 @@
---
title: Очередь сообщений
---
Очереди позволяют выполнять асинхронные операции. Их можно использовать для выполнения фоновых задач, таких как отправка приветственного письма при регистрации.
Каждый случай использования будет иметь собственный класс очереди, расширенный из `MessageQueueServiceBase`.
В настоящее время мы поддерживаем только `bull-mq`[bull-mq](https://bullmq.io/) в качестве драйвера очереди.
## Шаги для создания и использования новой очереди
1. Добавьте имя очереди для вашей новой очереди в перечисление `MESSAGE_QUEUES`.
2. Предоставьте фабричную реализацию очереди с именем очереди в качестве токена зависимости.
3. Инжектируйте созданную вами очередь в необходимый модуль/сервис с именем очереди в качестве токена зависимости.
4. Добавьте класс worker с внедрением зависимостей на основе токена, как у producer.
### Пример использования
```ts
class Resolver {
constructor(@Inject(MESSAGE_QUEUES.custom) private queue: MessageQueueService) {}
async onSomeAction() {
//business logic
await this.queue.add(someData);
}
}
//async worker
class CustomWorker {
constructor(@Inject(MESSAGE_QUEUES.custom) private queue: MessageQueueService) {
this.initWorker();
}
async initWorker() {
await this.queue.work(async ({ id, data }) => {
//worker logic
});
}
}
```

View File

@@ -0,0 +1,87 @@
---
title: Команды бекэнда
icon: terminal
---
## Полезные команды
Эти команды следует выполнять из папки packages/twenty-server.
Из любой другой папки можно запускать `npx nx {command} twenty-server` (или `npx nx run twenty-server:{command}`).
### Первоначальная настройка
```
npx nx database:reset twenty-server # setup the database with dev seeds
```
### Запуск сервера
```
npx nx run twenty-server:start
```
### Lint
```
npx nx run twenty-server:lint # pass --fix to fix lint errors
```
### Тест
```
npx nx run twenty-server:test:unit # run unit tests
npx nx run twenty-server:test:integration # run integration tests
```
Примечание: вы можете использовать `npx nx run twenty-server:test:integration:with-db-reset`, если необходимо сбросить базу данных перед выполнением интеграционных тестов.
### Сброс базы данных
Если вы хотите сбросить и заполнить базу данных начальными данными, выполните следующую команду:
```bash
npx nx run twenty-server:database:reset
```
### Миграции
#### Для объектов в схемах Core/Metadata (TypeORM)
```bash
npx nx run twenty-server:database:migrate:generate
```
## Технологический стек
Для работы с серверной частью Twenty в основном использует NestJS.
Prisma был первым ORM, который мы использовали. Но чтобы пользователи могли создавать собственные поля и объекты, использование более низкого уровня было более логичным, так как нам нужен был тонкий контроль. Теперь проект использует TypeORM.
Вот как теперь выглядит стек технологий.
**Ядро**
* [NestJS](https://nestjs.com/)
* [TypeORM](https://typeorm.io/)
* [GraphQL Yoga](https://the-guild.dev/graphql/yoga-server)
**База данных**
* [Postgres](https://www.postgresql.org/)
**Интеграции сторонних решений**
* [Sentry](https://sentry.io/welcome/) для отслеживания ошибок
**Тестирование**
* [Jest](https://jestjs.io/)
**Инструменты**
* [Yarn](https://yarnpkg.com/)
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
**Разработка**
* [AWS EKS](https://aws.amazon.com/eks/)

View File

@@ -0,0 +1,85 @@
---
title: Приложение Zapier
---
Легко синхронизируйте Twenty с более чем 3000 приложениями с помощью [Zapier](https://zapier.com/). Автоматизируйте задачи, повышайте продуктивность и улучшайте ваши отношения с клиентами!
## О Zapier
Zapier — это инструмент, который позволяет автоматизировать рабочие процессы, соединяя приложения, которые ваша команда использует каждый день. Основная концепция Zapier — это рабочие процессы автоматизации, называемые Zaps, которые включают триггеры и действия.
Вы можете узнать больше о том, как работает Zapier [здесь](https://zapier.com/how-it-works).
## Настройка
### Шаг 1: Установите пакеты Zapier
```bash
cd packages/twenty-zapier
yarn
```
### Шаг 2: Войдите через CLI
Используйте свои учетные данные Zapier для входа с помощью CLI:
```bash
zapier login
```
### Шаг 3: Настройка переменных окружения
В каталоге `packages/twenty-zapier` выполните:
```bash
cp .env.example .env
```
Запустите приложение локально, перейдите на [http://localhost:3000/settings/api-webhooks](http://localhost:3000/settings/api-webhooks) и сгенерируйте API ключ.
Замените значение **YOUR_API_KEY** в файле `.env` сгенерированным вами API ключом.
## Разработка
<Warning>
Перед выполнением любой команды `zapier` обязательно запустите `yarn build`.
</Warning>
### Тест
```bash
yarn test
```
### Lint
```bash
yarn format
```
### Отслеживайте и компилируйте при редактировании кода
```bash
yarn watch
```
### Проверьте ваше приложение Zapier
```bash
yarn validate
```
### Разверните ваше приложение Zapier
```bash
yarn deploy
```
### Список всех команд CLI Zapier
```bash
zapier
```