-
Notifications
You must be signed in to change notification settings - Fork 1
[FEAT] 투표 개최자 API 구현 #203
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
Merged
Merged
[FEAT] 투표 개최자 API 구현 #203
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
9f91e6c
refactor: poll 엔티티에 개최자 id 추가
coli-geonwoo d311049
feat: poll domain 추가
coli-geonwoo b480dd4
feat: vote domain 추가
coli-geonwoo 980798c
feat: controller 계층 구현
coli-geonwoo 9c0bf91
feat: VoteInfo 계층 구현
coli-geonwoo a1b559e
feat: repository 계층 구현
coli-geonwoo 61fc36d
feat: poll 생성로직 구현
coli-geonwoo 4e36d7a
feat: poll 서비스 로직 구현
coli-geonwoo 51a846f
feat: poll 컨트롤러 로직 개발
coli-geonwoo 47798a6
feat: 참여자 이름, 코드 테스트 작성
coli-geonwoo ac57a53
feat: 참여자 이름, 코드 테스트 작성
coli-geonwoo 4ee38ed
chore: basetest 디렉토리 이동
coli-geonwoo b2353b1
test: poll domainRepository 테스트 작성
coli-geonwoo 7f54c78
test: PollServiceTest 작성
coli-geonwoo b0fb06c
rename: Jpa 벤더 표기 삭제
coli-geonwoo aed0b79
test: controllerTest 작성
coli-geonwoo f973177
fix: 실패하는 테스트 수정
coli-geonwoo 22c2302
test: 문서화 코드 작성
coli-geonwoo f4f9866
refactor: 투표 생성시 다른 정보들도 같이 넘기도록 수정
coli-geonwoo 8991862
rename : updateToDone > finishPoll
coli-geonwoo 117a5f1
rename : resolveVoteInfo > countVotes
coli-geonwoo c9666f9
style: 무의미한 개행 제거
coli-geonwoo 32cfd07
style: 무의미한 개행 제거
coli-geonwoo 0d58848
refactor: 초기 생성자 추가
coli-geonwoo 9134f84
rename : readPollInfo > getPollInfo
coli-geonwoo 7da7c6e
test: 선거완료 문서화 코드 response 변경
coli-geonwoo de1c89f
test: nullandemptyandblanksource 사용하도록 변경
coli-geonwoo 538be99
test: CRUD 테스트를 컨벤션에 맞도록 변경
coli-geonwoo 486abf1
test: 테스트 생성자 변환
coli-geonwoo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
49 changes: 49 additions & 0 deletions
49
src/main/java/com/debatetimer/controller/poll/PollController.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| package com.debatetimer.controller.poll; | ||
|
|
||
| import com.debatetimer.controller.auth.AuthMember; | ||
| import com.debatetimer.domain.member.Member; | ||
| import com.debatetimer.dto.poll.response.PollCreateResponse; | ||
| import com.debatetimer.dto.poll.response.PollInfoResponse; | ||
| import com.debatetimer.service.poll.PollService; | ||
| import lombok.RequiredArgsConstructor; | ||
| 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.PostMapping; | ||
| import org.springframework.web.bind.annotation.ResponseStatus; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| @RestController | ||
| @RequiredArgsConstructor | ||
| public class PollController { | ||
|
|
||
| private final PollService pollService; | ||
|
|
||
| @PostMapping("/api/polls/{tableId}") | ||
| @ResponseStatus(HttpStatus.CREATED) | ||
| public PollCreateResponse createPoll( | ||
| @AuthMember Member member, | ||
| @PathVariable(name = "tableId") long tableId | ||
| ) { | ||
| return pollService.create(tableId, member); | ||
| } | ||
|
|
||
| @GetMapping("/api/polls/{pollId}") | ||
| @ResponseStatus(HttpStatus.OK) | ||
| public PollInfoResponse getPollInfo( | ||
| @AuthMember Member member, | ||
| @PathVariable(name = "pollId") long pollId | ||
| ) { | ||
| return pollService.getPollInfo(pollId, member); | ||
| } | ||
|
|
||
| @PatchMapping("/api/polls/{pollId}") | ||
| @ResponseStatus(HttpStatus.OK) | ||
| public PollInfoResponse finishPoll( | ||
| @AuthMember Member member, | ||
| @PathVariable(name = "pollId") long pollId | ||
| ) { | ||
| return pollService.finishPoll(pollId, member); | ||
| } | ||
| } |
22 changes: 22 additions & 0 deletions
22
src/main/java/com/debatetimer/domain/poll/ParticipantName.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package com.debatetimer.domain.poll; | ||
|
|
||
| import com.debatetimer.exception.custom.DTClientErrorException; | ||
| import com.debatetimer.exception.errorcode.ClientErrorCode; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public class ParticipantName { | ||
|
|
||
| private final String value; | ||
|
|
||
| public ParticipantName(String value) { | ||
| validateName(value); | ||
| this.value = value; | ||
| } | ||
|
|
||
| private void validateName(String value) { | ||
| if (value == null || value.isBlank()) { | ||
| throw new DTClientErrorException(ClientErrorCode.INVALID_POLL_PARTICIPANT_NAME); | ||
| } | ||
| } | ||
| } |
22 changes: 22 additions & 0 deletions
22
src/main/java/com/debatetimer/domain/poll/ParticipateCode.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package com.debatetimer.domain.poll; | ||
|
|
||
| import com.debatetimer.exception.custom.DTClientErrorException; | ||
| import com.debatetimer.exception.errorcode.ClientErrorCode; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public class ParticipateCode { | ||
|
|
||
| private final String value; | ||
|
|
||
| public ParticipateCode(String value) { | ||
| validateName(value); | ||
| this.value = value; | ||
| } | ||
|
|
||
| private void validateName(String value) { | ||
| if (value == null || value.isBlank()) { | ||
| throw new DTClientErrorException(ClientErrorCode.INVALID_POLL_PARTICIPANT_CODE); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package com.debatetimer.domain.poll; | ||
|
|
||
| import com.debatetimer.domain.customize.Agenda; | ||
| import com.debatetimer.domain.customize.TeamName; | ||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @Getter | ||
| @RequiredArgsConstructor | ||
| public class Poll { | ||
|
|
||
| private final Long id; | ||
| private final long tableId; | ||
| private final long memberId; | ||
| private final PollStatus status; | ||
| private final TeamName prosTeamName; | ||
| private final TeamName consTeamName; | ||
| private final Agenda agenda; | ||
|
|
||
| public Poll(long tableId, long memberId, String prosTeamName, String consTeamName, String agenda) { | ||
| this(null, tableId, memberId, PollStatus.PROGRESS, | ||
| new TeamName(prosTeamName), new TeamName(consTeamName), new Agenda(agenda)); | ||
| } | ||
|
|
||
| public Poll(Long id, long tableId, long memberId, PollStatus status, | ||
| String prosTeamName, String consTeamName, String agenda) { | ||
| this(id, tableId, memberId, status, new TeamName(prosTeamName), new TeamName(consTeamName), new Agenda(agenda)); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package com.debatetimer.domain.poll; | ||
|
|
||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @Getter | ||
| @RequiredArgsConstructor | ||
| public class Vote { | ||
|
|
||
| private final Long id; | ||
| private final long pollId; | ||
| private final VoteTeam team; | ||
| private final ParticipantName name; | ||
| private final ParticipateCode code; | ||
|
|
||
| public Vote(Long id, long pollId, VoteTeam team, String name, String code) { | ||
| this(id, pollId, team, new ParticipantName(name), new ParticipateCode(code)); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package com.debatetimer.domain.poll; | ||
|
|
||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public class VoteInfo { | ||
|
|
||
| private final long pollId; | ||
| private final long totalCount; | ||
| private final long prosCount; | ||
| private final long consCount; | ||
|
|
||
| public VoteInfo(long pollId, long prosCount, long consCount) { | ||
| this.pollId = pollId; | ||
| this.totalCount = prosCount + consCount; | ||
| this.prosCount = prosCount; | ||
| this.consCount = consCount; | ||
| } | ||
| } | ||
24 changes: 24 additions & 0 deletions
24
src/main/java/com/debatetimer/domainrepository/poll/CustomizeTableDomainRepository.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package com.debatetimer.domainrepository.poll; | ||
|
|
||
| import com.debatetimer.domain.customize.CustomizeTable; | ||
| import com.debatetimer.domain.member.Member; | ||
| import com.debatetimer.exception.custom.DTClientErrorException; | ||
| import com.debatetimer.exception.errorcode.ClientErrorCode; | ||
| import com.debatetimer.repository.customize.CustomizeTableRepository; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Repository; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| @Repository | ||
| @RequiredArgsConstructor | ||
| public class CustomizeTableDomainRepository { | ||
|
|
||
| private final CustomizeTableRepository customizeTableRepository; | ||
|
|
||
| @Transactional(readOnly = true) | ||
| public CustomizeTable getByIdAndMember(long tableId, Member member) { | ||
| return customizeTableRepository.findByIdAndMember(tableId, member) | ||
| .orElseThrow(() -> new DTClientErrorException(ClientErrorCode.TABLE_NOT_FOUND)) | ||
| .toDomain(); | ||
| } | ||
| } |
42 changes: 42 additions & 0 deletions
42
src/main/java/com/debatetimer/domainrepository/poll/PollDomainRepository.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package com.debatetimer.domainrepository.poll; | ||
|
|
||
| import com.debatetimer.domain.poll.Poll; | ||
| import com.debatetimer.entity.poll.PollEntity; | ||
| import com.debatetimer.exception.custom.DTClientErrorException; | ||
| import com.debatetimer.exception.errorcode.ClientErrorCode; | ||
| import com.debatetimer.repository.poll.PollRepository; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Repository; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| @Repository | ||
| @RequiredArgsConstructor | ||
| public class PollDomainRepository { | ||
|
|
||
| private final PollRepository pollRepository; | ||
|
|
||
| @Transactional | ||
| public Poll create(Poll poll) { | ||
| PollEntity pollEntity = new PollEntity(poll); | ||
| return pollRepository.save(pollEntity) | ||
| .toDomain(); | ||
| } | ||
|
|
||
| @Transactional(readOnly = true) | ||
| public Poll getByIdAndMemberId(long id, long memberId) { | ||
| return findPoll(id, memberId) | ||
| .toDomain(); | ||
| } | ||
|
|
||
| @Transactional | ||
| public Poll finishPoll(long pollId, long memberId) { | ||
| PollEntity pollEntity = findPoll(pollId, memberId); | ||
| pollEntity.updateToDone(); | ||
| return pollEntity.toDomain(); | ||
| } | ||
|
|
||
| private PollEntity findPoll(long pollId, long memberId) { | ||
| return pollRepository.findByIdAndMemberId(pollId, memberId) | ||
| .orElseThrow(() -> new DTClientErrorException(ClientErrorCode.POLL_NOT_FOUND)); | ||
| } | ||
| } |
31 changes: 31 additions & 0 deletions
31
src/main/java/com/debatetimer/domainrepository/poll/VoteDomainRepository.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package com.debatetimer.domainrepository.poll; | ||
|
|
||
| import com.debatetimer.domain.poll.VoteInfo; | ||
| import com.debatetimer.domain.poll.VoteTeam; | ||
| import com.debatetimer.entity.poll.VoteEntity; | ||
| import com.debatetimer.repository.poll.VoteRepository; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.stream.Collectors; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Repository; | ||
|
|
||
| @Repository | ||
| @RequiredArgsConstructor | ||
| public class VoteDomainRepository { | ||
|
|
||
| private final VoteRepository voteRepository; | ||
|
|
||
| public VoteInfo findVoteInfoByPollId(long pollId) { | ||
| List<VoteEntity> pollVotes = voteRepository.findAllByPollId(pollId); | ||
| return countVotes(pollId, pollVotes); | ||
| } | ||
|
|
||
| private VoteInfo countVotes(long pollId, List<VoteEntity> voteEntities) { | ||
| Map<VoteTeam, Long> teamCount = voteEntities.stream() | ||
| .collect(Collectors.groupingBy(VoteEntity::getTeam, Collectors.counting())); | ||
| long prosCount = teamCount.getOrDefault(VoteTeam.PROS, 0L); | ||
| long consCount = teamCount.getOrDefault(VoteTeam.CONS, 0L); | ||
| return new VoteInfo(pollId, prosCount, consCount); | ||
| } | ||
| } |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/debatetimer/dto/poll/response/PollCreateResponse.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.debatetimer.dto.poll.response; | ||
|
|
||
| import com.debatetimer.domain.poll.Poll; | ||
| import com.debatetimer.domain.poll.PollStatus; | ||
|
|
||
| public record PollCreateResponse( | ||
| long id, | ||
| PollStatus status, | ||
| String prosTeamName, | ||
| String consTeamName | ||
| ) { | ||
|
|
||
| public PollCreateResponse(Poll poll) { | ||
| this(poll.getId(), poll.getStatus(), poll.getProsTeamName().getValue(), poll.getConsTeamName().getValue()); | ||
| } | ||
| } |
28 changes: 28 additions & 0 deletions
28
src/main/java/com/debatetimer/dto/poll/response/PollInfoResponse.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package com.debatetimer.dto.poll.response; | ||
|
|
||
| import com.debatetimer.domain.poll.Poll; | ||
| import com.debatetimer.domain.poll.PollStatus; | ||
| import com.debatetimer.domain.poll.VoteInfo; | ||
|
|
||
| public record PollInfoResponse( | ||
| long id, | ||
| PollStatus status, | ||
| String prosTeamName, | ||
| String consTeamName, | ||
| long totalCount, | ||
| long prosCount, | ||
| long consCount | ||
| ) { | ||
|
|
||
| public PollInfoResponse(Poll poll, VoteInfo voteInfo) { | ||
| this( | ||
| poll.getId(), | ||
| poll.getStatus(), | ||
| poll.getProsTeamName().getValue(), | ||
| poll.getConsTeamName().getValue(), | ||
| voteInfo.getTotalCount(), | ||
| voteInfo.getProsCount(), | ||
| voteInfo.getConsCount() | ||
| ); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기는 서비스에서 검증해서 따로 검증로직이 없는 건가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[질문 ✋ ]
음.. 검증로직을 원래 넣었었는데 서로 시각이 다른 부분이 있을 것 같아 비토랑 커찬 시각이 궁금하네요.
해당 count 값은 애플리케이션 서버 로직 내에서 완전히 통제되는 값이에요. 즉, 외부 변인에 의해 수정될 여지가 크게 없다고 판단했어요.
또, 만약 검증로직을 넣는다면 ClientError인지, Server Error로 처리해야할지가 애매했습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 "DB에 있는 값을 보여주기 위한 객체"에는 유효성 검사를 잘 안하는 것 같아요.차라리 동작 안하는 것보다는 뭐라도 어떻게는 동작하게 하자는 느낌?
만약에 이 객체가 유저가 입력을 위한 객체로도 쓰인다고 하면, 그 때 추가하지 않을까 싶네요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개인적으로 저는 넣는 편이긴 합니다. 다만 그 검증은 사용자에게 보여주기보단 다른 개발자의 실수 방지 용도에 더 가깝긴 할 것 같아요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
일단 voter api를 만들기 위해 놔두겠습니다. 백엔드 회의 때 논의해보시죵