İlk commit: Stepstead backend (FastAPI)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
commit
ea049b8ccd
45 changed files with 6751 additions and 0 deletions
59
routers/leaderboard.py
Normal file
59
routers/leaderboard.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
"""
|
||||
Liderlik tablosu — adım (lifetime), level ve gold sıralamaları.
|
||||
GET /leaderboard?by=steps|level|gold → top 20 + kendi sıran.
|
||||
"""
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import select, text
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from deps import get_current_user
|
||||
from models import Character, User, get_db
|
||||
|
||||
router = APIRouter(prefix="/leaderboard", tags=["leaderboard"])
|
||||
|
||||
ORDER_COLS = {"steps": "step_lifetime", "level": "total_xp", "gold": "gold"}
|
||||
|
||||
|
||||
class LeaderRow(BaseModel):
|
||||
rank: int
|
||||
name: str
|
||||
level: int
|
||||
value: int # sıralama kriterinin değeri
|
||||
me: bool
|
||||
|
||||
|
||||
class LeaderboardOut(BaseModel):
|
||||
by: str
|
||||
rows: list[LeaderRow]
|
||||
my_rank: int
|
||||
|
||||
|
||||
@router.get("", response_model=LeaderboardOut)
|
||||
async def leaderboard(by: str = "steps",
|
||||
user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
|
||||
if by not in ORDER_COLS:
|
||||
raise HTTPException(400, "by: steps | level | gold")
|
||||
col = ORDER_COLS[by]
|
||||
char = (await db.execute(select(Character).where(Character.user_id == user.id))).scalar_one_or_none()
|
||||
if not char:
|
||||
raise HTTPException(404, "Karakter yok")
|
||||
|
||||
rows = (await db.execute(text(f"""
|
||||
SELECT rank, name, level, val, id FROM (
|
||||
SELECT id, name, level, {col} AS val,
|
||||
RANK() OVER (ORDER BY {col} DESC, id) AS rank
|
||||
FROM characters
|
||||
) t WHERE rank <= 20 OR id = :me
|
||||
ORDER BY rank
|
||||
"""), {"me": char.id})).all()
|
||||
|
||||
my_rank = 0
|
||||
out: list[LeaderRow] = []
|
||||
for r in rows:
|
||||
me = r[4] == char.id
|
||||
if me:
|
||||
my_rank = int(r[0])
|
||||
if int(r[0]) <= 20:
|
||||
out.append(LeaderRow(rank=int(r[0]), name=r[1], level=int(r[2]), value=int(r[3]), me=me))
|
||||
return LeaderboardOut(by=by, rows=out, my_rank=my_rank)
|
||||
Loading…
Add table
Add a link
Reference in a new issue