Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
6199cdf
fix: Reset all base player when go to next inning
isaac56 May 7, 2021
2dc7b5b
refactor: Move checking to join game from GameService to User
isaac56 May 10, 2021
db57480
[#1] feat: Add status column to game table
isaac56 May 10, 2021
9bc9df5
chore: Initialize a first game that user joined as away team in
isaac56 May 10, 2021
fa8c1a0
[#6] feat: Change GameDescriptionDTO to contain status
isaac56 May 10, 2021
099aa17
[#6] feat: Change the status of the game to suit the current situation
isaac56 May 10, 2021
e4dcfed
[#6] feat: Implement api to leave the game
isaac56 May 10, 2021
a0f7962
refactor: Create BadStatusException
isaac56 May 10, 2021
47cb664
[#6] feat: Modifiy to end the game when a match is decided
isaac56 May 10, 2021
82acf9e
refactor: Remove unnecessary userId from createNewGame parameters
isaac56 May 10, 2021
e898e47
chore: Add a `jjwt` dependency to build.gradle
isaac56 May 10, 2021
c8c7673
[#11] feat: Create JwtTokenUtil
isaac56 May 10, 2021
3cca64c
[#11] test: Create JwtTokenUtilTest
isaac56 May 10, 2021
a87f849
refactor: Rename typo
isaac56 May 10, 2021
1648b51
[#11] feat: Handle exceptions related to jwt
isaac56 May 10, 2021
483d9ac
[#11] Add expiredMinute parameter to a `createToken` method
isaac56 May 10, 2021
e26fd9f
[#11] feat: Implement GithubOauthService
isaac56 May 10, 2021
f2627bf
[#1] refactor: Remove unused oauth_access_token table
isaac56 May 10, 2021
8a0e084
refactor: Rename typo
isaac56 May 10, 2021
ed7ad9c
[#11] feat: Implement UserService
isaac56 May 10, 2021
c07a15b
[#11] fix: Use `builder.claim`instead of `builder.setClaims`
isaac56 May 10, 2021
17e3525
[#11] feat: Create UnauthorizedException
isaac56 May 10, 2021
a8363e0
[#11] feat: Add a method to get user id from jwt (UserService)
isaac56 May 10, 2021
95c8076
[#11] feat: Create ApiUserController
isaac56 May 10, 2021
ab4c65a
[#11] feat: Implement token authentication using interceptor
isaac56 May 10, 2021
6a380c7
refactor: Remove `System.out.println`
isaac56 May 11, 2021
8bc5204
fix: Modifiy to increase count first when ball or strike
isaac56 May 13, 2021
3ed7565
chore: Change setting files to deployment version
isaac56 May 13, 2021
9671f43
Merge pull request #19 from isaac56/feature/BE/login-oauth-jwt
isaac56 May 13, 2021
1632a7b
feat: Add api that checking valid jwt
isaac56 May 13, 2021
676eceb
Revert "feat: Add api that checking valid jwt"
isaac56 May 14, 2021
bb1b081
fix: Fix that pitch-result api is not using userId
isaac56 May 14, 2021
b1e9cf9
refactor: Get jwt's secret key from environment variable
isaac56 May 15, 2021
dab22b6
refactor: Create `ok()` static method in ApiResult
isaac56 May 16, 2021
2b03550
refactor: Remove unnecessary if statements by collecting conditions
isaac56 May 16, 2021
80da780
refactor: Change exception handler's parameter from exception to spec…
isaac56 May 17, 2021
7c34dfd
refactor: Remove magic number
isaac56 May 17, 2021
548cb08
feat: Remove null property from json response by using @JsonInclude
isaac56 May 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BE/baseball/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'io.jsonwebtoken:jjwt:0.9.1'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package team9.baseball.DTO.response;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiResult<T> {
private T data;
private String error;
Expand All @@ -14,6 +16,10 @@ private ApiResult(T data, String error) {
this.error = error;
}

public static ApiResult<?> ok() {
return new ApiResult<>("OK", null);
}

public static <T> ApiResult<T> succeed(T data) {
return new ApiResult(data, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import team9.baseball.domain.enums.GameStatus;

@Getter
@Setter
Expand All @@ -13,4 +14,5 @@ public class GameDescriptionDTO {
private String homeTeam;
private String awayUserEmail;
private String homeUserEmail;
private GameStatus status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package team9.baseball.DTO.response.github;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class GithubEmailDTO {
private String email;
private boolean primary;
private boolean verified;
private String visibility;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package team9.baseball.DTO.response.github;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class GithubTokenDTO {
@JsonProperty("access_token")
private String accessToken;

@JsonProperty("token_type")
private String tokenType;

@JsonProperty("scope")
private String scope;

public String getAuthorizationValue() {
return this.tokenType + " " + this.accessToken;
}
}
Comment on lines +19 to +22
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

26 changes: 26 additions & 0 deletions BE/baseball/src/main/java/team9/baseball/config/WebMvcConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package team9.baseball.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
private HandlerInterceptor interceptor;

@Autowired
public WebMvcConfig(@Qualifier(value = "certificationInterceptor") HandlerInterceptor interceptor) {
this.interceptor = interceptor;
}
Comment on lines +12 to +17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그냥 CertificationInterceptor를 직접 받아도 상관 없다는 생각이 듭니다.


@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor)
.addPathPatterns("/**")
.excludePathPatterns("/user/**/")
.excludePathPatterns("/game/list");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import team9.baseball.DTO.response.ApiResult;
import team9.baseball.service.GameService;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

@RestController
Expand All @@ -27,29 +28,40 @@ public ApiResult getGameDescriptions() {

@PostMapping
public ApiResult createGame(@RequestBody CreateGameDTO createGameDTO) {
gameService.createNewGame(1l, createGameDTO.getAwayTeamId(), createGameDTO.getHomeTeamId());
return ApiResult.succeed("OK");
gameService.createNewGame(createGameDTO.getAwayTeamId(), createGameDTO.getHomeTeamId());
return ApiResult.ok();
}

@PostMapping("/joining")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저라면, path에 join하려는 게임이 무엇인지도 포함해줬을 것 같아요.

public ApiResult joinGame(@Valid @RequestBody JoinGameDTO joinGameDTO) {
gameService.joinGame(1l, joinGameDTO.getGameId(), joinGameDTO.getMyVenue());
return ApiResult.succeed("OK");
public ApiResult joinGame(@Valid @RequestBody JoinGameDTO joinGameDTO, HttpServletRequest request) {
long userId = (long) request.getAttribute("userId");
Comment on lines +36 to +37
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ServletRequest에서 필요한 데이터를 바인딩 하는 방법에 대해서 찾아보면 어떨까요?
https://www.baeldung.com/spring-mvc-custom-data-binder
https://reflectoring.io/spring-boot-argumentresolver/
https://codeboje.de/spring-mvc-argument-mapping-basics/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모든 응답을 ApiResult로 반환하는건 제 생각엔 그다지 좋지 않은 것 같습니다.

gameService.joinGame(userId, joinGameDTO.getGameId(), joinGameDTO.getMyVenue());
return ApiResult.ok();
}

@DeleteMapping("/joining")
public ApiResult quitGame(HttpServletRequest request) {
Comment on lines +42 to +43
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그냥 quit을 POST 요청 보내는것이 더 직관적인 API일 것 같습니다.

long userId = (long) request.getAttribute("userId");
gameService.quitGame(userId);
return ApiResult.ok();
}

@GetMapping("/status")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

무엇의 상태인가요?

public ApiResult getCurrentGameStatus() {
return ApiResult.succeed(gameService.getCurrentGameStatus(1l));
public ApiResult getCurrentGameStatus(HttpServletRequest request) {
long userId = (long) request.getAttribute("userId");
return ApiResult.succeed(gameService.getCurrentGameStatus(userId));
}

@PostMapping("/status/pitch-result")
public ApiResult pitch(@RequestBody PitchResultDTO pitchResultDTO) {
gameService.applyPitchResult(1l, pitchResultDTO.getPitchResult());
return ApiResult.succeed("OK");
public ApiResult pitch(@RequestBody PitchResultDTO pitchResultDTO, HttpServletRequest request) {
long userId = (long) request.getAttribute("userId");
gameService.applyPitchResult(userId, pitchResultDTO.getPitchResult());
return ApiResult.ok();
}

@GetMapping("/history")
public ApiResult getCurrentGameHistory() {
return ApiResult.succeed(gameService.getCurrentGameHistory(1l));
public ApiResult getCurrentGameHistory(HttpServletRequest request) {
long userId = (long) request.getAttribute("userId");
return ApiResult.succeed(gameService.getCurrentGameHistory(userId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package team9.baseball.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import team9.baseball.DTO.response.ApiResult;
import team9.baseball.domain.enums.ResourceServer;
import team9.baseball.service.OauthService;
import team9.baseball.service.UserService;

@RestController
@RequestMapping("/user")
public class ApiUserController {
private final UserService userService;
private final OauthService oauthService;

@Autowired
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳이 안붙여줘도 되는 애노테이션입니다.

public ApiUserController(UserService userService, OauthService oauthService) {
this.userService = userService;
this.oauthService = oauthService;
}

@GetMapping("/login/oauth/github")
public ApiResult loginUsingGithub(String code) {
String accessToken = oauthService.getAccessToken(code);
String email = oauthService.getEmail(accessToken);

return ApiResult.succeed(userService.signIn(email, ResourceServer.GITHUB));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.MappedCollection;
import team9.baseball.domain.aggregate.team.Team;
import team9.baseball.domain.enums.GameStatus;
import team9.baseball.domain.enums.Halves;
import team9.baseball.domain.enums.PitchResult;
import team9.baseball.exception.BadStatusException;
import team9.baseball.exception.NotFoundException;

import java.util.HashMap;
Expand Down Expand Up @@ -45,12 +47,17 @@ public class Game {

private int outCount;

private GameStatus status;

@MappedCollection(idColumn = "game_id", keyColumn = "key_in_game")
private Map<String, BattingHistory> battingHistoryMap = new HashMap<>();

@MappedCollection(idColumn = "game_id", keyColumn = "key_in_game")
private Map<String, Inning> inningMap = new HashMap<>();

private final int STRIKE_OUT_COUNT = 3;
private final int INNING_OUT_COUNT = 3;

public Game(Team awayTeam, Team homeTeam) {
this.awayTeamId = awayTeam.getId();
this.homeTeamId = homeTeam.getId();
Expand All @@ -63,6 +70,8 @@ public Game(Team awayTeam, Team homeTeam) {
this.currentInning = 1;
this.currentHalves = Halves.TOP;
this.inningMap.put(Inning.acquireKeyInGame(currentInning, currentHalves), new Inning(currentInning, currentHalves));

this.status = GameStatus.WAITING;
}

private void initializeBattingHistory(Team team) {
Expand All @@ -73,30 +82,42 @@ private void initializeBattingHistory(Team team) {
}
}

public void checkWaiting() {
if (this.status != GameStatus.WAITING) {
throw new BadStatusException("대기중인 게임이 아닙니다.");
}
}

public void checkPlaying() {
if (this.status != GameStatus.PLAYING) {
throw new BadStatusException("진행중인 게임이 아닙니다.");
}
}
Comment on lines +85 to +95
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


public void proceedStrike(Team awayTeam, Team homeTeam) {
//카운트 증가
this.strikeCount++;
//기록할 pitch history 생성
PitchHistory pitchHistory = new PitchHistory(acquireDefenseTeamId(), pitcherUniformNumber,
acquireAttackTeamId(), batterUniformNumber, PitchResult.STRIKE, this.strikeCount, this.ballCount);
//현재 이닝에 pitch history 기록
acquireCurrentInning().pitchHistoryList.add(pitchHistory);

//카운트 증가
this.strikeCount++;
//삼진 아웃 처리
if (strikeCount == 3) {
if (strikeCount == STRIKE_OUT_COUNT) {
proceedOut(awayTeam, homeTeam);
}
}

public void proceedBall(Team awayTeam, Team homeTeam) {
//카운트 증가
this.ballCount++;
//기록할 pitch history 생성
PitchHistory pitchHistory = new PitchHistory(acquireDefenseTeamId(), pitcherUniformNumber,
acquireAttackTeamId(), batterUniformNumber, PitchResult.BALL, this.strikeCount, this.ballCount);
//현재 이닝에 pitch history 기록
acquireCurrentInning().pitchHistoryList.add(pitchHistory);

//카운트 증가
this.ballCount++;
//볼넷일 경우 출루하고 다음 타자 등판
if (ballCount == 4) {
sendBatterOnBase();
Expand Down Expand Up @@ -191,7 +212,7 @@ private void proceedOut(Team awayTeam, Team homeTeam) {
battingHistory.plusOut();

//3회 아웃이면 다음이닝으로 변경
if (outCount == 3) {
if (outCount == INNING_OUT_COUNT) {
goToNextInning(awayTeam, homeTeam);
return;
}
Expand All @@ -214,10 +235,19 @@ private void sendBatterOnBase() {
}

private void goToNextInning(Team awayTeam, Team homeTeam) {
//게임 종료 상황이면 다음이닝으로 넘어가지 않고 게임종료
if (isExited()) {
this.status = GameStatus.EXITED;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상태를 바꾸는 부분이 여기 있어도 될까요?
다음 이닝으로 가는 것과 현재 게임의 상태를 바꾸는 것은 조금 다른 책임같아서요!

return;
}

//카운트 초기화
this.strikeCount = 0;
this.ballCount = 0;
this.outCount = 0;
this.base1UniformNumber = null;
this.base2UniformNumber = null;
this.base3UniformNumber = null;

//다음 이닝으로 변경
if (this.currentHalves == Halves.BOTTOM) {
Expand All @@ -240,6 +270,19 @@ private void goToNextInning(Team awayTeam, Team homeTeam) {
sendBatterOnPlate(attackTeam.getId(), nextBatterUniformNumber);
}

private boolean isScoreDifferent() {
return getTotalScore(Halves.TOP) != getTotalScore(Halves.BOTTOM);
}

private boolean isExited() {
if ((currentInning == 9 && currentHalves == Halves.BOTTOM && isScoreDifferent())
|| (currentInning == 12 && currentHalves == Halves.BOTTOM)) {
return true;
}

return false;
}

private void sendBatterOnPlate(int batterTeamId, int nextBatterUniformNumber) {
//카운트 초기화
this.strikeCount = 0;
Expand Down

This file was deleted.

Loading