Skip to content

Commit

Permalink
feat: artist subscription (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
devmizz authored Jul 27, 2024
1 parent 6b948f4 commit 39f2d39
Show file tree
Hide file tree
Showing 33 changed files with 519 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ private RequestMatcher getMatcherForUserAndAdmin() {
antMatcher(HttpMethod.POST, "/api/v1/shows/**/interest"),
antMatcher(HttpMethod.POST, "/api/v1/shows/**/alert"),
antMatcher(HttpMethod.POST, "/api/v1/genres/**"),
antMatcher(HttpMethod.POST, "/api/v1/artists/subscribe")
antMatcher(HttpMethod.GET, "/api/v1/artists/subscribed"),
antMatcher(HttpMethod.POST, "/api/v1/artists/subscribe"),
antMatcher(HttpMethod.POST, "/api/v1/artists/unsubscribe")
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.example.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.Builder;

public record PaginationApiResponse<T>(
@Schema(description = "조회한 데이터 개수")
int size,
@Schema(description = "다음 조회 가능 여부")
boolean hasNext,
@Schema(description = "조회 데이터")
List<T> data
) {

@Builder
public PaginationApiResponse(
List<T> data,
boolean hasNext
) {
this(data.size(), hasNext, data);
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package com.example.artist.controller;

import com.example.artist.controller.dto.param.ArtistSubscriptionPaginationApiParam;
import com.example.artist.controller.dto.request.ArtistPaginationApiRequest;
import com.example.artist.controller.dto.request.ArtistSubscriptionApiRequest;
import com.example.artist.controller.dto.request.ArtistSubscriptionPaginationApiRequest;
import com.example.artist.controller.dto.request.ArtistUnsubscriptionApiRequest;
import com.example.artist.controller.dto.response.ArtistPaginationApiResponse;
import com.example.artist.controller.dto.response.ArtistSimpleApiResponse;
import com.example.artist.controller.dto.response.ArtistSubscriptionApiResponse;
import com.example.artist.controller.dto.response.ArtistUnsubscriptionApiResponse;
import com.example.artist.service.ArtistService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.example.dto.response.PaginationApiResponse;
import org.example.security.dto.AuthenticatedUser;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
Expand Down Expand Up @@ -52,6 +57,25 @@ public ResponseEntity<ArtistPaginationApiResponse> getArtists(
);
}

@GetMapping("/subscriptions")
@Operation(summary = "구독한 아티스트 목록 조회")
public ResponseEntity<PaginationApiResponse<ArtistSubscriptionPaginationApiParam>> getSubscribedArtists(
@AuthenticationPrincipal AuthenticatedUser user,
@ParameterObject ArtistSubscriptionPaginationApiRequest request
) {
var response = artistService.findArtistSubscriptions(request.toServiceRequest(user.userId()));
var data = response.data().stream()
.map(ArtistSubscriptionPaginationApiParam::from)
.toList();

return ResponseEntity.ok(
PaginationApiResponse.<ArtistSubscriptionPaginationApiParam>builder()
.hasNext(response.hasNext())
.data(data)
.build()
);
}

@PostMapping("/subscribe")
@Operation(summary = "구독하기")
public ResponseEntity<ArtistSubscriptionApiResponse> subscribe(
Expand All @@ -67,9 +91,15 @@ public ResponseEntity<ArtistSubscriptionApiResponse> subscribe(

@PostMapping("/unsubscribe")
@Operation(summary = "구독 취소하기")
public ResponseEntity<Void> unsubscribe(
public ResponseEntity<ArtistUnsubscriptionApiResponse> unsubscribe(
@AuthenticationPrincipal AuthenticatedUser user,
@Valid @RequestBody ArtistUnsubscriptionApiRequest request
) {
return ResponseEntity.noContent().build();
;
return ResponseEntity.ok(
ArtistUnsubscriptionApiResponse.from(
artistService.unsubscribe(request.toServiceRequest(user.userId()))
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.example.artist.controller.dto.param;

import com.example.artist.service.dto.param.ArtistSubscriptionPaginationServiceParam;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.UUID;

public record ArtistSubscriptionPaginationApiParam(
@Schema(description = "아티스트 ID")
UUID id,
@Schema(description = "아티스트 이미지 URL")
String imageUrl,
@Schema(description = "아티스트 한글 이름")
String koreanName,
@Schema(description = "아티스트 영문 이름")
String englishName
) {

public static ArtistSubscriptionPaginationApiParam from(ArtistSubscriptionPaginationServiceParam param) {
return new ArtistSubscriptionPaginationApiParam(
param.artistId(),
param.artistImageUrl(),
param.artistKoreanName(),
param.artistEnglishName()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.example.artist.controller.dto.request;

import com.example.artist.service.dto.request.ArtistSubscriptionPaginationServiceRequest;
import com.example.artist.vo.ArtistSortStandardApiType;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.UUID;

@Schema
public record ArtistSubscriptionPaginationApiRequest(

@Parameter(
description = "정렬 기준, default: ENGLISH_NAME_ASC",
schema = @Schema(implementation = ArtistSortStandardApiType.class)
)
ArtistSortStandardApiType sortStandard,

@Parameter(description = "이전 페이지네이션 마지막 데이터의 ID / 최초 조회라면 null")
UUID cursor,

@Parameter(description = "조회하는 데이터 개수")
int size
) {

public ArtistSubscriptionPaginationApiRequest(
ArtistSortStandardApiType sortStandard,
UUID cursor,
int size
) {
this.sortStandard = sortStandard == null ? ArtistSortStandardApiType.ENGLISH_NAME_ASC : sortStandard;
this.cursor = cursor;
this.size = size;
}

public ArtistSubscriptionPaginationServiceRequest toServiceRequest(UUID userId) {
return ArtistSubscriptionPaginationServiceRequest.builder()
.size(size)
.sortStandard(sortStandard)
.cursor(cursor)
.userId(userId)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.artist.controller.dto.request;

import com.example.artist.service.dto.request.ArtistUnsubscriptionServiceRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import java.util.List;
Expand All @@ -12,4 +13,10 @@ public record ArtistUnsubscriptionApiRequest(
List<UUID> artistIds
) {

public ArtistUnsubscriptionServiceRequest toServiceRequest(UUID userId) {
return ArtistUnsubscriptionServiceRequest.builder()
.artistIds(artistIds())
.userId(userId)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.artist.controller.dto.response;

import com.example.artist.service.dto.response.ArtistUnsubscriptionServiceResponse;
import java.util.List;
import java.util.UUID;

public record ArtistUnsubscriptionApiResponse(
List<UUID> successUnsubscriptionArtistIds
) {

public static ArtistUnsubscriptionApiResponse from(
ArtistUnsubscriptionServiceResponse response
) {
return new ArtistUnsubscriptionApiResponse(response.successUnsubscriptionArtistIds());
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.example.artist.service;

import com.example.artist.service.dto.param.ArtistSubscriptionPaginationServiceParam;
import com.example.artist.service.dto.request.ArtistSubscriptionPaginationServiceRequest;
import com.example.artist.service.dto.request.ArtistSubscriptionServiceRequest;
import com.example.artist.service.dto.request.ArtistUnsubscriptionServiceRequest;
import com.example.artist.service.dto.response.ArtistSubscriptionPaginationServiceResponse;
import com.example.artist.service.dto.response.ArtistSubscriptionServiceResponse;
import com.example.artist.service.dto.response.ArtistUnsubscriptionServiceResponse;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.entity.ArtistSubscription;
Expand All @@ -23,47 +26,63 @@ public class ArtistService {
private final ArtistSubscriptionUseCase artistSubscriptionUseCase;

public ArtistSubscriptionServiceResponse subscribe(ArtistSubscriptionServiceRequest request) {
List<Artist> existArtists = artistUseCase.findAllArtistInIds(request.artistIds());
List<Artist> existArtistsInRequest = artistUseCase.findAllArtistInIds(request.artistIds());
List<UUID> existArtistIdsInRequest = existArtistsInRequest.stream()
.map(Artist::getId)
.toList();

List<ArtistSubscription> newArtistSubscription = getNewArtistSubscription(
existArtists,
List<ArtistSubscription> subscriptions = artistSubscriptionUseCase.subscribe(
existArtistIdsInRequest,
request.userId()
);

artistSubscriptionUseCase.subscribe(newArtistSubscription);

return ArtistSubscriptionServiceResponse.builder()
.successSubscriptionArtistIds(
newArtistSubscription.stream()
subscriptions.stream()
.map(ArtistSubscription::getArtistId)
.toList()
)
.build();
).build();
}

private List<ArtistSubscription> getNewArtistSubscription(
List<Artist> artists,
UUID userId
public ArtistUnsubscriptionServiceResponse unsubscribe(
ArtistUnsubscriptionServiceRequest request
) {
var existSubscriptionByArtistId = getExistSubscriptionByArtistId(userId);
return artists.stream()
.filter(artist -> !existSubscriptionByArtistId.containsKey(artist.getId()))
.map(artist ->
ArtistSubscription.builder()
.artistId(artist.getId())
.userId(userId)
.build()
).toList();
List<ArtistSubscription> unsubscribedArtists = artistSubscriptionUseCase.unsubscribe(
request.artistIds(),
request.userId()
);

return ArtistUnsubscriptionServiceResponse.builder()
.successUnsubscriptionArtistIds(
unsubscribedArtists.stream()
.map(ArtistSubscription::getArtistId)
.toList()
).build();
}

private Map<UUID, ArtistSubscription> getExistSubscriptionByArtistId(UUID userId) {
return artistSubscriptionUseCase.findSubscriptionList(userId)
.stream()
.collect(
Collectors.toMap(
ArtistSubscription::getArtistId,
artistSubscription -> artistSubscription
)
);
public ArtistSubscriptionPaginationServiceResponse findArtistSubscriptions(
ArtistSubscriptionPaginationServiceRequest request
) {
List<ArtistSubscription> subscriptions = artistSubscriptionUseCase.findSubscriptionList(request.userId());
List<UUID> subscriptionArtistIds = subscriptions.stream()
.map(ArtistSubscription::getArtistId)
.toList();

if (subscriptionArtistIds.isEmpty()) {
return ArtistSubscriptionPaginationServiceResponse.builder()
.data(List.of())
.hasNext(false)
.build();
}

var response = artistUseCase.findAllArtistInCursorPagination(request.toDomainRequest(subscriptionArtistIds));
List<ArtistSubscriptionPaginationServiceParam> data = response.data().stream()
.map(ArtistSubscriptionPaginationServiceParam::new)
.toList();

return ArtistSubscriptionPaginationServiceResponse.builder()
.data(data)
.hasNext(response.hasNext())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.example.artist.service.dto.param;

import java.util.UUID;
import org.example.dto.artist.response.SimpleArtistResponse;

public record ArtistSubscriptionPaginationServiceParam(
UUID artistId,
String artistImageUrl,
String artistKoreanName,
String artistEnglishName
) {

public ArtistSubscriptionPaginationServiceParam(SimpleArtistResponse response) {
this(
response.id(),
response.image(),
response.koreanName(),
response.englishName()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import java.util.UUID;
import lombok.Builder;
import org.example.entity.artist.Artist;
import org.example.entity.artist.ArtistGender;
import org.example.entity.artist.ArtistType;
import org.example.vo.ArtistGender;
import org.example.vo.ArtistType;
import org.springframework.web.multipart.MultipartFile;

@Builder
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.example.artist.service.dto.request;

import com.example.artist.vo.ArtistSortStandardApiType;
import java.util.List;
import java.util.UUID;
import lombok.Builder;
import org.example.dto.artist.request.ArtistPaginationDomainRequest;

@Builder
public record ArtistSubscriptionPaginationServiceRequest(
int size,
ArtistSortStandardApiType sortStandard,
UUID cursor,
UUID userId
) {

public ArtistPaginationDomainRequest toDomainRequest(List<UUID> artistIds) {
return ArtistPaginationDomainRequest.builder()
.size(size)
.sortStandard(sortStandard.toDomainType())
.artistIds(artistIds)
.cursor(cursor)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.artist.service.dto.request;

import java.util.List;
import java.util.UUID;
import lombok.Builder;

@Builder
public record ArtistUnsubscriptionServiceRequest(
List<UUID> artistIds,
UUID userId
) {

}
Loading

0 comments on commit 39f2d39

Please sign in to comment.