Skip to content

Commit

Permalink
Refactor/#461 같은 멤버가 등록중인 노래에 같은 부분을 킬링파트로 등록시 추가 데이터를 저장하지 않는 기능 구현 (#…
Browse files Browse the repository at this point in the history
…469)

* refactor: VotingSongPart 에 ManyToOne 관계의 Member 필드 추가

생성자 변경으로 인해 실패하는 테스트 수정, sql 스크립트에 해당 변경 내용 적용

* feat: 멤버가 등록한 같은 파트가 있는지 확인하는 메서드 추가

* feat: VotingSongPartService 멤버가 등록한 같은 파트 처리 로직 추가

* feat: VotingSongPartController 멤버가 등록한 같은 파트 처리 로직, 테스트 추가

* style: 공백 제거

* refactor: VotingSongPart 의 Member 필드를 삭제하고 Vote 에 멤버를 추가한다.

* refactor: VotingSongPartService 로직 변경

* refactor: 리뷰 반영
  • Loading branch information
splitCoding authored Sep 27, 2023
1 parent e23e1c3 commit 77b5dd8
Show file tree
Hide file tree
Showing 18 changed files with 348 additions and 65 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package shook.shook.voting_song.application;

import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shook.shook.auth.ui.argumentresolver.MemberInfo;
import shook.shook.member.domain.Member;
import shook.shook.member.domain.repository.MemberRepository;
import shook.shook.member.exception.MemberException;
import shook.shook.part.domain.PartLength;
import shook.shook.voting_song.application.dto.VotingSongPartRegisterRequest;
import shook.shook.voting_song.domain.Vote;
Expand All @@ -20,38 +25,64 @@
@Service
public class VotingSongPartService {

private final MemberRepository memberRepository;
private final VotingSongRepository votingSongRepository;
private final VotingSongPartRepository votingSongPartRepository;
private final VoteRepository voteRepository;

@Transactional
public void register(final Long votingSongId, final VotingSongPartRegisterRequest request) {
final VotingSong votingSong = votingSongRepository.findById(votingSongId)
.orElseThrow(() -> new VotingSongException.VotingSongNotExistException(
Map.of("VotingSongId", String.valueOf(votingSongId))
));
public boolean registerAndReturnMemberPartDuplication(final MemberInfo memberInfo,
final Long votingSongId,
final VotingSongPartRegisterRequest request) {
final long memberId = memberInfo.getMemberId();
final Member member = findMemberThrowIfNotExist(memberId);
final VotingSong votingSong = findVotingSongThrowIfNotExist(votingSongId);

final int startSecond = request.getStartSecond();
final PartLength partLength = PartLength.findBySecond(request.getLength());
final VotingSongPart votingSongPart =
VotingSongPart.forSave(startSecond, partLength, votingSong);

if (votingSong.isUniquePart(votingSongPart)) {
addPartAndVote(votingSong, votingSongPart);
return;
final Optional<VotingSongPart> findVotingSongPart =
votingSongPartRepository.findByVotingSongAndStartSecondAndLength(votingSong, startSecond, partLength);

if (findVotingSongPart.isPresent()) {
return voteToExistVotingSongPartAndReturnVoteDuplication(member, votingSong, findVotingSongPart.get());
}

voteToExistPart(votingSong, votingSongPart);
final VotingSongPart newVotingSongPart = VotingSongPart.forSave(startSecond, partLength, votingSong);
addPartAndVote(member, votingSong, newVotingSongPart);
return false;
}

private void addPartAndVote(final VotingSong votingSong, final VotingSongPart votingSongPart) {
votingSong.addPart(votingSongPart);
votingSongPartRepository.save(votingSongPart);
private Member findMemberThrowIfNotExist(final Long memberId) {
return memberRepository.findById(memberId)
.orElseThrow(MemberException.MemberNotExistException::new);
}

private VotingSong findVotingSongThrowIfNotExist(final Long votingSongId) {
return votingSongRepository.findById(votingSongId)
.orElseThrow(() -> {
final Map<String, String> errorProperties = Map.of("VotingSongId", String.valueOf(votingSongId));
return new VotingSongException.VotingSongNotExistException(errorProperties);
});
}

voteToPart(votingSongPart);
private boolean voteToExistVotingSongPartAndReturnVoteDuplication(final Member member,
final VotingSong votingSong,
final VotingSongPart votingSongPart) {
if (existSameVoteByMember(member, votingSongPart)) {
return true;
}
voteToExistPart(member, votingSong, votingSongPart);
return false;
}

private void voteToExistPart(final VotingSong votingSong, final VotingSongPart votingSongPart) {
private boolean existSameVoteByMember(final Member member, final VotingSongPart votingSongPart) {
return voteRepository.existsByMemberAndVotingSongPart(member, votingSongPart);
}

private void voteToExistPart(final Member member,
final VotingSong votingSong,
final VotingSongPart votingSongPart) {
final VotingSongPart existPart = votingSong.getSameLengthPartStartAt(votingSongPart)
.orElseThrow(() -> new VotingSongPartException.PartNotExistException(
Map.of(
Expand All @@ -61,12 +92,19 @@ private void voteToExistPart(final VotingSong votingSong, final VotingSongPart v
)
));

voteToPart(existPart);
voteToPart(member, existPart);
}

private void voteToPart(final VotingSongPart votingSongPart) {
final Vote newVote = Vote.forSave(votingSongPart);
private void voteToPart(final Member member, final VotingSongPart votingSongPart) {
final Vote newVote = Vote.forSave(member, votingSongPart);
votingSongPart.vote(newVote);
voteRepository.save(newVote);
}

private void addPartAndVote(final Member member, final VotingSong votingSong, final VotingSongPart votingSongPart) {
votingSong.addPart(votingSongPart);
votingSongPartRepository.save(votingSongPart);

voteToPart(member, votingSongPart);
}
}
16 changes: 11 additions & 5 deletions backend/src/main/java/shook/shook/voting_song/domain/Vote.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import shook.shook.member.domain.Member;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
Expand All @@ -32,20 +33,25 @@ public class Vote {
@JoinColumn(name = "voting_song_part_id", foreignKey = @ForeignKey(name = "none"), updatable = false, nullable = false)
private VotingSongPart votingSongPart;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", foreignKey = @ForeignKey(name = "none"), updatable = false, nullable = false)
private Member member;

@Column(nullable = false, updatable = false)
private LocalDateTime createdAt = LocalDateTime.now().truncatedTo(ChronoUnit.MICROS);

private Vote(final Long id, final VotingSongPart votingSongPart) {
private Vote(final Long id, final Member member, final VotingSongPart votingSongPart) {
this.id = id;
this.member = member;
this.votingSongPart = votingSongPart;
}

public static Vote saved(final Long id, final VotingSongPart votingSongPart) {
return new Vote(id, votingSongPart);
public static Vote saved(final Long id, final Member member, final VotingSongPart votingSongPart) {
return new Vote(id, member, votingSongPart);
}

public static Vote forSave(final VotingSongPart votingSongPart) {
return new Vote(null, votingSongPart);
public static Vote forSave(final Member member, final VotingSongPart votingSongPart) {
return new Vote(null, member, votingSongPart);
}

@PrePersist
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ private void validatePart(final VotingSongPart newVotingSongPart) {

public boolean isUniquePart(final VotingSongPart newVotingSongPart) {
return votingSongParts.stream()
.noneMatch(
(votingSongPart) -> votingSongPart.hasEqualStartAndLength(newVotingSongPart)
);
.noneMatch(votingSongPart -> votingSongPart.hasEqualStartAndLength(newVotingSongPart));
}

public Optional<VotingSongPart> getSameLengthPartStartAt(final VotingSongPart other) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import shook.shook.member.domain.Member;
import shook.shook.voting_song.domain.Vote;
import shook.shook.voting_song.domain.VotingSongPart;

@Repository
public interface VoteRepository extends JpaRepository<Vote, Long> {

boolean existsByMemberAndVotingSongPart(final Member member, final VotingSongPart part);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package shook.shook.voting_song.domain.repository;

import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import shook.shook.part.domain.PartLength;
import shook.shook.voting_song.domain.VotingSong;
import shook.shook.voting_song.domain.VotingSongPart;

@Repository
public interface VotingSongPartRepository extends JpaRepository<VotingSongPart, Long> {

List<VotingSongPart> findAllByVotingSong(final VotingSong song);

Optional<VotingSongPart> findByVotingSongAndStartSecondAndLength(final VotingSong votingSong,
final int startSecond, final PartLength length);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import shook.shook.auth.ui.argumentresolver.Authenticated;
import shook.shook.auth.ui.argumentresolver.MemberInfo;
import shook.shook.voting_song.application.VotingSongPartService;
import shook.shook.voting_song.application.dto.VotingSongPartRegisterRequest;
import shook.shook.voting_song.ui.openapi.VotingSongPartApi;
Expand All @@ -21,12 +23,15 @@ public class VotingSongPartController implements VotingSongPartApi {
private final VotingSongPartService votingSongPartService;

@PostMapping
public ResponseEntity<Void> registerPart(
@PathVariable(name = "voting_song_id") final Long votingSongId,
@Valid @RequestBody final VotingSongPartRegisterRequest request
) {
votingSongPartService.register(votingSongId, request);
public ResponseEntity<Void> registerPart(@Authenticated final MemberInfo memberInfo,
@PathVariable(name = "voting_song_id") final Long votingSongId,
@Valid @RequestBody final VotingSongPartRegisterRequest request) {
final boolean memberPartDuplication =
votingSongPartService.registerAndReturnMemberPartDuplication(memberInfo, votingSongId, request);

if (memberPartDuplication) {
return ResponseEntity.ok().build();
}
return ResponseEntity.status(HttpStatus.CREATED).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import shook.shook.auth.ui.argumentresolver.Authenticated;
import shook.shook.auth.ui.argumentresolver.MemberInfo;
import shook.shook.voting_song.application.dto.VotingSongPartRegisterRequest;

@Tag(name = "VotingSongPart", description = "파트 수집 중인 노래의 파트 API")
Expand All @@ -27,8 +29,15 @@ public interface VotingSongPartApi {
description = "파트 수집 중인 노래의 id",
required = true
)
@Parameter(
name = "memberInfo",
description = "토큰을 파싱해서 얻은 회원 정보",
required = true,
hidden = true
)
@PostMapping
ResponseEntity<Void> registerPart(
@Authenticated final MemberInfo memberInfo,
@PathVariable(name = "voting_song_id") final Long votingSongId,
@Valid @RequestBody final VotingSongPartRegisterRequest request
);
Expand Down
1 change: 1 addition & 0 deletions backend/src/main/resources/dev/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ create table if not exists vote
(
id bigint auto_increment,
voting_song_part_id bigint not null,
member_id bigint not null,
created_at timestamp(6) not null,
primary key (id)
);
Expand Down
2 changes: 2 additions & 0 deletions backend/src/main/resources/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,5 @@ alter table song
add column genre varchar(255) check
(genre in ('BALLAD', 'DANCE', 'HIPHOP', 'RHYTHM_AND_BLUES', 'INDIE', 'ROCK_METAL', 'TROT',
'FOLK_BLUES', 'POP', 'JAZZ', 'CLASSIC', 'J_POP', 'EDM', 'ETC'));
alter table vote
add column member_id bigint not null;
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ void setUp() {
@Test
void register() {
//given
final KillingPartCommentRegisterRequest request = new KillingPartCommentRegisterRequest(
"댓글 내용");
final KillingPartCommentRegisterRequest request = new KillingPartCommentRegisterRequest("댓글 내용");

//when
killingPartCommentService.register(SAVED_PART.getId(), request, MEMBER_ID);
Expand Down
Loading

0 comments on commit 77b5dd8

Please sign in to comment.