Context
The gamification system now awards XP (agent.xp events), tracks district unlocks, and badges. A leaderboard ties it together — showing which agents are most active and rewarding competition.
What to implement
Route: GET /api/leaderboard
Query params: limit (default 20, max 100), metric (xp | quests | districts, default xp)
Response:
{
"metric": "xp",
"updatedAt": 1234567890,
"entries": [
{ "rank": 1, "agentId": "bot-1", "xp": 1250, "questsCompleted": 8, "districtsUnlocked": 3 },
{ "rank": 2, "agentId": "bot-2", "xp": 980, "questsCompleted": 5, "districtsUnlocked": 2 }
]
}
Data source
- XP: sum of all
agent.xp events per agent
- Quests: count of
quest.completed events per agent
- Districts: count of unlocked districts from district store
Caching
Leaderboard is expensive to compute — cache for 60 seconds (in-memory, same TTL pattern as other stores).
Acceptance criteria
🎁 Evidencia visual = reward extra
- Si tu PR incluye video demo o capturas de pantalla mostrando la funcionalidad pedida funcionando end-to-end, va a ser considerado para rewards de GrantFox en esta issue. No es obligatorio, pero suma mucho para la evaluación.
Context
The gamification system now awards XP (agent.xp events), tracks district unlocks, and badges. A leaderboard ties it together — showing which agents are most active and rewarding competition.
What to implement
Route: GET /api/leaderboard
Query params:
limit(default 20, max 100),metric(xp|quests|districts, defaultxp)Response:
{ "metric": "xp", "updatedAt": 1234567890, "entries": [ { "rank": 1, "agentId": "bot-1", "xp": 1250, "questsCompleted": 8, "districtsUnlocked": 3 }, { "rank": 2, "agentId": "bot-2", "xp": 980, "questsCompleted": 5, "districtsUnlocked": 2 } ] }Data source
agent.xpevents per agentquest.completedevents per agentCaching
Leaderboard is expensive to compute — cache for 60 seconds (in-memory, same TTL pattern as other stores).
Acceptance criteria
metric=questsranks by quest completionslimit=5returns only top 5🎁 Evidencia visual = reward extra