banyaro/backend/routes/stats.py

44 lines
1.5 KiB
Python

from fastapi import APIRouter, Depends
from database import db
from auth import get_current_user, get_current_user_optional
router = APIRouter()
_STATS_SQL = """
SELECT u.id, u.name, u.avatar_url,
ROUND(COALESCE(SUM(r.distanz_km), 0), 1) AS total_km,
COUNT(DISTINCT r.id) AS routen,
COUNT(DISTINCT p.id) AS pois,
ROUND(COALESCE(SUM(r.distanz_km), 0), 1) * 1
+ COUNT(DISTINCT p.id) * 5
+ COUNT(DISTINCT r.id) * 10 AS punkte
FROM users u
LEFT JOIN routes r ON r.user_id = u.id AND r.is_valid = 1
LEFT JOIN user_map_pois p ON p.user_id = u.id
GROUP BY u.id
"""
@router.get("/leaderboard")
async def leaderboard(_user=Depends(get_current_user_optional)):
with db() as conn:
rows = conn.execute(f"""
SELECT * FROM ({_STATS_SQL})
ORDER BY punkte DESC, total_km DESC
LIMIT 20
""").fetchall()
return [dict(r) for r in rows]
@router.get("/me")
async def my_stats(user=Depends(get_current_user)):
with db() as conn:
row = conn.execute(f"""
SELECT s.*, rank_tbl.rang FROM ({_STATS_SQL}) s
JOIN (
SELECT id, ROW_NUMBER() OVER (ORDER BY punkte DESC, total_km DESC) AS rang
FROM ({_STATS_SQL})
) rank_tbl ON rank_tbl.id = s.id
WHERE s.id = ?
""", (user["id"],)).fetchone()
return dict(row) if row else {}