Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REFACTOR] 리그 생성 시 자동으로 Organization 등록되도록 수정 #223

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a7ae04d
[FEAT] 경기 수정 기능 구현 #208
Zena0128 Sep 11, 2024
3ee97b1
[TEST] 경기 수정 기능 서비스 테스트 추가 #208
Zena0128 Sep 11, 2024
888f13a
[TEST] 경기 수정 기능 인수 테스트 추가 #208
Zena0128 Sep 11, 2024
4bb4552
[DOCS] 경기 수정 기능 문서화 추가
Zena0128 Sep 11, 2024
6c51383
[DOCS] 누락된 파라미터 추가
Zena0128 Sep 11, 2024
1bb6e9a
[MERGE] 메인과 병합
Zena0128 Sep 11, 2024
0b6fe12
[TEST] 서비스 테스트에서 LocalDateTime.now()를 사용해 테스트하지 않도록 수정
Zena0128 Sep 11, 2024
f4551e3
[TEST] 게임 수정 서비스 테스트 피드백 반영 #208
Zena0128 Sep 12, 2024
c37a689
[FEAT] security config에 게임 수정 Url 추가 #208
Zena0128 Sep 12, 2024
86617cf
[TEST] 게임 수정 인수 테스트 피드백 반영 #208
Zena0128 Sep 12, 2024
d50a18c
[MERGE] 메인 브랜치 변경 사항 반영 #208
Zena0128 Sep 12, 2024
09b53ba
[REFACTOR] 캡슐화를 위해 서비스단에서 사용되는 게임 수정 메소드 변경 #208
Zena0128 Sep 13, 2024
846e324
[REFACTOR] 유지보수성 향상을 위해 update 메소드들 분리 #208
Zena0128 Sep 13, 2024
82ae0a8
[TEST] 인수 테스트에서 게임 수정 테스트 시 수정 후 다시 가져와 정보 확인하도록 추가 #208
Zena0128 Sep 13, 2024
2db3e1b
[FEAT] 게임 정보 상세조회 시 누락된 round 추가 #208
Zena0128 Sep 13, 2024
1c69fc7
[DOCS] 게임 상세조회 수정한 부분 문서화 추가
Zena0128 Sep 13, 2024
73329f1
Merge branch 'main' into feat/#208-game
Zena0128 Sep 14, 2024
725ac4f
[REFACTOR] 게임 수정 시 엔티티가 DTO에 의존하거나 불필요한 엔티티 생성하지 않도록 수정 #208
Zena0128 Sep 18, 2024
afdb5e7
[MERGE] 메인 브랜치 변경 사항 반영 #215
Jin409 Sep 14, 2024
d155abc
[FEAT] 출전 선수 조회 기능 구현 #215
Jin409 Sep 14, 2024
e943348
[MERGE] 메인 브랜치 병합
Zena0128 Sep 18, 2024
9e80f35
[MERGE] 메인 브랜치 병합
Zena0128 Sep 18, 2024
f362032
[MERGE] 메인 브랜치 병합
Zena0128 Sep 18, 2024
002ad86
[TEST] 라인업 선수가 출전 중인지 확인하도록 테스트 수정 #215
Jin409 Sep 16, 2024
f699b62
[TEST] 사용되지 않는 fixture 용 repository 삭제 #215
Jin409 Sep 16, 2024
2498d4d
[MERGE] 메인 브랜치 병합
Zena0128 Sep 18, 2024
488c898
Merge branch 'main' of https://github.com/hufscheer/spectator-server …
Zena0128 Sep 19, 2024
f193d7f
[REFACTOR] 리그 생성 시 organization을 요청파라미터로 받지 않아도 자동으로 채워지도록 수정 #222
Zena0128 Sep 19, 2024
a503b2f
[TEST] 리그 생성 인수 테스트 수정 #222
Zena0128 Sep 19, 2024
8883196
[DOCS] 리그 생성 문서화 수정 #222
Zena0128 Sep 19, 2024
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
4 changes: 4 additions & 0 deletions src/docs/asciidoc/api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ operation::game-query-controller-test/출전_선수를_조회한다[snippets='ht

operation::game-controller-test/경기를_등록한다[snippets='http-request,path-parameters,http-response']

=== 게임 수정

operation::game-controller-test/경기를_수정한다[snippets='http-request,path-parameters,http-response']

== 라인업 API

=== 라인업 선수 선발로 변경
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ SecurityFilterChain filterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc
mvc.pattern(HttpMethod.GET, "/members/info"),
mvc.pattern(HttpMethod.POST, "/leagues"),
mvc.pattern(HttpMethod.PUT, "/leagues/{leagueId}"),
mvc.pattern(HttpMethod.PUT, "/leagues/{leagueId}/{gameId}"),
mvc.pattern(HttpMethod.POST, "/leagues/*/teams"),
mvc.pattern(HttpMethod.POST, "/leagues/{leagueId}/teams"),
mvc.pattern(HttpMethod.PUT, "/leagues/{leagueId}/teams/{teamId}"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.sports.server.auth.exception.AuthorizationErrorMessages;
import com.sports.server.command.game.domain.Game;
import com.sports.server.command.game.domain.GameRepository;
import com.sports.server.command.game.domain.GameState;
import com.sports.server.command.game.domain.GameTeam;
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.leagueteam.domain.LeagueTeam;
import com.sports.server.command.member.domain.Member;
import com.sports.server.command.sport.domain.Sport;
Expand Down Expand Up @@ -69,4 +71,19 @@ private League getLeagueAndCheckPermission(final Long leagueId, final Member man

return league;
}

@Transactional
public void updateGame(Long leagueId, Long gameId, GameRequestDto.Update request, Member manager) {
League league = entityUtils.getEntity(leagueId, League.class);
if (!league.isManagedBy(manager)) {
throw new UnauthorizedException(AuthorizationErrorMessages.PERMISSION_DENIED);
}
Game game = entityUtils.getEntity(gameId, Game.class);
game.updateName(request.name());
game.updateStartTime(request.startTime());
game.updateVideoId(request.videoId());
game.updateGameQuarter(request.quarter());
game.updateState(GameState.from(request.state()));
game.updateRound(Round.from(request.round()));
}
}
33 changes: 33 additions & 0 deletions src/main/java/com/sports/server/command/game/domain/Game.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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 @@ -23,6 +24,7 @@
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.util.StringUtils;
import org.springframework.http.HttpStatus;

@Entity
Expand Down Expand Up @@ -114,6 +116,37 @@ public void cancelScore(LineupPlayer scorer) {
scoredTeam.cancelScore();
}

public void updateName(String name) {
if (StringUtils.hasText(name)) {
this.name = name;
}
}

public void updateStartTime(LocalDateTime startTime) {
this.startTime = startTime;
}

public void updateVideoId(String videoId) {
if (StringUtils.hasText(videoId)) {
this.videoId = videoId;
}
}

public void updateGameQuarter(String gameQuarter) {
if (StringUtils.hasText(gameQuarter)) {
this.gameQuarter = gameQuarter;
}
}

public void updateState(GameState state) {
this.state = state;
}

public void updateRound(Round round) {
this.round = round;
}


public Game(Sport sport, Member manager, League league, String name, LocalDateTime startTime,
String videoId, String gameQuarter, GameState state, Round round) {
this.sport = sport;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,14 @@ public Game toEntity(Sport sport, Member manager, League league) {
Round.from(round));
}
}
}

public record Update(
String name,
String round,
String quarter,
String state,
LocalDateTime startTime,
String videoId
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@
import java.net.URI;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PatchMapping;
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.RestController;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
Expand Down Expand Up @@ -53,6 +49,15 @@ public ResponseEntity<Void> registerGame(@PathVariable final Long leagueId,
return ResponseEntity.created(URI.create("")).build();
}

@PutMapping("/leagues/{leagueId}/{gameId}")
public ResponseEntity<Void> updateGame(@PathVariable final Long leagueId,
@PathVariable final Long gameId,
@RequestBody final GameRequestDto.Update requestDto,
final Member member) {
gameService.updateGame(leagueId, gameId, requestDto, member);
return ResponseEntity.ok().build();
}

@PatchMapping("/games/{gameId}/{gameTeamId}/lineup-players/{lineupPlayerId}/captain/register")
public ResponseEntity<Void> changePlayerToCaptain(@PathVariable final Long gameId,
@PathVariable final Long lineupPlayerId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ public class LeagueService {
private final LeagueRepository leagueRepository;

public void register(final Member manager, final LeagueRequestDto.Register request) {
Organization organization = entityUtils.getEntity(request.organizationId(), Organization.class);
leagueRepository.save(request.toEntity(manager, organization));
leagueRepository.save(request.toEntity(manager));
}

public void update(final Member manager, final LeagueRequestDto.Update request, final Long leagueId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@

public class LeagueRequestDto {
public record Register(
Long organizationId,
String name,
String maxRound,
LocalDateTime startAt,
LocalDateTime endAt
) {
public League toEntity(final Member manager, final Organization organization) {
return new League(manager, organization, name, startAt, endAt, Round.from(maxRound));
public League toEntity(final Member manager) {
return new League(manager, manager.getOrganization(), name, startAt, endAt, Round.from(maxRound));
Copy link
Contributor

Choose a reason for hiding this comment

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

흠.. 이렇게 하면 쿼리가 한번 더 나가게 되지 않을까요?
AuthMemberResolver 에서 Member 를 자동으로 주입하고 있기 때문에 어쩔 수 없으려나요? 어떻게 생각하시나요?

Copy link
Contributor Author

@Zena0128 Zena0128 Sep 19, 2024

Choose a reason for hiding this comment

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

@Jin409 join쿼리로 member의 organization까지 한 번에 가져오는 방법도 생각해보긴 했는데..
어차피 멤버는 한 개만 들어와서 join쿼리의 효율성이 높지 않기도 하고,
join쿼리로 organization을 가져오든, get으로 organization을 가져오든 상관 없이
인증 과정에서 파라미터로 받는 멤버를 조회하는 쿼리 한 번 + organization 가져오는 쿼리 한 번 총 두 번 실행되어 유의미한 차이가 없을 것으로 생각해서 요렇게 짜긴 했어요!
더 효율적인 방법이 있으려나요?? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

흠 그쵸 그쵸 어차피 한개니까 괜찮을 것 같아요!
그리고 organization 이 이제 의미가 없어서 데이터베이스 상에 데이터도 얼마 없을 것 같아서 괜찮을 것 같네요! 굳굳

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public record GameDetailResponse(
String gameName,
String sportName,
List<TeamResponse> gameTeams,
String state
String state,
String round
) {

public GameDetailResponse(Game game, List<GameTeam> gameTeams) {
Expand All @@ -27,7 +28,8 @@ public GameDetailResponse(Game game, List<GameTeam> gameTeams) {
.sorted(Comparator.comparingLong(GameTeam::getId))
.map(TeamResponse::new)
.toList(),
game.getState().name()
game.getState().name(),
game.getRound().name()
);
}

Expand Down
101 changes: 79 additions & 22 deletions src/main/resources/static/docs/api.html
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ <h1>훕치치 서버 API 문서</h1>
<li><a href="#_게임_라인업_조회">게임 라인업 조회</a></li>
<li><a href="#_게임_출전_선수_조회">게임 출전 선수 조회</a></li>
<li><a href="#_게임_등록">게임 등록</a></li>
<li><a href="#_게임_수정">게임 수정</a></li>
</ul>
</li>
<li><a href="#_라인업_api">라인업 API</a>
Expand Down Expand Up @@ -765,13 +766,13 @@ <h4 id="_게임_상세_조회_http_response"><a class="link" href="#_게임_상
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Content-Length: 403
Content-Length: 431

{
"startTime" : "2024-01-19T13:00:00",
"videoId" : "videoId",
"gameQuarter" : "전반전",
"gameName" : "4강",
"gameName" : "여름축구",
"sportName" : "축구",
"gameTeams" : [ {
"gameTeamId" : 1,
Expand All @@ -784,7 +785,8 @@ <h4 id="_게임_상세_조회_http_response"><a class="link" href="#_게임_상
"logoImageUrl" : "logo.com",
"score" : 1
} ],
"state" : "PLAYING"
"state" : "PLAYING",
"round" : "4강"
}</code></pre>
</div>
</div>
Expand Down Expand Up @@ -831,9 +833,9 @@ <h4 id="_게임_상세_조회_response_fields"><a class="link" href="#_게임_
<td class="tableblock halign-left valign-top"><p class="tableblock">종목</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sportName</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>round</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">종목</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">게임의 라운드</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>gameTeams[].gameTeamId</code></p></td>
Expand Down Expand Up @@ -1601,7 +1603,7 @@ <h4 id="_게임_등록_http_request"><a class="link" href="#_게임_등록_http_
"round" : "16강",
"quarter" : "경기전",
"state" : "SCHEDULED",
"startTime" : "2024-09-18T18:41:01.634111",
"startTime" : "2024-09-19T14:37:00.616319",
"idOfTeam1" : 1,
"idOfTeam2" : 2,
"videoId" : "videoId"
Expand Down Expand Up @@ -1644,6 +1646,67 @@ <h4 id="_게임_등록_http_response"><a class="link" href="#_게임_등록_http
</div>
</div>
</div>
<div class="sect2">
<h3 id="_게임_수정"><a class="link" href="#_게임_수정">게임 수정</a></h3>
<div class="sect3">
<h4 id="_게임_수정_http_request"><a class="link" href="#_게임_수정_http_request">HTTP request</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">PUT /leagues/1/1 HTTP/1.1
Content-Type: application/json
Content-Length: 172
Host: www.api.hufstreaming.site
Cookie: HCC_SES=temp-cookie

{
"name" : "게임 이름",
"round" : "16강",
"quarter" : "전반전",
"state" : "PLAYING",
"startTime" : "2024-09-19T14:37:00.629697",
"videoId" : "videoId"
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_게임_수정_path_parameters"><a class="link" href="#_게임_수정_path_parameters">Path parameters</a></h4>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 1. /leagues/{leagueId}/{gameId}</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Parameter</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>leagueId</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">리그의 ID</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>gameId</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">경기의 ID</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_게임_수정_http_response"><a class="link" href="#_게임_수정_http_response">HTTP response</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
Expand Down Expand Up @@ -1908,16 +1971,15 @@ <h4 id="_리그_생성_http_request"><a class="link" href="#_리그_생성_http_
<div class="content">
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">POST /leagues HTTP/1.1
Content-Type: application/json
Content-Length: 179
Content-Length: 155
Host: www.api.hufstreaming.site
Cookie: HCC_SES=temp-cookie

{
"organizationId" : 1,
"name" : "우물정 제기차기 대회",
"maxRound" : "4강",
"startAt" : "2024-09-18T18:41:01.840974",
"endAt" : "2024-09-18T18:41:01.840975"
"startAt" : "2024-09-19T14:37:00.888284",
"endAt" : "2024-09-19T14:37:00.888288"
}</code></pre>
</div>
</div>
Expand All @@ -1939,11 +2001,6 @@ <h4 id="_리그_생성_request_fields"><a class="link" href="#_리그_생성_req
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>organizationId</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Number</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">조직 id</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>name</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">대회 이름</p></td>
Expand Down Expand Up @@ -1992,8 +2049,8 @@ <h4 id="_리그_수정_http_request"><a class="link" href="#_리그_수정_http_

{
"name" : "훕치치배 망고 빨리먹기 대회",
"startAt" : "2024-09-18T18:41:01.856257",
"endAt" : "2024-09-18T18:41:01.856261",
"startAt" : "2024-09-19T14:37:00.906675",
"endAt" : "2024-09-19T14:37:00.906679",
"maxRound" : "16강"
}</code></pre>
</div>
Expand Down Expand Up @@ -2873,12 +2930,12 @@ <h4 id="_매니저가_생성한_리그_전체_조회_http_response"><a class="li
"state" : "진행 중",
"sizeOfLeagueTeams" : 2,
"maxRound" : "16강",
"startAt" : "2024-09-18T18:41:05.056959",
"endAt" : "2024-09-18T18:41:05.056959",
"startAt" : "2024-09-19T14:37:04.588733",
"endAt" : "2024-09-19T14:37:04.588733",
"inProgressGames" : [ {
"id" : 1,
"state" : "PLAYING",
"startTime" : "2024-09-18T18:41:05.056951",
"startTime" : "2024-09-19T14:37:04.588727",
"gameTeams" : [ {
"gameTeamId" : 1,
"gameTeamName" : "경영 야생마",
Expand Down Expand Up @@ -4117,7 +4174,7 @@ <h4 id="_사용자_로그인_http_response"><a class="link" href="#_사용자_
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Set-Cookie: HCC_SES=testAccessToken; Path=/; Max-Age=604800; Expires=Wed, 25 Sep 2024 09:40:56 GMT; Secure; HttpOnly; SameSite=Strict</code></pre>
Set-Cookie: HCC_SES=testAccessToken; Path=/; Max-Age=604800; Expires=Thu, 26 Sep 2024 05:36:55 GMT; Secure; HttpOnly; SameSite=Strict</code></pre>
</div>
</div>
</div>
Expand Down Expand Up @@ -4191,7 +4248,7 @@ <h4 id="_사용자_정보_조회_response_fields"><a class="link" href="#_사용
<div id="footer">
<div id="footer-text">
Version 0.0.1-SNAPSHOT<br>
Last updated 2024-09-18 18:40:18 +0900
Last updated 2024-09-19 14:24:11 +0900
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/highlight.min.js"></script>
Expand Down
Loading
Loading