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

Feature/#101 히스토리 조회 #102

Merged
merged 13 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 2 additions & 2 deletions src/main/java/play/pluv/base/BaseEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ public abstract class BaseEntity {

@Column(updatable = false, nullable = false)
@CreatedDate
private LocalDateTime createdAt;
protected LocalDateTime createdAt;

@Column(nullable = false)
@LastModifiedDate
private LocalDateTime updatedAt;
protected LocalDateTime updatedAt;
}
38 changes: 38 additions & 0 deletions src/main/java/play/pluv/history/application/HistoryReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package play.pluv.history.application;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import play.pluv.history.domain.History;
import play.pluv.history.domain.TransferFailMusic;
import play.pluv.history.domain.TransferredMusic;
import play.pluv.history.domain.repository.HistoryRepository;
import play.pluv.history.domain.repository.TransferFailMusicRepository;
import play.pluv.history.domain.repository.TransferredMusicRepository;

@Component
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class HistoryReader {

private final HistoryRepository historyRepository;
private final TransferredMusicRepository transferredMusicRepository;
private final TransferFailMusicRepository transferFailMusicRepository;

public List<History> readByMemberId(final Long memberId) {
return historyRepository.findByMemberId(memberId);
}

public History readById(final Long historyId) {
return historyRepository.readById(historyId);
}

public List<TransferredMusic> readTransferredMusics(final Long historyId) {
return transferredMusicRepository.findByHistoryId(historyId);
}

public List<TransferFailMusic> readTransferFailMusics(final Long historyId) {
return transferFailMusicRepository.findByHistoryId(historyId);
}
}
38 changes: 38 additions & 0 deletions src/main/java/play/pluv/history/application/HistoryService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package play.pluv.history.application;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import play.pluv.history.domain.History;
import play.pluv.history.domain.TransferFailMusic;
import play.pluv.history.domain.TransferredMusic;

@Service
@RequiredArgsConstructor
public class HistoryService {

private final HistoryReader historyReader;

@Transactional(readOnly = true)
public List<History> findHistories(final Long memberId) {
return historyReader.readByMemberId(memberId);
}

@Transactional(readOnly = true)
public History findHistory(final Long historyId, final Long memberId) {
final History history = historyReader.readById(historyId);
history.validateOwner(memberId);
return history;
}

@Transactional(readOnly = true)
public List<TransferFailMusic> findTransferFailMusics(final Long historyId, final Long memberId) {
return historyReader.readTransferFailMusics(historyId);
}

@Transactional(readOnly = true)
public List<TransferredMusic> findTransferredMusics(final Long historyId, final Long memberId) {
return historyReader.readTransferredMusics(historyId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package play.pluv.history.application.dto;

import play.pluv.history.domain.History;

public record HistoryDetailResponse(
Long id,
Integer totalSongCount,
Integer transferredSongCount,
String title,
String imageUrl,
String source,
String destination
) {

public static HistoryDetailResponse from(final History history) {
return new HistoryDetailResponse(
history.getId(),
history.getTotalSongCount(),
history.getTransferredSongCount(),
history.getTitle(),
history.getThumbNailUrl(),
history.getSource().getName(),
history.getDestination().getName()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package play.pluv.history.application.dto;

import static java.util.Comparator.comparing;

import java.time.LocalDate;
import java.util.List;
import play.pluv.history.domain.History;

public record HistoryListResponse(
Long id,
Integer transferredSongCount,
LocalDate transferredDate,
String title,
String imageUrl
) {

public static List<HistoryListResponse> createList(final List<History> histories) {
return histories.stream()
.map(HistoryListResponse::from)
.sorted(comparing(HistoryListResponse::transferredDate).reversed())
.toList();
}

private static HistoryListResponse from(final History history) {
return new HistoryListResponse(
history.getId(), history.getTransferredSongCount(), history.getCreatedAt().toLocalDate(),
history.getTitle(), history.getThumbNailUrl()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package play.pluv.history.application.dto;

import java.util.List;
import play.pluv.history.domain.TransferFailMusic;
import play.pluv.history.domain.TransferredMusic;

public record HistoryMusicResponse(
String title,
String imageUrl,
String artistNames
) {

public static HistoryMusicResponse from(final TransferredMusic transferredMusic) {
return new HistoryMusicResponse(
transferredMusic.getTitle(), transferredMusic.getImageUrl(),
transferredMusic.getArtistNames()
);
}

public static HistoryMusicResponse from(final TransferFailMusic transferFailMusic) {
return new HistoryMusicResponse(
transferFailMusic.getTitle(), transferFailMusic.getImageUrl(),
transferFailMusic.getArtistNames()
);
}

public static List<HistoryMusicResponse> createListFromTransferFail(
final List<TransferFailMusic> transferFailMusics
) {
return transferFailMusics.stream()
.map(HistoryMusicResponse::from)
.toList();
}

public static List<HistoryMusicResponse> createListFromTransferred(
final List<TransferredMusic> transferredMusics
) {
return transferredMusics.stream()
.map(HistoryMusicResponse::from)
.toList();
}
}
59 changes: 59 additions & 0 deletions src/main/java/play/pluv/history/controller/HistoryController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package play.pluv.history.controller;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import play.pluv.base.BaseResponse;
import play.pluv.history.application.HistoryService;
import play.pluv.history.application.dto.HistoryDetailResponse;
import play.pluv.history.application.dto.HistoryListResponse;
import play.pluv.history.application.dto.HistoryMusicResponse;
import play.pluv.security.JwtMemberId;

@RestController
@RequiredArgsConstructor
public class HistoryController {

private final HistoryService historyService;

@GetMapping("/history/me")
public BaseResponse<List<HistoryListResponse>> getHistories(final JwtMemberId jwtMemberId) {
final var histories = historyService.findHistories(jwtMemberId.memberId());
final List<HistoryListResponse> historyListResponses = HistoryListResponse
.createList(histories);
return BaseResponse.ok(historyListResponses);
}

@GetMapping("/history/{id}")
public BaseResponse<HistoryDetailResponse> getHistory(
final JwtMemberId jwtMemberId, @PathVariable final Long id
) {
final var history = historyService.findHistory(id, jwtMemberId.memberId());
final HistoryDetailResponse response = HistoryDetailResponse.from(history);
return BaseResponse.ok(response);
}

@GetMapping("/history/{id}/music/fail")
public BaseResponse<List<HistoryMusicResponse>> getTransferFailMusics(
final JwtMemberId jwtMemberId, @PathVariable final Long id
) {
final var transferFailMusics = historyService.findTransferFailMusics(
id, jwtMemberId.memberId()
);
final List<HistoryMusicResponse> responses = HistoryMusicResponse
.createListFromTransferFail(transferFailMusics);
return BaseResponse.ok(responses);
}

@GetMapping("/history/{id}/music/success")
public BaseResponse<List<HistoryMusicResponse>> getTransferredMusics(
final JwtMemberId jwtMemberId, @PathVariable final Long id
) {
final var transferredMusics = historyService.findTransferredMusics(id, jwtMemberId.memberId());
final List<HistoryMusicResponse> responses = HistoryMusicResponse
.createListFromTransferred(transferredMusics);
return BaseResponse.ok(responses);
}
}
28 changes: 27 additions & 1 deletion src/main/java/play/pluv/history/domain/History.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@

import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;
import static play.pluv.history.exception.HistoryExceptionType.HISTORY_NOT_OWNER;

import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import java.time.LocalDateTime;
import java.util.Objects;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import play.pluv.base.BaseEntity;
import play.pluv.history.exception.HistoryException;
import play.pluv.playlist.domain.MusicStreaming;

@Entity
@NoArgsConstructor(access = PROTECTED)
@Getter
@NoArgsConstructor(access = PROTECTED)
public class History extends BaseEntity {

@Id
Expand All @@ -32,6 +36,22 @@ public class History extends BaseEntity {
@Enumerated(EnumType.STRING)
private MusicStreaming destination;

public History(final Long id, final String title, final String thumbNailUrl,
final Integer transferredSongCount,
final Integer totalSongCount, final Long memberId, final MusicStreaming source,
final MusicStreaming destination, final LocalDateTime createdAt) {
this.id = id;
this.title = title;
this.thumbNailUrl = thumbNailUrl;
this.transferredSongCount = transferredSongCount;
this.totalSongCount = totalSongCount;
this.memberId = memberId;
this.source = source;
this.destination = destination;
this.createdAt = createdAt;
this.updatedAt = createdAt;
}

@Builder
public History(final String title, final String thumbNailUrl, final Integer transferredSongCount,
final Integer totalSongCount, final Long memberId, final MusicStreaming source,
Expand All @@ -44,4 +64,10 @@ public History(final String title, final String thumbNailUrl, final Integer tran
this.source = source;
this.destination = destination;
}

public void validateOwner(final Long memberId) {
if (!Objects.equals(memberId, this.memberId)) {
throw new HistoryException(HISTORY_NOT_OWNER);
}
}
}
4 changes: 4 additions & 0 deletions src/main/java/play/pluv/history/domain/TransferFailMusic.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import play.pluv.base.BaseEntity;
Expand All @@ -20,8 +21,11 @@ public class TransferFailMusic extends BaseEntity {
@GeneratedValue(strategy = IDENTITY)
private Long id;
private Long historyId;
@Getter
private String title;
@Getter
private String imageUrl;
@Getter
private String artistNames;

@Builder
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/play/pluv/history/domain/TransferredMusic.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import play.pluv.base.BaseEntity;
Expand All @@ -21,8 +22,11 @@ public class TransferredMusic extends BaseEntity {
@GeneratedValue(strategy = IDENTITY)
private Long id;
private Long historyId;
@Getter
private String title;
@Getter
private String imageUrl;
@Getter
private String artistNames;
@Embedded
private HistoryMusicId musicId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import static play.pluv.history.exception.HistoryExceptionType.HISTORY_NOT_FOUND;

import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import play.pluv.history.domain.History;
import play.pluv.history.exception.HistoryException;

public interface HistoryRepository extends JpaRepository<History, Long> {

List<History> findByMemberId(final Long memberId);

default History readById(final Long id) {
return findById(id).orElseThrow(() -> new HistoryException(HISTORY_NOT_FOUND));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package play.pluv.history.exception;

import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;

import lombok.Getter;
Expand All @@ -11,6 +12,7 @@
@RequiredArgsConstructor
public enum HistoryExceptionType implements BaseExceptionType {

HISTORY_NOT_OWNER(FORBIDDEN, "요청한 히스토리는 유저의 소유가 아닙니다"),
HISTORY_NOT_FOUND(NOT_FOUND, "요청한 이전 내역을 찾을 수 없습니다.");

private final HttpStatus httpStatus;
Expand Down
Loading
Loading