ChallengeService.java
package com.seebie.server.service;
import com.seebie.server.dto.ChallengeDto;
import com.seebie.server.dto.ChallengeDetailDto;
import com.seebie.server.mapper.dtotoentity.UnsavedChallengeListMapper;
import com.seebie.server.mapper.entitytodto.ChallengeMapper;
import com.seebie.server.repository.ChallengeRepository;
import jakarta.persistence.EntityNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;
import java.util.List;
import java.util.UUID;
@Service
public class ChallengeService {
private ChallengeRepository challengeRepo;
private UnsavedChallengeListMapper toEntity;
private ChallengeMapper toDto = new ChallengeMapper();
public ChallengeService(ChallengeRepository challengeRepo, UnsavedChallengeListMapper toEntity) {
this.challengeRepo = challengeRepo;
this.toEntity = toEntity;
}
@Transactional
public ChallengeDetailDto saveNew(UUID publicId, ChallengeDto challenge) {
// The computed value for timeAsleep isn't calculated until the transaction is closed
// so the entity does not have the correct value here.
var entity = challengeRepo.save(toEntity.toUnsavedEntity(publicId, challenge));
return toDto.apply(entity);
}
@Transactional
public ChallengeDetailDto update(UUID publicId, Long challengeId, ChallengeDto dto) {
var entity = challengeRepo.findByUser(publicId, challengeId)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST, "Challenge not found"));
entity.setChallengeData(dto.name(), dto.description(), dto.start(), dto.finish());
return toDto.apply(entity);
}
@Transactional(readOnly = true)
public ChallengeDetailDto retrieve(UUID publicId, Long challengeId) {
return challengeRepo.findDtoBy(publicId, challengeId)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST, "Challenge not found"));
}
@Transactional
public void remove(UUID publicId, Long challengeId) {
challengeRepo.findByUser(publicId, challengeId)
.ifPresentOrElse(challengeRepo::delete, () -> {
throw new EntityNotFoundException("No challenge with id " + challengeId + " found for user " + publicId);
});
}
@Transactional(readOnly = true)
public List<ChallengeDetailDto> getChallenges(UUID publicId) {
return challengeRepo.findAllByUser(publicId);
}
}