DailyChallengeController.java
package com.wavii.controller;
import com.wavii.dto.challenge.CompleteChallengResponseDto;
import com.wavii.dto.challenge.DailyChallengeDto;
import com.wavii.dto.challenge.StatsDto;
import com.wavii.model.User;
import com.wavii.service.DailyChallengeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/challenges")
@RequiredArgsConstructor
@Slf4j
public class DailyChallengeController {
private final DailyChallengeService challengeService;
/**
* GET /api/challenges/today
* Devuelve los desafios del dia visibles para el usuario segun su nivel.
* Si aun no se han generado los desafios del dia, los genera en este momento.
*/
@GetMapping("/today")
public ResponseEntity<List<DailyChallengeDto>> getTodayChallenges(
@AuthenticationPrincipal User currentUser) {
try {
List<DailyChallengeDto> challenges = challengeService.getTodayChallengesForUser(currentUser);
return ResponseEntity.ok(challenges);
} catch (Exception e) {
log.error("Error fetching today challenges: {}", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).<List<DailyChallengeDto>>build();
}
}
/**
* POST /api/challenges/{id}/complete
* Marca un desafio como completado por el usuario autenticado.
* Actualiza XP, racha y nivel del usuario y devuelve el nuevo estado.
*/
@PostMapping("/{id}/complete")
public ResponseEntity<CompleteChallengResponseDto> completeChallenge(
@PathVariable Long id,
@AuthenticationPrincipal User currentUser) {
try {
CompleteChallengResponseDto response = challengeService.completeChallenge(id, currentUser);
return ResponseEntity.ok(response);
} catch (IllegalArgumentException e) {
return ResponseEntity.notFound().build();
} catch (IllegalStateException e) {
return ResponseEntity.badRequest().build();
} catch (DataIntegrityViolationException e) {
return ResponseEntity.badRequest().build();
}
}
/**
* GET /api/challenges/stats
* Devuelve las estadisticas del usuario: racha, mejor racha, XP, nivel
* y dias completados del mes actual para el calendario.
*/
@GetMapping("/stats")
public ResponseEntity<StatsDto> getStats(
@AuthenticationPrincipal User currentUser) {
try {
StatsDto stats = challengeService.getStats(currentUser);
return ResponseEntity.ok(stats);
} catch (Exception e) {
log.error("Error fetching challenge stats: {}", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).<StatsDto>build();
}
}
}