تخطَّ إلى المحتوى
العودة إلى المدونة

هندسة البرمجيات

وقت القراءة
11 دقيقة قراءة
تاريخ النشر
آخر تحديث

مقال من برمج تك

بناء معمارية SaaS متعددة المستأجرين في Laravel

هندسة برمج تكالفريق الهندسيآخر مراجعة للمحتوى: ٢٠ تموز ٢٠٢٦
بناء معمارية SaaS متعددة المستأجرين في Laravel

يتناول هذا المقال «بناء معمارية SaaS متعددة المستأجرين في Laravel» ضمن محور «معمارية SaaS متعددة المستأجرين في Laravel»، بلغة تشغيلية يمكن لفريق العمل تطبيقها مباشرة.

معمارية البرمجيات المقدمة كخدمة (SaaS) لعدة مستأجرين في Laravel لا تتحقق بإضافة عمود tenant_id إلى الجداول ثم نسيانه. يمر العزل عبر تحديد المؤسسة في الطلب، والتفويض، والاستعلام، والطابور، والتخزين المؤقت، والملفات، والسجلات، والتصدير. أي موضع يفقد هذا السياق قد يكشف بيانات أو يكتبها تحت عميل آخر. لذلك يبدأ التصميم من نموذج التهديد وحدود البيانات، ثم يختار نمط قاعدة البيانات وأدوات الإطار، لا العكس.

عرّف المستأجر وحدود العزل

قد يكون المستأجر شركة أو فرعاً أو مجموعة قانونية، وقد ينتمي المستخدم إلى واحد أو عدة مستأجرين. اكتب القاعدة صراحة: ما البيانات التابعة للمستأجر؟ ما البيانات العالمية المشتركة؟ من يستطيع الانتقال بين المؤسسات؟ وهل موظف الدعم يحتاج وصولاً مؤقتاً؟ لا تستخدم «المؤسسة الحالية» كمفهوم غامض.

افصل التعريف عن التفويض. معرفة أن الطلب يخص المستأجر ألف لا تثبت أن المستخدم مخول لرؤية الفاتورة داخل ألف. تحتاج سياسات للأدوار والموارد، كما تحتاج منع أي معرف يأتي من الواجهة من تجاوز السياق الموثوق.

اختر نموذج قاعدة البيانات وفق المخاطر

المخطط المشترك يضع مستأجرين عدة في الجداول نفسها مع مفتاح عزل. يبسّط الترحيل والتحليلات والتشغيل في كثير من المنتجات، لكنه يرفع أهمية كل استعلام وسياسة. قاعدة منفصلة لكل مستأجر تقوي بعض حدود العزل والاستعادة، لكنها تضيف تنسيق ترحيلات واتصالات ومراقبة ونسخاً كثيرة. توجد نماذج هجينة أيضاً.

قارن متطلبات التنظيم، وحجم البيانات، واحتمال الاستعلامات المشتركة، وحاجة الاستعادة الفردية، وقدرة الفريق التشغيلية. لا تختَر القواعد المنفصلة لأنها تبدو «أكثر أماناً» إذا لم تستطع تحديثها ومراقبتها بثبات، ولا تختَر المشترك لتقليل التكلفة من دون دفاعات واختبارات.

أنشئ سياقاً موثوقاً مبكراً

استخرج هوية المستأجر من نطاق أو مسار أو عضوية موثقة، ثم أنشئ كائناً واضحاً للسياق قبل دخول منطق العمل. لا تعتمد على tenant_id يرسله النموذج. نظّف السياق بعد الطلب، خصوصاً في عمال PHP طويلة الحياة أو اختبارات تشارك العملية، حتى لا يتسرب إلى طلب لاحق.

اجعل غياب السياق يفشل بوضوح في المسارات التي تتطلبه. القيمة الافتراضية الصامتة خطرة. أما لوحة الإدارة العالمية، فصممها كمسار منفصل بصلاحيات ومراجعة أقوى، لا كتعطيل سريع للنطاق العام.

طبّق النطاق في أكثر من طبقة

يمكن لنطاق Eloquent عام أن يقلل النسيان، لكنه لا يكفي وحده. راجع الاستعلامات الخام والعلاقات والـ joins والتقارير وعمليات upsert. استخدم سياسات Laravel للتفويض، واكتب مستودعات أو حالات استخدام تقبل سياقاً صريحاً عند الحاجة. كل «بدون نطاق» يجب أن يكون نادراً ومبرراً ومختبراً.

تستطيع PostgreSQL Row Level Security إضافة طبقة دفاع في العمق. لكنها تحتاج سياسات صحيحة، ودور اتصال مناسباً، وضبطاً لسياق الجلسة والمعاملات. اختبرها فعلياً؛ وجود السياسة لا يعني أن دور التطبيق خاضع لها تلقائياً في كل إعداد.

احمل السياق إلى الطوابير

المهمة الخلفية تحدث خارج الطلب الذي أنشأها. ضع معرف المستأجر في payload موثوق، وأعد إنشاء السياق داخل التنفيذ، ثم أزله في النهاية. تحقق من أن المستخدم أو المورد ما زال صالحاً إذا طال الانتظار. لا تمرر نموذجاً كاملاً بافتراض أن كل علاقة ستُحمّل بالنطاق الصحيح.

قسّم فشل المهام ومراقبتها حسب المستأجر من دون كشف البيانات في الاسم أو السجل. عند إعادة المحاولة، يجب أن تبقى العملية idempotent وألا تنتقل إلى مؤسسة أخرى بسبب حالة عامل قديمة.

اعزل التخزين المؤقت والملفات والبحث

كل مفتاح cache يحتاج مساحة أسماء للمستأجر، بما في ذلك الأقفال والحدود والـ feature flags. والملفات تحتاج مساراً وسياسة وصول وروابط موقعة مرتبطة بالمؤسسة. فهرس البحث والقنوات اللحظية والتصدير والإشعارات تحتاج المبدأ نفسه. قاعدة البيانات ليست المكان الوحيد للبيانات.

اكتب قائمة بكل مخزن خارجي وخدمة: Redis، تخزين ملفات، محرك بحث، مراقبة، مزود بريد، وتحليلات. حدد ما يرسل إليه، وكيف يُحذف أو يُصدّر، وكيف يمنع الوصول المتبادل.

صمّم الانضمام والتبديل والإلغاء

إنشاء المستأجر عملية لها حالات: التحقق، وإنشاء الإعدادات، وتعيين المالك، وتطبيق الخطة، وربما تهيئة بيانات. استخدم orchestration قابلاً لإعادة المحاولة بدل سلسلة غير محمية. إذا فشلت خطوة، يجب معرفة ما اكتمل وكيف يُستأنف أو يُرجع.

تبديل المستأجر في واجهة المستخدم يحتاج إعادة تحقق من العضوية ومسح البيانات المحلية الحساسة وإعادة تحميل الصلاحيات. أما الإلغاء، فيحتاج سياسة تصدير واحتفاظ وحذف تمنع بقاء ملفات أو jobs أو cache منسي.

عالج الجار كثير الاستهلاك

قد يشغّل مستأجر تصديراً كبيراً أو يستدعي API بكثافة. ضع حدوداً عادلة حسب الخطة والمخاطر، وقسّم الطوابير أو الأولويات عندما يلزم، وراقب زمن الاستجابة والأخطاء واستهلاك الموارد بنسبة إلى المستأجر. لا تضع الاسم أو المعلومات الحساسة في المقاييس؛ استخدم معرفاً داخلياً مضبوطاً.

الهدف ليس معاقبة العميل النشط، بل منع عمل واحد من تدهور الخدمة للجميع. صمم مسارات ثقيلة كمهام قابلة للمراقبة والإلغاء، وقدم حالة للمستخدم بدلاً من طلب HTTP طويل.

خطط للترحيلات من أول يوم

في المخطط المشترك، ترحيل واحد يغير الجميع، لذلك اختبر التوافق الخلفي ونشر التغيير على مراحل. أضف العمود أو الحالة أولاً، ثم انشر الكود المتوافق، ثم رحّل البيانات، ثم شدد القيد. تجنب قفل جدول كبير في وقت الذروة من دون قياس.

في القواعد المنفصلة، تحتاج سجلاً لإصدار كل قاعدة، وآلية استكمال عند الفشل، ومراقبة للمستأجرين المتأخرين. لا تفترض أن تشغيل أمر في حلقة هو خطة ترحيل.

راقب من دون تسريب

اربط الطلبات والمهام والأخطاء بمعرف مستأجر داخلي ليس سراً لكنه لا يحمل اسماً. اخفِ محتوى السجلات، ولا تسجل payloads كاملة افتراضياً. أنشئ لوحات تظهر نسبة الفشل والكمون والطوابير والاستخدام، مع صلاحيات مناسبة للوصول إلى التفاصيل.

عند دعم عميل، استخدم آلية impersonation أو وصول مؤقت تسجل من دخل ولماذا ومدة الوصول، بدلاً من مشاركة كلمة مرور. اجعل الإنهاء تلقائياً ومرئياً للمراجعة.

اختبر العزل كخاصية

أنشئ اختبارات بمستأجرين على الأقل، وحاول قراءة وتعديل وحذف وتصدير موارد متبادلة. اختبر المعرفات المتوقعة وغير المتوقعة، والعلاقات، والمهام، والـ cache، والملفات، والبحث، ولوحة الإدارة. أضف الاختبار عند كل حادثة أو مسار جديد.

يمكن للاختبارات التوليدية أو جداول الحالات توسيع التغطية، لكن المراجعة الهندسية تظل مهمة. يشرح دليل Clean Architecture وDDD في Laravel كيف تحافظ على حدود المجال والتكاملات من دون دفن القاعدة في Controller.

النسخ الاحتياطي والتصدير ليسا شيئاً واحداً

النسخة الاحتياطية تعيد الخدمة، أما تصدير المستأجر فيمنحه بياناته بصيغة قابلة للاستخدام. اختبر الاستعادة الكاملة وحدد كيف ستتعامل مع استعادة مؤسسة واحدة عند الحاجة. في المخطط المشترك قد تتطلب الاستعادة إلى بيئة معزولة ثم استخراج السجلات، لا استبدال قاعدة الإنتاج.

وثّق الحذف عبر الجداول والملفات والبحث والنسخ الخاضعة لسياسة الاحتفاظ. لا تعد بحذف فوري من كل نسخة إذا كانت خطة الاستعادة تتطلب احتفاظاً زمنياً؛ اشرح السياسة بدقة.

ابدأ بقرار قابل لإعادة التقييم

تقدم خدمة تطوير منصات SaaS إطاراً لتحديد الحدود قبل المخطط. ويمكن مراجعة تطبيق عملي للقرارات في دراسة حالة Clinic Tek من دون افتراض أن نموذج منتج واحد يصلح للجميع.

لا تحتاج المنصة الجديدة إلى حل كل نمط توسع من اليوم الأول، لكنها تحتاج حدوداً صريحة واختبارات وبيانات قابلة للنقل. اطلب مراجعة معمارية لخريطة عزل المستأجرين قبل أن يصبح السياق موزعاً بين عشرات الاستعلامات والمهام.

أسئلة شائعة

لا. يجب أن يشمل العزل الاستعلامات والطوابير والتخزين المؤقت والملفات والقنوات، مع اختبارات وصول متبادل.

المصادر

#SaaS #Laravel #المعمارية

سياسة التحرير في برمج تك

اقرأ أيضاً

مقالات ذات صلة

  1. 01

    هندسة البرمجيات / 11 دقيقة قراءة

    تطبيق Clean Architecture وDDD عملياً في Laravel

    تطبيق Clean Architecture وDDD عملياً
    غلاف: تطبيق Clean Architecture وDDD عملياً
  2. 02

    هندسة البرمجيات / 12 دقيقة قراءة

    Flutter وLaravel: خلفية واحدة لتطبيقات iOS وAndroid

    Flutter وLaravel: خلفية واحدة لتطبيقات
    غلاف: Flutter وLaravel: خلفية واحدة لتطبيقات
  3. 03

    هندسة البرمجيات / 12 دقيقة قراءة

    أنماط PWA تعمل دون إنترنت للأسواق ذات الشبكة المتغيرة

    أنماط PWA تعمل دون إنترنت

هل تبني نظاماً خاصاً لعملك؟

بعد قراءة «بناء معمارية SaaS متعددة»، أرسل لنا وصفاً للمشروع والمستخدمين والتكاملات المطلوبة، وسنرد بخطوة عملية خلال يوم عمل.