للطلاب والخريجين الأدلة التقنية

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

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

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

في آخر لقاء قبل نهاية الفصل قال لك المشرف جملة واحدة: «أريد منكم ثلاث أفكار لمشروع التخرج الأسبوع القادم، وكل فكرة في صفحة». فخرجت أنت وزملاؤك الثلاثة من مكتبه وفتحتم مجموعة المحادثة، فاقترح أحدكم نظام حضور بالبصمة، واقترح الثاني متجراً إلكترونياً، واقترح الثالث «تطبيق ذكاء اصطناعي»، ثم سكتت المجموعة. والمشكلة أن هذه الأفكار ليست سيئة لأنها صعبة أو سهلة، وإنما لأنها لا تقول شيئاً عن تخصصكم، فطالب تقنية المعلومات Information Technology يفترض أن يقدم مشروعاً يظهر أنه يعرف كيف يبني الأنظمة ويشغلها ويحافظ عليها لمستخدمين حقيقيين، وليس أنه يعرف كيف يكتب شاشة تسجيل دخول.

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

وسوف نناقش في هذا المقال ما يلي:

  • الفرق بين مشروع البكالوريوس ورسالة الماجستير في نظر اللجنة.
  • ما الذي يجعل الفكرة فكرة تقنية معلومات، وكيف تصفي أفكارك في أسبوع واحد بستة أسئلة.
  • تسع أفكار للبكالوريوس: المراقبة، والنسخ الاحتياطي، والدخول الموحد، ومكتب الخدمة، وقياس Wi-Fi، ومنصة التطوير الداخلية، والمعمل بالكود، وخدمة فوق البيانات المفتوحة، والمساهمة في مشروع مفتوح المصدر.
  • ست أفكار للماجستير بأسئلة بحثية قابلة للقياس.
  • الأفكار المستهلكة التي تعب منها المشرفون، وكيف تحول واحدة منها إلى مشروع حقيقي.
  • جدول مقارنة لكل الأفكار بالمستوى والصعوبة وتوفر البيانات والمهارات.
  • تجربة عملية Lab: مراقب صغير بلغة Python يقيس خدمات البيانات المفتوحة، ومشكلة حقيقية ظهرت فيه، وماذا يحدث إذا غيرنا المهلة.
  • كيف تعرض الأفكار الثلاث على المشرف، وأخطاء شائعة، وقائمة تحقق.

ما الفرق بين مشروع البكالوريوس Bachelor ورسالة الماجستير Master؟

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

أما رسالة الماجستير فيعمل عليها باحث واحد في الغالب، ولمدة سنة أو سنتين، والمطلوب منها شيء مختلف تماماً، وهو الإجابة عن سؤال بحثي Research Question لم يجب عنه أحد بنفس الشكل. والرسالة لا تقيم بحجم النظام الذي بنيته، وإنما بثلاثة أشياء: هل قرأت الأعمال السابقة Related Work وعرفت أين توقفت؟ وما الإضافة Novelty التي قدمتها، ولو كانت صغيرة مثل تطبيق أسلوب معروف في بيئة لها قيد محلي؟ وهل التقييم قابل للتكرار، أي فيه خط أساس Baseline تقارن به، وتجارب مكررة، وبيانات وكود يستطيع غيرك أن يعيد بها النتيجة؟

لوحة من عمودين: عمود البكالوريوس Bachelor بأربعة بنود هي المشكلة والمستخدم، والنطاق المناسب للفريق، والبناء والتشغيل، والتقييم بالأرقام، وتحته سؤال اللجنة هل يعمل ومن استخدمه وكيف قسته، وعمود الماجستير Master بأربعة بنود هي السؤال البحثي، والأعمال السابقة، والإضافة، والتقييم القابل للتكرار، وتحته سؤال اللجنة ما الجديد وكيف تعرف أنه أفضل
مشروع البكالوريوس نظام يعمل ويقاس، ورسالة الماجستير سؤال يجاب عنه بقياس يقبل التكرار

وقد يتساءل البعض: إذا كانت الفكرة واحدة فما الذي يتغير؟ لنأخذ مثالاً المراقبة Monitoring، فمشروع البكالوريوس فيها أن تبني لجمعية خيرية منصة مراقبة تنبه الفني قبل أن يتصل به الموظفون، وتقيس كم دقيقة اختصرت من زمن اكتشاف العطل. أما سؤال الماجستير في نفس المجال فقد يكون: هل تكتشف الفحوص الاصطناعية Synthetic Checks أعطال الخدمات الحكومية الرقمية أسرع من قياس تجربة المستخدم الحقيقي، وبأي نسبة من الإنذارات الكاذبة؟ والفرق أن الأول يسلم نظاماً لمستخدم، والثاني يسلم إجابة لمجتمع بحثي. وسوف ترى في المقال أن أغلب أفكار البكالوريوس لها أخت في الماجستير، ولهذا السبب رتبناها في خريطة واحدة.

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

ما الذي يجعل الفكرة فكرة تقنية معلومات IT؟

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

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

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

كيف تصفي أفكارك في أسبوع واحد؟ ستة أسئلة Idea Filter

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

  • المشكلة Problem: اكتبها في جملة واحدة فيها جهة وألم يمكن قياسه، مثل «فني المدرسة يعرف بانقطاع نظام الدرجات من اتصالات المعلمين»، وليس «نظام لإدارة الشبكة».
  • المستخدم User: شخص تستطيع أن تقابله هذا الأسبوع، فإذا لم تجد أحداً يجرب الحل فلن تجد من يقيمه في نهاية الفصل.
  • البيانات Data: مصدر حقيقي فتحته بنفسك، وعرفت حجمه وترخيصه، وليس «سنجمع البيانات لاحقاً»، والسبب أن البيانات هي أكثر ما يتأخر في المشاريع.
  • التقييم Evaluation: رقم قبل ورقم بعد، مثل زمن الاستعادة RTO أو متوسط زمن اكتشاف العطل MTTD أو نسبة التذاكر التي حلت ضمن اتفاقية مستوى الخدمة SLA.
  • المخاطرة Risk: الشيء الوحيد الذي إن فشل انتهى المشروع، مثل صلاحية الوصول إلى شبكة الجامعة أو موافقة الجهة على بياناتها.
  • التميز Stand-out: ما الذي يجعل مشروعك مختلفاً عن مشروع الدفعة السابقة الموجود في مستودع القسم.
ستة مربعات متتالية لأيام الأسبوع، في كل منها سؤال: المشكلة Problem، والمستخدم User، والبيانات Data، والتقييم Evaluation، والمخاطرة Risk، والتميز Stand-out، وتحت كل سؤال سبب سقوط الفكرة فيه بلون أحمر، وفي الأسفل مربع أخضر لليوم السابع: نموذج صغير Feasibility Spike يجلب البيانات الحقيقية ويحسب رقماً واحداً، ومربع أحمر لما يرفضه المشرف عادة
ستة أسئلة في ستة أيام، ثم نموذج صغير لأقوى فكرة في اليوم السابع

وفي اليوم السابع خذ أقوى فكرة واكتب لها نموذجاً صغيراً Feasibility Spike، وهو برنامج قصير يثبت أن أصعب جزء في الفكرة ممكن: يجلب البيانات الحقيقية، أو يتصل بالخدمة، أو يقيس رقماً واحداً. وهذا ما سوف نفعله في التجربة العملية في آخر المقال، وسوف ترى أن ساعتين من التجربة كشفتا مشكلة لم تكن لتظهر في أي مقترح مكتوب. والمشرف الذي يرى أمامه مخرجاً حقيقياً يتعامل معك بشكل مختلف تماماً عن المشرف الذي يقرأ «سوف نقوم ببناء نظام متكامل».

خريطة الأفكار Idea Map: خمس عشرة فكرة في سبعة مجالات

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

خريطة من سبعة مربعات للمجالات: التشغيل والمراقبة وفيه B1 مراقبة خدمات جهة صغيرة وM1 المراقبة الاصطناعية مقابل المستخدم الحقيقي وM2 أخذ العينات في التتبع، والاستمرارية وفيه B2 نسخ احتياطي واستعادة مختبرة، والهوية والحسابات وفيه B3 دخول موحد لجمعية خيرية، وإدارة الخدمات وفيه B4 مكتب خدمة بمؤشرات SLA وM3 تنقيب عملية الحوادث، والشبكات وفيه B5 قياس شبكة الحرم وM6 شبكة عالية الكثافة، والمنصات والسحابة وفيه B6 منصة تطوير وتشغيل للقسم وB7 معمل افتراضي بالكود وM4 التكلفة الكلية مع إقامة البيانات وM5 جدولة واعية بالطاقة، والبيانات المفتوحة والمصدر المفتوح وفيه B8 خدمة فوق منصة البيانات المفتوحة وB9 تعريب أداة تشغيل مفتوحة المصدر
تسع أفكار للبكالوريوس وست للماجستير، وأغلب المجالات فيها فكرة من المستويين

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

أفكار البكالوريوس Bachelor Projects: تسع أفكار لفريق وفصلين

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

B1: مراقبة خدمات جهة صغيرة Monitoring قبل أن يتصل المستخدم

Project title: Proactive Service Monitoring for a Small Organization

في أغلب الجهات الصغيرة يعرف الفني بالعطل من أول موظف يتصل به، فالموقع متوقف منذ ساعة، والشهادة انتهت أمس، والقرص امتلأ قبل أسبوع، ولا أحد يعرف حتى يشتكي المستخدم. ومشروعك هنا أن تبني للجهة منصة مراقبة تكتشف العطل قبل المستخدم، ولكن بالطريقة الصحيحة، أي أن تبدأ من الإشارات التي يقترحها كتاب مراقبة الأنظمة الموزعة من Google SRE: زمن الاستجابة Latency، وحجم الطلبات Traffic، ونسبة الأخطاء Errors، والتشبع Saturation، ثم تحدد لكل خدمة هدف مستوى الخدمة SLO وتنبه عليه وليس على كل رقم يتحرك. وقد شرحنا الأساس في مفاهيم المراقبة Observability، وهذه هي الفكرة التي سوف نبني لها النموذج الصغير في التجربة العملية.

  • المشكلة: الجهة تعرف بالأعطال من شكاوى المستخدمين، ولا تملك أرقاماً عن إتاحة خدماتها.
  • من يستخدمه: فني تقنية المعلومات في مدرسة أو عيادة أو جمعية، ومديرها الذي يريد تقريراً شهرياً.
  • النطاق للفريق: عضو للفحوص الخارجية (HTTP وDNS والشهادات)، وعضو لمقاييس السيرفرات، وعضو لجمع السجلات Logs، وعضو للتنبيهات وقواعدها، وعضو للوحات والتقرير الشهري.
  • الأدوات المقترحة: Prometheus مع blackbox_exporter للفحوص، وGrafana للوحات، وAlertmanager للتنبيه، وUptime Kuma إذا أرادت الجهة واجهة بسيطة، وGrafana Loki للسجلات.
  • البيانات: قياساتك أنت على خدمات الجهة، ويمكن أن تبدأ قبل موافقة الجهة بقياس خدمات عامة مثل منصة البيانات المفتوحة كما سنفعل في التجربة العملية.
  • التقييم: متوسط زمن الاكتشاف MTTD قبل المشروع وبعده، ونسبة التنبيهات الكاذبة False Positives، وأعطال تصطنعها بنفسك Fault Injection وتقيس متى اكتشفتها المنصة.
  • الصعوبة: متوسطة.
  • المخاطرة التي تنهيه: أن يمر الفصل دون أي عطل حقيقي فلا يكون لديك ما تقيسه، والحل أن تخطط من البداية لأعطال مصطنعة موثقة.
  • كيف يتميز: فحص المحتوى وليس رمز الحالة فقط، وتنبيه مبني على ميزانية الأخطاء Error Budget كما في دليل التنبيه على SLO، وتقرير شهري يفهمه المدير.

B2: نسخ احتياطي Backup واستعادة مختبرة لمدرسة أو عيادة

Project title: Tested Backup and Restore for a School or Clinic

اسأل أي جهة صغيرة: هل عندكم نسخة احتياطية؟ وسوف تسمع «نعم» في الغالب. ثم اسأل: متى آخر مرة استعدتم منها؟ وسوف تسمع صمتاً. وهذا هو المشروع، فالنسخة التي لم تختبر استعادتها ليست نسخة، وإنما أمل. ومشروعك أن تطبق قاعدة 3-2-1 على بيانات الجهة، أي ثلاث نسخ على وسيطين ونسخة خارج المكان، ثم تبني فوقها ما لا يبنيه أحد عادة: استعادة آلية دورية تتحقق من أن الملفات وقاعدة البيانات تعود فعلاً، وتسجل كم أخذت من الوقت. وقد شرحنا القاعدة في النسخ الاحتياطي بقاعدة 3-2-1، وقارنا الأدوات في restic أم Borg أم Kopia.

  • المشكلة: بيانات المرضى أو الطلاب أو الحسابات في جهاز واحد أو حساب سحابي واحد، ولا أحد يعرف كم تحتاج استعادتها.
  • من يستخدمه: مدير العيادة أو المدرسة، والفني الذي سيستلم النظام بعدك.
  • النطاق للفريق: عضو لجرد البيانات وتصنيفها، وعضو للنسخ وجدولته، وعضو للنسخة خارج المكان وتشفيرها، وعضو للاستعادة الآلية والتقرير.
  • الأدوات المقترحة: restic أو Kopia أو Borg، ومخزن متوافق مع S3 على سيرفر ثان كما في تخزين الكائنات S3 على سيرفرك.
  • البيانات: بيانات تجريبية بحجم بيانات الجهة الحقيقي وبنيتها، لأن الجهة الصحية لن تعطيك سجلات المرضى، ولا يجب أن تطلبها.
  • التقييم: نقطة الاستعادة المستهدفة RPO وزمن الاستعادة المستهدف RTO قبل وبعد، وحجم التخزين بعد إزالة التكرار Deduplication، ونسبة نجاح الاستعادة الآلية خلال شهر.
  • الصعوبة: سهلة إلى متوسطة، وتصبح متوسطة إذا شملت قاعدة بيانات تعمل أثناء النسخ.
  • المخاطرة التي تنهيه: أن تطلب بيانات حقيقية حساسة فتتأخر الموافقة حتى نهاية الفصل، والحل بيانات تجريبية بنفس الشكل من اليوم الأول.
  • كيف يتميز: تمرين استعادة كامل أمام اللجنة، تحذف فيه السيرفر وتعيده وتعرض الزمن الحقيقي.

B3: الدخول الموحد SSO وإدارة الحسابات لجمعية خيرية

Project title: Single Sign-On and Account Management for a Nonprofit

الجمعية الخيرية النموذجية فيها بريد، ومجلد ملفات مشترك، ونظام للمتطوعين، وموقع، وكل نظام بحسابه وكلمة مروره، وعندما يغادر متطوع لا أحد يعرف أين حساباته كلها. ومشروعك أن تبني لها مزود هوية Identity Provider واحداً، يدخل منه الموظف إلى كل الأنظمة، وتنشئ حسابه وتلغيه من مكان واحد. وقد شرحنا المفاهيم في ما هو الدخول الموحد SSO، وتثبيت Keycloak وauthentik، وربط المعلمين والطلاب بـ Moodle في دخول موحد مع Moodle.

  • المشكلة: حسابات موزعة على أنظمة كثيرة، وحسابات متطوعين سابقين ما زالت تعمل.
  • من يستخدمه: موظفو الجمعية ومتطوعوها، ومسؤول تقنية المعلومات فيها.
  • النطاق للفريق: عضو لمزود الهوية وإعداده، وعضو لربط الأنظمة بـ OIDC أو SAML، وعضو لدورة حياة الحساب من الانضمام إلى المغادرة، وعضو لتجربة المستخدم والتوثيق بالعربية.
  • الأدوات المقترحة: Keycloak أو authentik، وNextcloud للملفات، وSCIM للتزويد الآلي كما في ما هو SCIM.
  • البيانات: قائمة الأنظمة والحسابات الحالية من الجهة نفسها، بعد إخفاء الأسماء.
  • التقييم: زمن إنشاء حساب موظف جديد وزمن إلغائه قبل وبعد، وعدد كلمات المرور التي يحفظها الموظف، وعدد الحسابات اليتيمة Orphaned Accounts التي اكتشفتها.
  • الصعوبة: متوسطة.
  • المخاطرة التي تنهيه: نظام مهم في الجمعية لا يدعم OIDC ولا SAML، فاكتشف ذلك في الأسبوع الأول قبل أن تعد بربطه.
  • كيف يتميز: تقرير مغادرة آلي يثبت أن حسابات الموظف المغادر أغلقت كلها خلال دقائق.

B4: مكتب خدمة Helpdesk بمؤشرات SLA لقسم الجامعة

Project title: IT Helpdesk with SLA Metrics for a University Department

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

  • المشكلة: لا توجد أرقام عن طلبات الدعم، والطلبات تضيع بين القنوات.
  • من يستخدمه: فنيو الدعم في الكلية، والطلاب والموظفون الذين يرفعون الطلبات.
  • النطاق للفريق: عضو لإعداد النظام وفئاته، وعضو لقنوات الاستقبال (البريد ونموذج الويب)، وعضو لقاعدة المعرفة، وعضو للوحات المؤشرات وتقرير SLA.
  • الأدوات المقترحة: Zammad أو GLPI.
  • البيانات: سجل حوادث حقيقي منشور على مستودع UCI من منصة ServiceNow لشركة تقنية، فيه 141,712 حدثاً لـ 24,918 حادثة و36 حقلاً، منها الأولوية وعدد مرات إعادة الإسناد وهل التزمت الحادثة بالـ SLA، وترخيصه CC BY 4.0، تستخدمه لتجربة اللوحات وقواعد التصعيد قبل أن تصل بيانات القسم.
  • التقييم: زمن أول رد وزمن الحل لكل فئة، ونسبة الالتزام بالـ SLA، ونسبة الطلبات التي حلت من قاعدة المعرفة دون فني.
  • الصعوبة: سهلة إلى متوسطة.
  • المخاطرة التي تنهيه: أن لا يستخدم الفنيون النظام ويستمروا في الواتساب، لذلك اجعل استقبال الرسائل من القناة التي يستخدمونها جزءاً من النطاق.
  • كيف يتميز: إعادة تشغيل سجل UCI على نظامك لقياس أثر قواعد التصعيد قبل تطبيقها على القسم.

B5: قياس شبكة Wi-Fi في الحرم Site Survey قبل التعديل وبعده

Project title: Campus Wi-Fi Site Survey Before and After Changes

كل طالب لديه رأي في شبكة الجامعة، ولكن قليلاً من يملك أرقاماً. ومشروعك أن تقيس الشبكة اللاسلكية في مبنى واحد بطريقة منهجية: سرعة التنزيل والرفع، وزمن الاستجابة، وقوة الإشارة، في نقاط محددة وأوقات محددة، ثم ترسم خريطة حرارية Heatmap، وتقترح تعديلاً مع فريق تقنية المعلومات في الجامعة مثل تغيير القنوات أو مكان نقطة وصول، ثم تقيس مرة أخرى. ونفس الفكرة تصلح لجهات تحتاج شبكة مؤقتة كثيفة، مثل مخيمات الحج والعمرة والفعاليات الكبيرة، حيث يتصل آلاف الأشخاص في مساحة صغيرة لأيام قليلة. وإذا وصلت إلى المصادقة فقد شرحنا Wi-Fi للمؤسسات مع FreeRADIUS وبوابة الدخول Captive Portal.

  • المشكلة: شكاوى عن بطء الشبكة دون قياس يحدد أين وفي أي وقت.
  • من يستخدمه: إدارة تقنية المعلومات في الجامعة، والطلاب في المبنى.
  • النطاق للفريق: عضو لخطة القياس ونقاطها، وعضو لأداة القياس الآلية، وعضو لقاعدة البيانات والخريطة، وعضو لتحليل ما قبل وبعد والتقرير.
  • الأدوات المقترحة: iperf3 مع سيرفر داخل الشبكة، وسكربت قياس على أجهزة محمولة، وGrafana للوحة.
  • البيانات: قياساتك أنت، ومعها بيانات Ookla المفتوحة لسرعات الإنترنت في مربعات بطول نحو 610 أمتار، تحدث كل ربع سنة منذ 2019، لتقارن تجربة الحرم بما حوله، وترخيصها CC BY-NC-SA 4.0 أي أنها للاستخدام غير التجاري.
  • التقييم: المئين 95 لزمن الاستجابة p95 والسرعة الوسيطة في كل نقطة قبل وبعد التعديل، ونسبة النقاط التي تحقق حداً متفقاً عليه.
  • الصعوبة: متوسطة.
  • المخاطرة التي تنهيه: أن لا توافق إدارة تقنية المعلومات على أي تعديل، فيبقى المشروع قياساً بلا تحسين، فاحصل على الموافقة قبل التسجيل.
  • كيف يتميز: قياس متكرر آلي في أوقات الذروة بدل قياس يدوي مرة واحدة.

B6: منصة تطوير وتشغيل داخلية Internal DevOps Platform للقسم

Project title: Internal DevOps Platform for an Academic Department

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

  • المشكلة: مشاريع الطلاب لا تعمل بعد التسليم، والمشرف لا يستطيع أن يرى تاريخ العمل.
  • من يستخدمه: طلاب القسم ومشرفوهم، والفني الذي يدير المعامل.
  • النطاق للفريق: عضو لمستودع الكود والحسابات، وعضو لخطوط البناء Pipelines والـ Runners، وعضو لبيئات النشر والعزل، وعضو للحصص Quotas والمراقبة.
  • الأدوات المقترحة: Gitea مع Gitea Actions أو Woodpecker CI، وDocker، ومزود الهوية الذي في الجامعة.
  • البيانات: سجلات استخدام المنصة نفسها خلال فصل تجريبي مع مادة واحدة.
  • التقييم: زمن الانتقال من الدفع Push إلى النشر، وعدد المشاريع التي ما زالت تعمل بعد شهر من التسليم، ورضا المشرفين.
  • الصعوبة: متوسطة إلى صعبة.
  • المخاطرة التي تنهيه: أن لا تجد مادة توافق على التجربة، فاتفق مع أستاذ مادة قبل بداية الفصل.
  • كيف يتميز: قالب مشروع جاهز يحصل منه الطالب على مستودع وخط بناء ورابط نشر في دقيقة.

B7: معمل افتراضي بالكود Infrastructure as Code يعاد بناؤه في دقائق

Project title: Rebuildable Virtual Lab with Infrastructure as Code

معامل الشبكات والأنظمة في الجامعة تعد يدوياً قبل كل فصل، فيقضي الفني أياماً في تثبيت الأجهزة الافتراضية وإعدادها، ثم يغير الطلاب فيها ما يغيرون فلا تعود كما كانت. ومشروعك أن تكتب المعمل كله كوداً، أي أن تصف الأجهزة والشبكات والإعدادات في ملفات في Git، وتعيد بناء المعمل لكل شعبة بأمر واحد. وقد شرحنا المفهوم في البنية كشيفرة IaC، وقصة Terraform وOpenTofu، وأول جهاز افتراضي في Proxmox.

  • المشكلة: تجهيز المعمل يدوي وبطيء، ولا يمكن إعادته لحالته الأولى.
  • من يستخدمه: فنيو المعامل وأساتذة مواد الشبكات والأنظمة.
  • النطاق للفريق: عضو لطبقة الأجهزة الافتراضية، وعضو للشبكات والعزل بين الشعب، وعضو لإعداد الأنظمة بـ Ansible، وعضو لبوابة يطلب منها الأستاذ معمله.
  • الأدوات المقترحة: Proxmox VE وOpenTofu وAnsible.
  • البيانات: قائمة معامل مادتين حقيقيتين في القسم بأجهزتها وإعداداتها.
  • التقييم: زمن تجهيز معمل كامل يدوياً مقابل الكود، وعدد الفروقات بين معملين بنيا من نفس الكود (المفروض صفر)، وزمن إعادة معمل إلى حالته الأولى.
  • الصعوبة: متوسطة إلى صعبة.
  • المخاطرة التي تنهيه: عدم وجود سيرفر يكفي، فاتفق على العتاد مع القسم مبكراً، أو ابدأ بمعمل صغير على جهاز واحد.
  • كيف يتميز: اختبار آلي بعد كل بناء يتحقق أن كل جهاز يصل إلى ما يجب أن يصل إليه ولا يصل إلى غيره.

B8: خدمة فوق منصة البيانات المفتوحة Open Data Service

Project title: Open Data Service with Freshness Monitoring and Change Detection

منصة البيانات المفتوحة الوطنية فيها عشرات الآلاف من مجموعات البيانات من جهات حكومية مختلفة، ففي يوم كتابة هذا المقال أرجعت واجهة التصنيفات فيها 51 تصنيفاً، ومجموع حقل عدد مجموعات البيانات فيها 32,965. ولكن من يريد أن يبني تطبيقاً على هذه البيانات يواجه أسئلة تشغيلية: هل تحدثت البيانات؟ وهل تغيرت أعمدتها؟ وهل الخدمة متاحة الآن؟ ومشروعك أن تبني خدمة وسيطة تجلب مجموعات بيانات محددة في مجال واحد، مثل التعليم أو الصحة، وتحفظ نسخها بتواريخها، وتنبه المشتركين عند تغير البيانات أو بنيتها، وتراقب إتاحة المصدر. والتجربة العملية في هذا المقال هي الخطوة الأولى في هذا المشروع أيضاً.

  • المشكلة: المطور أو الباحث لا يعرف متى تحدثت البيانات ولا متى تغيرت بنيتها، فيتعطل تطبيقه دون أن يعرف السبب.
  • من يستخدمه: الباحثون والمطورون والصحفيون الذين يبنون على البيانات الحكومية.
  • النطاق للفريق: عضو لجلب البيانات ونسخها، وعضو لاكتشاف التغيير في البيانات وبنيتها، وعضو للواجهة البرمجية API والبحث بالعربية، وعضو للمراقبة والتنبيهات.
  • الأدوات المقترحة: Python لجلب البيانات، وPostgreSQL للتخزين، ومحرك بحث عربي كما في البحث في النصوص العربية.
  • البيانات: منصة البيانات المفتوحة وموقع الهيئة العامة للإحصاء.
  • التقييم: زمن اكتشاف تحديث البيانات من لحظة نشرها، ونسبة التغييرات في البنية التي اكتشفت، وزمن استجابة الواجهة مقارنة بالمصدر.
  • الصعوبة: متوسطة.
  • المخاطرة التي تنهيه: شروط الوصول، فالمنصة أمامها جدار تطبيقات ويب WAF يرفض بعض العملاء كما سنرى في التجربة، وواجهاتها الداخلية غير موثقة للعامة، لذلك راجع شروط الاستخدام واطلب الوصول الرسمي إلى الواجهات البرمجية من البداية، ولا تبن مشروعك على تجاوز أي حماية.
  • كيف يتميز: سجل تاريخي لتغير مجموعات البيانات لا يوفره المصدر نفسه.

B9: المساهمة في مشروع مفتوح المصدر Open Source Contribution

Project title: Arabic Localization Contribution to an Open Source Tool

هذه فكرة يتجاهلها أغلب الطلاب، مع أنها من أقوى ما يمكن أن تضعه في سيرتك الذاتية، لأن عملك يبقى منشوراً باسمك في مشروع يستخدمه آلاف الناس، ويراجعه مطورون محترفون قبل قبوله. ومشروعك أن تختار أداة تشغيل مفتوحة المصدر تستخدمها الجهات، وتحسن دعمها للعربية، أي الترجمة والاتجاه من اليمين لليسار RTL والتواريخ والأرقام، ثم تصلح أخطاء حقيقية في قائمة المشروع. فمثلاً Uptime Kuma يترجم عبر منصة Weblate الخاصة به ويشرح طريقة المساهمة في دليل المساهمة، وNetBox لتوثيق الشبكات له دليل مساهمة واضح أيضاً. وقبل أن تبدأ اقرأ تراخيص البرمجيات مفتوحة المصدر، والتعريب والنص ثنائي الاتجاه.

  • المشكلة: أدوات تشغيل تستخدمها الجهات المحلية بواجهة عربية ناقصة أو اتجاهها خاطئ.
  • من يستخدمه: كل من يستخدم الأداة بالعربية، ومشرفو المشروع.
  • النطاق للفريق: عضو للترجمة ومراجعتها، وعضو لأخطاء الاتجاه في الواجهة، وعضو لتنسيق التواريخ والأرقام، وعضو للاختبارات والتوثيق، ويمكن أن يكون الفريق أصغر هنا.
  • الأدوات المقترحة: Git وGitHub، وبيئة المشروع نفسه.
  • البيانات: قائمة المشكلات Issues المفتوحة في المشروع، وسجل مساهماتك.
  • التقييم: عدد طلبات الدمج Pull Requests المقبولة، ونسبة الترجمة العربية قبل وبعد، وعدد أخطاء الاتجاه المغلقة، وتجربة مستخدمين قبل وبعد.
  • الصعوبة: متوسطة، والصعوبة الحقيقية في التواصل مع المشرفين على المشروع وانتظار مراجعتهم.
  • المخاطرة التي تنهيه: أن لا يراجع أحد مساهماتك قبل نهاية الفصل، لذلك اختر مشروعاً نشطاً يرد على طلبات الدمج خلال أيام، وراجع ذلك في سجله قبل الاختيار.
  • كيف يتميز: رابط لكل مساهمة مقبولة في التقرير، وهذا دليل لا يستطيع أحد التشكيك فيه.

أفكار الماجستير Master Research: ستة أسئلة بحثية قابلة للقياس

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

M1: هل تكتشف الفحوص الاصطناعية Synthetic Monitoring الأعطال أسرع من قياس المستخدم الحقيقي RUM؟

Project title: Synthetic Monitoring Versus Real User Monitoring for Outage Detection

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

  • الأعمال السابقة: ابدأ من فصول المراقبة في كتاب Google SRE وفصل أهداف مستوى الخدمة، ثم ابحث عن دراسات مقارنة بين الأسلوبين.
  • الإضافة الممكنة: نموذج أعطال موثق (بطء في السيرفر، وفشل DNS، وانتهاء شهادة، وصفحة رفض بحالة 200 مثل التي سنراها في التجربة) وقياس زمن اكتشاف كل نوع بكل أسلوب.
  • الأدوات: blackbox_exporter أو مراقب مكتوب بيدك، ومكتبة قياس في المتصفح، وبيئة تجريبية تحقن فيها الأعطال.
  • البيانات: سجلاتك من بيئة الاختبار، وحركة مستخدمين مولدة بأداة مثل k6.
  • التقييم: زمن الاكتشاف لكل نوع عطل، ونسبة الإنذارات الكاذبة، وكلفة كل أسلوب بعدد الطلبات والتخزين.
  • الصعوبة: متوسطة.
  • المخاطرة: أن تكون الأعطال المصطنعة بعيدة عن الواقع، فاربط كل نوع بتقرير حادثة منشور.

M2: كم تخسر من الأعطال عندما تأخذ عينة من التتبع Trace Sampling؟

Project title: The Impact of Trace Sampling on Failure Detection

التتبع الموزع Distributed Tracing يسجل مسار كل طلب بين الخدمات، ولكنه مكلف في التخزين، لذلك تأخذ أغلب الأنظمة عينة، إما في بداية الطلب Head Sampling بنسبة ثابتة، أو بعد انتهائه Tail Sampling بحسب نتيجته. والسؤال البحثي: لجهة صغيرة بميزانية تخزين محدودة، كم تخسر من الطلبات البطيئة والفاشلة عند كل نسبة وكل أسلوب، وأين النقطة التي تتوازن فيها الكلفة مع القدرة على التشخيص؟ وقد شرحنا الأساس في التتبع الموزع مع OpenTelemetry، والكلفة في تكلفة المراقبة.

  • الأعمال السابقة: توثيق أخذ العينات في OpenTelemetry ومعالج Tail Sampling في الـ Collector.
  • الإضافة الممكنة: منحنى الكلفة مقابل نسبة الأعطال المحفوظة لتطبيق حقيقي متعدد الخدمات، بأنماط أعطال مختلفة.
  • الأدوات: تطبيق OpenTelemetry التجريبي فيه خدمات بلغات مختلفة وأعطال يمكن تشغيلها، والـ Collector، ومخزن للتتبع.
  • البيانات: التتبع الذي يولده التطبيق التجريبي تحت حركة مولدة.
  • التقييم: نسبة الطلبات الفاشلة والبطيئة المحفوظة، وحجم التخزين، والذاكرة التي يستهلكها الـ Collector.
  • الصعوبة: متوسطة إلى صعبة.
  • المخاطرة: موارد الجهاز، فالتطبيق التجريبي فيه خدمات كثيرة، فتأكد من حجم الذاكرة المطلوب قبل التسجيل.

M3: أين تتأخر الحوادث؟ تنقيب العمليات Process Mining في سجل ITSM

Project title: Process Mining of Incident Resolution Delays in ITSM Logs

كل حادثة في مكتب الخدمة تمر بحالات: فتحت، وأسندت، وأعيد إسنادها، وانتظرت المستخدم، وحلت، وأغلقت، وأحياناً أعيد فتحها. وتنقيب العمليات يأخذ هذه الأحداث ويرسم العملية كما حدثت فعلاً، وليس كما رسمت في الإجراءات. والسؤال البحثي: ما أنماط المسار التي ترتبط بعدم الالتزام بالـ SLA، وهل إعادة الإسناد أكثر من مرة هي السبب الرئيسي كما يفترض أغلب مديري الدعم؟

  • الأعمال السابقة: أعمال تنقيب العمليات على سجلات الحوادث، وابدأ من موقع مجتمع تنقيب العمليات.
  • الإضافة الممكنة: مقارنة نتائج سجل عام بسجل مكتب خدمة محلي بعد إخفاء الهوية، أو اختبار قاعدة تصعيد مقترحة بمحاكاة على السجل.
  • الأدوات: مكتبة pm4py في Python.
  • البيانات: سجل حوادث ServiceNow على UCI بـ 141,712 حدثاً و24,918 حادثة، وفيه حقول عدد إعادة الإسناد وعدد إعادة الفتح والالتزام بالـ SLA.
  • التقييم: مدى مطابقة النموذج المكتشف للسجل Conformance، والفرق في نسبة الالتزام بين الأنماط مع اختبار إحصائي.
  • الصعوبة: متوسطة.
  • المخاطرة: أن تتحول الرسالة إلى رسالة تعلم آلة تتنبأ بالالتزام، فأبقها على تحليل العملية وقراراتها، وإلا فهي أقرب إلى مسار علم البيانات.

M4: التكلفة الكلية TCO للاستضافة الذاتية مقابل السحابة مع إقامة البيانات داخل المملكة

Project title: Total Cost of Ownership: Self-Hosting Versus Cloud Under Saudi Data Residency

الجهة الصغيرة التي تتعامل مع بيانات شخصية عليها أن تلتزم بنظام حماية البيانات الشخصية، وقد يدفعها ذلك إلى إبقاء البيانات داخل المملكة، فتسأل: هل أستضيف بنفسي، أم أستأجر من مزود سحابي له مركز بيانات محلي، أم أجمع بينهما؟ والسؤال البحثي: ما نموذج التكلفة الكلية Total Cost of Ownership لثلاث سنوات لجهة من 20 إلى 200 مستخدم، بعد احتساب العمالة والنسخ الاحتياطي والتوافرية ومتطلبات الإقامة، وأين نقطة التحول بين الخيارات؟ وقد ناقشنا جوانب منه في السحابة ليست دائماً الأرخص وPDPL للخدمات المستضافة والاستضافة الذاتية كخيار استراتيجي.

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

M5: جدولة واعية بالطاقة Energy-aware Scheduling في مركز بيانات صغير

Project title: Energy-Aware Scheduling in a Small Data Center

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

  • الأعمال السابقة: أبحاث جدولة المهام وتجميع الأجهزة الافتراضية Consolidation في مراكز البيانات.
  • الأدوات: محاكي تكتبه بنفسك في Python، أو محاكي منشور، ثم تجربة صغيرة على سيرفرات حقيقية في المعمل.
  • البيانات: بيانات تجمعات Google، ونسخة 2019 منها تغطي ثماني تجمعات Borg خلال مايو 2019 بحجم نحو 2.4 تيرابايت مضغوطة ومتاحة عبر BigQuery فقط كما يذكر توثيقها، لذلك خذ منها عينة، ومعها سجلات استخدام سيرفرات الجامعة إن وافقت.
  • التقييم: الطاقة الموفرة بالنسبة المئوية، والمئين 95 لزمن انتظار المهام، وعدد مرات تشغيل السيرفرات وإطفائها.
  • الصعوبة: صعبة.
  • المخاطرة: حجم البيانات وكلفة الاستعلام عليها، فحدد العينة في المقترح.

M6: شبكة Wi-Fi عالية الكثافة High-Density: أي إعداد يحسن زمن الاستجابة؟

Project title: Configuration Tuning for Latency in High-Density Wi-Fi Networks

قاعة محاضرات فيها 200 طالب، أو مخيم في موسم الحج، أو ملعب في مباراة، كلها بيئات يتصل فيها عدد كبير من الأجهزة بعدد محدود من نقاط الوصول. والسؤال البحثي: أي الإعدادات (عرض القناة، وتوجيه الأجهزة بين النطاقات Band Steering، والحد الأدنى لسرعة الاتصال، وقوة الإرسال) يحسن المئين 95 لزمن الاستجابة أكثر في هذه البيئات، وهل تتفق النتيجة مع ما توصي به أدلة المصنعين؟

  • الأعمال السابقة: أبحاث الشبكات اللاسلكية الكثيفة ومعايير IEEE 802.11، وبيانات منشورة على IEEE DataPort.
  • الإضافة الممكنة: قياسات ميدانية في بيئة محلية حقيقية بتجربة مصممة، أي تغيير متغير واحد في كل مرة وتكرار القياس.
  • الأدوات: iperf3، وأجهزة قياس متعددة، ونقاط وصول تستطيع التحكم في إعدادها، وOpenWrt إذا احتجت تحكماً أدق.
  • البيانات: قياساتك، وبيانات Ookla على AWS للمقارنة بالمحيط.
  • التقييم: p95 لزمن الاستجابة ونسبة فقد الحزم لكل إعداد، مع اختبار إحصائي للفروق.
  • الصعوبة: صعبة.
  • المخاطرة: عدم الحصول على صلاحية تغيير إعدادات شبكة حقيقية، فاتفق مع إدارة تقنية المعلومات على نافذة تجارب محددة، أو ابن بيئة تجريبية بنقاط وصول خاصة بك.

أفكار مستهلكة Overused Ideas: كيف تحول واحدة منها إلى مشروع حقيقي؟

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

  • نظام الحضور Attendance System: لا تبن نظاماً آخر، وإنما خذ نظام الحضور الموجود في الكلية واسأل: ما إتاحته في الدقائق العشر الأولى من كل محاضرة، حين يسجل مئات الطلاب في نفس الوقت؟ فيصبح المشروع مراقبة وقياس سعة وخطة تحسين، وهو مشروع B1 بمستخدم حقيقي.
  • المتجر الإلكتروني E-commerce: بدل متجر عام، خذ متجراً صغيراً حقيقياً واسأل: لو سقط السيرفر الليلة، كم ساعة يحتاج ليعود، وكم طلباً سيضيع؟ فيصبح المشروع نسخاً احتياطياً واستعادة وتوافرية، وهو مشروع B2.
  • بوت محادثة الجامعة University Chatbot: هذا يتحول إلى مشروع ذكاء اصطناعي في الغالب، وإذا أردت أن تبقى في تقنية المعلومات فخذ الجزء التشغيلي منه، أي قاعدة معرفة مكتب الخدمة وقياس نسبة الطلبات التي تحل دون فني، وهو جزء من B4.
  • شبكة الشركة الافتراضية في Packet Tracer: هذه تمرين مادة وليست مشروع تخرج، وتحولها إلى مشروع عندما تصبح شبكة حقيقية مكتوبة كوداً، يعاد بناؤها وتختبر آلياً، وهو مشروع B7.
  • نظام حجز المواعيد للعيادة: السؤال الأهم للعيادة ليس شاشة الحجز، وإنما من يدخل إلى بيانات المرضى، وأين تحفظ، وهل تستعاد، فيصبح المشروع هوية ونسخاً احتياطياً بقيود حماية البيانات.

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

جدول مقارنة الأفكار Comparison Table

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

الفكرةالمستوىالصعوبةتوفر البياناتأهم ما تتعلمه
B1 مراقبة خدمات جهة صغيرة
Proactive Service Monitoring for a Small Organization
بكالوريوسمتوسطةتولدها، وخدمات عامة للبدايةPrometheus وSLO والتنبيه
B2 نسخ احتياطي واستعادة مختبرة
Tested Backup and Restore for a School or Clinic
بكالوريوسسهلة إلى متوسطةبيانات تجريبية بشكل الحقيقيةRPO وRTO وrestic والتخزين
B3 دخول موحد لجمعية
Single Sign-On and Account Management for a Nonprofit
بكالوريوسمتوسطةمن الجهةOIDC وSAML وSCIM ودورة حياة الحساب
B4 مكتب خدمة بمؤشرات SLA
IT Helpdesk with SLA Metrics for a University Department
بكالوريوسسهلة إلى متوسطةعالية (UCI) ثم من القسمITSM والمؤشرات وقاعدة المعرفة
B5 قياس Wi-Fi الحرم
Campus Wi-Fi Site Survey Before and After Changes
بكالوريوسمتوسطةتولدها، وOokla للمقارنةالقياس المنهجي والشبكات اللاسلكية
B6 منصة تطوير وتشغيل للقسم
Internal DevOps Platform for an Academic Department
بكالوريوسمتوسطة إلى صعبةتولدها خلال فصل تجريبيCI/CD والعزل والحصص
B7 معمل افتراضي بالكود
Rebuildable Virtual Lab with Infrastructure as Code
بكالوريوسمتوسطة إلى صعبةمن القسمProxmox وOpenTofu وAnsible
B8 خدمة فوق البيانات المفتوحة
Open Data Service with Freshness Monitoring and Change Detection
بكالوريوسمتوسطةعالية، بشروط الوصولجلب البيانات واكتشاف التغيير والمراقبة
B9 تعريب أداة مفتوحة المصدر
Arabic Localization Contribution to an Open Source Tool
بكالوريوسمتوسطةعالية (Issues المشروع)Git والمراجعة والتعريب
M1 الاصطناعية مقابل المستخدم الحقيقي
Synthetic Monitoring Versus Real User Monitoring for Outage Detection
ماجستيرمتوسطةتولدها في بيئة تجريبيةتصميم تجربة حقن الأعطال
M2 أخذ العينات في التتبع
The Impact of Trace Sampling on Failure Detection
ماجستيرمتوسطة إلى صعبةتولدها من التطبيق التجريبيOpenTelemetry وقياس الكلفة
M3 تنقيب عملية الحوادث
Process Mining of Incident Resolution Delays in ITSM Logs
ماجستيرمتوسطةعالية (UCI)تنقيب العمليات والإحصاء
M4 التكلفة الكلية مع الإقامة
Total Cost of Ownership: Self-Hosting Versus Cloud Under Saudi Data Residency
ماجستيرمتوسطةمن الجهات والمقابلاتنماذج التكلفة وتحليل الحساسية
M5 جدولة واعية بالطاقة
Energy-Aware Scheduling in a Small Data Center
ماجستيرصعبةعالية لكنها ضخمة (Google)المحاكاة والجدولة
M6 Wi-Fi عالي الكثافة
Configuration Tuning for Latency in High-Density Wi-Fi Networks
ماجستيرصعبةتولدها ميدانياًتصميم التجارب والشبكات اللاسلكية

وإذا كنت في البكالوريوس وتريد أن تختار ثلاثاً للمشرف، فالمزيج الذي ننصح به: فكرة بيانات عالية التوفر تبدأ فيها من اليوم الأول (B4 أو B8)، وفكرة بمستخدم حقيقي تعرفه (B1 أو B2 أو B3)، وفكرة تميزك (B9 أو B7). وبهذا الشكل إذا رفض المشرف واحدة فالبديلتان مختلفتان فعلاً، وليستا نفس الفكرة بثلاثة عناوين.

تجربة عملية Lab: مراقب اصطناعي Synthetic Monitor لخدمات البيانات المفتوحة

قلنا في بداية المقال إن أقوى ما تحمله إلى المشرف نموذج صغير يثبت أن أصعب جزء في الفكرة ممكن، والآن سوف نقوم بذلك لفكرتين معاً: B1 مراقبة الخدمات، وB8 الخدمة فوق البيانات المفتوحة، لأن كلتيهما تبدأ بنفس السؤال: هل نستطيع أن نقيس خدمة حقيقية من الخارج بدقة، ونعرف أنها تعمل فعلاً للمستخدم وليس لرمز الحالة فقط؟ والهدف ليس بناء Prometheus من جديد، فهو موجود ويقوم بذلك أفضل منا، وإنما أن نفهم ما يقيسه المراقب في الداخل، حتى نعرف ماذا نكتب في المقترح، وما الذي قد يفشل.

البرنامج مكتوب بلغة Python 3.13 بالمكتبة القياسية فقط، فلا يحتاج تثبيت أي شيء، ويقيس لكل هدف في كل جولة أربع مراحل: تحليل الاسم DNS، والاتصال TCP، ومصافحة TLS مع قراءة تاريخ انتهاء الشهادة، وزمن أول بايت TTFB، ثم يقرأ المحتوى ويفحصه، ويتبع التحويلات Redirects حتى ثلاث مرات، ويكتب في النهاية ملخصاً وملفاً بصيغة Prometheus النصية.

البرنامج probe.py

البرنامج كاملاً كما يلي:

# A small synthetic monitor (Python 3.13, standard library only): the feasibility spike for the
# "monitoring for a small organisation" graduation project idea.
#   python probe.py targets.json [--rounds 5] [--interval 3] [--timeout 5] [--metrics metrics.prom]
# For every target and round it measures DNS, TCP connect, TLS handshake and time to first byte (TTFB),
# follows up to 3 redirects, and checks the body, not only the status code. At the end it prints a summary
# (availability by status code and by content check, p50/p95 of the total time, certificate days left)
# and writes the last values in the Prometheus text exposition format.
import argparse, json, socket, ssl, statistics, time
from datetime import datetime, timezone
from http.client import HTTPResponse
from urllib.parse import urlsplit, urljoin

def probe_once(url, timeout, ua, max_redirects=3):
    hops, t_start = [], time.perf_counter()
    for _ in range(max_redirects + 1):
        u = urlsplit(url)
        host, port = u.hostname, u.port or (443 if u.scheme == 'https' else 80)
        path = (u.path or '/') + ('?' + u.query if u.query else '')
        h = {'url': url}
        t0 = time.perf_counter()
        try:
            addr = socket.getaddrinfo(host, port, type=socket.SOCK_STREAM)[0][4]
            h['dns_ms'] = (time.perf_counter() - t0) * 1000
            t1 = time.perf_counter()
            sock = socket.create_connection(addr[:2], timeout=timeout)
            h['connect_ms'] = (time.perf_counter() - t1) * 1000
            cert_days = None
            if u.scheme == 'https':
                t2 = time.perf_counter()
                ctx = ssl.create_default_context()
                sock = ctx.wrap_socket(sock, server_hostname=host)
                h['tls_ms'] = (time.perf_counter() - t2) * 1000
                na = sock.getpeercert()['notAfter']
                exp = datetime.fromtimestamp(ssl.cert_time_to_seconds(na), timezone.utc)
                cert_days = (exp - datetime.now(timezone.utc)).days
            h['cert_days'] = cert_days
            t3 = time.perf_counter()
            req = f'GET {path} HTTP/1.1\r\nHost: {host}\r\nUser-Agent: {ua}\r\nAccept: text/html,*/*\r\nConnection: close\r\n\r\n'
            sock.sendall(req.encode())
            resp = HTTPResponse(sock)
            resp.begin()
            h['ttfb_ms'] = (time.perf_counter() - t3) * 1000
            body = resp.read()
            sock.close()
            h['status'], h['bytes'], h['body'] = resp.status, len(body), body.decode('utf-8', 'replace')
            loc = resp.getheader('Location')
        except (OSError, ssl.SSLError) as e:
            h['error'] = f'{type(e).__name__}: {e}'
            hops.append(h)
            break
        hops.append(h)
        if h['status'] in (301, 302, 303, 307, 308) and loc:
            url = urljoin(url, loc)
            continue
        break
    total = (time.perf_counter() - t_start) * 1000
    return hops, total

def judge(hops, markers, min_bytes, json_sum=None):
    last = hops[-1]
    if 'error' in last:
        return False, False, last['error']
    status_ok = 200 <= last['status'] < 400
    hit = next((m for m in markers if m in last['body']), None)
    if hit:
        return status_ok, False, f'marker "{hit}"'
    if json_sum:  # an API target: the body must be a JSON list and the field must add up to more than 0
        try:
            total = sum(int(x.get(json_sum, 0)) for x in json.loads(last['body']))
        except (ValueError, TypeError, AttributeError) as e:
            return status_ok, False, f'not the expected JSON ({type(e).__name__})'
        return status_ok, status_ok and total > 0, f'{len(json.loads(last["body"]))} items, sum {json_sum}={total}'
    if last['bytes'] < min_bytes:
        return status_ok, False, f'{last["bytes"]} bytes < {min_bytes}'
    return status_ok, status_ok, 'ok'

def pct(xs, p):
    xs = sorted(xs)
    if not xs: return float('nan')
    k = (len(xs) - 1) * p / 100
    f = int(k); c = min(f + 1, len(xs) - 1)
    return xs[f] + (xs[c] - xs[f]) * (k - f)

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('targets'); ap.add_argument('--rounds', type=int, default=5)
    ap.add_argument('--interval', type=float, default=3); ap.add_argument('--timeout', type=float, default=5)
    ap.add_argument('--metrics', default='metrics.prom'); ap.add_argument('--ua', help='override the User-Agent of targets.json')
    a = ap.parse_args()
    cfg = json.load(open(a.targets, encoding='utf-8'))
    ua, markers, min_bytes = a.ua or cfg['user_agent'], cfg['reject_markers'], cfg['min_bytes']
    print(f'== probing {len(cfg["targets"])} targets, {a.rounds} rounds, interval {a.interval}s, timeout {a.timeout}s, UA "{ua}" ==')
    res = {t['name']: [] for t in cfg['targets']}
    for r in range(1, a.rounds + 1):
        for t in cfg['targets']:
            hops, total = probe_once(t['url'], a.timeout, ua)
            s_ok, c_ok, why = judge(hops, markers, min_bytes, t.get('json_sum'))
            res[t['name']].append((hops, total, s_ok, c_ok, why))
            last = hops[-1]
            chain = ' -> '.join(str(h.get('status', 'ERR')) for h in hops)
            parts = [f'dns {last["dns_ms"]:.0f}' if 'dns_ms' in last else None,
                     f'tcp {last["connect_ms"]:.0f}' if 'connect_ms' in last else None,
                     f'tls {last["tls_ms"]:.0f}' if 'tls_ms' in last else None,
                     f'ttfb {last["ttfb_ms"]:.0f}' if 'ttfb_ms' in last else None]
            print(f'r{r} {t["name"]:<10} {chain:<15} {" ".join(p for p in parts if p):<30} total {total:6.0f} ms '
                  f'{last.get("bytes", 0):>7} B  status_ok={int(s_ok)} content_ok={int(c_ok)} ({why})')
        if r < a.rounds: time.sleep(a.interval)
    print('\n== summary ==')
    print(f'{"target":<10} {"up(status)":>10} {"up(content)":>11} {"p50 ms":>7} {"p95 ms":>7} {"cert days":>9}')
    lines = ['# HELP probe_success 1 if the last probe passed the content check',
             '# TYPE probe_success gauge',
             '# HELP probe_duration_seconds total time of the last probe including redirects',
             '# TYPE probe_duration_seconds gauge',
             '# HELP probe_ssl_days_left days until the certificate of the final hop expires',
             '# TYPE probe_ssl_days_left gauge']
    for name, rows in res.items():
        n = len(rows)
        up_s = sum(r[2] for r in rows) / n * 100
        up_c = sum(r[3] for r in rows) / n * 100
        totals = [r[1] for r in rows if 'error' not in r[0][-1]]
        cert = rows[-1][0][-1].get('cert_days')
        print(f'{name:<10} {up_s:>9.0f}% {up_c:>10.0f}% {pct(totals, 50):>7.0f} {pct(totals, 95):>7.0f} {str(cert):>9}')
        lines.append(f'probe_success{{target="{name}"}} {int(rows[-1][3])}')
        lines.append(f'probe_duration_seconds{{target="{name}"}} {rows[-1][1] / 1000:.3f}')
        if cert is not None: lines.append(f'probe_ssl_days_left{{target="{name}"}} {cert}')
    open(a.metrics, 'w', encoding='utf-8').write('\n'.join(lines) + '\n')
    print(f'\nwrote {len(lines)} lines to {a.metrics}')

if __name__ == '__main__':
    main()

في البرنامج أعلاه لاحظ التالي:

  • الدالة probe_once لا تستخدم urllib، وإنما تفتح الاتصال بنفسها خطوة بخطوة: getaddrinfo ثم create_connection ثم wrap_socket، والسبب أننا نريد زمن كل مرحلة وحدها، وurllib تعطيك الزمن الكلي فقط.
  • بعد المصافحة نقرأ notAfter من الشهادة ونحسب الأيام الباقية، لأن انتهاء الشهادة من أكثر أسباب الانقطاع شيوعاً في الجهات الصغيرة، وهو العطل الوحيد الذي تعرف موعده مسبقاً.
  • الدالة judge تعطي حكمين: status_ok إذا كانت الحالة بين 200 و399، وcontent_ok إذا نجحت الحالة ولم يحتو المحتوى على كلمة من قائمة الرفض وكان حجمه معقولاً، أو إذا كان الهدف واجهة JSON فيجب أن تكون قائمة يزيد مجموع الحقل المطلوب فيها على صفر. وسوف ترى بعد قليل لماذا نحتاج الحكمين.
  • الدالة pct تحسب المئين بالاستيفاء الخطي، فالمتوسط يخفي البطء الذي يشعر به بعض المستخدمين، والمئين 95 يظهره.
  • الملف الأخير يكتب بصيغة العرض النصية في Prometheus، وبنفس أسماء المقاييس التي يستخدمها blackbox_exporter تقريباً، حتى يكون الانتقال إلى الأداة الحقيقية في المشروع سهلاً.

ملف الأهداف targets.json

الأهداف ست خدمات عامة لها علاقة بأفكار المقال: النطاق القديم لمنصة البيانات المفتوحة، والنطاق الجديد، وواجهة التصنيفات فيها، وموقع الهيئة العامة للإحصاء، وموقع هيئة الاتصالات والفضاء والتقنية، وصفحة سجل الحوادث في UCI الذي اقترحناه لفكرتي B4 وM3:

{
  "user_agent": "ArabRoot-gradproject-probe/1.0 (+https://arabroot.io)",
  "reject_markers": [
    "Request Rejected",
    "Access Denied"
  ],
  "min_bytes": 1024,
  "targets": [
    {
      "name": "od-old",
      "url": "https://od.data.gov.sa/"
    },
    {
      "name": "od-new",
      "url": "https://open.data.gov.sa/"
    },
    {
      "name": "od-api",
      "url": "https://open.data.gov.sa/api/categories",
      "json_sum": "noDatasets"
    },
    {
      "name": "gastat",
      "url": "https://www.stats.gov.sa/"
    },
    {
      "name": "cst",
      "url": "https://www.cst.gov.sa/"
    },
    {
      "name": "uci",
      "url": "https://archive.ics.uci.edu/dataset/498/incident+management+process+enriched+event+log"
    }
  ]
}

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

التشغيل والمخرج Output

للتشغيل من مجلد lab:

python probe.py targets.json --rounds 5 --interval 3 --timeout 5 > probe.out

والمخرج سوف يكون كما يلي (جولتان من الخمس، ثم الملخص كاملاً، والمخرج كله في lab/probe.out):

== probing 6 targets, 5 rounds, interval 3.0s, timeout 5.0s, UA "ArabRoot-gradproject-probe/1.0 (+https://arabroot.io)" ==
r1 od-old     302 -> 200      dns 1 tcp 24 tls 155 ttfb 38   total    514 ms    1208 B  status_ok=1 content_ok=1 (ok)
r1 od-new     200             dns 1 tcp 23 tls 115 ttfb 76   total    214 ms    1208 B  status_ok=1 content_ok=1 (ok)
r1 od-api     200             dns 1 tcp 30 tls 111 ttfb 2416 total   2558 ms   16384 B  status_ok=1 content_ok=1 (51 items, sum noDatasets=32965)
r1 gastat     302 -> 302 -> 200 dns 1 tcp 62 tls 175 ttfb 398  total   1230 ms  267711 B  status_ok=1 content_ok=1 (ok)
r1 cst        200             dns 46 tcp 22 tls 121 ttfb 178 total    625 ms 1276505 B  status_ok=1 content_ok=1 (ok)
r1 uci        200             dns 1 tcp 237 tls 306 ttfb 556 total   1590 ms   83612 B  status_ok=1 content_ok=1 (ok)
r2 od-old     302 -> 200      dns 1 tcp 30 tls 148 ttfb 41   total    453 ms    1208 B  status_ok=1 content_ok=1 (ok)
r2 od-new     200             dns 1 tcp 38 tls 137 ttfb 38   total    214 ms    1208 B  status_ok=1 content_ok=1 (ok)
r2 od-api     200             dns 1 tcp 22 tls 126 ttfb 2430 total   2580 ms   16384 B  status_ok=1 content_ok=1 (51 items, sum noDatasets=32965)
r2 gastat     302 -> 302 -> 200 dns 1 tcp 67 tls 187 ttfb 398  total   1195 ms  267711 B  status_ok=1 content_ok=1 (ok)
r2 cst        200             dns 1 tcp 19 tls 121 ttfb 394  total    734 ms 1276505 B  status_ok=1 content_ok=1 (ok)
r2 uci        200             dns 1 tcp 230 tls 332 ttfb 518 total   1553 ms   83612 B  status_ok=1 content_ok=1 (ok)

== summary ==
target     up(status) up(content)  p50 ms  p95 ms cert days
od-old           100%        100%     511     678        79
od-new           100%        100%     214     263        79
od-api           100%        100%    2642    2753        79
gastat           100%        100%    1230    1443       179
cst              100%        100%     734     867       153
uci              100%        100%    1590    1654        18

wrote 24 lines to metrics.prom

وعند قراءة المخرج لاحظ التالي:

  • السطر الأول لكل جولة هو النطاق القديم od.data.gov.sa، وسلسلته 302 -> 200 تعني أنه يحول إلى النطاق الجديد، ولذلك زمنه الكلي ضعف زمن النطاق الجديد تقريباً، فالمراقب يدفع ثمن مصافحتين. وهذه ملاحظة مهمة لفكرة B8: إذا كان تطبيقك يستخدم الرابط القديم فهو يدفع هذا الزمن في كل طلب.
  • صفحة المنصة الجديدة حجمها 1208 بايت فقط، وزمن أول بايت فيها نحو 40 ملي ثانية. والسبب أن المنصة تطبيق صفحة واحدة Single Page Application، فالسيرفر يرسل هيكلاً صغيراً فيه وسم <app-root> وملفات JavaScript، والمتصفح هو الذي يبني الصفحة ويطلب البيانات من الواجهة. وهذا يعني أن نجاح الصفحة الرئيسية لا يثبت أن البيانات تصل، ولهذا السبب أضفنا هدف الواجهة.
  • واجهة التصنيفات od-api أرجعت 51 تصنيفاً، ومجموع حقل noDatasets فيها 32,965، وهذا هو الفحص الذي يثبت أن البيانات تصل فعلاً. ولكن زمن أول بايت فيها نحو 2.4 ثانية في كل الجولات، أي أن السيرفر نفسه يأخذ هذا الوقت في تجهيز الرد، لأن مراحل DNS وTCP وTLS فيها مثل الصفحة الرئيسية تقريباً.
  • موقع الهيئة العامة للإحصاء يمر بتحويلين 302 -> 302 -> 200 قبل الصفحة، وحجمها نحو 268 كيلوبايت، أما موقع هيئة الاتصالات فحجم صفحته الرئيسية نحو 1.27 ميجابايت، وهذا وحده سبب كاف لاختلاف زمنهما الكلي.
  • صفحة UCI هي الوحيدة خارج المملكة، وتظهر المسافة في زمن الاتصال TCP بنحو 230 ملي ثانية في كل جولة، مقابل 20 إلى 90 ملي ثانية تقريباً للمواقع المحلية، لأن مصافحة TCP جولة ذهاب وعودة كاملة عبر القارات.
  • زمن DNS في أغلب الجولات ملي ثانية واحدة، لأن نظام التشغيل يحتفظ بالإجابة في ذاكرته المؤقتة Cache بعد الطلب الأول، ولذلك ترى أحياناً قيمة أعلى مثل 46 أو 113 عندما تنتهي صلاحية الإجابة ويطلبها من جديد.
  • في عمود cert days لاحظ أن شهادة UCI بقي عليها 18 يوماً فقط عند التشغيل. وهي شهادة من Let's Encrypt عمرها 90 يوماً، وهذا هو التنبيه الذي تريد أن تراه في منصة المراقبة قبل الانتهاء بأسبوعين وليس بعده بساعة.
رسم لمراحل الفحص من المراقب probe.py إلى DNS ثم TCP ثم TLS ثم TTFB ثم قراءة المحتوى، وتحته ثلاثة أشرطة أفقية بمقياس واحد من الجولة الأولى: od-new بإجمالي 214 ملي ثانية أغلبها TLS بـ 115، وod-api بإجمالي 2558 منها 2416 لأول بايت، وuci بإجمالي 1590 منها 237 للاتصال و306 للمصافحة و556 لأول بايت و490 لقراءة المحتوى
نفس السيرفر يرد على الصفحة في 76 ملي ثانية وعلى الواجهة في 2.4 ثانية، والمسافة تظهر في زمن الاتصال

وأما ملف المقاييس metrics.prom فهو ما يقرؤه Prometheus إذا وضعت المراقب خلف سيرفر ويب صغير، وأوله كما يلي:

# HELP probe_success 1 if the last probe passed the content check
# TYPE probe_success gauge
# HELP probe_duration_seconds total time of the last probe including redirects
# TYPE probe_duration_seconds gauge
# HELP probe_ssl_days_left days until the certificate of the final hop expires
# TYPE probe_ssl_days_left gauge
probe_success{target="od-old"} 1
probe_duration_seconds{target="od-old"} 0.719
probe_ssl_days_left{target="od-old"} 79

المشكلة الحقيقية: صفحة رفض بحالة HTTP 200

لم يخرج المراقب بهذا الشكل من أول محاولة. فقبل كتابته فتحنا رابط المنصة بأداة curl لنتأكد أنه يعمل، فأرجع الحالة 200، ولكن عند قراءة المحتوى وجدنا صفحة من 244 بايت عنوانها Request Rejected ونصها «The requested URL was rejected. Please consult with your administrator»، ومعها رقم دعم. أي أن جدار تطبيقات الويب WAF أمام المنصة قرر أن هذا العميل غير مرغوب فيه، وأرسل صفحة الرفض برمز النجاح. وهنا تظهر المشكلة الحقيقية لأي منصة مراقبة: المراقب الذي ينظر إلى رمز الحالة وحده كان سيرسم لوحة خضراء بنسبة إتاحة 100%، بينما لا تصل أي بيانات.

والآن سوف نقوم بإعادة هذه الحالة بالمراقب نفسه، بتغيير اسم العميل فقط إلى الاسم الافتراضي لمكتبة Python:

python probe.py targets.json --rounds 2 --interval 3 --ua "Python-urllib/3.13" --metrics metrics-ua.prom > probe-ua.out

والمخرج سوف يكون كما يلي (الجولة الأولى والملخص):

== probing 6 targets, 2 rounds, interval 3.0s, timeout 5s, UA "Python-urllib/3.13" ==
r1 od-old     302 -> 200      dns 1 tcp 33 tls 154 ttfb 31   total    516 ms     244 B  status_ok=1 content_ok=0 (marker "Request Rejected")
r1 od-new     200             dns 1 tcp 22 tls 164 ttfb 26   total    214 ms     245 B  status_ok=1 content_ok=0 (marker "Request Rejected")
r1 od-api     200             dns 1 tcp 29 tls 138 ttfb 32   total    200 ms     244 B  status_ok=1 content_ok=0 (marker "Request Rejected")
r1 gastat     302 -> 302 -> 200 dns 1 tcp 51 tls 214 ttfb 444  total   1293 ms  267719 B  status_ok=1 content_ok=1 (ok)
r1 cst        200             dns 163 tcp 41 tls 143 ttfb 1366 total   1902 ms 1276518 B  status_ok=1 content_ok=1 (ok)
r1 uci        200             dns 1 tcp 230 tls 325 ttfb 521 total   1595 ms   83612 B  status_ok=1 content_ok=1 (ok)

== summary ==
target     up(status) up(content)  p50 ms  p95 ms cert days
od-old           100%          0%     533     548        79
od-new           100%          0%     236     257        79
od-api           100%          0%     253     301        79
gastat           100%        100%    1343    1389       179
cst              100%        100%    1220    1834       153
uci              100%        100%    1654    1706        18

wrote 24 lines to metrics-ua.prom

لاحظ أن عمود up(status) بقي 100% للأهداف الثلاثة على المنصة، وأن عمود up(content) نزل إلى صفر، والسبب في آخر كل سطر: marker "Request Rejected". وحتى واجهة التصنيفات التي ترجع JSON أرجعت نفس صفحة HTML بحالة 200. أما المواقع الثلاثة الأخرى فلم تتأثر، أي أن القرار خاص بالجدار الذي أمام المنصة. ولا نعرف القواعد التي يطبقها الجدار، ولا يجب أن نحاول تخمينها أو تجاوزها، فالدرس هنا ليس كيف تمر من الجدار، وإنما أن منصة المراقبة يجب أن تفحص ما يراه المستخدم.

مقارنة من جانبين: مراقب يعرف عن نفسه باسم ArabRoot-gradproject-probe يحصل على الصفحة الحقيقية بحجم 1208 بايت وواجهة التصنيفات بـ 51 تصنيفاً، فإتاحته 100% بحسب الحالة و100% بحسب المحتوى، ومراقب باسم Python-urllib/3.13 يحصل على صفحة Request Rejected بحجم 244 بايت من جدار WAF بحالة 200، فإتاحته 100% بحسب الحالة و0% بحسب المحتوى
نفس الرابط ونفس الحالة 200، والفرق يظهر فقط عند فحص المحتوى

وهذه المشكلة تعطيك ثلاثة أشياء لمشروعك. الأول قاعدة في التصميم: كل فحص في منصة المراقبة يجب أن يحتوي على شرط محتوى، مثل كلمة يجب أن تظهر أو حقل JSON يجب أن يكون له قيمة، وهذا ما يسميه blackbox_exporter بفحص الجسم وتجده في إعداداته. والثاني فقرة في فصل المخاطر في المقترح: الخدمات الحكومية أمامها جدران حماية قد ترفض المراقبة الآلية، لذلك يجب التنسيق مع الجهة قبل مراقبة خدماتها في المشروع الفعلي، أو مراقبة خدمات الجهة التي تعمل معها هي فقط. والثالث نوع عطل حقيقي تستطيع أن تضيفه إلى نموذج الأعطال في فكرة الماجستير M1.

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

ماذا يحدث إذا قصرنا المهلة Timeout إلى 0.3 ثانية؟

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

python probe.py targets.json --rounds 3 --interval 3 --timeout 0.3 --metrics metrics-timeout.prom > probe-timeout.out

والمخرج سوف يكون كما يلي (الجولة الأولى والملخص):

== probing 6 targets, 3 rounds, interval 3.0s, timeout 0.3s, UA "ArabRoot-gradproject-probe/1.0 (+https://arabroot.io)" ==
r1 od-old     302 -> 200      dns 1 tcp 28 tls 159 ttfb 53   total    531 ms    1208 B  status_ok=1 content_ok=1 (ok)
r1 od-new     200             dns 1 tcp 30 tls 160 ttfb 45   total    236 ms    1208 B  status_ok=1 content_ok=1 (ok)
r1 od-api     ERR             dns 1 tcp 27 tls 150           total    492 ms       0 B  status_ok=0 content_ok=0 (TimeoutError: The read operation timed out)
r1 gastat     302 -> 302 -> ERR dns 1 tcp 64 tls 218           total   1057 ms       0 B  status_ok=0 content_ok=0 (TimeoutError: The read operation timed out)
r1 cst        ERR             dns 1 tcp 22 tls 203           total    526 ms       0 B  status_ok=0 content_ok=0 (TimeoutError: The read operation timed out)
r1 uci        ERR             dns 1 tcp 235 tls 388          total    932 ms       0 B  status_ok=0 content_ok=0 (TimeoutError: The read operation timed out)

== summary ==
target     up(status) up(content)  p50 ms  p95 ms cert days
od-old           100%        100%     584     618        79
od-new           100%        100%     236     265        79
od-api             0%          0%     nan     nan        79
gastat             0%          0%     nan     nan       179
cst               67%         67%     610     667       153
uci                0%          0%     nan     nan        18

wrote 24 lines to metrics-timeout.prom

في المخرج أعلاه لاحظ التالي:

  • واجهة التصنيفات وموقع الإحصاء وصفحة UCI أصبحت إتاحتها صفراً، مع أن أياً منها لم يتعطل بين التشغيلين، والخطأ في كل سطر TimeoutError: The read operation timed out بعد نجاح DNS وTCP وTLS، أي أن المراقب استسلم وهو ينتظر أول بايت.
  • موقع هيئة الاتصالات نجح في جولتين من ثلاث، لأن زمن أول بايت فيه يتغير بين 161 و1366 ملي ثانية في التشغيلات الثلاثة، فيقع أحياناً تحت 300 وأحياناً فوقها. وهذا أخطر من الفشل الدائم، لأنه ينتج تنبيهاً يظهر ويختفي، فيتعود الفني على تجاهله.
  • والأغرب أن مصافحة UCI أخذت 388 ملي ثانية ونجحت رغم أن المهلة 300، وأن موقع الهيئة أكمل تحميل 1.27 ميجابايت في الجولتين الناجحتين. والسبب أن مهلة الـ socket في Python تطبق على كل عملية قراءة أو كتابة وحدها، وليس على الطلب كله، كما يشرح توثيق وحدة socket في قسم المهلات. فالمصافحة مكونة من عدة قراءات كل منها أقصر من 300، والتحميل الكبير مكون من قراءات صغيرة كثيرة.
جدول من ستة صفوف للأهداف بعمودين للإتاحة: بمهلة 5 ثوان كلها 100%، وبمهلة 0.3 ثانية بقي od-old وod-new على 100% ونزل od-api وgastat وuci إلى 0% وcst إلى 67%، مع سبب كل صف، وفي الأسفل ملاحظتان: المهلة لكل عملية وليست للطلب كله، والقاعدة أن تكون المهلة فوق p95 الطبيعي بهامش واضح مع حد أعلى للطلب كله Deadline
لم يتعطل أي سيرفر بين التشغيلين، والذي تغير هو إعداد المراقب فقط

والقاعدة التي تخرج بها لمشروعك: اجعل المهلة لكل هدف فوق المئين 95 الطبيعي له بهامش واضح، فواجهة تصنيفات المنصة مثلاً p95 لها نحو 2.75 ثانية في التشغيل الأول، فمهلة 5 ثوان معقولة لها وغير معقولة لصفحة ترد في 200 ملي ثانية. وأضف حداً أعلى للطلب كله Deadline بجانب مهلة العمليات، ولا تطلق تنبيهاً من فشل واحد، وإنما من فشل متكرر أو من استهلاك ميزانية الأخطاء، وهذا ما تفعله قواعد Alertmanager بشرط المدة for.

ماذا يثبت هذا النموذج Feasibility Spike للمشرف؟

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

  • نستطيع قياس كل مرحلة من مراحل الطلب وحدها، ولدينا خط أساس لست خدمات: p95 من 263 ملي ثانية إلى 2.75 ثانية.
  • وجدنا نوعي عطل لا يكتشفهما فحص الحالة: صفحة رفض بحالة 200، وتطبيق صفحة واحدة ينجح هيكله بينما قد تفشل بياناته، ولذلك سيكون فحص المحتوى جزءاً من التصميم.
  • وجدنا شهادة بقي عليها 18 يوماً، أي أن تنبيه الشهادات وحده يستحق المشروع لجهة صغيرة.
  • قسنا أثر إعداد المهلة على الإنذارات الكاذبة، وهذا يصبح فصلاً في التقييم وسؤالاً قد يتطور إلى فكرة الماجستير M1.
  • المخاطرة الأكبر هي الوصول إلى خدمات الجهة، وخطة التخفيف هي الاتفاق المكتوب مع الجهة قبل المقترح.

كيف تعرض الأفكار الثلاث على المشرف Supervisor؟

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

  1. العنوان: جملة تحمل الجهة والنتيجة، مثل «مراقبة خدمات جمعية خيرية وتقليل زمن اكتشاف الأعطال»، وليس «نظام مراقبة متكامل».
  2. المشكلة في ثلاثة أسطر، مع رقم إن وجد، مثل عدد الأنظمة أو عدد مرات الانقطاع التي ذكرها الفني.
  3. المستخدم: اسم الجهة ومن قابلتم فيها، وهل وافقت على التجربة.
  4. النطاق: ما سوف تبنونه وما لن تبنوه، وتقسيم العمل على الأعضاء.
  5. البيانات: المصدر بالرابط، والحجم، والترخيص.
  6. التقييم: المقياس، وخط الأساس، وكيف ستقيسون بعد المشروع.
  7. المخاطرة وخطة تخفيفها.
  8. الدليل: لقطة من مخرج النموذج الصغير، إن كانت هذه أقوى فكرة.

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

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

أخطاء شائعة Common Mistakes في مشاريع تقنية المعلومات

  • مشروع برمجة بثوب تقنية معلومات: تطبيق ويب جديد بلا تشغيل ولا قياس، والحل أن تسأل ماذا يتغير في تشغيل أنظمة الجهة بعد مشروعك.
  • أدوات كثيرة بلا سؤال: عشر أدوات في الصفحة الأولى من المقترح، ولا مقياس واحد في فصل التقييم، والسبب أن الفريق بدأ من الأدوات وليس من المشكلة.
  • بيئة على حاسوب طالب واحد: كل شيء يعمل على جهاز عضو في الفريق، ويتوقف يوم المناقشة، والحل سيرفر أو جهاز افتراضي مشترك من الأسبوع الأول، والإعدادات كلها في Git.
  • مراقبة الحالة فقط: كما رأيت في التجربة، رمز الحالة 200 لا يعني أن المستخدم يرى ما يجب أن يراه.
  • نسخ احتياطي بلا استعادة: فريق يعرض جدول النسخ في المناقشة، ثم يسأله عضو اللجنة: استعد الآن، فلا يعرف كم سيأخذ.
  • بيانات حقيقية حساسة دون موافقة: سجلات مرضى أو طلاب في جهاز طالب، وهذه مخالفة قبل أن تكون خطأ، فاقرأ PDPL للخدمات المستضافة واستخدم بيانات تجريبية بنفس البنية.
  • تقييم بالرضا فقط: استبيان «هل أعجبك النظام؟» بعشرة مشاركين ليس تقييماً، وإنما مكمل لرقم تشغيلي قبل وبعد.
  • مهلات وحدود عشوائية: مهلة ثانية واحدة وتنبيه عند أول فشل، فتصبح المنصة مصدر إزعاج، والحل أن تبني الحدود من خط أساس مقيس.
  • توثيق في نهاية الفصل: دليل التشغيل يكتب أثناء البناء، لأن من سيستلم النظام بعدك يحتاج أن يعرف لماذا اخترت كل إعداد، وليس أنك اخترته فقط.

قائمة تحقق Checklist قبل لقاء المشرف

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

الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

  • مشروع البكالوريوس نظام يعمل لمستخدم حقيقي ويقاس أثره، ورسالة الماجستير سؤال بحثي يجاب عنه بتجربة قابلة للتكرار، وأغلب الأفكار تصلح للمستويين بسؤال مختلف.
  • فكرة تقنية المعلومات فيها جهة تشغل أنظمة لمستخدمين، ويتغير بعد المشروع شيء يمكن قياسه في تشغيلها، والجهات الصغيرة أفضل مكان لها.
  • ستة أسئلة تصفي بها الأفكار في أسبوع: المشكلة والمستخدم والبيانات والتقييم والمخاطرة والتميز، ثم نموذج صغير لأقوى فكرة.
  • تسع أفكار للبكالوريوس وست للماجستير، ببيانات حقيقية مثل سجل حوادث UCI وبيانات Ookla ومنصة البيانات المفتوحة وبيانات تجمعات Google.
  • الأفكار المستهلكة تتحول إلى مشاريع حقيقية عندما تحتفظ بالجهة وتغير السؤال من «ماذا نبني؟» إلى «ماذا نقيس في تشغيله؟».
  • التجربة العملية أظهرت أن رمز الحالة 200 قد يخفي صفحة رفض، وأن مهلة قصيرة تصنع أعطالاً غير موجودة، وكلاهما درس يدخل في تصميم مشروعك.

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

دليلتخصص تقنية المعلومات Information Technology: منهج IT2017ما الذي يجعل تقنية المعلومات تخصصاً مستقلاً بحسب منهج IT2017، وماذا تعطيك خطط الجامعات السعودية منه، وكيف تكمل السحابة والتشغيل بنفسك.دليلأي تخصص تقني تختار؟ ما تدرسه فعلاً وأين تعمل بعدهماذا تدرس فعلاً في كل تخصص تقني بحسب الخطط الدراسية السعودية، وأين يعمل خريجوه، ومتى يهم اسم التخصص ومتى تهم المهارة.دليلمفاهيم المراقبة Observability: من الإشارة إلى التنبيهما الذي تجيب عنه المقاييس والسجلات والتتبع، وكيف تبني تنبيهاً على ما يشعر به المستخدم وعلى ميزانية الأخطاء بدل كل رقم.دليلالنسخ الاحتياطي بقاعدة 3-2-1 واختبار الاستعادةكيف تحدد كم بيانات تقبل أن تخسر، وتبني نسخاً لا يستطيع المخترق حذفها، وتتأكد أنك تستطيع استعادتها فعلاً.دليلما هو الدخول الموحد SSO؟ المصطلحات التي تحتاجها أولاًخريطة لمصطلحات الدخول الموحد SSO مع تجربة حقيقية تبين كيف تفتح جلسة واحدة في مزود الهوية تطبيقين، وماذا يبقى بعد الخروج.دليلإدارة خدمات تقنية المعلومات ITSM: ما الذي تحتاجه فعلاً؟كيف تنظم عمل الدعم الفني بالتذاكر والمؤقتات والتصعيد، وما الذي تأخذه من ITIL دون بيروقراطية.دليلمصطلحات البنية كشيفرة IaC التي تحتاجها قبل أي أداةما معنى أن تكتب بنيتك في ملفات داخل Git، ولماذا يفشل السكربت العادي عند تشغيله مرة ثانية، وما الذي تحفظه الأداة في ملف الحالة.دليلGitea Actions: تشغيل CI/CD وبناء Docker Images على سيرفركاجعل سيرفرك يختبر الكود ويبني Docker Images تلقائياً مع كل push، دون أن يخرج كودك أو أسرارك إلى خدمة CI خارجية.

سجل التحديثات

  • نوفمبر 2026: كتابة المقال، والتحقق من كل مصدر بيانات ورابط فيه، وتشغيل البرنامج probe.py على Python 3.13 على ست خدمات عامة يوم 1 نوفمبر 2026 بثلاثة إعدادات: الافتراضي، واسم عميل المكتبة الافتراضي، ومهلة 0.3 ثانية.
نشرة عرب رووت | ArabRoot

معرفة تستحق مكاناً في بريدك.

مقالات مختارة وأدوات مفيدة وأفكار لمشروعك القادم، في رسالة واحدة كل أسبوع.

يمكنك إلغاء الاشتراك متى شئت. الخصوصية

تم استلام طلبك. افتح بريدك واضغط رابط التأكيد لإتمام الاشتراك.