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

- الدور
- تصميم وتنفيذ، من البداية للنهاية
- النطاق
- منصة ومنهج ولوحة إدارة — ١١٥ مسارًا
- التقنيات
- Django 5.2 LTS · PostgreSQL · Railway
- المُسلَّم
- أربع كراسات مصدرية، لوحة هوية، رسومات الوحدات
المطلوب
العميل مدرّس كيمياء عنده منهج ثانوية عامة وأربع كراسات. الموجود كان منهجًا تفاعليًا من صفحة واحدة للكراسة الأولى — بلا حسابات، بلا دفع، بلا أي طريقة تمنع حد يحفظ الصفحة ويوزّعها، وبلا أي طريقة يرد بها على طالب يقول إنه دفع ولم يصله شيء.
المطلوب كان مشروعًا تجاريًا لا موقعًا: بِع وحدة، امنح الوصول لسنة، استرِدّه عند انتهائها، احمِ المحتوى المدفوع فعلًا، وأعطِ شخصًا غير تقني شاشة واحدة تجيب: مين دفع، ومين عنده وصول، وإيه اللي حصل.
قيدان شكّلا البنية. الدفع في مصر يدوي — تحويل بنكي وفودافون كاش، يراجعه شخص أمام كشف حساب — فما كان ممكنًا أن يتعلق الوصول بـ webhook دفع. والمنهج القائم كان ثمانية آلاف سطر JavaScript شغّالة بلا build step، وهذا رصيد لا دَين. فبُنِيَت Django حوله لا من خلاله، ولم تحتج واجهة المنهج أي تعديل.
ما تم تسليمه
- الصفحة الرئيسية وكتالوج الوحدات والحساب ونظام دخول كامل — تسجيل دخول، واستعادة كلمة مرور، وتغيير إجباري عند أول دخول
- أربعة أدوار، والوصول للوحدة يُمنح لسنة ويُطبَّق على الطابع الزمني
- محتوى المحاضرات المدفوعة يُقدَّم عبر فحص وصول فقط، ولا يُخزَّن كملفات ثابتة أبدًا
- اختبارات تُصحَّح بالكامل على الخادم، وتسحب ورقة جديدة لكل محاولة من بنك أسئلة
- إعدادات اختبار لكل محاضرة — الطول ومزيج الصعوبة ودرجة النجاح — تُثبَّت على المحاولة لحظة بدئها
- تقدُّم متزامن بين الأجهزة، والنجاح يُشتق من المحاولات المُصحَّحة ولا يُقبل من المتصفح إطلاقًا
- لوحة إدارة من ١٨ شاشة: طابور التسجيل، الطلاب، الصلاحيات، بنك الأسئلة، سجل البريد، سجل التدقيق
- ٢٠ رسالة بريد تشغيلية، مستقلة عن المزوّد، وحالة التسليم متتبَّعة كحالة قائمة بذاتها
- webhook موقَّع بـ HMAC ومقيَّد بحيث لا يستطيع نموذج أن يطلب إلا وحدته هو
- ١٢ محرك محاكاة يحسب فيزياءه بدل أن يعرض إجابة مخزّنة
- منشورة على نطاق حقيقي، مع HSTS وسياسة أمان محتوى وتحديد معدّل الطلبات وقفل جهاز واحد لكل طالب
- مسارًا
- 115
- اختبارًا
- 446
- محرك محاكاة
- 12
- سطر، تصميمًا وخلفية
- 30,100

القرارات، ولماذا
سرد التقنيات المستخدمة لا يقول شيئًا. المفيد في دراسة الحالة هو القرارات التي كان لها بديل حقيقي — لذلك يذكر كل قرار هنا ثمنه، لا ما تم اختياره فحسب.
- ٠١
المحاضرات المدفوعة ليست ملفات يصل إليها الخادم
كل محتوى محاضرة يعيش خارج شجرة الملفات الثابتة، واختبار يُفشل البناء لو ظهر واحد بداخلها.
أي ملف يُقدَّم يمكن جلبه أو تخمينه أو ربطه أو كشطه، مهما كان الفحص السابق لعرضه. لذلك نُقل المحتوى خارج جذر الموقع تمامًا، ويُجمَّع مع كل طلب بعد اجتياز فحص الوصول. حماية المحتوى كلها قائمة على هذه الحقيقة البنيوية، لا على قاعدة يجب أن يتذكرها أحد.
الثمن · المحتوى يُعرض من التطبيق لا من CDN — تكلفة غير محسوسة عند هذا الحجم، مقابل منهج مدفوع لا يفصله عن أن يصير مجانيًا نقرةٌ يمنى واحدة.
- ٠٢
انتهاء الاشتراك تفرضه الساعة، لا تسمية في قاعدة البيانات
كل فحص وصول يرشّح على الطابع الزمني للانتهاء. المهمة الليلية تعيد التسمية فقط.
التصميم البديهي مهمة مجدولة تقلب الصلاحيات إلى «منتهية»، وفحص يقرأ الحالة. وهو يفشل بصمت لصالح العميل: لو توقفت المهمة لن يبلّغ أحد، ويحتفظ الجميع بوصول توقفوا عن دفع ثمنه. وعكسه يعني أن الوصول ينتهي في موعده بالضبط، سواء عملت المهمة أمس أو الشهر الماضي أو لم تعمل قط.
الثمن · التسمية القديمة تصبح تفصيلة في التقارير لا ثغرة دخول، ولوحة التحكم تقول ذلك صراحةً فلا يضطر أحد لاستنتاجه من رقم.
- ٠٣
المتصفح كان يحمل مفتاح إجابة امتحانه بنفسه
دالة واحدة تحوّل السؤال إلى JSON، وتُجمِّع الإجابة الصحيحة داخل الفرع الذي لا يعمل إلا بعد إجابة الطالب.
المنهج الأصلي كان يشحن كل خيار ومعه علامة صحته داخل مصدر الصفحة. أعادت النسخة الجديدة التصحيح إلى الخادم، وجعلت التسريب مستحيلًا بنيويًا لا غائبًا فحسب: السؤال غير المُجاب لا يوجد له مسار كود يحمل الإجابة ولا الشرح ولا ترتيبًا يلمّح إليها. وإجابة السؤال نفسه مرتين مرفوضة، وإلا أمكن للعميل إرسال كل الخيارات بالتتابع والاحتفاظ بالذي عاد صحيحًا.
الثمن · رحلة شبكة لكل إجابة بدل فحص محلي فوري — واختبار يقرأ كل محتوى محاضرة ويفشل لو عاد الترميز القديم يومًا.
- ٠٤
نموذج التسجيل يقدّم طلبًا. ولا يستطيع منح الوصول.
إرسال النموذج ينشئ صفًا في طابور. وشخص يعتمده أمام كشف حساب بنكي.
الدفع يدوي، فأي مسار يحوّل الإرسال إلى وصول كان سيسلّم المنهج المدفوع لأي شخص يعثر على رابط النموذج. وبصيغة النتيجة: لو تسرّب مفتاح التكامل غدًا، فأسوأ ما يمكن حدوثه صفوف في طابور يرفضها إنسان.
الثمن · النظام يحمل حالة مراجعة دفع ثانية مستقلة، فيظل سؤال المال قابلًا للإجابة بعد حسم سؤال الوصول — ويستطيع العميل نقل البوابة متى جهزت عملياته لذلك.
- ٠٥
بريد فاشل لا يستطيع أبدًا إلغاء تسجيل ناجح
الإرسال يقع خارج المعاملة، ودالة الإرسال لا ترفع استثناءً إلى مُستدعيها أبدًا.
أسوأ ما يمكن أن يحدث في هذا المنتج طالب دفع، ومُنِح الوصول، ولم يُبلَّغ بشيء لأن خادم بريد تعذّر الوصول إليه للحظات. لذلك تُتتبَّع حالة التسليم كحالة مستقلة لها إعادة محاولتها الخاصة، بجوار التسجيل لا بداخله.
الثمن · معالج الاستثناءات واسع عن قصد. كل مزوّد يرفع نوعًا مختلفًا، ولا يُسمح لأي منها بأن يصل إلى اعتماد.
- ٠٦
عارض الجزيئات يحسب الفيزياء، ولا يرسم الإجابة
كل سحابة إلكترونية تنفر من الأخرى على سطح كرة وحدة، والشكل الذي تراه هو وضع الاتزان.
تثبيت الأشكال يدويًا كان سيكلّف جزءًا يسيرًا من العمل، وسيبدو مطابقًا في لقطة شاشة. وكان سيكون صورةً للإجابة: زوايا الروابط تنضغط من ١٠٩٫٥° إلى ١٠٦٫٣° إلى ١٠٣٫٢° عبر الميثان والنشادر والماء لأن الأزواج الحرة تحمل وزنًا أكبر في المعادلة نفسها، لا لأن ثلاثة أرقام كُتبت. ويستطيع الطالب أن يسحب الجزيء خارج شكله ويراه يعود إليه، وهذا هو مربط الفرس التعليمي كله.
الثمن · نموذج تربيعي عكسي بسيط يستقر في حدود ١٫٣° من أرقام الكتاب، لذلك تُعرض الزاوية المثالية بجوار المحسوبة — فيتحول الفارق نفسه إلى شيء يستطيع الطالب أن يسأل عنه.
- ٠٧
قوقعة واحدة، وسجل واحد، ولوحة ألوان لكل وحدة
إضافة وحدة جديدة ملف بيانات وملف ألوان، يُختاران بالرقم.
قوقعة المنهج لا تعرف مادتها. وكل ما يجعل الوحدة عالمًا قائمًا بذاته — محاضراتها ومساراتها ومحركاتها وفهرس بحثها ولونها المميز — يعيش في ملفين يُختاران برقم الوحدة، فيبني الشريط الجانبي ولوحة التقدّم نفسيهما، ولا تُعدَّل القوقعة المشتركة لإضافة محتوى. والكراسات الأربع التي عند العميل أربعة ملفات بيانات، لا أربع عمليات بناء.
الثمن · كُتبت القوقعة حين كانت هناك وحدة واحدة، فما زالت متغيرات ألوانها تحمل اسم تلك الوحدة. وأثبتت الوحدة الثانية صحة الآلية — ٦٣ لونًا مكتوبًا يدويًا صارت token واحدًا قابلًا للتنسيق — وإعادة التسمية مُسجَّلة كبند قائم.
ميثاق المحاكاة
في المنهج اثنا عشر محركًا تفاعليًا، تخضع كلها لقاعدة واحدة: المحرك يحسب نتيجته ولا يرسمها. وهذا ليس تفضيلًا جماليًا. فالنتيجة المكتوبة يدويًا لا يمكن دفعها لاختبار صمودها، ولا يستطيع الطالب أن يكتشف شيئًا من صورةٍ لإجابة.
وبالتحديد: مختبر الغازات لا يحوي معادلة خاصة بأي قانون في أي موضع من الملف — فبويل وشارل وجاي لوساك وأفوجادرو كلها تنبثق من تثبيت متغير مختلف في معادلة الحالة نفسها. ومنحنى المعايرة يحل اتزان الشحنة متضمنًا التأيّن الذاتي للماء، ولذلك يستقر الأس الهيدروجيني عند سبعة بالضبط عند نقطة التكافؤ بدل أن ينطلق إلى ما لا نهاية فيحتاج تقييدًا. ومسطّحات منحنى التسخين ليست مرسومة مسطّحة؛ فتغيّر الحالة يمتص حرارته الكامنة كاملةً قبل أن تصبح الدرجة التالية ممكنة، فالاستواء نتيجة لا شكل.
بُني منحنى التسخين ثلاث مرات، وهذا التسلسل أنفع ما في هذا القسم. أولًا كجهاز بجوار رسم بياني: واضح من النظرة الأولى، رخيص الرسم. ثم كأربع وستين جسيمًا في صندوق ثلاثي الأبعاد يدور — أكثر إبهارًا بكثير، وأسوأ بكثير، لأنه افترض أن الطالب يعرف سلفًا أن السرعة والحرية كمّيتان مختلفتان، وهو بالضبط ما وُجدت المحاضرة لتعليمه. والذي شُحن هو النسخة الأولى مرسومة كما ينبغي، مع نقل التعليم إلى سُلَّم من خمسة أعمدة، طول كلٍّ منها بقدر الطاقة التي تكلّفها مرحلته. فحين يبدو المحرك رخيصًا، تحقّق إن كان يرسم صورةً للإجابة. وحين يبدو ذكيًا، تحقّق إن كان يفترض ما جاء ليعلّمه.
الأمان، مُختبَرًا بعين مهاجم
أُجريت المراجعة بعقلية مهاجم لا بقائمة تحقق: ٣٩ محاولة اختراق عبر ثماني هويات — زائر مجهول، وطالب مسجَّل، وآخر انتهى اشتراكه، وثالث سُحب وصوله، ورابع موقوف، وطالب ثانٍ، وصاحب المنهج، والمدير. مراجع مباشرة للكائنات على المحاضرات والمحاولات والتقدّم والعلامات المرجعية وسجلات البريد وطلبات التسجيل؛ وتمشيط المعرّفات المتسلسلة؛ واجتياز المسارات على معرّف المحتوى؛ ومسار محتوى معبوث مكتوب مباشرةً في قاعدة البيانات؛ ودرجاتٌ ونجاحٌ مُرسَلة من العميل؛ وتصعيد صلاحيات؛ وتزوير طلبات عبر المواقع على كل مسار يغيّر حالة.
رفض التطبيق الـ٣٩ كلها بحالته القائمة، وبقيت المحاولات داخل حزمة الاختبارات حتى لا يتوقف ذلك عن الصحة بصمت.
وما خرج منها: سياسة أمان محتوى بلا سكربت مضمّن ولا eval، وقد تطلّبت إزالة ٥٦ معالج حدث مضمّنًا؛ وتحديد معدّل على مسارات المصادقة؛ وقفل جهاز واحد لكل طالب. وهذا الأخير كان له تنفيذان بديهيان ورُفض كلاهما — عنوان IP لأن الهاتف يغيّره كل ساعة والمدرسة تتشاركه، وبصمة الجهاز لأن كل مدخلاتها يوفّرها الشخص نفسه المراد تعريفه.
هويتان في منتج واحد
التطبيق منصة تحتوي وحدات، لا وحدة أُضيف إليها غيرها لاحقًا، والفصل البصري مفروض بالتحميل لا بالتسمية. فصفحة المنصة لا تحمّل ملف أنماط المنهج أبدًا، وصفحة المنهج لا تحمّل ملف المنصة. والنتيجة أن واجهة المنهج بأكملها — الجزء الذي كان يعمل أصلًا — لم تحتج أي تعديل حين بُنيت المنصة حولها.
قوقعة المنصة هادئة وتحريرية عن قصد: اللون فيها ملك للوحدات، وكل وحدة تقدّم لونها المميز لبطاقتها. ودخول الوحدة يمنحك عالمها بملء الشاشة بلا أي زخرف من المنصة، والعنصر الوحيد الباقي منها بداخلها رابط واحد للخروج، منسَّق بألوان الوحدة نفسها.
قيس ذلك كله عند ثلاثة عروض وفي الوضعين الفاتح والداكن: لا فيض أفقي عند أي عرض، وتباين يجتاز معيار AA في كل موضع، ومع تعطيل الحركة لا يقف أي من العناصر الاثني عشر الظاهرة عند شفافية أقل من الكاملة — وهي الحالة التي يتلقاها زائر خفض الحركة وزائر عطّل JavaScript على السواء.
ما استُبعد عن قصد
ضبط النطاق جزء من العمل. كل بند هنا دُرس ثم استُبعد لسبب مذكور.
- الشهادات والترتيب
- الدرجات بيانات تدريب بمحاولات غير محدودة. والشهادة كانت ستجعل ذلك غير صادق.
- مستورد أسئلة
- بُني فعلًا، وحمّل ٣٢٩ سؤالًا مبدئيًا من الكراسات. لكن أي مُحلِّل فوق مستند يخمّن، والإجابة المُدخَلة خطأً تُخطِّئ طالبًا أصاب. حُذف هو واعتماده.
- مساعد ذكاء اصطناعي في المتصفح
- كان موجودًا في النسخة الأصلية، ينادي واجهة نموذج من المتصفح بلا مفتاح ولا وسيط، فما كان ليعمل أصلًا. أُزيل بناءً على طلب العميل.
- طابور مهام
- لا شيء هنا يحتاج وسيط رسائل. البريد يُرسَل داخل الطلب، والعمل الخلفي أمران مجدولان.
- أمان على مستوى الصف في قاعدة البيانات
- نظاما تصريح يجب أن يتفقا مصنعُ أخطاء. هنا قرار وصول واحد، في دالة واحدة.
المنصة في الخدمة — عليها طلاب مسجَّلون يستخدمونها — لكن العميل لم يفتح إطلاقه العلني بعد، فهي تعمل بهدوء عن قصد لا لأنها غير مكتملة. وأرقام هذه الصفحة قيست على المستودع في ٢ سبتمبر ٢٠٢٦.
التقنيات
- Django 5.2 LTS
- Python
- PostgreSQL
- JavaScript
- Railway
الخدمات
- تصميم المنتج
- هندسة الخلفية
- هندسة الواجهة
- المحاكاة التفاعلية
- مراجعة الأمان
محتاج حاجة مبنية بنفس المستوى؟
نصمم ونبني أنظمة كاملة — مسار شراء يعمل، وصلاحيات، ولوحة تحكم تدير الشغل فعليًا. والعربية عندنا ليست ترجمة تُركَّب في الآخر.
