🏢 Muzibu Corporate System

Doğru Mimari: User-Based Hierarchy + UI Taslakları

v3 - DÜZELTME User = Firma/Şube/Çalışan 26 Kasım 2025
🎯

Doğru Mimari Anlayışı

❌ ÖNCEKİ PLAN HATALI İDİ: "Firma için ayrı tablo" yaklaşımı yanlıştı!
✅ DOĞRU MANTIK: Her user = bir kayıt. Firma da user, şube de user, çalışan da user!

🔍 Muzibu Sisteminin Gerçek Yapısı

Temel Prensipler:

  • Muzibu = Tek tenant (1001)
  • Her kayıt (firma/şube/çalışan) = users tablosunda 1 satır
  • muzibu_corporate_accounts = Hiyerarşi ve rol bilgisi
  • parent_id = İlişki kurucu

Örnek Veri Yapısı:

📊 users tablosu:
├── id: 100 | email: starbucks@firma.com | name: "Starbucks Türkiye"
├── id: 101 | email: kadikoy@starbucks.com | name: "Kadıköy Şubesi"
├── id: 102 | email: ahmet@starbucks.com | name: "Ahmet Yılmaz"
└── id: 103 | email: ayse@starbucks.com | name: "Ayşe Demir"
📊 muzibu_corporate_accounts tablosu:
├── id: 1 | user_id: 100 | parent_id: NULL | role: owner | company_name: "Starbucks"
├── id: 2 | user_id: 101 | parent_id: 1 | role: manager | branch_name: "Kadıköy"
├── id: 3 | user_id: 102 | parent_id: 2 | role: employee
└── id: 4 | user_id: 103 | parent_id: 2 | role: employee

🏗️ Görsel Hiyerarşi

🏢 Starbucks (user_id: 100, parent_id: NULL, role: owner)
├── 🏪 Kadıköy Şubesi (user_id: 101, parent_id: 100, role: manager)
│ ├── 👤 Ahmet Yılmaz (user_id: 102, parent_id: 101, role: employee)
│ └── 👤 Ayşe Demir (user_id: 103, parent_id: 101, role: employee)
├── 🏪 Beşiktaş Şubesi (user_id: 104, parent_id: 100, role: manager)
│ ├── 👤 Mehmet Kaya (user_id: 105, parent_id: 104, role: employee)
│ └── 👤 Zeynep Çelik (user_id: 106, parent_id: 104, role: employee)
└── 🏪 Ankara Kızılay (user_id: 107, parent_id: 100, role: manager)
└── 👤 Can Öztürk (user_id: 108, parent_id: 107, role: employee)
📊

Yapılacak Değişiklikler

1️⃣ Migration: 3 Alan Ekle

Mevcut muzibu_corporate_accounts tablosuna sadece 3 alan eklenecek:

Alan Tip Açıklama Örnek
branch_name string nullable Şube adı (sadece manager için) "Kadıköy Şubesi"
role enum owner, manager, employee "manager"
settings json nullable Esnek ayarlar (şehir, adres vb.) {"city": "İstanbul", "address": "..."}

Migration Kodu:

// database/migrations/tenant/2025_11_26_add_hierarchy_fields.php public function up() { Schema::table('muzibu_corporate_accounts', function (Blueprint $table) { $table->string('branch_name')->nullable()->after('company_name'); $table->enum('role', ['owner', 'manager', 'employee']) ->default('employee')->after('is_active'); $table->json('settings')->nullable()->after('role'); $table->index('role'); }); }

2️⃣ Model Güncelleme

MuzibuCorporateAccount.php modelinde küçük eklemeler:

// Modules/Muzibu/app/Models/MuzibuCorporateAccount.php protected $fillable = [ ..., // Mevcut alanlar 'branch_name', 'role', 'settings', ]; protected $casts = [ 'is_active' => 'boolean', 'settings' => 'array', // JSON cast ]; // Yeni helper metodlar public function isOwner(): bool { return $this->role === 'owner'; } public function isManager(): bool { return $this->role === 'manager'; } public function isEmployee(): bool { return $this->role === 'employee'; } // Şubeleri getir (sadece owner için) public function getBranches() { return $this->children()->where('role', 'manager')->get(); } // Çalışanları getir (manager için) public function getEmployees() { return $this->children()->where('role', 'employee')->get(); } // Firma adını getir (hiyerarşide yukarı git) public function getCompanyName(): ?string { if ($this->isOwner()) { return $this->company_name; } $root = $this; while ($root->parent) { $root = $root->parent; } return $root->company_name ?? null; }

3️⃣ Kullanım Örnekleri

Firma Oluştur (Owner):

// 1. Users tablosuna firma kaydı ekle $firmaUser = User::create([ 'name' => 'Starbucks Türkiye', 'email' => 'starbucks@firma.com', 'password' => Hash::make('password'), ]); // 2. Corporate account oluştur $corporate = MuzibuCorporateAccount::create([ 'user_id' => $firmaUser->id, 'parent_id' => null, 'company_name' => 'Starbucks Türkiye', 'corporate_code' => MuzibuCorporateAccount::generateCode(), 'role' => 'owner', 'settings' => [ 'max_branches' => 200, 'subscription_plan' => 'enterprise', ], ]);

Şube Ekle (Manager):

// 1. Users tablosuna şube kaydı ekle $subeUser = User::create([ 'name' => 'Kadıköy Şubesi', 'email' => 'kadikoy@starbucks.com', 'password' => Hash::make('password'), ]); // 2. Corporate account oluştur $sube = MuzibuCorporateAccount::create([ 'user_id' => $subeUser->id, 'parent_id' => $corporate->id, // Firma ID 'branch_name' => 'Kadıköy Şubesi', 'role' => 'manager', 'settings' => [ 'city' => 'İstanbul', 'address' => 'Kadıköy Moda Caddesi No: 42', 'phone' => '0216 555 12 34', ], ]);

Çalışan Ekle (Employee):

// 1. Users tablosuna çalışan kaydı ekle $calisanUser = User::create([ 'name' => 'Ahmet Yılmaz', 'email' => 'ahmet@starbucks.com', 'password' => Hash::make('password'), ]); // 2. Corporate account oluştur MuzibuCorporateAccount::create([ 'user_id' => $calisanUser->id, 'parent_id' => $sube->id, // Şube ID 'role' => 'employee', ]);
🎨

Admin Panel UI Taslakları

1️⃣ Kurumsal Hesaplar - Tree View

Mevcut corporate-manage.blade.php üzerinde güncelleme yapılacak.

🏢 Kurumsal Hesaplar (User-Based Hierarchy)
🏢 Starbucks Türkiye (user: starbucks@firma.com | role: owner | 28 şube)
🏪 Kadıköy Şubesi (user: kadikoy@starbucks.com | role: manager | 12 çalışan)
👤 Ahmet Yılmaz (ahmet@starbucks.com | role: employee)
👤 Ayşe Demir (ayse@starbucks.com | role: employee)
🏪 Beşiktaş Şubesi (besiktas@starbucks.com | role: manager | 8 çalışan)
🏢 McDonalds (user: mcdonalds@firma.com | role: owner | 52 şube)
🏪 Ataşehir Şubesi (atasehir@mcdonalds.com | role: manager | 15 çalışan)

2️⃣ Kayıt Ekleme/Düzenleme Formu

Mevcut forma 3 alan ekleme + user seçimi ile birleştirme

✏️ Kurumsal Hesap Ekle
💡 İPUCU: Önce Users tablosuna kayıt ekleyin, sonra buradan corporate account oluşturun!
Owner = Ana firma, Manager = Şube, Employee = Çalışan
Employee için şube seçin, Manager için firma seçin
💡 Şehir, adres, telefon, max_branches gibi esnek bilgiler
🚀

Uygulama Adımları

ADIM 1 (15 dk)

Migration Oluştur & Çalıştır

  • 3 alan ekle: branch_name, role, settings
  • Index ekle: role
  • Migration çalıştır (tenant database)
ADIM 2 (30 dk)

Model Güncelle

  • Fillable ekle: 3 yeni alan
  • Casts ekle: settings → array
  • Helper metodlar: isOwner(), isManager(), getBranches()
ADIM 3 (1 saat)

Livewire Component Güncelle

  • CorporateAccountComponent'e rol seçimi ekle
  • Form validasyonu: rol bazlı zorunlu alanlar
  • Tree-view render mantığı ekle
ADIM 4 (1 saat)

Blade View Güncelle

  • corporate-manage.blade.php → Tree-view ekle
  • Form'a 3 alan ekle (role, branch_name, settings)
  • Rol bazlı gösterim (owner → firma, manager → şube)
ADIM 5 (30 dk)

Test

  • Firma oluştur (owner)
  • Şube ekle (manager)
  • Çalışan ekle (employee)
  • Hiyerarşiyi kontrol et
⏱️ TOPLAM SÜRE: ~3 SAAT
Minimal değişiklik, düşük risk, aynı gün içinde tamamlanır!
💡

İsteğe Bağlı İyileştirmeler

🎨 Alpine.js Tree Toggle

Açılır/kapanır ağaç görünümü için:

<div x-data="{ expanded: {} }"> <div @click="expanded[1] = !expanded[1]"> <span x-text="expanded[1] ? '▼' : '▶'"></span> Starbucks </div> <div x-show="expanded[1]"> Şubeler... </div> </div>

🔍 Rol Bazlı Filtre

Sadece owner'ları veya manager'ları göster:

// Livewire Component public $roleFilter = 'all'; public function getRecordsProperty() { $query = MuzibuCorporateAccount::query(); if ($this->roleFilter !== 'all') { $query->where('role', $this->roleFilter); } return $query->with('owner')->get(); }

📊 Dashboard İstatistikleri

Firma/Şube/Çalışan sayıları:

// Stats hesaplama $stats = [ 'total_companies' => MuzibuCorporateAccount::where('role', 'owner')->count(), 'total_branches' => MuzibuCorporateAccount::where('role', 'manager')->count(), 'total_employees' => MuzibuCorporateAccount::where('role', 'employee')->count(), ];

🔐 Yetki Kontrolü Middleware

Sadece kendi şubesini düzenleyebilir:

// Helper method public function canManage(User $user, MuzibuCorporateAccount $account) { $userAccount = MuzibuCorporateAccount::where('user_id', $user->id)->first(); if (!$userAccount) { return false; } // Owner kendi altındaki herkesi yönetebilir if ($userAccount->isOwner()) { return $account->parent_id === $userAccount->id || $account->id === $userAccount->id; } // Manager kendi altındaki çalışanları yönetebilir if ($userAccount->isManager()) { return $account->parent_id === $userAccount->id; } return false; }

Özet

🎯 Doğru Mimari

  • Her user = bir kayıt (firma, şube, çalışan hepsi users tablosunda)
  • muzibu_corporate_accounts = Hiyerarşi tablosu (parent_id ile ilişki)
  • role = Ayırt edici (owner/manager/employee)
  • Minimal değişiklik (sadece 3 alan ekle)
  • Hızlı implementasyon (~3 saat)

📋 Yapılacaklar Listesi

  1. Migration oluştur (3 alan)
  2. Model'i güncelle (fillable, casts, helpers)
  3. Livewire component'i genişlet
  4. Blade view'u güncelle (tree-view)
  5. Test et (firma → şube → çalışan)
✅ HAZIR! Artık doğru mimariye göre kodlamaya başlayabiliriz! 🚀