feat: Leaderboard to use Riyadh timezone
This commit is contained in:
parent
c18f52672a
commit
f1a488d70a
@ -68,10 +68,11 @@ public class PuzzleController {
|
||||
}
|
||||
|
||||
@GetMapping("/leaderboard")
|
||||
@Operation(summary = "Get daily leaderboard", description = "Returns leaderboard for today's puzzle ordered by submission time")
|
||||
public ResponseEntity<ApiResponse<List<LeaderboardEntry>>> getLeaderboard() {
|
||||
@Operation(summary = "Get daily leaderboard", description = "Returns leaderboard with 9am cutoff logic (before 9am shows yesterday, from 9am shows today)")
|
||||
public ResponseEntity<ApiResponse<Map<String, Object>>> getLeaderboard() {
|
||||
try {
|
||||
List<PuzzleAttempt> attempts = puzzleService.getTodaysLeaderboard();
|
||||
String leaderboardInfo = puzzleService.getLeaderboardDateInfo();
|
||||
|
||||
List<LeaderboardEntry> leaderboard = attempts.stream()
|
||||
.filter(attempt -> attempt.isSolved())
|
||||
@ -85,7 +86,12 @@ public class PuzzleController {
|
||||
))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return ResponseEntity.ok(ApiResponse.success(leaderboard));
|
||||
Map<String, Object> response = Map.of(
|
||||
"leaderboard", leaderboard,
|
||||
"dateInfo", leaderboardInfo
|
||||
);
|
||||
|
||||
return ResponseEntity.ok(ApiResponse.success(response));
|
||||
} catch (RuntimeException e) {
|
||||
return ResponseEntity.ok(ApiResponse.error(e.getMessage()));
|
||||
}
|
||||
|
||||
@ -9,6 +9,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@ -26,6 +30,9 @@ public class PuzzleService {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
private static final ZoneId RIYADH_TIMEZONE = ZoneId.of("Asia/Riyadh");
|
||||
private static final LocalTime CUTOFF_TIME = LocalTime.of(9, 0); // 9:00 AM
|
||||
|
||||
private static final List<String> WORD_LIST = Arrays.asList(
|
||||
"APPLE", "BEACH", "CHAIN", "DANCE", "EAGLE", "FLAME", "GRAPE", "HOUSE", "IMAGE", "JUDGE",
|
||||
"KNIFE", "LIGHT", "MUSIC", "NIGHT", "OCEAN", "PEACE", "QUEEN", "RIVER", "STAGE", "TIGER",
|
||||
@ -88,7 +95,7 @@ public class PuzzleService {
|
||||
);
|
||||
|
||||
public Puzzle getTodaysPuzzle() {
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDate today = getRiyadhToday();
|
||||
Optional<Puzzle> existingPuzzle = puzzleRepository.findByDate(today);
|
||||
|
||||
if (existingPuzzle.isPresent()) {
|
||||
@ -105,6 +112,26 @@ public class PuzzleService {
|
||||
return WORD_LIST.get(random.nextInt(WORD_LIST.size()));
|
||||
}
|
||||
|
||||
private LocalDate getRiyadhToday() {
|
||||
return ZonedDateTime.now(RIYADH_TIMEZONE).toLocalDate();
|
||||
}
|
||||
|
||||
private LocalDateTime getRiyadhNow() {
|
||||
return ZonedDateTime.now(RIYADH_TIMEZONE).toLocalDateTime();
|
||||
}
|
||||
|
||||
private LocalDate getLeaderboardDate() {
|
||||
LocalDateTime riyadhNow = getRiyadhNow();
|
||||
LocalDate today = riyadhNow.toLocalDate();
|
||||
|
||||
// If it's before 9 AM, show yesterday's leaderboard
|
||||
if (riyadhNow.toLocalTime().isBefore(CUTOFF_TIME)) {
|
||||
return today.minusDays(1);
|
||||
}
|
||||
// From 9 AM onwards, show today's leaderboard
|
||||
return today;
|
||||
}
|
||||
|
||||
public boolean hasUserSolvedToday() {
|
||||
User currentUser = userService.getCurrentUser();
|
||||
Puzzle todaysPuzzle = getTodaysPuzzle();
|
||||
@ -134,7 +161,26 @@ public class PuzzleService {
|
||||
}
|
||||
|
||||
public List<PuzzleAttempt> getTodaysLeaderboard() {
|
||||
Puzzle todaysPuzzle = getTodaysPuzzle();
|
||||
return puzzleAttemptRepository.findByPuzzleOrderBySubmittedAtAsc(todaysPuzzle);
|
||||
LocalDate leaderboardDate = getLeaderboardDate();
|
||||
Optional<Puzzle> puzzleOpt = puzzleRepository.findByDate(leaderboardDate);
|
||||
|
||||
if (puzzleOpt.isEmpty()) {
|
||||
// If no puzzle exists for the leaderboard date, return empty list
|
||||
return Arrays.asList();
|
||||
}
|
||||
|
||||
return puzzleAttemptRepository.findByPuzzleOrderBySubmittedAtAsc(puzzleOpt.get());
|
||||
}
|
||||
|
||||
public String getLeaderboardDateInfo() {
|
||||
LocalDateTime riyadhNow = getRiyadhNow();
|
||||
LocalDate leaderboardDate = getLeaderboardDate();
|
||||
LocalDate today = riyadhNow.toLocalDate();
|
||||
|
||||
if (leaderboardDate.equals(today)) {
|
||||
return "Today's Leaderboard (from 9:00 AM Riyadh time)";
|
||||
} else {
|
||||
return "Yesterday's Leaderboard (before 9:00 AM Riyadh time)";
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user