🎮 توثيق دمج ألعاب الحدث (Event Games)

يوثّق هذا المستند الـ API الخاص بالموبايل لعرض قائمة الألعاب النشطة وترتيب المتصدرين، سواء لكل الألعاب أو لعبة بعينها.

1. API قائمة الألعاب النشطة

يُستخدم لجلب كل الألعاب النشطة حتى يتمكن الموبايل من عرض قائمة الفلاتر (فلترة الترتيب على لعبة معينة).

GET /api/v1/events/event-games/games

Middleware المطلوب:

عام — لا يتطلب تسجيل دخول

فقط: app-active + client-version-valid

يُستخدم من الفرونت (صفحات الأحداث) والموبايل بدون Bearer Token.

Query Parameters:

لا يوجد — يجلب كل الألعاب النشطة بدون فلترة.

مثال الاستجابة:

{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "Lucky Spinner Pro",
      "icon_url": "https://cdn.example.com/games/spinner.png",
      "provider": "baishun"
    },
    {
      "id": 2,
      "name": "Treasure Hunter",
      "icon_url": "https://cdn.example.com/games/treasure.png",
      "provider": "gamezi"
    }
  ]
}

حقول الاستجابة:

الحقل النوع الوصف
id integer معرف اللعبة — يُستخدم كـ game_id في طلب الترتيب
name string اسم اللعبة
icon_url string رابط أيقونة اللعبة (URL كامل)
provider string مزود اللعبة: baishun أو gamezi

2. API المتصدرين (Leaderboard)

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

GET /api/v1/events/event-games/leaderboard

Middleware المطلوب:

عام — لا يتطلب تسجيل دخول

فقط: app-active + client-version-valid

يُستخدم من الفرونت (صفحات الأحداث) والموبايل بدون Bearer Token.

Query Parameters:

البارامتر النوع القيم المقبولة الافتراضي الوصف
period string current_week / current_month / last_month current_week الفترة الزمنية للترتيب
game_id integer أي id من API الألعاب null (كل الألعاب) فلترة على لعبة معينة — اتركه فارغاً لكل الألعاب
limit integer 1 → 50 20 عدد المتصدرين المطلوب

أمثلة على الطلبات:

1️⃣ كل الألعاب — الأسبوع الحالي (الافتراضي):

GET /api/v1/events/event-games/leaderboard
GET /api/v1/events/event-games/leaderboard?period=current_week

2️⃣ لعبة معينة — الشهر الحالي:

GET /api/v1/events/event-games/leaderboard?period=current_month&game_id=1

3️⃣ كل الألعاب — الشهر الماضي — أول 10 فقط:

GET /api/v1/events/event-games/leaderboard?period=last_month&limit=10

3. نماذج الاستجابة

استجابة Leaderboard الكاملة:

{
  "success": true,
  "meta": {
    "period": "current_week",
    "game_id": null,
    "start": "2026-07-14 00:00:00",
    "end": "2026-07-20 23:59:59"
  },
  "data": [
    {
      "id": 58,
      "uid": "58",
      "uid_level": null,
      "name": "محمد أحمد",
      "current_profile_image_url": "https://cdn.example.com/photos/58.jpg",
      "hosting_agent": false,
      "level": { "icon": "https://cdn.example.com/levels/gold.png" },
      "karizma_level": { "icon": "..." },
      "exp_level": { "icon": "..." },
      "payment_level": { "icon": "..." },
      "privilege_package": null,
      "vip_order": 0,
      "gender": "male",
      "country": { "flag": "https://flagcdn.com/w320/sa.png" },
      "score": 9800
    },
    {
      "id": 123,
      "uid": "123",
      "name": "سارة علي",
      "score": 7500
      // ...
    }
  ]
}

حقول meta:

الحقلالوصف
periodالفترة الزمنية المختارة
game_idمعرف اللعبة المفلترة أو null
startتاريخ بداية الفترة
endتاريخ نهاية الفترة

حقول كل مستخدم في data[]:

الحقلالنوعالوصف
idintegerمعرف المستخدم
uidstringالـ UID المرئي للمستخدم
namestringاسم المستخدم
current_profile_image_urlstringرابط الصورة الشخصية
scoreintegerإجمالي ما أنفقه في الفترة المحددة
levelobjectمستوى النقاط (مع الأيقونة)
karizma_levelobjectمستوى الكاريزما
countryobjectالدولة مع رابط العلم
privilege_packageobject / nullباقة الامتياز النشطة (إن وجدت)

4. صفحة الويب (دمج الحدث)

صفحة الويب هي الواجهة التي تربط الحدث بشكل مرئي للمستخدمين — وهي منفصلة عن الموبايل وعن لوحة التحكم الإدارية التي بُنيت بالفعل.

الصفحة تستهلك نفس الـ API الموثّقة أعلاه:

قائمة الألعاب

تستدعي GET /api/v1/events/event-games/games لتعبئة قائمة الفلاتر في الصفحة.

المتصدرون

تستدعي GET /api/v1/events/event-games/leaderboard مع الـ query params المناسبة لعرض الترتيب حسب اختيار الزائر (الفترة + اللعبة).

✅ تحديث: الـ APIs أصبحت عامة

كلا الـ endpoints (/games و/leaderboard) أصبحا عامَين بدون auth — الفرونت يستدعيهما مباشرة بدون أي Bearer Token.

5. تدفق البيانات الكامل

الخطوة 1 — جلب الألعاب:

الموبايل/الويب ──GET /api/v1/events/event-games/games──▶ الخادم
               ◀──[{ id:1, name:"Lucky Spinner", ... }]── الخادم

               (بدون Authorization header — endpoint عام)

الخطوة 2 — عرض الكل:

الموبايل/الويب ──GET /leaderboard?period=current_week──▶ الخادم
               ◀──[{ name:"محمد", score:9800 }, ...]──── الخادم

               (بدون Authorization header — endpoint عام)

الخطوة 3 — عند اختيار لعبة معينة:

المستخدم يختار "Lucky Spinner" (id=1)
الموبايل ──GET /leaderboard?period=current_week&game_id=1──▶ الخادم
         ◀──[ترتيب المتصدرين في Lucky Spinner فقط]────────── الخادم

💡 منطق التوصية:

  • استدعِ /games مرة واحدة عند فتح الشاشة وخزّن النتيجة محلياً.
  • أضف خيار "كل الألعاب" يدوياً في الـ UI — وهو الافتراضي (بدون إرسال game_id).
  • عند تغيير الفلتر (لعبة أو فترة)، أعد استدعاء /leaderboard فقط.
  • رتّب المتصدرين في الـ UI حسب ترتيب الاستجابة — هم مرتبون بالفعل تنازلياً.

6. أكواد الخطأ

الكود HTTP السبب الحل
401 Token غير موجود أو منتهي لم يعد مطبّقاً — الـ API أصبح عاماً.
422 قيمة period غير مقبولة أو game_id غير موجود تحقق من القيم المقبولة في الجدول أعلاه.
200 + data: [] لا يوجد نشاط في هذه الفترة / اللعبة حالة طبيعية — اعرض رسالة "لا يوجد متصدرون بعد".

⚠️ ملاحظة مهمة:

المستخدمون الموجودون في قائمة الحظر (bannedUsers) يُستبعدون تلقائياً من نتائج الترتيب.