كيف بنيت PostedIn: النظام وراء خدمة محتوى LinkedIn
معتصم شعبان يشرح بناء PostedIn: فصل الموقع عن مساحة العميل، وقواعد الباقات، ومراجعة الدفع، وعزل البيانات، والتعامل مع نتائج النشر غير المؤكدة.

يمكن وصف PostedIn بأنه خدمة لمحتوى LinkedIn، لكن تنفيذها يحتاج إلى أكثر من محرر منشورات. العميل يختار باقة، ويرسل معلوماته، ويراجع المحتوى، ثم يختار طريقة النشر. وراء كل خطوة بيانات وصلاحيات وحالة يجب أن يفهمها العميل والمسؤول.
أنا معتصم شعبان، مؤسس الخدمة ومطوّرها. أشرح هنا قرارات من بنائها، استنادًا إلى مراجعة التنفيذ في ١٨ سبتمبر ٢٠٢٦. هذه النسخة تقابل دراسة الحالة بالإنجليزية.
الموقع العام ومساحة العميل لهما وظيفتان مختلفتان
الموقع العام يشرح العرض ويتيح المحتوى لمحركات البحث. مساحة العميل تحتاج إلى جلسات دخول وصلاحيات وسجلات قابلة للتعديل وتكاملات خارجية. الفصل بينهما كان قرارًا تشغيليًا، وليس مجرد اختلاف في التصميم.
يستخدم PostedIn تطبيق Next.js مستقلًا للموقع التسويقي بمسارات عربية وإنجليزية. تُصدّر صفحاته إلى ملفات ثابتة يقدّمها Nginx. وفي التطبيق الآخر، يعمل الخادم على تشغيل لوحة العميل وواجهات API، مع حماية مساحة العمل بالمصادقة.
يسمح ذلك بتصحيح وصف باقة أو نشر مقال دون إعادة تشغيل التطبيق الذي يدير عمل العملاء. لكن يظل من الضروري توحيد الروابط والهوية وبيانات المنتج بين الجانبين. فصل البناء لا يعني أن يكون للخدمة عرضان مختلفان.
قواعد الباقات تحتاج إلى مصدر واحد
بطاقة الأسعار تصف التزامًا يجب أن يطبّقه النظام. عندما تتضمن باقة 15 منشورًا نصيًا، يجب أن يميّز التطبيق هذا الحد عن باقة تسمح بالصور أو منشورات PDF متعددة الصفحات.
تستورد صفحة أسعار PostedIn كتالوج الباقات نفسه الذي يستخدمه التطبيق. يحتوي الكتالوج على الحدود الرقمية وأوقات الإعداد والمزايا المتاحة. وتأتي الصياغة العربية والإنجليزية حول هذه القيم المشتركة.
يقلل ذلك احتمال تغيير السعر في الموقع مع بقاء حد قديم في مساحة العميل. لكنه لا يغني عن مراجعة النص: «أربعة منشورات متعددة الصفحات ضمن 30 منشورًا» تختلف عن «30 منشورًا إضافة إلى أربعة». قبل بناء منتج مشابه، أحدد القواعد التي يجب أن تتفق عليها صفحات التسويق والدفع والصلاحيات ولوحة الإدارة.
الإيصال واعتماد الدفع وتسليم المحتوى ليست حالة واحدة
تدعم الخدمة مسارًا لمراجعة الدفع المحلي: يقدّم العميل طلبًا وإيصالًا، ثم يراجعه المسؤول قبل اعتماد الدفع. يأتي إعداد المحتوى بعد قبول الطلب واكتمال وصف المطلوب، وفق الباقة المناسبة.
دمج هذه الأحداث في علامة «تم» واحدة يترك العميل والمسؤول دون تفسير لما حدث. الطلب يحتاج إلى حالة، والدفع يحتاج إلى قرار، والمحتوى يحتاج إلى إعداد ومراجعة. إرسال رسالة بريد لا يثبت وحده أن دفعة المحتوى أُعدّت أو وصلت إلى صندوق العميل.
حتى الطلب المجاني يحتاج إلى قبول ومعلومات مكتملة وإعداد حساب وتجهيز محتوى. قبل تصميم لوحة مشابهة، أكتب لكل انتقال: من يستطيع تنفيذه؟ ما الشروط السابقة له؟ وماذا سيرى العميل بعده؟ هذه الأسئلة تحدد النظام بصورة أفضل من قائمة عناصر للوحة تحكم.
المراجعة تسبق النشر التلقائي
تبدأ حسابات PostedIn الجديدة بالنشر اليدوي. يستطيع العميل فحص المحتوى وتعديله قبل تفعيل طابور النشر التلقائي، ويجب إعداد اتصال LinkedIn أولًا.
يتعامل المجدول مع الوقت الذي يحدده العميل والمعدل المسموح به في الباقة. ويسجّل حالة النشر للتمييز بين عمل ينتظر التنفيذ ومحاولة إرسال وعملية تأكد نجاحها. هذه الفروق ضرورية لأن واجهة الخدمة الخارجية ليست تحت سيطرة التطبيق.
تخيّل انتهاء مهلة الاتصال بعد إرسال طلب نشر. إعادة المحاولة فورًا قد تنشر نسخة ثانية إذا نجح الطلب الأول وضاعت استجابته. في PostedIn، تحتاج نتائج النشر غير المؤكدة إلى مراجعة، بدل افتراض أن كل انتهاء مهلة يسمح بإعادة آمنة.
الدرس نفسه ينطبق على الدفع والبريد والتكاملات: حدّد معنى «نجح»، واحتفظ بالدليل، واجعل النتيجة غير المؤكدة ظاهرة للمسؤول. رسالة النجاح في الواجهة يجب أن تعبّر عن نتيجة رصدها النظام.
بيانات كل عميل تحتاج إلى حدود داخل الخادم
يحفظ PostedIn سجلات التطبيق في SQLite، وتبقى الوسائط التي يرفعها العملاء خلف مسارات محمية بالمصادقة. تُفصل مساحات العمل بحسب العميل، ولذلك فالتحقق من تسجيل الدخول هو البداية فقط. يجب أيضًا التأكد من أن السجل المطلوب يخص مساحة يحق لهذا الشخص الوصول إليها.
تُطبّق هذه الفحوص في الخادم. إخفاء زر أو تصفية قائمة في الواجهة لا يفرضان صلاحيات. وتنطبق القاعدة على حدود الباقات: الخادم يقرر إن كانت العملية مسموحة، حتى لو شرحت الواجهة الحد بالفعل.
تُختبر هذه المسارات بقواعد بيانات مؤقتة ومحاكاة للنشر. لا ينبغي أن ينشر الاختبار منشورًا حقيقيًا على LinkedIn، أو يستخدم إيصال عميل، أو يعدّل اشتراكًا فعليًا لإثبات أن الزر يعمل.
دعم العربية يمتد إلى ما بعد ترجمة العناوين
للخدمة روابط مستقلة بالعربية والإنجليزية، وبيانات صفحات مترجمة، وتخطيط من اليمين إلى اليسار عند الحاجة. كما تعكس العملة ومتطلبات التسجيل وشرح الدفع السوق المصري الذي تستهدفه الخدمة حاليًا.
النماذج والتنقّل والتواريخ ورسائل التحقق والتأكيد تحتاج إلى الوضوح نفسه في اللغتين. تبقى قواعد الباقات واحدة، بينما تُكتب الشروح بطريقة طبيعية لكل قارئ. إدراج هذه الحالات في نطاق العمل يمنع أن تبدو الصفحة الرئيسية مكتملة ثم تعيد أول رسالة خطأ المستخدم إلى لغة أخرى.
ما الذي أسأله قبل بناء منتجك؟
- ●من يستخدم المنتج، وما الذي يحق لكل دور رؤيته أو تغييره؟
- ●أي الخطوات آلية، وأيها تحتاج إلى قرار إنسان؟
- ●ما الدليل على نجاح الدفع أو التسليم أو النشر الخارجي؟
- ●ماذا يحدث إذا توقفت خدمة خارجية أثناء الطلب؟
- ●أي الأجزاء يمكن إطلاقها مستقلّة، وكيف نرجع إلى إصدار يعمل؟
تحدد الإجابات نطاق الإصدار الأول. PostedIn مثال على ربط العرض العام بالعمل الأقل ظهورًا اللازم لتقديم الخدمة. إذا كنت تخطط لبوابة عملاء أو منتج SaaS، أرسل لي سير العمل الذي يحتاج منتجك إلى دعمه.