mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-30 21:53:28 +08:00
fix: harden unicode safety checks
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
**🌐 Dil / Language / 语言 / 語言**
|
||||
**Dil / Language / 语言 / 語言**
|
||||
|
||||
[**English**](../../README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [**Türkçe**](README.md)
|
||||
|
||||
@@ -105,7 +105,7 @@ Bu repository yalnızca ham kodu içerir. Rehberler her şeyi açıklıyor.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Hızlı Başlangıç
|
||||
## Hızlı Başlangıç
|
||||
|
||||
2 dakikadan kısa sürede başlayın:
|
||||
|
||||
@@ -121,7 +121,7 @@ Bu repository yalnızca ham kodu içerir. Rehberler her şeyi açıklıyor.
|
||||
|
||||
### Adım 2: Rule'ları Kurun (Gerekli)
|
||||
|
||||
> ⚠️ **Önemli:** Claude Code plugin'leri `rule`'ları otomatik olarak dağıtamaz. Manuel olarak kurmalısınız:
|
||||
> WARNING: **Önemli:** Claude Code plugin'leri `rule`'ları otomatik olarak dağıtamaz. Manuel olarak kurmalısınız:
|
||||
|
||||
```bash
|
||||
# Önce repo'yu klonlayın
|
||||
@@ -164,11 +164,11 @@ Manuel kurulum talimatları için `rules/` klasöründeki README'ye bakın.
|
||||
/plugin list everything-claude-code@everything-claude-code
|
||||
```
|
||||
|
||||
✨ **Bu kadar!** Artık 28 agent, 116 skill ve 59 command'a erişiminiz var.
|
||||
**Bu kadar!** Artık 28 agent, 116 skill ve 59 command'a erişiminiz var.
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Çapraz Platform Desteği
|
||||
## Çapraz Platform Desteği
|
||||
|
||||
Bu plugin artık **Windows, macOS ve Linux**'u tam olarak destekliyor, ana IDE'ler (Cursor, OpenCode, Antigravity) ve CLI harness'lar arasında sıkı entegrasyon ile birlikte. Tüm hook'lar ve script'ler maksimum uyumluluk için Node.js ile yeniden yazıldı.
|
||||
|
||||
@@ -215,7 +215,7 @@ export ECC_DISABLED_HOOKS="pre:bash:tmux-reminder,post:edit:typecheck"
|
||||
|
||||
---
|
||||
|
||||
## 📦 İçindekiler
|
||||
## İçindekiler
|
||||
|
||||
Bu repo bir **Claude Code plugin'i** - doğrudan kurun veya component'leri manuel olarak kopyalayın.
|
||||
|
||||
@@ -293,7 +293,7 @@ everything-claude-code/
|
||||
|
||||
---
|
||||
|
||||
## 🗺️ Hangi Agent'ı Kullanmalıyım?
|
||||
## Hangi Agent'ı Kullanmalıyım?
|
||||
|
||||
Nereden başlayacağınızdan emin değil misiniz? Bu hızlı referansı kullanın:
|
||||
|
||||
@@ -337,7 +337,7 @@ Nereden başlayacağınızdan emin değil misiniz? Bu hızlı referansı kullan
|
||||
|
||||
---
|
||||
|
||||
## ❓ SSS
|
||||
## SSS
|
||||
|
||||
<details>
|
||||
<summary><b>Hangi agent/command'ların kurulu olduğunu nasıl kontrol ederim?</b></summary>
|
||||
@@ -410,7 +410,7 @@ Evet. ECC çapraz platformdur:
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testleri Çalıştırma
|
||||
## Testleri Çalıştırma
|
||||
|
||||
Plugin kapsamlı bir test suite içerir:
|
||||
|
||||
@@ -426,7 +426,7 @@ node tests/hooks/hooks.test.js
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Katkıda Bulunma
|
||||
## Katkıda Bulunma
|
||||
|
||||
**Katkılar beklenir ve teşvik edilir.**
|
||||
|
||||
@@ -448,7 +448,7 @@ Lütfen katkıda bulunun! Rehber için [CONTRIBUTING.md](../../CONTRIBUTING.md)'
|
||||
|
||||
---
|
||||
|
||||
## 📄 Lisans
|
||||
## Lisans
|
||||
|
||||
MIT - Özgürce kullanın, ihtiyaç duyduğunuz gibi değiştirin, yapabiliyorsanız geri katkıda bulunun.
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ Oluşturulan artifact'lar:
|
||||
╔══════════════════════════════════════════════════════════════╗
|
||||
║ E2E Test Sonuçları ║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ Durum: ✅ TÜM TESTLER GEÇTİ ║
|
||||
║ Durum: PASS: TÜM TESTLER GEÇTİ ║
|
||||
║ Toplam: 3 test ║
|
||||
║ Geçti: 3 (%100) ║
|
||||
║ Başarısız: 0 ║
|
||||
@@ -191,15 +191,15 @@ Oluşturulan artifact'lar:
|
||||
╚══════════════════════════════════════════════════════════════╝
|
||||
|
||||
Artifact'lar:
|
||||
📸 Ekran Görüntüleri: 2 dosya
|
||||
📹 Videolar: 0 dosya (sadece hatada)
|
||||
🔍 İzlemeler: 0 dosya (sadece hatada)
|
||||
📊 HTML Rapor: playwright-report/index.html
|
||||
Ekran Görüntüleri: 2 dosya
|
||||
Videolar: 0 dosya (sadece hatada)
|
||||
İzlemeler: 0 dosya (sadece hatada)
|
||||
HTML Rapor: playwright-report/index.html
|
||||
|
||||
Raporu görüntüle: npx playwright show-report
|
||||
```
|
||||
|
||||
✅ E2E test paketi CI/CD entegrasyonuna hazır!
|
||||
PASS: E2E test paketi CI/CD entegrasyonuna hazır!
|
||||
```
|
||||
|
||||
## Test Artifact'ları
|
||||
@@ -235,7 +235,7 @@ open artifacts/search-results.png
|
||||
Bir test aralıklı olarak başarısız olursa:
|
||||
|
||||
```
|
||||
⚠️ DENGESİZ TEST TESPİT EDİLDİ: tests/e2e/markets/trade.spec.ts
|
||||
WARNING: DENGESİZ TEST TESPİT EDİLDİ: tests/e2e/markets/trade.spec.ts
|
||||
|
||||
Test 10 çalıştırmadan 7'sinde geçti (%70 geçme oranı)
|
||||
|
||||
@@ -254,10 +254,10 @@ Karantina önerisi: Düzeltilene kadar test.fixme() olarak işaretle
|
||||
## Tarayıcı Yapılandırması
|
||||
|
||||
Testler varsayılan olarak birden fazla tarayıcıda çalışır:
|
||||
- ✅ Chromium (Desktop Chrome)
|
||||
- ✅ Firefox (Desktop)
|
||||
- ✅ WebKit (Desktop Safari)
|
||||
- ✅ Mobile Chrome (opsiyonel)
|
||||
- PASS: Chromium (Desktop Chrome)
|
||||
- PASS: Firefox (Desktop)
|
||||
- PASS: WebKit (Desktop Safari)
|
||||
- PASS: Mobile Chrome (opsiyonel)
|
||||
|
||||
Tarayıcıları ayarlamak için `playwright.config.ts`'yi yapılandırın.
|
||||
|
||||
@@ -285,7 +285,7 @@ CI pipeline'ınıza ekleyin:
|
||||
|
||||
PMX için bu E2E testlerine öncelik verin:
|
||||
|
||||
**🔴 KRİTİK (Her Zaman Geçmeli):**
|
||||
**KRİTİK (Her Zaman Geçmeli):**
|
||||
1. Kullanıcı cüzdan bağlayabilir
|
||||
2. Kullanıcı piyasalara göz atabilir
|
||||
3. Kullanıcı piyasa arayabilir (semantik arama)
|
||||
@@ -294,7 +294,7 @@ PMX için bu E2E testlerine öncelik verin:
|
||||
6. Piyasa doğru çözülür
|
||||
7. Kullanıcı fon çekebilir
|
||||
|
||||
**🟡 ÖNEMLİ:**
|
||||
**ÖNEMLİ:**
|
||||
1. Piyasa oluşturma akışı
|
||||
2. Kullanıcı profil güncellemeleri
|
||||
3. Gerçek zamanlı fiyat güncellemeleri
|
||||
@@ -305,20 +305,20 @@ PMX için bu E2E testlerine öncelik verin:
|
||||
## En İyi Uygulamalar
|
||||
|
||||
**YAPIN:**
|
||||
- ✅ Sürdürülebilirlik için Page Object Model kullanın
|
||||
- ✅ Selector'lar için data-testid nitelikleri kullanın
|
||||
- ✅ Rastgele timeout'lar değil, API yanıtlarını bekleyin
|
||||
- ✅ Kritik kullanıcı yolculuklarını uçtan uca test edin
|
||||
- ✅ Main'e merge etmeden önce testleri çalıştırın
|
||||
- ✅ Testler başarısız olduğunda artifact'ları inceleyin
|
||||
- PASS: Sürdürülebilirlik için Page Object Model kullanın
|
||||
- PASS: Selector'lar için data-testid nitelikleri kullanın
|
||||
- PASS: Rastgele timeout'lar değil, API yanıtlarını bekleyin
|
||||
- PASS: Kritik kullanıcı yolculuklarını uçtan uca test edin
|
||||
- PASS: Main'e merge etmeden önce testleri çalıştırın
|
||||
- PASS: Testler başarısız olduğunda artifact'ları inceleyin
|
||||
|
||||
**YAPMAYIN:**
|
||||
- ❌ Kırılgan selector'lar kullanmayın (CSS sınıfları değişebilir)
|
||||
- ❌ Uygulama detaylarını test etmeyin
|
||||
- ❌ Production'a karşı testler çalıştırmayın
|
||||
- ❌ Dengesiz testleri görmezden gelmeyin
|
||||
- ❌ Başarısızlıklarda artifact incelemesini atlamayın
|
||||
- ❌ Her edge case'i E2E ile test etmeyin (unit testler kullanın)
|
||||
- FAIL: Kırılgan selector'lar kullanmayın (CSS sınıfları değişebilir)
|
||||
- FAIL: Uygulama detaylarını test etmeyin
|
||||
- FAIL: Production'a karşı testler çalıştırmayın
|
||||
- FAIL: Dengesiz testleri görmezden gelmeyin
|
||||
- FAIL: Başarısızlıklarda artifact incelemesini atlamayın
|
||||
- FAIL: Her edge case'i E2E ile test etmeyin (unit testler kullanın)
|
||||
|
||||
## Önemli Notlar
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ ok project/internal/handler 0.023s
|
||||
| Değiştirilen dosyalar | 2 |
|
||||
| Kalan sorunlar | 0 |
|
||||
|
||||
Build Durumu: ✅ BAŞARILI
|
||||
Build Durumu: PASS: BAŞARILI
|
||||
```
|
||||
|
||||
## Düzeltilen Yaygın Hatalar
|
||||
|
||||
@@ -124,16 +124,16 @@ return fmt.Errorf("get user %s: %w", userID, err)
|
||||
- YÜKSEK: 1
|
||||
- ORTA: 0
|
||||
|
||||
Öneri: ❌ KRİTİK sorun düzeltilene kadar merge'i engelle
|
||||
Öneri: FAIL: KRİTİK sorun düzeltilene kadar merge'i engelle
|
||||
```
|
||||
|
||||
## Onay Kriterleri
|
||||
|
||||
| Durum | Koşul |
|
||||
|--------|-----------|
|
||||
| ✅ Onayla | KRİTİK veya YÜKSEK sorun yok |
|
||||
| ⚠️ Uyarı | Sadece ORTA sorunlar (dikkatle merge et) |
|
||||
| ❌ Engelle | KRİTİK veya YÜKSEK sorun bulundu |
|
||||
| PASS: Onayla | KRİTİK veya YÜKSEK sorun yok |
|
||||
| WARNING: Uyarı | Sadece ORTA sorunlar (dikkatle merge et) |
|
||||
| FAIL: Engelle | KRİTİK veya YÜKSEK sorun bulundu |
|
||||
|
||||
## Diğer Komutlarla Entegrasyon
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ Yerel dosya yollarından veya HTTP(S) URL'lerinden içgüdüleri içe aktar.
|
||||
## İçe Aktarma İşlemi
|
||||
|
||||
```
|
||||
📥 Importing instincts from: team-instincts.yaml
|
||||
Importing instincts from: team-instincts.yaml
|
||||
================================================
|
||||
|
||||
Found 12 instincts to import.
|
||||
@@ -60,12 +60,12 @@ These will be added:
|
||||
|
||||
## Duplicate Instincts (3)
|
||||
Already have similar instincts:
|
||||
⚠️ prefer-functional-style
|
||||
WARNING: prefer-functional-style
|
||||
Local: 0.8 confidence, 12 observations
|
||||
Import: 0.7 confidence
|
||||
→ Keep local (higher confidence)
|
||||
|
||||
⚠️ test-first-workflow
|
||||
WARNING: test-first-workflow
|
||||
Local: 0.75 confidence
|
||||
Import: 0.9 confidence
|
||||
→ Update to import (higher confidence)
|
||||
@@ -102,7 +102,7 @@ project_name: "my-project"
|
||||
|
||||
İçe aktarma sonrası:
|
||||
```
|
||||
✅ Import complete!
|
||||
PASS: Import complete!
|
||||
|
||||
Added: 8 instincts
|
||||
Updated: 1 instinct
|
||||
|
||||
@@ -73,7 +73,7 @@ origin: auto-extracted
|
||||
| **[X]'e Ekle** | Mevcut bir skill'e eklenmelidir | Hedef skill'i ve eklemeleri göster → Adım 6 |
|
||||
| **Düşür** | Önemsiz, gereksiz veya çok soyut | Gerekçeyi açıkla ve dur |
|
||||
|
||||
**Yönlendirici boyutlar** (karar verirken, puanlanmaz):
|
||||
**Yönlendirici boyutlar** (karar verirken, puanlanmaz):
|
||||
|
||||
- **Spesifiklik ve Uygulanabilirlik**: Hemen kullanılabilir kod örnekleri veya komutlar içerir
|
||||
- **Kapsam Uyumu**: Ad, tetikleyici koşullar ve içerik hizalanmış ve tek bir desene odaklanmış
|
||||
|
||||
@@ -204,9 +204,9 @@ Her iki analizi sentezle, **Adım Adım Implementation Planı** oluştur:
|
||||
3. **Kalın metinle** prompt çıktıla (MUTLAKA gerçek kaydedilen dosya yolunu kullan):
|
||||
|
||||
---
|
||||
**Plan oluşturuldu ve `.claude/plan/actual-feature-name.md` dosyasına kaydedildi**
|
||||
**Plan oluşturuldu ve `.claude/plan/actual-feature-name.md` dosyasına kaydedildi**
|
||||
|
||||
**Lütfen yukarıdaki planı inceleyin. Şunları yapabilirsiniz:**
|
||||
**Lütfen yukarıdaki planı inceleyin. Şunları yapabilirsiniz:**
|
||||
- **Planı değiştir**: Neyin ayarlanması gerektiğini söyleyin, planı güncelleyeceğim
|
||||
- **Planı çalıştır**: Aşağıdaki komutu yeni bir oturuma kopyalayın
|
||||
|
||||
@@ -215,7 +215,7 @@ Her iki analizi sentezle, **Adım Adım Implementation Planı** oluştur:
|
||||
```
|
||||
---
|
||||
|
||||
**NOT**: Yukarıdaki `actual-feature-name.md` gerçek kaydedilen dosya adıyla değiştirilmelidir!
|
||||
**NOT**: Yukarıdaki `actual-feature-name.md` gerçek kaydedilen dosya adıyla değiştirilmelidir!
|
||||
|
||||
4. **Mevcut yanıtı hemen sonlandır** (Burada dur. Daha fazla tool çağrısı yok.)
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ Silindi: 12 kullanılmayan fonksiyon
|
||||
Atlandı: 2 öğe (testler başarısız)
|
||||
Kazanç: ~450 satır kaldırıldı
|
||||
──────────────────────────────
|
||||
Tüm testler geçiyor ✅
|
||||
Tüm testler geçiyor PASS:
|
||||
```
|
||||
|
||||
## Kurallar
|
||||
|
||||
@@ -133,7 +133,7 @@ FAIL lib/liquidity.test.ts
|
||||
1 test failed, 0 passed
|
||||
```
|
||||
|
||||
✅ Testler beklendiği gibi başarısız. Uygulamaya hazır.
|
||||
PASS: Testler beklendiği gibi başarısız. Uygulamaya hazır.
|
||||
|
||||
## Adım 4: Minimal Kod Uygula (GREEN)
|
||||
|
||||
@@ -179,7 +179,7 @@ PASS lib/liquidity.test.ts
|
||||
3 tests passed
|
||||
```
|
||||
|
||||
✅ Tüm testler geçiyor!
|
||||
PASS: Tüm testler geçiyor!
|
||||
|
||||
## Adım 6: Refactor Et (IYILEŞTIR)
|
||||
|
||||
@@ -236,7 +236,7 @@ PASS lib/liquidity.test.ts
|
||||
3 tests passed
|
||||
```
|
||||
|
||||
✅ Refactoring tamamlandı, testler hala geçiyor!
|
||||
PASS: Refactoring tamamlandı, testler hala geçiyor!
|
||||
|
||||
## Adım 8: Kapsama Oranını Kontrol Et
|
||||
|
||||
@@ -247,29 +247,29 @@ File | % Stmts | % Branch | % Funcs | % Lines
|
||||
---------------|---------|----------|---------|--------
|
||||
liquidity.ts | 100 | 100 | 100 | 100
|
||||
|
||||
Coverage: 100% ✅ (Hedef: 80%)
|
||||
Coverage: 100% PASS: (Hedef: 80%)
|
||||
```
|
||||
|
||||
✅ TDD oturumu tamamlandı!
|
||||
PASS: TDD oturumu tamamlandı!
|
||||
```
|
||||
|
||||
## TDD En İyi Uygulamaları
|
||||
|
||||
**YAPIN:**
|
||||
- ✅ Herhangi bir uygulamadan ÖNCE testi yazın
|
||||
- ✅ Testleri çalıştırın ve uygulamadan önce başarısız olduklarını doğrulayın
|
||||
- ✅ Testleri geçirmek için minimal kod yazın
|
||||
- ✅ Testler yeşil olduktan sonra refactor edin
|
||||
- ✅ Edge case'leri ve hata senaryolarını ekleyin
|
||||
- ✅ %80+ kapsama hedefleyin (kritik kod için %100)
|
||||
- PASS: Herhangi bir uygulamadan ÖNCE testi yazın
|
||||
- PASS: Testleri çalıştırın ve uygulamadan önce başarısız olduklarını doğrulayın
|
||||
- PASS: Testleri geçirmek için minimal kod yazın
|
||||
- PASS: Testler yeşil olduktan sonra refactor edin
|
||||
- PASS: Edge case'leri ve hata senaryolarını ekleyin
|
||||
- PASS: %80+ kapsama hedefleyin (kritik kod için %100)
|
||||
|
||||
**YAPMAYIN:**
|
||||
- ❌ Testlerden önce uygulama yazmayın
|
||||
- ❌ Her değişiklikten sonra testleri çalıştırmayı atlamayın
|
||||
- ❌ Aynı anda çok fazla kod yazmayın
|
||||
- ❌ Başarısız testleri görmezden gelmeyin
|
||||
- ❌ Uygulama detaylarını test etmeyin (davranışı test edin)
|
||||
- ❌ Her şeyi mock'lamayın (integration testleri tercih edin)
|
||||
- FAIL: Testlerden önce uygulama yazmayın
|
||||
- FAIL: Her değişiklikten sonra testleri çalıştırmayı atlamayın
|
||||
- FAIL: Aynı anda çok fazla kod yazmayın
|
||||
- FAIL: Başarısız testleri görmezden gelmeyin
|
||||
- FAIL: Uygulama detaylarını test etmeyin (davranışı test edin)
|
||||
- FAIL: Her şeyi mock'lamayın (integration testleri tercih edin)
|
||||
|
||||
## Dahil Edilecek Test Türleri
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ File Before After
|
||||
src/services/auth.ts 45% 88%
|
||||
src/utils/validation.ts 32% 82%
|
||||
──────────────────────────────
|
||||
Overall: 67% 84% ✅
|
||||
Overall: 67% 84% PASS:
|
||||
```
|
||||
|
||||
## Odak Alanları
|
||||
|
||||
@@ -23,7 +23,7 @@ origin: ECC
|
||||
### RESTful API Yapısı
|
||||
|
||||
```typescript
|
||||
// ✅ Kaynak tabanlı URL'ler
|
||||
// PASS: Kaynak tabanlı URL'ler
|
||||
GET /api/markets # Kaynakları listele
|
||||
GET /api/markets/:id # Tek kaynak getir
|
||||
POST /api/markets # Kaynak oluştur
|
||||
@@ -31,7 +31,7 @@ PUT /api/markets/:id # Kaynağı değiştir (tam)
|
||||
PATCH /api/markets/:id # Kaynağı güncelle (kısmi)
|
||||
DELETE /api/markets/:id # Kaynağı sil
|
||||
|
||||
// ✅ Filtreleme, sıralama, sayfalama için query parametreleri
|
||||
// PASS: Filtreleme, sıralama, sayfalama için query parametreleri
|
||||
GET /api/markets?status=active&sort=volume&limit=20&offset=0
|
||||
```
|
||||
|
||||
@@ -131,7 +131,7 @@ export default withAuth(async (req, res) => {
|
||||
### Sorgu Optimizasyonu
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Sadece gerekli sütunları seç
|
||||
// PASS: İYİ: Sadece gerekli sütunları seç
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status, volume')
|
||||
@@ -139,7 +139,7 @@ const { data } = await supabase
|
||||
.order('volume', { ascending: false })
|
||||
.limit(10)
|
||||
|
||||
// ❌ KÖTÜ: Her şeyi seç
|
||||
// FAIL: KÖTÜ: Her şeyi seç
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
@@ -148,13 +148,13 @@ const { data } = await supabase
|
||||
### N+1 Sorgu Önleme
|
||||
|
||||
```typescript
|
||||
// ❌ KÖTÜ: N+1 sorgu problemi
|
||||
// FAIL: KÖTÜ: N+1 sorgu problemi
|
||||
const markets = await getMarkets()
|
||||
for (const market of markets) {
|
||||
market.creator = await getUser(market.creator_id) // N sorgu
|
||||
}
|
||||
|
||||
// ✅ İYİ: Toplu getirme
|
||||
// PASS: İYİ: Toplu getirme
|
||||
const markets = await getMarkets()
|
||||
const creatorIds = markets.map(m => m.creator_id)
|
||||
const creators = await getUsers(creatorIds) // 1 sorgu
|
||||
|
||||
@@ -48,12 +48,12 @@ Tüm projelerde uygulanabilir evrensel kodlama standartları.
|
||||
### Değişken İsimlendirme
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Açıklayıcı isimler
|
||||
// PASS: İYİ: Açıklayıcı isimler
|
||||
const marketSearchQuery = 'election'
|
||||
const isUserAuthenticated = true
|
||||
const totalRevenue = 1000
|
||||
|
||||
// ❌ KÖTÜ: Belirsiz isimler
|
||||
// FAIL: KÖTÜ: Belirsiz isimler
|
||||
const q = 'election'
|
||||
const flag = true
|
||||
const x = 1000
|
||||
@@ -62,12 +62,12 @@ const x = 1000
|
||||
### Fonksiyon İsimlendirme
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Fiil-isim kalıbı
|
||||
// PASS: İYİ: Fiil-isim kalıbı
|
||||
async function fetchMarketData(marketId: string) { }
|
||||
function calculateSimilarity(a: number[], b: number[]) { }
|
||||
function isValidEmail(email: string): boolean { }
|
||||
|
||||
// ❌ KÖTÜ: Belirsiz veya sadece isim
|
||||
// FAIL: KÖTÜ: Belirsiz veya sadece isim
|
||||
async function market(id: string) { }
|
||||
function similarity(a, b) { }
|
||||
function email(e) { }
|
||||
@@ -76,7 +76,7 @@ function email(e) { }
|
||||
### Değişmezlik Kalıbı (KRİTİK)
|
||||
|
||||
```typescript
|
||||
// ✅ HER ZAMAN spread operatörü kullanın
|
||||
// PASS: HER ZAMAN spread operatörü kullanın
|
||||
const updatedUser = {
|
||||
...user,
|
||||
name: 'New Name'
|
||||
@@ -84,7 +84,7 @@ const updatedUser = {
|
||||
|
||||
const updatedArray = [...items, newItem]
|
||||
|
||||
// ❌ ASLA doğrudan mutasyon yapmayın
|
||||
// FAIL: ASLA doğrudan mutasyon yapmayın
|
||||
user.name = 'New Name' // KÖTÜ
|
||||
items.push(newItem) // KÖTÜ
|
||||
```
|
||||
@@ -92,7 +92,7 @@ items.push(newItem) // KÖTÜ
|
||||
### Hata Yönetimi
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Kapsamlı hata yönetimi
|
||||
// PASS: İYİ: Kapsamlı hata yönetimi
|
||||
async function fetchData(url: string) {
|
||||
try {
|
||||
const response = await fetch(url)
|
||||
@@ -108,7 +108,7 @@ async function fetchData(url: string) {
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ KÖTÜ: Hata yönetimi yok
|
||||
// FAIL: KÖTÜ: Hata yönetimi yok
|
||||
async function fetchData(url) {
|
||||
const response = await fetch(url)
|
||||
return response.json()
|
||||
@@ -118,14 +118,14 @@ async function fetchData(url) {
|
||||
### Async/Await En İyi Uygulamaları
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Mümkün olduğunda paralel yürütme
|
||||
// PASS: İYİ: Mümkün olduğunda paralel yürütme
|
||||
const [users, markets, stats] = await Promise.all([
|
||||
fetchUsers(),
|
||||
fetchMarkets(),
|
||||
fetchStats()
|
||||
])
|
||||
|
||||
// ❌ KÖTÜ: Gereksiz yere sıralı
|
||||
// FAIL: KÖTÜ: Gereksiz yere sıralı
|
||||
const users = await fetchUsers()
|
||||
const markets = await fetchMarkets()
|
||||
const stats = await fetchStats()
|
||||
@@ -134,7 +134,7 @@ const stats = await fetchStats()
|
||||
### Tür Güvenliği
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Doğru tipler
|
||||
// PASS: İYİ: Doğru tipler
|
||||
interface Market {
|
||||
id: string
|
||||
name: string
|
||||
@@ -146,7 +146,7 @@ function getMarket(id: string): Promise<Market> {
|
||||
// Implementation
|
||||
}
|
||||
|
||||
// ❌ KÖTÜ: 'any' kullanımı
|
||||
// FAIL: KÖTÜ: 'any' kullanımı
|
||||
function getMarket(id: any): Promise<any> {
|
||||
// Implementation
|
||||
}
|
||||
@@ -157,7 +157,7 @@ function getMarket(id: any): Promise<any> {
|
||||
### Bileşen Yapısı
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Tiplerle fonksiyonel bileşen
|
||||
// PASS: İYİ: Tiplerle fonksiyonel bileşen
|
||||
interface ButtonProps {
|
||||
children: React.ReactNode
|
||||
onClick: () => void
|
||||
@@ -182,7 +182,7 @@ export function Button({
|
||||
)
|
||||
}
|
||||
|
||||
// ❌ KÖTÜ: Tip yok, belirsiz yapı
|
||||
// FAIL: KÖTÜ: Tip yok, belirsiz yapı
|
||||
export function Button(props) {
|
||||
return <button onClick={props.onClick}>{props.children}</button>
|
||||
}
|
||||
@@ -191,7 +191,7 @@ export function Button(props) {
|
||||
### Özel Hook'lar
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Yeniden kullanılabilir özel hook
|
||||
// PASS: İYİ: Yeniden kullanılabilir özel hook
|
||||
export function useDebounce<T>(value: T, delay: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
||||
|
||||
@@ -213,25 +213,25 @@ const debouncedQuery = useDebounce(searchQuery, 500)
|
||||
### State Yönetimi
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Doğru state güncellemeleri
|
||||
// PASS: İYİ: Doğru state güncellemeleri
|
||||
const [count, setCount] = useState(0)
|
||||
|
||||
// Önceki state'e dayalı fonksiyonel güncelleme
|
||||
setCount(prev => prev + 1)
|
||||
|
||||
// ❌ KÖTÜ: Doğrudan state referansı
|
||||
// FAIL: KÖTÜ: Doğrudan state referansı
|
||||
setCount(count + 1) // Async senaryolarda eski olabilir
|
||||
```
|
||||
|
||||
### Koşullu Render
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Açık koşullu render
|
||||
// PASS: İYİ: Açık koşullu render
|
||||
{isLoading && <Spinner />}
|
||||
{error && <ErrorMessage error={error} />}
|
||||
{data && <DataDisplay data={data} />}
|
||||
|
||||
// ❌ KÖTÜ: Ternary cehennemi
|
||||
// FAIL: KÖTÜ: Ternary cehennemi
|
||||
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}
|
||||
```
|
||||
|
||||
@@ -254,7 +254,7 @@ GET /api/markets?status=active&limit=10&offset=0
|
||||
### Response Formatı
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Tutarlı response yapısı
|
||||
// PASS: İYİ: Tutarlı response yapısı
|
||||
interface ApiResponse<T> {
|
||||
success: boolean
|
||||
data?: T
|
||||
@@ -285,7 +285,7 @@ return NextResponse.json({
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
// ✅ İYİ: Schema doğrulama
|
||||
// PASS: İYİ: Schema doğrulama
|
||||
const CreateMarketSchema = z.object({
|
||||
name: z.string().min(1).max(200),
|
||||
description: z.string().min(1).max(2000),
|
||||
@@ -348,14 +348,14 @@ types/market.types.ts # .types soneki ile camelCase
|
||||
### Ne Zaman Yorum Yapmalı
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: NİÇİN'i açıklayın, NE'yi değil
|
||||
// PASS: İYİ: NİÇİN'i açıklayın, NE'yi değil
|
||||
// Kesintiler sırasında API'yi aşırı yüklemekten kaçınmak için exponential backoff kullan
|
||||
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)
|
||||
|
||||
// Büyük dizilerle performans için burada kasıtlı olarak mutasyon kullanılıyor
|
||||
items.push(newItem)
|
||||
|
||||
// ❌ KÖTÜ: Açık olanı belirtmek
|
||||
// FAIL: KÖTÜ: Açık olanı belirtmek
|
||||
// Sayacı 1 artır
|
||||
count++
|
||||
|
||||
@@ -395,12 +395,12 @@ export async function searchMarkets(
|
||||
```typescript
|
||||
import { useMemo, useCallback } from 'react'
|
||||
|
||||
// ✅ İYİ: Pahalı hesaplamaları memoize et
|
||||
// PASS: İYİ: Pahalı hesaplamaları memoize et
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ İYİ: Callback'leri memoize et
|
||||
// PASS: İYİ: Callback'leri memoize et
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
@@ -411,7 +411,7 @@ const handleSearch = useCallback((query: string) => {
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ İYİ: Ağır bileşenleri lazy yükle
|
||||
// PASS: İYİ: Ağır bileşenleri lazy yükle
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
|
||||
export function Dashboard() {
|
||||
@@ -426,13 +426,13 @@ export function Dashboard() {
|
||||
### Veritabanı Sorguları
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Sadece gerekli sütunları seç
|
||||
// PASS: İYİ: Sadece gerekli sütunları seç
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status')
|
||||
.limit(10)
|
||||
|
||||
// ❌ KÖTÜ: Her şeyi seç
|
||||
// FAIL: KÖTÜ: Her şeyi seç
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
@@ -459,12 +459,12 @@ test('benzerliği doğru hesaplar', () => {
|
||||
### Test İsimlendirme
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Açıklayıcı test isimleri
|
||||
// PASS: İYİ: Açıklayıcı test isimleri
|
||||
test('sorguya uygun market bulunamadığında boş dizi döndürür', () => { })
|
||||
test('OpenAI API anahtarı eksikse hata fırlatır', () => { })
|
||||
test('Redis kullanılamazsa substring aramaya geri döner', () => { })
|
||||
|
||||
// ❌ KÖTÜ: Belirsiz test isimleri
|
||||
// FAIL: KÖTÜ: Belirsiz test isimleri
|
||||
test('çalışır', () => { })
|
||||
test('arama testi', () => { })
|
||||
```
|
||||
@@ -475,12 +475,12 @@ Bu anti-kalıplara dikkat edin:
|
||||
|
||||
### 1. Uzun Fonksiyonlar
|
||||
```typescript
|
||||
// ❌ KÖTÜ: 50 satırdan uzun fonksiyon
|
||||
// FAIL: KÖTÜ: 50 satırdan uzun fonksiyon
|
||||
function processMarketData() {
|
||||
// 100 satır kod
|
||||
}
|
||||
|
||||
// ✅ İYİ: Küçük fonksiyonlara böl
|
||||
// PASS: İYİ: Küçük fonksiyonlara böl
|
||||
function processMarketData() {
|
||||
const validated = validateData()
|
||||
const transformed = transformData(validated)
|
||||
@@ -490,7 +490,7 @@ function processMarketData() {
|
||||
|
||||
### 2. Derin İç İçe Geçme
|
||||
```typescript
|
||||
// ❌ KÖTÜ: 5+ seviye iç içe geçme
|
||||
// FAIL: KÖTÜ: 5+ seviye iç içe geçme
|
||||
if (user) {
|
||||
if (user.isAdmin) {
|
||||
if (market) {
|
||||
@@ -503,7 +503,7 @@ if (user) {
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ İYİ: Erken dönüşler
|
||||
// PASS: İYİ: Erken dönüşler
|
||||
if (!user) return
|
||||
if (!user.isAdmin) return
|
||||
if (!market) return
|
||||
@@ -515,11 +515,11 @@ if (!hasPermission) return
|
||||
|
||||
### 3. Sihirli Sayılar
|
||||
```typescript
|
||||
// ❌ KÖTÜ: Açıklanmamış sayılar
|
||||
// FAIL: KÖTÜ: Açıklanmamış sayılar
|
||||
if (retryCount > 3) { }
|
||||
setTimeout(callback, 500)
|
||||
|
||||
// ✅ İYİ: İsimlendirilmiş sabitler
|
||||
// PASS: İYİ: İsimlendirilmiş sabitler
|
||||
const MAX_RETRIES = 3
|
||||
const DEBOUNCE_DELAY_MS = 500
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ React, Next.js ve performanslı kullanıcı arayüzleri için modern frontend ka
|
||||
### Kalıtım Yerine Composition
|
||||
|
||||
```typescript
|
||||
// ✅ İYİ: Bileşen composition
|
||||
// PASS: İYİ: Bileşen composition
|
||||
interface CardProps {
|
||||
children: React.ReactNode
|
||||
variant?: 'default' | 'outlined'
|
||||
@@ -294,17 +294,17 @@ export function useMarkets() {
|
||||
### Memoization
|
||||
|
||||
```typescript
|
||||
// ✅ Pahalı hesaplamalar için useMemo
|
||||
// PASS: Pahalı hesaplamalar için useMemo
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ Alt bileşenlere geçirilen fonksiyonlar için useCallback
|
||||
// PASS: Alt bileşenlere geçirilen fonksiyonlar için useCallback
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
|
||||
// ✅ Pure bileşenler için React.memo
|
||||
// PASS: Pure bileşenler için React.memo
|
||||
export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
||||
return (
|
||||
<div className="market-card">
|
||||
@@ -320,7 +320,7 @@ export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ Ağır bileşenleri lazy yükle
|
||||
// PASS: Ağır bileşenleri lazy yükle
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
const ThreeJsBackground = lazy(() => import('./ThreeJsBackground'))
|
||||
|
||||
@@ -515,7 +515,7 @@ export class ErrorBoundary extends React.Component<
|
||||
```typescript
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
|
||||
// ✅ Liste animasyonları
|
||||
// PASS: Liste animasyonları
|
||||
export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
@@ -534,7 +534,7 @@ export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ Modal animasyonları
|
||||
// PASS: Modal animasyonları
|
||||
export function Modal({ isOpen, onClose, children }: ModalProps) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
|
||||
@@ -22,13 +22,13 @@ Bu skill tüm kodun güvenlik en iyi uygulamalarını takip etmesini sağlar ve
|
||||
|
||||
### 1. Secret Yönetimi
|
||||
|
||||
#### ❌ ASLA Bunu Yapmayın
|
||||
#### FAIL: ASLA Bunu Yapmayın
|
||||
```typescript
|
||||
const apiKey = "sk-proj-xxxxx" // Hardcoded secret
|
||||
const dbPassword = "password123" // Kaynak kodda
|
||||
```
|
||||
|
||||
#### ✅ HER ZAMAN Bunu Yapın
|
||||
#### PASS: HER ZAMAN Bunu Yapın
|
||||
```typescript
|
||||
const apiKey = process.env.OPENAI_API_KEY
|
||||
const dbUrl = process.env.DATABASE_URL
|
||||
@@ -108,14 +108,14 @@ function validateFileUpload(file: File) {
|
||||
|
||||
### 3. SQL Injection Önleme
|
||||
|
||||
#### ❌ ASLA SQL Concatenation Yapmayın
|
||||
#### FAIL: ASLA SQL Concatenation Yapmayın
|
||||
```typescript
|
||||
// TEHLİKELİ - SQL Injection açığı
|
||||
const query = `SELECT * FROM users WHERE email = '${userEmail}'`
|
||||
await db.query(query)
|
||||
```
|
||||
|
||||
#### ✅ HER ZAMAN Parametreli Sorgular Kullanın
|
||||
#### PASS: HER ZAMAN Parametreli Sorgular Kullanın
|
||||
```typescript
|
||||
// Güvenli - parametreli sorgu
|
||||
const { data } = await supabase
|
||||
@@ -140,10 +140,10 @@ await db.query(
|
||||
|
||||
#### JWT Token İşleme
|
||||
```typescript
|
||||
// ❌ YANLIŞ: localStorage (XSS'e karşı savunmasız)
|
||||
// FAIL: YANLIŞ: localStorage (XSS'e karşı savunmasız)
|
||||
localStorage.setItem('token', token)
|
||||
|
||||
// ✅ DOĞRU: httpOnly cookies
|
||||
// PASS: DOĞRU: httpOnly cookies
|
||||
res.setHeader('Set-Cookie',
|
||||
`token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)
|
||||
```
|
||||
@@ -300,18 +300,18 @@ app.use('/api/search', searchLimiter)
|
||||
|
||||
#### Loglama
|
||||
```typescript
|
||||
// ❌ YANLIŞ: Hassas veri loglama
|
||||
// FAIL: YANLIŞ: Hassas veri loglama
|
||||
console.log('User login:', { email, password })
|
||||
console.log('Payment:', { cardNumber, cvv })
|
||||
|
||||
// ✅ DOĞRU: Hassas veriyi gizle
|
||||
// PASS: DOĞRU: Hassas veriyi gizle
|
||||
console.log('User login:', { email, userId })
|
||||
console.log('Payment:', { last4: card.last4, userId })
|
||||
```
|
||||
|
||||
#### Hata Mesajları
|
||||
```typescript
|
||||
// ❌ YANLIŞ: İç detayları açığa çıkarma
|
||||
// FAIL: YANLIŞ: İç detayları açığa çıkarma
|
||||
catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, stack: error.stack },
|
||||
@@ -319,7 +319,7 @@ catch (error) {
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ DOĞRU: Genel hata mesajları
|
||||
// PASS: DOĞRU: Genel hata mesajları
|
||||
catch (error) {
|
||||
console.error('Internal error:', error)
|
||||
return NextResponse.json(
|
||||
|
||||
@@ -314,39 +314,39 @@ npm run test:coverage
|
||||
|
||||
## Kaçınılması Gereken Yaygın Test Hataları
|
||||
|
||||
### ❌ YANLIŞ: Implementasyon Detaylarını Test Etme
|
||||
### FAIL: YANLIŞ: Implementasyon Detaylarını Test Etme
|
||||
```typescript
|
||||
// İç state'i test etme
|
||||
expect(component.state.count).toBe(5)
|
||||
```
|
||||
|
||||
### ✅ DOĞRU: Kullanıcı Tarafından Görünen Davranışı Test Et
|
||||
### PASS: DOĞRU: Kullanıcı Tarafından Görünen Davranışı Test Et
|
||||
```typescript
|
||||
// Kullanıcıların gördüğünü test et
|
||||
expect(screen.getByText('Sayı: 5')).toBeInTheDocument()
|
||||
```
|
||||
|
||||
### ❌ YANLIŞ: Kırılgan Selector'lar
|
||||
### FAIL: YANLIŞ: Kırılgan Selector'lar
|
||||
```typescript
|
||||
// Kolayca bozulur
|
||||
await page.click('.css-class-xyz')
|
||||
```
|
||||
|
||||
### ✅ DOĞRU: Semantik Selector'lar
|
||||
### PASS: DOĞRU: Semantik Selector'lar
|
||||
```typescript
|
||||
// Değişikliklere karşı dayanıklı
|
||||
await page.click('button:has-text("Gönder")')
|
||||
await page.click('[data-testid="submit-button"]')
|
||||
```
|
||||
|
||||
### ❌ YANLIŞ: Test İzolasyonu Yok
|
||||
### FAIL: YANLIŞ: Test İzolasyonu Yok
|
||||
```typescript
|
||||
// Testler birbirine bağımlı
|
||||
test('kullanıcı oluşturur', () => { /* ... */ })
|
||||
test('aynı kullanıcıyı günceller', () => { /* önceki teste bağımlı */ })
|
||||
```
|
||||
|
||||
### ✅ DOĞRU: Bağımsız Testler
|
||||
### PASS: DOĞRU: Bağımsız Testler
|
||||
```typescript
|
||||
// Her test kendi verisini hazırlar
|
||||
test('kullanıcı oluşturur', () => {
|
||||
|
||||
Reference in New Issue
Block a user