Skip to content

Commit

Permalink
Merge pull request #240 from hufscheer/feat/#236-pk-timeline
Browse files Browse the repository at this point in the history
[FEAT] 승부차기 타임라인 등록 기능 구현
  • Loading branch information
Jin409 authored Sep 25, 2024
2 parents f872341 + 0f3f143 commit 9f12ecf
Show file tree
Hide file tree
Showing 14 changed files with 526 additions and 66 deletions.
4 changes: 4 additions & 0 deletions src/docs/asciidoc/api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ operation::timeline-controller-test/교체_타임라인을_생성한다[snippets

operation::timeline-controller-test/게임_진행_변경_타임라인을_생성한다[snippets='http-request,path-parameters,request-fields,http-response']

=== 승부차기 타임라인 생성

operation::timeline-controller-test/게임_승부차기_타임라인을_생성한다[snippets='http-request,path-parameters,request-fields,http-response']

=== 게임의 타임라인 조회

operation::timeline-query-controller-test/타임라인을_조회한다[snippets='http-request,path-parameters,http-response,response-fields']
Expand Down
21 changes: 19 additions & 2 deletions src/main/java/com/sports/server/command/game/domain/Game.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.sports.server.command.game.domain;

import com.sports.server.command.game.dto.GameRequestDto;
import com.sports.server.command.league.domain.League;
import com.sports.server.command.league.domain.Round;
import com.sports.server.command.member.domain.Member;
Expand All @@ -24,8 +23,8 @@
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.util.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;

@Entity
@Getter
Expand Down Expand Up @@ -103,6 +102,15 @@ public void score(LineupPlayer scorer) {
scoredTeam.score();
}

public void scoreInPk(LineupPlayer scorer) {
GameTeam scoredTeam = teams.stream()
.filter(scorer::isInTeam)
.findAny()
.orElseThrow(() -> new IllegalArgumentException("참여하지 않는 선수는 승부차기에서 득점할 수 없습니다."));

scoredTeam.scoreInPk();
}

public boolean isMangedBy(Member member) {
return manager.equals(member);
}
Expand All @@ -116,6 +124,15 @@ public void cancelScore(LineupPlayer scorer) {
scoredTeam.cancelScore();
}

public void cancelPkScore(LineupPlayer scorer) {
GameTeam scoredTeam = teams.stream()
.filter(scorer::isInTeam)
.findAny()
.orElseThrow(() -> new IllegalArgumentException("참여하지 않는 선수는 득점을 취소할 수 없습니다."));

scoredTeam.cancelPkScore();
}

public void updateName(String name) {
if (StringUtils.hasText(name)) {
this.name = name;
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/sports/server/command/game/domain/GameTeam.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class GameTeam extends BaseEntity<GameTeam> {
private static final int MAXIMUM_OF_TOTAL_CHEER_COUNT = 100_000_000;
private static final int MINIMUM_OF_CHEER_COUNT = 0;
private static final int SCORE_VALUE = 1;
private static final int PK_SCORE_VALUE = 1;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "game_id")
Expand All @@ -47,6 +48,9 @@ public class GameTeam extends BaseEntity<GameTeam> {
@Column(name = "score", nullable = false)
private int score;

@Column(name = "pk_score", nullable = false)
private int pkScore;

public void validateCheerCountOfGameTeam(final int cheerCount) {
if (cheerCount >= MAXIMUM_OF_CHEER_COUNT || cheerCount <= MINIMUM_OF_CHEER_COUNT) {
throw new CustomException(HttpStatus.BAD_REQUEST, "잘못된 범위의 응원 요청 횟수입니다.");
Expand Down Expand Up @@ -78,12 +82,22 @@ public void score() {
this.score += SCORE_VALUE;
}

public void scoreInPk() {
this.pkScore += PK_SCORE_VALUE;
}

public void cancelScore() {
if (this.score > 0) {
this.score -= SCORE_VALUE;
}
}

public void cancelPkScore() {
if (this.pkScore > 0) {
this.pkScore -= PK_SCORE_VALUE;
}
}

public GameTeam(Game game, LeagueTeam leagueTeam) {
this.game = game;
this.leagueTeam = leagueTeam;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
package com.sports.server.command.timeline.domain;

import com.sports.server.command.game.domain.Game;
import com.sports.server.command.game.domain.LineupPlayer;
import jakarta.persistence.*;
import com.sports.server.command.sport.domain.Quarter;
import jakarta.persistence.Column;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@DiscriminatorValue("PK")
@Getter
public class PKTimeline extends Timeline {
Expand All @@ -21,11 +31,21 @@ public TimelineType getType() {
return TimelineType.PK;
}

public PKTimeline(Game game,
Quarter recordedQuarter, Integer recordedAt,
LineupPlayer scorer, Boolean isSuccess) {
super(game, recordedQuarter, recordedAt);
this.scorer = scorer;
this.isSuccess = isSuccess;
}

@Override
public void apply() {
game.scoreInPk(scorer);
}

@Override
public void rollback() {
game.cancelPkScore(scorer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,31 @@ public TimelineType getType() {
return TimelineType.GAME_PROGRESS;
}
}

@Getter
public static class RegisterPk extends TimelineRequest {
private final Long gameTeamId;
private final Long scorerId;
private final Boolean isSuccess;

public RegisterPk(
Integer recordedAt,
Long recordedQuarterId,
Long gameTeamId,
Long scorerId,
boolean isSuccess
) {
super(recordedQuarterId, recordedAt);
this.gameTeamId = gameTeamId;
this.scorerId = scorerId;
this.isSuccess = isSuccess;
}

@Override
public TimelineType getType() {
return TimelineType.PK;
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
import com.sports.server.command.game.domain.Game;
import com.sports.server.command.game.domain.LineupPlayer;
import com.sports.server.command.sport.domain.Quarter;
import com.sports.server.command.timeline.domain.*;
import com.sports.server.command.timeline.domain.GameProgressTimeline;
import com.sports.server.command.timeline.domain.PKTimeline;
import com.sports.server.command.timeline.domain.ReplacementTimeline;
import com.sports.server.command.timeline.domain.ScoreTimeline;
import com.sports.server.command.timeline.domain.Timeline;
import com.sports.server.command.timeline.domain.TimelineType;
import com.sports.server.command.timeline.dto.TimelineRequest;
import com.sports.server.common.application.EntityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
Expand All @@ -20,7 +24,8 @@ public class TimelineMapper {
private final Map<TimelineType, TimelineSupplier> suppliers = Map.of(
TimelineType.SCORE, (g, r) -> toScoreTimeline(g, (TimelineRequest.RegisterScore) r),
TimelineType.REPLACEMENT, (g, r) -> toReplacementTimeline(g, (TimelineRequest.RegisterReplacement) r),
TimelineType.GAME_PROGRESS, (g, r) -> toProgressTimeline(g, (TimelineRequest.RegisterProgress) r)
TimelineType.GAME_PROGRESS, (g, r) -> toProgressTimeline(g, (TimelineRequest.RegisterProgress) r),
TimelineType.PK, (g, r) -> toPkTimeline(g, (TimelineRequest.RegisterPk) r)
);

public Timeline toEntity(Game game, TimelineRequest request) {
Expand Down Expand Up @@ -60,6 +65,17 @@ private Timeline toProgressTimeline(Game game,
);
}

private PKTimeline toPkTimeline(Game game,
TimelineRequest.RegisterPk pkRequest) {
return new PKTimeline(
game,
getQuarter(pkRequest.getRecordedQuarterId()),
pkRequest.getRecordedAt(),
getPlayer(pkRequest.getScorerId()),
pkRequest.getIsSuccess()
);
}

private Quarter getQuarter(Long quarterId) {
return entityUtils.getEntity(quarterId, Quarter.class);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.sports.server.command.timeline.presentation;

import com.sports.server.command.member.domain.Member;
import com.sports.server.command.timeline.dto.TimelineRequest;
import com.sports.server.command.timeline.application.TimelineService;
import com.sports.server.command.timeline.dto.TimelineRequest;
import java.net.URI;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
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;

@RestController
@RequestMapping("/games/{gameId}/timelines")
Expand Down Expand Up @@ -40,6 +44,14 @@ public ResponseEntity<Void> createProgressTimeline(@PathVariable Long gameId,
return ResponseEntity.created(URI.create("")).build();
}

@PostMapping("/pk")
public ResponseEntity<Void> createPkTimeline(@PathVariable Long gameId,
@RequestBody TimelineRequest.RegisterPk request,
Member member) {
timelineService.register(member, gameId, request);
return ResponseEntity.created(URI.create("")).build();
}

@DeleteMapping("/{timelineId}")
public ResponseEntity<Void> deleteTimeline(@PathVariable Long gameId,
@PathVariable Long timelineId,
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/db/migration/V18__update-game-teams.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE game_teams
ADD COLUMN pk_score INT NOT NULL DEFAULT 0;
Loading

0 comments on commit 9f12ecf

Please sign in to comment.