2026-02-01 09:31:38 +01:00

167 lines
5.3 KiB
Python

"""
API endpoints pour les badges
"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime
from app.database import get_db
from app.models.badge import Badge, UserBadge
from app.models.user import User
from app.schemas.badge import (
BadgeResponse,
BadgeListResponse,
BadgeCheckResponse,
UserBadgeResponse,
UserBadgeListResponse,
BadgeUnlockRequest,
)
from app.services.badge_service import BadgeService
router = APIRouter()
@router.get("/", response_model=BadgeListResponse)
def get_all_badges(
db: Session = Depends(get_db),
user_id: Optional[int] = None,
):
"""
Récupère tous les badges disponibles
- Indique les badges débloqués par l'utilisateur si user_id est fourni
- Retourne les critères de débloquage
"""
# Récupérer tous les badges
badges = db.query(Badge).all()
# Si user_id est fourni, récupérer les badges débloqués
unlocked_badge_ids = set()
if user_id:
unlocked_badges = db.query(UserBadge).filter(UserBadge.user_id == user_id).all()
unlocked_badge_ids = set(ub.badge_id for ub in unlocked_badges)
# Formater la réponse
badge_responses = []
for badge in badges:
badge_responses.append(
BadgeResponse(
id=badge.id,
badgeId=badge.badge_id,
name=badge.name,
description=badge.description,
icon=badge.icon,
category=badge.category,
criteriaType=badge.criteria_type,
criteriaValue=badge.criteria_value,
criteriaDescription=badge.criteria_description,
rarity=badge.rarity,
points=badge.points,
createdAt=badge.created_at.isoformat(),
unlocked=badge.badge_id in unlocked_badge_ids if user_id else None,
)
)
return BadgeListResponse(
data=badge_responses,
meta={
"count": len(badge_responses),
"timestamp": datetime.utcnow().isoformat(),
"version": "v1"
}
)
@router.post("/check", response_model=BadgeCheckResponse)
def check_badges(
request: BadgeUnlockRequest,
db: Session = Depends(get_db),
):
"""
Vérifie et débloque les nouveaux badges pour un utilisateur
- Vérifie les critères de badges de l'utilisateur
- Débloque les nouveaux badges atteints
- Retourne les badges débloqués
- Envoie les notifications
"""
# Vérifier que l'utilisateur existe
user = db.query(User).filter(User.id == request.userId).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Utilisateur non trouvé"
)
# Utiliser le service pour vérifier et débloquer les badges
badge_service = BadgeService(db)
result = badge_service.check_and_unlock_badges(request.userId)
return BadgeCheckResponse(
data={
"new_badges": result["new_badges"],
"total_badges": result["total_badges"],
"message": result["message"],
},
meta={
"timestamp": datetime.utcnow().isoformat(),
"version": "v1"
}
)
@router.get("/users/{user_id}", response_model=UserBadgeListResponse)
def get_user_badges(
user_id: int,
db: Session = Depends(get_db),
):
"""
Récupère tous les badges débloqués par un utilisateur
"""
# Vérifier que l'utilisateur existe
user = db.query(User).filter(User.id == user_id).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Utilisateur non trouvé"
)
# Récupérer les badges débloqués
user_badges = db.query(UserBadge).filter(UserBadge.user_id == user_id).all()
# Formater la réponse
badge_responses = []
for user_badge in user_badges:
badge = db.query(Badge).filter(Badge.id == user_badge.badge_id).first()
if badge:
badge_responses.append(
UserBadgeResponse(
id=user_badge.id,
userId=user_badge.user_id,
badgeId=user_badge.badge_id,
unlockedAt=user_badge.unlocked_at.isoformat(),
badge={
"id": badge.id,
"badgeId": badge.badge_id,
"name": badge.name,
"description": badge.description,
"icon": badge.icon,
"category": badge.category,
"criteriaType": badge.criteria_type,
"criteriaValue": badge.criteria_value,
"criteriaDescription": badge.criteria_description,
"rarity": badge.rarity,
"points": badge.points,
"createdAt": badge.created_at.isoformat(),
}
)
)
return UserBadgeListResponse(
data={"badges": badge_responses},
meta={
"count": len(badge_responses),
"timestamp": datetime.utcnow().isoformat(),
"version": "v1"
}
)