* feat(docs): mirror every docs/ page in all 65 locales Extends the documentation mirrors from the 22-page core set (#13940) to every Markdown page under docs/: 152 sources x 65 locales = 9,880 mirrors (6,208 new), language bars rewritten for the full locale list, state adopted so the blocking drift gate now covers all 152 pages. run-translation.mjs: an oversized block made only of table rows or list items (PROVIDER_REFERENCE.md 244-row table, FREE_TIERS.md 71-item list) is cut at item boundaries and rejoined without a blank line — the single 16-40 KB request outlived the backend socket for verbose scripts. 48 older mirrors whose tables had lost rows were retranslated with --force. * docs(i18n): refresh mirrors for the sources the base changed since the branch cut Section-level retranslation of the 29 docs (and README.md) whose source or mirrors moved on release/v3.8.51 during the run, then state adoption; the drift gate is green again on the merged tree.
63 KiB
Gamification & Leaderboard System (العربية)
🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW
مصدر الحقيقة:
src/lib/gamification/، وsrc/lib/db/gamification.ts، وsrc/app/api/gamification/آخر تحديث: 2026-06-28 — v3.8.40
يتضمن OmniRoute طبقة تلعيب تعتمد النهج المحلي أولًا، وتكافئ المستخدمين على التفاعل مع المنصة — من خلال إجراء الطلبات، والتبديل بين المزوّدين، وإنشاء التركيبات، ومشاركة الرموز، والمساهمة في المجتمع. تُخزَّن جميع الحالات في SQLite؛ أما الاتحاد مع خوادم المجتمع فهو اختياري ويعتمد على الدفع.
صُمم النظام ليكون عديم زمن الاستجابة على المسار الحرج — إذ تُرسَل أحداث التلعيب بأسلوب الإطلاق والنسيان من مسار معالجة الطلبات، ولا تحجب أبدًا استجابة LLM.
نظرة عامة
الغرض
زيادة تفاعل المستخدمين والاحتفاظ بهم من خلال توفير تقدّم مرئي (نقاط الخبرة، والمستويات، والشارات)، وإثبات اجتماعي (لوحات المتصدرين)، وحوافز اقتصادية (مشاركة الرموز، ومكافآت الدعوات).
النطاق
| الميزة | الوصف |
|---|---|
| نقاط الخبرة والمستويات | كسب نقاط خبرة لكل إجراء؛ والترقي وفق منحنى متعدد الحدود |
| الشارات | أكثر من 20 إنجازًا موزعة على 5 فئات وبأربع درجات من الندرة |
| سلاسل النشاط | تتبّع الاستخدام النشط يوميًا مع السلسلة الحالية والأطول |
| لوحات المتصدرين | نطاقات عامة وأسبوعية وشهرية ولمشاركة الرموز والمساهمات |
| مشاركة الرموز | تحويل الأرصدة بين المستخدمين عبر دفتر أستاذ مزدوج القيد |
| الدعوة والاسترداد | رموز إحالة مخزّنة بصيغة مجزأة باستخدام SHA-256 |
| خوادم المجتمع | الاتحاد مع مثيلات OmniRoute خارجية |
| مكافحة الغش | احتساب النقاط من جانب الخادم، وتحديد المعدل، واكتشاف الشذوذ بدرجة z |
مبادئ التصميم
- محلي أولًا — تُخزَّن جميع الحالات في SQLite، ولا حاجة إلى خدمات خارجية.
- غير حاجب — تُرسَل الأحداث بأسلوب الإطلاق والنسيان؛ ولا يتأخر مسار استجابة LLM أبدًا بسبب منطق التلعيب.
- الخادم هو المرجع — تُحتسب نقاط الخبرة على جانب الخادم فقط؛ ولا يمكن للعملاء تضخيم النتائج.
- مراعٍ للخصوصية — المشاركة في لوحة المتصدرين اختيارية؛ ويمكن للمستخدمين إخفاء ملفاتهم الشخصية.
- جاهز للاتحاد — يمكن لخوادم المجتمع دفع النتائج عبر API موقّعة؛ والمزامنة استبدالية وليست تراكمية.
البنية
سير العمل عالي المستوى
طلب العميل
→ /v1/chat/completions
→ handleChatCore() [open-sse/handlers/chatCore.ts]
→ ... (مسار المعالجة الحالي) ...
→ إرسال استجابة المنبع إلى العميل
→ setImmediate (إطلاق ونسيان):
→ emitGamificationEvent() [src/lib/gamification/events.ts]
→ awardXp() [src/lib/gamification/xp.ts]
→ updateStreak() [src/lib/gamification/streaks.ts]
→ evaluateBadges() [src/lib/gamification/badges.ts]
→ updateLeaderboard() [src/lib/gamification/leaderboard.ts]
→ checkAnomalies() [src/lib/gamification/antiCheat.ts]
يُعد باعث الأحداث نقطة التكامل الوحيدة. يستدعي chatCore.ts
الدالة emitGamificationEvent() بعد إرسال الاستجابة؛ ثم توزّع وحدة الأحداث
العمل على الأنظمة الفرعية لنقاط الخبرة، وسلاسل النشاط، والشارات، ولوحات
المتصدرين، ومكافحة الغش.
مخطط تبعيات الوحدات
src/lib/gamification/
events.ts ← نقطة الدخول (تُستدعى من chatCore.ts)
├── xp.ts ← احتساب نقاط الخبرة وتحديد المستوى
├── streaks.ts ← تتبّع سلسلة النشاط اليومية
├── badges.ts ← تقييم معايير الشارات
├── leaderboard.ts ← احتساب الترتيب والبث عبر SSE
├── antiCheat.ts ← تحديد المعدل واكتشاف الشذوذ
├── sharing.ts ← دفتر أستاذ تحويل الرموز
├── invites.ts ← إدارة رموز الدعوة والاسترداد
├── servers.ts ← اتحاد خوادم المجتمع
└── notifications.ts ← تدفق إشعارات SSE
src/lib/db/
gamification.ts ← جميع عمليات CRUD (8 جداول)
src/app/api/gamification/
leaderboard/ ← GET للتصنيفات، وPOST للتحديث اليدوي
leaderboard/stream ← تحديثات فورية عبر SSE
transfer/ ← GET للسجل، وPOST لإرسال الرموز
invite/ ← GET/POST للرموز، وDELETE للإلغاء
invite/redeem/ ← POST لاسترداد رمز
servers/ ← GET/POST/DELETE لخوادم المجتمع
federation/score/ ← POST لدفع النتيجة إلى الخادم
federation/leaderboard/ ← GET لجلب لوحة المتصدرين من الخادم
notifications/ ← إشعارات الشارات والترقية عبر SSE
anomalies/ ← GET لتقارير الشذوذ (للمشرف)
rotate/ ← POST لتدوير أسرار رموز الدعوة
طبقة البيانات
جداول قاعدة البيانات
توجد جميع الجداول في قاعدة بيانات OmniRoute SQLite الرئيسية، والتي أنشأها ملف الترحيل
060_create_gamification.sql. يُورَّث تسجيل WAL من النسخة المفردة
getDbInstance() في src/lib/db/core.ts.
┌─────────────────────────┐ ┌──────────────────────────┐
│ leaderboard │ │ user_levels │
├─────────────────────────┤ ├──────────────────────────┤
│ id TEXT PK │ │ api_key_id TEXT PK │
│ api_key_id TEXT │ │ xp INTEGER │
│ scope TEXT │ │ level INTEGER │
│ score INTEGER │ │ title TEXT │
│ period TEXT │ │ updated_at TEXT │
│ updated_at TEXT │ └──────────────────────────┘
└─────────────────────────┘
│
│ 1:N
▼
┌─────────────────────────┐ ┌──────────────────────────┐
│ user_badges │ │ badge_definitions │
├─────────────────────────┤ ├──────────────────────────┤
│ id TEXT PK │ │ id TEXT PK │
│ api_key_id TEXT │ │ name TEXT │
│ badge_id TEXT FK │ │ category TEXT │
│ earned_at TEXT │ │ rarity TEXT │
│ notified INTEGER │ │ criteria_type TEXT │
└─────────────────────────┘ │ criteria TEXT(JSON) │
│ description TEXT │
│ icon TEXT │
│ hidden INTEGER │
└──────────────────────────┘
┌─────────────────────────┐ ┌──────────────────────────┐
│ xp_audit_log │ │ token_ledger │
├─────────────────────────┤ ├──────────────────────────┤
│ id TEXT PK │ │ id TEXT PK │
│ api_key_id TEXT │ │ from_key_id TEXT │
│ action TEXT │ │ to_key_id TEXT │
│ xp_awarded INTEGER │ │ amount INTEGER │
│ metadata TEXT(JSON)│ │ idempotency_key TEXT UQ │
│ created_at TEXT │ │ created_at TEXT │
└─────────────────────────┘ └──────────────────────────┘
┌─────────────────────────┐ ┌──────────────────────────┐
│ invite_tokens │ │ community_servers │
├─────────────────────────┤ ├──────────────────────────┤
│ id TEXT PK │ │ id TEXT PK │
│ api_key_id TEXT │ │ name TEXT │
│ code TEXT UQ │ │ url TEXT │
│ token_hash TEXT │ │ token_hash TEXT │
│ uses INTEGER │ │ status TEXT │
│ max_uses INTEGER │ │ last_sync TEXT │
│ created_at TEXT │ │ created_at TEXT │
│ expires_at TEXT │ └──────────────────────────┘
└─────────────────────────┘
وحدة النطاق: src/lib/db/gamification.ts
تتبع نمط OmniRoute القياسي — تستورد getDbInstance() من
core.ts، وتُصدِّر دوال CRUD محددة الأنواع. لا توجد استعلامات SQL أولية في معالجات المسارات.
الدوال الرئيسية:
| الدالة | الوصف |
|---|---|
upsertLeaderboardEntry() |
إدراج أو تحديث النتيجة للقيم (api_key_id, scope, period) |
getLeaderboard() |
تصنيفات مقسّمة إلى صفحات لنطاق/فترة محددة |
getUserLevel() |
الحصول على سجل مستوى المستخدم أو إنشاؤه |
updateUserLevel() |
تعيين XP والمستوى واللقب ذريًا |
getBadgeDefinitions() |
جميع تعريفات الشارات (مع إمكانية التصفية) |
getUserBadges() |
الشارات التي حصل عليها المستخدم |
awardBadge() |
إدراج استحقاق الشارة (متكرر آمنًا استنادًا إلى badge_id) |
logXpAction() |
الإلحاق بـ xp_audit_log |
getXpAuditLog() |
سجل تدقيق مقسّم إلى صفحات لمستخدم |
insertLedgerEntry() |
تحويل بقيد مزدوج (ضمن معاملة) |
getBalance() |
مجموع ما استلمه المستخدم مطروحًا منه ما أرسله |
getTransferHistory() |
سجل تحويلات مقسّم إلى صفحات |
createInviteToken() |
إدراج رمز دعوة + رمز مميز مُجزّأ |
redeemInviteToken() |
البحث باستخدام الرمز والتحقق وزيادة عدد مرات الاستخدام |
upsertCommunityServer() |
تسجيل خادم اتحادي أو تحديثه |
getCommunityServers() |
عرض قائمة الخوادم الخاصة بمستخدم |
deleteCommunityServer() |
إزالة تسجيل خادم |
نظام XP / المستويات
الملف: src/lib/gamification/xp.ts
منحنى المستويات
تتبع نقاط XP المطلوبة للوصول إلى المستوى n منحنى متعدد الحدود:
xp_for_level(n) = floor(100 * n^1.5)
| المستوى | XP للمستوى التالي | XP التراكمية | اللقب |
|---|---|---|---|
| 1 | 100 | 100 | مبتدئ |
| 5 | 1,118 | 2,415 | مبتدئ |
| 10 | 3,162 | 10,523 | مستكشف |
| 25 | 12,500 | 86,024 | مستكشف |
| 50 | 35,355 | 345,529 | خبير |
| 75 | 64,952 | 948,683 | متمرس |
| 100 | 100,000 | 2,050,000 | أسطورة |
الألقاب
| نطاق المستويات | اللقب |
|---|---|
| 1 – 9 | مبتدئ |
| 10 – 24 | مستكشف |
| 25 – 49 | خبير |
| 50 – 74 | متمرس |
| 75 – 100 | أسطورة |
مكافآت XP
| الإجراء | XP | الوصف |
|---|---|---|
request |
1 | لكل طلب API يُوجَّه عبر OmniRoute |
provider_switch |
5 | التبديل إلى مزود مختلف |
model_switch |
3 | التبديل إلى نموذج مختلف |
combo_create |
10 | إنشاء تركيبة جديدة |
combo_use |
2 | استخدام تركيبة لطلب |
token_share |
1 | لكل 1 000 رمز تتم مشاركتها مع مستخدم آخر |
invite_redeem |
50 | استرداد رمز دعوة |
daily_login |
5 | الاستخدام النشط اليومي (مرة واحدة يوميًا) |
streak_bonus |
2 | لكل يوم متتالٍ في السلسلة (مضروبًا في طول السلسلة) |
badge_unlock |
10 | فتح شارة |
مسار المنح
export async function awardXp(
apiKeyId: string,
action: XpAction,
metadata?: Record<string, unknown>
): Promise<{ xp: number; level: number; title: string; levelUp: boolean }>;
- ابحث عن
XP_REWARDS[action]للحصول على مقدار XP. - مرِّر العملية عبر
checkRateLimit()(مكافحة الغش: بحد أقصى 1000 XP/دقيقة لكل مفتاح). - افتح معاملة:
- اقرأ الصف الحالي من
user_levels. - أضف XP؛ وأعد حساب المستوى عبر
levelFromXp(totalXp). - إذا تغير المستوى، فعيّن
levelUp = true. - حدّث صف
user_levels. - أدرج سجلًا في
xp_audit_log.
- اقرأ الصف الحالي من
- أعد النتيجة. يتولى المستدعي معالجة الإشعارات.
الدالة المساعدة: levelFromXp(totalXp)
تكرّر العملية عبر المستويات من 1 إلى 100، مع جمع xp_for_level(n) حتى تتجاوز نقاط XP التراكمية
القيمة totalXp. تُعيد أعلى مستوى تم استيفاء عتبته.
درجة تعقيدها O(100) — وهي مقبولة لأن الحد الأقصى للمستويات هو 100.
نظام الشارات
الملف: src/lib/gamification/badges.ts
الفئات
| الفئة | الوصف | أمثلة على الشارات |
|---|---|---|
usage |
إنجازات مرحلية تعتمد على حجم الاستخدام | الطلب الأول، 1K طلب، 100K |
sharing |
مشاركة الرموز والإحالات | المشاركة الأولى، كريم (10 مشاركات) |
contribution |
المشاركة المجتمعية | منشئ التركيبات، مستكشف المزودين |
streak |
الاستمرارية بمرور الوقت | محارب الأسبوع، المخلص الشهري |
rare |
إنجازات مخفية أو يصعب تحقيقها | مستخدم مبكر، مُبلّغ عن الأخطاء |
درجات الندرة
| الندرة | اللون | مؤشر الاحتمالية |
|---|---|---|
common |
رمادي | معظم المستخدمين |
uncommon |
أخضر | المستخدمون النشطون |
rare |
أزرق | المستخدمون المتفانون |
legendary |
ذهبي | أعلى 1% |
أنواع المعايير
| النوع | الحقل | الوصف |
|---|---|---|
action_count |
count |
تنفيذ الإجراء N مرة (مثلًا، 1000 طلب) |
streak |
days |
الحفاظ على سلسلة لمدة N يومًا متتاليًا |
unique_count |
field, n |
استخدام N من القيم الفريدة (مثلًا، 10 نماذج مختلفة) |
rank |
scope, n |
الوصول إلى المرتبة N ضمن نطاق لوحة صدارة |
first |
— | أن تكون أول من ينفذ إجراءً |
hidden |
(متغير) | لا تظهر المعايير حتى تُكتسب الشارة |
تُخزَّن تعريفات الشارات في badge_definitions بوصفها criteria بتنسيق JSON:
{
"type": "action_count",
"action": "request",
"count": 1000
}
مسار التقييم
emitGamificationEvent(event)
→ evaluateBadges(apiKeyId, event)
→ getBadgeDefinitions() # جميع التعريفات
→ getUserBadges(apiKeyId) # الشارات المكتسبة بالفعل (تُتخطى)
→ لكل شارة غير مكتسبة:
→ matchesCriteria(badge, event, userState)
→ عند التطابق: awardBadge(apiKeyId, badgeId)
→ إعادة حمولة الإشعار
يعتمد التقييم على الأحداث — إذ يُنفَّذ بعد كل حدث من أحداث التلعيب، لكنه
لا يتحقق إلا من الشارات التي يتوافق criteria.type الخاص بها مع إجراء الحدث. وهذا
يحافظ على سرعة التقييم (< 5ms لمعظم الأحداث).
matchesCriteria(badge, event, userState)
| نوع المعيار | التحقق |
|---|---|
action_count |
getActionCount(apiKeyId, action) >= count |
streak |
getCurrentStreak(apiKeyId) >= days |
unique_count |
getUniqueCount(apiKeyId, field) >= n |
rank |
getRank(apiKeyId, scope) <= n |
first |
لا يوجد إدخال سابق في xp_audit_log لنوع الإجراء هذا |
hidden |
يفوّض التحقق إلى الفحص الفرعي المناسب |
الشارات المدمجة (20+)
القائمة الكاملة للشارات
| الشارة | الفئة | الندرة | المعايير |
|---|---|---|---|
| الخطوات الأولى | الاستخدام | شائعة | طلب واحد |
| بداية الانطلاق | الاستخدام | شائعة | 100 طلب |
| مستخدم متمرس | الاستخدام | غير شائعة | 1,000 طلب |
| قائد المئة | الاستخدام | نادرة | 10,000 طلب |
| القوة المطلقة | الاستخدام | أسطورية | 100,000 طلب |
| المتنقل بين المزودين | المساهمة | شائعة | استخدام 5 مزودين مختلفين |
| خبير المزودين | المساهمة | غير شائعة | استخدام 20 مزودًا مختلفًا |
| مهندس التركيبات | المساهمة | غير شائعة | إنشاء 5 تركيبات |
| أستاذ التركيبات | المساهمة | نادرة | إنشاء 25 تركيبة |
| المشاركة الأولى | المشاركة | شائعة | عملية نقل رموز واحدة |
| كريم | المشاركة | غير شائعة | 10 عمليات نقل رموز |
| مُحسن | المشاركة | نادرة | نقل 10,000 رمز إجمالًا |
| مُحيل | المشاركة | شائعة | إحالة ناجحة واحدة |
| منشئ الشبكات | المشاركة | غير شائعة | 10 إحالات ناجحة |
| محارب الأسبوع | الاستمرارية | غير شائعة | استمرارية لمدة 7 أيام |
| مخلص شهريًا | الاستمرارية | نادرة | استمرارية لمدة 30 يومًا |
| لا يمكن إيقافه | الاستمرارية | أسطورية | استمرارية لمدة 365 يومًا |
| المتبني المبكر | نادرة | أسطورية | الانضمام خلال الفترة التجريبية |
| رائد الضغط | نادرة | غير شائعة | استخدام الضغط 100 مرة |
| جامع المهارات | نادرة | نادرة | استخدام 10 مهارات مختلفة |
| مستكشف النماذج | المساهمة | غير شائعة | استخدام 15 نموذجًا مختلفًا |
متتبّع السلسلة
الملف: src/lib/gamification/streaks.ts
نموذج البيانات
تُخزَّن السلاسل في جدول key_value (وهو جدول أدوات مساعدة مشترك) ضمن
مفاتيح ذات نطاقات اسمية:
| المفتاح | القيمة | الوصف |
|---|---|---|
gamification:streak:{keyId} |
{current},{longest},{lastDate} |
بيانات السلسلة النشطة |
المنطق
export async function updateStreak(
apiKeyId: string
): Promise<{ current: number; longest: number; milestone: boolean }>;
- قراءة سجل السلسلة من
key_value. - تحليل
{current}و{longest}و{lastDate}(سلسلة تاريخ بتنسيق ISO). - إذا كان
lastDate === today— فلا تغيير (احتُسب هذا اليوم بالفعل). - إذا كان
lastDate === yesterday— فتُزاد قيمةcurrent، وتُحدَّثlongestعند الحاجة. - إذا كان
lastDate < yesterday— فتُعاد تهيئةcurrent = 1(انقطعت السلسلة). - كتابة السجل المحدَّث.
- التحقق من المحطات: 7 و14 و30 و60 و90 و180 و365 يومًا. عند تجاوز إحداها، تُعيَّن
milestone = true(تمنح الجهة المستدعية نقاط XP وتتحقق من الشارات).
الحالات الحدّية
- المنطقة الزمنية: تستخدم السلاسل تواريخ UTC (
new Date().toISOString().slice(0, 10)). وهذا مقصود — إذ تمنع المنطقة الزمنية القياسية الواحدة التحايل عبر التنقل بين المناطق الزمنية. - المستخدمون الجدد: لا يوجد سجل للسلسلة؛ ينشئ الطلب الأول سجلًا بالقيم
current=1, longest=1, lastDate=today. - طلبات متعددة يوميًا: لا يزيد السلسلة سوى الطلب الأول خلال يوم UTC.
لوحة المتصدرين
الملف: src/lib/gamification/leaderboard.ts
النطاقات
| النطاق | الفترة | الوصف |
|---|---|---|
global |
all |
إجمالي نقاط XP التراكمية على مدار الوقت |
weekly |
week |
نقاط XP المكتسبة في أسبوع UTC الحالي (الاثنين-الأحد) |
monthly |
month |
نقاط XP المكتسبة في شهر UTC الحالي |
tokens_shared |
all |
إجمالي الرموز المنقولة إلى الآخرين |
contributions |
all |
التركيبات المنشأة + المزوّدون المستخدمون + المهارات المستخدمة |
حساب الترتيب
تُحسب المراتب عند وقت القراءة ولا تُخزَّن. يمنع ذلك تقادم بيانات الترتيب ويلغي الحاجة إلى مهام دورية لإعادة حساب المراتب.
export async function getLeaderboard(
scope: LeaderboardScope,
period: string,
limit: number,
offset: number
): Promise<{ entries: LeaderboardEntry[]; total: number }>;
نمط الاستعلام:
SELECT api_key_id, score,
RANK() OVER (ORDER BY score DESC) as rank
FROM leaderboard
WHERE scope = ? AND period = ?
ORDER BY score DESC
LIMIT ? OFFSET ?
تدوير الفترات
تُدوَّر لوحات المتصدرين الأسبوعية والشهرية تلقائيًا:
- الأرشفة: عند حد الفترة، تُنسخ الإدخالات الحالية إلى
leaderboard_archiveمع تسمية الفترة. - إعادة الضبط: تُحذف إدخالات الفترة المنتهية.
- التشغيل: يُجرى التحقق عند كل استدعاء لـ
updateLeaderboard()؛ ويؤدي أول طلب في فترة جديدة إلى تشغيل التدوير.
يضمن ذلك إعادة ضبط اللوحات الأسبوعية كل يوم اثنين في الساعة 00:00 بتوقيت UTC، وإعادة ضبط اللوحات الشهرية في اليوم الأول من كل شهر.
تحديثات SSE في الوقت الفعلي
نقطة النهاية: GET /api/gamification/stream
العميل → GET /api/gamification/stream
→ إنشاء اتصال SSE
→ يرسل الخادم فورًا لقطة لأعلى 10 مراكز في لوحة المتصدرين
→ كل 5 ثوانٍ: إرسال أعلى 10 مراكز المحدَّثة إذا طرأ تغيير
→ كل 15 ثانية: تعليق نبض اتصال (": heartbeat\n\n")
→ يقطع العميل الاتصال → التنظيف (إزالة المستمع)
تنسيق الحدث:
event: leaderboard
data: {"scope":"global","entries":[...]}
event: leaderboard
data: {"scope":"weekly","entries":[...]}
: heartbeat
يتتبّع مدير SSE العملاء المتصلين لكل نطاق، ولا يرسل التحديثات إلا عندما تكون بيانات لوحة المتصدرين قد تغيّرت فعليًا منذ آخر إرسال.
مشاركة الرموز
الملف: src/lib/gamification/sharing.ts
دفتر القيد المزدوج
يُنشئ كل تحويل صفّين في token_ledger:
| الصف | from_key_id |
to_key_id |
amount |
|---|---|---|---|
| مدين | المُرسِل | المُستلِم | +المبلغ |
| دائن | المُستلِم | المُرسِل | -المبلغ |
مهلًا — الاصطلاح هو:
| الصف | from_key_id |
to_key_id |
amount |
المعنى |
|---|---|---|---|---|
| إرسال | المُرسِل | المُستلِم | +المبلغ | تدفق خارج من المُرسِل |
| استلام | المُستلِم | المُرسِل | +المبلغ | تدفق داخل إلى المُستلِم |
يُحتسب الرصيد كما يلي:
SELECT
COALESCE(SUM(CASE WHEN to_key_id = ? THEN amount ELSE 0 END), 0)
- COALESCE(SUM(CASE WHEN from_key_id = ? THEN amount ELSE 0 END), 0)
AS balance
FROM token_ledger
WHERE from_key_id = ? OR to_key_id = ?
سير عملية التحويل
export async function transferTokens(
fromKeyId: string,
toKeyId: string,
amount: number,
idempotencyKey: string
): Promise<{ success: boolean; balance: number }>;
- التحقق من الصحة:
amount > 0وfromKeyId !== toKeyId. - التكرار الآمن: تحقّق مما إذا كانت
idempotency_keyموجودة بالفعل في دفتر الأستاذ. إذا كانت موجودة، فأعِد النتيجة المخزنة مؤقتًا. - المعاملة (معاملة SQLite واحدة):
a. احسب رصيد المُرسِل.
b. إذا كان
balance < amount، فألغِ العملية (الرصيد غير كافٍ). c. أدرِج صف الإرسال (from=sender,.
تحديد المعدّل
- بحد أقصى 10 تحويلات في الدقيقة لكل مفتاح API.
- بحد أقصى 10,000 رمز لكل تحويل منفرد.
- بحد أقصى 100,000 رمز مُحوَّل يوميًا لكل مفتاح API.
رموز الدعوة والاسترداد
الملف: src/lib/gamification/invites.ts
تنسيق الرمز
- الرمز: أبجدي رقمي مكوّن من 8 أحرف (مثل
A3K9-X7M2)، سهل القراءة، ويُعرَض للمستخدم. - الرمز المميّز: رمز مميّز عشوائي بحجم 32 بايت، يُخزَّن كتجزئة SHA-256. يُستخدم للاسترداد البرمجي (مثل روابط URL).
التخزين
| العمود | القيمة |
|---|---|
code |
A3K9X7M2 (فريد، مفهرس) |
token_hash |
SHA-256(raw_token) |
يُعاد الرمز المميّز الخام إلى المستخدم مرة واحدة فقط عند إنشائه. لا تقوم OmniRoute بتخزينه أو عرضه مرة أخرى مطلقًا — ولا تبقى سوى التجزئة.
منع الإحالة الذاتية
عندما يسترد مستخدم رمزًا، يتحقّق النظام مما يلي:
- أن الرمز ينتمي إلى
api_key_idمختلف. - أن المستخدم الذي يجري الاسترداد لم يسبق له استرداد أي رمز من المُحيل نفسه
(عبر ربط
invite_tokens+ سجل الاسترداد).
إذا فشل أي من التحقّقين، يُرفض الاسترداد مع رسالة خطأ واضحة.
انتهاء الصلاحية والحدود
- القيمة الافتراضية لـ
max_uses: 10 (قابلة للتهيئة عند الإنشاء). - القيمة الافتراضية لـ
expires_at: 30 يومًا من تاريخ الإنشاء. - تُرجع الرموز منتهية الصلاحية أو المستنفدة HTTP 410 Gone.
اتحاد خوادم المجتمع
الملف: src/lib/gamification/servers.ts
الاتصال
يُسجَّل خادم مجتمع عبر رمز دعوة صادر عن الخادم البعيد. تقوم النسخة المحلية بما يلي:
- تستقبل رمز الدعوة (مثلًا، عند لصقه في لوحة المعلومات).
- تستدعي
POST /api/gamification/federation/leaderboardعلى الخادم البعيد للتحقق من صحة الرمز وجلب لوحة المتصدرين الحالية. - تخزّن سجل الخادم مع
status: connected.
نموذج المزامنة
يستخدم الاتحاد مزامنة الاستبدال، وليس المزامنة التراكمية:
النسخة المحلية خادم المجتمع
│ │
├── إرسال النقاط ─────────────►│ POST /federation/score
│ { api_key_id, score } │ (يتحقق الخادم من تجزئة الرمز)
│ │
├── جلب لوحة المتصدرين ───────►│ GET /federation/leaderboard
│◄── أعلى N من الإدخالات ──────┤ (تستبدل ذاكرة التخزين المؤقت المحلية)
│ │
└── فحص السلامة ──────────────►│ GET /federation/health
(كل 60 ثانية، بمهلة 5 ثوانٍ) │
المصادقة
تتضمن طلبات الاتحاد ما يلي:
Authorization: Bearer <raw_token>
X-Federation-Version: 1
يُجزِّئ الخادم البعيد الرمز ويبحث عن الصف المطابق في community_servers. يؤدي ذلك إلى تجنب إرسال التجزئة المخزنة.
مراقبة السلامة
يتتبع كل سجل خادم ما يلي:
| الحقل | الوصف |
|---|---|
status |
connected، degraded، unreachable |
last_sync |
الطابع الزمني ISO لآخر مزامنة ناجحة |
failures |
حالات فشل فحص السلامة المتتالية |
بعد 5 حالات فشل متتالية، تتغير الحالة إلى unreachable وتتوقف المزامنة مؤقتًا حتى ينجح فحص سلامة يدوي.
مكافحة الغش
الملف: src/lib/gamification/antiCheat.ts
احتساب النقاط من جانب الخادم
تُجرى جميع حسابات XP في src/lib/gamification/xp.ts. لا يرسل العملاء نقاطًا مطلقًا، بل يرسلون إجراءات، ويحسب الخادم XP. لا يمكن الكتابة إلى العمود leaderboard.score إلا بواسطة التعليمات البرمجية التي تعمل من جانب الخادم.
تحديد المعدل
| الحد الأقصى | القيمة | النطاق |
|---|---|---|
| الحد الأقصى لـ XP في الدقيقة | 1,000 | لكل مفتاح API |
| الحد الأقصى للتحويلات في الدقيقة | 10 | لكل مفتاح API |
| الحد الأقصى لمبلغ التحويل | 10,000 | لكل تحويل |
| الحد الأقصى للتحويلات اليومية | 100,000 | لكل مفتاح API |
تستخدم حدود المعدل نافذة منزلقة في الذاكرة (بالنمط نفسه المستخدم في RateLimitManager ضمن open-sse/services/). ويجري الرجوع إلى عدادات مستندة إلى SQLite إذا أُعيد تشغيل العملية.
اكتشاف الحالات الشاذة باستخدام الدرجة المعيارية Z
يحتفظ النظام، لكل مفتاح API، بنافذة متحركة لمدة 7 أيام لمقدار XP المكتسب في الساعة. عند كل منح لـ XP:
- احسب معدل XP الحالي للمستخدم في الساعة.
- احسب متوسط المجتمع والانحراف المعياري.
- احسب
z = (user_rate - mean) / stddev. - إذا كانت
z > 3.0(3 انحرافات معيارية)، فضع علامة عليها كحالة شاذة.
تُسجَّل الحالات الشاذة في xp_audit_log مع action = 'anomaly_detected'، وتُعرض في لوحة معلومات المسؤول.
سجل التدقيق
يُسجَّل كل منح لـ XP، وتحويل، وحصول على شارة، واكتشاف حالة شاذة في xp_audit_log مع ما يلي:
| الحقل | الوصف |
|---|---|
api_key_id |
مَن |
action |
ما حدث (xp_award، transfer، anomaly، …) |
xp_awarded |
المقدار (0 للأحداث غير المرتبطة بـ XP) |
metadata |
JSON يتضمن السياق (نوع الإجراء، الهدف، …) |
created_at |
الوقت (ISO 8601) |
يمكن للمسؤولين الاستعلام عن سجل التدقيق الكامل عبر GET /api/gamification/anomalies.
مسارات API
تتبع جميع المسارات نمط OmniRoute القياسي:
المسار → طلب CORS التمهيدي → التحقق من نص الطلب (Zod) → المصادقة (extractApiKey)
→ المعالج
نقاط النهاية
| الطريقة | المسار | الوصف | المصادقة |
|---|---|---|---|
| GET | /api/gamification/leaderboard |
الحصول على لوحة المتصدرين (النطاق، الفترة، ترقيم الصفحات) | اختيارية |
| POST | /api/gamification/leaderboard |
فرض تحديث ذاكرة التخزين المؤقت للوحة المتصدرين | مطلوبة |
| GET | /api/gamification/stream |
تحديثات فورية للوحة المتصدرين عبر SSE | اختيارية |
| GET | /api/gamification/transfer |
الحصول على سجل التحويلات (ترقيم الصفحات) | مطلوبة |
| POST | /api/gamification/transfer |
إرسال الرموز إلى مستخدم آخر | مطلوبة |
| GET | /api/gamification/invite |
عرض رموز الدعوة الخاصة بي | مطلوبة |
| POST | /api/gamification/invite |
إنشاء رمز دعوة جديد | مطلوبة |
| DELETE | /api/gamification/invite |
إبطال رمز دعوة | مطلوبة |
| POST | /api/gamification/invite/redeem |
استرداد رمز دعوة | مطلوبة |
| GET | /api/gamification/servers |
عرض خوادم المجتمع | مطلوبة |
| POST | /api/gamification/servers |
الاتصال بخادم مجتمع | مطلوبة |
| DELETE | /api/gamification/servers |
قطع الاتصال بخادم مجتمع | مطلوبة |
| POST | /api/gamification/federation/score |
إرسال النتيجة إلى خادم بعيد | اتحاد |
| GET | /api/gamification/federation/leaderboard |
جلب لوحة المتصدرين من خادم بعيد | اتحاد |
| GET | /api/gamification/notifications |
إشعارات الشارات/الارتقاء في المستوى عبر SSE | مطلوبة |
| GET | /api/gamification/anomalies |
عرض تقارير الحالات الشاذة (المشرف) | مشرف |
| POST | /api/gamification/rotate |
تدوير أسرار رموز الدعوة | مطلوبة |
أمثلة على الطلبات/الاستجابات
POST /api/gamification/transfer
// الطلب
{
"to": "recipient-api-key-id",
"amount": 500,
"idempotencyKey": "uuid-v4"
}
// الاستجابة 200
{
"success": true,
"transfer": {
"id": "txn-uuid",
"from": "sender-api-key-id",
"to": "recipient-api-key-id",
"amount": 500,
"createdAt": "2026-05-19T12:00:00.000Z"
},
"balance": 2500
}
// الاستجابة 400 (رصيد غير كافٍ)
{
"error": "Insufficient balance",
"balance": 200,
"requested": 500
}
GET /api/gamification/leaderboard?scope=weekly&limit=10
{
"scope": "weekly",
"period": "2026-W20",
"entries": [
{
"rank": 1,
"apiKeyId": "key-uuid",
"displayName": "User***1234",
"score": 15230,
"level": 42,
"title": "Expert"
}
],
"total": 847,
"updatedAt": "2026-05-19T12:00:00.000Z"
}
أدوات MCP (8)
مسجّلة في open-sse/mcp-server/ إلى جانب الأدوات الحالية. وتندرج ضمن
نطاق صلاحية gamification.
| الأداة | الوصف | مخطط الإدخال | |
|---|---|---|---|
gamification_leaderboard |
الحصول على لوحة المتصدرين لنطاق/فترة | { scope, period?, limit? } |
|
gamification_rank |
الحصول على ترتيب المستدعي وجيرانه | { scope } |
|
gamification_profile |
الحصول على ملخص نقاط XP والمستوى واللقب والسلسلة | {} |
|
gamification_badges |
عرض الشارات المكتسبة أو جميع التعريفات | { earned?: boolean } |
|
gamification_transfer |
إرسال الرموز إلى مستخدم آخر | { to, amount } |
|
gamification_invite |
إنشاء رموز الدعوة أو عرضها | `{ action: "create" | "list" }` |
gamification_servers |
عرض خوادم المجتمع أو الاتصال بها | { action, token? } |
|
gamification_anomalies |
عرض تقارير الحالات الشاذة (نطاق المسؤول) | { limit?, since? } |
صفحات لوحة المعلومات
/dashboard/leaderboard
- عرض المنصة لأعلى 3 متصدرين مع الصور الرمزية ونقاط XP.
- محدد النطاق: عالمي / أسبوعي / شهري / الرموز التي تمت مشاركتها / المساهمات.
- جدول مقسّم إلى صفحات (25 لكل صفحة) يتضمن الترتيب والاسم والنتيجة والمستوى واللقب.
- تحديثات SSE في الوقت الفعلي — تُعرض تغييرات الترتيب برسوم متحركة.
- يُميّز المستخدم الحالي في الجدول باستخدام صف ثابت بعنوان "ترتيبك".
/dashboard/profile
- شريط تقدم XP يتضمن المستوى الحالي والحد المطلوب للمستوى التالي.
- عرض شارة اللقب بشكل بارز.
- معرض الشارات — الشارات المكتسبة مع تاريخ اكتسابها، والشارات غير المكتسبة باللون الرمادي (تُظهر الشارات المخفية "???" حتى يتم اكتسابها).
- عدّاد السلسلة مع أيقونة لهب؛ وتقويم السلسلة (آخر 30 يومًا).
- مخطط سجل XP (نقاط XP اليومية خلال آخر 30 يومًا).
/dashboard/tokens
- رصيد الرموز (بارز، في أعلى الصفحة).
- نموذج التحويل: المستلم، والمبلغ، ومربع حوار التأكيد.
- جدول سجل التحويلات مع عوامل تصفية (مرسلة/مستلمة/الكل).
- قسم الدعوات: الرموز النشطة، وإنشاء رمز جديد، ورابط المشاركة.
- خوادم المجتمع: قائمة تتضمن حالة السلامة وخياري الاتصال/قطع الاتصال.
/dashboard/gamification/admin
- قائمة الحالات الشاذة مع مستوى الخطورة والمستخدم والطابع الزمني ودرجة z.
- عارض سجل التدقيق مع عوامل تصفية (نوع الإجراء، والمستخدم، والنطاق الزمني).
- إحصاءات النظام: إجمالي نقاط XP الممنوحة، والمستخدمون النشطون، ومعدلات اكتساب الشارات.
- نظرة عامة على سلامة خوادم الاتحاد.
تكامل خط المعالجة
نقطة التكامل
ترتبط آليات التلعيب بخط معالجة الطلبات عند نقطة واحدة في
open-sse/handlers/chatCore.ts:
// بعد إرسال الاستجابة إلى العميل:
setImmediate(() => {
emitGamificationEvent({
type: "request.completed",
apiKeyId,
metadata: {
provider: selectedProvider,
model: selectedModel,
comboId: resolvedCombo?.id,
compressionUsed: compressionStats?.applied,
skillUsed: skillExecution?.name,
},
}).catch(() => {
// تنفيذ دون انتظار: سجّل الخطأ، ولكن لا تمرّره أبدًا إلى العميل
});
});
أنواع الأحداث
| نوع الحدث | وقت الإطلاق |
|---|---|
request.completed |
إرسال استجابة LLM ناجحة |
provider.switch |
تغيير المزوّد (تُحتسب عملية الرجوع الاحتياطي للمجموعة) |
combo.created |
حفظ إعداد مجموعة جديد |
combo.used |
الوصول بنجاح إلى هدف المجموعة |
badge.earned |
عثور تقييم الشارة على تطابق |
streak.milestone |
تجاوز الحد الفاصل للسلسلة |
transfer.sent |
اكتمال تحويل الرموز |
referral.redeemed |
استرداد رمز الدعوة بنجاح |
compression.used |
تطبيق ضغط المطالبة |
skill.executed |
اكتمال تنفيذ المهارة |
model.first_use |
عدم استخدام النموذج خلال الأيام السبعة الماضية |
ضمان عدم الحظر
يضمن نمط setImmediate + .catch(() => {}) ما يلي:
- إرسال الاستجابة بالكامل قبل تشغيل آليات التلعيب.
- عدم ظهور أخطاء التلعيب للعميل مطلقًا.
- تشغيل معالجة الحدث في المهمة المصغرة التالية، وليس ضمن السياق الحالي.
الأمان
نموذج التهديدات
| التهديد | الإجراء الوقائي |
|---|---|
| تضخيم النقاط | احتساب XP على جانب الخادم فقط؛ يرسل العملاء الإجراءات، وليس النقاط |
| هجمات إعادة التشغيل | مفاتيح منع التكرار للتحويلات؛ إزالة التكرارات من سجل التدقيق |
| الاحتيال في التحويلات | دفتر أستاذ مزدوج القيد؛ معاملات ذرية؛ حدود للمعدل |
| الإحالة الذاتية | التحقق المتقاطع من api_key_id عند الاسترداد |
| التلاعب بلوحة المتصدرين | اكتشاف الحالات الشاذة باستخدام الدرجة المعيارية Z؛ لوحة معلومات إدارية للحالات الشاذة |
| سرقة رمز الاتحاد | تخزين مجزأ باستخدام SHA-256؛ لا يُعرض الرمز الخام إلا مرة واحدة |
| التخمين بالقوة الغاشمة لرموز الدعوة | تحديد معدل الطلبات على نقطة نهاية الاسترداد؛ عشوائية بطول 8 أحرف |
| هجمات XSS في أسماء العرض | تنقية أسماء العرض؛ ترميز مُدخلات لوحة المتصدرين |
| هجمات التوقيت على قيم التجزئة | استخدام crypto.timingSafeEqual لمقارنة تجزئة الرمز |
متطلبات المصادقة
- عام (من دون مصادقة):
GET /leaderboard،GET /stream(لوحات متصدرين للقراءة فقط). - مفتاح API مطلوب: جميع عمليات الكتابة والملف الشخصي والتحويلات والدعوات.
- للمسؤول فقط: لوحة معلومات الحالات الشاذة، وعارض سجل التدقيق.
- الاتحاد: مسار مصادقة منفصل يستخدم الرمز الخام في ترويسة
Authorization، ويُتحقق منه بمقارنته مع تجزئة SHA-256 المخزنة.
الاختبار
ملفات الاختبار
تستخدم جميع الاختبارات مشغّل الاختبارات الأصلي في Node.js (node --import tsx/esm --test).
| ملف الاختبار | ما يغطيه | الاختبارات |
|---|---|---|
tests/unit/gamification/xp.test.ts |
احتساب XP، ومنحنى المستويات، والألقاب | 8 |
tests/unit/gamification/badges.test.ts |
مطابقة معايير الشارات ومنحها | 10 |
tests/unit/gamification/streaks.test.ts |
منطق السلاسل، والمحطات المرحلية، والحالات الحدية | 7 |
tests/unit/gamification/leaderboard.test.ts |
احتساب الترتيب، وتقسيم الصفحات، والتدوير | 8 |
tests/unit/gamification/sharing.test.ts |
التحويلات، والرصيد، ومنع التكرار | 9 |
tests/unit/gamification/invites.test.ts |
الإنشاء، والاسترداد، وانتهاء الصلاحية، والإحالة الذاتية | 7 |
tests/unit/gamification/antiCheat.test.ts |
حدود المعدل، والدرجة المعيارية Z، وتسجيل التدقيق | 6 |
tests/unit/gamification/events.test.ts |
إصدار الأحداث، والتوزيع، ومعالجة الأخطاء | 5 |
تشغيل الاختبارات
# جميع اختبارات التلعيب
node --import tsx/esm --test tests/unit/gamification/*.test.ts
# ملف اختبار واحد
node --import tsx/esm --test tests/unit/gamification/xp.test.ts
متطلبات التغطية
وفقًا لـ CONTRIBUTING.md — يجب أن تحقق جميع الوحدات الجديدة ما يلي:
- تغطية الفروع >= 80%.
- اختبار كل دالة عامة مرة واحدة على الأقل.
- اختبار مسارات الخطأ (الرصيد غير الكافي، والرموز منتهية الصلاحية، وحدود المعدل).
بنية الملفات
src/
lib/
db/
migrations/
060_create_gamification.sql # الجداول الثمانية جميعها + الفهارس
gamification.ts # وحدة عمليات CRUD للنطاق
gamification/
xp.ts # حساب نقاط XP، ومنحنى المستويات، والألقاب
badges.ts # تعريفات الشارات، والمعايير، والتقييم
streaks.ts # تتبّع الاستمرارية اليومية
leaderboard.ts # حساب الترتيب، وSSE، والتدوير
antiCheat.ts # تحديد المعدل، ودرجة z، والتدقيق
sharing.ts # سجل نقل الرموز
invites.ts # رموز الدعوة/الاسترداد
servers.ts # اتحاد خوادم المجتمع
events.ts # باعث الأحداث (نقطة التكامل)
notifications.ts # تدفق إشعارات SSE
app/
api/
gamification/
leaderboard/route.ts # GET/POST للوحة المتصدرين
leaderboard/stream/route.ts # تحديثات فورية عبر SSE
transfer/route.ts # GET/POST لعمليات النقل
invite/route.ts # GET/POST/DELETE لرموز الدعوة
invite/redeem/route.ts # POST لاسترداد الرمز
servers/route.ts # GET/POST/DELETE للخوادم
federation/score/route.ts # POST لدفع النتيجة
federation/leaderboard/route.ts # GET لجلب لوحة المتصدرين
notifications/route.ts # إشعارات SSE
anomalies/route.ts # GET لتقارير الحالات الشاذة
rotate/route.ts # POST لتدوير الأسرار
(dashboard)/
dashboard/
leaderboard/page.tsx # صفحة الترتيب
profile/page.tsx # صفحة نقاط XP/الشارات/الاستمرارية
tokens/page.tsx # صفحة الرصيد/عمليات النقل/الدعوات
gamification/admin/page.tsx # مراقبة المسؤول للحالات الشاذة
shared/
constants/
gamification.ts # XP_REWARDS، TITLES، BADGE_DEFS، LIMITS
tests/
unit/
gamification/
xp.test.ts
badges.test.ts
streaks.test.ts
leaderboard.test.ts
sharing.test.ts
invites.test.ts
antiCheat.test.ts
events.test.ts
docs/
frameworks/
GAMIFICATION.md # هذا المستند
استراتيجية الترحيل
المرحلة 1: النواة الخلفية (PR 1)
- ترحيل
060_create_gamification.sql(8 جداول). src/lib/db/gamification.ts(وحدة النطاق).src/lib/gamification/xp.ts، وstreaks.ts، وevents.ts.- نقطة التكامل في
chatCore.ts. - اختبارات الوحدات لنقاط XP، والاستمرارية، والأحداث.
المرحلة 2: الشارات ولوحة المتصدرين (PR 2)
src/lib/gamification/badges.ts، وleaderboard.ts.- تعريفات الشارات في الثوابت.
- مسارات API للوحة المتصدرين + تدفق SSE.
- اختبارات الوحدات للشارات ولوحة المتصدرين.
المرحلة 3: المشاركة والدعوات (PR 3)
src/lib/gamification/sharing.ts، وinvites.ts، وantiCheat.ts.- مسارات API للنقل والدعوات.
- اختبارات الوحدات للمشاركة، والدعوات، ومكافحة الغش.
المرحلة 4: الاتحاد ولوحة المعلومات (PR 4)
src/lib/gamification/servers.ts، وnotifications.ts.- مسارات API للاتحاد.
- صفحات لوحة المعلومات (لوحة المتصدرين، والملف الشخصي، والرموز، والإدارة).
- تسجيل أدوات MCP.
اعتبارات مستقبلية
- الفعاليات الموسمية: مجموعات شارات محدودة المدة ومواسم للوحات الصدارة.
- لوحات صدارة الفرق: تجميع المستخدمين حسب المؤسسة أو المجموعة.
- مضاعِفات XP: تعزيز XP خلال الفترات الترويجية.
- مشاركة الإنجازات: إنشاء بطاقات شارات قابلة للمشاركة (صور OpenGraph).
- الإشعارات الفورية للجوال: إشعارات قائمة على webhook لأحداث الشارات/المستويات.
- واجهة برمجة تطبيقات لوحة الصدارة: واجهة برمجة تطبيقات عامة لعمليات التكامل مع الجهات الخارجية.