Dosya:
Modules/TenantManagement/app/Http/Livewire/TenantComponent.php
Satır: 629-670
→
prepareTenantDirectories()
❌ Sorun:
Yeni tenant oluşturulurken Laravel File::ensureDirectoryExists() kullanıyor.
Bu fonksiyon PHP-FPM user'ı (root veya www-data) ile çalıştığında klasörleri root:root owner ile oluşturur.
Nginx/Apache'nin tuufi.com_:psaserv user'ı bu dosyalara erişemez → 403 Forbidden veya 500 Internal Server Error
✅ Çözüm:
Klasör oluşturulduktan HEMEN SONRA owner ve permission düzelt:
// TenantComponent::prepareTenantDirectories() içinde
$tenantPath = storage_path("tenant{$tenantId}");
File::ensureDirectoryExists($tenantPath, 0775, true);
// ✅ ZORUNLU: Owner düzelt!
exec("sudo chown -R tuufi.com_:psaserv {$tenantPath}");
exec("sudo find {$tenantPath} -type d -exec chmod 755 {} \\;");
exec("sudo find {$tenantPath} -type f -exec chmod 644 {} \\;");
Beklenen Sonuç: Tüm tenant storage klasörleri tuufi.com_:psaserv owner ile oluşur, site düzgün çalışır
Dosya:
Modules/TenantManagement/app/Http/Livewire/TenantComponent.php
Satır: 358-389
→
deleteTenant()
❌ Sorun:
Tenant silinirken sadece Laravel kaydı ve storage dizinleri temizleniyor. MySQL database'i ayakta kalıyor! Bu orphan database'ler disk alanı tüketir.
✅ Çözüm:
Tenant silinirken database'i de DROP et:
// TenantComponent::deleteTenant() içinde
$tenant = Tenant::find($id);
if ($tenant) {
// Storage temizle
$this->cleanTenantDirectories($tenant->id);
// ✅ Database'i DROP et
$dbName = $tenant->tenancy_db_name;
DB::statement("DROP DATABASE IF EXISTS `{$dbName}`");
// Laravel kaydını sil
$tenant->delete();
}
Beklenen Sonuç: Tenant silindiğinde hem Laravel kaydı, hem storage, hem de database temizlenir
Dosya:
Modules/TenantManagement/app/Http/Livewire/TenantComponent.php
Satır: 265-279, 303-306
❌ Sorun:
theme_settings alanı migration'da
json tipinde tanımlanmış.
TenantComponent'te DB::table()->update() ile
json_encode($themeSettings) kullanılıyor.
Bu double encoding riski taşıyor çünkü Laravel JSON kolonları otomatik encode eder!
✅ Çözüm:
İKİ SEÇENEK var:
Seçenek 1: Eloquent Kullan (Önerilen)
// JSON cast varsa ARRAY gönder, Laravel otomatik encode eder
$tenant->update([
'title' => $this->name,
'theme_settings' => $themeSettings, // ✅ Array olarak
]);
Seçenek 2: DB::table() Kullanırsan Cast'i Devre Dışı Bırak
// DB::table() ile cast yok, manuel encode et
DB::table('tenants')->where('id', $id)->update([
'theme_settings' => json_encode($themeSettings) // ✅ JSON string
]);
Beklenen Sonuç: theme_settings doğru JSON formatında saklanır, double encoding önlenir
⚠️ Tutarsızlık:
readme/documentation/tenant-olusturma.md → Tinker örneğinde seeder çalıştırılıyor
Admin Panel (TenantComponent) → Seeder çalıştırmıyor!
✅ Öneri:
// TenantComponent::saveTenant() içinde
$tenant = Tenant::create([...]);
// Tenant database'ini seed et
$tenant->run(function () {
Artisan::call('db:seed', [
'--class' => 'TenantDatabaseSeeder',
'--force' => true
]);
});
Beklenen Sonuç: Admin panel'den oluşturulan tenant'lar da otomatik seed edilir
⚠️ Risk:
config/tenancy.php →
'--path' => ['Modules/*/database/migrations/tenant']
Joker karakter (*) kullanıldığı için tüm modüllerin tenant migration'ları otomatik yüklenmeli ama test edilmemiş!
✅ Öneri:
Yeni bir test tenant oluştur ve migration'ları kontrol et:
php artisan tenants:migrate --tenant=test_tenant_id
# Modül migration'larının yüklenip yüklenmediğini kontrol et
# Eğer sorun varsa path'i manuel listele:
'--path' => [
'database/migrations/tenant',
'Modules/Shop/database/migrations/tenant',
'Modules/Blog/database/migrations/tenant',
// ...
]
⚠️ Eksik Konular:
✅ Öneri:
readme/documentation/tenant-olusturma.md dosyasını güncelle:
UUID devre dışı (id_generator: null),
integer ID kullanılıyor ($incrementing = true).
Migration ve model tutarlı.
normalizeDomain() fonksiyonu www prefix'ini,
http/https protocol'ünü ve trailing slash'i otomatik temizliyor.
İlk eklenen domain otomatik olarak primary yapılıyor
(setPrimaryDomain()).
Tenant başına sadece 1 primary domain olması garanti ediliyor.
Her tenant için ayrı storage klasörü (storage/tenant{id}/)
ve public storage linki (public/storage/tenant{id}/) oluşturuluyor.
MySQLDatabaseManager aktif, CREATE permission granted. Tenant database'leri otomatik oluşuyor.
Database, Redis, Storage, Queue, Session bootstrapper'ları aktif. Her tenant izole çalışıyor.
Storage Permission Hatası - HEMEN Düzelt!
prepareTenantDirectories() içine owner/chmod komutları ekle
Database DROP İşlemi - Tenant Silme
deleteTenant() içine DROP DATABASE ekle
JSON Double Encoding - theme_settings
Eloquent kullan veya json_encode() kaldır
Admin Panel Seeder Eksikliği
saveTenant() içine TenantDatabaseSeeder ekle
Dokümantasyon Güncelle
tenant-olusturma.md dosyasına eksik bölümleri ekle