المدونةنُشر في

منتج واحد، وعملاء كثير

عيادة، ومحل، ومدرّب، وفرع مورّد — كل واحد جهة مستقلة، والتطبيق واحد. وهكذا لا تختلط البيانات، ولا يتفرّع الكود.

  • بنية
  • خلفية
  • SaaS
قنوات تركواز في سطح داكن، كل واحدة لحاله.

في منتجات تخدم أكثر من جهة من نفس التطبيق. كل جهة تشوف شغلها فقط. المستخدم يدخل، والبيانات لا تعبر الجدار. هذا ليس إعداد Microsoft Entra، وليس كلمة SaaS على سلايد. SaaS طريقة تبيع بها. وهذا الشكل طريقة تبني بها. يأتيان معًا كثيرًا، لكنهما ليسا الشيء نفسه.

هذا ما يسمّى multi-tenant. نبنيه كي تعمل العيادات والمحلات والمدرّبون والمورّدون على الكود نفسه، ولكل واحد بياناته المستقلة. الجوال واللوحة والخلفية نظام واحد. والفصل يتم في الخلفية.

وش يعني جهة

الجهة عادة شركة أو عيادة أو محل — مو المستخدم. المستخدم عام. العضوية تربطه بجهة. صلاحياته داخل هذه الجهة. يمكن أن يكون في أكثر من جهة. كلمة «أدمن» لا تعني شيئًا حتى تحدّد: أدمن لأي جهة؟

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

أربعة أشياء لازم تنفصل

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

ثلاث طرق تفصل فيها البيانات

الأسماء تختلف. المعنى واحد.

جدول واحد، وعمود للجهة

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

سكيما لكل جهة

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

قاعدة لكل جهة

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

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

أمان الصفوف على Postgres

أمان صفوف Postgres شرطُ WHERE يطبّقه المحرّك تلقائيًا. مكانه جدول واحد وعمود جهة. ولا يغني عن العمود ولا عن الفهرس. هو شبكة أمان لليوم الذي ينسى فيه المطوّر الفلتر.

على Supabase، جدول مكشوف بدون أمان صفوف يقدر أن يقرأه ويكتب فيه أي أحد معه المفتاح العام. تشغّل الأمان ولا تضع سياسات، فلا يظهر شيء. مالك الجدول يتجاوز الأمان إلا إذا أجبرته. والتطبيق لا يتصل كمالك. مفتاح service role يتجاوز الأمان، ومكانه السيرفر فقط.

الصلاحيات وعضوية الجهة لا تكون في حقل يعدّله المستخدم. تكون في مكان يتحكم فيه السيرفر، أو في جدول عضوية. توكن JWT قد يصبح قديمًا، وتغيير العضوية لا يظهر حتى يتجدّد التوكن. سياسة خاطئة تفشل بهدوء: الواسعة ترجع صفوفًا زائدة، والضيّقة ترجع ولا شيء ولا تُظهر خطأ. اختبر الاتجاهين.

متى من أول يوم

إذا كان عميلك جهةً، فأدرج الجهة في النسخة الأولى. الفصل يمكن أن يكون الأرخص: جدول واحد، وعمود جهة، وأمان صفوف. لا تفتح قاعدة لكل جهة لأن تدوينة قالت «إنتربرايز». ولا تبنِ صلاحيات معقّدة على افتراض.

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

اللوحة والجوال والخلفية — شيء واحد

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

كيف يظهر هذا الكلام في العمل

Naqrah.app — كل عيادة جهة على منصة حجز في عُمان. المريض يبحث ويحجز. وكل عيادة تدير مواعيدها.

T-CODE — تجّار بفروع. تطبيق المتسوق ولوحة التاجر منتج واحد. تخفي فرعًا دون أن تمسّ محلًا آخر.

Oxygen Academy — مدرّب وطالب وسفير. صلاحيات، مو ثلاثة تطبيقات. عربي وإنجليزي. الدفعات عند المدرّب، مو في صندوق مشترك.

WOSTA — مشترين ومورّدين. المورّد يدير أكثر من مستودع أو فرع، ولكل واحد طلباته وعروضه وفواتيره. العربي هو الأساس. التسجيل برمز يُرسل إلى الجوال.

إذا أُنجز بشكل صحيح، لا يُرى

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

أخبرنا عن مشروعك.

اكتب لنا وش تبي تبني. يرد عليك من سينفّذ الشغل.

تواصل معنا