Skip to main content
LibreChat is joining ClickHouse to power the open-source Agentic Data Stack 🎉 Learn more
LibreChat

Kod Standartları ve Kuralları

LibreChat'e katkıda bulunmak için kodlama standartları, çalışma alanı sınırları ve kurallar.

Çalışma Alanı Sınırları

LibreChat bir monorepo'dur. Tüm yeni kodlar doğru çalışma alanını hedeflemelidir:

Çalışma AlanıDilTarafAmaç
/apiJS (eski)BackendExpress sunucusu — buradaki değişiklikleri en aza indirin
/packages/apiTypeScriptBackendYeni backend kodu burada yer alır (sadece TS, /api tarafından tüketilir)
/packages/data-schemasTypeScriptBackendVeritabanı modelleri/şemaları ve veritabanına özgü paylaşılan mantık
/packages/data-providerTypeScriptPaylaşılanAPI tipleri, endpoint'ler, veri servisi — frontend ve backend tarafından kullanılır
/clientTypeScript/ReactFrontendFrontend SPA
/packages/clientTypeScriptFrontendPaylaşılan frontend araçları
  • /packages/api içindeki tüm yeni backend kodları TypeScript olmalıdır.
  • /api değişikliklerini mutlak minimumda tutun (/packages/api dizinini çağıran ince JS sarmalayıcıları).
  • Veritabanına özgü paylaşılan mantık /packages/data-schemas içinde yer alır.
  • Frontend/backend paylaşımlı API mantığı (endpoint'ler, tipler, data-service) /packages/data-provider dizininde yer alır.
  • Proje kök dizininden tüm derlenmiş kodları oluşturun: npm run build.
  • API/tip değişikliklerinden sonra paylaşılan data-provider kodunu yeniden derleyin: npm run build:data-provider.

Genel Kılavuzlar

  • "Clean code" (temiz kod) prensiplerini kullanın: fonksiyonları ve modülleri küçük tutun, tek sorumluluk ilkesine (single responsibility principle) bağlı kalın ve ifade edici, okunabilir kod yazın.
  • Anlamlı ve açıklayıcı değişken ve fonksiyon isimleri kullanın.
  • Kodun okunabilirliğini ve sürdürülebilirliğini kısalığa tercih edin.
  • Tutarlı kod biçimlendirmesi için sağlanan .eslintrc ve .prettierrc dosyalarını kullanın.
  • Mümkün olduğunda otomatik düzeltmeyi kullanarak tüm biçimlendirme lint hatalarını giderin. Tüm TypeScript/ESLint uyarıları ve hataları çözülmelidir.

Adlandırma ve Dosya Organizasyonu

  • Mümkün olduğunda permissions.ts, capabilities.ts veya service.ts gibi tek kelimelik dosya adları kullanın.
  • Birden fazla kelime gerektiğinde, adminCapabilities.ts yerine admin/capabilities.ts gibi dosya bağlamını veren tek kelimelik bir dizini tercih edin.
  • Dizinin bağlam sağlamasına izin verin. app/appConfigService.ts yerine app/service.ts tercih edin.

Kod Yapısı

  • İç içe geçmekten kaçının (Never-nesting): erken dönüşler (early returns), düz kod yapısı ve minimum girinti kullanın. Karmaşık işlemleri, iyi adlandırılmış yardımcı fonksiyonlara bölün.
  • İşlevsel öncelikli: saf işlevler, değiştirilemez veri, zorunlu döngüler yerine map/filter/reduce. Yalnızca alan modellemesini veya durum kapsüllemeyi açıkça iyileştirdiği durumlarda OOP'ye başvurun.
  • Dinamik içe aktarma (dynamic imports) kullanmayın, kesinlikle gerekli olmadığı sürece.
  • Tekrarlanan mantığı özel yardımcı işlevlere (DRY) ayırın. Neredeyse aynı uygulamalar yerine parametreli yardımcıları, sabitleri, paylaşılan doğrulayıcıları, merkezi hata yönetimini ve paylaşılan tipleri tercih edin.

Yineleme ve Performans

  • Döngüleri en aza indirin — özellikle mesaj dizileri gibi sıkça yinelenen paylaşılan veri yapıları üzerinde. Ölçek büyüdükçe her ek geçiş maliyeti artırır.
  • Mümkün olduğunda ardışık O(n) işlemlerini tek bir geçişte birleştirin; iş birleştirilebiliyorsa aynı koleksiyon üzerinde asla iki kez döngü kurmayın.
  • Yinelemeye olan ihtiyacı azaltan veri yapılarını seçin (örneğin, Array.find/Array.includes yerine aramalar için Map/Set kullanın).
  • Gereksiz nesne oluşturmaktan kaçının; zaman-mekan ödünleşimlerini (space-time tradeoffs) göz önünde bulundurun.
  • Bellek sızıntılarını önleyin: closure'lara (kapanışlar) dikkat edin, kaynakları/olay dinleyicilerini (event listeners) temizleyin, döngüsel referanslardan kaçının.

Tip Güvenliği

  • Asla any kullanmayın. Tüm parametreler, dönüş değerleri ve değişkenler için açık türler (explicit types) kullanın.
  • unknown kullanımını sınırlayınunknown, Record<string, unknown> ve as unknown as T iddialarından kaçının. Bir Record<string, unknown> kullanımı neredeyse her zaman eksik bir açık tip tanımına işaret eder.
  • Türleri kopyalamayın — yeni bir tür tanımlamadan önce projenin içinde (özellikle packages/data-provider dizininde) halihazırda bir türün var olup olmadığını kontrol edin. Mevcut türleri yeniden kullanın ve genişletin.
  • Union tiplerini, generic yapıları ve interface'leri uygun şekilde kullanın.

Yorumlar ve Dokümantasyon

  • Kendi kendini belgeleyen kodlar yazın; kodun ne yaptığını anlatan satır içi yorumlar kullanmayın.
  • Yalnızca karmaşık/belirgin olmayan mantık veya genel API'lerdeki intellisense için JSDoc kullanın.
  • Kısa dokümantasyon için tek satırlık JSDoc, karmaşık durumlar için çok satırlı JSDoc kullanın.
  • Kesinlikle gerekli olmadıkça tek satırlık // yorumlarından kaçının.

İçe Aktarma Sırası

İçe aktarmalar (imports) üç bölüm halinde (sırasıyla) düzenlenmiştir:

  1. Paket içe aktarımları — en kısa satır uzunluğundan en uzuna doğru sıralanmıştır (react her zaman ilk içe aktarımdır).
  2. import type içe aktarmaları — en uzundan en kısaya doğru sıralanmıştır (önce paket türleri, ardından yerel türler; uzunluk sıralaması alt gruplar arasında sıfırlanır).
  3. Yerel/proje içe aktarımları — en uzundan en kısaya doğru sıralanmıştır.
  • Aynı modülden gelen değer içe aktarımlarını mümkün olduğunca birleştirin.
  • Tip içe aktarmaları için her zaman bağımsız import type { ... } kullanın; değer içe aktarmalarının içinde asla satır içi type anahtar sözcüğünü kullanmayın (örneğin, import { Foo, type Bar } yanlıştır).

Döngü Tercihleri

  • Döngüleri mümkün olduğunca sınırlandırın. Tek geçişli (single-pass) dönüşümleri tercih edin ve aynı verinin üzerinden tekrar tekrar geçmekten kaçının.
  • performans açısından kritik veya dizin bağımlı işlemler için for (let i = 0; ...) kullanın.
  • Basit dizi yinelemesi için for...of.
  • for...in yalnızca nesne özelliği numaralandırması içindir.

Node.js API Sunucusu

API Tasarımı

  • API'leri tasarlarken RESTful prensiplerini takip edin.
  • Rotalar, denetleyiciler, servisler ve modeller için anlamlı ve açıklayıcı isimler kullanın.
  • Her rota için uygun HTTP yöntemlerini (GET, POST, PUT, DELETE) kullanın.
  • Tutarlı API yanıtları için uygun durum kodlarını ve yanıt yapılarını kullanın (başarı için 2xx, istemciden gelen hatalı istekler için 4xx, sunucu hatası için 5xx).
  • İstisnaları yakalamak ve düzgün bir şekilde yönetmek için try-catch bloklarını kullanın.
  • Uygun hata yönetimini uygulayın ve tutarlı bir şekilde uygun hata yanıtları döndürün.
  • Önemli olayları ve hataları günlüğe kaydetmek için utils dizininde bulunan günlük kaydı sistemini kullanın.
  • requireJWTAuth ara yazılımını (middleware) kullanarak JWT tabanlı, durumsuz (stateless) kimlik doğrulaması yapın.

Dosya Yapısı

Yeni backend kodu, TypeScript olarak /packages/api dizinine eklenir. Eski /api dizini şu yapıyı takip eder:

Rotalar

Her bir HTTP istek yöntemini, kullanılacak ara yazılımları ve her rota için çağrılacak denetleyici işlevini belirtir.

  • Her bir kaynak veya mantıksal gruplandırma için ayrı dosyalarda Express Router kullanarak rotaları tanımlayın.
  • Açıklayıcı rota isimleri kullanın ve RESTful kurallarına uyun.
  • Rotaları kısa tutun ve tek bir sorumluluğa odaklanın.
  • Tüm rotaların başına /api ad alanını ekleyin.

Denetleyiciler

Uygun servis fonksiyonlarını çağırmak ve ilgili yanıt durum kodunu ve JSON gövdesini döndürmek dahil olmak üzere, her rota için mantığı içerir.

  • İstek/yanıt mantığını yönetmek için her rota için ayrı bir kontrolcü dosyası oluşturun.
  • Controller dosyalarını PascalCase kuralını kullanarak adlandırın ve dosya adının sonuna "Controller" ekleyin (örneğin, UserController.js).
  • Karmaşık işlemleri servis veya model dosyalarına devrederek controller'ları ince tutun.

Servisler

Birden fazla controller arasında paylaşılan karmaşık iş mantığını veya işlemleri içerir.

  • Servis dosyalarını PascalCase kuralını kullanarak adlandırın ve dosya adının sonuna "Service" ekleyin (örneğin, AuthService.js).
  • Daha iyi yeniden kullanılabilirlik için servisleri belirli modellere veya veritabanlarına sıkı bir şekilde bağlamaktan kaçının.
  • Her servis içinde tek sorumluluk ilkesini koruyun.

Modeller

Veri varlıklarını ve bunların ilişkilerini temsil etmek için Mongoose modellerini tanımlar.

  • Model dosyaları ve bunlarla ilişkili koleksiyonlar için tekil, PascalCase isimler kullanın (örneğin, User.js ve users koleksiyonu).
  • Modellerde yalnızca gerekli alanları, indeksleri ve doğrulamaları dahil edin.
  • İstek/yanıt nesnelerine doğrudan referans vermekten kaçınarak modelleri API katmanından bağımsız tutun.

Veritabanı Erişimi (MongoDB ve Mongoose)

  • MongoDB ODM'si olarak Mongoose (https://mongoosejs.com) kullanın.
  • Her bir varlık için ayrı model dosyaları oluşturun ve sorumlulukların net bir şekilde ayrıldığından emin olun.
  • Veri bütünlüğünü sağlamak için Mongoose şema doğrulamasını kullanın.
  • Veritabanı bağlantılarını verimli bir şekilde yönetin ve bağlantı sızıntılarından kaçının.
  • Kısa ve okunabilir veritabanı sorguları oluşturmak için Mongoose sorgu oluşturucularını (query builders) kullanın.

React Client

Genel TypeScript ve React En İyi Uygulamaları

  • Statik tiplemeden ve geliştirilmiş araçlardan yararlanmak için TypeScript best practices kullanın.
  • İlgili dosyaları özellik dizinleri içinde gruplandırın (örneğin, SidePanel/Memories/).
  • Bileşenleri PascalCase kuralını kullanarak adlandırın.
  • Bileşenin amacını doğru bir şekilde yansıtan kısa ve açıklayıcı isimler kullanın.
  • Karmaşık bileşenleri uygun olduğunda daha küçük, yeniden kullanılabilir bileşenlere bölün.
  • Bileşenler içindeki işleme (rendering) mantığını minimumda tutun.
  • Yeniden kullanılabilir parçaları ayrı fonksiyonlara veya hook'lara ayırın.
  • TypeScript türlerini veya arayüzlerini kullanarak prop türü tanımlarını uygulayın.
  • Uygun olan yerlerde form doğrulama kullanın (form doğrulama ve gönderimi için React Hook Form kullanıyoruz).

Yerelleştirme

  • İstemciye yönelik tüm metinler useLocalize() hook'u kullanılarak yerelleştirilmelidir.
  • Yalnızca client/src/locales/en/translation.json dosyasındaki İngilizce anahtarları güncelleyin (diğer diller harici olarak otomatikleştirilmiştir).
  • Anlamsal yerelleştirme anahtarı önekleri kullanın: com_ui_, com_assistants_ vb.
  • Yeni yerelleştirme anahtarları için her zaman anlamlı bir yedek metin sağlayın.

Veri Servisleri

  • client/src/data-provider/[Feature]/queries.ts dosyasında veri sağlayıcı kancaları (hooks) oluşturun.
  • client/src/data-provider/[Feature]/index.ts dosyasındaki tüm hook'ları dışa aktarın.
  • client/src/data-provider/index.ts dosyasına özellik dışa aktarımlarını (feature exports) ekleyin.
  • Tüm API etkileşimleri için React Query (@tanstack/react-query) kullanın.
  • Mutasyonlarda uygun sorgu geçersiz kılma (query invalidation) işlemini uygulayın.
  • packages/data-provider/src/keys.ts dosyasına QueryKeys ve MutationKeys ekleyin.

Paylaşılan API entegrasyonunu eklerken şunları güncelleyin:

  • packages/data-provider/src/api-endpoints.ts (endpoint'ler)
  • packages/data-provider/src/data-service.ts (veri hizmeti işlevleri)
  • packages/data-provider/src/types/queries.ts (TypeScript türleri)

Performans

  • Ölçekte bellek ve hız verimliliğine öncelik verin.
  • Büyük veri kümeleri için uygun imleç (cursor) sayfalama yöntemini uygulayın.
  • Uygun bağımlılık dizileri (dependency arrays) ile gereksiz yeniden oluşturmalardan (re-renders) kaçının.
  • React Query'nin önbelleğe alma ve arka planda yeniden getirme (refetching) özelliklerinden yararlanın.

Test Etme ve Dokümantasyon

  • Jest kullanarak tüm kritik ve karmaşık işlevler için birim testleri yazın.
  • Supertest kullanarak tüm API endpoint'leri için entegrasyon testleri yazın.
  • Playwright kullanarak tüm istemci tarafı işlevleri için uçtan uca testler yazın.
  • Testin amacını net bir şekilde ifade etmek için açıklayıcı test durumu ve fonksiyon isimleri kullanın.
  • Testleri kendi çalışma dizinlerinden çalıştırın: cd api && npx jest <pattern>, cd packages/api && npx jest <pattern> vb.
  • UI/veri akışları için yükleme, başarı ve hata durumlarını kapsayın.
  • Frontend testlerinde bileşenleri render etmek için test/layout-test-utils kullanın.
  • Mock'lar yerine gerçek mantığı tercih edin. Yalnızca harici HTTP API'leri, hız sınırlamalı servisler ve deterministik olmayan sistem çağrıları gibi yerel olarak kontrol edilemeyen durumları mock'layın.
  • Temel uygulamayı değiştirmeden çağrıları doğrulamak (assert) gerektiğinde spy'ları kullanın.
  • Sorguların ve şema doğrulamanın gerçek veritabanı davranışını sergilemesi için MongoDB destekli testlerde mongodb-memory-server kullanın.

Bu rehber nasıl?