Elevatus منتج حقيقي. يعمل الآن على elevatus.jobs، يتعامل مع التوظيف للعملاء المؤسسيين والوزارات الحكومية عبر الشرق الأوسط. كنت جزءاً من الفريق الذي بنى المعمارية متعددة المستأجرين التي تعمل عليها، خلال وقتي في Talentera بين 2018 و2020. هذه التدوينة تتحدث عن ما يعنيه ذلك فعلاً — ليس حديث تعدد المستأجرين المجرد الذي ستجده في مدونة Stripe الهندسية، بل التفاصيل المحددة المحرجة الجذابة لبناء منصة حيث تشارك وزارة حكومية وسلسلة تجزئة نفس قاعدة الكود ونفس معمارية قاعدة البيانات ونفس محرك سير العمل، ولا يمكن لأي منهما معرفة أن الآخر موجود أبداً.

مشكلة عزل المستأجر ليست في المقام الأول مشكلة بيانات

حين يفكر المهندسون في تعدد المستأجرين، يفكرون في البيانات أولاً: جداول مشتركة مقابل schemas منفصلة مقابل قواعد بيانات منفصلة. هذا حقيقي ومهم. في Elevatus، استخدمنا نموذج عزل على مستوى الصف مع معرّفات المستأجر على كل صف، مدموجاً مع فصل على مستوى schema لبعض جداول التهيئة الحساسة. هذا يمنحك الأساسيات.

المشكلة الصعبة الحقيقية هي الهوية والوصول. ليس “هل يستطيع المستأجر A قراءة بيانات المستأجر B” — ذلك مجرد فلترة للاستعلام. المشكلة الصعبة هي: كيف تدير هوية المستخدم عبر منصة حيث نفس عنوان البريد الإلكتروني قد ينتمي لمرشح وظيفة تقدّم لمناصب في ثلاثة مستأجرين مختلفين؟ ماذا يعني أن يكون ذلك الشخص “مسجّل الدخول”؟ أي تهيئة مستأجر تحكم جلسته؟ ماذا يحدث حين المستأجر A والمستأجر B يشغّلان نفس جولة التوظيف لنفس المنصب، ونفس المرشح تقدّم للاثنين؟

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

الجواب الذي بنيناه حول Keycloak: نموذج هوية مُدمَج حيث لكل مستأجر realm خاص به، مع المرشحين الموجودين كنوع هوية عابرة للـrealm. الملف الشخصي الأساسي للمرشح يعيش في فضاء هوية مشترك. بيانات طلبه تعيش في realm المستأجر. تدفق المصادقة كان محدداً بالمستأجر — لا تستطيع تسجيل الدخول إلى واجهة المستأجر A ببيانات اعتماد المستأجر B — لكن المرشح يمكنه الاحتفاظ بطلبات نشطة عبر مستأجرين متعددين في نفس الوقت دون إنشاء سجلات هوية متعارضة. federation الـrealm وتبادل الرمز المميز عبر الـrealm في Keycloak جعل هذا قابلاً للتنفيذ. بدونها، كنا سنحل federation الهوية يدوياً، وهو النوع من العمل الذي يولّد حوادث أمنية.

ما معنى “مدعوم بالذكاء الاصطناعي” في 2018

عرض Elevatus تضمّن “توظيف مدعوم بالذكاء الاصطناعي”، وهو بيان صحيح في 2018 بنفس الطريقة التي تكون فيها كثير من البيانات الصحيحة أكثر تعقيداً قليلاً مما تبدو.

لم نكن نعمل بنماذج لغوية كبيرة. GPT-3 لم يكن موجوداً بعد. ما كنا نفعله كان مزيجاً من تحليل السير الذاتية وتقييمها بالتعلم الآلي، وترتيب المرشحين بناءً على معايير مُرجَّحة، وتجارب مبكرة مع تحليل مقابلات الفيديو. تحليل السيرة الذاتية كان الجزء الذي عمل جيداً فعلاً في الإنتاج — استخراج بيانات مُهيكلة من سير ذاتية غير مُهيكلة بخمس لغات (العربية والإنجليزية والفرنسية والهندية وعدد من اللغات الأخرى) وتطبيعها في ملف مرشح يستطيع النظام ترتيبه مقابل معايير الوظيفة. التحدي آنذاك لم يكن صعوبة التعلم الآلي — بل كانت بيانات التدريب المُصنَّفة لتحليل السير الذاتية باللغة العربية شحيحة فعلاً، وجودة النموذج كانت تعكس ذلك. بنينا حلقة تغذية راجعة حيث قرارات المُجنِّد (تم التوظيف / رُفض / انتقل للمرحلة التالية) تغذّي نموذج الترتيب مجدداً، مما حسّنه مع الوقت على أساس لكل مستأجر.

هذا الجزء الأخير — تخصيص النموذج لكل مستأجر — كان مثيراً للاهتمام معمارياً ومزعجاً تشغيلياً. متغيّر النموذج لكل مستأجر يعني أن قرارات مُجنِّد وزارة حكومية (حيث تسيطر الامتثال التنظيمي والتحقق من الأوراق الثبوتية على معيار التوظيف) تُشكّل نموذجاً مختلفاً جوهرياً عن النموذج المُدرَّب على قرارات شركة تقنية (حيث تسيطر المحفظة والمهارة المُثبتة). هذه النتيجة الصحيحة. إنها أيضاً مشكلة تخزين وخدمة لا توجد إذا كنت تشغّل نموذجاً عالمياً واحداً فقط. تعدد المستأجرين مُطبَّق على بنية تحتية التعلم الآلي هو مجموعة إضافية كاملة من القيود.

تحليل مقابلات الفيديو كان أقل جاهزية للإنتاج. معالجة اللغة الطبيعية على ردود مقابلة مُسجَّلة بالفيديو، وتوليد تقييمات ملخّصة للمُجنِّدين. نجح. كان أيضاً، بعد التفكير، النوع من الأنظمة الذي يتطلب تصميماً أعمق بكثير حول التحيز والعدالة مما كان لدينا أدوات له في 2018. المجال تطور بشكل كبير. ما سأقوله: كنا نطرح أسئلة “هل يعكس هذا النموذج تنوع مجموعة التوظيف بعدالة” قبل أن تصبح هذه الأسئلة سائدة، لأن عملاءنا طلبوا ذلك — الوزارات الحكومية العاملة بتفويضات التنوع الصريحة ستطرح أسئلة حادة حول مخرجات الذكاء الاصطناعي، و”قال النموذج ذلك” ليس إجابة مقبولة لمكتب وزير.

تنسيق سير العمل لكل مستأجر، لا عالمياً

تكامل Camunda BPMN كان أحد القرارات الهيكلية التي أكثر ما يُرضيني من تلك الفترة. سير عمل التوظيف معقدة فعلاً: لها تفريع شرطي (إذا كان الدور يتطلب تصريح أمني، أضف هذه الخطوات)، ومسارات متوازية (يمكن للفحص التقني وفحص الموارد البشرية التشغيل في وقت واحد)، وحالة تعتمد على الوقت (إذا لم يستجب المرشح في 7 أيام، أطلق تذكيراً، ثم صعّد، ثم أغلق الطلب)، وتختلف اختلافاً جذرياً بين المستأجرين.

سير عمل التوظيف في وزارة حكومية لمنصب في الخدمة المدنية قد يكون من 14 مرحلة وتضم ثلاث لجان موافقة. سير عمل startup قد يكون من 5 مراحل وتستغرق أسبوعاً. لا يمكنك ترميز أي من هذين بشكل صلب. لا يمكنك بناء واجهة قابلة للتهيئة تغطي كليهما. ما تستطيع فعله هو نمذجة كليهما كتعريفات عملية BPMN، وتخزينها لكل مستأجر، والسماح لـCamunda بتنفيذهما بنفس المحرك.

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

مشكلة الإعداد

العملاء المؤسسيون والحكوميون كلاهما لديه عمليات إعداد طويلة مؤلمة. لكنها مؤلمة بطرق مختلفة.

العملاء المؤسسيون يريدون تكاملات: SSO عبر موفّر هوية موجود، webhooks في ATS أو HRIS الخاص بهم، علامة تجارية مخصصة، وصول API لأدواتهم الداخلية. لديهم مطورون. يستطيعون تصحيح حمولة webhook. مشكلة الإعداد هي قابلية التهيئة — كم عدد المقابض التي تعرضها المنصة، وكم هي موثّقة.

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

بناء منصة تستطيع إعداد كلا النوعين في نفس الوقت هو مشكلة منتج ومعمارية لا تُحل بجعل المنصة أكثر قابلية للتهيئة. تحتاج عضلة تنظيمية إلى جانب القدرة التقنية — أشخاص يفهمون المشتريات، يستطيعون إنتاج الوثائق التي تتطلبها مراجعة الأمن الحكومي، يستطيعون ترجمة “نحتاج اتفاقية معالجة بيانات تمتثل للقانون المحلي لسيادة البيانات” إلى قيود فعلية للمنصة. الكود هو الجزء الأسهل.

ما كنت سأفعله بشكل مختلف

طبقة الموبايل — Ionic في البداية، Flutter لاحقاً — أُضيفت كسطح منتج منفصل وظهر ذلك. أنماط تجربة المستخدم في الموبايل أولاً للتوظيف مختلفة فعلاً عن أنماط سطح المكتب. تجربة المرشح على الموبايل (التقديم، تتبع حالة الطلب، إجراء مقابلات فيديو على الهاتف) لها قيود مختلفة عن تجربة المُجنِّد على سطح المكتب (مراجعة مئات المرشحين، اتخاذ قرارات مجمّعة، إدارة جولات التوظيف). بنينا تجربة الموبايل كتكييف لتجربة الويب، مما يعني أنها لم تكن قط جيدة كمنتج ذو أولوية موبايل حقيقية.

لو كنت أصمم هذا اليوم، كانت تجربة المرشح وتجربة المُجنِّد ستُعامَلان كمنتجين منفصلين بقيود تصميم منفصلة، يتشاركان صدفةً backend. طبقة الـAPI كانت ستُصمَّم مع كلا المستهلكين في الحسبان من البداية، لا مُضافة لاحقاً لدعم الموبايل. هذا الدرس القياسي عن “API-first” الذي يتعلمه الجميع بالطريقة الصعبة مرة واحدة.

الحكومات تستخدم Elevatus فعلاً. هذه الجملة تبدو مختلفة بعد المرور بعملية المشتريات، ومراجعات الأمن، ومفاوضات التخصيص، وعمل التكامل الذي يتطلبه الوصول إلى “يستخدمون فعلاً.” إنها ليست MVP يستخدمه متبنٍّ ودود مبكر. إنها برمجيات إنتاج تُشغّل عمليات حرجة لمؤسسات لا تتحمل وقت التوقف.

هذا ما بنيت.