# تطبيق فصل الأدوار حسب المؤسسات (Tenant-Scoped Roles)

## 📋 المشكلة
جميع المؤسسات (Tenants) كانت ترى نفس الأدوار (Roles) عند إنشاء أو تعديل مستخدم، مما يخلق مشاكل أمنية وخلط بين بيانات المؤسسات المختلفة.

## ✅ الحل المطبق

### 1. إضافة حقل `tenant_id` لجدول `roles`

**الملف:** `database/migrations/2026_01_24_154020_add_tenant_id_to_roles_table.php`

```php
public function up(): void
{
    Schema::table('roles', function (Blueprint $table) {
        $table->foreignId('tenant_id')
            ->nullable()
            ->after('id')
            ->constrained('tenants')
            ->nullOnDelete();
        
        $table->index('tenant_id');
    });
}
```

**الغرض:**
- ربط كل دور بمؤسسة معينة
- السماح بأدوار عامة (tenant_id = null) للاستخدام المشترك

---

### 2. تحديث UserForm لتصفية الأدوار

**الملف:** `app/Filament/Resources/Users/Schemas/UserForm.php`

```php
->relationship(
    name: 'roles',
    titleAttribute: 'name',
    modifyQueryUsing: function ($query) {
        $user = auth()->user();

        // System Admin يرى جميع الأدوار
        if ($user->is_system_admin) {
            return $query;
        }

        // Tenant users يروا فقط أدوار مؤسستهم أو الأدوار العامة
        if ($user->tenant_id) {
            return $query->where(function ($q) use ($user) {
                $q->where('tenant_id', $user->tenant_id)
                  ->orWhereNull('tenant_id');
            });
        }

        // مستخدم بدون tenant_id يرى فقط الأدوار العامة
        return $query->whereNull('tenant_id');
    }
)
```

**الفلترة تعمل كالتالي:**
- **System Admin**: يرى كل الأدوار في النظام
- **Tenant User**: يرى فقط أدوار مؤسسته + الأدوار العامة (null)
- **مستخدم بدون مؤسسة**: يرى فقط الأدوار العامة

---

### 3. إنشاء Seeder للأدوار الأساسية

**الملف:** `database/seeders/TenantRolesSeeder.php`

ينشئ الأدوار التالية لكل مؤسسة:
- `admin` - مدير المؤسسة
- `user` - مستخدم عادي
- `accountant` - محاسب
- `warehouse_keeper` - أمين المخزن

**كل دور مرتبط بـ tenant_id محدد**

---

## 🚀 خطوات التطبيق

### 1. تشغيل الـ Migration
```bash
php artisan migrate
```

### 2. تشغيل الـ Seeder لإنشاء الأدوار
```bash
php artisan db:seed --class=TenantRolesSeeder
```

### 3. (اختياري) تحديث الأدوار الموجودة
إذا كان لديك أدوار موجودة بدون tenant_id، يجب تعيينها لمؤسساتها:

```php
// في Tinker أو Script
use Spatie\Permission\Models\Role;
use App\Models\Tenant;

// تعيين أدوار موجودة لمؤسسة معينة
$tenant = Tenant::find(1);
Role::whereNull('tenant_id')
    ->where('name', 'admin')
    ->update(['tenant_id' => $tenant->id]);
```

---

## 🎯 الميزات المكتسبة

### ✅ عزل تام بين المؤسسات
- كل مؤسسة لها أدوارها الخاصة
- لا يمكن لمؤسسة رؤية أو استخدام أدوار مؤسسة أخرى

### ✅ مرونة في الأدوار
- يمكن إنشاء أدوار خاصة بكل مؤسسة
- يمكن إنشاء أدوار عامة (tenant_id = null) للاستخدام المشترك

### ✅ أمان محسّن
- منع تعيين أدوار غير مصرح بها
- فلترة تلقائية في واجهة المستخدم

### ✅ سهولة الإدارة
- كل مؤسسة تدير أدوارها بشكل مستقل
- System Admin يحتفظ بالتحكم الكامل

---

## 📝 ملاحظات هامة

### 1. الأدوار العامة (Global Roles)
الأدوار التي `tenant_id = null` يمكن رؤيتها واستخدامها من جميع المؤسسات.
استخدمها للأدوار المشتركة مثل: `guest`, `support`

### 2. إنشاء أدوار جديدة
عند إنشاء دور جديد من داخل panel، يجب التأكد من تعيين `tenant_id`:

```php
Role::create([
    'name' => 'custom_role',
    'tenant_id' => auth()->user()->tenant_id,
    'guard_name' => 'web'
]);
```

### 3. التوافق مع Filament Shield
إذا كنت تستخدم Filament Shield، تأكد من تحديث الأدوار المُنشأة تلقائياً:

```bash
php artisan shield:generate --all
```

ثم قم بتعيين `tenant_id` للأدوار المُنشأة.

---

## 🔄 التكامل مع TenantSetupService

يمكن تحديث `TenantSetupService` لإنشاء الأدوار الأساسية تلقائياً عند إنشاء مؤسسة جديدة:

```php
// في app/Services/TenantSetupService.php

protected function seedTenantData(Tenant $tenant): void
{
    // ... الكود الموجود
    
    // إضافة الأدوار الأساسية
    $this->seedTenantRoles($tenant->id);
}

protected function seedTenantRoles(int $tenantId): void
{
    $roles = ['admin', 'user', 'accountant', 'warehouse_keeper'];
    
    foreach ($roles as $roleName) {
        Role::firstOrCreate([
            'name' => $roleName,
            'tenant_id' => $tenantId,
            'guard_name' => 'web'
        ]);
    }
}
```

---

## 🎉 النتيجة النهائية

الآن عند إنشاء أو تعديل مستخدم:
- ✅ System Admin يرى جميع الأدوار
- ✅ Tenant users يروا فقط أدوار مؤسستهم
- ✅ فصل تام وآمن بين المؤسسات
- ✅ واجهة مستخدم نظيفة ومنظمة
