feat: implement coinflip api
All checks were successful
CI / Get Changed Files (pull_request) Successful in 10s
CI / Docker frontend validation (pull_request) Has been skipped
CI / eslint (pull_request) Has been skipped
CI / oxlint (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
CI / test-build (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Successful in 2m13s
CI / Checkstyle Main (pull_request) Successful in 2m48s

This commit is contained in:
Phan Huy Tran 2025-05-15 10:27:43 +02:00
commit 21209524be
6 changed files with 121 additions and 1 deletions

View file

@ -0,0 +1,6 @@
package de.szut.casino.coinflip;
public enum CoinSide {
HEAD,
TAILS;
}

View file

@ -0,0 +1,45 @@
package de.szut.casino.coinflip;
import de.szut.casino.exceptionHandling.exceptions.InsufficientFundsException;
import de.szut.casino.exceptionHandling.exceptions.UserNotFoundException;
import de.szut.casino.shared.service.BalanceService;
import de.szut.casino.user.UserEntity;
import de.szut.casino.user.UserService;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
@RestController
public class CoinflipController {
private final UserService userService;
private final BalanceService balanceService;
private final CoinflipService coinflipService;
public CoinflipController(UserService userService, BalanceService balanceService, CoinflipService coinflipService) {
this.userService = userService;
this.balanceService = balanceService;
this.coinflipService = coinflipService;
}
@PostMapping("/coinflip")
public ResponseEntity<Object> coinFlip(@RequestBody @Valid CoinflipDto coinflipDto) {
Optional<UserEntity> optionalUser = userService.getCurrentUser();
if (optionalUser.isEmpty()) {
throw new UserNotFoundException();
}
UserEntity user = optionalUser.get();
if (!this.balanceService.hasFunds(user, coinflipDto)) {
throw new InsufficientFundsException();
}
return ResponseEntity.ok(coinflipService.play(user, coinflipDto));
}
}

View file

@ -0,0 +1,20 @@
package de.szut.casino.coinflip;
import de.szut.casino.shared.dto.BetDto;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
@Getter
@Setter
public class CoinflipDto extends BetDto {
@NotNull(message = "chosen side cannot be null")
private CoinSide coinSide;
public CoinflipDto(BigDecimal betAmount, CoinSide coinSide) {
super(betAmount);
this.coinSide = coinSide;
}
}

View file

@ -0,0 +1,15 @@
package de.szut.casino.coinflip;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
@AllArgsConstructor
@Setter
@Getter
public class CoinflipResult {
private boolean isWin;
private BigDecimal payout;
}

View file

@ -0,0 +1,34 @@
package de.szut.casino.coinflip;
import de.szut.casino.shared.service.BalanceService;
import de.szut.casino.user.UserEntity;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Random;
@Service
public class CoinflipService {
private final Random random = new Random();
private final BalanceService balanceService;
public CoinflipService(BalanceService balanceService) {
this.balanceService = balanceService;
}
public CoinflipResult play(UserEntity user, CoinflipDto coinflipDto) {
this.balanceService.subtractFunds(user, coinflipDto.getBetAmount());
CoinflipResult coinflipResult = new CoinflipResult(false, BigDecimal.ZERO);
CoinSide coinSide = this.random.nextBoolean() ? CoinSide.HEAD : CoinSide.TAILS;
if (coinSide == coinflipDto.getCoinSide()) {
coinflipResult.setWin(true);
BigDecimal payout = coinflipDto.getBetAmount().multiply(BigDecimal.TWO);
this.balanceService.addFunds(user, payout);
coinflipResult.setPayout(payout);
}
return coinflipResult;
}
}

View file

@ -9,7 +9,7 @@ import java.math.BigDecimal;
@Service @Service
public class BalanceService { public class BalanceService {
private UserRepository userRepository; private final UserRepository userRepository;
public BalanceService(UserRepository userRepository) { public BalanceService(UserRepository userRepository) {
this.userRepository = userRepository; this.userRepository = userRepository;