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,102 @@
---
title: 개념
description: Twenty 앱이 작동하는 방식 — 엔티티 모델, 샌드박싱, 설치 라이프사이클.
icon: sitemap
---
Twenty 앱은 사용자 정의 객체, 로직, UI 컴포넌트 및 AI 기능으로 워크스페이스를 확장하는 TypeScript 패키지입니다. 앱은 Twenty 플랫폼에서 완전한 샌드박싱과 권한 제어 하에 실행됩니다.
## 앱 작동 방식
앱은 `twenty-sdk` 패키지의 `defineEntity()` 함수를 사용해 선언된 **엔티티**의 모음입니다. SDK는 빌드 시점에 AST 분석을 통해 이러한 선언을 감지하고, 앱이 워크스페이스에 추가하는 내용을 완전하게 설명한 **매니페스트**를 생성합니다. 이 함수들은 빌드 시점에 구성을 검증하고 IDE 자동 완성과 타입 안정성을 제공합니다.
```
your-app/
├── src/
│ ├── application-config.ts ← defineApplication (required, one per app)
│ ├── roles/ ← defineRole
│ ├── objects/ ← defineObject
│ ├── fields/ ← defineField
│ ├── logic-functions/ ← defineLogicFunction
│ ├── front-components/ ← defineFrontComponent
│ ├── skills/ ← defineSkill
│ ├── agents/ ← defineAgent
│ ├── views/ ← defineView
│ ├── navigation-menu-items/ ← defineNavigationMenuItem
│ └── page-layouts/ ← definePageLayout
├── public/ ← Static assets (images, icons)
└── package.json
```
<Note>
**파일 구성은 사용자의 선택입니다.** 엔티티 감지는 AST 기반이며 — 파일 위치와 관계없이 SDK가 `export default defineEntity(...)` 호출을 찾습니다. 위의 폴더 구조는 관례이며 필수 사항은 아닙니다.
</Note>
## 엔티티 유형
| 엔티티 | 목적 | 문서 |
| --------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| **애플리케이션** | 앱 식별, 기본 역할, 변수 | [Application Config](/l/ko/developers/extend/apps/config/application) |
| **역할** | 객체와 필드에 대한 권한 세트 | [Roles & Permissions](/l/ko/developers/extend/apps/config/roles) |
| **객체** | 필드가 있는 사용자 정의 레코드 타입 | [Objects](/l/ko/developers/extend/apps/data/objects) |
| **필드** | 다른 앱의 객체에 필드를 추가 | [Extending Objects](/l/ko/developers/extend/apps/data/extending-objects) |
| **관계** | 객체 간 양방향 링크 | [Relations](/l/ko/developers/extend/apps/data/relations) |
| **로직 함수** | 트리거가 있는 서버 측 TypeScript | [로직 함수](/l/ko/developers/extend/apps/logic/logic-functions) |
| **스킬** | 재사용 가능한 AI 에이전트 지침 | [스킬 및 에이전트](/l/ko/developers/extend/apps/logic/skills-and-agents) |
| **에이전트** | 사용자 지정 프롬프트를 사용하는 AI 에이전트 | [스킬 및 에이전트](/l/ko/developers/extend/apps/logic/skills-and-agents) |
| **연결 제공자** | 서드파티 API용 OAuth 자격 증명 | [Connections](/l/ko/developers/extend/apps/logic/connections) |
| **뷰** | 사전 구성된 레코드 목록 뷰 | [Views](/l/ko/developers/extend/apps/layout/views) |
| **내비게이션 메뉴 항목** | 사용자 정의 사이드바 항목 | [Navigation Menu Items](/l/ko/developers/extend/apps/layout/navigation-menu-items) |
| **페이지 레이아웃** | 레코드 상세 페이지의 탭과 위젯 | [Page Layouts](/l/ko/developers/extend/apps/layout/page-layouts) |
| **프런트 컴포넌트** | Twenty 내부의 샌드박스 React UI | [프런트 컴포넌트](/l/ko/developers/extend/apps/layout/front-components) |
| **공유 의존성** | 앱의 프런트 컴포넌트에서 공유되고 package.json에 선언된 의존성 | [공유 의존성](/l/ko/developers/extend/apps/layout/front-components#sharing-dependencies-across-front-components) |
| **명령 메뉴 항목** | 빠른 작업 및 Cmd+K 항목 | [Command Menu Items](/l/ko/developers/extend/apps/layout/command-menu-items) |
## 샌드박싱
* **로직 함수**는 서버의 격리된 Node.js 프로세스에서 실행됩니다. 이들은 타입이 지정된 API 클라이언트를 통해서만 데이터에 액세스하며, 이 클라이언트는 실행을 트리거한 사람 또는 앱 자체로 작동합니다. [호출에 사용되는 액세스 권한](/l/ko/developers/extend/apps/logic/logic-functions#whose-access-a-call-uses)을 참조하세요.
* **프런트 컴포넌트**는 Remote DOM을 사용하는 Web Worker에서 실행됩니다 — 메인 페이지와는 샌드박스로 격리되어 있지만 네이티브 DOM 요소를 렌더링합니다(iframe이 아님). 이들은 메시지 전달 호스트 API를 통해 Twenty와 통신합니다.
* **권한**은 API 수준에서 강제 적용됩니다. `defineApplicationRole()`로 선언된 역할에서 파생된 두 개의 런타임 토큰이 주입됩니다. 기본 토큰은 실행 뒤에 사람이 있는 경우마다 실행을 트리거한 사람이 할 수 있는 작업으로 더 제한됩니다.
## 앱 라이프사이클
```
┌─────────────────────────────────────────────────────────┐
│ Development │
│ npx create-twenty-app → yarn twenty dev (live sync) │
├─────────────────────────────────────────────────────────┤
│ Build & Deploy │
│ yarn twenty dev:build → yarn twenty app:publish │
├─────────────────────────────────────────────────────────┤
│ Install flow │
│ upload → [pre-install] → metadata migration → │
│ generate SDK → [post-install] → … → [uninstall] │
├─────────────────────────────────────────────────────────┤
│ Publish │
│ npm publish → appears in Twenty marketplace │
└─────────────────────────────────────────────────────────┘
```
* **`yarn twenty dev`** — 소스 파일을 감시하고 연결된 Twenty 서버로 변경 사항을 실시간 동기화합니다. 스키마가 변경되면 타입이 지정된 API 클라이언트가 자동으로 재생성됩니다.
* **`yarn twenty dev:build`** — TypeScript를 컴파일하고, 로직 함수와 프런트 컴포넌트를 esbuild로 번들링하며, 매니페스트를 생성합니다.
* **사전/사후 설치 및 제거 훅** — 설치 중이거나 제거 직전에 실행되는 선택적 함수입니다. 자세한 내용은 [Install Hooks](/l/ko/developers/extend/apps/config/install-hooks)를 참조하세요.
## 다음 단계
<CardGroup cols={2}>
<Card title="설정" icon="screwdriver-wrench" href="/l/ko/developers/extend/apps/config/overview">
애플리케이션 식별, 기본 역할, 설치 및 제거 훅.
</Card>
<Card title="데이터" icon="database" href="/l/ko/developers/extend/apps/data/overview">
객체, 필드, 양방향 관계.
</Card>
<Card title="로직" icon="bolt" href="/l/ko/developers/extend/apps/logic/overview">
로직 함수, 스킬, 에이전트, OAuth 연결.
</Card>
<Card title="레이아웃" icon="table-columns" href="/l/ko/developers/extend/apps/layout/overview">
뷰, 내비게이션, 페이지 레이아웃, 프런트 컴포넌트.
</Card>
<Card title="작업" icon="rocket" href="/l/ko/developers/extend/apps/operations/overview">
CLI, 테스트, 리모트, CI, 앱 게시.
</Card>
</CardGroup>

View File

@@ -0,0 +1,87 @@
---
title: 로컬 서버
description: 로컬 Twenty Docker 서버를 관리합니다. 시작, 중지, 업그레이드, 병렬 테스트 인스턴스 및 수동 SDK 설정을 수행할 수 있습니다.
icon: server
---
## 로컬 서버 관리
로컬 Twenty 컨테이너를 제어하려면 `yarn twenty docker:*`를 사용하세요:
| 명령 | 하는 일 |
| -------------------------------------- | ----------------------------- |
| `yarn twenty docker:start` | 서버 시작(필요하면 이미지를 가져옴) |
| `yarn twenty docker:start 2.2.0` | 특정 서버 버전을 시작합니다 |
| `yarn twenty docker:start --port 3030` | 사용자 지정 포트에서 시작 |
| `yarn twenty docker:stop` | 서버 중지(데이터 보존) |
| `yarn twenty docker:status` | URL, 버전 및 로그인 자격 증명 표시 |
| `yarn twenty docker:logs` | 서버 로그 스트리밍 |
| `yarn twenty docker:reset` | 데이터를 모두 삭제하고 새로 시작 |
| `yarn twenty docker:upgrade` | `twenty-app-dev` 최신 이미지를 가져오기 |
| `yarn twenty docker:upgrade 2.2.0` | 특정 버전으로 업그레이드합니다 |
데이터는 두 개의 Docker 볼륨에 저장되어 재시작 후에도 유지됩니다(PostgreSQL은 `twenty-app-dev-data`, 파일은 `twenty-app-dev-storage`). `reset`을 사용하여 모든 것을 삭제하세요.
## 서버 버전 고정하기
버전을 전달하지 않으면, `docker:start`는 `package.json`의 앱 `engines.twenty` 범위에서 버전을 결정합니다. 이 범위는 앱이 설치될 때 서버가 검증에 사용하는 범위와 같습니다. 이 명령은 해당 범위를 만족하는 가장 최근에 게시된 `twenty-app-dev` 이미지를 시작하며, 해당 필드가 없거나 게시된 버전이 범위와 일치하지 않으면 `latest`로 대체합니다:
```json filename="package.json"
{
"engines": {
"twenty": ">=2.2.0"
}
}
```
단일 실행에서만 범위를 재정의하려면 버전을 명시적으로 전달하세요: `yarn twenty docker:start 2.3.0`. 이미 다른 버전에서 컨테이너가 존재하는 경우, `docker:start`는 해당 컨테이너를 제자리에서 업그레이드합니다(데이터 볼륨을 유지하면서 컨테이너를 재생성).
## 서버 이미지 업그레이드
`yarn twenty docker:upgrade`는 최신 이미지를 가져와 다이제스트를 비교하고, 실제로 변경 사항이 있을 때만 컨테이너를 다시 생성합니다. 데이터 볼륨은 유지되며 — 컨테이너만 교체됩니다. 새 이미지를 가져왔고 컨테이너가 실행 중이었다면, 업그레이드는 자동으로 새 컨테이너를 시작합니다; 이후 `yarn twenty docker:start`를 실행하여 상태가 정상(healthy)이 될 때까지 기다리세요.
```bash filename="Terminal"
yarn twenty docker:upgrade # Latest
yarn twenty docker:upgrade 2.2.0 # Specific version
```
`yarn twenty docker:status`로 실행 중인 버전을 확인하세요(컨테이너에 포함된 `APP_VERSION`을 표시합니다).
## 병렬 테스트 인스턴스 실행
완전히 분리된 두 번째 인스턴스를 관리하려면 모든 `docker:*` 명령에 `--test`를 전달하세요 — 메인 개발 데이터를 건드리지 않고 통합 테스트를 실행하거나 실험할 때 유용합니다:
| 명령 | 하는 일 |
| ----------------------------------- | ---------------------------- |
| `yarn twenty docker:start --test` | 테스트 인스턴스를 시작합니다(기본 포트는 2021) |
| `yarn twenty docker:stop --test` | 중지 |
| `yarn twenty docker:status --test` | 상태 표시 |
| `yarn twenty docker:logs --test` | 로그 스트리밍 |
| `yarn twenty docker:reset --test` | 데이터 삭제 |
| `yarn twenty docker:upgrade --test` | 이미지 업그레이드 |
테스트 인스턴스는 자체 컨테이너(`twenty-app-dev-test`), 전용 볼륨(`twenty-app-dev-test-data`, `twenty-app-dev-test-storage`), 구성으로 실행되며, 메인 인스턴스와 충돌 없이 나란히 실행됩니다. `--test`를 `--port`와 함께 사용하여 2021을 재정의하세요.
## 수동 설정(스캐폴더 없이)
기존 프로젝트에 SDK를 추가하는 경우 스캐폴더 단계를 건너뜁니다:
```bash filename="Terminal"
yarn add twenty-sdk twenty-client-sdk
```
`package.json`에 스크립트를 추가하세요:
```json filename="package.json"
{
"scripts": {
"twenty": "twenty"
}
}
```
이제 `yarn twenty dev`, `yarn twenty docker:start` 등을 실행할 수 있습니다.
<Note>
`twenty-sdk`를 전역으로 설치하지 마세요 — 각 프로젝트에 고정하여 각 앱이 자체 버전을 사용하도록 하세요.
</Note>

View File

@@ -0,0 +1,79 @@
---
title: 프로젝트 구조
description: 스캐폴딩된 Twenty 앱 안에 무엇이 들어 있는지 — 파일, 폴더, 그리고 각 요소의 역할을 설명합니다.
icon: folder-tree
---
`npx create-twenty-app`으로 생성한 새 앱은 다음과 같은 구조입니다:
```text filename="my-twenty-app/"
my-twenty-app/
package.json
src/
application-config.ts # Required — your app's entry point
default-role.ts # Permissions for logic functions
constants/
universal-identifiers.ts # Auto-generated UUIDs and metadata
front-components/
main-page.tsx # Welcome page component
navigation-menu-items/
main-page.navigation-menu-item.ts # Sidebar entry for the welcome page
page-layouts/
main-page.page-layout.ts # Standalone page hosting the component
__tests__/
application-config.test.ts # Unit test
global-setup.ts # Integration test setup (sync + uninstall)
schema.integration-test.ts # Integration test against a live server
.github/workflows/
ci.yml # Lint, typecheck, unit + integration tests
cd.yml # Deploy + install on push to main
publish.yml # Publish to npm on version tags (with provenance)
public/
logo.svg # Static assets
vitest.config.ts # Integration test runner config
vitest.unit.config.ts # Unit test runner config
tsconfig.json, tsconfig.spec.json
.nvmrc, .yarnrc.yml, .oxlintrc.json
README.md, AGENTS.md, CLAUDE.md, CHANGELOG.md, SETUP.md
```
## 주요 파일
| 파일 / 폴더 | 목적 |
| -------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `src/application-config.ts` | **필수.** 앱의 기본 구성 파일입니다. |
| `src/default-role.ts` | 로직 함수가 접근할 수 있는 범위를 제어하는 기본 역할 |
| `src/constants/universal-identifiers.ts` | 자동 생성된 UUID와 앱 메타데이터(표시 이름, 설명). |
| `src/front-components/`, `src/navigation-menu-items/`, `src/page-layouts/` | 시작용 환영 페이지: 사이드바에서 접근할 수 있는, 독립적인 페이지 레이아웃에 의해 렌더링되는 프런트 컴포넌트입니다. |
| `src/__tests__/` | 실제 서버와 앱을 동기화하는 통합 테스트(글로벌 설정 포함)와 단위 테스트입니다. |
| `public/` | 앱과 함께 제공되는 정적 에셋(이미지, 폰트). |
| `AGENTS.md` / `CLAUDE.md` | 앱에서 작업하는 AI 코딩 에이전트를 위한 안내서입니다. |
| `CHANGELOG.md` / `SETUP.md` | 주요 변경 로그와 로컬 개발을 위한 설정 지침입니다. |
<Note>
**파일 구성은 사용자의 선택입니다.** 위 폴더들은 관례일 뿐이며, SDK는 파일 위치와 관계없이 `export default defineEntity(...)` 호출에 대한 AST 분석을 통해 엔티티를 감지합니다.
</Note>
## 의존성
두 Twenty SDK 패키지는 `dependencies`가 아니라 `devDependencies` 아래에 속해야 합니다.
```json filename="package.json"
{
"dependencies": {},
"devDependencies": {
"twenty-client-sdk": "2.20.0",
"twenty-sdk": "2.20.0",
"twenty-ui": "1.0.0-alpha.1"
}
}
```
스캐폴더는 `twenty-sdk`와 `twenty-client-sdk`를 자체 버전에 고정합니다. 업그레이드할 때 두 패키지의 버전을 동기화된 상태로 유지하세요.
* \*\*`twenty-sdk`\*\*는 `twenty` CLI와 빌드/스캐폴딩 도구를 제공합니다. 이 패키지는 개발 및 빌드 시점에만 실행되며, 배포된 앱의 런타임에서는 전혀 임포트되지 않습니다.
* \*\*`twenty-client-sdk`\*\*는 앱 코드(`CoreApiClient`, `MetadataApiClient`, `RestApiClient`)에서 임포트되지만, 런타임에는 Twenty가 이를 제공합니다. 로직 함수는 생성된 SDK 레이어에서 이를 가져오고, 프런트엔드 컴포넌트는 서버에서 제공되는 모듈에서 이를 해석하여 가져옵니다. 설치된 사본은 타입 검사와 배포 시점 빌드에만 사용되므로, 배포된 번들에 포함되어 함께 제공될 필요가 없습니다.
어느 한 패키지라도 `dependencies` 아래에 두면, 설치된 앱의 런타임 번들에 포함되어 쓸모없는 부하가 됩니다. `twenty dev:build`는 둘 중 하나라도 여전히 `dependencies` 아래에 나열되어 있으면 경고를 출력합니다.
앱의 실제 런타임 의존성(로직 함수가 런타임에 실제로 임포트하는 라이브러리)은 평소와 같이 `dependencies` 아래에 추가하세요. 의존성 트리를 슬림하게 유지하세요: `dependencies`는 압축 해제 기준 250MB로 제한된 런타임 레이어에 설치되며, 이 용량을 초과하면 동기화 또는 설치가 의존성 크기 오류와 함께 실패합니다. UI 라이브러리와 개발 도구는 `devDependencies`에 포함되어야 합니다.

View File

@@ -0,0 +1,166 @@
---
title: 빠른 시작
icon: rocket
description: 몇 분 만에 첫 번째 Twenty 앱을 만들어 보세요.
---
## 사전 준비
* **Node.js 24.5+** — [여기에서 다운로드](https://nodejs.org/)
* **Yarn 4** — Corepack을 통해 Node.js와 함께 제공됩니다. 활성화하려면: `corepack enable`
* **Docker** — [여기에서 다운로드](https://www.docker.com/products/docker-desktop/). 로컬 Twenty 서버를 실행하려면 필요합니다. 이미 다른 곳에서 Twenty가 실행 중이라면 건너뛰세요.
Twenty 앱을 빌드하는 과정은 세 단계로 이루어집니다. 스캐폴더는 이를 단일 해피 패스 명령으로 합쳐 주지만, 각 단계는 별개의 개념입니다 — 문제가 발생했을 때 현재 단계가 어디인지 알면 무엇을 고쳐야 하는지 파악할 수 있습니다.
| 단계 | 하는 일 | 도구 | 결과 |
| ------------ | ------------------------- | ----------------------------------- | -------------------- |
| **1. 스캐폴딩** | 앱의 소스 코드를 생성 | `npx create-twenty-app` | 디스크에 TypeScript 프로젝트 |
| **2. 서버 실행** | 동기화 대상으로 사용할 Twenty 서버 시작 | Docker + `yarn twenty docker:start` | 실행 중인 Twenty 인스턴스 |
| **3. 동기화** | 코드를 서버와 실시간 동기화 | `yarn twenty dev` | 변경 사항이 UI에 표시됨 |
---
## 1단계 — 프로젝트 스캐폴딩
템플릿에서 새 앱을 생성합니다:
```bash filename="Terminal"
npx create-twenty-app@latest my-twenty-app
```
스캐폴더는 비대화식입니다. 디렉터리 이름이 앱 이름이 됩니다. 생성되는 메타데이터를 사용자 지정하려면 `--display-name` 및 `--description`을(를) 전달합니다(나중에 `src/constants/universal-identifiers.ts`에서 수정할 수도 있습니다). 이 명령은 `my-twenty-app/`에 시작용 `application-config.ts`, 기본 역할, CI/CD 워크플로, 통합 테스트가 포함된 TypeScript 프로젝트를 생성합니다.
**이 단계를 마치면:** 로컬 머신에 앱의 소스 코드가 준비됩니다. 아직 실행되지는 않았습니다 — 그건 2단계에서 진행합니다.
---
## 2단계 — 로컬 Twenty 서버 실행
앱은 동기화할 Twenty 서버가 필요합니다. 이 서버는 Docker에서 로컬로 실행되는 완전한 Twenty 인스턴스입니다 — UI, GraphQL API, PostgreSQL을 포함합니다. 로컬 코드가 해당 서버로 정의를 업로드하면 UI에 표시됩니다.
Scaffolder가 이를 대신 시작합니다. Docker가 실행 중이면 `twentycrm/twenty-app-dev` 이미지를 pull 하고, 포트 `2020`에서 시작한 다음, 미리 시드된 데모 워크스페이스(`tim@apple.dev`)에 대해 CLI를 인증합니다. 별도의 로그인은 필요하지 않습니다.
대신 기존 Twenty 서버에 연결하려면 `--url \<your-server-url>`을 전달하세요. 원격 서버는 OAuth로 인증합니다. 브라우저가 열리면 로그인한 뒤 **Authorize**를 클릭해 워크스페이스에 대한 CLI 액세스를 허용하면 됩니다. (로컬에서도 `--authentication-method oauth`로 OAuth를 선택할 수 있습니다. `tim@apple.dev` / `tim@apple.dev`로 로그인하세요.)
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty 로그인 화면" />
</div>
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI 권한 부여 화면" />
</div>
권한 부여가 완료되면 터미널에 설정이 완료되었다는 메시지가 표시됩니다.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="앱 스캐폴딩 성공" />
</div>
**이 단계를 마치면:** [http://localhost:2020](http://localhost:2020)에서 Twenty 서버가 실행 중이며, CLI가 해당 서버로 동기화하도록 권한이 부여됩니다.
<Note>
Docker가 설치되어 있지 않거나 실행 중이 아니면, 스캐폴더가 OS에 맞는 올바른 시작 명령을 알려줍니다. Docker가 올라오면 `yarn twenty docker:start`로 이어서 진행할 수 있습니다 — 다시 스캐폴딩할 필요는 없습니다.
</Note>
---
## 3단계 — 변경 사항 동기화
이 단계는 대부분의 시간을 보내게 될 내부 루프입니다.
```bash filename="Terminal"
cd my-twenty-app
yarn twenty dev
```
`src/`를 감시하며 변경될 때마다 다시 빌드하고, 결과를 서버에 동기화합니다. 파일을 수정해 저장하면 몇 초 안에 서버에 변경 사항이 반영됩니다. 터미널에서 실시간 상태 패널을 확인할 수 있습니다.
더 자세한 출력(빌드 로그, 동기화 요청, 오류 트레이스)을 보려면 `--verbose`를 추가하세요.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/extends/apps/dev.png" alt="개발 모드 터미널 출력" />
</div>
[http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer)를 엽니다. **Your Apps** 아래에 앱이 표시됩니다.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps 목록에 My twenty app이 표시됨" />
</div>
**My twenty app**을 클릭하여 **애플리케이션 등록**을 확인하세요 — 앱을 설명하는 서버 수준의 레코드입니다(이름, 식별자, OAuth 자격 증명, 소스). 하나의 등록은 동일한 서버의 여러 워크스페이스에 설치할 수 있습니다.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="애플리케이션 등록 세부정보" />
</div>
워크스페이스 설치를 확인하려면 **View installed app**을 클릭하세요. **About** 탭에는 버전과 관리 옵션이 표시됩니다.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="설치된 앱" />
</div>
**이 단계를 마치면:** 라이브 개발 루프가 준비됩니다. `src/`의 파일을 수정하면 UI에 반영됩니다.
### CI 및 스크립트를 위한 1회성 동기화
워처 없이 동일한 파이프라인을 한 번만 실행하려면 `plan`과 `apply`를 사용하세요:
```bash filename="Terminal"
yarn twenty plan # preview the metadata changes without applying them
yarn twenty apply # show the plan, then apply it
```
| 명령 | 동작 | 사용 시점 |
| ------------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------- |
| `yarn twenty dev` | 소스 파일을 감시하고 변경될 때마다 다시 동기화합니다. 중지할 때까지 계속 실행됩니다. | 대화형 로컬 개발. |
| `yarn twenty apply` | 한 번만 빌드 + 동기화를 수행하고, 성공 시 `0`, 실패 시 `1`로 종료합니다. 파괴적인 변경 사항에 대해 확인을 요청합니다(건너뛰려면 `--force`를 전달하세요). | CI, pre-commit 훅, AI 에이전트, 스크립트형 워크플로. |
| `yarn twenty plan` | 메타데이터 변경 사항을 **실제로 적용하지 않고** 빌드하고 출력합니다. | 커밋하기 전에 동기화가 어떤 변경을 수행할지 살펴봅니다. |
모든 모드에는 인증된 리모트가 필요합니다. `plan`에 대한 자세한 내용은 [동기화 및 복구](/l/ko/developers/extend/apps/operations/sync-and-recovery#previewing-changes-plan)를 참고하세요.
<Note>
`yarn twenty dev --once` 및 `yarn twenty dev --once --dry-run`은 `yarn twenty apply` 및 `yarn twenty plan`의 사용 중단된 별칭입니다.
</Note>
### 개발 모드 옵션
| 플래그 | 설명 |
| ------------------------------------- | --------------------------------------------- |
| `--force` | 확인 없이 파괴적인 변경 사항(삭제)을 적용합니다. |
| `--debounceMs \<ms>` | 파일 변경 디바운스 지연 시간을 밀리초 단위로 설정합니다(기본값: `1000`). |
| `--verbose` / `--debug` | 자세한 빌드 로그, 동기화 요청, 오류 추적을 표시합니다. |
## 만들 수 있는 것
앱은 **엔터티**로 구성됩니다 — 각 엔터티는 하나의 `export default`만 포함하는 TypeScript 파일로 정의됩니다:
| 엔터티 | 하는 일 |
| ------------- | ---------------------------------------------------------- |
| **객체 & 필드** | 사용자 정의 데이터 모델(Post Card, Invoice 등) 타입이 지정된 필드 포함 |
| **로직 함수** | HTTP 라우트, cron 스케줄 또는 데이터베이스 이벤트로 트리거되는 서버 측 TypeScript 코드 |
| **프론트 컴포넌트** | Twenty의 UI(사이드 패널, 위젯, 명령 메뉴) 안에 렌더링되는 React 컴포넌트 |
| **스킬 & 에이전트** | AI 기능 — 재사용 가능한 지침과 자율형 어시스턴트 |
| **뷰 & 내비게이션** | 사전 구성된 목록 뷰와 사이드바 메뉴 항목 |
| **페이지 레이아웃** | 탭과 위젯이 있는 사용자 정의 레코드 상세 페이지 |
전체 참고 문서: [개념](/l/ko/developers/extend/apps/getting-started/concepts).
## 다음 단계
<CardGroup cols={2}>
<Card title="설정" icon="screwdriver-wrench" href="/l/ko/developers/extend/apps/config/overview">
애플리케이션 ID, 기본 역할, 설치 및 제거 훅, 공개 자산.
</Card>
<Card title="데이터" icon="database" href="/l/ko/developers/extend/apps/data/overview">
객체, 필드, 그리고 양방향 관계.
</Card>
<Card title="로직" icon="bolt" href="/l/ko/developers/extend/apps/logic/overview">
로직 함수, 스킬, 에이전트, OAuth 연결.
</Card>
<Card title="레이아웃" icon="table-columns" href="/l/ko/developers/extend/apps/layout/overview">
뷰, 내비게이션, 페이지 레이아웃, 프론트 컴포넌트.
</Card>
<Card title="작업" icon="rocket" href="/l/ko/developers/extend/apps/operations/overview">
CLI, 테스트, 리모트, CI, 그리고 앱 게시.
</Card>
</CardGroup>

View File

@@ -0,0 +1,63 @@
---
title: 스캐폴딩
description: "`yarn twenty dev:add`를 사용해 엔티티 파일을 대화형으로 생성하여 객체, 필드, 뷰, 로직 함수 등을 추가하세요."
icon: wand-magic-sparkles
---
엔티티 파일을 수동으로 만드는 대신, 대화형 스캐폴더를 사용하세요:
```bash filename="Terminal"
yarn twenty dev:add
```
이 도구는 엔티티 유형을 선택하도록 안내하고, 필요한 필드를 하나씩 진행한 다음, 안정적인 `universalIdentifier`와 올바른 `defineEntity()` 호출이 포함된 바로 사용할 수 있는 파일을 생성합니다.
첫 번째 프롬프트를 건너뛰려면 엔티티 타입을 직접 전달할 수도 있습니다:
```bash filename="Terminal"
yarn twenty dev:add object
yarn twenty dev:add logicFunction
yarn twenty dev:add frontComponent
```
## 사용 가능한 엔티티 타입
| 엔티티 유형 | 명령 | 생성된 파일 |
| ----------- | ------------------------------------------ | --------------------------------------------------------- |
| 객체 | `yarn twenty dev:add object` | `src/objects/\<name>.ts` |
| 필드 | `yarn twenty dev:add field` | `src/fields/\<name>.ts` |
| 로직 함수 | `yarn twenty dev:add logicFunction` | `src/logic-functions/\<name>.ts` |
| 프런트 컴포넌트 | `yarn twenty dev:add frontComponent` | `src/front-components/\<name>.tsx` |
| 역할 | `yarn twenty dev:add role` | `src/roles/\<name>.ts` |
| 스킬 | `yarn twenty dev:add skill` | `src/skills/\<name>.ts` |
| 에이전트 | `yarn twenty dev:add agent` | `src/agents/\<name>.ts` |
| 뷰 | `yarn twenty dev:add view` | `src/views/\<name>.ts` |
| 내비게이션 메뉴 항목 | `yarn twenty dev:add navigationMenuItem` | `src/navigation-menu-items/\<name>.ts` |
| 페이지 레이아웃 | `yarn twenty dev:add pageLayout` | `src/page-layouts/\<name>.ts` |
| 페이지 레이아웃 탭 | `yarn twenty dev:add pageLayoutTab` | `src/page-layout-tabs/\<name>.ts` |
| 명령 메뉴 항목 | `yarn twenty dev:add commandMenuItem` | `src/command-menu-items/\<name>.ts` |
| 보기 필드 | `yarn twenty dev:add viewField` | `src/view-fields/\<name>.ts` |
| 연결 제공자 | `yarn twenty dev:add connectionProvider` | `src/connection-providers/\<name>.ts` |
| 타임라인 활동 유형 | `yarn twenty dev:add timelineActivityType` | `src/timeline-activity-types/\<name>.ts` |
## 스캐폴더가 생성하는 것
각 엔티티 타입은 자체 템플릿을 가집니다. 예를 들어, `yarn twenty dev:add object`는 다음을 묻습니다:
1. **이름(단수)** — 예: `invoice`
2. **이름(복수)** — 예: `invoices`
3. **레이블(단수)** — 이름에서 자동으로 채워짐(예: `Invoice`)
4. **레이블(복수)** — 자동으로 채워짐(예: `Invoices`)
5. **뷰와 내비게이션 항목을 생성할까요?** — 예라고 답하면, 스캐폴더가 새 객체에 대한 일치하는 뷰와 사이드바 링크도 생성합니다.
다른 엔티티 타입은 더 단순한 프롬프트를 사용하며 — 대부분 이름만 묻습니다.
`field` 엔티티 타입은 더 자세합니다: 필드 이름, 레이블, 타입( `TEXT`, `NUMBER`, `SELECT`, `RELATION` 등 사용 가능한 모든 필드 타입 목록에서 선택), 그리고 대상 객체의 `universalIdentifier`를 묻습니다.
## 사용자 지정 출력 경로
`--path` 플래그를 사용해 생성된 파일을 사용자 지정 위치에 배치하세요:
```bash filename="Terminal"
yarn twenty dev:add logicFunction --path src/custom-folder
```

View File

@@ -0,0 +1,14 @@
---
title: 문제 해결
description: 일반적인 첫 실행 문제 — Docker, Node 버전, Yarn, 의존성.
icon: wrench
---
* **Docker 오류** — `yarn twenty docker:start`를 실행하기 전에 Docker Desktop(또는 데몬)이 실행 중인지 확인하세요. 오류 메시지에 OS에 맞는 올바른 시작 명령이 표시됩니다.
* **잘못된 Node 버전** — 24.5+가 필요합니다 (`engines.node: ^24.5.0`). `node -v`로 확인하세요.
* **Yarn 4 누락** — `corepack enable`을 실행하세요.
* **의존성 문제** — `rm -rf node_modules && yarn install`.
* **`twenty-sdk` v2.8.0으로 업그레이드한 후 오류 발생** — v2.8.0에서 `dependencies`에서 `devDependencies`로 이동했습니다. [프로젝트 구조 → Dependencies](/l/ko/developers/extend/apps/getting-started/project-structure#dependencies)를 참조하세요.
* **`twenty dev:build`는 `dependencies` 아래의 `twenty-client-sdk`에 대해 경고합니다** — 이는 실행 시 Twenty에서 제공되므로, `twenty-sdk`와 함께 `devDependencies`로 옮겨야 합니다. [프로젝트 구조 → Dependencies](/l/ko/developers/extend/apps/getting-started/project-structure#dependencies)를 참조하세요.
막히셨나요? [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322)에서 문의하세요.