i18n - docs translations (#21337)

Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
github-actions[bot]
2026-06-08 19:28:21 +02:00
committed by GitHub
parent 356cec5f24
commit 44c4c27c76
25 changed files with 1041 additions and 231 deletions
@@ -123,20 +123,22 @@ yarn twenty dev
yarn twenty dev --once
```
| Команда | Поведение | Когда использовать |
| ------------------------ | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `yarn twenty dev` | Отслеживает и повторно синхронизирует при каждом изменении. Продолжает работать, пока вы его не остановите. | Интерактивная локальная разработка. |
| `yarn twenty dev --once` | Одна сборка и синхронизация, завершает работу с кодом `0` при успехе и `1` при ошибке. | CI, хуки pre-commit, AI-агенты, скриптовые рабочие процессы. |
| Команда | Поведение | Когда использовать |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `yarn twenty dev` | Отслеживает и повторно синхронизирует при каждом изменении. Продолжает работать, пока вы его не остановите. | Интерактивная локальная разработка. |
| `yarn twenty dev --once` | Одна сборка и синхронизация, завершает работу с кодом `0` при успехе и `1` при ошибке. | CI, хуки pre-commit, AI-агенты, скриптовые рабочие процессы. |
| `yarn twenty dev --once --dry-run` | Создает и выводит изменения метаданных **без их применения**. | Проверка того, какие изменения внесет синхронизация, прежде чем зафиксировать их. |
Оба режима требуют аутентифицированного удалённого репозитория.
Оба режима требуют аутентифицированного удалённого репозитория. Смотрите раздел [Syncing & recovery](/l/ru/developers/extend/apps/operations/sync-and-recovery#previewing-changes-dry-run) для получения дополнительной информации о `--dry-run`.
### Параметры режима разработки
| Флаг | Описание |
| ------------------------------------- | ------------------------------------------------------------------------------------- |
| `--once` | Выполнить сборку и синхронизацию один раз, затем завершить работу. |
| `--debounceMs \<ms>` | Установить задержку дебаунса изменений файлов в миллисекундах (по умолчанию: `2000`). |
| `--verbose` / `--debug` | Показывать подробные журналы сборки, запросы синхронизации и трассировки ошибок. |
| Флаг | Описание |
| ------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `--once` | Выполнить сборку и синхронизацию один раз, затем завершить работу. |
| `--dry-run` | С опцией `--once` можно просмотреть изменения метаданных, не применяя их. Ничего не записывает. |
| `--debounceMs \<ms>` | Установить задержку дебаунса изменений файлов в миллисекундах (по умолчанию: `2000`). |
| `--verbose` / `--debug` | Показывать подробные журналы сборки, запросы синхронизации и трассировки ошибок. |
## Что вы можете создать
@@ -200,45 +200,22 @@ export default defineFrontComponent({
Front-компоненты выполняются в браузере в изолированном Web Worker, в то время как [логические функции](/l/ru/developers/extend/apps/logic/logic-functions) выполняются на стороне сервера. Между ними нет прямого внутрипроцессного вызова — вместо этого front-компонент обращается к логической функции по HTTP.
Логическая функция, объявленная с `httpRouteTriggerSettings`, доступна по эндпоинту `/s/` по адресу `${TWENTY_API_URL}/s\<path>`. Ваш front-компонент вызывает этот маршрут с помощью `fetch`, аутентифицируясь с использованием `TWENTY_APP_ACCESS_TOKEN`, который Twenty внедряет в worker.
Логическая функция, объявленная с `httpRouteTriggerSettings`, доступна по эндпоинту `/s/` по адресу `${TWENTY_API_URL}/s\<path>`. Ваш front-компонент вызывает этот маршрут с помощью `RestApiClient` из `twenty-client-sdk/rest`, который аутентифицируется с использованием `TWENTY_APP_ACCESS_TOKEN`, который Twenty внедряет в worker.
Небольшой переиспользуемый хелпер делает места вызова чище:
```ts src/shared/call-app-route.ts
export async function callAppRoute(
path: string,
body: Record<string, unknown>,
): Promise<unknown> {
const apiUrl = process.env.TWENTY_API_URL ?? '';
const token = process.env.TWENTY_APP_ACCESS_TOKEN;
const res = await fetch(`${apiUrl}/s${path}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...(token ? { Authorization: `Bearer ${token}` } : {}),
},
body: JSON.stringify(body),
});
if (!res.ok) {
throw new Error(`Logic function failed (${res.status})`);
}
return res.json();
}
```
`RestApiClient` создан именно для этого. Он считывает `TWENTY_API_URL` и `TWENTY_APP_ACCESS_TOKEN` из окружения worker, добавляет заголовок `Authorization: Bearer`, сериализует и парсит JSON и выбрасывает `RestApiClientError`, когда токен или URL отсутствуют или ответ не является 2xx — чтобы вам не приходилось реализовывать этот шаблонный код в каждом компоненте.
Безголовый front-компонент может выполнить вызов при монтировании через компонент `Command`, а затем автоматически размонтироваться:
```tsx src/front-components/sync-prs.tsx
import { defineFrontComponent } from 'twenty-sdk/define';
import { Command } from 'twenty-sdk/command';
import { callAppRoute } from 'src/shared/call-app-route';
import { RestApiClient } from 'twenty-client-sdk/rest';
const SyncPrs = () => {
const execute = async () => {
await callAppRoute('/github/fetch-prs', {
const client = new RestApiClient();
await client.post('/s/github/fetch-prs', {
owner: 'twentyhq',
repo: 'twenty',
});
@@ -256,7 +233,7 @@ export default defineFrontComponent({
});
```
`path`, переданный в `callAppRoute`, должен совпадать с `httpRouteTriggerSettings.path` логической функции (префикс `/s` добавляется хелпером):
Путь, передаваемый клиенту, — это общедоступный путь маршрута: значение `httpRouteTriggerSettings.path` для логической функции с префиксом `/s`. Сохраните `isAuthRequired: true`; клиент передает токен доступа к приложению Twenty mints для вашего компонента:
```ts src/logic-functions/fetch-prs.logic-function.ts
import { defineLogicFunction } from 'twenty-sdk/define';
@@ -284,6 +261,48 @@ export default defineLogicFunction({
`TWENTY_API_URL` и `TWENTY_APP_ACCESS_TOKEN` внедряются автоматически — см. [переменные приложения](#application-variables). Поскольку секретные переменные приложения никогда не раскрываются front-компонентам, храните ключи API и другую конфиденциальную логику в логической функции, а не во front-компоненте.
</Note>
### Справочник по RestApiClient
Импортируйте `RestApiClient` из `twenty-client-sdk/rest`. Он принадлежит к тому же семейству клиентов, что и `CoreApiClient` и `MetadataApiClient`, но предназначен для HTTP-маршрутов вашего приложения вместо GraphQL API.
| Метод | Описание |
| --------------------------------- | ----------------------------------------- |
| `get(path, options?)` | Отправляет запрос `GET` |
| `post(path, body?, options?)` | Отправляет запрос `POST` |
| `put(path, body?, options?)` | Отправляет запрос `PUT` |
| `patch(path, body?, options?)` | Отправляет запрос `PATCH` |
| `delete(path, options?)` | Отправляет запрос `DELETE` |
| `request(method, path, options?)` | Универсальный запрос с любым HTTP-методом |
В `options` принимаются `headers`, `query` (объект с параметрами строки запроса; значения, равные null или undefined, пропускаются) и `AbortSignal` через `signal`. Объект `body`, не являющийся `FormData`, автоматически сериализуется в JSON. При получении `401` клиент один раз обновляет токен доступа через хост и повторяет запрос.
Базовый URL и токен по умолчанию берутся из окружения. При необходимости передавайте переопределения в конструктор — например, в тестах:
```ts
const client = new RestApiClient({
baseUrl: 'https://api.example.com',
token: 'my-token',
});
```
Неудачные запросы выбрасывают `RestApiClientError`, предоставляющую `status`, `statusText`, `url` и разобранное `body`:
```tsx
import { RestApiClient, RestApiClientError } from 'twenty-client-sdk/rest';
const client = new RestApiClient();
try {
const prs = await client.get('/s/github/fetch-prs', {
query: { state: 'open' },
});
} catch (error) {
if (error instanceof RestApiClientError) {
console.error(error.status, error.body);
}
}
```
## Доступ к контексту времени выполнения
Внутри вашего компонента используйте хуки SDK для доступа к текущему пользователю, записи и экземпляру компонента:
@@ -20,6 +20,9 @@ icon: rocket
<Card title="CLI" icon="terminal" href="/l/ru/developers/extend/apps/operations/cli">
Справочник по `yarn twenty` — exec, logs, uninstall, remotes.
</Card>
<Card title="Синхронизация и восстановление" icon="компас" href="/l/ru/developers/extend/apps/operations/sync-and-recovery">
Какие команды когда использовать, как читать diff синхронизации и пошаговое восстановление.
</Card>
<Card title="Тестирование" icon="flask" href="/l/ru/developers/extend/apps/operations/testing">
Настройка Vitest, интеграционные тесты, проверка типов, рабочий процесс CI.
</Card>
@@ -0,0 +1,111 @@
---
title: Синхронизация и восстановление
description: Какую команду когда использовать, как читать вывод синхронизации и поэтапный план восстановления на случай расхождения локальных метаданных — до того, как дойдет до полного сброса.
icon: компас
---
Локальная разработка приложения строится вокруг **синхронизации**: CLI пересобирает ваш манифест, а сервер применяет только разницу между ним и метаданными, которые уже есть в вашем рабочем пространстве. На этой странице описано, какую команду выбрать, как читать, что изменила синхронизация, и что делать — по шагам — когда локальное состояние выглядит несогласованным.
## Какую команду и когда использовать
<Note>
Для повседневной локальной разработки вам почти всегда нужна команда `yarn twenty dev`. Развертывание и публикация предназначены для выпуска релизов, **а не** для локального цикла разработки.
</Note>
| Вы хотите… | Команда | Заметки |
| ---------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Выполнять локальные итерации с синхронизацией в реальном времени | `yarn twenty dev` | Отслеживает ваши файлы и синхронизирует при каждом изменении. |
| Выполнить одну синхронизацию и выйти (CI, скрипты, хуки) | `yarn twenty dev --once` | Одна сборка + синхронизация, затем завершение работы. |
| Предпросмотр изменений **без их применения** | `yarn twenty dev --once --dry-run` | Вычисляет и выводит diff; ничего не записывает. |
| Удалить приложение из рабочего пространства | `yarn twenty app:uninstall` | Добавьте `--yes`, чтобы пропустить запрос подтверждения. |
| Отправить на сервер tar-архив | `yarn twenty app:publish --private` | Требуется **строго более высокая** версия в `package.json` — см. [Публикация](/l/ru/developers/extend/apps/operations/publishing). |
| Опубликовать на маркетплейсе (npm) | `yarn twenty app:publish` | — |
| Установить / обновить развернутую версию | `yarn twenty app:install` | Устанавливает версию, которая сейчас развернута. |
| Очистить локальный сервер и начать с нуля | `yarn twenty docker:reset` | Удаляет **все** локальные данные — крайняя мера. |
### Для локальной синхронизации не нужно повышать версию
Правило строго возрастающей `version` (`VERSION_ALREADY_EXISTS` при deploy, `APP_ALREADY_INSTALLED` / `CANNOT_DOWNGRADE_APPLICATION` при install) относится к **`app:publish` / `app:install`** — пути релизов. `yarn twenty dev` синхронизирует ваш манифест на месте и никогда не требует изменения версии, поэтому вам не нужно трогать `package.json`, чтобы делать итерации. Если вы ловите себя на том, что поднимаете версию, чтобы протестировать локальное изменение, значит вы используете релизный путь, когда вам нужен цикл разработки (dev loop).
## Чтение вывода синхронизации
Каждая синхронизация выводит изменения метаданных, которые она применила (или применила бы, с `--dry-run`):
```text filename="Terminal"
Metadata changes: 2 created, 1 updated, 1 deleted
created objectMetadata rocket
created fieldMetadata timelineActivities
updated fieldMetadata launchedAt
deleted pageLayout legacyTab
✓ Synced
```
Это ваша первая диагностическая точка: она показывает, какие именно объекты, поля и макеты изменились, чтобы вы могли подтвердить, что синхронизация сделала то, что вы ожидали, до проверки в интерфейсе.
Когда синхронизация завершается с ошибкой на одной сущности, в сообщении указываются проблемная сущность и её `universalIdentifier`, например:
```text
Migration action 'create' for 'fieldMetadata' (universalIdentifier: 2020...4337) failed
```
Используйте этот идентификатор, чтобы найти сущность в своем манифесте (и, при необходимости, в рабочем пространстве), вместо того чтобы гадать, какая из них конфликтует.
## Предпросмотр изменений (dry run)
`yarn twenty dev --once --dry-run` собирает ваш манифест, запрашивает у сервера план миграции и выводит его — **без применения чего-либо**. Это безопасный способ ответить на вопрос «что изменит эта синхронизация?» до того, как вы на неё согласитесь.
```bash filename="Terminal"
yarn twenty dev --once --dry-run
```
```text filename="Terminal"
Building manifest...
Computing metadata diff (dry run, nothing will be applied)...
Metadata changes: 1 created, 1 updated
created fieldMetadata timelineActivities
updated objectMetadata rocket
✓ Dry run complete for My App — no changes were applied
```
Пробный запуск (dry run):
* **Ничего не записывает** — ни миграции метаданных, ни обновления записи приложения, ни изменений ролей/вкладок по умолчанию, ни генерации API‑клиента.
* Возвращает **тот же diff**, который применит реальная синхронизация, чтобы вы могли заранее просмотреть создаваемые/обновляемые/удаляемые сущности.
* Полезен перед рискованным изменением, при проверке изменения, сгенерированного ИИ, или в скрипте, который должен завершаться с ошибкой, если вот-вот будет применено неожиданное изменение.
<Note>
Пробный запуск предварительно показывает только изменения **метаданных** и требует, чтобы приложение хотя бы один раз уже было синхронизировано (чтобы рабочее пространство знало о нём). Если вы запускаете его для приложения, которое никогда не синхронизировалось, сервер сообщит, что приложение не установлено — сначала один раз выполните `yarn twenty dev`.
</Note>
## Лестница восстановления
Когда локальные метаданные выглядят неверно, действуйте поэтапно в следующем порядке и останавливайтесь, как только проблема решена. Каждый следующий шаг более разрушителен, чем предыдущий.
1. **Повторно синхронизируйте.** Снова выполните `yarn twenty dev --once`. Синхронизации идемпотентны — повторный запуск корректного манифеста безопасен и часто устраняет временный сбой.
2. **Просмотрите план.** Выполните `yarn twenty dev --once --dry-run`, чтобы увидеть, что именно намеревается изменить следующая синхронизация, не применяя эти изменения.
3. **Прочитайте сообщение об ошибке.** Если синхронизация завершается с ошибкой, обратите внимание на тип метаданных и `universalIdentifier` в сообщении (см. выше) и найдите эту сущность в своем манифесте. Конфликт обычно указывает на дублированный или повторно используемый идентификатор.
4. **Удалите и переустановите.** Выполните `yarn twenty app:uninstall`, затем синхронизируйте снова (`yarn twenty dev`). Это пересобирает метаданные приложения с нуля, сохраняя остальную часть вашего рабочего пространства нетронутой.
5. **Полный сброс (крайняя мера).** Выполните `yarn twenty docker:reset`, затем заново выполните начальное наполнение данными и синхронизацию.
<Warning>
`yarn twenty docker:reset` удаляет **все** данные в вашей локальной инсталляции — все рабочие пространства, записи и приложения. Используйте его только после того, как предыдущие шаги не помогли.
</Warning>
<Note>
Столкнулись с ошибкой метаданных? Пожалуйста, [создайте issue](https://github.com/twentyhq/twenty/issues/new/choose) и приложите сообщение о сбое миграции (с типом метаданных и `universalIdentifier`), вывод `Metadata changes` из синхронизации и команды, которые вы запускали.
</Note>
## Избегайте одновременных синхронизаций в одном рабочем пространстве
Синхронизация применяет миграции метаданных. Запуск нескольких операций sync, deploy или install по отношению к **одному и тому же рабочему пространству одновременно** — например, из нескольких терминалов или при параллельных итерациях агентов ИИ — может перемешать эти миграции и оставить метаданные в частично примененном состоянии.
Сервер последовательно обрабатывает синхронизации для каждого рабочего пространства, чтобы предотвратить это, но вам всё равно следует пропускать чувствительные операции с метаданными через **один** процесс, а не запускать их параллельно. Если вы организуете разработку с несколькими агентами, направляйте их вызовы sync/deploy/install через одну очередь, чтобы в каждый момент времени выполнялась только одна операция.
## Как различать типы сбоев
Когда что‑то идёт не так, diff метаданных и именованные ошибки помогают определить, на каком этапе произошел сбой:
* **Ошибка сборки манифеста** — CLI завершается с ошибкой до синхронизации (`MANIFEST_BUILD_FAILED`, `TYPECHECK_FAILED`); исправьте исходный код приложения.
* **Ошибка синхронизации / миграции** — сборка проходит успешно, но применение diff завершается сбоем с указанием сущности и `universalIdentifier`; исправьте конфликтующие метаданные.
* **Ошибка выполнения кода приложения** — синхронизация проходит успешно, но ваши логические функции или компоненты ведут себя неправильно во время выполнения; проверьте [журналы функций](/l/ru/developers/extend/apps/operations/cli).
* **Локальное состояние экземпляра** — ни один из вышеперечисленных пунктов не подходит, и рабочее пространство всё ещё выглядит неправильно; двигайтесь вниз по лестнице восстановления.