43 lines
1.6 KiB
Python
43 lines
1.6 KiB
Python
from fastapi import APIRouter, Depends
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select, func, desc
|
|
from app.database import get_db
|
|
from app.models.user import User
|
|
from app.models.achievement import Achievement, UserAchievement
|
|
from app.utils.auth import get_current_user
|
|
|
|
router = APIRouter(prefix="/api/achievements", tags=["achievements"])
|
|
|
|
@router.get("")
|
|
async def all_achievements(db: AsyncSession = Depends(get_db)):
|
|
achievements = (await db.execute(select(Achievement))).scalars().all()
|
|
return [
|
|
{"id": str(a.id), "name": a.name, "description": a.description, "icon": a.icon,
|
|
"category": a.category, "points": a.points}
|
|
for a in achievements
|
|
]
|
|
|
|
@router.get("/mine")
|
|
async def my_achievements(user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
|
|
result = await db.execute(
|
|
select(UserAchievement, Achievement)
|
|
.join(Achievement, UserAchievement.achievement_id == Achievement.id)
|
|
.where(UserAchievement.user_id == user.id)
|
|
)
|
|
rows = result.all()
|
|
return [
|
|
{"id": str(ua.id), "achievement": {"id": str(a.id), "name": a.name, "icon": a.icon, "points": a.points},
|
|
"unlocked_at": ua.unlocked_at.isoformat()}
|
|
for ua, a in rows
|
|
]
|
|
|
|
@router.get("/leaderboard")
|
|
async def leaderboard(db: AsyncSession = Depends(get_db)):
|
|
users = (await db.execute(
|
|
select(User).order_by(desc(User.total_points)).limit(20)
|
|
)).scalars().all()
|
|
return [
|
|
{"name": u.name or u.email.split("@")[0], "points": u.total_points, "streak": u.streak_days}
|
|
for u in users
|
|
]
|