SchedulerService.java
package com.archiweb.service;
import com.archiweb.model.Code;
import com.archiweb.model.Draw;
import com.archiweb.model.User;
import com.archiweb.model.Win;
import com.archiweb.repository.CodeRepository;
import com.archiweb.repository.DrawRepository;
import com.archiweb.repository.UserRepository;
import com.archiweb.repository.WinRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;
@Service
@Slf4j
public class SchedulerService {
private final CodeRepository codeRepository;
private final WinRepository winRepository;
private final UserRepository userRepository;
private final DrawRepository drawRepository;
// 📅 date du début du jeu – à adapter selon ton contexte
private static final LocalDate GAME_START_DATE = LocalDate.of(2025, 10, 1);
private static final LocalDate GAME_END_DATE = GAME_START_DATE.plusDays(30);
public SchedulerService(CodeRepository codeRepository,
WinRepository winRepository,
UserRepository userRepository,
DrawRepository drawRepository) {
this.codeRepository = codeRepository;
this.winRepository = winRepository;
this.userRepository = userRepository;
this.drawRepository = drawRepository;
}
// 🕒 1. Clôture automatique du jeu après 30 jours
@Scheduled(cron = "0 0 0 * * *") // chaque jour à minuit
public void closeGameIfExpired() {
LocalDate today = LocalDate.now();
if (today.isAfter(GAME_END_DATE)) {
long activeCodes = codeRepository.countByUsed(false);
log.info("🚫 Le jeu est terminé depuis le {}, désactivation automatique.", GAME_END_DATE);
log.info("🔒 {} codes non utilisés seront désormais considérés comme invalides.", activeCodes);
} else {
long remainingDays = GAME_END_DATE.toEpochDay() - today.toEpochDay();
log.info("⏳ Le jeu est encore ouvert. {} jour(s) restant(s) avant la clôture.", remainingDays);
}
}
// 🎰 2. Tirage automatique du gagnant final
@Scheduled(cron = "0 5 0 * * *") // chaque jour à 00h05
public void performAutomaticFinalDraw() {
LocalDate today = LocalDate.now();
if (today.isAfter(GAME_END_DATE)) {
if (drawRepository.existsByType("FINAL")) {
log.info("🏁 Le tirage final a déjà été effectué.");
return;
}
List<Win> allWins = winRepository.findAll();
if (allWins.isEmpty()) {
log.warn("⚠️ Aucun participant trouvé — tirage final non effectué.");
return;
}
Random random = new Random();
Win selectedWin = allWins.get(random.nextInt(allWins.size()));
User winner = selectedWin.getUser();
Draw draw = new Draw();
draw.setType("FINAL");
draw.setWinner(winner);
draw.setCreatedAt(LocalDateTime.now());
drawRepository.save(draw);
log.info("🎉 Tirage final automatique effectué ! Gagnant : {} ({})",
winner.getUsername(), winner.getEmail());
}
}
// 🧹 3. Nettoyage des codes expirés / données obsolètes
@Scheduled(cron = "0 30 2 * * *") // chaque jour à 2h30 du matin
public void cleanExpiredCodes() {
List<Code> expiredCodes = codeRepository.findAll().stream()
.filter(code -> code.getExpiresAt() != null &&
code.getExpiresAt().isBefore(LocalDateTime.now()))
.toList();
if (expiredCodes.isEmpty()) {
log.info("🧹 Aucun code expiré à nettoyer aujourd’hui.");
return;
}
log.info("🧹 Nettoyage de {} codes expirés...", expiredCodes.size());
codeRepository.deleteAll(expiredCodes);
log.info("✅ Nettoyage terminé à {}", LocalDateTime.now());
}
}