diff --git a/README.md b/README.md
index 1d821fb..4a661be 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,8 @@
해당 프로젝트는 SOPT 32th APPJAM 프로젝트입니다.
+Sparkle, 연인과 승부를 통한 설렘 가득 소원권 내기 앱 서비스입니다.
+
## Contributors
[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-)
@@ -94,3 +96,21 @@ hotfix : 출시 버전에서 발생한 버그를 수정 하는 브랜치
└── test
```
+
+### 역할 분담
+```
+박진수
+DB 설계, AWS 인프라, CD 구성, User 도메인 및 소셜 로그인 api, 잡일
+```
+```
+이영주
+DB 설계, CI구성, 소원권 및 미션 카테고리 api
+```
+```
+신지연
+DB 설계, 한판 승부 및 승부 히스토리 api
+```
+
+### Architecture
+
+
diff --git a/src/main/java/com/universe/uni/controller/ShortGameController.java b/src/main/java/com/universe/uni/controller/ShortGameController.java
new file mode 100644
index 0000000..2243e6d
--- /dev/null
+++ b/src/main/java/com/universe/uni/controller/ShortGameController.java
@@ -0,0 +1,28 @@
+package com.universe.uni.controller;
+
+import javax.validation.Valid;
+
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.universe.uni.dto.request.CreateShortGameRequestDto;
+import com.universe.uni.dto.response.CreateShortGameResponseDto;
+import com.universe.uni.service.GameService;
+
+import lombok.RequiredArgsConstructor;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/game/short")
+public class ShortGameController {
+
+ private final GameService gameService;
+
+ @PostMapping
+ public CreateShortGameResponseDto createShortGame(@RequestBody @Valid final CreateShortGameRequestDto createShortGameRequestDto) {
+ return gameService.createShortGame(createShortGameRequestDto);
+ }
+
+}
diff --git a/src/main/java/com/universe/uni/controller/WishCouponController.java b/src/main/java/com/universe/uni/controller/WishCouponController.java
index c4b4beb..2dc9a74 100644
--- a/src/main/java/com/universe/uni/controller/WishCouponController.java
+++ b/src/main/java/com/universe/uni/controller/WishCouponController.java
@@ -1,7 +1,9 @@
package com.universe.uni.controller;
import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
@@ -9,6 +11,7 @@
import com.universe.uni.dto.request.UpdateWishCouponRequestDto;
import com.universe.uni.dto.response.UpdateWishCouponResponseDto;
+import com.universe.uni.dto.response.WishCouponResponseDto;
import com.universe.uni.service.WishCouponService;
import lombok.RequiredArgsConstructor;
@@ -22,9 +25,19 @@ public class WishCouponController {
@PatchMapping
@ResponseStatus(HttpStatus.OK)
- public UpdateWishCouponResponseDto updateWishCoupon(
- @RequestBody UpdateWishCouponRequestDto requestDto
- ) {
+ public UpdateWishCouponResponseDto updateWishCoupon(@RequestBody UpdateWishCouponRequestDto requestDto) {
return wishCouponService.uploadWishCoupon(requestDto);
}
+
+ @PatchMapping("/{wishCouponId}")
+ @ResponseStatus(HttpStatus.OK)
+ public void useWishCoupon(@PathVariable Long wishCouponId) {
+ wishCouponService.useWishCoupon(wishCouponId);
+ }
+
+ @GetMapping("/{wishCouponId}")
+ @ResponseStatus(HttpStatus.OK)
+ public WishCouponResponseDto wishCouponResponseDto(@PathVariable Long wishCouponId) {
+ return wishCouponService.getWishCoupon(wishCouponId);
+ }
}
diff --git a/src/main/java/com/universe/uni/domain/GameResult.java b/src/main/java/com/universe/uni/domain/GameResult.java
index 0dceae4..ca375b7 100644
--- a/src/main/java/com/universe/uni/domain/GameResult.java
+++ b/src/main/java/com/universe/uni/domain/GameResult.java
@@ -4,7 +4,7 @@
import java.util.Objects;
public enum GameResult {
- WIN, LOSE, DRAW;
+ WIN, LOSE, DRAW, UNDECIDED;
public static GameResult findMatchResultBy(String gameResultName) {
return Arrays.stream(values())
diff --git a/src/main/java/com/universe/uni/domain/entity/Game.java b/src/main/java/com/universe/uni/domain/entity/Game.java
index 3c6bee6..f877eae 100644
--- a/src/main/java/com/universe/uni/domain/entity/Game.java
+++ b/src/main/java/com/universe/uni/domain/entity/Game.java
@@ -41,4 +41,9 @@ public class Game {
@Column(name = "finish_at")
private LocalDateTime finishAt;
+
+ public Game(Couple couple) {
+ this.couple = couple;
+ this.enable = Boolean.TRUE;
+ }
}
diff --git a/src/main/java/com/universe/uni/domain/entity/MissionCategory.java b/src/main/java/com/universe/uni/domain/entity/MissionCategory.java
index 6f07671..11f07f7 100644
--- a/src/main/java/com/universe/uni/domain/entity/MissionCategory.java
+++ b/src/main/java/com/universe/uni/domain/entity/MissionCategory.java
@@ -9,13 +9,14 @@
import javax.persistence.Table;
import com.universe.uni.domain.MissionType;
-import com.universe.uni.domain.entity.convertor.GameResultAttributeConverter;
import com.universe.uni.domain.entity.convertor.MissionTypeAttributeConverter;
import lombok.AccessLevel;
+import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
+@Getter
@Table(name = "mission_category")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class MissionCategory {
diff --git a/src/main/java/com/universe/uni/domain/entity/RoundGame.java b/src/main/java/com/universe/uni/domain/entity/RoundGame.java
index 0d5ecba..6ee7fa6 100644
--- a/src/main/java/com/universe/uni/domain/entity/RoundGame.java
+++ b/src/main/java/com/universe/uni/domain/entity/RoundGame.java
@@ -11,6 +11,7 @@
import javax.persistence.Table;
import lombok.AccessLevel;
+import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -39,4 +40,11 @@ public class RoundGame {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_game_history_id")
private UserGameHistory userGameHistory;
+
+ @Builder
+ public RoundGame(Game game, MissionCategory missionCategory) {
+ this.game = game;
+ this.missionCategory = missionCategory;
+ this.enable = Boolean.TRUE;
+ }
}
diff --git a/src/main/java/com/universe/uni/domain/entity/RoundMission.java b/src/main/java/com/universe/uni/domain/entity/RoundMission.java
index 488a50e..bf04560 100644
--- a/src/main/java/com/universe/uni/domain/entity/RoundMission.java
+++ b/src/main/java/com/universe/uni/domain/entity/RoundMission.java
@@ -17,6 +17,7 @@
import com.universe.uni.domain.entity.convertor.GameResultAttributeConverter;
import lombok.AccessLevel;
+import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -53,4 +54,13 @@ public class RoundMission {
@Column(name = "final_result")
@Convert(converter = GameResultAttributeConverter.class)
private GameResult finalResult;
+
+ @Builder
+ public RoundMission(RoundGame roundGame, MissionContent missionContent, User user) {
+ this.roundGame = roundGame;
+ this.missionContent = missionContent;
+ this.user = user;
+ this.result = GameResult.UNDECIDED;
+ this.finalResult = GameResult.UNDECIDED;
+ }
}
diff --git a/src/main/java/com/universe/uni/domain/entity/ShortGame.java b/src/main/java/com/universe/uni/domain/entity/ShortGame.java
index 12fbf13..b8075bd 100644
--- a/src/main/java/com/universe/uni/domain/entity/ShortGame.java
+++ b/src/main/java/com/universe/uni/domain/entity/ShortGame.java
@@ -5,6 +5,7 @@
import javax.persistence.PrimaryKeyJoinColumn;
import lombok.AccessLevel;
+import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -15,4 +16,8 @@
@PrimaryKeyJoinColumn(name = "game_id")
public class ShortGame extends Game {
+ @Builder
+ public ShortGame(Couple couple) {
+ super(couple);
+ }
}
diff --git a/src/main/java/com/universe/uni/domain/entity/User.java b/src/main/java/com/universe/uni/domain/entity/User.java
index fc1ce0e..85436f9 100644
--- a/src/main/java/com/universe/uni/domain/entity/User.java
+++ b/src/main/java/com/universe/uni/domain/entity/User.java
@@ -11,6 +11,7 @@
import javax.persistence.ManyToOne;
import javax.persistence.Table;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.universe.uni.domain.SnsType;
import com.universe.uni.domain.entity.convertor.SnsTypeAttributeConverter;
diff --git a/src/main/java/com/universe/uni/domain/entity/UserGameHistory.java b/src/main/java/com/universe/uni/domain/entity/UserGameHistory.java
index b1db018..45ce0f2 100644
--- a/src/main/java/com/universe/uni/domain/entity/UserGameHistory.java
+++ b/src/main/java/com/universe/uni/domain/entity/UserGameHistory.java
@@ -26,7 +26,7 @@
import static lombok.AccessLevel.PROTECTED;
@Entity
-@Table(name = "user_match_history")
+@Table(name = "user_game_history")
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
diff --git a/src/main/java/com/universe/uni/domain/entity/WishCoupon.java b/src/main/java/com/universe/uni/domain/entity/WishCoupon.java
index b43262b..7339aa4 100644
--- a/src/main/java/com/universe/uni/domain/entity/WishCoupon.java
+++ b/src/main/java/com/universe/uni/domain/entity/WishCoupon.java
@@ -49,7 +49,7 @@ public class WishCoupon {
private LocalDateTime usedAt;
@ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "user_id", nullable = false)
+ @JoinColumn(name = "user_id")
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@@ -61,15 +61,12 @@ public class WishCoupon {
private GameType gameType;
@Builder
- public WishCoupon(Long id, String image, String content, boolean isVisible, boolean isUsed, LocalDateTime usedAt,
- User user, Game game, GameType gameType) {
- this.id = id;
+ public WishCoupon(String image, String content, boolean isVisible,
+ Game game, GameType gameType) {
this.image = image;
this.content = content;
this.isVisible = isVisible;
- this.isUsed = isUsed;
- this.usedAt = usedAt;
- this.user = user;
+ this.isUsed = Boolean.FALSE;
this.game = game;
this.gameType = gameType;
}
@@ -81,4 +78,9 @@ public void updateContent(String content) {
public void makeVisible() {
this.isVisible = true;
}
+
+ public void useWishCoupon() {
+ this.isUsed = true;
+ this.usedAt = LocalDateTime.now();
+ }
}
diff --git a/src/main/java/com/universe/uni/dto/request/CreateShortGameRequestDto.java b/src/main/java/com/universe/uni/dto/request/CreateShortGameRequestDto.java
new file mode 100644
index 0000000..3cfa9f8
--- /dev/null
+++ b/src/main/java/com/universe/uni/dto/request/CreateShortGameRequestDto.java
@@ -0,0 +1,15 @@
+package com.universe.uni.dto.request;
+
+import javax.validation.constraints.NotNull;
+
+import lombok.Getter;
+
+@Getter
+public class CreateShortGameRequestDto {
+
+ @NotNull
+ private Long missionCategoryId;
+
+ @NotNull
+ private String wishContent;
+}
diff --git a/src/main/java/com/universe/uni/dto/response/CreateShortGameResponseDto.java b/src/main/java/com/universe/uni/dto/response/CreateShortGameResponseDto.java
new file mode 100644
index 0000000..0b5fdd8
--- /dev/null
+++ b/src/main/java/com/universe/uni/dto/response/CreateShortGameResponseDto.java
@@ -0,0 +1,18 @@
+package com.universe.uni.dto.response;
+
+import com.universe.uni.domain.entity.RoundMission;
+import com.universe.uni.domain.entity.ShortGame;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public class CreateShortGameResponseDto {
+ private ShortGameDto shortGame;
+ private RoundMissionDto roundMission;
+
+ public static CreateShortGameResponseDto of(ShortGame shortGame, RoundMission roundMission) {
+ return new CreateShortGameResponseDto(new ShortGameDto(shortGame), new RoundMissionDto(roundMission));
+ }
+}
diff --git a/src/main/java/com/universe/uni/dto/response/RoundMissionDto.java b/src/main/java/com/universe/uni/dto/response/RoundMissionDto.java
new file mode 100644
index 0000000..305f8c3
--- /dev/null
+++ b/src/main/java/com/universe/uni/dto/response/RoundMissionDto.java
@@ -0,0 +1,26 @@
+package com.universe.uni.dto.response;
+
+import java.time.LocalDateTime;
+
+import com.universe.uni.domain.GameResult;
+import com.universe.uni.domain.entity.MissionContent;
+import com.universe.uni.domain.entity.RoundMission;
+
+import lombok.Getter;
+
+@Getter
+public class RoundMissionDto {
+ private long roundMissionId;
+ private MissionContent missionContent;
+ private GameResult result;
+ private GameResult finalResult;
+ private LocalDateTime updatedAt;
+
+ public RoundMissionDto(RoundMission roundMission){
+ this.roundMissionId = roundMission.getId();
+ this.missionContent = roundMission.getMissionContent();
+ this.result = roundMission.getResult();
+ this.finalResult = roundMission.getFinalResult();
+ this.updatedAt = roundMission.getUpdatedAt();
+ }
+}
diff --git a/src/main/java/com/universe/uni/dto/response/ShortGameDto.java b/src/main/java/com/universe/uni/dto/response/ShortGameDto.java
new file mode 100644
index 0000000..85df1eb
--- /dev/null
+++ b/src/main/java/com/universe/uni/dto/response/ShortGameDto.java
@@ -0,0 +1,21 @@
+package com.universe.uni.dto.response;
+
+import java.time.LocalDateTime;
+
+import com.universe.uni.domain.entity.ShortGame;
+
+import lombok.Getter;
+
+@Getter
+public class ShortGameDto {
+ private Long id;
+ private Boolean enable;
+ private LocalDateTime finishAt;
+
+ public ShortGameDto(ShortGame shortGame) {
+ this.id = shortGame.getId();
+ this.enable = shortGame.getEnable();
+ this.finishAt = shortGame.getFinishAt();
+ }
+
+}
diff --git a/src/main/java/com/universe/uni/dto/response/WishCouponResponseDto.java b/src/main/java/com/universe/uni/dto/response/WishCouponResponseDto.java
new file mode 100644
index 0000000..09ac96e
--- /dev/null
+++ b/src/main/java/com/universe/uni/dto/response/WishCouponResponseDto.java
@@ -0,0 +1,20 @@
+package com.universe.uni.dto.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import lombok.Builder;
+
+@JsonPropertyOrder({"id", "isMine", "image", "content", "isVisible", "isUsed", "usedAt", "gameType"})
+@Builder
+public record WishCouponResponseDto(
+ Long id,
+ boolean isMine,
+ String image,
+ String content,
+ @JsonProperty("isVisible") boolean visible,
+ @JsonProperty("isUsed") boolean used,
+ String usedAt,
+ String gameType
+) {
+}
diff --git a/src/main/java/com/universe/uni/exception/dto/ErrorType.java b/src/main/java/com/universe/uni/exception/dto/ErrorType.java
index 71aeb37..2a4493b 100644
--- a/src/main/java/com/universe/uni/exception/dto/ErrorType.java
+++ b/src/main/java/com/universe/uni/exception/dto/ErrorType.java
@@ -17,6 +17,8 @@ public enum ErrorType {
"요청 방식이 잘못된 경우입니다. 요청 방식 자체가 잘못된 경우입니다."),
VALIDATION_TOKEN_MISSING_EXCEPTION(HttpStatus.BAD_REQUEST, "UE1002",
"요청 시 토큰이 누락되어 토큰 값이 없는 경우입니다."),
+ ALREADY_GAME_CREATED(HttpStatus.BAD_REQUEST, "UE1003",
+ "이미 생성된 승부가 있습니다."),
/**
* 401 Unauthorized
@@ -32,6 +34,9 @@ public enum ErrorType {
"잘못된 endpoint에 요청한 경우입니다."),
USER_NOT_FOUND_EXCEPTION(HttpStatus.NOT_FOUND, "UE5002",
"조회한 유저가 존재하지 않는 경우 입니다."),
+ NOT_FOUND_MISSION_CATEGORY_EXCEPTION(HttpStatus.NOT_FOUND, "UE5003", "존재하지 않는 미션 카테고리입니다"),
+ NOT_FOUND_MISSION_CONTENT(HttpStatus.NOT_FOUND, "UE5004", "해당 카테고리 미션이 존재하지 않습니다."),
+ NOT_FOUND_ROUND_MISSION(HttpStatus.NOT_FOUND, "UE5005", "해당 라운드 미션이 존재하지 않습니다."),
/**
* 406 Not Acceptable
diff --git a/src/main/java/com/universe/uni/repository/GameRepository.java b/src/main/java/com/universe/uni/repository/GameRepository.java
new file mode 100644
index 0000000..b547eee
--- /dev/null
+++ b/src/main/java/com/universe/uni/repository/GameRepository.java
@@ -0,0 +1,11 @@
+package com.universe.uni.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.universe.uni.domain.entity.Couple;
+import com.universe.uni.domain.entity.Game;
+
+public interface GameRepository extends JpaRepository {
+
+ boolean existsByCoupleAndEnable(Couple couple, boolean enable);
+}
diff --git a/src/main/java/com/universe/uni/repository/MissionCategoryRepository.java b/src/main/java/com/universe/uni/repository/MissionCategoryRepository.java
new file mode 100644
index 0000000..845a481
--- /dev/null
+++ b/src/main/java/com/universe/uni/repository/MissionCategoryRepository.java
@@ -0,0 +1,8 @@
+package com.universe.uni.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.universe.uni.domain.entity.MissionCategory;
+
+public interface MissionCategoryRepository extends JpaRepository {
+}
diff --git a/src/main/java/com/universe/uni/repository/MissionContentRepository.java b/src/main/java/com/universe/uni/repository/MissionContentRepository.java
new file mode 100644
index 0000000..121d21a
--- /dev/null
+++ b/src/main/java/com/universe/uni/repository/MissionContentRepository.java
@@ -0,0 +1,12 @@
+package com.universe.uni.repository;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.universe.uni.domain.entity.MissionCategory;
+import com.universe.uni.domain.entity.MissionContent;
+
+public interface MissionContentRepository extends JpaRepository {
+ List findByMissionCategory(MissionCategory missionCategory);
+}
diff --git a/src/main/java/com/universe/uni/repository/RoundGameRepository.java b/src/main/java/com/universe/uni/repository/RoundGameRepository.java
new file mode 100644
index 0000000..74acdc0
--- /dev/null
+++ b/src/main/java/com/universe/uni/repository/RoundGameRepository.java
@@ -0,0 +1,8 @@
+package com.universe.uni.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.universe.uni.domain.entity.RoundGame;
+
+public interface RoundGameRepository extends JpaRepository {
+}
diff --git a/src/main/java/com/universe/uni/repository/RoundMissionRepository.java b/src/main/java/com/universe/uni/repository/RoundMissionRepository.java
new file mode 100644
index 0000000..6943ba7
--- /dev/null
+++ b/src/main/java/com/universe/uni/repository/RoundMissionRepository.java
@@ -0,0 +1,13 @@
+package com.universe.uni.repository;
+
+import java.util.Optional;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.universe.uni.domain.entity.RoundGame;
+import com.universe.uni.domain.entity.RoundMission;
+import com.universe.uni.domain.entity.User;
+
+public interface RoundMissionRepository extends JpaRepository {
+ Optional findByRoundGameAndUser(RoundGame roundGame, User user);
+}
diff --git a/src/main/java/com/universe/uni/repository/UserRepository.java b/src/main/java/com/universe/uni/repository/UserRepository.java
index 87b8c74..b885fba 100644
--- a/src/main/java/com/universe/uni/repository/UserRepository.java
+++ b/src/main/java/com/universe/uni/repository/UserRepository.java
@@ -1,8 +1,13 @@
package com.universe.uni.repository;
+import java.util.List;
+
import org.springframework.data.jpa.repository.JpaRepository;
+import com.universe.uni.domain.entity.Couple;
import com.universe.uni.domain.entity.User;
public interface UserRepository extends JpaRepository {
+ List findByCouple(Couple couple);
+
}
diff --git a/src/main/java/com/universe/uni/service/GameService.java b/src/main/java/com/universe/uni/service/GameService.java
new file mode 100644
index 0000000..7dcb315
--- /dev/null
+++ b/src/main/java/com/universe/uni/service/GameService.java
@@ -0,0 +1,109 @@
+package com.universe.uni.service;
+
+import static com.universe.uni.exception.dto.ErrorType.*;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.universe.uni.domain.entity.Couple;
+import com.universe.uni.domain.entity.MissionCategory;
+import com.universe.uni.domain.entity.RoundGame;
+import com.universe.uni.domain.entity.RoundMission;
+import com.universe.uni.domain.entity.ShortGame;
+import com.universe.uni.domain.entity.User;
+import com.universe.uni.domain.entity.WishCoupon;
+import com.universe.uni.dto.request.CreateShortGameRequestDto;
+import com.universe.uni.dto.response.CreateShortGameResponseDto;
+import com.universe.uni.exception.BadRequestException;
+import com.universe.uni.exception.NotFoundException;
+import com.universe.uni.repository.GameRepository;
+import com.universe.uni.repository.RoundGameRepository;
+import com.universe.uni.repository.RoundMissionRepository;
+import com.universe.uni.repository.UserRepository;
+
+import lombok.RequiredArgsConstructor;
+
+@Service
+@RequiredArgsConstructor
+public class GameService {
+
+ private final GameRepository gameRepository;
+ private final RoundGameRepository roundGameRepository;
+ private final RoundMissionRepository roundMissionRepository;
+ private final UserRepository userRepository;
+ private final MissionService missionService;
+ private final WishCouponService wishCouponService;
+
+ @Transactional
+ public CreateShortGameResponseDto createShortGame(CreateShortGameRequestDto createShortGameRequestDto) {
+
+ User user = getUser();
+ Couple couple = user.getCouple();
+
+ verifyOngoingGame(couple);
+
+ //한판승부 생성
+ ShortGame shortGame = ShortGame.builder()
+ .couple(couple)
+ .build();
+
+ //미션 카테고리 가져와서
+ MissionCategory missionCategory= missionService
+ .getMissionCategoryById(createShortGameRequestDto.getMissionCategoryId());
+
+ //roundGame 생성
+ RoundGame roundGame = RoundGame.builder()
+ .game(shortGame)
+ .missionCategory(missionCategory)
+ .build();
+
+ //커플 유저 둘 다 가져와서 roundMission 만들어주기
+ List userList = userRepository.findByCouple(getUser().getCouple());
+ List roundMissionList = userList.stream()
+ .map(u -> createRoundMission(roundGame, u))
+ .collect(Collectors.toList());
+
+ //소원권 생성
+ WishCoupon wishCoupon = wishCouponService.issueWishCoupon(createShortGameRequestDto.getWishContent(),
+ shortGame);
+
+ gameRepository.save(shortGame);
+ roundGameRepository.save(roundGame);
+ roundMissionRepository.saveAll(roundMissionList);
+ wishCouponService.saveWishCoupon(wishCoupon);
+
+
+ RoundMission myRoundMission = getRoundMissionByRoundGameAndUser(roundGame, user);
+
+ return CreateShortGameResponseDto.of(shortGame, myRoundMission);
+ }
+
+ private RoundMission createRoundMission(RoundGame roundGame, User user) {
+ return RoundMission.builder()
+ .roundGame(roundGame)
+ .user(user)
+ .missionContent(missionService.getMissionContentByRandom(roundGame.getMissionCategory()))
+ .build();
+ }
+
+ private RoundMission getRoundMissionByRoundGameAndUser(RoundGame roundGame, User user) {
+ return roundMissionRepository.findByRoundGameAndUser(roundGame, user)
+ .orElseThrow(() -> new NotFoundException(NOT_FOUND_ROUND_MISSION));
+ }
+
+ //임시 : 유저 가져오는 함수
+ private User getUser() {
+ Optional byId = userRepository.findById(1L);
+ return byId.get();
+ }
+
+ private void verifyOngoingGame(Couple couple) {
+ if(gameRepository.existsByCoupleAndEnable(couple, true)) {
+ throw new BadRequestException(ALREADY_GAME_CREATED);
+ }
+ }
+}
diff --git a/src/main/java/com/universe/uni/service/MissionService.java b/src/main/java/com/universe/uni/service/MissionService.java
new file mode 100644
index 0000000..8eb9fc1
--- /dev/null
+++ b/src/main/java/com/universe/uni/service/MissionService.java
@@ -0,0 +1,41 @@
+package com.universe.uni.service;
+
+import static com.universe.uni.exception.dto.ErrorType.*;
+
+import java.util.List;
+import java.util.Random;
+
+import org.springframework.stereotype.Service;
+
+import com.universe.uni.domain.entity.MissionCategory;
+import com.universe.uni.domain.entity.MissionContent;
+import com.universe.uni.exception.NotFoundException;
+import com.universe.uni.repository.MissionCategoryRepository;
+import com.universe.uni.repository.MissionContentRepository;
+
+import lombok.RequiredArgsConstructor;
+
+@Service
+@RequiredArgsConstructor
+public class MissionService {
+
+ private final MissionCategoryRepository missionCategoryRepository;
+ private final MissionContentRepository missionContentRepository;
+
+ public MissionCategory getMissionCategoryById(Long missionCategoryId) {
+ return missionCategoryRepository.findById(missionCategoryId)
+ .orElseThrow(() -> new NotFoundException(NOT_FOUND_MISSION_CATEGORY_EXCEPTION));
+ }
+
+ public MissionContent getMissionContentByRandom(MissionCategory missionCategory) {
+ List missionContentList = missionContentRepository
+ .findByMissionCategory(missionCategory);
+
+ try {
+ int randomIndex = new Random().nextInt(missionContentList.size());
+ return missionContentList.get(randomIndex);
+ } catch (Exception exception) {
+ throw new NotFoundException(NOT_FOUND_MISSION_CONTENT);
+ }
+ }
+}
diff --git a/src/main/java/com/universe/uni/service/WishCouponService.java b/src/main/java/com/universe/uni/service/WishCouponService.java
index 0b1c1d7..687ada2 100644
--- a/src/main/java/com/universe/uni/service/WishCouponService.java
+++ b/src/main/java/com/universe/uni/service/WishCouponService.java
@@ -6,10 +6,13 @@
import org.springframework.transaction.annotation.Transactional;
import com.universe.uni.domain.GameType;
+import com.universe.uni.domain.entity.Game;
import com.universe.uni.domain.entity.WishCoupon;
import com.universe.uni.dto.request.UpdateWishCouponRequestDto;
import com.universe.uni.dto.response.UpdateWishCouponResponseDto;
+import com.universe.uni.dto.response.WishCouponResponseDto;
import com.universe.uni.exception.BadRequestException;
+import com.universe.uni.exception.NotFoundException;
import com.universe.uni.exception.dto.ErrorType;
import com.universe.uni.repository.WishCouponRepository;
@@ -25,8 +28,8 @@ public class WishCouponService {
@Transactional
public UpdateWishCouponResponseDto uploadWishCoupon(UpdateWishCouponRequestDto requestDto) {
GameType gameType = GameType.valueOf(requestDto.gameType());
- List wishCouponList = wishCouponRepository.findByGameTypeAndIsVisibleFalseAndIsUsedFalseAndUsedAtIsNull(
- gameType);
+ List wishCouponList = wishCouponRepository
+ .findByGameTypeAndIsVisibleFalseAndIsUsedFalseAndUsedAtIsNull(gameType);
if (wishCouponList.isEmpty()) {
throw new BadRequestException(ErrorType.INVALID_REQUEST_METHOD);
@@ -37,10 +40,23 @@ public UpdateWishCouponResponseDto uploadWishCoupon(UpdateWishCouponRequestDto r
wishCoupon.updateContent(requestDto.content());
wishCoupon.makeVisible();
- return fromWishCoupon(wishCoupon);
+ return fromWishCouponToUpdateWishCouponResponseDto(wishCoupon);
}
- private UpdateWishCouponResponseDto fromWishCoupon(WishCoupon wishCoupon) {
+ public void useWishCoupon(Long wishCouponId) {
+ WishCoupon wishCoupon = wishCouponRepository.findById(wishCouponId)
+ .orElseThrow(() -> new NotFoundException(ErrorType.INVALID_ENDPOINT_EXCEPTION));
+
+ wishCoupon.useWishCoupon();
+ }
+
+ public WishCouponResponseDto getWishCoupon(Long wishCouponId) {
+ WishCoupon wishCoupon = wishCouponRepository.findById(wishCouponId)
+ .orElseThrow(() -> new NotFoundException(ErrorType.INVALID_ENDPOINT_EXCEPTION));
+ return fromWishCouponToWishCouponResponseDto(wishCoupon);
+ }
+
+ private UpdateWishCouponResponseDto fromWishCouponToUpdateWishCouponResponseDto(WishCoupon wishCoupon) {
String usedAt = wishCoupon.getUsedAt() != null ? wishCoupon.getUsedAt().toString() : null;
return UpdateWishCouponResponseDto.builder()
@@ -53,4 +69,43 @@ private UpdateWishCouponResponseDto fromWishCoupon(WishCoupon wishCoupon) {
.gameType(String.valueOf(wishCoupon.getGameType()))
.build();
}
+
+ public WishCoupon issueWishCoupon(String content, Game game) {
+ if(content == null || content.isEmpty()) {
+ return createWishCoupon(content, game, false);
+ } else {
+ return createWishCoupon(content, game, true);
+ }
+ }
+
+ private WishCoupon createWishCoupon(String content, Game game, Boolean isVisible) {
+ return WishCoupon.builder()
+ .content(content)
+ .isVisible(isVisible)
+ .game(game)
+ .gameType(GameType.SHORT)
+ .build();
+ }
+
+ @Transactional
+ public void saveWishCoupon(WishCoupon wishCoupon) {
+ wishCouponRepository.save(wishCoupon);
+ }
+
+ private WishCouponResponseDto fromWishCouponToWishCouponResponseDto(WishCoupon wishCoupon) {
+ /** TODO 영주 : 추후 1L 내 userId로 바꾸기*/
+ boolean isMine = wishCoupon.getUser().getId() == 1L;
+ String usedAt = wishCoupon.getUsedAt() != null ? wishCoupon.getUsedAt().toString() : null;
+
+ return WishCouponResponseDto.builder()
+ .id(wishCoupon.getId())
+ .isMine(isMine)
+ .image(wishCoupon.getImage())
+ .content(wishCoupon.getContent())
+ .visible(wishCoupon.isVisible())
+ .used(wishCoupon.isUsed())
+ .usedAt(usedAt)
+ .gameType(String.valueOf(wishCoupon.getGameType()))
+ .build();
+ }
}
diff --git a/uni-config b/uni-config
index baa0dcf..b67041c 160000
--- a/uni-config
+++ b/uni-config
@@ -1 +1 @@
-Subproject commit baa0dcf1874699992f482592db35d16b7914d0a3
+Subproject commit b67041c002d29e44401cf562ee2411baf2e5789c