# Citrus Platform - Cursor Rules

## Proje Genel Kuralları

### Dil ve Lokalizasyon
- Tüm metinler Laravel Localization kullanmalı
- Türkçe ve İngilizce dil desteği zorunlu
- Dil dosyaları `lang/tr/` ve `lang/en/` klasörlerinde
- Çeviri anahtarları kebab-case formatında: `module_name.key_name`
- Blade template'lerde `{{ __('module.key') }}` kullan
- Controller'larda `__('module.key')` kullan

### Modül Yapısı
- Her modül için aşağıdaki yapıyı takip et:
```
app/Filament/Admin/Resources/ModuleName/
├── ModuleNameResource.php
├── Pages/
│   ├── ListModuleName.php
│   ├── CreateModuleName.php
│   └── EditModuleName.php
├── Schemas/
│   └── ModuleNameForm.php
└── Tables/
    └── ModuleNameTable.php
```

### Filament Resource Oluşturma
- Yeni modül oluştururken Filament'in kendi komutunu kullan:
```bash
php artisan make:filament-resource ModelName --generate --model --migration --factory
```
- Bu komut otomatik olarak tüm gerekli dosyaları oluşturur
- Manuel dosya oluşturma yerine bu komutu tercih et
- Komut çalıştırıldıktan sonra model ve migration'ları ihtiyaca göre düzenle

### Resource Sınıfı Kuralları
- `getNavigationLabel()`, `getModelLabel()`, `getPluralModelLabel()` metodlarını implement et
- Tüm metinler için localization kullan
- Navigation icon için Heroicon kullan

### Page Sınıfları Kuralları
- `getTitle()` metodunu implement et ve localization kullan
- Action butonları için `->label(__('module.action_name'))` kullan
- Notification mesajları için localization kullan
- `getRedirectUrl()` metodunu implement et

### Form ve Table Kuralları
- Form field'ları için label'ları localization'dan al
- Table column'ları için header'ları localization'dan al
- Validation mesajları için localization kullan

### Filament 4.x Import Kuralları (ÖNEMLİ!)

#### **Table Actions (DOĞRU):**
```php
// Table Actions için
use Filament\Actions\EditAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\RestoreAction;
use Filament\Actions\ForceDeleteAction;

// Bulk Actions için
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\RestoreBulkAction;

// Filters için
use Filament\Tables\Filters\TrashedFilter;
use Filament\Tables\Filters\SelectFilter;

// Columns için
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\ImageColumn;

// Table metodları
$table
    ->recordActions([      // ✅ Doğru
        EditAction::make(),
    ])
    ->toolbarActions([     // ✅ Doğru
        BulkActionGroup::make([
            DeleteBulkAction::make(),
        ]),
    ]);

// Utilities (Schema içinde kullanım)
use Filament\Schemas\Components\Utilities\Get;  // ✅ Doğru - Form state okuma
use Filament\Schemas\Components\Utilities\Set;  // ✅ Doğru - Form state yazma
```

#### **Form & Schema Components (DOĞRU):**
```php
// Form input components
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\FileUpload;

// Layout components (ÖNEMLİ: Schemas namespace!)
use Filament\Schemas\Components\Section;   // ✅ Doğru
use Filament\Schemas\Components\Grid;      // ✅ Doğru
use Filament\Schemas\Components\Fieldset;  // ✅ Doğru
use Filament\Schemas\Components\Flex;      // ✅ Doğru
use Filament\Schemas\Components\Group;     // ✅ Doğru - Schema içinde gruplamak için
use Filament\Schemas\Components\View;      // ✅ Doğru - Blade view component

// Tabs components (ÖNEMLİ: Schemas namespace!)
use Filament\Schemas\Components\Tabs;      // ✅ Doğru
use Filament\Schemas\Components\Tabs\Tab;  // ✅ Doğru
// FORM/INFOLIST içindeki tab'lar için yukarıdaki import'ları kullan

// Wizard component (Schemas namespace!)
use Filament\Schemas\Components\Wizard;
use Filament\Schemas\Components\Wizard\Step;

// Infolist entry components
use Filament\Infolists\Components\TextEntry;
use Filament\Infolists\Components\IconEntry;
use Filament\Infolists\Components\ImageEntry;
```
Get $get('data') şeklinde kullanma sakın bu sonsuz döngüye sebep olur. Aşağıdaki kullanımlar yanlış onun yerine
```php
$existingData = $get('data') ?? [];
```
```php
$existingData = $get('data') ?? [];
```
```php
$existingData = $get('data') ?? [];

```
onun yerineşu şekilde kullanılır.
```php
$existingData = $state?->section_data ?? []; 
```


#### **Filament 4.x TAB KULLANIM KURALLARI (KRİTİK!):**

Filament 4.x'te **iki farklı Tab sistemi** vardır:

**1. Resource List Pages Tabs (getTabs() metodu):**
```php
// ❌ YANLIŞ - Bu class Filament 4.x'te YOK!
use Filament\Resources\Components\Tab;

// ✅ DOĞRU - ListRecords page'lerinde getTabs() için
use Filament\Schemas\Components\Tabs\Tab;

// Örnek kullanım:
class ListSettings extends ListRecords
{
    public function getTabs(): array
    {
        return [
            'all' => Tab::make('Tümü')
                ->icon('heroicon-o-squares-2x2')
                ->badge(100)
                ->modifyQueryUsing(fn (Builder $query) => $query),
            
            'active' => Tab::make('Aktif')
                ->icon('heroicon-o-check')
                ->badge(50)
                ->modifyQueryUsing(fn (Builder $query) => $query->where('is_active', true)),
        ];
    }
}
```

**2. Form/Schema Tabs (Form içinde kullanım):**
```php
// ✅ DOĞRU - Form/Schema içinde tabs için
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;

// Örnek kullanım:
public static function form(Schema $schema): Schema
{
    return $schema
        ->components([
            Tabs::make('Tabs')
                ->tabs([
                    Tab::make('Genel Bilgiler')
                        ->icon('heroicon-o-information-circle')
                        ->schema([
                            TextInput::make('name'),
                            // ...
                        ]),
                    Tab::make('SEO')
                        ->icon('heroicon-o-magnifying-glass')
                        ->schema([
                            TextInput::make('meta_title'),
                            // ...
                        ]),
                ])
                ->columnSpanFull()
                ->persistTabInQueryString(),
        ]);
}
```

#### **YANLIŞ KULLANIM (Eski Filament 3.x):**
```php
// ❌ YANLIŞ - Bu namespace'ler Filament 4'te YOK!
use Filament\Tables\Actions\EditAction;      // ❌
use Filament\Forms\Components\Section;       // ❌
use Filament\Forms\Components\Grid;          // ❌
use Filament\Forms\Components\Group;         // ❌ Forms namespace altında Group YOK
use Filament\Forms\Components\Tabs;          // ❌ Forms namespace altında Tabs YOK
use Filament\Resources\Components\Tab;       // ❌ Bu class hiç YOK
use Filament\Forms\Get;                       // ❌ Bu namespace YOK
use Filament\Forms\Set;                       // ❌ Bu namespace YOK

// ❌ YANLIŞ - Eski metod adları
$table
    ->actions([...])      // ❌ Kullanma!
    ->bulkActions([...])  // ❌ Kullanma!
```

#### **ÖZET (Filament 4.x Import Referansı):**
- ✅ **Table Actions:** `Filament\Actions\` namespace
- ✅ **Table Columns:** `Filament\Tables\Columns\` namespace
- ✅ **Table Filters:** `Filament\Tables\Filters\` namespace
- ✅ **Form Inputs:** `Filament\Forms\Components\` namespace
- ✅ **Layout Components:** `Filament\Schemas\Components\` namespace
  - Section, Grid, Fieldset, Flex, Group, Tabs, View vb.
- ✅ **Tabs (Tüm Kullanımlar):** `Filament\Schemas\Components\Tabs\Tab` (Her yerde bu!)
- ✅ **Utilities:** `Filament\Schemas\Components\Utilities\` namespace
  - Get, Set (Schema içinde form state okuma/yazma)
- ✅ **Infolist Entries:** `Filament\Infolists\Components\` namespace
- ✅ **Table Methods:** `->recordActions()` ve `->toolbarActions()`

**Kritik Notlar:**
- `Filament\Resources\Components\Tab` diye bir class **YOK**. Tüm tab kullanımları `Filament\Schemas\Components\Tabs\Tab` ile yapılır!
- `Filament\Forms\Components\Group` diye bir class **YOK**. Schema içinde gruplamak için `Filament\Schemas\Components\Group` kullan!
- `Filament\Forms\Get` ve `Filament\Forms\Set` diye class'lar **YOK**. `Filament\Schemas\Components\Utilities\Get` ve `Filament\Schemas\Components\Utilities\Set` kullan!

#### **Filament 4.x VIEW COMPONENT KULLANIM KURALLARI (KRİTİK!):**

View component'ine veri iletmek için **sadece `viewData()` metodu** kullanılır:

```php
use Filament\Schemas\Components\View;

// ✅ DOĞRU - viewData() ile veri gönder
View::make('components.template-preview')
    ->viewData([
        'type' => 'header',
        'fieldName' => 'html_content',
    ])
    ->columnSpanFull();

// ❌ YANLIŞ - with() metodu ÇALIŞMAZ!
View::make('components.template-preview')
    ->with([...])  // ❌ Bu metod View component'inde YOK!

// ❌ YANLIŞ - extraAttributes() sadece HTML attribute'leri için
View::make('components.template-preview')
    ->extraAttributes([
        'data-type' => 'header',  // ❌ Bu view'e değişken olarak GİTMEZ!
    ])
```

**Özet:**
- ✅ `->viewData([...])` → Blade view'e değişken gönderir
- ❌ `->with([...])` → View component'inde bu metod YOK
- ❌ `->extraAttributes([...])` → Sadece HTML attribute'leri için, view değişkenleri için DEĞİL

#### **Filament 4.x REPEATER KULLANIM KURALLARI (KRİTİK!):**

Repeater component'ı JSON array formatında tekrarlanan form component'leri oluşturmak için kullanılır.

**Temel Kullanım:**
```php
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;

Repeater::make('members')
    ->schema([
        TextInput::make('name')->required(),
        Select::make('role')
            ->options([
                'member' => 'Member',
                'administrator' => 'Administrator',
            ])
            ->required(),
    ])
    ->defaultItems(0)
    ->addActionLabel('Add Member')
    ->reorderable()
    ->collapsible()
    ->itemLabel(fn (array $state): ?string => $state['name'] ?? null)
```

**Simple Repeater (Tek Field için):**
```php
// ✅ DOĞRU - Filament 4.x'te simple() metodu parametre alır
Repeater::make('tags')
    ->simple(
        TextInput::make('tag')
            ->label('Tag')
            ->required()
    )

// ❌ YANLIŞ - Bu kullanım HATA VERİR
Repeater::make('tags')
    ->schema([
        TextInput::make('tag')->required(),
    ])
    ->simple()  // ❌ Parametre gerekli!
```

**Nested Repeater ile Dikkat Edilmesi Gerekenler:**

1. **Aynı İsimli Field'lar Çakışır:**
```php
// ❌ YANLIŞ - Bu HATA VERİR (FileUpload array beklerken string alır)
Repeater::make('data')
    ->schema([
        TextInput::make('value'),      // İlk value
        FileUpload::make('value'),     // İkinci value - ÇAKIŞMA!
        Textarea::make('value'),       // Üçüncü value - ÇAKIŞMA!
    ])

// ✅ DOĞRU - dehydrated() ile sadece görünür olan kaydedilir
Repeater::make('data')
    ->schema([
        TextInput::make('value')
            ->visible(fn ($get) => $get('type') === 'text')
            ->dehydrated(fn ($get) => $get('type') === 'text'),
        
        FileUpload::make('value')
            ->visible(fn ($get) => $get('type') === 'image')
            ->dehydrated(fn ($get) => $get('type') === 'image'),
        
        Textarea::make('value')
            ->visible(fn ($get) => $get('type') === 'textarea')
            ->dehydrated(fn ($get) => $get('type') === 'textarea'),
    ])
```

2. **Conditional Field'lar:**
```php
// Sadece görünür olan field dehydrate edilir
Select::make('type')
    ->options([...])
    ->live(), // Değişikliği dinlemek için

TextInput::make('value')
    ->visible(fn (Get $get) => $get('type') === 'text')
    ->dehydrated(fn (Get $get) => $get('type') === 'text'),
```

3. **Item Labels:**
```php
// Item'lara dinamik label ekle
Repeater::make('sections')
    ->schema([...])
    ->itemLabel(fn (array $state): ?string => 
        isset($state['type']) 
            ? __('pages.section_type_' . $state['type']) 
            : 'Item'
    )
```

4. **Repeater Özellikleri:**
```php
Repeater::make('items')
    ->schema([...])
    ->defaultItems(0)           // Başlangıç item sayısı
    ->addActionLabel('Add')     // Ekleme butonu label'ı
    ->reorderable()             // Sürükle-bırak ile sıralama
    ->collapsible()             // Açılıp kapanabilir
    ->collapsed()               // Başlangıçta kapalı
    ->cloneable()               // Kopyalama butonu
    ->deletable()               // Silme butonu
    ->minItems(1)               // Minimum item sayısı
    ->maxItems(10)              // Maximum item sayısı
```

**Referans:** [Filament Repeater Docs](https://filamentphp.com/docs/4.x/forms/repeater)

### Dil Dosyası Yapısı
<?php

return [
    'title' => 'Modül Başlığı',
    'navigation_label' => 'Navigasyon Etiketi',
    'model_label' => 'Tekil Model Etiketi',
    'plural_model_label' => 'Çoğul Model Etiketi',
    
    // Actions
    'create' => 'Oluştur',
    'edit' => 'Düzenle',
    'delete' => 'Sil',
    'restore' => 'Geri Yükle',
    'force_delete' => 'Kalıcı Olarak Sil',
    
    // Form fields
    'field_name' => 'Alan Etiketi',
    
    // Messages
    'created_successfully' => 'Başarıyla oluşturuldu.',
    'updated_successfully' => 'Başarıyla güncellendi.',
    'deleted_successfully' => 'Başarıyla silindi.',
    
    // Table columns
    'table_column_name' => 'Sütun Başlığı',
    
    // Validation messages
    'field_required' => 'Bu alan zorunludur.',
    'field_unique' => 'Bu değer zaten kullanılıyor.',
];


### Model Kuralları
- `$fillable` array'ini tanımla
- `$casts` array'ini kullan
- Soft delete için `SoftDeletes` trait'ini kullan
- `$dates` array'ini kullan

### Migration Kuralları
- Tablo adları çoğul olmalı
- Column adları snake_case
- Foreign key'ler için `_id` suffix'i kullan
- Timestamps için `created_at` ve `updated_at` kullan
- Soft delete için `deleted_at` kullan
- Mevcut tablolar için migration oluştururken `if (!Schema::hasTable())` kontrolü kullanma
- Soft delete hatası alındığında `deleted_at` sütununu ekleyen ayrı migration oluştur

### Test Kuralları
- Her modül için test dosyaları oluştur
- Feature test'leri yaz
- Unit test'leri yaz
- Localization test'leri yaz

### Kod Stili
- PSR-12 standartlarına uy
- Type hinting kullan
- Return type'ları belirt
- DocBlock'ları yaz
- Kısa ve açıklayıcı metod isimleri kullan

### Güvenlik
- CSRF koruması aktif
- Validation kuralları uygula
- Authorization kontrolü yap
- SQL injection koruması
- XSS koruması

### Performans
- Eager loading kullan
- Database index'leri ekle
- Cache kullan
- Query optimization yap

## Pages Modülü Örnek Yapısı

Pages modülü bu kuralların uygulandığı örnek modüldür. Yeni modül oluştururken bu yapıyı referans al.

### Dosya Yapısı
- `PageResource.php` - Ana resource sınıfı
- `Pages/ListPages.php` - Liste sayfası
- `Pages/CreatePage.php` - Oluşturma sayfası  
- `Pages/EditPage.php` - Düzenleme sayfası
- `Schemas/PageForm.php` - Form şeması
- `Tables/PagesTable.php` - Tablo şeması
- `lang/tr/pages.php` - Türkçe çeviriler
- `lang/en/pages.php` - İngilizce çeviriler

### Özellikler
- ✅ Localization desteği
- ✅ Soft delete
- ✅ Form validation
- ✅ Table filtering
- ✅ Action buttons
- ✅ Notifications
- ✅ Redirect handling

## Universal Translation System

### Translation System Kullanımı
Platform, dinamik ve evrensel bir çeviri sistemi içerir. Herhangi bir modele çeviri desteği eklemek için:

```php
use App\Traits\HasTranslations;

class YourModel extends Model
{
    use HasTranslations;
    
    protected $translatable = [
        'title',
        'content',
        'description',
        'meta_title',
        'meta_description',
    ];
}
```

### Translation Kuralları
- ✅ Çevrilecek alanlar `$translatable` array'inde tanımlanmalı
- ✅ `HasTranslations` trait'i kullanılmalı
- ✅ Trait'te `$translatable` property tanımlama (conflict oluşur)
- ✅ Her model kendi `$translatable` array'ini tanımlar
- ✅ Slug, ID, FK gibi alanlar çevrilmemeli

### Translation Metodları
```php
// Çeviri kaydet
$model->setTranslation('field_name', 'en', 'Translation', 'published');

// Çeviri oku
$model->translate('field_name'); // Mevcut dilde
$model->translate('field_name', 'en'); // Belirli dilde
$model->translate('field_name', 'en', false); // Fallback olmadan

// Çeviri kontrolü
$model->hasTranslation('field_name', 'en');

// İlerleme takibi
$model->getTranslationProgress(); // ['tr' => 100, 'en' => 75]
$model->getMissingTranslations('en'); // ['meta_description']
```

### Translation Workflow
- `draft` → `review` → `approved` → `published`
- Sadece `published` çeviriler son kullanıcıya görünür
- User-language permissions ile kontrol edilir

### Helper Functions
```php
current_language(); // Mevcut dil objesi
available_languages(); // Aktif diller
translate_model($model, 'field', 'en'); // Model çevirisi
user_can_manage_language('en'); // Kullanıcı yetkisi
switch_language('en'); // Dil değiştir
```

### Dokümantasyon
- `docs/TRANSLATION_SYSTEM.md` - Tam sistem dokümantasyonu
- `docs/TRANSLATION_QUICK_START.md` - Hızlı başlangıç rehberi
