"""API геймификации (ТЗ 3.13): XP, уровень, прогресс, события начисления, дейли."""
from typing import Any
from fastapi import APIRouter
from sqlalchemy.exc import IntegrityError
from app.dependencies import DbDep, UserDep
from app.realtime import publish
from app.services.xp import claim_daily, xp_events, xp_summary
router = APIRouter(prefix="/api/xp", tags=["xp"])
@router.get("")
async def get_xp(db: DbDep, user: UserDep) -> dict[str, Any]:
"""Сводка: суммарный XP, уровень, прогресс до следующего."""
return xp_summary(db)
@router.get("/events")
async def get_xp_events(db: DbDep, user: UserDep) -> list[dict[str, Any]]:
"""Все события начисления: редкость растения, признак «из 3 вариантов», даты."""
return xp_events(db)
@router.post("/daily")
async def post_daily(db: DbDep, user: UserDep) -> dict[str, Any]:
"""Ежедневная награда за визит: 50 монет раз в сутки (идемпотентно).
Гонка двух параллельных POST — оба прошли check-then-insert — ловится
уникальным индексом на коммите: молча отдаём granted=False вместо 500.
"""
result = claim_daily(db)
if result.get("granted"):
try:
db.commit()
except IntegrityError:
db.rollback()
return {"granted": False, "coins": 0}
publish(str(user["user_id"]), "xp.changed", {"celebrate": False})
return result