موقع لتنظيم فعالية اجتماعية (فضفضة / تعارف / استماع ونصائح) مع الحفاظ التام على خصوصية المشاركين:
- المشارك يسجّل اسمه واهتماماته وغرضه من الحضور.
- المنظّم يعطي كل مشارك اسماً مستعاراً — الاسم الحقيقي لا يظهر لأحد غير المنظّم (تُفرض الخصوصية بقواعد أمان قاعدة البيانات، لا بمجرد الإخفاء في الواجهة).
- توزيع تلقائي ذكي على ٣ جولات × ٢٠ دقيقة (فضفضة مع مستمع، تعارف مع تعارف حسب الاهتمامات المشتركة)، مع تعديل يدوي وتجنّب تكرار الشركاء بين الجولات.
- كل مشارك يتابع من هاتفه: اسمه المستعار، مع من يجلس وعلى أي طاولة، وعدّاد تنازلي متزامن.
- بعد الجولات يفتح المنظّم مرحلة الاختيار: كل مشارك يختار شخصاً واحداً ممن جلس معهم للجلوس معه بعد الفعالية — الاختيارات تظهر للمنظّم فقط، مع إبراز الاختيارات المتبادلة 💚.
بدون أي خوادم تديرها: الموقع صفحات ثابتة على GitHub Pages (مجاني)، والبيانات تتزامن عبر Firebase Realtime Database (الباقة المجانية).
- ادخل إلى console.firebase.google.com بحساب Google وأنشئ مشروعاً جديداً (أي اسم).
- من القائمة الجانبية: Build ← Realtime Database ← Create Database — اختر أقرب منطقة، وابدأ بوضع Test mode مؤقتاً.
- من القائمة الجانبية: Build ← Authentication ← Get started ← Sign-in method — فعّل Anonymous.
- من إعدادات المشروع (⚙️ ← Project settings ← Your apps): أضف تطبيق Web (رمز
</>) وانسخ كائنfirebaseConfig.
افتح الملف docs/js/firebase-config.js وعدّل:
- قيم
firebaseConfig(الصق ما نسخته من Firebase — انتبه أنdatabaseURLموجود؛ إن لم يظهر في الكائن المنسوخ فخذه من صفحة Realtime Database). ORGANIZER_PIN: الرقم السري للوحة المنظّم.
ملاحظة: مفاتيح Firebase للويب ليست أسراراً — الحماية الحقيقية تأتي من قواعد الأمان في الخطوة ٤.
من صفحة المستودع في GitHub: Settings ← Pages ← Source: Deploy from a branch ← Branch: master (أو الفرع الرئيسي) / Folder: /docs ثم Save.
بعد دقيقة سيصبح الموقع متاحاً على:
- صفحة المشاركين:
https://اسمك.github.io/اسم-المستودع/ - لوحة المنظّم:
https://اسمك.github.io/اسم-المستودع/organizer.html
- افتح لوحة المنظّم من الجهاز الذي ستديره ليلة الفعالية وأدخل الرقم السري.
- سيظهر لك بانر أصفر فيه معرّف جهازك — انسخه.
- افتح ملف
firebase-rules.jsonواستبدل كلORGANIZER_UID(تظهر ٩ مرات) بالمعرّف الذي نسخته. - الصق محتوى الملف في Firebase Console ← Realtime Database ← Rules ثم اضغط Publish.
- عد للوحة المنظّم واضغط "اعتماد هذا الجهاز" — سيختفي البانر.
⚠️ إذا مسحت بيانات المتصفح على جهاز المنظّم سيتغيّر المعرّف، وستحتاج لتكرار هذه الخطوة بالمعرّف الجديد.
- قبل الفعالية: شارك رابط الموقع. المرحلة الافتراضية "التسجيل مفتوح" — يسجّل الجميع من هواتفهم ويظهر لهم "بانتظار موافقة المنظّم".
- تبويب المشاركون: تظهر الطلبات الجديدة أعلى الجدول — اضغط "✓ قبول" لكل مدعوّ (أو "✕" لرفض دخيل؛ يُحذف تسجيله). المشارك ينتقل تلقائياً لصفحة الانتظار فور قبوله. ثم اضغط "🎲 توليد أسماء للجميع" (أو عدّل يدوياً) — يظهر الاسم المستعار فوراً على هاتف صاحبه.
- تبويب الجولات ← الجولة ١: اضغط "توزيع تلقائي"، راجع الطاولات (تعديل يدوي: اضغط شخصاً ثم آخر ليتبادلا)، ثم "نشر وبدء الجولة" — يرى كل مشارك طاولته وشريكه ويبدأ عدّاد الـ ٢٠ دقيقة متزامناً على كل الأجهزة.
- عند انتهاء الوقت اضغط "إنهاء الجولة" (استراحة)، ثم كرّر للجولتين ٢ و٣ — الخوارزمية تتجنّب تلقائياً تكرار الشركاء وتحذّرك إن اضطرت للتكرار.
- تبويب الاختيارات: اضغط "فتح مرحلة الاختيار" — يختار كل مشارك من هاتفه شخصاً واحداً ممن جلس معهم. تظهر لك الاختيارات لحظياً مع شارة 💚 اختيار متبادل عند التطابق.
- اضغط "إنهاء الفعالية" وتولَّ تنسيق اللقاءات بنفسك حفاظاً على الخصوصية.
العدد الفردي؟ الخوارزمية تُلحق الشخص المتبقي بأنسب طاولة ليجلسوا ثلاثة.
ما تضمنه قواعد الأمان بعد نشرها (الخطوة ٤):
- ✅ الاسم الحقيقي لا يستطيع قراءته إلا صاحبه والمنظّم — لا يصل لأجهزة بقية المشاركين إطلاقاً.
- ✅ الاختيارات النهائية لا يقرؤها إلا المنظّم (وكل شخص يرى اختياره هو فقط).
- ✅ لا يستطيع أحد غير المنظّم تعديل التوزيعات أو المراحل أو الأسماء المستعارة.
- ✅ المشارك يسجّل مرة واحدة فقط وأثناء فترة التسجيل فقط.
⚠️ الرقم السري للوحة المنظّم بوابة شكلية في المتصفح فقط — القفل الحقيقي هو معرّف جهاز المنظّم في القواعد.- ✅ أي شخص لديه الرابط يستطيع طلب التسجيل، لكن لا يدخل الفعالية (ولا التوزيع) إلا بعد موافقة المنظّم — والقواعد تمنع تقنياً أن يقبل أحد نفسه بنفسه.
⚠️ إن أبقيت قاعدة البيانات في وضع الاختبار (Test mode) دون نشر القواعد، فكل البيانات مقروءة لمن يملك عنوان قاعدة البيانات — لا تتجاوز الخطوة ٤ لفعالية حقيقية.
python3 -m http.server 8000 --directory docs
# ثم افتح http://localhost:8000 (المشارك) و http://localhost:8000/organizer.html (المنظّم)لمحاكاة عدة مشاركين افتح عدة نوافذ تصفح خفي (كل نافذة تحصل على هوية مجهولة مستقلة).
اختبار خوارزمية التوزيع (بدون Firebase):
node --input-type=module -e "import('./docs/js/matching.js').then(m => console.log(m.matchRound([{uid:'a',purpose:'vent',interests:[]},{uid:'b',purpose:'listen',interests:[]}], new Map())))"| المشكلة | الحل |
|---|---|
| صفحة "الموقع غير مهيأ" | لم تُلصق إعدادات Firebase في docs/js/firebase-config.js |
PERMISSION_DENIED عند المنظّم |
معرّف الجهاز غير مطابق لما في القواعد — أعد الخطوة ٤ |
| المشارك لا يستطيع التسجيل | تأكد أن المرحلة "التسجيل مفتوح" (تبويب إعدادات) وأن Anonymous Auth مفعّل |
| العدّاد غير متزامن | يعتمد على توقيت خادم Firebase — تأكد من اتصال الإنترنت على الأجهزة |
| مشارك فقد جلسته (مسح المتصفح) | سيُعامل كجهاز جديد — سجّله المنظّم يدوياً أو ليسجّل من جديد إن كان التسجيل مفتوحاً |