📊 SettingManagement Modülü - Derinlemesine Analiz

📅 Tarih: 2025-11-30 | 🎯 Modül: SettingManagement | 👤 Analiz: Sistem Mimarisi, Form Builder, Veritabanı, Hardcode Sorunları

🏗️ Sistem Mimarisi

Genel Bakış

SettingManagement modülü, multi-tenant sistemde merkezi ayar yönetimi sağlar. 3-katmanlı bir yapıya sahiptir: SettingGroup (gruplar), Setting (ayar tanımları), SettingValue (tenant'a özel değerler).

SettingGroup
(Central DB)
Setting
(Central DB)
SettingValue
(Tenant DB)
3
Veritabanı Tablosu
30+
Form Element Tipi
2
Livewire Component

🗄️ Veritabanı Mimarisi

1. settings_groups (Central DB)

Kolon Tip Açıklama
id bigint Primary key
parent_id bigint (nullable) Alt grup için parent grup ID (hiyerarşik yapı)
name string Grup adı (örn: "Genel Ayarlar")
slug string (unique) URL-friendly isim (otomatik oluşturulur)
prefix string (nullable) Setting key prefix (örn: "ai" → ai_assistant_name)
icon string (nullable) FontAwesome icon (örn: "fas fa-robot")
order integer Sıralama numarası
layout KRİTİK JSON Form yapısını saklar (FormBuilder tarafından oluşturulur)
is_active boolean Grup aktif mi?
💡 ÖNEMLİ: layout kolonu form yapısını JSON formatında saklar. Bu JSON, FormBuilder ile görsel olarak oluşturulur ve ValuesComponent tarafından render edilir.

2. settings (Central DB)

Kolon Tip Açıklama
id bigint Primary key
group_id bigint Hangi gruba ait? (FK: settings_groups)
key string (unique) Ayar anahtarı (örn: "site_logo", "ai_assistant_name")
label string Kullanıcıya gösterilen etiket
type string Element tipi (text, textarea, select, image, vb.)
options JSON (nullable) Select/radio için seçenekler
default_value text (nullable) Varsayılan değer
sort_order integer Sıralama numarası
is_active boolean Ayar aktif mi?
is_system boolean Sistem ayarı mı? (silinemez)
is_required boolean Zorunlu alan mı?
help_text text (nullable) Yardım metni
⚠️ DİKKAT: settings tablosu Central DB'de! Ayar tanımları burada, ayar değerleri her tenant'ın kendi DB'sinde.

3. settings_values (Tenant DB)

Kolon Tip Açıklama
id bigint Primary key
setting_id bigint (unique) Hangi setting? (FK: settings - cross-database)
value text (nullable) Tenant'a özel değer

Değer Öncelik Sistemi

  1. Önce settings_values (Tenant DB) kontrol edilir
  2. Değer yoksa settings.default_value (Central DB) kullanılır
  3. O da yoksa setting($key, $fallback) fonksiyonuna verilen fallback döner

🎨 Form Builder Sistemi

Nasıl Çalışır?

Form Builder, görsel bir arayüz ile form elementlerini sürükle-bırak mantığıyla düzenlemenizi sağlar. Oluşturulan form yapısı JSON formatında settings_groups.layout kolonuna kaydedilir.

Layout JSON Yapısı

{ "title": "Yapay Zeka Asistan Ayarları", "description": "AI asistanınızın kişiliğini özelleştirin", "elements": [ { "type": "heading", "properties": { "content": "🤖 Kişilik ve Kimlik", "size": "h3" } }, { "type": "row", "columns": [ { "width": 6, "elements": [ { "type": "text", "properties": { "label": "AI Asistan İsmi", "name": "ai_assistant_name", "required": true } } ] } ] } ] }

Element Tipleri

📝 Metin Elemanları

  • text - Tek satır metin
  • textarea - Çok satır metin
  • number - Sayı
  • email - E-posta
  • password - Şifre
  • tel - Telefon
  • url - Web adresi

☑️ Seçim Elemanları

  • select - Açılır liste
  • checkbox - Onay kutusu
  • radio - Seçim düğmesi
  • switch - Anahtar (toggle)

📅 Veri Elemanları

  • date - Tarih
  • time - Saat
  • color - Renk seçici
  • range - Değer aralığı

📁 Dosya Elemanları

  • file - Dosya
  • image - Resim
  • favicon - Favicon
  • image_multiple - Çoklu resim

🎨 Düzen Elemanları

  • row - Satır (column sistemi)
  • heading - Başlık
  • paragraph - Paragraf
  • divider - Ayırıcı çizgi
  • spacer - Boşluk
  • card - Kart container
  • tab_group - Sekmeler

🔧 Özel Elemanlar

  • json - JSON editör
  • knowledge_base - AI bilgi bankası

Form Element Eklenme Süreci

1. FormBuilder
Görsel olarak element ekle
2. JSON Oluştur
getFormJSON()
3. saveLayout()
FormBuilderComponent
4. DB Kaydet
layout kolonu
5. Auto-Sync
settings tablosuna ekle

✅ Otomatik Setting Senkronizasyonu

FormBuilder'a element eklendiğinde, syncSettingsFromLayout() metodu otomatik çalışır:

  • Layout JSON'ından tüm form elementleri extract edilir (recursive)
  • Her element için settings tablosunda kayıt oluşturulur/güncellenir
  • Element name → Setting key
  • Element label → Setting label
  • Element type → Setting type
  • Element default_value → Setting default_value

💾 Veritabanı Kayıt Süreci

Yeni Setting Oluşturma (FormBuilder)

// 1. FormBuilder'da element oluştur { "type": "text", "properties": { "name": "ai_assistant_name", "label": "AI Asistan İsmi", "required": true } } // 2. Layout JSON'a kaydet (settings_groups.layout) // 3. syncSettingsFromLayout() otomatik çalışır Setting::create([ 'group_id' => 9, 'key' => 'ai_assistant_name', 'label' => 'AI Asistan İsmi', 'type' => 'text', 'is_required' => true ]);

Değer Kaydetme (ValuesComponent)

// Kullanıcı formda değer girer values['ai_assistant_name'] = "iXtif AI Asistanı" // save() metodu çağrılır SettingValue::updateOrCreate( ['setting_id' => 123], // AI Asistan İsmi'nin ID'si ['value' => 'iXtif AI Asistanı'] ); // Tenant DB'ye kaydedilir // settings_values tablosuna INSERT

Değer Okuma (Helper)

// 1. setting() helper kullan setting('ai_assistant_name') // 2. Cache kontrol (3600 saniye) Cache::remember('tenant_2_setting_key_ai_assistant_name', ...) // 3. Setting model'i bul (Central DB) Setting::where('key', 'ai_assistant_name')->first() // 4. getValue() metodu çalışır // - Önce SettingValue kontrol (Tenant DB) // - Yoksa default_value döner // 5. Sonuç: "iXtif AI Asistanı"

🚨 Hardcode Sorunları ve Tespit Edilen Problemler

1. Seeder Dosyalarında Hardcode Ayarlar

Sorun: Ayarlar Seeder dosyalarına hardcode edilmiş!

Tespit Edilen Dosyalar:

  • SettingsTableSeeder.php - Site ayarları hardcode
  • AISettingsSeeder.php - AI ayarları hardcode + layout JSON
  • ThemeSettingsSeeder.php - Tema renkleri hardcode + layout JSON

Örnek Hardcode:

// AISettingsSeeder.php settings = [ [ 'group_id' => 9, 'label' => 'AI Asistan İsmi', 'key' => 'ai_assistant_name', 'type' => 'text', 'default_value' => '', 'is_required' => true, ], // ... 30+ ayar daha! ]

Neden Sorun?

  • ❌ Yeni ayar eklemek için kod değişikliği gerekiyor
  • ❌ Değişiklikler production'a migration ile gitmeli
  • ❌ FormBuilder'dan eklenen ayarlar seeder'da yok
  • ❌ Layout JSON da seeder içinde (300+ satır kod!)

2. Layout JSON Hardcode

Sorun: Form layout'ları PHP koduna hardcode edilmiş!

Örnek:

// ThemeSettingsSeeder.php private function getThemeSettingsLayout(): string { layout = [ 'title' => 'Tema Ayarları Formu', 'elements' => [ [ 'type' => 'heading', 'properties' => [ 'content' => 'Temel Renkler', 'size' => 'h3' ] ], // ... 200+ satır JSON array ] ]; return json_encode(layout); }

Neden Sorun?

  • ❌ Form yapısını değiştirmek için kod değişikliği gerekiyor
  • ❌ FormBuilder'dan düzenleme yapınca seeder'daki JSON eski kalıyor
  • ❌ Layout JSON code içinde 200-300 satır yer kaplıyor
  • ❌ Seed her çalıştığında DB'deki layout override ediliyor!

3. Group ID Hardcode

Sorun: Group ID'leri sabit kodlanmış!

// AISettingsSeeder.php groupId = 9; // Hardcode! DB::table('settings_groups')->updateOrInsert( ['id' => 9], // ❌ Sabit ID [ 'name' => 'Yapay Zeka', 'parent_id' => 1, // ❌ Parent da sabit ] );

Neden Sorun?

  • ❌ Farklı tenant'larda ID충돌돌 riski
  • ❌ Auto-increment mekanizması bozulabilir
  • ❌ Yeni grup eklerken ID çakışması olabilir

4. Select Options Hardcode

Sorun: Dropdown seçenekleri kodda tanımlı!

// AISettingsSeeder.php 'options' => json_encode([ '' => '-- Seçim Yapın --', 'sales_expert' => 'Satış Uzmanı', 'technical_consultant' => 'Teknik Danışman', 'friendly_assistant' => 'Samimi Asistan', 'professional_consultant' => 'Profesyonel Danışman', 'hybrid' => 'Karma ⭐ Önerilen', ])

Neden Sorun?

  • ❌ Yeni seçenek eklemek için kod değişikliği gerekiyor
  • ❌ FormBuilder'dan option eklenemiyor
  • ❌ Çeviri (i18n) desteği yok

✅ Çözüm Önerileri ve Hedef Mimari

Hedef: %100 Database-Driven Sistem

Tüm ayarlar, form yapıları, layout'lar ve seçenekler sadece veritabanında olmalı. Hiçbir hardcode kod olmamalı. FormBuilder ile her şey yönetilebilmeli.

1. Seeder Dosyalarını Kaldırma Stratejisi

Adım 1: Mevcut Ayarları DB'ye Aktar

Seeder dosyalarındaki tüm ayarları FormBuilder ile manuel olarak DB'ye kaydet:

  • ✅ Her ayar grubu için FormBuilder aç
  • ✅ Seeder'daki layout JSON'ını FormBuilder'a import et
  • ✅ Kaydet → Otomatik olarak settings tablosuna eklenecek
  • ✅ Seeder dosyasını sil veya devre dışı bırak

Adım 2: Seeder Yerine Migration Kullan

İlk kurulum için migration kullan, sonraki değişiklikler FormBuilder ile:

  • ✅ Migration: Sadece SettingGroup oluştur (isim, slug, icon)
  • ✅ Layout JSON: Boş bırak (null)
  • ✅ Admin panelde FormBuilder ile layout oluştur
  • ✅ Setting kayıtları otomatik oluşturulsun

2. Select Options için Çözüm

Yaklaşım A: JSON Array (Mevcut Sistem)

// settings.options kolonu { "sales_expert": "Satış Uzmanı", "technical_consultant": "Teknik Danışman", "friendly_assistant": "Samimi Asistan" }
  • ✅ Basit ve hızlı
  • ✅ FormBuilder'dan eklenebilir
  • ❌ Çeviri (i18n) desteği yok

Yaklaşım B: Ayrı Options Tablosu

// Yeni tablo: setting_options - id - setting_id (FK: settings) - option_key (örn: sales_expert) - option_label (örn: Satış Uzmanı) - order
  • ✅ Dinamik option yönetimi
  • ✅ Çeviri desteği eklenebilir
  • ✅ Option başına ek metadata eklenebilir
  • ❌ Daha karmaşık yapı

3. Layout JSON Yönetimi

Mevcut Sistem Yeterli!

settings_groups.layout kolonu zaten JSON formatında form yapısını saklıyor. Sorun layout'ın kendisinde değil, seeder dosyalarında hardcode edilmesinde!

Yapılacak:

  • ✅ Seeder'daki getThemeSettingsLayout() gibi metodları kaldır
  • ✅ Layout JSON'ları FormBuilder ile oluştur
  • ✅ DB'de saklanan layout'ları kullan
  • ✅ Seed'de layout = null olsun (admin panelde manuel oluşturulsun)

4. Group ID Yönetimi

Çözüm: Auto-Increment + Slug Kullan

// ❌ YANLIŞ DB::table('settings_groups')->updateOrInsert( ['id' => 9], // Hardcode ID [...] ); // ✅ DOĞRU DB::table('settings_groups')->updateOrInsert( ['slug' => 'yapay-zeka'], // Unique slug kullan [ 'name' => 'Yapay Zeka', 'parent_id' => DB::table('settings_groups') ->where('slug', 'genel-sistem') ->value('id') // Parent'ı slug ile bul ] );

5. FormBuilder Property Panel Geliştirme

Select Element için Options Ekleyebilme

FormBuilder'ın sağ panel'inde select element seçildiğinde:

  • ✅ "Options" sekmesi ekle
  • ✅ Key-Value pair ekleme arayüzü
  • ✅ Sürükle-bırak ile sıralama
  • ✅ Kaydet düğmesi ile settings.options JSON'a kaydet

📋 Aksiyon Planı (Adım Adım)

Faz 1: Mevcut Durumu Temizleme

  1. Seeder Kontrolü
    • Hangi seeder'lar layout JSON içeriyor? → Tespit et
    • Hangi ayarlar hardcode? → Liste çıkar
  2. DB Export
    • Mevcut settings_groups tablosunu export et
    • Mevcut settings tablosunu export et
    • Layout JSON'larını ayrı dosyalara kaydet (backup)
  3. Seeder Cleanup
    • Tüm seeder dosyalarından layout JSON'larını kaldır
    • Setting array'lerini kaldır
    • Sadece SettingGroup tanımları kalsın (isim, slug, icon)

Faz 2: FormBuilder ile Yeniden Oluşturma

  1. Her Grup için:
    • Admin panel → SettingManagement → Form Builder aç
    • Eski layout JSON'ı import et (gerekirse manuel ekle)
    • Kaydet → Otomatik olarak settings tablosuna eklenecek
  2. Test Et:
    • Values sayfasını aç
    • Tüm alanların göründüğünü doğrula
    • Kaydetmeyi test et

Faz 3: Select Options Yönetimi

  1. FormBuilder Geliştirme:
    • Properties panel'e "Options" tab ekle
    • Key-Value input alanları ekle
    • Add/Remove button'ları ekle
    • Kaydetme işlemini güncelle
  2. Mevcut Options'ları Aktar:
    • Seeder'dan options JSON'larını DB'ye kopyala
    • FormBuilder ile düzenlenebilir yap

Faz 4: Migration Düzenleme

  1. İlk Kurulum Migration:
    • Sadece SettingGroup kayıtları oluştur
    • Layout = null bırak
    • Admin panelde manuel FormBuilder ile oluşturulsun
  2. Production Migration:
    • Mevcut layout JSON'ları DB'den al
    • Migration'da layout'ları ekle (tek seferlik)
    • Sonrasında tüm değişiklikler FormBuilder ile

Faz 5: Doğrulama ve Dokümantasyon

  1. Test Senaryoları:
    • ✅ FormBuilder ile yeni grup oluşturma
    • ✅ Form element ekleme/çıkarma
    • ✅ Select options ekleme
    • ✅ Layout değiştirme
    • ✅ Values sayfasında kaydetme
    • ✅ setting() helper ile okuma
  2. Dokümantasyon:
    • Yeni setting grubu oluşturma kılavuzu
    • FormBuilder kullanım kılavuzu
    • Seeder yerine FormBuilder kullanma

⚠️ Kritik Notlar

🚨 SEED OVERWRITE RİSKİ
Seeder dosyaları her çalıştığında DB'deki layout JSON'ı override ediyor! Admin panelde FormBuilder ile yaptığınız değişiklikler seed sonrası kaybolabilir.

Çözüm: Seeder dosyalarını tamamen kaldır veya sadece ilk kurulumda çalışsın.

⚠️ MULTI-TENANT DİKKAT
- settings_groups ve settings → Central DB
- settings_values → Tenant DB
- Yeni grup/ayar eklerken tüm tenant'lar otomatik görür
- Değerler tenant'a özgü
💡 CACHE YÖNETİMİ
- setting() helper 3600 saniye (1 saat) cache kullanıyor
- SettingValue model save/delete olunca cache otomatik temizleniyor
- Manuel temizlik: setting_clear_cache()

📊 Özet ve Sonuç

Mevcut Durum

  • ✅ Form Builder sistemi güçlü ve çalışıyor
  • ✅ Layout JSON yapısı esnek
  • ✅ Otomatik setting senkronizasyonu var
  • ❌ Seeder dosyalarında 1000+ satır hardcode kod
  • ❌ Layout JSON'lar PHP kodunda
  • ❌ Select options hardcode
  • ❌ Group ID'ler sabit

Hedef Durum

  • ✅ %100 database-driven sistem
  • ✅ Tüm ayarlar FormBuilder ile yönetilsin
  • ✅ Hiç hardcode kod kalmasın
  • ✅ Select options FormBuilder'dan eklenebilsin
  • ✅ Layout JSON sadece DB'de olsun
  • ✅ Seeder dosyaları minimal olsun (sadece grup tanımları)

Tahmini Süre

2-3
Gün - Seeder Cleanup
3-4
Gün - FormBuilder Geliştirme
1-2
Gün - Migration Düzenleme
1
Gün - Test & Dokümantasyon

Toplam: 7-10 gün