تخطَّ إلى المحتوى

تطوير تطبيقات SaaS

تطوير منتجات SaaS بـ Next.js

منتجات SaaS متعدّدة المستأجرين على App Router - فصل المستأجرين والتفويض محسومان قبل أول شاشة، وفوترة تصمد أمام التدقيق، ولوحة تحكّم تبقى على الخادم.

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

نحن نبني هذه المنتجات، ونبدأ بهذه الثلاثة.

فصل المستأجرين، محسومًا قبل أول شاشة

هناك ثلاثة نماذج، والصحيح منها يتوقّف على عملائك لا على الموضة.

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

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

التفويض عند البيانات لا عند المسار

الوسيط الذي يقرّر من يرى صفحةً بوّابة، والبوّابات مفيدة. لكنها ليست تفويضًا. فالـ Server Actions ومعالِجات المسارات تُستدعى مباشرة، وفحصٌ يعيش في الوسيط وحده فحصٌ لا تملكه نقطة النهاية.

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

فوترة تصمد أمام التدقيق

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

نعامل Stripe مصدرًا للحقيقة، ونسخة التطبيق ذاكرةً مؤقّتة تُعاد بناؤها من الخطّافات، بمعالج مُحايد التكرار ومفحوص التوقيع. وتُقرأ الاستحقاقات من قاعدة بياناتك في كل طلب، لأن استدعاء Stripe في مسار الطلب يجعل جاهزية منتجك معلّقة بجاهزيتهم.

والتناسب والفترات التجريبية وتغيّر المقاعد والمدفوعات الفاشلة، كلٌّ منها حالة على الواجهة أن تعبّر عنها. وما يزال يحقّ لحسابٍ متأخّر فعله قرارُ منتج، ونحن نسأل عنه بدل اختراعه.

مشكلة لوحة التحكّم

لوحات SaaS هي الموضع الذي تبطؤ عنده تطبيقات App Router. والغريزة use client في الأعلى لأن هناك رسومًا ومرشّحات، فتذهب شجرة اللوحة كاملةً إلى المتصفّح.

الجداول والترويسات والتنقّل وجلب البيانات تبقى على الخادم. أما الرسم والمرشّح ومنتقي التاريخ فجزر عميل. وحالة الرابط تحمل المرشّحات، فتصير الرؤية المُرشَّحة قابلة للمشاركة ويعمل زرّ الرجوع كما ينبغي. ولا تنتظر أي صفحة أبطأ عناصرها - بل يتدفّق كلٌّ خلف حدّه، وهذا هو مغزى أن loading.tsx ليس مؤشّر تحميل.

ما لا نفعله

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

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