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: En İyi Uygulamalar
---
Bu belge, arka uçta çalışırken uymanız gereken en iyi uygulamaları açıklar.
## Modüler bir yaklaşım izleyin
Arka uç, NestJS ile çalışırken temel bir ilke olan modüler bir yaklaşımı benimser. Kodunuzu temiz ve düzenli bir kod tabanı sağlamak için yeniden kullanılabilir modüllere ayırdığınızdan emin olun.
Her modül belirli bir özellik veya işlevselliği kapsamalı ve iyi tanımlanmış bir kapsama sahip olmalıdır. Bu modüler yaklaşım, sorumlulukların net bir şekilde ayrılmasını sağlar ve gereksiz karmaşıklıkları ortadan kaldırır.
## Modüllerde kullanılmak üzere servisleri dışa açın
Her zaman kod okunabilirliğini ve bakım yapılabilirliğini artıran, net ve tek bir sorumluluğa sahip hizmetler oluşturun. Hizmetlerin adlarını açıklayıcı ve tutarlı bir şekilde adlandırın.
Diğer modüllerde kullanmak istediğiniz hizmetleri dışa açmalısınız. Hizmetleri diğer modüllere dışa açmak, NestJS'nin güçlü bağımlılık enjeksiyonu sistemi sayesinde mümkündür ve bileşenler arasında gevşek bağlılığı teşvik eder.
## `any` tipini kullanmaktan kaçının
Bir değişkeni `any` olarak tanımladığınızda, TypeScript'in tür denetleyicisi herhangi bir tür denetimi yapmaz ve değişkene herhangi bir türde değer atamanızı mümkün kılar. TypeScript, değere göre değişkenin türünü belirlemek için tür çıkarımı kullanır. `any` olarak tanımlandığında, TypeScript türü artık çıkaramaz. Bu, geliştirme sırasında türle ilgili hataları yakalamayı zorlaştırır, çalışma zamanı hatalarına yol açar ve kodun bakım yapılabilirliğini, güvenilirliğini ve başkaları tarafından anlaşılabilirliğini azaltır.
Bu nedenle her şeyin bir türü olması gerekir. Bu yüzden, ad ve soyadı alanları olan yeni bir nesne oluşturuyorsanız, nesnenin yapısını tanımlayan ve ad ile soyadı alanlarını içeren bir arayüz veya tür tanımlamalısınız.

View File

@@ -0,0 +1,39 @@
---
title: Özel Nesneler
---
Nesneler, bir kuruluşa özgü verileri (kayıtlar, nitelikler ve değerler) saklamanıza olanak tanır. Twenty, hem standart hem de özel nesneler sağlar.
Standart nesneler, tüm kullanıcılar için kullanılabilir bir dizi niteliğe sahip yerleşik nesnelerdir. Twenty'deki standart nesne örnekleri arasında Şirket ve Kişi yer alır. Standart nesneler, tüm Twenty kullanıcıları için de mevcut olan standart alanlara sahiptir, örneğin Şirket.görünenAd.
Özel nesneler, kuruluşunuza özgü bilgileri depolamak için oluşturabileceğiniz nesnelerdir. Yerleşik değildir; çalışma alanınızdaki üyeler, standart nesnelerin uygun olmadığı bilgileri tutmak için özel nesneler oluşturabilir ve özelleştirebilir.
## Üst Düzey Şema
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/custom-object-schema.png" alt="Üst Düzey Şema" />
</div>
<br />
## Nasıl Çalışır
Özel nesneler, nesnelerin şekli, adı ve türünü belirleyen meta veri tablolarından gelir. Tüm bu bilgiler, tablolar içeren meta veri şema veritabanında bulunur:
* **VeriKaynağı**: Verinin nerede bulunduğuna dair detaylar.
* **Nesne**: Nesneyi tarif eder ve bir Veri Kaynağı'na bağlanır.
* **Alan**: Bir Nesnenin alanlarını özetler ve Nesneye bağlanır.
Özel bir nesne eklemek için, çalışma alanı üyesi /metadata API'sini sorgulayacaktır. Bu, meta verileri uygun şekilde günceller ve meta verilere dayanarak bir GraphQL şeması hesaplar ve bunu daha sonra kullanmak üzere bir GQL önbelleğine kaydeder.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/add-custom-objects.jpeg" alt="Özel nesneler eklemek için /metadata API'sini sorgulayın" />
</div>
<br />
Veri almak için süreç, /graphql uçnoktasına sorgular yapmayı ve bunları Sorgu Çözücü'den geçirmeyi içerir.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/custom-object-schema.png" alt="/graphql uçnoktasını sorgulayarak verileri alın" />
</div>

View File

@@ -0,0 +1,46 @@
---
title: Özellik Bayrakları
---
Özellik bayrakları deneysel özellikleri gizlemek için kullanılır. Twenty için, çalışma alanı seviyesinde ayarlanırlar, kullanıcı seviyesinde değil.
## Yeni bir özellik bayrağı ekleme
`FeatureFlagKey.ts` dosyasında özellik bayrağını ekleyin:
```ts
type FeatureFlagKey =
| 'IS_FEATURENAME_ENABLED'
| ...;
```
Ayrıca `feature-flag.entity.ts` enumuna ekleyin:
```ts
enum FeatureFlagKeys {
IsFeatureNameEnabled = 'IS_FEATURENAME_ENABLED',
...
}
```
Bir **backend** özelliği üzerinde bir özellik bayrağı uygulamak için kullanın:
```ts
@Gate({
featureFlag: 'IS_FEATURENAME_ENABLED',
})
```
Bir **frontend** özelliği üzerinde bir özellik bayrağı uygulamak için kullanın:
```ts
const isFeatureNameEnabled = useIsFeatureEnabled('IS_FEATURENAME_ENABLED');
```
## Dağıtım için özellik bayraklarını yapılandırın
`core.featureFlag` Tablosundaki ilgili kaydı değiştirin:
| kimlik | anahtar | çalışma alanı kimliği | değer |
| -------- | ------------------------ | --------------------- | ------- |
| Rastgele | `IS_FEATURENAME_ENABLED` | Çalışma Alanı kimliği | `doğru` |

View File

@@ -0,0 +1,125 @@
---
title: Klasör Mimarisi
info: Sunucu klasör mimarimize detaylı bir bakış
---
Arka uç dizin yapısı aşağıdaki gibidir:
```
server
└───ability
└───constants
└───core
└───database
└───decorators
└───filters
└───guards
└───health
└───integrations
└───metadata
└───workspace
└───utils
```
## Yetkiler
İzinleri tanımlar ve her bir varlık için işleyiciler içerir.
## Dekoratörler
Ek işlevsellik için NestJS'te özel dekoratörleri tanımlar.
Daha fazla bilgi için [özel dekoratörler](https://docs.nestjs.com/custom-decorators) sayfasına bakın.
## Filtreler
GraphQL uç noktalarında oluşabilecek istisnaları ele almak için istisna filtreleri içerir.
## Guard'lar
Daha fazla bilgi için [guard'lar](https://docs.nestjs.com/guards) sayfasına bakın.
## Sağlık
Veritabanının beklendiği gibi çalışıp çalışmadığını doğrulamak için JSON döndüren, herkese açık bir REST API'si (healthz) içerir.
## Meta Veriler
Özel nesneleri tanımlar ve bir GraphQL API'sini (graphql/metadata) kullanıma sunar.
## İş Alanı
Meta verilere dayalı özel GraphQL şeması oluşturur ve sunar.
### Çalışma Alanı Dizin Yapısı
```
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
```
Çalışma alanı dizininin kökünde, `createGraphQLSchema` fonksiyonunu içeren `workspace.factory.ts` dosyası bulunur. Bu fonksiyon, meta verileri kullanarak her bir çalışma alanına özgü bir şema üretir. Şema ve resolver oluşturmayı ayırarak, bu ayrık bileşenleri birleştiren `makeExecutableSchema` fonksiyonunu kullanırız.
Bu strateji sadece düzenle ilgili değildir; aynı zamanda performans ve ölçeklenebilirliği artırmak için oluşturulan tür tanımlarının önbelleğe alınması gibi optimizasyonlara da yardımcı olur.
### Çalışma Alanı Şema Oluşturucu
GraphQL şemasını oluşturur ve şunları içerir:
#### Factory'ler:
GraphQL ile ilgili yapıları oluşturmak için özelleşmiş kurucular.
* type.factory, alan meta verilerini `TypeMapperService` kullanarak GraphQL türlerine dönüştürür.
* type-definition.factory, `objectMetadata` temel alınarak GraphQL girdi veya çıktı nesneleri oluşturur.
#### GraphQL Türleri
Numaralandırmalar, girdiler, nesneler ve skalerleri içerir ve şema oluşturmanın yapı taşları olarak hizmet eder.
#### Arayüzler ve Nesne Tanımları
GraphQL varlıkları için şablonları içerir ve `MONEY` veya `URL` gibi hem önceden tanımlı hem de özel türleri kapsar.
#### Servisler
FieldMetadataType ile uygun GraphQL skalerini veya sorgu değiştiricilerini ilişkilendirmekten sorumlu servisi içerir.
#### Depolama
Yeniden kullanılabilir tür tanımlarını barındıran ve GraphQL türlerinin yinelenmesini önleyen `TypeDefinitionsStorage` sınıfını içerir.
### Çalışma Alanı Resolver Oluşturucu
GraphQL şemasında sorgulama ve mutasyon için resolver fonksiyonları oluşturur.
Bu dizindeki her bir factory, çeşitli tablolar genelinde uyarlanabilir kullanım için tasarlanmış `FindManyResolverFactory` gibi, farklı bir resolver türü üretmekten sorumludur.
### Çalışma Alanı Sorgu Çalıştırıcı
Veritabanında oluşturulan sorguları çalıştırır ve sonucu çözümleyip getirir.

View File

@@ -0,0 +1,41 @@
---
title: Mesaj Kuyruğu
---
Kuyruklar, asenkron işlemlerin gerçekleştirilmesine imkan tanır. Kayıt esnasında hoş geldin e-postası göndermek gibi arka plan görevleri gerçekleştirmek için kullanılabilirler.
Her kullanım durumu, `MessageQueueServiceBase`'den genişletilmiş kendi kuyruk sınıfına sahip olacaktır.
Şu anda yalnızca kuyruk sürücüsü olarak `bull-mq`[bull-mq](https://bullmq.io/) destekliyoruz.
## Yeni bir kuyruk oluşturma ve kullanma adımları
1. Yeni kuyruğunuz için enum `MESSAGE_QUEUES` altında bir kuyruk adı ekleyin.
2. Kuyruğun değişken adını bağımlılık belirteci olarak kullanarak kuyruk fabrikası uygulamasını sağlayın.
3. Oluşturduğunuz kuyruğu, gerekli modüle/hizmete kuyruk adıyla birlikte bağımlılık belirteci kullanarak enjekte edin.
4. Üretici gibi token tabanlı enjeksiyon ile çalışan sınıfını ekleyin.
### Örnek kullanım
```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: Backend Komutları
icon: terminal
---
## Faydalı Komutlar
Bu komutlar packages/twenty-server klasöründen çalıştırılmalıdır.
Diğer herhangi bir klasörden `npx nx {command} twenty-server` (veya `npx nx run twenty-server:{command}`) çalıştırabilirsiniz.
### İlk Kurulum
```
npx nx database:reset twenty-server # setup the database with dev seeds
```
### Sunucuyu Başlatma
```
npx nx run twenty-server:start
```
### Kod Temizleme
```
npx nx run twenty-server:lint # pass --fix to fix lint errors
```
### Test
```
npx nx run twenty-server:test:unit # run unit tests
npx nx run twenty-server:test:integration # run integration tests
```
Not: Entegrasyon testlerini çalıştırmadan önce veritabanını sıfırlamanız gerekirse `npx nx run twenty-server:test:integration:with-db-reset` komutunu kullanabilirsiniz.
### Veritabanını Sıfırlama
Veritabanını sıfırlamak ve tohum yüklemek istiyorsanız, aşağıdaki komutu kullanabilirsiniz:
```bash
npx nx run twenty-server:database:reset
```
### Geçişler
#### Core/Metadata şemalarında (TypeORM) nesneler için
```bash
npx nx run twenty-server:database:migrate:generate
```
## Teknoloji Yığını
Twenty, arka uç için öncelikle NestJS kullanır.
Prisma, kullandığımız ilk ORM idi. Ancak, kullanıcıların özel alanlar ve özel nesneler oluşturmasına izin vermek için, ince ayar kontrolü gerektirdiği için alt düzey bir seviye daha mantıklı geldi. Proje şu anda TypeORM kullanmaktadır.
İşte teknoloji yığını artık böyle görünüyor.
**Çekirdek**
* [NestJS](https://nestjs.com/)
* [TypeORM](https://typeorm.io/)
* [GraphQL Yoga](https://the-guild.dev/graphql/yoga-server)
**Veritabanı**
* [Postgres](https://www.postgresql.org/)
**Üçüncü Şahıs Entegrasyonları**
* [Sentry](https://sentry.io/welcome/) hataları izlemek için
**Test**
* [Jest](https://jestjs.io/)
**Araçlar**
* [Yarn](https://yarnpkg.com/)
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
**Geliştirme**
* [AWS EKS](https://aws.amazon.com/eks/)

View File

@@ -0,0 +1,85 @@
---
title: Zapier Uygulaması
---
Zapier'i kullanarak Twenty'yi 3000+ uygulama ile zahmetsizce senkronize edin. Görevleri otomatikleştirin, verimliliği artırın ve müşteri ilişkilerinizi güçlendirin!
## Zapier Hakkında
Zapier, ekibinizin her gün kullandığı uygulamaları bağlayarak iş akışlarını otomatikleştirmenize olanak tanıyan bir araçtır. Zapier'in temel konsepti, Zaps olarak adlandırılan otomasyon iş akışlarıdır ve tetikleyiciler ile işlemleri içerir.
Zapier'in nasıl çalıştığı hakkında daha fazla bilgi edinebilirsiniz [burada](https://zapier.com/how-it-works).
## Kurulum
### Adım 1: Zapier paketlerini yükleyin
```bash
cd packages/twenty-zapier
yarn
```
### Adım 2: CLI ile giriş yapın
Zapier kimlik bilgilerinizi kullanarak CLI ile oturum açın:
```bash
zapier login
```
### Adım 3: Çevre değişkenlerini ayarlayın
`packages/twenty-zapier` klasöründen şunu çalıştırın:
```bash
cp .env.example .env
```
Uygulamayı yerel ortamda çalıştırın, [http://localhost:3000/settings/api-webhooks](http://localhost:3000/settings/api-webhooks) adresine gidin ve bir API anahtarı oluşturun.
Yeni oluşturduğunuz API anahtarı ile `.env` dosyasındaki **YOUR_API_KEY** değerini değiştirin.
## Geliştirme
<Warning>
Herhangi bir `zapier` komutundan önce `yarn build` çalıştırdığınızdan emin olun.
</Warning>
### Test
```bash
yarn test
```
### Lint
```bash
yarn format
```
### Kod düzenlerken izle ve derle
```bash
yarn watch
```
### Zapier uygulamanızı doğrulayın
```bash
yarn validate
```
### Zapier uygulamanızı dağıtın
```bash
yarn deploy
```
### Tüm Zapier CLI komutlarını listeleyin
```bash
zapier
```

View File

@@ -0,0 +1,79 @@
---
title: Hatalar, İstekler ve Çekme İstekleri
icon: bug
info: Sorunları bildirin, özellik talep edin ve koda katkıda bulunun
---
## Hataları Bildirme
Bir hatayı bildirmek için lütfen [GitHub'da bir sorun oluşturun](https://github.com/twentyhq/twenty/issues/new).
[Discord'da](https://discord.gg/cx5n4Jzs57) da yardım isteyebilirsiniz.
## Özellik İstekleri
Eğer bunun bir hata olmadığından emin değilseniz ve bir özellik isteğine daha yakın olduğunu düşünüyorsanız, muhtemelen [bunun yerine bir tartışma başlatmalısınız](https://github.com/twentyhq/twenty/discussions/new).
## Çekme İsteği Gönderin
Twenty'ye koda katkıda bulunmak bir çekme isteği (PR) ile başlar.
### Başlamadan Önce
1. İlgili çalışmalar için [mevcut sorunları](https://github.com/twentyhq/twenty/issues) kontrol edin
2. Yeni özellikler için, tartışmak üzere önce bir sorun açın
3. [Davranış Kuralları](https://github.com/twentyhq/twenty/blob/main/.github/CODE_OF_CONDUCT.md) belgemizi inceleyin
### Fork'layın ve Klonlayın
1. Depoyu GitHub'da fork'layın
2. Fork'unuzu klonlayın:
```bash
git clone https://github.com/YOUR_USERNAME/twenty.git
cd twenty
```
3. Upstream uzak depoyu ekleyin:
```bash
git remote add upstream https://github.com/twentyhq/twenty.git
```
### Bir Dal Oluşturun
```bash
git checkout -b feature/your-feature-name
```
Açıklayıcı dal adları kullanın:
* `feature/add-export-button`
* `fix/login-redirect-issue`
* `docs/update-api-guide`
### Değişikliklerinizi Yapın
1. Temiz, iyi belgelenmiş kod yazın
2. Mevcut kod stilini izleyin
3. Yeni işlevsellik için testler ekleyin
4. Gerektiğinde belgeleri güncelleyin
### PR'nizi Gönderin
1. Dalınızı gönderin:
```bash
git push origin feature/your-feature-name
```
2. GitHub'da bir PR açın
3. PR şablonunu doldurun
4. İlgili sorunları ilişkilendirin
### PR Kontrol Listesi
* [ ] Kod, proje stil yönergelerine uyuyor
* [ ] Testler yerelde geçiyor
* [ ] Belgeler güncellendi
* [ ] PR açıklaması değişiklikleri açıklar

View File

@@ -0,0 +1,329 @@
---
title: En İyi Uygulamalar
icon: star
---
Bu belge, ön yüz üzerinde çalışırken takip etmeniz gereken en iyi uygulamaları özetler.
## Durum Yönetimi
React ve Jotai, kod tabanında durumu yönetir.
### Durumu depolamak için Jotai atomlarını kullanın
Durumunuzu depolamak için ihtiyaç duyduğunuz kadar atom oluşturmak iyi bir uygulamadır.
<Warning>
Prop drilling ile gereğinden fazla sade olmaya çalışmaktansa, fazladan atom kullanmak daha iyidir.
</Warning>
```tsx
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
export const myAtomState = createAtomState<string>({
key: 'myAtomState',
defaultValue: 'default value',
});
export const MyComponent = () => {
const [myAtom, setMyAtom] = useAtomState(myAtomState);
return (
<div>
<input
value={myAtom}
onChange={(e) => setMyAtom(e.target.value)}
/>
</div>
);
}
```
### Durum saklamak için `useRef` kullanmayın.
Durum saklamak için `useRef` kullanmaktan kaçının.
Durum saklamak istiyorsanız, `useState` veya `useAtomState` ile Jotai atomlarını kullanmalısınız.
Bazı yeniden render edilmelerin olmasını önlemek için `useRef`'e ihtiyacınız varmış gibi hissediyorsanız, [yeniden render yönetimi](#managing-re-renders) konusuna bakın.
## Yeniden render yönetimi
React'ta yeniden render'ları yönetmek zor olabilir.
Gereksiz yeniden render'ları önlemek için izlenecek bazı kurallar burada.
Yeniden render'ları **her zaman** önleyebileceğinizi unutmayın, olayların nedenini anlayarak.
### Kök seviyesinde çalışın
Yeni özelliklerde yeniden render'ları önlemek, onları kök seviyesinde ortadan kaldırarak artık kolaylaştı.
`PageChangeEffect` yan bileşeni, sayfa değişikliği sırasında yürütülecek tüm mantığı içeren tek bir `useEffect` barındırır.
Bu şekilde, yalnızca bir yerin yeniden render tetikleyebileceğini bilirsiniz.
### Kod tabanına `useEffect` eklemeden önce iki kez düşünün.
Yeniden render'lar çoğunlukla gereksiz `useEffect`'lerden kaynaklanır.
`useEffect`'e ihtiyacınız olup olmadığını düşünmelisiniz ya da mantığı bir olay işleyici fonksiyonuna taşıyabilirsiniz.
Genellikle mantığı `handleClick` veya `handleChange` gibi fonksiyonlara taşımayı kolay bulursunuz.
Bunları `onCompleted`, `onError`, vb. gibi Apollo kitaplıklarında da bulabilirsiniz.
### `useEffect` veya veri çekme mantığını çıkarmak için bir yan bileşen kullanın.
Kök bileşenize bir `useEffect` eklemeniz gerektiğini hissediyorsanız, bunu bir yan bileşene çıkarmayı düşünmelisiniz.
Aynısını Apollo kancaları ile veri çekme mantığı için de uygulayabilirsiniz.
```tsx
// ❌ Bad, will cause re-renders even if data is not changing,
// because useEffect needs to be re-evaluated
export const PageComponent = () => {
const [data, setData] = useAtomState(dataState);
const [someDependency] = useAtomState(someDependencyState);
useEffect(() => {
if(someDependency !== data) {
setData(someDependency);
}
}, [someDependency]);
return <div>{data}</div>;
};
export const App = () => (
<PageComponent />
);
```
```tsx
// ✅ Good, will not cause re-renders if data is not changing,
// because useEffect is re-evaluated in another sibling component
export const PageComponent = () => {
const [data, setData] = useAtomState(dataState);
return <div>{data}</div>;
};
export const PageData = () => {
const [data, setData] = useAtomState(dataState);
const [someDependency] = useAtomState(someDependencyState);
useEffect(() => {
if(someDependency !== data) {
setData(someDependency);
}
}, [someDependency]);
return <></>;
};
export const App = () => (
<>
<PageData />
<PageComponent />
</>
);
```
### Atom aile durumlarını ve seçimcilerini kullanın
Atom aile durumları ve seçimcileri, yeniden render'ları önlemenin harika bir yoludur.
Bir öğe listesini saklamanız gerektiğinde kullanılabilirdir.
### `React.memo(MyComponent)` kullanmamalısınız.
`React.memo()` kullanmaktan kaçının çünkü bu yeniden render'ın nedenini çözmez, bunun yerine yeniden render zincirini kırar, bu da beklenmeyen davranışlara yol açabilir ve kodun yeniden faktör edilmesini çok zor hale getirebilir.
### `useCallback` veya `useMemo` kullanımını sınırlayın.
Genellikle gerekli değildir ve performans kazanımı farkedilemeyecek kadar az olduğu için kodun okunmasını ve bakımını zorlaştırır.
## Console.log'lar
`console.log` ifadeleri geliştirirken değerlidir, değişken değerleri ve kod akışı hakkında gerçek zamanlı yanıtlar sağlar. Ancak, üretim kodunda bırakmak çeşitli sorunlara yol açabilir:
1. **Performans**: Aşırı loglama, özellikle istemci tarafı uygulamalarda çalışma zamanı performansını etkileyebilir.
2. **Güvenlik**: Hassas verileri loglama, tarayıcı konsolunu inceleyen herkes için kritik bilgilerin açığa çıkmasına neden olabilir.
3. **Temizlik**: Konsolu loglarla doldurmak, geliştiricilerin veya araçların görmesi gereken önemli uyarıları veya hataları gizleyebilir.
4. **Profesyonellik**: Konsolu kontrol eden son kullanıcılar veya müşteriler, birçok log ifadesi gördüğünde kodun kalitesini ve detaycılığını sorgulayabilir.
Kodunuzu üretime taşımadan önce tüm `console.log`ları kaldırdığınızdan emin olun.
## İsimlendirme
### Değişken Adlandırma
Değişken adları değişkenin amacını veya işlevini doğru bir şekilde tanımlamalıdır.
#### Genel adlar sorunu
Programlamada genel adlar ideal değildir çünkü kesinlik eksikliği nedeniyle belirsizlik ve kod okunabilirliğinin azalmasına neden olabilir. Bu tür adlar, değişkenin veya fonksiyonun amacını iletmede başarısız olur, geliştiricilerin kodun amacını daha derin bir araştırma yapmadan anlamalarını zorlaştırır. Bu, artan hata ayıklama süresi, hatalara eğilimli olma ve bakım ve işbirliği zorluklarına yol açabilir. Öte yandan, açıklayıcı adlandırma, kodu kendi kendini açıklayıcı hale getirir ve gezilebilirliği artırarak kod kalitesini ve geliştirici verimliliğini artırır.
```tsx
// ❌ Bad, uses a generic name that doesn't communicate its
// purpose or content clearly
const [value, setValue] = useState('');
```
```tsx
// ✅ Good, uses a descriptive name
const [email, setEmail] = useState('');
```
#### Değişken adlarında kaçınılması gereken bazı kelimeler
* kukla
### Olay işleyicileri
Olay işleyici adları `handle` ile başlamalı, bileşen props'larında olayları adlandırmak için `on` bir ön ek olarak kullanılmaktadır.
```tsx
// ❌ Bad
const onEmailChange = (val: string) => {
// ...
};
```
```tsx
// ✅ Good
const handleEmailChange = (val: string) => {
// ...
};
```
## Opsiyonel Props
Opsiyonel bir prop için varsayılan değeri geçmekten kaçının.
**ÖRNEK**
Aşağıda tanımlanan `EmailField` bileşeni alın:
```tsx
type EmailFieldProps = {
value: string;
disabled?: boolean;
};
const EmailField = ({ value, disabled = false }: EmailFieldProps) => (
<TextInput value={value} disabled={disabled} fullWidth />
);
```
**Kullanım**
```tsx
// ❌ Bad, passing in the same value as the default value adds no value
const Form = () => <EmailField value="username@email.com" disabled={false} />;
```
```tsx
// ✅ Good, assumes the default value
const Form = () => <EmailField value="username@email.com" />;
```
## Bileşenleri props olarak geçirme
Mümkün olduğunca, bileşenleri kendi içinde istemsiz geçen bileşenler olarak gönderin, böylece çocuklar hangi props'ları geçmeleri gerektiğine kendileri karar verebilirler.
Bunun en yaygın örneği simge bileşenleridir:
```tsx
const SomeParentComponent = () => <MyComponent Icon={MyIcon} />;
// In MyComponent
const MyComponent = ({ MyIcon }: { MyIcon: IconComponent }) => {
const theme = useTheme();
return (
<div>
<MyIcon size={theme.icon.size.md}>
</div>
)
};
```
React'in bir bileşeni bileşen olarak anlaması için PascalCase kullanmalısınız, böylece daha sonra `<MyIcon>` ile örnekleyebilirsiniz.
## Prop Taşıma: Minimumda Tutun
React bağlamında prop taşıma, durum değişkenlerini ve ayarlayıcılarını, aracı bileşenler kullanmasalar bile birçok bileşen katmanı aracılığıyla aktarma uygulamasına atıfta bulunur. Bazen gerekli olmakla birlikte, aşırı prop taşıma şu durumlara yol açabilir:
1. **Azalan Okunabilirlik**: Bir prop'un nereden kaynaklandığını veya nerede kullanıldığını izlemek, derin bir şekilde iç içe geçmiş bir bileşen yapısında karışık hale gelebilir.
2. **Bakım Zorlukları**: Bir bileşenin prop yapısındaki değişiklikler, prop'u doğrudan kullanmasalar bile, birden fazla bileşende ayarlamalar yapılmasını gerektirebilir.
3. **Azalan Bileşen Yeniden Kullanılabilirliği**: Çok fazla props'u yalnızca aşağıya aktarma amacıyla alan bir bileşen, daha az genel amaçlı hale gelir ve farklı bağlamlarda yeniden kullanılması zorlaşır.
Aşırı prop taşıma kullanıyorsanız, [durum yönetimi en iyi uygulamalarına](#state-management) bakın.
## İçe Aktarımlar
İçe aktarırken, tüm veya göreli yolları belirtmek yerine belirlenen takma adları tercih edin.
**Takma Adlar**
```js
{
alias: {
"~": path.resolve(__dirname, "src"),
"@": path.resolve(__dirname, "src/modules"),
"@testing": path.resolve(__dirname, "src/testing"),
},
}
```
**Kullanım**
```tsx
// ❌ Bad, specifies the entire relative path
import {
CatalogDecorator
} from '../../../../../testing/decorators/CatalogDecorator';
import {
ComponentDecorator
} from '../../../../../testing/decorators/ComponentDecorator';
```
```tsx
// ✅ Good, utilises the designated aliases
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from 'twenty-ui/testing';
```
## Şema Doğrulama
[Zod](https://github.com/colinhacks/zod), tiplenmemiş nesneler için bir şema doğrulayıcıdır:
```js
const validationSchema = z
.object({
exist: z.boolean(),
email: z
.string()
.email('Email must be a valid email'),
password: z
.string()
.regex(PASSWORD_REGEX, 'Password must contain at least 8 characters'),
})
.required();
type Form = z.infer<typeof validationSchema>;
```
## Geriye Dönük Uyumsuz Değişiklikler
Testler henüz kapsamlı bir şekilde entegre edilmediği için, ilerlemeden önce yapılan değişikliklerin başka yerlerde bozulmalara neden olmadığından emin olmak için her zaman kapsamlı manuel testler yapın.

View File

@@ -0,0 +1,110 @@
---
title: Klasör Mimarisi
icon: folder-tree
info: Klasör mimarimize detaylı bir bakış
---
Bu kılavuzda, proje dizin yapısının ayrıntılarını ve bunun Twenty'nin düzenine ve bakım kolaylığına nasıl katkıda bulunduğunu inceleyeceksiniz.
Bu klasör mimarisi kuralını izleyerek, belirli özelliklerle ilgili dosyaları bulmak kolaylaşır ve uygulamanın ölçeklenebilir ve bakımı yapılabilir olması sağlanır.
```
front
└───modules
│ └───module1
│ │ └───submodule1
│ └───module2
│ └───ui
│ │ └───display
│ │ └───inputs
│ │ │ └───buttons
│ │ └───...
└───pages
└───...
```
## Sayfalar
Uygulama rotaları tarafından tanımlanan üst düzey bileşenleri içerir. Bunlar, daha alt düzey bileşenleri modules klasöründen içe aktarırlar (daha fazla ayrıntı aşağıda).
## Modüller
Her modül, kendine özgü bileşenlerini, durumlarını ve iş mantığını içeren bir özellik ya da özellik grubu temsil eder.
Hepsi aşağıdaki yapıyı takip etmelidir. Modüllerin içine modüller (alt modüller) yerleştirebilirsiniz ve aynı kurallar uygulanır.
```
module1
└───components
│ └───component1
│ └───component2
└───constants
└───contexts
└───graphql
│ └───fragments
│ └───queries
│ └───mutations
└───hooks
│ └───internal
└───states
│ └───selectors
└───types
└───utils
```
### Bağlamlar
Bağlam, verileri her seviyede prop'ları elle aktarmak zorunda kalmadan bileşen ağacından aşağıya iletmenin bir yoludur.
Daha fazla bilgi için [React Context](https://react.dev/reference/react#context-hooks) sayfasına bakın.
### GraphQL
Parçalar, sorgular ve mutasyonları içerir.
Daha fazla bilgi için [GraphQL](https://graphql.org/learn/) sayfasına bakın.
* Parçalar
Bir parça, farklı yerlerde kullanabileceğiniz, bir sorgunun yeniden kullanılabilir bir parçasıdır. Parçaları kullanarak, kodun kopyalanmasını önlemek daha kolaydır.
Daha fazla bilgi için [GraphQL Parçaları](https://graphql.org/learn/queries/#fragments) sayfasına bakın.
* Sorgular
Daha fazla bilgi için [GraphQL Sorgular](https://graphql.org/learn/queries/) sayfasına bakın.
* Mutasyonlar
Daha fazla bilgi için [GraphQL Mutasyonlar](https://graphql.org/learn/queries/#mutations) sayfasına bakın.
### Kancalar
Daha fazla bilgi için [Kancalar](https://react.dev/learn/reusing-logic-with-custom-hooks) sayfasına bakın.
### Durumlar
Durum yönetim mantığını içerir. [Jotai](https://jotai.org) bunu ele almaktadır.
* Seçiciler: Türetilmiş atomlar (`createAtomSelector` kullanılarak) diğer atomlardan değerleri hesaplar ve otomatik olarak önbelleğe alınır.
React'ın yerleşik durum yönetimi, bir bileşen içinde hala durumu ele alır.
### Yardımcılar
Sadece yeniden kullanılabilir saf fonksiyonları içermelidir. Aksi takdirde, `hooks` klasöründe özel kancalar oluşturun.
## Kullanıcı Arayüzü
Uygulamada kullanılan tüm tekrar kullanılabilir UI bileşenlerini içerir.
Bu klasör, belirli bileşen türleri için `data`, `display`, `feedback` ve `input` gibi alt klasörler içerebilir. Her bir bileşen, kendi içinde bağımsız ve yeniden kullanılabilir olmalı, böylece uygulamanın farklı kısımlarında kullanılabilir.
UI bileşenlerini `modules` klasöründeki diğer bileşenlerden ayırarak, tutarlı bir tasarımı korumak ve kullanıcı arayüzünde değişiklikleri kod tabanının diğer bölümlerini (iş mantığı) etkilemeden yapmak daha kolaydır.
## Arayüz ve bağımlılıklar
Diğer modüllerin kodunu, `ui` klasörü hariç, herhangi bir modülden içe aktarabilirsiniz. Bu, kodunun test edilmesini kolaylaştıracaktır.
### Dahili
Bir modülün her bir parçası (kancalar, durumlar, ...) yalnızca modül içinde kullanılan kısımları içeren bir `internal` klasöre sahip olabilir.

View File

@@ -0,0 +1,91 @@
---
title: Ön Yüz Komutları
icon: terminal
---
## Faydalı Komutlar
### Uygulamayı Başlatma
```bash
npx nx start twenty-front
```
### API graphql şemasına dayalı graphql şemasını yeniden oluştur
```bash
npx nx run twenty-front:graphql:generate --configuration=metadata
```
VEYA
```bash
npx nx run twenty-front:graphql:generate
```
### Kod Temizleme
```bash
npx nx run twenty-front:lint # pass --fix to fix lint errors
```
## Çeviriler
```bash
npx nx run twenty-front:lingui:extract
npx nx run twenty-front:lingui:compile
```
### Test
```bash
npx nx run twenty-front:test # run jest tests
npx nx run twenty-front:storybook:serve:dev # run storybook
npx nx run twenty-front:storybook:test # run tests # (needs yarn storybook:serve:dev to be running)
npx nx run twenty-front:storybook:coverage # (needs yarn storybook:serve:dev to be running)
```
## Teknoloji Yığını
Proje temiz ve basit bir yığına sahip, minimum şablon koduyla.
**Uygulama**
* [React](https://react.dev/)
* [Apollo](https://www.apollographql.com/docs/)
* [GraphQL Codegen](https://the-guild.dev/graphql/codegen)
* [Jotai](https://jotai.org/)
* [TypeScript](https://www.typescriptlang.org/)
**Test**
* [Jest](https://jestjs.io/)
* [Storybook](https://storybook.js.org/)
**Araçlar**
* [Yarn](https://yarnpkg.com/)
* [Craco](https://craco.js.org/docs/)
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
## Mimari
### Rotalama
[React Router](https://reactrouter.com/) rotalamayı halleder.
Gereksiz [yeniden renderların](/l/tr/developers/contribute/capabilities/frontend-development/best-practices-front#managing-re-renders) önlenmesi için tüm rotalama mantığı `PageChangeEffect` içindeki bir `useEffect`'te yer alır.
### Durum Yönetimi
[Jotai](https://jotai.org/) durum yönetimini ele alır.
Durum yönetimi hakkında daha fazla bilgi için [en iyi uygulamalar](/l/tr/developers/contribute/capabilities/frontend-development/best-practices-front#state-management) bölümüne bakın.
## Test
[Jest](https://jestjs.io/) birim testi aracı olarak kullanılırken [Storybook](https://storybook.js.org/) bileşen testleri için kullanılır.
Jest, esas olarak yardımcı programların test edilmesi için kullanılır ve bileşenlerin kendisi için değil.
Storybook, izole bileşenlerin davranışlarının test edilmesi ve tasarım sisteminin gösterilmesi için kullanılır.

View File

@@ -0,0 +1,178 @@
---
title: Kısayollar
---
## Giriş
Bir kısayolu dinlemeniz gerektiğinde, normalde `onKeyDown` olay dinleyicisini kullanırsınız.
Ancak `twenty-front` uygulamasında, aynı anda monte edilmiş farklı bileşenlerde kullanılan aynı kısayollar arasında çakışmalar olabilir.
Örneğin, Enter tuşunu dinleyen bir sayfanız ve Enter tuşunu dinleyen bir modalınız varsa, ve modalın içinde Enter tuşunu dinleyen bir Seçim bileşeni varsa, hepsi aynı anda monte edildiğinde bir çakışma yaşayabilirsiniz.
## `useScopedHotkeys` hook'u
Bu sorunu ele almak için, kısayolları çakışma olmadan dinlemeyi mümkün kılan özel bir kanca geliştirdik.
Bir bileşene yerleştirirsiniz ve sadece bileşen monte edildiğinde VE belirtilen **kısayol kapsamı** aktif olduğunda kısayolları dinleyecektir.
## Pratikte kısayolları nasıl dinleyebilirsiniz?
Kısayol dinleme kurulumu iki adımdan oluşur:
1. Kısayolları dinleyecek [kısayol kapsamını](#what-is-a-hotkey-scope-) ayarlayın
2. Kısayolları dinlemek için `useScopedHotkeys` hook'unu kullanın
Kısayol kapsamlarının kurulumu, sol menü veya komut menüsü gibi diğer kullanıcı arayüzü öğelerinin de kısayolları dinleyebileceği için, basit sayfalarda bile gereklidir.
## Kısayollar için kullanım durumları
Genel olarak, kısayollara ihtiyaç duyan iki kullanım durumunuz olacaktır:
1. Bir sayfada veya bir sayfada monte edilmiş bir bileşende
2. Bir kullanıcı eylemi nedeniyle dikkati çeken modal-tipi bir bileşende
İkinci kullanım durumu, örneğin bir modal içinde bir açılır menü gibi, yineleyici olabilir.
### Bir sayfada kısayolları dinlemek
Örnek:
```tsx
const PageListeningEnter = () => {
const {
setHotkeyScopeAndMemorizePreviousScope,
goBackToPreviousHotkeyScope,
} = usePreviousHotkeyScope();
// 1. Set the hotkey scope in a useEffect
useEffect(() => {
setHotkeyScopeAndMemorizePreviousScope(
ExampleHotkeyScopes.ExampleEnterPage,
);
// Revert to the previous hotkey scope when the component is unmounted
return () => {
goBackToPreviousHotkeyScope();
};
}, [goBackToPreviousHotkeyScope, setHotkeyScopeAndMemorizePreviousScope]);
// 2. Use the useScopedHotkeys hook
useScopedHotkeys(
Key.Enter,
() => {
// Some logic executed on this page when the user presses Enter
// ...
},
ExampleHotkeyScopes.ExampleEnterPage,
);
return <div>My page that listens for Enter</div>;
};
```
### Modal-tipi bir bileşende kısayolları dinlemek
Bu örnekte, ebeveynine kapanmasını söylemek için Escape tuşunu dinleyen bir modal bileşeni kullanacağız.
Burada kullanıcı etkileşimi, kapsamı değiştirmektir.
```tsx
const ExamplePageWithModal = () => {
const [showModal, setShowModal] = useState(false);
const {
setHotkeyScopeAndMemorizePreviousScope,
goBackToPreviousHotkeyScope,
} = usePreviousHotkeyScope();
const handleOpenModalClick = () => {
// 1. Set the hotkey scope when user opens the modal
setShowModal(true);
setHotkeyScopeAndMemorizePreviousScope(
ExampleHotkeyScopes.ExampleModal,
);
};
const handleModalClose = () => {
// 1. Revert to the previous hotkey scope when the modal is closed
setShowModal(false);
goBackToPreviousHotkeyScope();
};
return <div>
<h1>My page with a modal</h1>
<button onClick={handleOpenModalClick}>Open modal</button>
{showModal && <MyModalComponent onClose={handleModalClose} />}
</div>;
};
```
Sonra modal bileşeninde:
```tsx
const MyDropdownComponent = ({ onClose }: { onClose: () => void }) => {
// 2. Use the useScopedHotkeys hook to listen for Escape.
// Note that escape is a common hotkey that could be used by many other components
// So it's important to use a hotkey scope to avoid conflicts
useScopedHotkeys(
Key.Escape,
() => {
onClose()
},
ExampleHotkeyScopes.ExampleModal,
);
return <div>My modal component</div>;
};
```
Bu modeli, mount/unmount ile yalnızca bir useEffect'e güvenmenin çakışmayı önlemek için yeterli olmayabileceği durumlarda kullanmak önemlidir.
Bu çakışmaların hata ayıklaması zor olabilir ve genellikle useEffect'lerle daha sık meydana gelebilir.
## Kısayol kapsamı nedir?
Kısayol kapsamı, kısayolların aktif olduğu bir bağlamı temsil eden bir dizedir. Genellikle bir enum olarak kodlanmıştır.
Kısayol kapsamını değiştirdiğinizde, bu kapsamı dinleyen kısayollar etkinleştirilecek ve diğer kapsamları dinleyen kısayollar devre dışı bırakılacaktır.
Aynı anda yalnızca bir kapsam ayarlayabilirsiniz.
Örneğin, her sayfa için kısayol kapsamları `PageHotkeyScope` enum'unda tanımlanmıştır:
```tsx
export enum PageHotkeyScope {
Settings = 'settings',
CreateWorkspace = 'create-workspace',
SignInUp = 'sign-in-up',
CreateProfile = 'create-profile',
PlanRequired = 'plan-required',
ShowPage = 'show-page',
PersonShowPage = 'person-show-page',
CompanyShowPage = 'company-show-page',
CompaniesPage = 'companies-page',
PeoplePage = 'people-page',
OpportunitiesPage = 'opportunities-page',
ProfilePage = 'profile-page',
WorkspaceMemberPage = 'workspace-member-page',
TaskPage = 'task-page',
}
```
Dahili olarak, şu anda seçili olan kapsam, uygulama genelinde paylaşılan bir Jotai atomunda saklanır:
```tsx
export const currentHotkeyScopeState = createState<HotkeyScope>({
key: 'currentHotkeyScopeState',
defaultValue: INITIAL_HOTKEYS_SCOPE,
});
```
Ancak bu atom asla el ile yönetilmemelidir! Bunu bir sonraki bölümde nasıl kullanacağımızı göreceğiz.
## İçsel olarak nasıl çalışıyor?
Gereksiz yeniden render etme işlemlerinden kaçınarak daha performanslı hale getiren [react-hotkeys-hook](https://react-hotkeys-hook.vercel.app/docs/intro) üzerine ince bir sarmalayıcı yaptık.
Ayrıca, kısayol kapsamı durumunu yönetmek ve uygulamanın her yerinde kullanılabilir hale getirmek için bir Jotai atomu oluşturuyoruz.

View File

@@ -0,0 +1,8 @@
---
title: Storybook
description: Twenty'nin UI bileşen kütüphanesine göz atın
---
Storybook'ta eksiksiz bileşen kütüphanemizi ve dokümantasyonumuzu görüntüleyin.
[Storybook'u Aç →](https://storybook.twenty.com)

View File

@@ -0,0 +1,291 @@
---
title: Stil Rehberi
icon: paintbrush
---
Bu belge, kod yazarken uyulması gereken kuralları içermektedir.
Buradaki amaç, okunması ve bakımı kolay tutarlı bir kod tabanı oluşturmaktır.
Bunun için, biraz daha ayrıntılı olmak, çok kısa olmaktan daha iyidir.
İnsanların kodu yazmaktan daha sık okuduğunu her zaman aklınızda bulundurun; özellikle herkesin katkıda bulunabildiği açık kaynak bir projede.
Burada tanımlanmayan, ancak linters tarafından otomatik olarak kontrol edilen birçok kural vardır.
## React
### Fonksiyonel bileşenler kullanın
Her zaman TSX fonksiyonel bileşenlerini kullanın.
Varsayılan `import`'u `const` ile kullanmayın, çünkü okunması daha zordur ve kod tamamlama ile içe aktarmak daha zordur.
```tsx
// ❌ Bad, harder to read, harder to import with code completion
const MyComponent = () => {
return <div>Hello World</div>;
};
export default MyComponent;
// ✅ Good, easy to read, easy to import with code completion
export function MyComponent() {
return <div>Hello World</div>;
};
```
### Özellikler
Prop'ların türünü oluşturun ve dışa aktarmaya gerek yoksa ona `(ComponentName)Props` adını verin.
Props destructuring kullanın.
```tsx
// ❌ Bad, no type
export const MyComponent = (props) => <div>Hello {props.name}</div>;
// ✅ Good, type
type MyComponentProps = {
name: string;
};
export const MyComponent = ({ name }: MyComponentProps) => <div>Hello {name}</div>;
```
#### Prop türlerini tanımlamak için `React.FC` veya `React.FunctionComponent` kullanmaktan kaçının
```tsx
/* ❌ - Bad, defines the component type annotations with `FC`
* - With `React.FC`, the component implicitly accepts a `children` prop
* even if it's not defined in the prop type. This might not always be
* desirable, especially if the component doesn't intend to render
* children.
*/
const EmailField: React.FC<{
value: string;
}> = ({ value }) => <TextInput value={value} disabled fullWidth />;
```
```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.
*/
type EmailFieldProps = {
value: string;
};
const EmailField = ({ value }: EmailFieldProps) => (
<TextInput value={value} disabled fullWidth />
);
```
#### JSX Elemanlarında Tek Değişkenli Prop Yayılımından Kaçının
JSX elemanlarında tek değişkenli prop yayılımını, örneğin `{...props}` kullanmaktan kaçının. Bu uygulama, bileşenin hangi prop'ları aldığını belirsizleştirdiği için okunması zor ve bakımı güç kodlara yol açar.
```tsx
/* ❌ - Bad, spreads a single variable prop into the underlying component
*/
const MyComponent = (props: OwnProps) => {
return <OtherComponent {...props} />;
}
```
```tsx
/* ✅ - Good, Explicitly lists all props
* - Enhances readability and maintainability
*/
const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => {
return <OtherComponent {...{ prop1, prop2, prop3 }} />;
};
```
Gerekçe:
* İlk bakışta, hangi prop'ların kod tarafından geçirildiği daha açıktır, bu da anlamayı ve bakımı kolaylaştırır.
* Prop'lar aracılığıyla bileşenler arasında sıkı bağlanmayı önlemeye yardımcı olur.
* Linting araçları, prop'ları açıkça listelediğinizde yanlış yazılmış veya kullanılmayan prop'ları tanımlamayı kolaylaştırır.
## JavaScript
### Nullish-birleştirme operatörü `??` kullanın
```tsx
// ❌ Bad, can return 'default' even if value is 0 or ''
const value = process.env.MY_VALUE || 'default';
// ✅ Good, will return 'default' only if value is null or undefined
const value = process.env.MY_VALUE ?? 'default';
```
### Opsiyonel zincirleme `?.` kullanın
```tsx
// ❌ Bad
onClick && onClick();
// ✅ Good
onClick?.();
```
## TypeScript
### `interface` yerine `type` kullanın
Neredeyse her zaman örtüştükleri ve `type` daha esnek olduğu için her zaman `interface` yerine `type` kullanın.
```tsx
// ❌ Bad
interface MyInterface {
name: string;
}
// ✅ Good
type MyType = {
name: string;
};
```
### enum'lar yerine string literal'leri kullanın
[String literalleri](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types), TypeScript'te enum benzeri değerleri yönetmek için en iyi yöntemdir. Pick ve Omit ile genişletilmeleri daha kolaydır ve özellikle kod tamamlama ile daha iyi bir geliştirici deneyimi sunarlar.
TypeScript, enum'ların neden kaçınılması gereken bir seçenek olduğunu [burada](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enums) açıklamaktadır.
```tsx
// ❌ Bad, utilizes an enum
enum Color {
Red = "red",
Green = "green",
Blue = "blue",
}
let color = Color.Red;
```
```tsx
// ✅ Good, utilizes a string literal
let color: "red" | "green" | "blue" = "red";
```
#### GraphQL ve iç kütüphaneler
GraphQL codegen tarafından üretilen enum'ları kullanmalısınız.
Bir iç kütüphane kullanırken de bir enum kullanmak daha iyidir, böylece iç kütüphane, iç API ile ilgili olmayan bir string literal türü açmak zorunda kalmaz.
Örnek:
```TSX
const {
setHotkeyScopeAndMemorizePreviousScope,
goBackToPreviousHotkeyScope,
} = usePreviousHotkeyScope();
setHotkeyScopeAndMemorizePreviousScope(
RelationPickerHotkeyScope.RelationPicker,
);
```
## Şekil Verme
### StyledComponents kullanın
Bileşenleri [Linaria styled](https://github.com/callstack/linaria) ile stillendirin.
```tsx
// ❌ Bad
<div className="my-class">Hello World</div>
```
```tsx
// ✅ Good
const StyledTitle = styled.div`
color: red;
`;
```
Styled bileşenleri, bunları "gerçek" bileşenlerden ayırt etmek için "Styled" önekiyle belirtin.
```tsx
// ❌ Bad
const Title = styled.div`
color: red;
`;
```
```tsx
// ✅ Good
const StyledTitle = styled.div`
color: red;
`;
```
### Temalandırma
Çoğu bileşen şekillendirmesi için temayı kullanmak tercih edilen bir yaklaşımdır.
#### Ölçü birimleri
Styled bileşenler içinde doğrudan `px` veya `rem` değerlerini kullanmaktan kaçının. Gerekli değerler genellikle temada tanımlanmıştır, bu nedenle bu amaçlar için temayı kullanmak önerilir.
#### Renkler
Yeni renkler eklemekten kaçının; Bunun yerine temadaki mevcut paleti kullanın. Palet uyum sağlamıyorsa, lütfen ekibin düzeltmesi için bir yorum bırakın.
```tsx
// ❌ Bad, directly specifies style values without utilizing the theme
const StyledButton = styled.button`
color: #333333;
font-size: 1rem;
font-weight: 400;
margin-left: 4px;
border-radius: 50px;
`;
```
```tsx
// ✅ Good, utilizes the theme
const StyledButton = styled.button`
color: ${({ theme }) => theme.font.color.primary};
font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.regular};
margin-left: ${({ theme }) => theme.spacing(1)};
border-radius: ${({ theme }) => theme.border.rounded};
`;
```
## Tip içermeyen importları zorunlu kılma
Tip ithalatlarından kaçının. Bu standardı uygulamak için bir Oxlint kuralı, herhangi bir tür içe aktarmayı denetler ve raporlar. Bu, TypeScript kodunda tutarlılık ve okunabilirliği sağlamaya yardımcı olur.
```tsx
// ❌ Bad
import { type Meta, type StoryObj } from '@storybook/react';
// ❌ Bad
import type { Meta, StoryObj } from '@storybook/react';
// ✅ Good
import { Meta, StoryObj } from '@storybook/react';
```
### Neden Tip İthalatları Yok
* **Tutarlılık**: Hem tip hem de değer ithalatları için tek bir yaklaşım kullanarak, kod tabanı modül import stilinde tutarlı kalır.
* **Okunabilirlik**: İthalat türü olmadığında, değer veya tip ithal ettiğiniz zaman daha anlaşılır olur böylece kod okunabilirliği artırılır. Bu belirsizliği azaltır ve ithal edilen sembollerinin amacını anlamayı kolaylaştırır.
* **Bakım Kolaylığı**: Kod tabanının bakımını kolaylaştırır çünkü geliştiriciler kodu incelerken veya değiştirirken yalnızca tip ithalatlarını tanımlayabilir ve bulabilirler.
### Oxlint Kuralı
Bir Oxlint kuralı, `typescript/consistent-type-imports`, tür içe aktarmalarının yasaklanması standardını uygular. Bu kural, herhangi bir tip ithalat ihlali için hata veya uyarı üretir.
Lütfen unutmayın ki bu kural, istemeden yapılan tip ithalatlarının gerçekleştiği nadir durumları özellikle ele alır. TypeScript'in kendisi, [TypeScript 3.8 sürüm notlarında](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html) belirtildiği gibi, bu uygulamayı caydırmaktadır. Çoğu durumda, yalnızca tip ithalatları kullanmanıza gerek yoktur.
Kodunuzun bu kurala uyduğundan emin olmak için, geliştirme iş akışınızın bir parçası olarak Oxlint'i çalıştırdığınızdan emin olun.

View File

@@ -0,0 +1,60 @@
---
title: Figma ile Çalışma
info: Twenty'nin Figma'sında nasıl işbirliği yapabileceğinizi öğrenin
---
Figma, tasarımcılar ve geliştiriciler arasındaki iletişim engelini aşmaya yardımcı olan işbirliği odaklı bir arayüz tasarım aracıdır.
Bu kılavuz, Figma ile nasıl işbirliği yapacağınızı açıklar.
## Erişim
1. **Paylaşılan bağlantıya erişin:** Projenin Figma dosyasına [buradan](https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty) erişebilirsiniz.
2. **Oturum açın:** Henüz oturum açmadıysanız, Figma sizden oturum açmanızı isteyecektir.
Geliştirici modu ve ayrılmış bir çerçeveyi seçme yeteneği gibi ana özellikler yalnızca oturum açmış kullanıcılara sunulur.
<Warning>
Bir hesabınız olmadan etkili bir şekilde işbirliği yapamazsınız.
</Warning>
## Figma yapısı
Sol kenar çubuğundan Twenty'nin Figma'sındaki farklı sayfalara erişebilirsiniz. Bu şekilde organize edilmişlerdir:
* **Bileşenler sayfası:** Bu, ilk sayfadır. Tasarımcı, tasarım dosyası boyunca kullanılan yeniden kullanılabilir tasarım öğelerini oluşturmak ve organize etmek için kullanır. Örneğin, düğmeler, simgeler, semboller veya diğer herhangi bir yeniden kullanılabilir bileşen. Bu, tasarımda tutarlılığı sağlamak amacıyla hizmet eder.
* **Ana sayfa:** İkinci sayfa ana sayfadır ve projenin tam kullanıcı arayüzünü gösterir. You can press ***Play*** to use the full app prototype.
* **Özellikler sayfaları:** Diğer sayfalar genellikle devam eden özelliklere adanmıştır. Uygulama veya web sitesinin belirli özelliklerinin veya modüllerinin tasarımlarını içerir. Genellikle hala devam etmektedirler.
## Kullanışlı İpuçları
Yalnızca-okuma erişimiyle tasarımı düzenleyemezsiniz, ancak tasarımları koda dönüştürmek için kullanışlı olan tüm özelliklere erişebilirsiniz.
### Geliştirici modunu kullan
Figma'nın Geliştirici Modu, tasarım ve geliştirme arasındaki boşluğu doldurarak, kolay tasarım gezintisi, etkili varlık yönetimi, verimli iletişim araçları, araç kutusu entegrasyonları, hızlı kod parçacıkları ve önemli katman bilgileri ile geliştiricilerin üretkenliğini arttırır. Geliştirici Modu hakkında daha fazla bilgiyi [buradan](https://www.figma.com/dev-mode/) öğrenebilirsiniz.
Tasarım özelliklerini görmek, CSS kopyalamak ve varlıklara erişmek için araç çubuğunun sağ kısmında, "Geliştirici" moduna geçiş yapın.
### Prototipi kullan
Prototip görünümüne erişmek için tuvaldeki herhangi bir öğeye tıklayın ve arayüzün sağ üst köşesindeki “Play” düğmesine basın. Prototip modu, tasarımla nihai ürünmüş gibi etkileşim kurmanızı sağlar. Ekranlar arasındaki akışı gösterir ve düğmeler, bağlantılar veya menüler gibi arayüz öğelerinin etkileşim sırasında nasıl davrandığını gösterir.
1. **Geçişler ve animasyonları anlama:** Prototip modunda, bir tasarımcı tarafından ekranlar veya UI öğeleri arasında eklenen herhangi bir geçişi veya animasyonu görebilir, geliştiricilere hedeflenen davranış ve stille ilgili net görsel talimatlar verir.
2. **Uygulama açıklaması:** Bir prototip aynı zamanda belirsizlikleri azaltmaya da yardımcı olabilir. Geliştiriciler, belirli öğelerin işlevselliği veya görünümü hakkında daha iyi bir anlayış kazanmak adına onunla etkileşime geçebilirler.
Figma platformunu öğrenmek ile ilgili daha kapsamlı detaylar ve rehberlik için resmi [Figma Dokümantasyonu](https://help.figma.com/hc/en-us) sayfasını ziyaret edebilirsiniz.
### Mesafeleri ölç
Bir öğe seçin, (Mac) `Option` tuşunu veya (Windows) `Alt` tuşunu basılı tutun, ardından aralarındaki mesafeyi görmek için başka bir öğenin üzerine gelin.
### VSCode için Figma uzantısı (Önerilir)
[Figma for VS Code](https://marketplace.visualstudio.com/items?itemName=figma.figma-vscode-extension) ile tasarım dosyalarını gezebilir ve inceleyebilir, tasarımcılarla işbirliği yapabilir, değişiklikleri takip edebilir ve uygulama hızını artırabilirsiniz - tüm bunları metin düzenleyicinizden ayrılmadan yapabilirsiniz.
Önerilen uzantılarımızın bir parçasıdır.
## İşbirliği
1. **Yorumları Kullanarak:** Araç çubuğunun sol kısmındaki balon simgesine tıklayarak yorum yapma özelliğini kullanabilirsiniz.
2. **İmleç sohbeti:** Figma'nın güzel bir özelliği İmleç sohbetidir. Eğer bir başkasının sizinle aynı anda Figma'yı kullandığını görürseniz, bir mesaj göndermek için Mac'te `;` tuşuna, Windows'ta ise `/` tuşuna basın.

View File

@@ -0,0 +1,317 @@
---
title: Yerel Kurulum
icon: laptop-code
description: Twenty'i yerel olarak çalıştırmak isteyen katkıda bulunanlar (veya meraklı geliştiriciler) için kılavuz.
---
## Ön Gereksinimler
<Tabs>
<Tab title="Linux ve macOS">
Twenty'i yüklemeden ve kullanmadan önce bilgisayarınıza aşağıdakileri yüklediğinizden emin olun:
* [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
* [Node v24.5.0](https://nodejs.org/en/download)
* [yarn v4](https://yarnpkg.com/getting-started/install)
* [nvm](https://github.com/nvm-sh/nvm/blob/master/README.md)
<Warning>
`npm` çalışmaz, bunun yerine `yarn` kullanmalısınız. Yarn artık Node.js ile birlikte geliyor, bu yüzden ayrı bir yüklemeye gerek yoktur.
Eğer henüz yapmadıysanız Yarn'ı etkinleştirmek için sadece `corepack enable` komutunu çalıştırmanız gerekiyor.
</Warning>
</Tab>
<Tab title="Windows (WSL)">
1. WSL Kurun
PowerShell'i Yönetici olarak açın ve çalıştırın:
```powershell
wsl --install
```
Şimdi bilgisayarınızı yeniden başlatmanız gerektiğine dair bir uyarı göreceksiniz. Eğer görmüyorsanız, manuel olarak yeniden başlatın.
Yeniden başlatıldığında bir PowerShell penceresi açılacak ve Ubuntu yüklenecek. Bu biraz zaman alabilir.
Ubuntu kurulumunuz için bir kullanıcı adı ve şifre oluşturmanız gerektiğine dair bir uyarı göreceksiniz.
2. git'i Yükleyin ve Yapılandırın
```bash
sudo apt-get install git
git config --global user.name "Your Name"
git config --global user.email "youremail@domain.com"
```
3. nvm, node.js ve yarn'ı Yükleyin
<Warning>
Doğru `node` versiyonunu yüklemek için `nvm` kullanın. `.nvmrc` tüm katkıda bulunanların aynı versiyonu kullanmasını sağlar.
</Warning>
```bash
sudo apt-get install curl
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
```
nvm'i kullanmak için terminalinizi kapatıp yeniden açın. Sonra aşağıdaki komutları çalıştırın.
```bash
nvm install # installs recommended node version
nvm use # use recommended node version
corepack enable
```
</Tab>
</Tabs>
---
## Adım 1: Git Clone
Terminalinizde aşağıdaki komutu çalıştırın.
<Tabs>
<Tab title="SSH (Önerilen)">
SSH anahtarlarını henüz kurmadıysanız, bunu nasıl yapacağınızı [buradan](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/about-ssh) öğrenebilirsiniz.
```bash
git clone git@github.com:twentyhq/twenty.git
```
</Tab>
<Tab title="HTTPS">
```bash
git clone https://github.com/twentyhq/twenty.git
```
</Tab>
</Tabs>
## Adım 2: Kök Dizine Konuçlanın
```bash
cd twenty
```
Sonraki adımlardaki tüm komutları projenin kök dizininden çalıştırmalısınız.
## Adım 3: Bir PostgreSQL Veritabanı Kurun
<Tabs>
<Tab title="Linux">
**Seçenek 1 (tercih edilen):** Veritabanınızı yerel olarak hazırlamak için:
Linux makinenize PostgreSQL yüklemek için aşağıdaki bağlantıyı kullanın: [PostgreSQL Kurulumu](https://www.postgresql.org/download/linux/)
```bash
psql postgres -c "CREATE DATABASE \"default\";" -c "CREATE DATABASE test;"
```
Not: İzin hatalarından kaçınmak için `psql` komutundan önce `sudo -u postgres` eklemeniz gerekebilir.
**Seçenek 2:** Eğer docker yüklüyse:
```bash
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
<Tab title="Mac OS">
**Seçenek 1 (tercih edilen):** Veritabanınızı `brew` ile yerel olarak kurmak için:
```bash
brew install postgresql@16
export PATH="/opt/homebrew/opt/postgresql@16/bin:$PATH"
brew services start postgresql@16
psql postgres -c "CREATE DATABASE \"default\";" -c "CREATE DATABASE test;"
```
PostgreSQL sunucusunun çalışıp çalışmadığını kontrol etmek için şu komutu çalıştırabilirsiniz:
```bash
brew services list
```
Yükleyici, macOS'ta Homebrew aracılığıyla yüklenirken
varsayılan olarak `postgres` kullanıcısını oluşturmayabilir. Bunun yerine, macOS kullanıcı adınıza (ör. "john") uygun bir PostgreSQL rolü oluşturur.
Gerekiyorsa `postgres` kullanıcısını kontrol etmek ve oluşturtmak için şu adımları izleyin:
```bash
# Connect to PostgreSQL
psql postgres
or
psql -U $(whoami) -d postgres
```
psql isteminde (postgres=#) şu komutu çalıştırın:
```bash
# List existing PostgreSQL roles
\du
```
Şu benzer bir çıktı göreceksiniz:
```bash
Role name | Attributes | Member of
-----------+-------------+-----------
john | Superuser | {}
```
Eğer listede bir `postgres` rolü görmüyorsanız, bir sonraki adıma geçin.
`postgres` rolünü manuel olarak oluşturun:
```bash
CREATE ROLE postgres WITH SUPERUSER LOGIN;
```
Bu, `postgres` adıyla giriş erişimi olan bir süper kullanıcı rolü oluşturur.
```bash
Role name | Attributes | Member of
-----------+-------------+-----------
postgres | Superuser | {}
john | Superuser | {}
```
**Seçenek 2:** Eğer docker yüklüyse:
```bash
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
<Tab title="Windows (WSL)">
Aşağıdaki tüm adımlar WSL terminalinde (sanallaştırma makineniz içinde) çalıştırılmalıdır.
**Seçenek 1:** PostgreSQL'i yerel olarak hazırlamak için:
Linux sanal makinenize PostgreSQL yüklemek için aşağıdaki bağlantıyı kullanın: [PostgreSQL Kurulumu](https://www.postgresql.org/download/linux/)
```bash
psql postgres -c "CREATE DATABASE \"default\";" -c "CREATE DATABASE test;"
```
Not: İzin hatalarından kaçınmak için `psql` komutundan önce `sudo -u postgres` eklemeniz gerekebilir.
**Seçenek 2:** Eğer docker yüklüyse:
WSL üzerinde Docker çalıştırmak ek bir karmaşıklık katmanı ekler.
Yalnızca ek adımlar dahil olmak üzere extra karmaşıklık adımlarına aşinaysanız kullanın. [Docker Desktop WSL2](https://docs.docker.com/desktop/wsl) etkinleştirmenizi içeren.
```bash
make -C packages/twenty-docker postgres-on-docker
```
</Tab>
</Tabs>
Artık veritabanına `localhost:5432` üzerinden erişebilirsiniz.
Yukarıdaki Docker seçeneğini kullandıysanız, varsayılan kimlik bilgileri kullanıcı adı `postgres` ve parola `postgres` şeklindedir. Yerel PostgreSQL kurulumları için, makinenizde yapılandırılmış kimlik bilgilerini ve rolleri kullanın.
## Adım 4: Redis Veritabanı (önbellek) Kurun
Twenty, en iyi performansı sağlamak için bir Redis önbelleği gerektirir.
<Tabs>
<Tab title="Linux">
**Seçenek 1:** Redis'i yerel olarak sağlamak için:
Linux makinenize Redis yüklemek için şu bağlantıyı kullanın: [Redis Kurulumu](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/)
**Seçenek 2:** Eğer docker yüklüyse:
```bash
make -C packages/twenty-docker redis-on-docker
```
</Tab>
<Tab title="Mac OS">
**Seçenek 1 (tercih edilen):** Redis'i `brew` ile yerel olarak sağlamak için:
```bash
brew install redis
```
Redis sunucunuzu başlatın:
```bash
brew services start redis
```
**Seçenek 2:** Eğer docker yüklüyse:
```bash
make -C packages/twenty-docker redis-on-docker
```
</Tab>
<Tab title="Windows (WSL)">
**Seçenek 1:** Redis'i yerel olarak sağlamak için:
Linux sanal makinenize Redis yüklemek için şu bağlantıyı kullanın: [Redis Kurulumu](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/)
**Seçenek 2:** Eğer docker yüklüyse:
```bash
make -C packages/twenty-docker redis-on-docker
```
</Tab>
</Tabs>
Bir istemci GUI'ye ihtiyacınız varsa, [Redis Insight](https://redis.io/insight/) (ücretsiz sürüm mevcut) öneriyoruz.
## Adım 5: Ortam değişkenlerini ayarlayın
Projenizi yapılandırmak için çevresel değişkenler veya `.env` dosyaları kullanın. Daha fazla bilgi [burada](/l/tr/developers/self-host/capabilities/setup).
`.env.example` dosyalarını `/front` ve `/server` içine kopyalayın:
```bash
cp ./packages/twenty-front/.env.example ./packages/twenty-front/.env
cp ./packages/twenty-server/.env.example ./packages/twenty-server/.env
```
<Info>
**Çoklu Çalışma Alanı Modu:** Varsayılan olarak, Twenty yalnızca bir çalışma alanının oluşturulabildiği tek çalışma alanı modunda çalışır. Çoklu çalışma alanı desteğini etkinleştirmek için (alt alan adına dayalı özellikleri test etmek açısından kullanışlıdır), sunucunuzdaki `.env` dosyanızda `IS_MULTIWORKSPACE_ENABLED=true` değerini ayarlayın. Ayrıntılar için [Çoklu Çalışma Alanı Modu](/l/tr/developers/self-host/capabilities/setup#multi-workspace-mode) bölümüne bakın.
</Info>
## Adım 6: Bağımlılıkların yüklenmesi
Twenty server'ı oluşturup veritabanınıza bazı veriler yerleştirmek için aşağıdaki komutu çalıştırın:
```bash
yarn
```
`npm` veya `pnpm` çalışmaz
## Adım 7: Projeyi çalıştırma
<Tabs>
<Tab title="Linux">
Dağıtımınıza bağlı olarak, Redis sunucusu otomatik olarak başlatılabilir.
Değilse, dağıtımınız için [Redis Kurulum Kılavuzu](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/) üzerinden kontrol edin.
</Tab>
<Tab title="Mac OS">
Redis zaten çalışıyor olmalıdır. Değilse, şu komutu çalıştırın:
```bash
brew services start redis
```
</Tab>
<Tab title="Windows (WSL)">
Dağıtımınıza bağlı olarak, Redis sunucusu otomatik olarak başlatılabilir.
Değilse, dağıtımınız için [Redis Kurulum Kılavuzu](https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/) üzerinden kontrol edin.
</Tab>
</Tabs>
Veritabanınızı aşağıdaki komutla kurun:
```bash
npx nx database:reset twenty-server
```
Sunucuyu, çalışanı ve ön uç hizmetlerini başlatın:
```bash
npx nx start twenty-server
npx nx worker twenty-server
npx nx start twenty-front
```
Alternatif olarak, tüm hizmetleri aynı anda başlatabilirsiniz:
```bash
npx nx start
```
## Adım 8: Twenty'yi kullanın
**Ön Uç**
Twenty'nin ön ucu [http://localhost:3001](http://localhost:3001) adresinde çalışıyor olacak.
Varsayılan demo hesabıyla giriş yapabilirsiniz: `tim@apple.dev` (şifre: `tim@apple.dev`)
**Arka Uç**
* Twenty'nin sunucusu [http://localhost:3000](http://localhost:3000) adresinde çalışır durumda olacak
* GraphQL API'sine [http://localhost:3000/graphql](http://localhost:3000/graphql) adresinden erişebilirsiniz.
* REST API'sine [http://localhost:3000/rest](http://localhost:3000/rest) adresinden ulaşabilirsiniz.
## Sorun Giderme
Herhangi bir sorunla karşılaşırsanız, çözümler için [Sorun Giderme](/l/tr/developers/self-host/capabilities/troubleshooting) sayfasına bakın.

View File

@@ -0,0 +1,77 @@
---
title: Komutlar
icon: terminal
description: Twenty geliştirmek için yararlı komutlar.
---
Komutlar, deponun kök dizininden `npx nx` kullanılarak çalıştırılabilir. Açık hedefleme için `npx nx run {project}:{command}` kullanın.
## Uygulamayı Başlatma
```bash
npx nx start twenty-front # Frontend dev server (http://localhost:3001)
npx nx start twenty-server # Backend server (http://localhost:3000)
npx nx run twenty-server:worker # Background worker
```
## Veritabanı
```bash
npx nx database:reset twenty-server # Reset and seed database
npx nx run twenty-server:database:migrate:prod # Run migrations
npx nx run twenty-server:database:migrate:generate --name <name> --type <fast|slow> # Generate a migration
```
## Lint denetimi
```bash
npx nx lint:diff-with-main twenty-front # Lint changed files (fastest)
npx nx lint:diff-with-main twenty-server
npx nx lint twenty-front --configuration=fix # Auto-fix
```
## Tip denetimi
```bash
npx nx typecheck twenty-front
npx nx typecheck twenty-server
```
## Test
```bash
# Frontend
npx nx test twenty-front # Jest unit tests
npx nx storybook:build twenty-front # Build Storybook
npx nx storybook:test twenty-front # Storybook tests
# Backend
npx nx run twenty-server:test:unit # Unit tests
npx nx run twenty-server:test:integration # Integration tests
npx nx run twenty-server:test:integration:with-db-reset # Integration with DB reset
# Single file (fastest)
npx jest path/to/test.test.ts --config=packages/{project}/jest.config.mjs
```
## GraphQL
```bash
npx nx run twenty-front:graphql:generate # Regenerate types
npx nx run twenty-front:graphql:generate --configuration=metadata # Metadata schema
```
## Çeviriler
```bash
npx nx run twenty-front:lingui:extract # Extract strings
npx nx run twenty-front:lingui:compile # Compile translations
```
## Derleme
```bash
npx nx build twenty-shared # Must be built first
npx nx build twenty-front
npx nx build twenty-server
```

View File

@@ -0,0 +1,31 @@
---
title: Katkıda Bulunun
description: Twenty'nin açık kaynak geliştirmesine katkıda bulunun.
---
<Frame>
<img src="/images/user-guide/github/github-header.png" alt="AI" />
</Frame>
## Genel Bakış
Twenty açık kaynaktır ve topluluktan gelen katkıları memnuniyetle karşılar. İster hataları düzeltiyor, ister özellikler ekliyor ya da belgeleri iyileştiriyor olun, katkılarınız Twenty'yi herkes için daha iyi hâle getirmeye yardımcı olur.
## Katkıda Bulunma Yolları
* **Hataları bildirin**: Sorunları belirlemeye ve belgelemeye yardımcı olun
* **Özellik önerin**: Yeni işlevler önerip uygulayın
* **Belgeleri iyileştirin**: Belgelerimizi daha anlaşılır ve daha faydalı hâle getirin
* **Ön uç geliştirme**: React tabanlı kullanıcı arayüzü üzerinde çalışın
* **Arka uç geliştirme**: NestJS sunucusuna katkıda bulunun
## Başlarken
<CardGroup cols={2}>
<Card title="Hata Raporları ve İstekler" icon="bug" href="/l/tr/developers/contribute/capabilities/bug-and-requests">
Sorunları bildirin veya özellik talep edin
</Card>
<Card title="Frontend Geliştirme" icon="browser" href="/l/tr/developers/contribute/capabilities/frontend-development/folder-architecture-front">
Kullanıcı arayüzüne katkıda bulunun
</Card>
</CardGroup>

View File

@@ -0,0 +1,176 @@
---
title: Stil Rehberi
icon: paintbrush
description: Twenty'ye katkıda bulunmak için kod kuralları ve en iyi uygulamalar.
---
## React
### Yalnızca fonksiyonel bileşenler
Her zaman named export'larla TSX fonksiyonel bileşenlerini kullanın.
```tsx
// ❌ Bad
const MyComponent = () => {
return <div>Hello World</div>;
};
export default MyComponent;
// ✅ Good
export function MyComponent() {
return <div>Hello World</div>;
};
```
### Özellikler
`{ComponentName}Props` adında bir type oluşturun. Destructuring kullanın. `React.FC` kullanmayın.
```tsx
type MyComponentProps = {
name: string;
};
export const MyComponent = ({ name }: MyComponentProps) => <div>Hello {name}</div>;
```
### Tek değişken için prop spread kullanmayın
```tsx
// ❌ Bad
const MyComponent = (props: MyComponentProps) => <Other {...props} />;
// ✅ Good
const MyComponent = ({ prop1, prop2 }: MyComponentProps) => <Other {...{ prop1, prop2 }} />;
```
## Durum Yönetimi
### Global durum için Jotai atomları
```tsx
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
export const myAtomState = createAtomState<string>({
key: 'myAtomState',
defaultValue: 'default value',
});
```
* Prop drilling yerine atomları tercih edin
* Durum için `useRef` kullanmayın — `useState` veya atomları kullanın
* Listeler için atom ailelerini ve seçicileri kullanın
### Gereksiz yeniden render'ları önleyin
* `useEffect` ve veri çekmeyi kardeş sidecar bileşenlere ayırın
* `useEffect` yerine olay işleyicilerini (`handleClick`, `handleChange`) tercih edin
* `React.memo()` kullanmayın — bunun yerine kök nedeni düzeltin
* `useCallback` / `useMemo` kullanımını sınırlayın
```tsx
// ❌ Bad — useEffect in the same component causes re-renders
export const Page = () => {
const [data, setData] = useAtomState(dataState);
const [dep] = useAtomState(depState);
useEffect(() => { setData(dep); }, [dep]);
return <div>{data}</div>;
};
// ✅ Good — extract into sibling
export const PageData = () => {
const [data, setData] = useAtomState(dataState);
const [dep] = useAtomState(depState);
useEffect(() => { setData(dep); }, [dep]);
return <></>;
};
export const Page = () => {
const [data] = useAtomState(dataState);
return <div>{data}</div>;
};
```
## TypeScript
* **`interface` yerine `type`** — daha esnek, birleştirmesi daha kolay
* **enum yerine string literal'lar** — GraphQL codegen enum'ları ve dahili kütüphane API'leri hariç
* **`any` yok** — katı TypeScript zorunludur
* **Type import'ları yok** — normal import'lar kullanın (Oxlint `typescript/consistent-type-imports` tarafından uygulanır)
* **[Zod](https://github.com/colinhacks/zod) kullanın** tiplenmemiş nesnelerin çalışma zamanı doğrulaması için
## JavaScript
```tsx
// Use nullish-coalescing (??) instead of ||
const value = process.env.MY_VALUE ?? 'default';
// Use optional chaining
onClick?.();
```
## İsimlendirme
* **Değişkenler**: camelCase, açıklayıcı (`email` değil `value`, `fieldMetadata` değil `fm`)
* **Sabitler**: SCREAMING_SNAKE_CASE
* **Tipler/Sınıflar**: PascalCase
* **Dosyalar/dizinler**: kebab-case (`.component.tsx`, `.service.ts`, `.entity.ts`)
* **Olay işleyicileri**: `handleClick` (işleyici fonksiyon için `onClick` değil)
* **Bileşen prop'ları**: önek olarak bileşen adını kullanın (`ButtonProps`)
* **Styled bileşenler**: `Styled` öneğini kullanın (`StyledTitle`)
## Stil
[Linaria](https://github.com/callstack/linaria) ile stillendirilmiş bileşenleri kullanın. Tema değerlerini kullanın — kodda sabit tanımlanmış `px`, `rem` veya renklerden kaçının.
```tsx
// ❌ Bad
const StyledButton = styled.button`
color: #333333;
font-size: 1rem;
margin-left: 4px;
`;
// ✅ Good
const StyledButton = styled.button`
color: ${({ theme }) => theme.font.color.primary};
font-size: ${({ theme }) => theme.font.size.md};
margin-left: ${({ theme }) => theme.spacing(1)};
`;
```
## İçe Aktarımlar
Göreli yollar yerine alias kullanın:
```tsx
// ❌ Bad
import { Foo } from '../../../../../testing/decorators/Foo';
// ✅ Good
import { Foo } from '~/testing/decorators/Foo';
import { Bar } from '@/modules/bar/components/Bar';
```
## Klasör Yapısı
```
front
└── modules/ # Feature modules
│ └── module1/
│ ├── components/
│ ├── constants/
│ ├── contexts/
│ ├── graphql/ (fragments, queries, mutations)
│ ├── hooks/
│ ├── states/ (atoms, selectors)
│ ├── types/
│ └── utils/
└── pages/ # Route-level components
└── ui/ # Reusable UI components (display, input, feedback, ...)
```
* Modüller diğer modüllerden import edebilir, ancak `ui/` bağımlılıksız kalmalıdır
* `internal/` alt klasörlerini modüle özel kod için kullanın
* Bileşenler 300 satırın altında, servisler 500 satırın altında