إعداد نظام تعدد المستأجرين (Multi-Tenancy) باستخدام حزمة Spatie و Laravel
أهلاً بك يا صديقي المبرمج. أكيد في وقت من الأوقات، جالك عميل أو شركة طلبت منك تعمل نظام (SaaS) يخدم أكتر من عميل في نفس الوقت، بس كل عميل بياناته معزولة تماماً عن التاني. هنا بيبدأ "وجع الدماغ" بتاع العزل، وإدارة الصلاحيات (Permissions) والأدوار (Roles) لكل مستأجر (Tenant) بشكل منفصل. النهاردة هنشرح إزاي تعمل ده بأسلوب احترافي باستخدام حزمة Spatie Laravel-Permission مع فكرة الـ Multi-Tenancy.
Table of contents [Show]
يعني إيه Multi-Tenancy أصلاً؟
ببساطة، الـ Multi-Tenancy هو إنك بتبني تطبيق ويب واحد (Single Instance) بيخدم شركات أو مؤسسات مختلفة، وكل شركة ليها مستخدمينها الخاصين، وصلاحياتهم، وبياناتهم اللي مستحيل يدخلوا على بيانات شركة تانية. ده بيوفر عليك كتير في الصيانة بدل ما ترفع نسخة من الكود لكل عميل.
الخطوة الأولى: تهيئة قاعدة البيانات
أول حاجة محتاجينها هي حزمة قوية تدير الصلاحيات. حزمة Spatie Laravel-Permission هي المعيار الذهبي في عالم لارافيل. عشان نربطها بنظام الـ Multi-Tenant، لازم نتأكد إن كل جدول فيه حقل tenant_id عشان نعزل البيانات. لو بتستخدم حزمة زي stancl/tenancy، هي هتهتم بـ (Database Isolation) وأنت عليك تهتم بتوزيع الصلاحيات لكل Tenant.
الخطوة التانية: إعداد الصلاحيات مع Spatie
بعد ما تثبت الحزمة، التحدي الحقيقي هو إن الصلاحيات (Permissions) تكون مرتبطة بالـ Tenant. في الإصدارات الجديدة من Spatie، الموضوع بقى مرن جداً. تقدر تخلي الـ Roles والـ Permissions موجودة في قاعدة بيانات الـ Tenant الواحد، أو تعملها (Global) وتتحكم فيها من الـ Admin Panel الأساسية.
كود بسيط عشان تنشئ دور (Role) جديد داخل نطاق معين:
// إنشاء دور داخل الـ Tenant الحالي
$role = Role::create(['name' => 'manager', 'tenant_id' => tenant('id')]);
// منح صلاحية معينة للمستخدم
$user->assignRole('manager');
الخطوة التالتة: عزل الصلاحيات (Scoping)
ده أهم جزء. لازم تضمن إن لما المستخدم يعمل $user->hasPermissionTo('edit-post')، الحزمة تتأكد إن الصلاحية دي تابعة للـ Tenant اللي هو فيه فعلاً. أفضل طريقة هي استخدام (Global Scopes) في لارافيل، أو التعديل في إعدادات الحزمة عشان تضيف tenant_id في الـ (Migration) الخاص بجداول الصلاحيات.
عدل ملف الإعدادات config/permission.php عشان تتأكد إن الـ Tables بتدعم الفلترة:
'models' => [
'role' => Spatie\Permission\Models\Role::class,
'permission' => Spatie\Permission\Models\Permission::class,
],
// تأكد من إضافة tenant_id في الجداول الأساسية عبر الـ Migrations
الخطوة الرابعة: نصائح ذهبية للأداء (Performance)
لما تكبر قاعدة البيانات، الـ Queries ممكن تبطأ. استخدم (Caching) الخاص بحزمة Spatie. الحزمة بتعمل (Cache) للصلاحيات تلقائياً، بس في نظام الـ Multi-Tenant، لازم تتأكد إن الـ Cache Key بيحتوي على الـ tenant_id عشان مفيش مستخدم ياخد صلاحيات مستخدم تاني في شركة تانية.
الخاتمة: نصيحة من أخ
يا صديقي، التعامل مع الأنظمة الضخمة زي الـ (SaaS) بيحتاج صبر ودقة. نصيحتي ليك: ابدأ بـ (Database Isolation) قوي قبل ما تدخل في تفاصيل الصلاحيات. اتعلم تقرأ الكود المصدري بتاع حزمة Spatie، هتفهم منها حاجات خرافية عن (Trait) و (Eloquent Relationships). طور مهاراتك في الـ (Architecture) قبل الـ (Coding)، لأن النظام لو اتبنى صح من الأول، هترتاح سنين.
بالتوفيق في مشروعك الجاي، ولو احتجت أي تفصيلة تقنية تانية، أنا موجود!