--- title: Twenty Uygulamaları description: Twenty özelleştirmelerini kod olarak oluşturun ve yönetin. --- Uygulamalar şu anda alfa testinde. Özellik işlevsel ancak hâlâ gelişmekte. ## Uygulamalar Nedir? Uygulamalar, Twenty özelleştirmelerini **kod olarak** oluşturup yönetmenizi sağlar. Her şeyi UI üzerinden yapılandırmak yerine, veri modelinizi ve mantık fonksiyonlarınızı kodla tanımlarsınız — bu da oluşturmayı, bakımı ve birden çok çalışma alanına dağıtmayı hızlandırır. **Bugün Yapabilecekleriniz:** * Özel nesneleri ve alanları kod olarak tanımlayın (yönetilen veri modeli) * Özel tetikleyicilerle mantık fonksiyonları oluşturun * Aynı uygulamayı birden çok çalışma alanına dağıtın ## Ön Gereksinimler * Node.js 24+ ve Yarn 4 * Bir Twenty çalışma alanı ve bir API anahtarı (https://app.twenty.com/settings/api-webhooks adresinde oluşturun) ## Başlarken Resmi scaffolder aracını kullanarak yeni bir uygulama oluşturun, ardından kimlik doğrulaması yapıp geliştirmeye başlayın: ```bash filename="Terminal" # Scaffold a new app npx create-twenty-app@latest my-twenty-app cd my-twenty-app # If you don't use yarn@4 corepack enable yarn install # Authenticate using your API key (you'll be prompted) yarn auth:login # Start dev mode: automatically syncs local changes to your workspace yarn app:dev ``` Buradan şunları yapabilirsiniz: ```bash filename="Terminal" # Add a new entity to your application (guided) yarn entity:add # Generate a typed Twenty client and workspace entity types yarn app:generate # Watch your application's function logs yarn function:logs # Execute a function by name yarn function:execute -n my-function -p '{"name": "test"}' # Uninstall the application from the current workspace yarn app:uninstall # Display commands' help yarn help ``` Ayrıca bkz.: [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) ve [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk) için CLI başvuru sayfaları. ## Proje yapısı (şablondan oluşturulmuş) `npx create-twenty-app@latest my-twenty-app` komutunu çalıştırdığınızda scaffolder şunları yapar: * Minimal bir temel uygulamayı `my-twenty-app/` içine kopyalar * Yerel bir `twenty-sdk` bağımlılığı ve Yarn 4 yapılandırması ekler * `twenty` CLI ile bağlantılı yapılandırma dosyaları ve betikler oluşturur * Varsayılan bir uygulama yapılandırması ve varsayılan bir fonksiyon rolü üretir Yeni şablondan oluşturulan bir uygulama şöyle görünür: ```text filename="my-twenty-app/" my-twenty-app/ package.json yarn.lock .gitignore .nvmrc .yarnrc.yml .yarn/ install-state.gz eslint.config.mjs tsconfig.json README.md public/ # Genel varlıklar klasörü (görseller, yazı tipleri vb.) src/ ├── application-config.ts # Gerekli - ana uygulama yapılandırması ├── roles/ │ └── default-role.ts # Mantık işlevleri için varsayılan rol ├── logic-functions/ │ └── hello-world.ts # Örnek mantık işlevi └── front-components/ └── hello-world.tsx # Örnek ön uç bileşeni ``` Genel hatlarıyla: * **package.json**: Uygulama adını, sürümünü, motorları (Node 24+, Yarn 4) bildirir ve `twenty-sdk` ile `app:dev`, `app:generate`, `entity:add`, `function:logs`, `function:execute`, `app:uninstall` gibi betikleri ve yerel `twenty` CLI’sine yetki devreden kimlik doğrulama komutlarını ekler. * **.gitignore**: `node_modules`, `.yarn`, `generated/` (türlendirilmiş istemci), `dist/`, `build/`, kapsam klasörleri, günlük dosyaları ve `.env*` dosyaları gibi yaygın artifaktları yok sayar. * **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Proje tarafından kullanılan Yarn 4 araç zincirini kilitler ve yapılandırır. * **.nvmrc**: Projenin beklediği Node.js sürümünü sabitler. * **eslint.config.mjs** ve **tsconfig.json**: Uygulamanızın TypeScript kaynakları için linting ve TypeScript yapılandırması sağlar. * **README.md**: Uygulama kökünde temel talimatların yer aldığı kısa bir README. * **public/**: Uygulamanızla birlikte sunulacak genel varlıkları (görseller, yazı tipleri, statik dosyalar) depolamak için bir klasör. Buraya yerleştirilen dosyalar senkronizasyon sırasında yüklenir ve çalışma zamanında erişilebilir olur. * **src/**: Uygulamanızı kod olarak tanımladığınız ana yer ### Varlık algılama SDK, TypeScript dosyalarınızı **`export default define({...})`** çağrılarını arayarak ayrıştırıp varlıkları algılar. Her varlık türünün, `twenty-sdk` tarafından dışa aktarılan karşılık gelen bir yardımcı fonksiyonu vardır: | Yardımcı fonksiyon | Varlık türü | | ------------------------ | ---------------------------------------- | | `defineObject()` | Özel nesne tanımları | | `defineLogicFunction()` | Mantık fonksiyon tanımları | | `defineFrontComponent()` | Front component definitions | | `defineRole()` | Rol tanımları | | `defineField()` | Mevcut nesneler için alan genişletmeleri | **Dosya adlandırma esnektir.** Varlık algılama AST tabanlıdır — SDK, kaynak dosyalarınızı `export default define({...})` desenini bulmak için tarar. Dosyalarınızı ve klasörlerinizi dilediğiniz gibi düzenleyebilirsiniz. Varlık türüne göre gruplama (örn. `logic-functions/`, `roles/`) bir gereklilik değil, yalnızca kod organizasyonu için bir gelenektir. Algılanan bir varlığa örnek: ```typescript // This file can be named anything and placed anywhere in src/ import { defineObject, FieldType } from 'twenty-sdk'; export default defineObject({ universalIdentifier: '...', nameSingular: 'postCard', // ... rest of config }); ``` İlerideki komutlar daha fazla dosya ve klasör ekleyecektir: * `yarn app:generate`, `generated/` klasörünü oluşturur (türlendirilmiş Twenty istemcisi + çalışma alanı türleri). * `yarn entity:add`, özel nesneleriniz, fonksiyonlarınız, ön bileşenleriniz veya rolleriniz için `src/` altında varlık tanım dosyaları ekler. ## Kimlik Doğrulama `yarn auth:login` komutunu ilk kez çalıştırdığınızda, sizden şunlar istenir: * API URL’si (varsayılan: http://localhost:3000 veya mevcut çalışma alanı profiliniz) * API anahtarı Kimlik bilgileriniz kullanıcı başına `~/.twenty/config.json` içinde saklanır. You can maintain multiple profiles and switch between them. ### Managing workspaces ```bash filename="Terminal" # Login interactively (recommended) yarn auth:login # Login to a specific workspace profile yarn auth:login --workspace my-custom-workspace # List all configured workspaces yarn auth:list # Switch the default workspace (interactive) yarn auth:switch # Switch to a specific workspace yarn auth:switch production # Check current authentication status yarn auth:status ``` Once you've switched workspaces with `auth:switch`, all subsequent commands will use that workspace by default. You can still override it temporarily with `--workspace `. ## SDK kaynaklarını kullanın (türler ve yapılandırma) twenty-sdk, uygulamanız içinde kullandığınız türlendirilmiş yapı taşları ve yardımcı fonksiyonlar sağlar. Aşağıda en sık dokunacağınız başlıca parçalar yer alıyor. ### Yardımcı fonksiyonlar SDK, uygulama varlıklarınızı tanımlamak için yardımcı fonksiyonlar sağlar. [Varlık algılama](#entity-detection) bölümünde açıklandığı gibi, varlıklarınızın algılanması için `export default define({...})` kullanmalısınız: | Fonksiyon | Amaç | | ------------------------ | ------------------------------------------------------------------------- | | `defineApplication()` | Uygulama meta verilerini yapılandırın (zorunlu, uygulama başına bir adet) | | `defineObject()` | Alanlara sahip özel nesneler tanımlayın | | `defineLogicFunction()` | İşleyicilerle mantık fonksiyonları tanımlayın | | `defineFrontComponent()` | Özel kullanıcı arayüzü için ön uç bileşenlerini tanımlayın | | `defineRole()` | Rol izinlerini ve nesne erişimini yapılandırın | | `defineField()` | Mevcut nesneleri ek alanlarla genişletin | Bu fonksiyonlar, derleme zamanında yapılandırmanızı doğrular ve IDE otomatik tamamlama ile tür güvenliği sağlar. ### Nesnelerin tanımlanması Özel nesneler, çalışma alanınızdaki kayıtlar için hem şemayı hem de davranışı tanımlar. Yerleşik doğrulamayla nesneler tanımlamak için `defineObject()` kullanın: ```typescript // src/app/postCard.object.ts import { defineObject, FieldType } from 'twenty-sdk'; enum PostCardStatus { DRAFT = 'DRAFT', SENT = 'SENT', DELIVERED = 'DELIVERED', RETURNED = 'RETURNED', } export default defineObject({ universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05', nameSingular: 'postCard', namePlural: 'postCards', labelSingular: 'Post Card', labelPlural: 'Post Cards', description: 'A post card object', icon: 'IconMail', 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, }, ], }); ``` Önemli noktalar: * Yerleşik doğrulama ve daha iyi IDE desteği için `defineObject()` kullanın. * `universalIdentifier` dağıtımlar arasında benzersiz ve kararlı olmalıdır. * Her alan bir `name`, `type`, `label` ve kendi kararlı `universalIdentifier` değerini gerektirir. * `fields` dizisi isteğe bağlıdır — özel alanlar olmadan da nesneler tanımlayabilirsiniz. * `yarn entity:add` kullanarak, adlandırma, alanlar ve ilişkiler konusunda sizi yönlendirerek yeni nesneler oluşturabilirsiniz. **Temel alanlar otomatik olarak oluşturulur.** Özel bir nesne tanımladığınızda Twenty, `name`, `createdAt`, `updatedAt`, `createdBy`, `position` ve `deletedAt` gibi standart alanları otomatik olarak ekler. Bunları `fields` dizinizde tanımlamanız gerekmez — yalnızca özel alanlarınızı ekleyin. ### Uygulama yapılandırması (application-config.ts) Her uygulamanın aşağıdakileri açıklayan tek bir `application-config.ts` dosyası vardır: * **Uygulamanın kim olduğu**: tanımlayıcılar, görünen ad ve açıklama. * **Fonksiyonlarının nasıl çalıştığı**: izinler için hangi rolü kullandıkları. * **(İsteğe bağlı) değişkenler**: fonksiyonlarınıza ortam değişkenleri olarak sunulan anahtar–değer çiftleri. Uygulama yapılandırmanızı tanımlamak için `defineApplication()` kullanın: ```typescript // src/application-config.ts import { defineApplication } from 'twenty-sdk'; import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role'; export default defineApplication({ universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7', displayName: 'My Twenty App', description: 'My first Twenty app', icon: 'IconWorld', applicationVariables: { DEFAULT_RECIPIENT_NAME: { universalIdentifier: '19e94e59-d4fe-4251-8981-b96d0a9f74de', description: 'Default recipient name for postcards', value: 'Jane Doe', isSecret: false, }, }, defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER, }); ``` Notlar: * `universalIdentifier` alanları size ait belirleyici kimliklerdir; bunları bir kez oluşturun ve eşitlemeler boyunca kararlı tutun. * `applicationVariables`, fonksiyonlarınız için ortam değişkenlerine dönüşür (örneğin, `DEFAULT_RECIPIENT_NAME` değeri `process.env.DEFAULT_RECIPIENT_NAME` olarak kullanılabilir). * `defaultRoleUniversalIdentifier`, rol dosyasıyla eşleşmelidir (aşağıya bakın). #### Roller ve izinler Uygulamalar, çalışma alanınızdaki nesneler ve eylemler üzerindeki izinleri kapsülleyen roller tanımlayabilir. `application-config.ts` içindeki `defaultRoleUniversalIdentifier` alanı, uygulamanızın mantık fonksiyonlarının kullandığı varsayılan rolü belirtir. * `TWENTY_API_KEY` olarak enjekte edilen çalışma zamanı API anahtarı bu varsayılan fonksiyon rolünden türetilir. * Türlendirilmiş istemci, o role tanınan izinlerle sınırlandırılır. * En az ayrıcalık ilkesini izleyin: Yalnızca fonksiyonlarınızın ihtiyaç duyduğu izinlere sahip özel bir rol oluşturun ve ardından evrensel tanımlayıcısına referans verin. ##### Varsayılan fonksiyon rolü (\*.role.ts) Yeni bir uygulama oluşturduğunuzda CLI ayrıca varsayılan bir rol dosyası da oluşturur. Yerleşik doğrulamayla roller tanımlamak için `defineRole()` kullanın: ```typescript // src/roles/default-role.ts import { defineRole, PermissionFlag } from 'twenty-sdk'; export const DEFAULT_ROLE_UNIVERSAL_IDENTIFIER = 'b648f87b-1d26-4961-b974-0908fd991061'; export default defineRole({ universalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER, label: 'Default function role', description: 'Default role for function Twenty client', canReadAllObjectRecords: false, canUpdateAllObjectRecords: false, canSoftDeleteAllObjectRecords: false, canDestroyAllObjectRecords: false, canUpdateAllSettings: false, canBeAssignedToAgents: false, canBeAssignedToUsers: false, canBeAssignedToApiKeys: false, objectPermissions: [ { objectUniversalIdentifier: '9f9882af-170c-4879-b013-f9628b77c050', canReadObjectRecords: true, canUpdateObjectRecords: true, canSoftDeleteObjectRecords: false, canDestroyObjectRecords: false, }, ], fieldPermissions: [ { objectUniversalIdentifier: '9f9882af-170c-4879-b013-f9628b77c050', fieldUniversalIdentifier: 'b2c37dc0-8ae7-470e-96cd-1476b47dfaff', canReadFieldValue: false, canUpdateFieldValue: false, }, ], permissionFlags: [PermissionFlag.APPLICATIONS], }); ``` Bu rolün `universalIdentifier` değeri daha sonra `application-config.ts` içinde `defaultRoleUniversalIdentifier` olarak referans verilir. Başka bir deyişle: * **\*.role.ts**, varsayılan fonksiyon rolünün neler yapabileceğini tanımlar. * **application-config.ts**, fonksiyonlarınızın izinlerini devralması için bu role işaret eder. Notlar: * Oluşturulan rol ile başlayın ve en az ayrıcalık ilkesini izleyerek aşamalı olarak kısıtlayın. * `objectPermissions` ve `fieldPermissions` değerlerini, fonksiyonlarınızın ihtiyaç duyduğu nesneler/alanlarla değiştirin. * `permissionFlags`, platform düzeyindeki yeteneklere erişimi kontrol eder. Minimumda tutun; yalnızca ihtiyacınız olanları ekleyin. * Çalışan bir örneği Hello World uygulamasında görün: [`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). ### Mantık fonksiyon yapılandırması ve giriş noktası Her fonksiyon dosyası, bir işleyici ve isteğe bağlı tetikleyiciler içeren bir yapılandırmayı dışa aktarmak için `defineLogicFunction()` kullanır. ```typescript // src/app/createPostCard.logic-function.ts import { defineLogicFunction } from 'twenty-sdk'; import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk'; import Twenty, { type Person } from '~/generated'; const handler = async (params: RoutePayload) => { const client = new Twenty(); // generated typed client const name = 'name' in params.queryStringParameters ? params.queryStringParameters.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world' : 'Hello world'; const result = await client.mutation({ createPostCard: { __args: { data: { name } }, id: true, name: true, }, }); return result; }; export default defineLogicFunction({ universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf', name: 'create-new-post-card', timeoutSeconds: 2, handler, triggers: [ // Public HTTP route trigger '/s/post-card/create' { universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6', type: 'route', path: '/post-card/create', httpMethod: 'GET', isAuthRequired: false, }, // Cron trigger (CRON pattern) // { // universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2', // type: 'cron', // pattern: '0 0 1 1 *', // }, // Database event trigger // { // universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156', // type: 'databaseEvent', // eventName: 'person.updated', // updatedFields: ['name'], // }, ], }); ``` Yaygın tetikleyici türleri: * **route**: Fonksiyonunuzu bir HTTP yolu ve yöntemiyle **`/s/` uç noktası altında** sunar: > örn. `path: '/post-card/create',` -> `/s/post-card/create` üzerinden çağırın * **cron**: Bir CRON ifadesi kullanarak fonksiyonunuzu bir zamanlamayla çalıştırır. * **databaseEvent**: Çalışma alanı nesnesi yaşam döngüsü olaylarında çalışır. Olay işlemi `updated` olduğunda, dinlenecek belirli alanlar `updatedFields` dizisinde belirtilebilir. Tanımsız veya boş bırakılırsa, herhangi bir güncelleme fonksiyonu tetikler. > örn. `person.updated` Notlar: * `triggers` dizisi isteğe bağlıdır. Tetikleyicisi olmayan fonksiyonlar, diğer fonksiyonlar tarafından çağrılan yardımcı fonksiyonlar olarak kullanılabilir. * Tek bir fonksiyonda birden çok tetikleyici türünü birleştirebilirsiniz. ### Rota tetikleyicisi yükü **Kırıcı değişiklik (v1.16, Ocak 2026):** Rota tetikleyicisi yük formatı değişti. v1.16'dan önce, sorgu parametreleri, yol parametreleri ve gövde doğrudan payload olarak gönderiliyordu. v1.16 itibarıyla, yapılandırılmış bir `RoutePayload` nesnesinin içine yerleştiriliyorlar. **v1.16'dan önce:** ```typescript const handler = async (params) => { const { param1, param2 } = params; // Direct access }; ``` **v1.16'dan sonra:** ```typescript const handler = async (event: RoutePayload) => { const { param1, param2 } = event.body; // Access via .body const { queryParam } = event.queryStringParameters; const { id } = event.pathParameters; }; ``` **Mevcut fonksiyonları taşımak için:** İşleyicinizi, parametreler nesnesinden doğrudan ayırmak yerine `event.body`, `event.queryStringParameters` veya `event.pathParameters` üzerinden ayrıştıracak şekilde güncelleyin. Bir rota tetikleyicisi mantık fonksiyonunuzu çağırdığında, AWS HTTP API v2 formatını izleyen bir `RoutePayload` nesnesi alır. Türü `twenty-sdk` içinden içe aktarın: ```typescript import { defineLogicFunction, 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' }; }; ``` `RoutePayload` türünün yapısı şu şekildedir: | Özellik | Tür | Açıklama | | ---------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------- | | `headers` | `Record` | HTTP başlıkları (`forwardedRequestHeaders` içinde listelenenlerle sınırlı) | | `queryStringParameters` | `Record` | Sorgu dizesi parametreleri (birden çok değer virgülle birleştirilir) | | `pathParameters` | `Record` | Rota deseninden çıkarılan yol parametreleri (örn., `/users/:id` → `{ id: '123' }`) | | `gövde` | `object \| null` | Ayrıştırılmış istek gövdesi (JSON) | | `isBase64Encoded` | `boolean` | Gövdenin base64 ile kodlanıp kodlanmadığı | | `requestContext.http.method` | `string` | HTTP yöntemi (GET, POST, PUT, PATCH, DELETE) | | `requestContext.http.path` | `string` | Ham istek yolu | ### HTTP başlıklarını iletme Varsayılan olarak, güvenlik nedenleriyle gelen isteklerden HTTP başlıkları mantık fonksiyonunuza **aktarılmaz**. Belirli başlıklara erişmek için bunları açıkça `forwardedRequestHeaders` dizisinde listeleyin: ```typescript export default defineLogicFunction({ 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'], }, ], }); ``` Daha sonra işleyicinizde bu başlıklara erişebilirsiniz: ```typescript const handler = async (event: RoutePayload) => { const signature = event.headers['x-webhook-signature']; const contentType = event.headers['content-type']; // Validate webhook signature... return { received: true }; }; ``` Başlık adları küçük harfe normalize edilir. Onlara küçük harfli anahtarlarla erişin (örneğin, `event.headers['content-type']`). Yeni fonksiyonları iki şekilde oluşturabilirsiniz: * **Şablondan**: `yarn entity:add` çalıştırın ve yeni bir mantık fonksiyonu ekleme seçeneğini seçin. Bu, bir işleyici ve yapılandırma içeren bir başlangıç dosyası oluşturur. * **Manuel**: Yeni bir `*.logic-function.ts` dosyası oluşturun ve aynı deseni izleyerek `defineLogicFunction()` kullanın. ### Ön uç bileşenleri Ön uç bileşenleri, Twenty'nin kullanıcı arayüzünde görüntülenen özel React bileşenleri oluşturmanıza olanak tanır. Yerleşik doğrulamayla bileşenleri tanımlamak için `defineFrontComponent()` kullanın: ```typescript // src/my-widget.front-component.tsx import { defineFrontComponent } from 'twenty-sdk'; const MyWidget = () => { return (

My Custom Widget

This is a custom front component for Twenty.

); }; export default defineFrontComponent({ universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890', name: 'my-widget', description: 'A custom widget component', component: MyWidget, }); ``` Önemli noktalar: * Ön uç bileşenleri, Twenty içinde yalıtılmış bağlamlarda görüntülenen React bileşenleridir. * Otomatik algılama için `*.front-component.tsx` dosya soneğini kullanın. * `component` alanı, React bileşeninize referans verir. * Bileşenler, `yarn app:dev` sırasında otomatik olarak oluşturulur ve senkronize edilir. Yeni ön uç bileşenlerini iki şekilde oluşturabilirsiniz: * **Şablondan**: `yarn entity:add` çalıştırın ve yeni bir ön uç bileşeni ekleme seçeneğini seçin. * **Manuel**: Yeni bir `*.front-component.tsx` dosyası oluşturun ve `defineFrontComponent()` kullanın. ### Oluşturulmuş türlendirilmiş istemci Çalışma alanı şemanıza göre generated/ içinde yerel bir türlendirilmiş istemci oluşturmak için yarn app:generate çalıştırın. Fonksiyonlarınızda kullanın: ```typescript import Twenty from '~/generated'; const client = new Twenty(); const { me } = await client.query({ me: { id: true, displayName: true } }); ``` İstemci `yarn app:generate` tarafından yeniden oluşturulur. Nesnelerinizi değiştirdikten sonra veya yeni bir çalışma alanına katılırken yeniden çalıştırın. #### Mantık fonksiyonlarında çalışma zamanı kimlik bilgileri Fonksiyonunuz Twenty üzerinde çalıştığında, platform kodunuz yürütülmeden önce kimlik bilgilerini ortam değişkenleri olarak enjekte eder: * `TWENTY_API_URL`: Uygulamanızın hedeflediği Twenty API'nin temel URL’si. * `TWENTY_API_KEY`: Uygulamanızın varsayılan fonksiyon rolü kapsamına sahip kısa ömürlü anahtar. Notlar: * Oluşturulan istemciye URL veya API anahtarı geçirmeniz gerekmez. Çalışma zamanında `TWENTY_API_URL` ve `TWENTY_API_KEY` değerlerini process.env üzerinden okur. * API anahtarının izinleri, `application-config.ts` içinde `defaultRoleUniversalIdentifier` aracılığıyla referans verilen role göre belirlenir. Bu, uygulamanızın mantık fonksiyonları tarafından kullanılan varsayılan roldür. * Uygulamalar, en az ayrıcalık ilkesini izlemek için roller tanımlayabilir. Yalnızca fonksiyonlarınızın ihtiyaç duyduğu izinleri verin ve ardından `defaultRoleUniversalIdentifier` değerini o rolün evrensel tanımlayıcısına yönlendirin. ### Hello World örneği Nesneleri, mantık fonksiyonlarını, ön uç bileşenlerini ve birden çok tetikleyiciyi gösteren minimal, uçtan uca bir örneği [buradan](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world) inceleyin: ## Manuel kurulum (scaffolder olmadan) En iyi başlangıç deneyimi için `create-twenty-app` kullanmanızı önersek de, bir projeyi manuel olarak da kurabilirsiniz. CLI'yi global olarak kurmayın. Bunun yerine `twenty-sdk`'yi yerel bir bağımlılık olarak ekleyin ve package.json içinde betikleri bağlayın: ```bash filename="Terminal" yarn add -D twenty-sdk ``` Ardından şu gibi betikler ekleyin: ```json filename="package.json" { "scripts": { "auth:login": "twenty auth:login", "auth:logout": "twenty auth:logout", "auth:status": "twenty auth:status", "auth:switch": "twenty auth:switch", "auth:list": "twenty auth:list", "app:dev": "twenty app:dev", "app:generate": "twenty app:generate", "app:uninstall": "twenty app:uninstall", "entity:add": "twenty entity:add", "function:logs": "twenty function:logs", "function:execute": "twenty function:execute", "help": "twenty help" } } ``` Artık aynı komutları Yarn üzerinden çalıştırabilirsiniz; örn. `yarn app:dev`, `yarn app:generate` vb. ## Sorun Giderme * Kimlik doğrulama hataları: `yarn auth:login` çalıştırın ve API anahtarınızın gerekli izinlere sahip olduğundan emin olun. * Sunucuya bağlanılamıyor: API URL’sini ve Twenty sunucusunun erişilebilir olduğunu doğrulayın. * Türler veya istemci eksik/eski: `yarn app:generate` çalıştırın. * Geliştirme modu eşitlenmiyor: `yarn app:dev`'in çalıştığından ve değişikliklerin ortamınız tarafından yok sayılmadığından emin olun. Discord Yardım Kanalı: https://discord.com/channels/1130383047699738754/1130386664812982322