File size: 1,638 Bytes
80a4a65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b6762c
80a4a65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b6762c
80a4a65
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
"""``/api/leaderboard`` — top users ranked by XP."""

import httpx
from fastapi import APIRouter

from app.core.config import SUPABASE_URL, SUPABASE_ANON_KEY
from app.services.supabase_service import supabase_headers


router = APIRouter()


@router.get("/api/leaderboard")
async def get_leaderboard(limit: int = 50):
    """Fetch top users ranked by XP from the public ``leaderboard`` view."""
    headers = {
        "apikey": SUPABASE_ANON_KEY,
        "Authorization": f"Bearer {SUPABASE_ANON_KEY}",
        "Content-Type": "application/json",
    }
    safe_limit = max(1, min(limit, 100))
    url = (
        f"{SUPABASE_URL}/rest/v1/leaderboard"
        f"?select=id,name,xp,completed_trainings,avatar_url"
        f"&order=xp.desc"
        f"&limit={safe_limit}"
    )
    try:
        async with httpx.AsyncClient(timeout=20) as client:
            resp = await client.get(url, headers=headers)
        if resp.status_code != 200:
            print(f"Leaderboard fetch error: {resp.status_code} {resp.text}")
            return {"users": [], "total": 0}
        rows = resp.json()
    except Exception as e:
        print(f"Leaderboard exception: {e}")
        return {"users": [], "total": 0}

    cleaned = []
    for i, row in enumerate(rows, start=1):
        cleaned.append({
            "rank": i,
            "id": row.get("id"),
            "name": row.get("name") or "مشغل",
            "xp": int(row.get("xp") or 0),
            "completed_trainings": int(row.get("completed_trainings") or 0),
            "avatar_url": row.get("avatar_url") or "",
        })
    return {"users": cleaned, "total": len(cleaned)}